aboutsummaryrefslogtreecommitdiffstats
path: root/net/llc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/llc
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'net/llc')
-rw-r--r--net/llc/Kconfig10
-rw-r--r--net/llc/Makefile24
-rw-r--r--net/llc/af_llc.c1079
-rw-r--r--net/llc/llc_c_ac.c1514
-rw-r--r--net/llc/llc_c_ev.c769
-rw-r--r--net/llc/llc_c_st.c4946
-rw-r--r--net/llc/llc_conn.c915
-rw-r--r--net/llc/llc_core.c179
-rw-r--r--net/llc/llc_if.c157
-rw-r--r--net/llc/llc_input.c189
-rw-r--r--net/llc/llc_output.c107
-rw-r--r--net/llc/llc_output.h20
-rw-r--r--net/llc/llc_pdu.c372
-rw-r--r--net/llc/llc_proc.c267
-rw-r--r--net/llc/llc_s_ac.c205
-rw-r--r--net/llc/llc_s_ev.c115
-rw-r--r--net/llc/llc_s_st.c183
-rw-r--r--net/llc/llc_sap.c316
-rw-r--r--net/llc/llc_station.c713
19 files changed, 12080 insertions, 0 deletions
diff --git a/net/llc/Kconfig b/net/llc/Kconfig
new file mode 100644
index 000000000000..b91c65108162
--- /dev/null
+++ b/net/llc/Kconfig
@@ -0,0 +1,10 @@
1config LLC
2 tristate
3 depends on NET
4
5config LLC2
6 tristate "ANSI/IEEE 802.2 LLC type 2 Support"
7 select LLC
8 help
9 This is a Logical Link Layer type 2, connection oriented support.
10 Select this if you want to have support for PF_LLC sockets.
diff --git a/net/llc/Makefile b/net/llc/Makefile
new file mode 100644
index 000000000000..5ebd4ed2bd42
--- /dev/null
+++ b/net/llc/Makefile
@@ -0,0 +1,24 @@
1###########################################################################
2# Makefile for the Linux 802.2 LLC (fully-functional) layer.
3#
4# Copyright (c) 1997 by Procom Technology,Inc.
5# 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6#
7# This program can be redistributed or modified under the terms of the
8# GNU General Public License as published by the Free Software Foundation.
9# This program is distributed without any warranty or implied warranty
10# of merchantability or fitness for a particular purpose.
11#
12# See the GNU General Public License for more details.
13###########################################################################
14
15obj-$(CONFIG_LLC) += llc.o
16
17llc-y := llc_core.o llc_input.o llc_output.o
18
19obj-$(CONFIG_LLC2) += llc2.o
20
21llc2-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_conn.o llc_c_st.o llc_pdu.o \
22 llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_station.o
23
24llc2-$(CONFIG_PROC_FS) += llc_proc.o
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
new file mode 100644
index 000000000000..20b4cfebd74c
--- /dev/null
+++ b/net/llc/af_llc.c
@@ -0,0 +1,1079 @@
1/*
2 * af_llc.c - LLC User Interface SAPs
3 * Description:
4 * Functions in this module are implementation of socket based llc
5 * communications for the Linux operating system. Support of llc class
6 * one and class two is provided via SOCK_DGRAM and SOCK_STREAM
7 * respectively.
8 *
9 * An llc2 connection is (mac + sap), only one llc2 sap connection
10 * is allowed per mac. Though one sap may have multiple mac + sap
11 * connections.
12 *
13 * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
14 * 2002-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
15 *
16 * This program can be redistributed or modified under the terms of the
17 * GNU General Public License as published by the Free Software Foundation.
18 * This program is distributed without any warranty or implied warranty
19 * of merchantability or fitness for a particular purpose.
20 *
21 * See the GNU General Public License for more details.
22 */
23#include <linux/config.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/tcp.h>
27#include <linux/rtnetlink.h>
28#include <linux/init.h>
29#include <net/llc.h>
30#include <net/llc_sap.h>
31#include <net/llc_pdu.h>
32#include <net/llc_conn.h>
33
34/* remember: uninitialized global data is zeroed because its in .bss */
35static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
36static u16 llc_ui_sap_link_no_max[256];
37static struct sockaddr_llc llc_ui_addrnull;
38static struct proto_ops llc_ui_ops;
39
40static int llc_ui_wait_for_conn(struct sock *sk, int timeout);
41static int llc_ui_wait_for_disc(struct sock *sk, int timeout);
42static int llc_ui_wait_for_data(struct sock *sk, int timeout);
43static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout);
44
45#if 0
46#define dprintk(args...) printk(KERN_DEBUG args)
47#else
48#define dprintk(args...)
49#endif
50
51/**
52 * llc_ui_next_link_no - return the next unused link number for a sap
53 * @sap: Address of sap to get link number from.
54 *
55 * Return the next unused link number for a given sap.
56 */
57static __inline__ u16 llc_ui_next_link_no(int sap)
58{
59 return llc_ui_sap_link_no_max[sap]++;
60}
61
62/**
63 * llc_proto_type - return eth protocol for ARP header type
64 * @arphrd: ARP header type.
65 *
66 * Given an ARP header type return the corresponding ethernet protocol.
67 */
68static __inline__ u16 llc_proto_type(u16 arphrd)
69{
70 return arphrd == ARPHRD_IEEE802_TR ?
71 htons(ETH_P_TR_802_2) : htons(ETH_P_802_2);
72}
73
74/**
75 * llc_ui_addr_null - determines if a address structure is null
76 * @addr: Address to test if null.
77 */
78static __inline__ u8 llc_ui_addr_null(struct sockaddr_llc *addr)
79{
80 return !memcmp(addr, &llc_ui_addrnull, sizeof(*addr));
81}
82
83/**
84 * llc_ui_header_len - return length of llc header based on operation
85 * @sk: Socket which contains a valid llc socket type.
86 * @addr: Complete sockaddr_llc structure received from the user.
87 *
88 * Provide the length of the llc header depending on what kind of
89 * operation the user would like to perform and the type of socket.
90 * Returns the correct llc header length.
91 */
92static __inline__ u8 llc_ui_header_len(struct sock *sk,
93 struct sockaddr_llc *addr)
94{
95 u8 rc = LLC_PDU_LEN_U;
96
97 if (addr->sllc_test || addr->sllc_xid)
98 rc = LLC_PDU_LEN_U;
99 else if (sk->sk_type == SOCK_STREAM)
100 rc = LLC_PDU_LEN_I;
101 return rc;
102}
103
104/**
105 * llc_ui_send_data - send data via reliable llc2 connection
106 * @sk: Connection the socket is using.
107 * @skb: Data the user wishes to send.
108 * @addr: Source and destination fields provided by the user.
109 * @noblock: can we block waiting for data?
110 *
111 * Send data via reliable llc2 connection.
112 * Returns 0 upon success, non-zero if action did not succeed.
113 */
114static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock)
115{
116 struct llc_sock* llc = llc_sk(sk);
117 int rc = 0;
118
119 if (llc_data_accept_state(llc->state) || llc->p_flag) {
120 int timeout = sock_sndtimeo(sk, noblock);
121
122 rc = llc_ui_wait_for_busy_core(sk, timeout);
123 }
124 if (!rc)
125 rc = llc_build_and_send_pkt(sk, skb);
126 return rc;
127}
128
129static void llc_ui_sk_init(struct socket *sock, struct sock *sk)
130{
131 sk->sk_type = sock->type;
132 sk->sk_sleep = &sock->wait;
133 sk->sk_socket = sock;
134 sock->sk = sk;
135 sock->ops = &llc_ui_ops;
136}
137
138static struct proto llc_proto = {
139 .name = "DDP",
140 .owner = THIS_MODULE,
141 .obj_size = sizeof(struct llc_sock),
142};
143
144/**
145 * llc_ui_create - alloc and init a new llc_ui socket
146 * @sock: Socket to initialize and attach allocated sk to.
147 * @protocol: Unused.
148 *
149 * Allocate and initialize a new llc_ui socket, validate the user wants a
150 * socket type we have available.
151 * Returns 0 upon success, negative upon failure.
152 */
153static int llc_ui_create(struct socket *sock, int protocol)
154{
155 struct sock *sk;
156 int rc = -ESOCKTNOSUPPORT;
157
158 if (sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM) {
159 rc = -ENOMEM;
160 sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
161 if (sk) {
162 rc = 0;
163 llc_ui_sk_init(sock, sk);
164 }
165 }
166 return rc;
167}
168
169/**
170 * llc_ui_release - shutdown socket
171 * @sock: Socket to release.
172 *
173 * Shutdown and deallocate an existing socket.
174 */
175static int llc_ui_release(struct socket *sock)
176{
177 struct sock *sk = sock->sk;
178 struct llc_sock *llc;
179
180 if (!sk)
181 goto out;
182 sock_hold(sk);
183 lock_sock(sk);
184 llc = llc_sk(sk);
185 dprintk("%s: closing local(%02X) remote(%02X)\n", __FUNCTION__,
186 llc->laddr.lsap, llc->daddr.lsap);
187 if (!llc_send_disc(sk))
188 llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
189 if (!sock_flag(sk, SOCK_ZAPPED))
190 llc_sap_remove_socket(llc->sap, sk);
191 release_sock(sk);
192 if (llc->sap && hlist_empty(&llc->sap->sk_list.list)) {
193 llc_release_sockets(llc->sap);
194 llc_sap_close(llc->sap);
195 }
196 if (llc->dev)
197 dev_put(llc->dev);
198 sock_put(sk);
199 llc_sk_free(sk);
200out:
201 return 0;
202}
203
204/**
205 * llc_ui_autoport - provide dynamically allocate SAP number
206 *
207 * Provide the caller with a dynamically allocated SAP number according
208 * to the rules that are set in this function. Returns: 0, upon failure,
209 * SAP number otherwise.
210 */
211static int llc_ui_autoport(void)
212{
213 struct llc_sap *sap;
214 int i, tries = 0;
215
216 while (tries < LLC_SAP_DYN_TRIES) {
217 for (i = llc_ui_sap_last_autoport;
218 i < LLC_SAP_DYN_STOP; i += 2) {
219 sap = llc_sap_find(i);
220 if (!sap) {
221 llc_ui_sap_last_autoport = i + 2;
222 goto out;
223 }
224 }
225 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
226 tries++;
227 }
228 i = 0;
229out:
230 return i;
231}
232
233/**
234 * llc_ui_autobind - Bind a socket to a specific address.
235 * @sk: Socket to bind an address to.
236 * @addr: Address the user wants the socket bound to.
237 *
238 * Bind a socket to a specific address. For llc a user is able to bind to
239 * a specific sap only or mac + sap. If the user only specifies a sap and
240 * a null dmac (all zeros) the user is attempting to bind to an entire
241 * sap. This will stop anyone else on the local system from using that
242 * sap. If someone else has a mac + sap open the bind to null + sap will
243 * fail.
244 * If the user desires to bind to a specific mac + sap, it is possible to
245 * have multiple sap connections via multiple macs.
246 * Bind and autobind for that matter must enforce the correct sap usage
247 * otherwise all hell will break loose.
248 * Returns: 0 upon success, negative otherwise.
249 */
250static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
251{
252 struct sock *sk = sock->sk;
253 struct llc_sock *llc = llc_sk(sk);
254 struct llc_sap *sap;
255 int rc = -EINVAL;
256
257 if (!sock_flag(sk, SOCK_ZAPPED))
258 goto out;
259 rc = -ENODEV;
260 llc->dev = dev_getfirstbyhwtype(addr->sllc_arphrd);
261 if (!llc->dev)
262 goto out;
263 rc = -EUSERS;
264 llc->laddr.lsap = llc_ui_autoport();
265 if (!llc->laddr.lsap)
266 goto out;
267 rc = -EBUSY; /* some other network layer is using the sap */
268 sap = llc_sap_open(llc->laddr.lsap, NULL);
269 if (!sap)
270 goto out;
271 memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
272 memcpy(&llc->addr, addr, sizeof(llc->addr));
273 /* assign new connection to its SAP */
274 llc_sap_add_socket(sap, sk);
275 sock_reset_flag(sk, SOCK_ZAPPED);
276 rc = 0;
277out:
278 return rc;
279}
280
281/**
282 * llc_ui_bind - bind a socket to a specific address.
283 * @sock: Socket to bind an address to.
284 * @uaddr: Address the user wants the socket bound to.
285 * @addrlen: Length of the uaddr structure.
286 *
287 * Bind a socket to a specific address. For llc a user is able to bind to
288 * a specific sap only or mac + sap. If the user only specifies a sap and
289 * a null dmac (all zeros) the user is attempting to bind to an entire
290 * sap. This will stop anyone else on the local system from using that
291 * sap. If someone else has a mac + sap open the bind to null + sap will
292 * fail.
293 * If the user desires to bind to a specific mac + sap, it is possible to
294 * have multiple sap connections via multiple macs.
295 * Bind and autobind for that matter must enforce the correct sap usage
296 * otherwise all hell will break loose.
297 * Returns: 0 upon success, negative otherwise.
298 */
299static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
300{
301 struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
302 struct sock *sk = sock->sk;
303 struct llc_sock *llc = llc_sk(sk);
304 struct llc_sap *sap;
305 int rc = -EINVAL;
306
307 dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap);
308 if (!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))
309 goto out;
310 rc = -EAFNOSUPPORT;
311 if (addr->sllc_family != AF_LLC)
312 goto out;
313 if (!addr->sllc_sap) {
314 rc = -EUSERS;
315 addr->sllc_sap = llc_ui_autoport();
316 if (!addr->sllc_sap)
317 goto out;
318 }
319 sap = llc_sap_find(addr->sllc_sap);
320 if (!sap) {
321 sap = llc_sap_open(addr->sllc_sap, NULL);
322 rc = -EBUSY; /* some other network layer is using the sap */
323 if (!sap)
324 goto out;
325 } else {
326 struct llc_addr laddr, daddr;
327 struct sock *ask;
328
329 memset(&laddr, 0, sizeof(laddr));
330 memset(&daddr, 0, sizeof(daddr));
331 /*
332 * FIXME: check if the the address is multicast,
333 * only SOCK_DGRAM can do this.
334 */
335 memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN);
336 laddr.lsap = addr->sllc_sap;
337 rc = -EADDRINUSE; /* mac + sap clash. */
338 ask = llc_lookup_established(sap, &daddr, &laddr);
339 if (ask) {
340 sock_put(ask);
341 goto out;
342 }
343 }
344 llc->laddr.lsap = addr->sllc_sap;
345 memcpy(llc->laddr.mac, addr->sllc_mac, IFHWADDRLEN);
346 memcpy(&llc->addr, addr, sizeof(llc->addr));
347 /* assign new connection to its SAP */
348 llc_sap_add_socket(sap, sk);
349 sock_reset_flag(sk, SOCK_ZAPPED);
350 rc = 0;
351out:
352 return rc;
353}
354
355/**
356 * llc_ui_shutdown - shutdown a connect llc2 socket.
357 * @sock: Socket to shutdown.
358 * @how: What part of the socket to shutdown.
359 *
360 * Shutdown a connected llc2 socket. Currently this function only supports
361 * shutting down both sends and receives (2), we could probably make this
362 * function such that a user can shutdown only half the connection but not
363 * right now.
364 * Returns: 0 upon success, negative otherwise.
365 */
366static int llc_ui_shutdown(struct socket *sock, int how)
367{
368 struct sock *sk = sock->sk;
369 int rc = -ENOTCONN;
370
371 lock_sock(sk);
372 if (sk->sk_state != TCP_ESTABLISHED)
373 goto out;
374 rc = -EINVAL;
375 if (how != 2)
376 goto out;
377 rc = llc_send_disc(sk);
378 if (!rc)
379 rc = llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
380 /* Wake up anyone sleeping in poll */
381 sk->sk_state_change(sk);
382out:
383 release_sock(sk);
384 return rc;
385}
386
387/**
388 * llc_ui_connect - Connect to a remote llc2 mac + sap.
389 * @sock: Socket which will be connected to the remote destination.
390 * @uaddr: Remote and possibly the local address of the new connection.
391 * @addrlen: Size of uaddr structure.
392 * @flags: Operational flags specified by the user.
393 *
394 * Connect to a remote llc2 mac + sap. The caller must specify the
395 * destination mac and address to connect to. If the user hasn't previously
396 * called bind(2) with a smac the address of the first interface of the
397 * specified arp type will be used.
398 * This function will autobind if user did not previously call bind.
399 * Returns: 0 upon success, negative otherwise.
400 */
401static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
402 int addrlen, int flags)
403{
404 struct sock *sk = sock->sk;
405 struct llc_sock *llc = llc_sk(sk);
406 struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
407 struct net_device *dev;
408 int rc = -EINVAL;
409
410 lock_sock(sk);
411 if (addrlen != sizeof(*addr))
412 goto out;
413 rc = -EAFNOSUPPORT;
414 if (addr->sllc_family != AF_LLC)
415 goto out;
416 /* bind connection to sap if user hasn't done it. */
417 if (sock_flag(sk, SOCK_ZAPPED)) {
418 /* bind to sap with null dev, exclusive */
419 rc = llc_ui_autobind(sock, addr);
420 if (rc)
421 goto out;
422 llc->daddr.lsap = addr->sllc_sap;
423 memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
424 }
425 dev = llc->dev;
426 if (sk->sk_type != SOCK_STREAM)
427 goto out;
428 rc = -EALREADY;
429 if (sock->state == SS_CONNECTING)
430 goto out;
431 sock->state = SS_CONNECTING;
432 sk->sk_state = TCP_SYN_SENT;
433 llc->link = llc_ui_next_link_no(llc->sap->laddr.lsap);
434 rc = llc_establish_connection(sk, dev->dev_addr,
435 addr->sllc_mac, addr->sllc_sap);
436 if (rc) {
437 dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__);
438 sock->state = SS_UNCONNECTED;
439 sk->sk_state = TCP_CLOSE;
440 goto out;
441 }
442 rc = llc_ui_wait_for_conn(sk, sk->sk_rcvtimeo);
443 if (rc)
444 dprintk("%s: llc_ui_wait_for_conn failed=%d\n", __FUNCTION__, rc);
445out:
446 release_sock(sk);
447 return rc;
448}
449
450/**
451 * llc_ui_listen - allow a normal socket to accept incoming connections
452 * @sock: Socket to allow incoming connections on.
453 * @backlog: Number of connections to queue.
454 *
455 * Allow a normal socket to accept incoming connections.
456 * Returns 0 upon success, negative otherwise.
457 */
458static int llc_ui_listen(struct socket *sock, int backlog)
459{
460 struct sock *sk = sock->sk;
461 int rc = -EINVAL;
462
463 lock_sock(sk);
464 if (sock->state != SS_UNCONNECTED)
465 goto out;
466 rc = -EOPNOTSUPP;
467 if (sk->sk_type != SOCK_STREAM)
468 goto out;
469 rc = -EAGAIN;
470 if (sock_flag(sk, SOCK_ZAPPED))
471 goto out;
472 rc = 0;
473 if (!(unsigned)backlog) /* BSDism */
474 backlog = 1;
475 sk->sk_max_ack_backlog = backlog;
476 if (sk->sk_state != TCP_LISTEN) {
477 sk->sk_ack_backlog = 0;
478 sk->sk_state = TCP_LISTEN;
479 }
480 sk->sk_socket->flags |= __SO_ACCEPTCON;
481out:
482 release_sock(sk);
483 return rc;
484}
485
486static int llc_ui_wait_for_disc(struct sock *sk, int timeout)
487{
488 DECLARE_WAITQUEUE(wait, current);
489 int rc;
490
491 add_wait_queue_exclusive(sk->sk_sleep, &wait);
492 for (;;) {
493 __set_current_state(TASK_INTERRUPTIBLE);
494 rc = 0;
495 if (sk->sk_state != TCP_CLOSE) {
496 release_sock(sk);
497 timeout = schedule_timeout(timeout);
498 lock_sock(sk);
499 } else
500 break;
501 rc = -ERESTARTSYS;
502 if (signal_pending(current))
503 break;
504 rc = -EAGAIN;
505 if (!timeout)
506 break;
507 }
508 __set_current_state(TASK_RUNNING);
509 remove_wait_queue(sk->sk_sleep, &wait);
510 return rc;
511}
512
513static int llc_ui_wait_for_conn(struct sock *sk, int timeout)
514{
515 DECLARE_WAITQUEUE(wait, current);
516 int rc;
517
518 add_wait_queue_exclusive(sk->sk_sleep, &wait);
519 for (;;) {
520 __set_current_state(TASK_INTERRUPTIBLE);
521 rc = -EAGAIN;
522 if (sk->sk_state == TCP_CLOSE)
523 break;
524 rc = 0;
525 if (sk->sk_state != TCP_ESTABLISHED) {
526 release_sock(sk);
527 timeout = schedule_timeout(timeout);
528 lock_sock(sk);
529 } else
530 break;
531 rc = -ERESTARTSYS;
532 if (signal_pending(current))
533 break;
534 rc = -EAGAIN;
535 if (!timeout)
536 break;
537 }
538 __set_current_state(TASK_RUNNING);
539 remove_wait_queue(sk->sk_sleep, &wait);
540 return rc;
541}
542
543static int llc_ui_wait_for_data(struct sock *sk, int timeout)
544{
545 DECLARE_WAITQUEUE(wait, current);
546 int rc = 0;
547
548 add_wait_queue_exclusive(sk->sk_sleep, &wait);
549 for (;;) {
550 __set_current_state(TASK_INTERRUPTIBLE);
551 if (sk->sk_shutdown & RCV_SHUTDOWN)
552 break;
553 /*
554 * Well, if we have backlog, try to process it now.
555 */
556 if (sk->sk_backlog.tail) {
557 release_sock(sk);
558 lock_sock(sk);
559 }
560 rc = 0;
561 if (skb_queue_empty(&sk->sk_receive_queue)) {
562 release_sock(sk);
563 timeout = schedule_timeout(timeout);
564 lock_sock(sk);
565 } else
566 break;
567 rc = -ERESTARTSYS;
568 if (signal_pending(current))
569 break;
570 rc = -EAGAIN;
571 if (!timeout)
572 break;
573 }
574 __set_current_state(TASK_RUNNING);
575 remove_wait_queue(sk->sk_sleep, &wait);
576 return rc;
577}
578
579static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout)
580{
581 DECLARE_WAITQUEUE(wait, current);
582 struct llc_sock *llc = llc_sk(sk);
583 int rc;
584
585 add_wait_queue_exclusive(sk->sk_sleep, &wait);
586 for (;;) {
587 dprintk("%s: looping...\n", __FUNCTION__);
588 __set_current_state(TASK_INTERRUPTIBLE);
589 rc = -ENOTCONN;
590 if (sk->sk_shutdown & RCV_SHUTDOWN)
591 break;
592 rc = 0;
593 if (llc_data_accept_state(llc->state) || llc->p_flag) {
594 release_sock(sk);
595 timeout = schedule_timeout(timeout);
596 lock_sock(sk);
597 } else
598 break;
599 rc = -ERESTARTSYS;
600 if (signal_pending(current))
601 break;
602 rc = -EAGAIN;
603 if (!timeout)
604 break;
605 }
606 __set_current_state(TASK_RUNNING);
607 remove_wait_queue(sk->sk_sleep, &wait);
608 return rc;
609}
610
611/**
612 * llc_ui_accept - accept a new incoming connection.
613 * @sock: Socket which connections arrive on.
614 * @newsock: Socket to move incoming connection to.
615 * @flags: User specified operational flags.
616 *
617 * Accept a new incoming connection.
618 * Returns 0 upon success, negative otherwise.
619 */
620static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
621{
622 struct sock *sk = sock->sk, *newsk;
623 struct llc_sock *llc, *newllc;
624 struct sk_buff *skb;
625 int rc = -EOPNOTSUPP;
626
627 dprintk("%s: accepting on %02X\n", __FUNCTION__,
628 llc_sk(sk)->laddr.lsap);
629 lock_sock(sk);
630 if (sk->sk_type != SOCK_STREAM)
631 goto out;
632 rc = -EINVAL;
633 if (sock->state != SS_UNCONNECTED || sk->sk_state != TCP_LISTEN)
634 goto out;
635 /* wait for a connection to arrive. */
636 rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo);
637 if (rc)
638 goto out;
639 dprintk("%s: got a new connection on %02X\n", __FUNCTION__,
640 llc_sk(sk)->laddr.lsap);
641 skb = skb_dequeue(&sk->sk_receive_queue);
642 rc = -EINVAL;
643 if (!skb->sk)
644 goto frees;
645 rc = 0;
646 newsk = skb->sk;
647 /* attach connection to a new socket. */
648 llc_ui_sk_init(newsock, newsk);
649 sock_reset_flag(newsk, SOCK_ZAPPED);
650 newsk->sk_state = TCP_ESTABLISHED;
651 newsock->state = SS_CONNECTED;
652 llc = llc_sk(sk);
653 newllc = llc_sk(newsk);
654 memcpy(&newllc->addr, &llc->addr, sizeof(newllc->addr));
655 newllc->link = llc_ui_next_link_no(newllc->laddr.lsap);
656
657 /* put original socket back into a clean listen state. */
658 sk->sk_state = TCP_LISTEN;
659 sk->sk_ack_backlog--;
660 skb->sk = NULL;
661 dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
662 llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
663frees:
664 kfree_skb(skb);
665out:
666 release_sock(sk);
667 return rc;
668}
669
670/**
671 * llc_ui_recvmsg - copy received data to the socket user.
672 * @sock: Socket to copy data from.
673 * @msg: Various user space related information.
674 * @size: Size of user buffer.
675 * @flags: User specified flags.
676 *
677 * Copy received data to the socket user.
678 * Returns non-negative upon success, negative otherwise.
679 */
680static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
681 struct msghdr *msg, size_t size, int flags)
682{
683 struct sock *sk = sock->sk;
684 struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;
685 struct sk_buff *skb;
686 size_t copied = 0;
687 int rc = -ENOMEM, timeout;
688 int noblock = flags & MSG_DONTWAIT;
689
690 dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__,
691 llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
692 lock_sock(sk);
693 timeout = sock_rcvtimeo(sk, noblock);
694 rc = llc_ui_wait_for_data(sk, timeout);
695 if (rc) {
696 dprintk("%s: llc_ui_wait_for_data failed recv "
697 "in %02X from %02X\n", __FUNCTION__,
698 llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
699 goto out;
700 }
701 skb = skb_dequeue(&sk->sk_receive_queue);
702 if (!skb) /* shutdown */
703 goto out;
704 copied = skb->len;
705 if (copied > size)
706 copied = size;
707 rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
708 if (rc)
709 goto dgram_free;
710 if (skb->len > copied) {
711 skb_pull(skb, copied);
712 skb_queue_head(&sk->sk_receive_queue, skb);
713 }
714 if (uaddr)
715 memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
716 msg->msg_namelen = sizeof(*uaddr);
717 if (!skb->list) {
718dgram_free:
719 kfree_skb(skb);
720 }
721out:
722 release_sock(sk);
723 return rc ? : copied;
724}
725
726/**
727 * llc_ui_sendmsg - Transmit data provided by the socket user.
728 * @sock: Socket to transmit data from.
729 * @msg: Various user related information.
730 * @len: Length of data to transmit.
731 *
732 * Transmit data provided by the socket user.
733 * Returns non-negative upon success, negative otherwise.
734 */
735static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
736 struct msghdr *msg, size_t len)
737{
738 struct sock *sk = sock->sk;
739 struct llc_sock *llc = llc_sk(sk);
740 struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name;
741 int flags = msg->msg_flags;
742 int noblock = flags & MSG_DONTWAIT;
743 struct net_device *dev;
744 struct sk_buff *skb;
745 size_t size = 0;
746 int rc = -EINVAL, copied = 0, hdrlen;
747
748 dprintk("%s: sending from %02X to %02X\n", __FUNCTION__,
749 llc->laddr.lsap, llc->daddr.lsap);
750 lock_sock(sk);
751 if (addr) {
752 if (msg->msg_namelen < sizeof(*addr))
753 goto release;
754 } else {
755 if (llc_ui_addr_null(&llc->addr))
756 goto release;
757 addr = &llc->addr;
758 }
759 /* must bind connection to sap if user hasn't done it. */
760 if (sock_flag(sk, SOCK_ZAPPED)) {
761 /* bind to sap with null dev, exclusive. */
762 rc = llc_ui_autobind(sock, addr);
763 if (rc)
764 goto release;
765 }
766 dev = llc->dev;
767 hdrlen = dev->hard_header_len + llc_ui_header_len(sk, addr);
768 size = hdrlen + len;
769 if (size > dev->mtu)
770 size = dev->mtu;
771 copied = size - hdrlen;
772 release_sock(sk);
773 skb = sock_alloc_send_skb(sk, size, noblock, &rc);
774 lock_sock(sk);
775 if (!skb)
776 goto release;
777 skb->sk = sk;
778 skb->dev = dev;
779 skb->protocol = llc_proto_type(addr->sllc_arphrd);
780 skb_reserve(skb, hdrlen);
781 rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied);
782 if (rc)
783 goto out;
784 if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
785 llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_mac,
786 addr->sllc_sap);
787 goto out;
788 }
789 if (addr->sllc_test) {
790 llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_mac,
791 addr->sllc_sap);
792 goto out;
793 }
794 if (addr->sllc_xid) {
795 llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_mac,
796 addr->sllc_sap);
797 goto out;
798 }
799 rc = -ENOPROTOOPT;
800 if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua))
801 goto out;
802 rc = llc_ui_send_data(sk, skb, noblock);
803 if (rc)
804 dprintk("%s: llc_ui_send_data failed: %d\n", __FUNCTION__, rc);
805out:
806 if (rc)
807 kfree_skb(skb);
808release:
809 if (rc)
810 dprintk("%s: failed sending from %02X to %02X: %d\n",
811 __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc);
812 release_sock(sk);
813 return rc ? : copied;
814}
815
816/**
817 * llc_ui_getname - return the address info of a socket
818 * @sock: Socket to get address of.
819 * @uaddr: Address structure to return information.
820 * @uaddrlen: Length of address structure.
821 * @peer: Does user want local or remote address information.
822 *
823 * Return the address information of a socket.
824 */
825static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
826 int *uaddrlen, int peer)
827{
828 struct sockaddr_llc sllc;
829 struct sock *sk = sock->sk;
830 struct llc_sock *llc = llc_sk(sk);
831 int rc = 0;
832
833 lock_sock(sk);
834 if (sock_flag(sk, SOCK_ZAPPED))
835 goto out;
836 *uaddrlen = sizeof(sllc);
837 memset(uaddr, 0, *uaddrlen);
838 if (peer) {
839 rc = -ENOTCONN;
840 if (sk->sk_state != TCP_ESTABLISHED)
841 goto out;
842 if(llc->dev)
843 sllc.sllc_arphrd = llc->dev->type;
844 sllc.sllc_sap = llc->daddr.lsap;
845 memcpy(&sllc.sllc_mac, &llc->daddr.mac, IFHWADDRLEN);
846 } else {
847 rc = -EINVAL;
848 if (!llc->sap)
849 goto out;
850 sllc.sllc_sap = llc->sap->laddr.lsap;
851
852 if (llc->dev) {
853 sllc.sllc_arphrd = llc->dev->type;
854 memcpy(&sllc.sllc_mac, &llc->dev->dev_addr,
855 IFHWADDRLEN);
856 }
857 }
858 rc = 0;
859 sllc.sllc_family = AF_LLC;
860 memcpy(uaddr, &sllc, sizeof(sllc));
861out:
862 release_sock(sk);
863 return rc;
864}
865
866/**
867 * llc_ui_ioctl - io controls for PF_LLC
868 * @sock: Socket to get/set info
869 * @cmd: command
870 * @arg: optional argument for cmd
871 *
872 * get/set info on llc sockets
873 */
874static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
875 unsigned long arg)
876{
877 return dev_ioctl(cmd, (void __user *)arg);
878}
879
880/**
881 * llc_ui_setsockopt - set various connection specific parameters.
882 * @sock: Socket to set options on.
883 * @level: Socket level user is requesting operations on.
884 * @optname: Operation name.
885 * @optval User provided operation data.
886 * @optlen: Length of optval.
887 *
888 * Set various connection specific parameters.
889 */
890static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
891 char __user *optval, int optlen)
892{
893 struct sock *sk = sock->sk;
894 struct llc_sock *llc = llc_sk(sk);
895 int rc = -EINVAL, opt;
896
897 lock_sock(sk);
898 if (level != SOL_LLC || optlen != sizeof(int))
899 goto out;
900 rc = get_user(opt, (int __user *)optval);
901 if (rc)
902 goto out;
903 rc = -EINVAL;
904 switch (optname) {
905 case LLC_OPT_RETRY:
906 if (opt > LLC_OPT_MAX_RETRY)
907 goto out;
908 llc->n2 = opt;
909 break;
910 case LLC_OPT_SIZE:
911 if (opt > LLC_OPT_MAX_SIZE)
912 goto out;
913 llc->n1 = opt;
914 break;
915 case LLC_OPT_ACK_TMR_EXP:
916 if (opt > LLC_OPT_MAX_ACK_TMR_EXP)
917 goto out;
918 llc->ack_timer.expire = opt;
919 break;
920 case LLC_OPT_P_TMR_EXP:
921 if (opt > LLC_OPT_MAX_P_TMR_EXP)
922 goto out;
923 llc->pf_cycle_timer.expire = opt;
924 break;
925 case LLC_OPT_REJ_TMR_EXP:
926 if (opt > LLC_OPT_MAX_REJ_TMR_EXP)
927 goto out;
928 llc->rej_sent_timer.expire = opt;
929 break;
930 case LLC_OPT_BUSY_TMR_EXP:
931 if (opt > LLC_OPT_MAX_BUSY_TMR_EXP)
932 goto out;
933 llc->busy_state_timer.expire = opt;
934 break;
935 case LLC_OPT_TX_WIN:
936 if (opt > LLC_OPT_MAX_WIN)
937 goto out;
938 llc->k = opt;
939 break;
940 case LLC_OPT_RX_WIN:
941 if (opt > LLC_OPT_MAX_WIN)
942 goto out;
943 llc->rw = opt;
944 break;
945 default:
946 rc = -ENOPROTOOPT;
947 goto out;
948 }
949 rc = 0;
950out:
951 release_sock(sk);
952 return rc;
953}
954
955/**
956 * llc_ui_getsockopt - get connection specific socket info
957 * @sock: Socket to get information from.
958 * @level: Socket level user is requesting operations on.
959 * @optname: Operation name.
960 * @optval: Variable to return operation data in.
961 * @optlen: Length of optval.
962 *
963 * Get connection specific socket information.
964 */
965static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
966 char __user *optval, int __user *optlen)
967{
968 struct sock *sk = sock->sk;
969 struct llc_sock *llc = llc_sk(sk);
970 int val = 0, len = 0, rc = -EINVAL;
971
972 lock_sock(sk);
973 if (level != SOL_LLC)
974 goto out;
975 rc = get_user(len, optlen);
976 if (rc)
977 goto out;
978 rc = -EINVAL;
979 if (len != sizeof(int))
980 goto out;
981 switch (optname) {
982 case LLC_OPT_RETRY:
983 val = llc->n2; break;
984 case LLC_OPT_SIZE:
985 val = llc->n1; break;
986 case LLC_OPT_ACK_TMR_EXP:
987 val = llc->ack_timer.expire; break;
988 case LLC_OPT_P_TMR_EXP:
989 val = llc->pf_cycle_timer.expire; break;
990 case LLC_OPT_REJ_TMR_EXP:
991 val = llc->rej_sent_timer.expire; break;
992 case LLC_OPT_BUSY_TMR_EXP:
993 val = llc->busy_state_timer.expire; break;
994 case LLC_OPT_TX_WIN:
995 val = llc->k; break;
996 case LLC_OPT_RX_WIN:
997 val = llc->rw; break;
998 default:
999 rc = -ENOPROTOOPT;
1000 goto out;
1001 }
1002 rc = 0;
1003 if (put_user(len, optlen) || copy_to_user(optval, &val, len))
1004 rc = -EFAULT;
1005out:
1006 release_sock(sk);
1007 return rc;
1008}
1009
1010static struct net_proto_family llc_ui_family_ops = {
1011 .family = PF_LLC,
1012 .create = llc_ui_create,
1013 .owner = THIS_MODULE,
1014};
1015
1016static struct proto_ops llc_ui_ops = {
1017 .family = PF_LLC,
1018 .owner = THIS_MODULE,
1019 .release = llc_ui_release,
1020 .bind = llc_ui_bind,
1021 .connect = llc_ui_connect,
1022 .socketpair = sock_no_socketpair,
1023 .accept = llc_ui_accept,
1024 .getname = llc_ui_getname,
1025 .poll = datagram_poll,
1026 .ioctl = llc_ui_ioctl,
1027 .listen = llc_ui_listen,
1028 .shutdown = llc_ui_shutdown,
1029 .setsockopt = llc_ui_setsockopt,
1030 .getsockopt = llc_ui_getsockopt,
1031 .sendmsg = llc_ui_sendmsg,
1032 .recvmsg = llc_ui_recvmsg,
1033 .mmap = sock_no_mmap,
1034 .sendpage = sock_no_sendpage,
1035};
1036
1037extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
1038extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
1039
1040static int __init llc2_init(void)
1041{
1042 int rc = proto_register(&llc_proto, 0);
1043
1044 if (rc != 0)
1045 goto out;
1046
1047 llc_build_offset_table();
1048 llc_station_init();
1049 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
1050 rc = llc_proc_init();
1051 if (rc != 0)
1052 goto out_unregister_llc_proto;
1053 sock_register(&llc_ui_family_ops);
1054 llc_add_pack(LLC_DEST_SAP, llc_sap_handler);
1055 llc_add_pack(LLC_DEST_CONN, llc_conn_handler);
1056out:
1057 return rc;
1058out_unregister_llc_proto:
1059 proto_unregister(&llc_proto);
1060 goto out;
1061}
1062
1063static void __exit llc2_exit(void)
1064{
1065 llc_station_exit();
1066 llc_remove_pack(LLC_DEST_SAP);
1067 llc_remove_pack(LLC_DEST_CONN);
1068 sock_unregister(PF_LLC);
1069 llc_proc_exit();
1070 proto_unregister(&llc_proto);
1071}
1072
1073module_init(llc2_init);
1074module_exit(llc2_exit);
1075
1076MODULE_LICENSE("GPL");
1077MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
1078MODULE_DESCRIPTION("IEEE 802.2 PF_LLC support");
1079MODULE_ALIAS_NETPROTO(PF_LLC);
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
new file mode 100644
index 000000000000..b218be4c10ec
--- /dev/null
+++ b/net/llc/llc_c_ac.c
@@ -0,0 +1,1514 @@
1/*
2 * llc_c_ac.c - actions performed during connection state transition.
3 *
4 * Description:
5 * Functions in this module are implementation of connection component actions
6 * Details of actions can be found in IEEE-802.2 standard document.
7 * All functions have one connection and one event as input argument. All of
8 * them return 0 On success and 1 otherwise.
9 *
10 * Copyright (c) 1997 by Procom Technology, Inc.
11 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
12 *
13 * This program can be redistributed or modified under the terms of the
14 * GNU General Public License as published by the Free Software Foundation.
15 * This program is distributed without any warranty or implied warranty
16 * of merchantability or fitness for a particular purpose.
17 *
18 * See the GNU General Public License for more details.
19 */
20#include <linux/netdevice.h>
21#include <net/llc_conn.h>
22#include <net/llc_sap.h>
23#include <net/sock.h>
24#include <net/llc_c_ev.h>
25#include <net/llc_c_ac.h>
26#include <net/llc_c_st.h>
27#include <net/llc_pdu.h>
28#include <net/llc.h>
29
30#include "llc_output.h"
31
32static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb);
33static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb);
34static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *ev);
35
36static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb);
37
38static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
39 struct sk_buff *skb);
40
41static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb);
42
43#define INCORRECT 0
44
45int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb)
46{
47 struct llc_sock *llc = llc_sk(sk);
48
49 if (llc->remote_busy_flag) {
50 u8 nr;
51 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
52
53 llc->remote_busy_flag = 0;
54 del_timer(&llc->busy_state_timer.timer);
55 nr = LLC_I_GET_NR(pdu);
56 llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
57 }
58 return 0;
59}
60
61int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
62{
63 int rc = -ENOTCONN;
64 u8 dsap;
65 struct llc_sap *sap;
66
67 llc_pdu_decode_dsap(skb, &dsap);
68 sap = llc_sap_find(dsap);
69 if (sap) {
70 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
71 struct llc_sock *llc = llc_sk(sk);
72
73 llc_pdu_decode_sa(skb, llc->daddr.mac);
74 llc_pdu_decode_da(skb, llc->laddr.mac);
75 llc->dev = skb->dev;
76 ev->ind_prim = LLC_CONN_PRIM;
77 rc = 0;
78 }
79 return rc;
80}
81
82int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
83{
84 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
85
86 ev->cfm_prim = LLC_CONN_PRIM;
87 return 0;
88}
89
90static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb)
91{
92 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
93
94 ev->cfm_prim = LLC_DATA_PRIM;
95 return 0;
96}
97
98int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb)
99{
100 llc_conn_rtn_pdu(sk, skb);
101 return 0;
102}
103
104int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb)
105{
106 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
107 u8 reason = 0;
108 int rc = 0;
109
110 if (ev->type == LLC_CONN_EV_TYPE_PDU) {
111 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
112
113 if (LLC_PDU_IS_RSP(pdu) &&
114 LLC_PDU_TYPE_IS_U(pdu) &&
115 LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM)
116 reason = LLC_DISC_REASON_RX_DM_RSP_PDU;
117 else if (LLC_PDU_IS_CMD(pdu) &&
118 LLC_PDU_TYPE_IS_U(pdu) &&
119 LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC)
120 reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
121 } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)
122 reason = LLC_DISC_REASON_ACK_TMR_EXP;
123 else {
124 reason = 0;
125 rc = -EINVAL;
126 }
127 if (!rc) {
128 ev->reason = reason;
129 ev->ind_prim = LLC_DISC_PRIM;
130 }
131 return rc;
132}
133
134int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb)
135{
136 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
137
138 ev->reason = ev->status;
139 ev->cfm_prim = LLC_DISC_PRIM;
140 return 0;
141}
142
143int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
144{
145 u8 reason = 0;
146 int rc = 1;
147 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
148 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
149 struct llc_sock *llc = llc_sk(sk);
150
151 switch (ev->type) {
152 case LLC_CONN_EV_TYPE_PDU:
153 if (LLC_PDU_IS_RSP(pdu) &&
154 LLC_PDU_TYPE_IS_U(pdu) &&
155 LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR) {
156 reason = LLC_RESET_REASON_LOCAL;
157 rc = 0;
158 } else if (LLC_PDU_IS_CMD(pdu) &&
159 LLC_PDU_TYPE_IS_U(pdu) &&
160 LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) {
161 reason = LLC_RESET_REASON_REMOTE;
162 rc = 0;
163 } else {
164 reason = 0;
165 rc = 1;
166 }
167 break;
168 case LLC_CONN_EV_TYPE_ACK_TMR:
169 case LLC_CONN_EV_TYPE_P_TMR:
170 case LLC_CONN_EV_TYPE_REJ_TMR:
171 case LLC_CONN_EV_TYPE_BUSY_TMR:
172 if (llc->retry_count > llc->n2) {
173 reason = LLC_RESET_REASON_LOCAL;
174 rc = 0;
175 } else
176 rc = 1;
177 break;
178 }
179 if (!rc) {
180 ev->reason = reason;
181 ev->ind_prim = LLC_RESET_PRIM;
182 }
183 return rc;
184}
185
186int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb)
187{
188 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
189
190 ev->reason = 0;
191 ev->cfm_prim = LLC_RESET_PRIM;
192 return 0;
193}
194
195int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
196 struct sk_buff *skb)
197{
198 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
199
200 if (LLC_PDU_IS_RSP(pdu) &&
201 LLC_PDU_TYPE_IS_I(pdu) &&
202 LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf)
203 llc_conn_ac_clear_remote_busy(sk, skb);
204 return 0;
205}
206
207int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
208 struct sk_buff *skb)
209{
210 struct llc_sock *llc = llc_sk(sk);
211
212 if (llc->data_flag == 2)
213 del_timer(&llc->rej_sent_timer.timer);
214 return 0;
215}
216
217int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
218{
219 int rc = -ENOBUFS;
220 struct sk_buff *nskb = llc_alloc_frame();
221
222 if (nskb) {
223 struct llc_sock *llc = llc_sk(sk);
224 struct llc_sap *sap = llc->sap;
225
226 nskb->dev = llc->dev;
227 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
228 llc->daddr.lsap, LLC_PDU_CMD);
229 llc_pdu_init_as_disc_cmd(nskb, 1);
230 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
231 if (rc)
232 goto free;
233 llc_conn_send_pdu(sk, nskb);
234 llc_conn_ac_set_p_flag_1(sk, skb);
235 }
236out:
237 return rc;
238free:
239 kfree_skb(nskb);
240 goto out;
241}
242
243int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
244{
245 int rc = -ENOBUFS;
246 struct sk_buff *nskb = llc_alloc_frame();
247
248 if (nskb) {
249 struct llc_sock *llc = llc_sk(sk);
250 struct llc_sap *sap = llc->sap;
251 u8 f_bit;
252
253 nskb->dev = llc->dev;
254 llc_pdu_decode_pf_bit(skb, &f_bit);
255 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
256 llc->daddr.lsap, LLC_PDU_RSP);
257 llc_pdu_init_as_dm_rsp(nskb, f_bit);
258 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
259 if (rc)
260 goto free;
261 llc_conn_send_pdu(sk, nskb);
262 }
263out:
264 return rc;
265free:
266 kfree_skb(nskb);
267 goto out;
268}
269
270int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
271{
272 int rc = -ENOBUFS;
273 struct sk_buff *nskb = llc_alloc_frame();
274
275 if (nskb) {
276 struct llc_sock *llc = llc_sk(sk);
277 struct llc_sap *sap = llc->sap;
278 u8 f_bit = 1;
279
280 nskb->dev = llc->dev;
281 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
282 llc->daddr.lsap, LLC_PDU_RSP);
283 llc_pdu_init_as_dm_rsp(nskb, f_bit);
284 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
285 if (rc)
286 goto free;
287 llc_conn_send_pdu(sk, nskb);
288 }
289out:
290 return rc;
291free:
292 kfree_skb(nskb);
293 goto out;
294}
295
296int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
297{
298 u8 f_bit;
299 int rc = -ENOBUFS;
300 struct sk_buff *nskb;
301 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
302 struct llc_sock *llc = llc_sk(sk);
303
304 llc->rx_pdu_hdr = *((u32 *)pdu);
305 if (LLC_PDU_IS_CMD(pdu))
306 llc_pdu_decode_pf_bit(skb, &f_bit);
307 else
308 f_bit = 0;
309 nskb = llc_alloc_frame();
310 if (nskb) {
311 struct llc_sap *sap = llc->sap;
312
313 nskb->dev = llc->dev;
314 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
315 llc->daddr.lsap, LLC_PDU_RSP);
316 llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
317 llc->vR, INCORRECT);
318 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
319 if (rc)
320 goto free;
321 llc_conn_send_pdu(sk, nskb);
322 }
323out:
324 return rc;
325free:
326 kfree_skb(nskb);
327 goto out;
328}
329
330int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
331{
332 int rc = -ENOBUFS;
333 struct sk_buff *nskb = llc_alloc_frame();
334
335 if (nskb) {
336 u8 f_bit = 0;
337 struct llc_sock *llc = llc_sk(sk);
338 struct llc_sap *sap = llc->sap;
339 struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;
340
341 nskb->dev = llc->dev;
342 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
343 llc->daddr.lsap, LLC_PDU_RSP);
344 llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
345 llc->vR, INCORRECT);
346 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
347 if (rc)
348 goto free;
349 llc_conn_send_pdu(sk, nskb);
350 }
351out:
352 return rc;
353free:
354 kfree_skb(nskb);
355 goto out;
356}
357
358int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
359{
360 u8 f_bit;
361 int rc = -ENOBUFS;
362 struct sk_buff *nskb;
363
364 llc_pdu_decode_pf_bit(skb, &f_bit);
365 nskb = llc_alloc_frame();
366 if (nskb) {
367 struct llc_sock *llc = llc_sk(sk);
368 struct llc_sap *sap = llc->sap;
369 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
370
371 nskb->dev = llc->dev;
372 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
373 llc->daddr.lsap, LLC_PDU_RSP);
374 llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
375 llc->vR, INCORRECT);
376 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
377 if (rc)
378 goto free;
379 llc_conn_send_pdu(sk, nskb);
380 }
381out:
382 return rc;
383free:
384 kfree_skb(nskb);
385 goto out;
386}
387
388int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
389{
390 int rc;
391 struct llc_sock *llc = llc_sk(sk);
392 struct llc_sap *sap = llc->sap;
393
394 llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
395 llc->daddr.lsap, LLC_PDU_CMD);
396 llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
397 rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
398 if (!rc) {
399 llc_conn_send_pdu(sk, skb);
400 llc_conn_ac_inc_vs_by_1(sk, skb);
401 }
402 return rc;
403}
404
405static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
406{
407 int rc;
408 struct llc_sock *llc = llc_sk(sk);
409 struct llc_sap *sap = llc->sap;
410
411 llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
412 llc->daddr.lsap, LLC_PDU_CMD);
413 llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
414 rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
415 if (!rc) {
416 llc_conn_send_pdu(sk, skb);
417 llc_conn_ac_inc_vs_by_1(sk, skb);
418 }
419 return rc;
420}
421
422int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
423{
424 int rc;
425 struct llc_sock *llc = llc_sk(sk);
426 struct llc_sap *sap = llc->sap;
427
428 llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
429 llc->daddr.lsap, LLC_PDU_CMD);
430 llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
431 rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
432 if (!rc) {
433 llc_conn_send_pdu(sk, skb);
434 llc_conn_ac_inc_vs_by_1(sk, skb);
435 }
436 return 0;
437}
438
439int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
440{
441 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
442 u8 nr = LLC_I_GET_NR(pdu);
443
444 llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
445 return 0;
446}
447
448int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
449 struct sk_buff *skb)
450{
451 u8 nr;
452 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
453 int rc = -ENOBUFS;
454 struct sk_buff *nskb = llc_alloc_frame();
455
456 if (nskb) {
457 struct llc_sock *llc = llc_sk(sk);
458 struct llc_sap *sap = llc->sap;
459
460 nskb->dev = llc->dev;
461 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
462 llc->daddr.lsap, LLC_PDU_RSP);
463 llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
464 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
465 if (!rc)
466 llc_conn_send_pdu(sk, nskb);
467 else
468 kfree_skb(skb);
469 }
470 if (rc) {
471 nr = LLC_I_GET_NR(pdu);
472 rc = 0;
473 llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
474 }
475 return rc;
476}
477
478int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
479{
480 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
481 u8 nr = LLC_I_GET_NR(pdu);
482
483 llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);
484 return 0;
485}
486
487int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
488{
489 int rc = -ENOBUFS;
490 struct sk_buff *nskb = llc_alloc_frame();
491
492 if (nskb) {
493 struct llc_sock *llc = llc_sk(sk);
494 struct llc_sap *sap = llc->sap;
495
496 nskb->dev = llc->dev;
497 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
498 llc->daddr.lsap, LLC_PDU_CMD);
499 llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
500 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
501 if (rc)
502 goto free;
503 llc_conn_send_pdu(sk, nskb);
504 }
505out:
506 return rc;
507free:
508 kfree_skb(nskb);
509 goto out;
510}
511
512int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
513{
514 int rc = -ENOBUFS;
515 struct sk_buff *nskb = llc_alloc_frame();
516
517 if (nskb) {
518 u8 f_bit = 1;
519 struct llc_sock *llc = llc_sk(sk);
520 struct llc_sap *sap = llc->sap;
521
522 nskb->dev = llc->dev;
523 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
524 llc->daddr.lsap, LLC_PDU_RSP);
525 llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
526 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
527 if (rc)
528 goto free;
529 llc_conn_send_pdu(sk, nskb);
530 }
531out:
532 return rc;
533free:
534 kfree_skb(nskb);
535 goto out;
536}
537
538int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
539{
540 int rc = -ENOBUFS;
541 struct sk_buff *nskb = llc_alloc_frame();
542
543 if (nskb) {
544 struct llc_sock *llc = llc_sk(sk);
545 struct llc_sap *sap = llc->sap;
546 u8 f_bit = 0;
547
548 nskb->dev = llc->dev;
549 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
550 llc->daddr.lsap, LLC_PDU_RSP);
551 llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
552 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
553 if (rc)
554 goto free;
555 llc_conn_send_pdu(sk, nskb);
556 }
557out:
558 return rc;
559free:
560 kfree_skb(nskb);
561 goto out;
562}
563
564int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
565{
566 int rc = -ENOBUFS;
567 struct sk_buff *nskb = llc_alloc_frame();
568
569 if (nskb) {
570 struct llc_sock *llc = llc_sk(sk);
571 struct llc_sap *sap = llc->sap;
572
573 nskb->dev = llc->dev;
574 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
575 llc->daddr.lsap, LLC_PDU_CMD);
576 llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
577 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
578 if (rc)
579 goto free;
580 llc_conn_send_pdu(sk, nskb);
581 }
582out:
583 return rc;
584free:
585 kfree_skb(nskb);
586 goto out;
587}
588
589int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
590{
591 int rc = -ENOBUFS;
592 struct sk_buff *nskb = llc_alloc_frame();
593
594 if (nskb) {
595 struct llc_sock *llc = llc_sk(sk);
596 struct llc_sap *sap = llc->sap;
597 u8 f_bit = 1;
598
599 nskb->dev = llc->dev;
600 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
601 llc->daddr.lsap, LLC_PDU_RSP);
602 llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
603 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
604 if (rc)
605 goto free;
606 llc_conn_send_pdu(sk, nskb);
607 }
608out:
609 return rc;
610free:
611 kfree_skb(nskb);
612 goto out;
613}
614
615int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
616{
617 int rc = -ENOBUFS;
618 struct sk_buff *nskb = llc_alloc_frame();
619
620 if (nskb) {
621 u8 f_bit = 0;
622 struct llc_sock *llc = llc_sk(sk);
623 struct llc_sap *sap = llc->sap;
624
625 nskb->dev = llc->dev;
626 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
627 llc->daddr.lsap, LLC_PDU_RSP);
628 llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
629 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
630 if (rc)
631 goto free;
632 llc_conn_send_pdu(sk, nskb);
633 }
634out:
635 return rc;
636free:
637 kfree_skb(nskb);
638 goto out;
639}
640
641int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
642{
643 struct llc_sock *llc = llc_sk(sk);
644
645 if (!llc->remote_busy_flag) {
646 llc->remote_busy_flag = 1;
647 mod_timer(&llc->busy_state_timer.timer,
648 jiffies + llc->busy_state_timer.expire * HZ);
649 }
650 return 0;
651}
652
653int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
654{
655 int rc = -ENOBUFS;
656 struct sk_buff *nskb = llc_alloc_frame();
657
658 if (nskb) {
659 struct llc_sock *llc = llc_sk(sk);
660 struct llc_sap *sap = llc->sap;
661
662 nskb->dev = llc->dev;
663 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
664 llc->daddr.lsap, LLC_PDU_RSP);
665 llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
666 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
667 if (rc)
668 goto free;
669 llc_conn_send_pdu(sk, nskb);
670 }
671out:
672 return rc;
673free:
674 kfree_skb(nskb);
675 goto out;
676}
677
678int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
679{
680 int rc = -ENOBUFS;
681 struct sk_buff *nskb = llc_alloc_frame();
682
683 if (nskb) {
684 struct llc_sock *llc = llc_sk(sk);
685 struct llc_sap *sap = llc->sap;
686
687 nskb->dev = llc->dev;
688 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
689 llc->daddr.lsap, LLC_PDU_CMD);
690 llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
691 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
692 if (rc)
693 goto free;
694 llc_conn_send_pdu(sk, nskb);
695 }
696out:
697 return rc;
698free:
699 kfree_skb(nskb);
700 goto out;
701}
702
703int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
704{
705 int rc = -ENOBUFS;
706 struct sk_buff *nskb = llc_alloc_frame();
707
708 if (nskb) {
709 struct llc_sock *llc = llc_sk(sk);
710 struct llc_sap *sap = llc->sap;
711 u8 f_bit = 1;
712
713 nskb->dev = llc->dev;
714 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
715 llc->daddr.lsap, LLC_PDU_RSP);
716 llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
717 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
718 if (rc)
719 goto free;
720 llc_conn_send_pdu(sk, nskb);
721 }
722out:
723 return rc;
724free:
725 kfree_skb(nskb);
726 goto out;
727}
728
729int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
730{
731 int rc = -ENOBUFS;
732 struct sk_buff *nskb = llc_alloc_frame();
733
734 if (nskb) {
735 struct llc_sock *llc = llc_sk(sk);
736 struct llc_sap *sap = llc->sap;
737 u8 f_bit = 1;
738
739 nskb->dev = llc->dev;
740 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
741 llc->daddr.lsap, LLC_PDU_RSP);
742 llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
743 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
744 if (rc)
745 goto free;
746 llc_conn_send_pdu(sk, nskb);
747 }
748out:
749 return rc;
750free:
751 kfree_skb(nskb);
752 goto out;
753}
754
755int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
756{
757 int rc = -ENOBUFS;
758 struct sk_buff *nskb = llc_alloc_frame();
759
760 if (nskb) {
761 struct llc_sock *llc = llc_sk(sk);
762 struct llc_sap *sap = llc->sap;
763
764 nskb->dev = llc->dev;
765 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
766 llc->daddr.lsap, LLC_PDU_RSP);
767 llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
768 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
769 if (rc)
770 goto free;
771 llc_conn_send_pdu(sk, nskb);
772 }
773out:
774 return rc;
775free:
776 kfree_skb(nskb);
777 goto out;
778}
779
780int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
781{
782 int rc = -ENOBUFS;
783 struct sk_buff *nskb = llc_alloc_frame();
784
785 if (nskb) {
786 struct llc_sock *llc = llc_sk(sk);
787 struct llc_sap *sap = llc->sap;
788
789 nskb->dev = llc->dev;
790 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
791 llc->daddr.lsap, LLC_PDU_RSP);
792 llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
793 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
794 if (rc)
795 goto free;
796 llc_conn_send_pdu(sk, nskb);
797 }
798out:
799 return rc;
800free:
801 kfree_skb(nskb);
802 goto out;
803}
804
805void llc_conn_set_p_flag(struct sock *sk, u8 value)
806{
807 int state_changed = llc_sk(sk)->p_flag && !value;
808
809 llc_sk(sk)->p_flag = value;
810
811 if (state_changed)
812 sk->sk_state_change(sk);
813}
814
815int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
816{
817 int rc = -ENOBUFS;
818 struct sk_buff *nskb = llc_alloc_frame();
819 struct llc_sock *llc = llc_sk(sk);
820
821 if (nskb) {
822 struct llc_sap *sap = llc->sap;
823 u8 *dmac = llc->daddr.mac;
824
825 if (llc->dev->flags & IFF_LOOPBACK)
826 dmac = llc->dev->dev_addr;
827 nskb->dev = llc->dev;
828 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
829 llc->daddr.lsap, LLC_PDU_CMD);
830 llc_pdu_init_as_sabme_cmd(nskb, 1);
831 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
832 if (rc)
833 goto free;
834 llc_conn_send_pdu(sk, nskb);
835 llc_conn_set_p_flag(sk, 1);
836 }
837out:
838 return rc;
839free:
840 kfree_skb(nskb);
841 goto out;
842}
843
844int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
845{
846 u8 f_bit;
847 int rc = -ENOBUFS;
848 struct sk_buff *nskb = llc_alloc_frame();
849
850 llc_pdu_decode_pf_bit(skb, &f_bit);
851 if (nskb) {
852 struct llc_sock *llc = llc_sk(sk);
853 struct llc_sap *sap = llc->sap;
854
855 nskb->dev = llc->dev;
856 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
857 llc->daddr.lsap, LLC_PDU_RSP);
858 llc_pdu_init_as_ua_rsp(nskb, f_bit);
859 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
860 if (rc)
861 goto free;
862 llc_conn_send_pdu(sk, nskb);
863 }
864out:
865 return rc;
866free:
867 kfree_skb(nskb);
868 goto out;
869}
870
871int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb)
872{
873 llc_sk(sk)->s_flag = 0;
874 return 0;
875}
876
877int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb)
878{
879 llc_sk(sk)->s_flag = 1;
880 return 0;
881}
882
883int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
884{
885 struct llc_sock *llc = llc_sk(sk);
886
887 llc_conn_set_p_flag(sk, 1);
888 mod_timer(&llc->pf_cycle_timer.timer,
889 jiffies + llc->pf_cycle_timer.expire * HZ);
890 return 0;
891}
892
893/**
894 * llc_conn_ac_send_ack_if_needed - check if ack is needed
895 * @sk: current connection structure
896 * @skb: current event
897 *
898 * Checks number of received PDUs which have not been acknowledged, yet,
899 * If number of them reaches to "npta"(Number of PDUs To Acknowledge) then
900 * sends an RR response as acknowledgement for them. Returns 0 for
901 * success, 1 otherwise.
902 */
903int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb)
904{
905 u8 pf_bit;
906 struct llc_sock *llc = llc_sk(sk);
907
908 llc_pdu_decode_pf_bit(skb, &pf_bit);
909 llc->ack_pf |= pf_bit & 1;
910 if (!llc->ack_must_be_send) {
911 llc->first_pdu_Ns = llc->vR;
912 llc->ack_must_be_send = 1;
913 llc->ack_pf = pf_bit & 1;
914 }
915 if (((llc->vR - llc->first_pdu_Ns + 129) % 128) >= llc->npta) {
916 llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, skb);
917 llc->ack_must_be_send = 0;
918 llc->ack_pf = 0;
919 llc_conn_ac_inc_npta_value(sk, skb);
920 }
921 return 0;
922}
923
924/**
925 * llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag
926 * @sk: current connection structure
927 * @skb: current event
928 *
929 * This action resets ack_must_be_send flag of given connection, this flag
930 * indicates if there is any PDU which has not been acknowledged yet.
931 * Returns 0 for success, 1 otherwise.
932 */
933int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb)
934{
935 llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0;
936 return 0;
937}
938
939/**
940 * llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs
941 * @sk: current connection structure
942 * @skb: current event
943 *
944 * Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to
945 * all received PDUs which have not been acknowledged, yet. ack_pf flag is
946 * set to one if one PDU with p-bit set to one is received. Returns 0 for
947 * success, 1 otherwise.
948 */
949static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
950 struct sk_buff *skb)
951{
952 int rc;
953 struct llc_sock *llc = llc_sk(sk);
954 struct llc_sap *sap = llc->sap;
955
956 llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
957 llc->daddr.lsap, LLC_PDU_RSP);
958 llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
959 rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
960 if (!rc) {
961 llc_conn_send_pdu(sk, skb);
962 llc_conn_ac_inc_vs_by_1(sk, skb);
963 }
964 return rc;
965}
966
967/**
968 * llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs
969 * @sk: current connection structure.
970 * @skb: current event.
971 *
972 * This action sends an I-format PDU as acknowledge to received PDUs which
973 * have not been acknowledged, yet, if there is any. By using of this
974 * action number of acknowledgements decreases, this technic is called
975 * piggy backing. Returns 0 for success, 1 otherwise.
976 */
977int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
978{
979 struct llc_sock *llc = llc_sk(sk);
980
981 if (llc->ack_must_be_send) {
982 llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
983 llc->ack_must_be_send = 0 ;
984 llc->ack_pf = 0;
985 } else
986 llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
987 return 0;
988}
989
990/**
991 * llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked
992 * @sk: current connection structure.
993 * @skb: current event.
994 *
995 * This action sends an RR response with f-bit set to ack_pf flag as
996 * acknowledge to all received PDUs which have not been acknowledged, yet,
997 * if there is any. ack_pf flag indicates if a PDU has been received with
998 * p-bit set to one. Returns 0 for success, 1 otherwise.
999 */
1000static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
1001 struct sk_buff *skb)
1002{
1003 int rc = -ENOBUFS;
1004 struct sk_buff *nskb = llc_alloc_frame();
1005
1006 if (nskb) {
1007 struct llc_sock *llc = llc_sk(sk);
1008 struct llc_sap *sap = llc->sap;
1009
1010 nskb->dev = llc->dev;
1011 llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
1012 llc->daddr.lsap, LLC_PDU_RSP);
1013 llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
1014 rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
1015 if (rc)
1016 goto free;
1017 llc_conn_send_pdu(sk, nskb);
1018 }
1019out:
1020 return rc;
1021free:
1022 kfree_skb(nskb);
1023 goto out;
1024}
1025
1026/**
1027 * llc_conn_ac_inc_npta_value - tries to make value of npta greater
1028 * @sk: current connection structure.
1029 * @skb: current event.
1030 *
1031 * After "inc_cntr" times calling of this action, "npta" increase by one.
1032 * this action tries to make vale of "npta" greater as possible; number of
1033 * acknowledgements decreases by increasing of "npta". Returns 0 for
1034 * success, 1 otherwise.
1035 */
1036static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb)
1037{
1038 struct llc_sock *llc = llc_sk(sk);
1039
1040 if (!llc->inc_cntr) {
1041 llc->dec_step = 0;
1042 llc->dec_cntr = llc->inc_cntr = 2;
1043 ++llc->npta;
1044 if (llc->npta > 127)
1045 llc->npta = 127 ;
1046 } else
1047 --llc->inc_cntr;
1048 return 0;
1049}
1050
1051/**
1052 * llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one
1053 * @sk: current connection structure.
1054 * @skb: current event.
1055 *
1056 * After receiving "dec_cntr" times RR command, this action decreases
1057 * "npta" by one. Returns 0 for success, 1 otherwise.
1058 */
1059int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb)
1060{
1061 struct llc_sock *llc = llc_sk(sk);
1062
1063 if (!llc->connect_step && !llc->remote_busy_flag) {
1064 if (!llc->dec_step) {
1065 if (!llc->dec_cntr) {
1066 llc->inc_cntr = llc->dec_cntr = 2;
1067 if (llc->npta > 0)
1068 llc->npta = llc->npta - 1;
1069 } else
1070 llc->dec_cntr -=1;
1071 }
1072 } else
1073 llc->connect_step = 0 ;
1074 return 0;
1075}
1076
1077/**
1078 * llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one
1079 * @sk: current connection structure.
1080 * @skb: current event.
1081 *
1082 * After receiving "dec_cntr" times RNR command, this action decreases
1083 * "npta" by one. Returns 0 for success, 1 otherwise.
1084 */
1085int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb)
1086{
1087 struct llc_sock *llc = llc_sk(sk);
1088
1089 if (llc->remote_busy_flag)
1090 if (!llc->dec_step) {
1091 if (!llc->dec_cntr) {
1092 llc->inc_cntr = llc->dec_cntr = 2;
1093 if (llc->npta > 0)
1094 --llc->npta;
1095 } else
1096 --llc->dec_cntr;
1097 }
1098 return 0;
1099}
1100
1101/**
1102 * llc_conn_ac_dec_tx_win_size - decreases tx window size
1103 * @sk: current connection structure.
1104 * @skb: current event.
1105 *
1106 * After receiving of a REJ command or response, transmit window size is
1107 * decreased by number of PDUs which are outstanding yet. Returns 0 for
1108 * success, 1 otherwise.
1109 */
1110int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb)
1111{
1112 struct llc_sock *llc = llc_sk(sk);
1113 u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q);
1114
1115 llc->k -= unacked_pdu;
1116 if (llc->k < 2)
1117 llc->k = 2;
1118 return 0;
1119}
1120
1121/**
1122 * llc_conn_ac_inc_tx_win_size - tx window size is inc by 1
1123 * @sk: current connection structure.
1124 * @skb: current event.
1125 *
1126 * After receiving an RR response with f-bit set to one, transmit window
1127 * size is increased by one. Returns 0 for success, 1 otherwise.
1128 */
1129int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb)
1130{
1131 struct llc_sock *llc = llc_sk(sk);
1132
1133 llc->k += 1;
1134 if (llc->k > 128)
1135 llc->k = 128 ;
1136 return 0;
1137}
1138
1139int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
1140{
1141 struct llc_sock *llc = llc_sk(sk);
1142
1143 del_timer(&llc->pf_cycle_timer.timer);
1144 del_timer(&llc->ack_timer.timer);
1145 del_timer(&llc->rej_sent_timer.timer);
1146 del_timer(&llc->busy_state_timer.timer);
1147 llc->ack_must_be_send = 0;
1148 llc->ack_pf = 0;
1149 return 0;
1150}
1151
1152int llc_conn_ac_stop_other_timers(struct sock *sk, struct sk_buff *skb)
1153{
1154 struct llc_sock *llc = llc_sk(sk);
1155
1156 del_timer(&llc->rej_sent_timer.timer);
1157 del_timer(&llc->pf_cycle_timer.timer);
1158 del_timer(&llc->busy_state_timer.timer);
1159 llc->ack_must_be_send = 0;
1160 llc->ack_pf = 0;
1161 return 0;
1162}
1163
1164int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb)
1165{
1166 struct llc_sock *llc = llc_sk(sk);
1167
1168 mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire * HZ);
1169 return 0;
1170}
1171
1172int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb)
1173{
1174 struct llc_sock *llc = llc_sk(sk);
1175
1176 mod_timer(&llc->rej_sent_timer.timer,
1177 jiffies + llc->rej_sent_timer.expire * HZ);
1178 return 0;
1179}
1180
1181int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
1182 struct sk_buff *skb)
1183{
1184 struct llc_sock *llc = llc_sk(sk);
1185
1186 if (!timer_pending(&llc->ack_timer.timer))
1187 mod_timer(&llc->ack_timer.timer,
1188 jiffies + llc->ack_timer.expire * HZ);
1189 return 0;
1190}
1191
1192int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb)
1193{
1194 del_timer(&llc_sk(sk)->ack_timer.timer);
1195 return 0;
1196}
1197
1198int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb)
1199{
1200 struct llc_sock *llc = llc_sk(sk);
1201
1202 del_timer(&llc->pf_cycle_timer.timer);
1203 llc_conn_set_p_flag(sk, 0);
1204 return 0;
1205}
1206
1207int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb)
1208{
1209 del_timer(&llc_sk(sk)->rej_sent_timer.timer);
1210 return 0;
1211}
1212
1213int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb)
1214{
1215 int acked;
1216 u16 unacked = 0;
1217 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1218 struct llc_sock *llc = llc_sk(sk);
1219
1220 llc->last_nr = PDU_SUPV_GET_Nr(pdu);
1221 acked = llc_conn_remove_acked_pdus(sk, llc->last_nr, &unacked);
1222 /* On loopback we don't queue I frames in unack_pdu_q queue. */
1223 if (acked > 0 || (llc->dev->flags & IFF_LOOPBACK)) {
1224 llc->retry_count = 0;
1225 del_timer(&llc->ack_timer.timer);
1226 if (llc->failed_data_req) {
1227 /* already, we did not accept data from upper layer
1228 * (tx_window full or unacceptable state). Now, we
1229 * can send data and must inform to upper layer.
1230 */
1231 llc->failed_data_req = 0;
1232 llc_conn_ac_data_confirm(sk, skb);
1233 }
1234 if (unacked)
1235 mod_timer(&llc->ack_timer.timer,
1236 jiffies + llc->ack_timer.expire * HZ);
1237 } else if (llc->failed_data_req) {
1238 u8 f_bit;
1239
1240 llc_pdu_decode_pf_bit(skb, &f_bit);
1241 if (f_bit == 1) {
1242 llc->failed_data_req = 0;
1243 llc_conn_ac_data_confirm(sk, skb);
1244 }
1245 }
1246 return 0;
1247}
1248
1249int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb)
1250{
1251 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1252
1253 if (LLC_PDU_IS_RSP(pdu)) {
1254 u8 f_bit;
1255
1256 llc_pdu_decode_pf_bit(skb, &f_bit);
1257 if (f_bit) {
1258 llc_conn_set_p_flag(sk, 0);
1259 llc_conn_ac_stop_p_timer(sk, skb);
1260 }
1261 }
1262 return 0;
1263}
1264
1265int llc_conn_ac_set_data_flag_2(struct sock *sk, struct sk_buff *skb)
1266{
1267 llc_sk(sk)->data_flag = 2;
1268 return 0;
1269}
1270
1271int llc_conn_ac_set_data_flag_0(struct sock *sk, struct sk_buff *skb)
1272{
1273 llc_sk(sk)->data_flag = 0;
1274 return 0;
1275}
1276
1277int llc_conn_ac_set_data_flag_1(struct sock *sk, struct sk_buff *skb)
1278{
1279 llc_sk(sk)->data_flag = 1;
1280 return 0;
1281}
1282
1283int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
1284 struct sk_buff *skb)
1285{
1286 if (!llc_sk(sk)->data_flag)
1287 llc_sk(sk)->data_flag = 1;
1288 return 0;
1289}
1290
1291int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb)
1292{
1293 llc_conn_set_p_flag(sk, 0);
1294 return 0;
1295}
1296
1297static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb)
1298{
1299 llc_conn_set_p_flag(sk, 1);
1300 return 0;
1301}
1302
1303int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct sk_buff *skb)
1304{
1305 llc_sk(sk)->remote_busy_flag = 0;
1306 return 0;
1307}
1308
1309int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct sk_buff *skb)
1310{
1311 llc_sk(sk)->cause_flag = 0;
1312 return 0;
1313}
1314
1315int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct sk_buff *skb)
1316{
1317 llc_sk(sk)->cause_flag = 1;
1318 return 0;
1319}
1320
1321int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct sk_buff *skb)
1322{
1323 llc_sk(sk)->retry_count = 0;
1324 return 0;
1325}
1326
1327int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, struct sk_buff *skb)
1328{
1329 llc_sk(sk)->retry_count++;
1330 return 0;
1331}
1332
1333int llc_conn_ac_set_vr_0(struct sock *sk, struct sk_buff *skb)
1334{
1335 llc_sk(sk)->vR = 0;
1336 return 0;
1337}
1338
1339int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct sk_buff *skb)
1340{
1341 llc_sk(sk)->vR = PDU_GET_NEXT_Vr(llc_sk(sk)->vR);
1342 return 0;
1343}
1344
1345int llc_conn_ac_set_vs_0(struct sock *sk, struct sk_buff *skb)
1346{
1347 llc_sk(sk)->vS = 0;
1348 return 0;
1349}
1350
1351int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb)
1352{
1353 llc_sk(sk)->vS = llc_sk(sk)->last_nr;
1354 return 0;
1355}
1356
1357int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
1358{
1359 llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128;
1360 return 0;
1361}
1362
1363void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
1364{
1365 struct sock *sk = (struct sock *)timeout_data;
1366 struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
1367
1368 bh_lock_sock(sk);
1369 if (skb) {
1370 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1371
1372 skb->sk = sk;
1373 ev->type = LLC_CONN_EV_TYPE_P_TMR;
1374 llc_process_tmr_ev(sk, skb);
1375 }
1376 bh_unlock_sock(sk);
1377}
1378
1379void llc_conn_busy_tmr_cb(unsigned long timeout_data)
1380{
1381 struct sock *sk = (struct sock *)timeout_data;
1382 struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
1383
1384 bh_lock_sock(sk);
1385 if (skb) {
1386 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1387
1388 skb->sk = sk;
1389 ev->type = LLC_CONN_EV_TYPE_BUSY_TMR;
1390 llc_process_tmr_ev(sk, skb);
1391 }
1392 bh_unlock_sock(sk);
1393}
1394
1395void llc_conn_ack_tmr_cb(unsigned long timeout_data)
1396{
1397 struct sock* sk = (struct sock *)timeout_data;
1398 struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
1399
1400 bh_lock_sock(sk);
1401 if (skb) {
1402 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1403
1404 skb->sk = sk;
1405 ev->type = LLC_CONN_EV_TYPE_ACK_TMR;
1406 llc_process_tmr_ev(sk, skb);
1407 }
1408 bh_unlock_sock(sk);
1409}
1410
1411void llc_conn_rej_tmr_cb(unsigned long timeout_data)
1412{
1413 struct sock *sk = (struct sock *)timeout_data;
1414 struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
1415
1416 bh_lock_sock(sk);
1417 if (skb) {
1418 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1419
1420 skb->sk = sk;
1421 ev->type = LLC_CONN_EV_TYPE_REJ_TMR;
1422 llc_process_tmr_ev(sk, skb);
1423 }
1424 bh_unlock_sock(sk);
1425}
1426
1427int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
1428{
1429 llc_sk(sk)->X = llc_sk(sk)->vS;
1430 llc_conn_ac_set_vs_nr(sk, skb);
1431 return 0;
1432}
1433
1434int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb)
1435{
1436 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1437 u8 nr = PDU_SUPV_GET_Nr(pdu);
1438
1439 if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
1440 llc_conn_ac_set_vs_nr(sk, skb);
1441 return 0;
1442}
1443
1444/*
1445 * Non-standard actions; these not contained in IEEE specification; for
1446 * our own usage
1447 */
1448/**
1449 * llc_conn_disc - removes connection from SAP list and frees it
1450 * @sk: closed connection
1451 * @skb: occurred event
1452 */
1453int llc_conn_disc(struct sock *sk, struct sk_buff *skb)
1454{
1455 /* FIXME: this thing seems to want to die */
1456 return 0;
1457}
1458
1459/**
1460 * llc_conn_reset - resets connection
1461 * @sk : reseting connection.
1462 * @skb: occurred event.
1463 *
1464 * Stop all timers, empty all queues and reset all flags.
1465 */
1466int llc_conn_reset(struct sock *sk, struct sk_buff *skb)
1467{
1468 llc_sk_reset(sk);
1469 return 0;
1470}
1471
1472/**
1473 * llc_circular_between - designates that b is between a and c or not
1474 * @a: lower bound
1475 * @b: element to see if is between a and b
1476 * @c: upper bound
1477 *
1478 * This function designates that b is between a and c or not (for example,
1479 * 0 is between 127 and 1). Returns 1 if b is between a and c, 0
1480 * otherwise.
1481 */
1482u8 llc_circular_between(u8 a, u8 b, u8 c)
1483{
1484 b = b - a;
1485 c = c - a;
1486 return b <= c;
1487}
1488
1489/**
1490 * llc_process_tmr_ev - timer backend
1491 * @sk: active connection
1492 * @skb: occurred event
1493 *
1494 * This function is called from timer callback functions. When connection
1495 * is busy (during sending a data frame) timer expiration event must be
1496 * queued. Otherwise this event can be sent to connection state machine.
1497 * Queued events will process by llc_backlog_rcv function after sending
1498 * data frame.
1499 */
1500static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
1501{
1502 if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
1503 printk(KERN_WARNING "%s: timer called on closed connection\n",
1504 __FUNCTION__);
1505 kfree_skb(skb);
1506 } else {
1507 if (!sock_owned_by_user(sk))
1508 llc_conn_state_process(sk, skb);
1509 else {
1510 llc_set_backlog_type(skb, LLC_EVENT);
1511 sk_add_backlog(sk, skb);
1512 }
1513 }
1514}
diff --git a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c
new file mode 100644
index 000000000000..cd130c3b72bc
--- /dev/null
+++ b/net/llc/llc_c_ev.c
@@ -0,0 +1,769 @@
1/*
2 * llc_c_ev.c - Connection component state transition event qualifiers
3 *
4 * A 'state' consists of a number of possible event matching functions,
5 * the actions associated with each being executed when that event is
6 * matched; a 'state machine' accepts events in a serial fashion from an
7 * event queue. Each event is passed to each successive event matching
8 * function until a match is made (the event matching function returns
9 * success, or '0') or the list of event matching functions is exhausted.
10 * If a match is made, the actions associated with the event are executed
11 * and the state is changed to that event's transition state. Before some
12 * events are recognized, even after a match has been made, a certain
13 * number of 'event qualifier' functions must also be executed. If these
14 * all execute successfully, then the event is finally executed.
15 *
16 * These event functions must return 0 for success, to show a matched
17 * event, of 1 if the event does not match. Event qualifier functions
18 * must return a 0 for success or a non-zero for failure. Each function
19 * is simply responsible for verifying one single thing and returning
20 * either a success or failure.
21 *
22 * All of followed event functions are described in 802.2 LLC Protocol
23 * standard document except two functions that we added that will explain
24 * in their comments, at below.
25 *
26 * Copyright (c) 1997 by Procom Technology, Inc.
27 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
28 *
29 * This program can be redistributed or modified under the terms of the
30 * GNU General Public License as published by the Free Software Foundation.
31 * This program is distributed without any warranty or implied warranty
32 * of merchantability or fitness for a particular purpose.
33 *
34 * See the GNU General Public License for more details.
35 */
36#include <linux/netdevice.h>
37#include <net/llc_conn.h>
38#include <net/llc_sap.h>
39#include <net/sock.h>
40#include <net/llc_c_ev.h>
41#include <net/llc_pdu.h>
42
43#if 1
44#define dprintk(args...) printk(KERN_DEBUG args)
45#else
46#define dprintk(args...)
47#endif
48
49extern u16 llc_circular_between(u8 a, u8 b, u8 c);
50
51/**
52 * llc_util_ns_inside_rx_window - check if sequence number is in rx window
53 * @ns: sequence number of received pdu.
54 * @vr: sequence number which receiver expects to receive.
55 * @rw: receive window size of receiver.
56 *
57 * Checks if sequence number of received PDU is in range of receive
58 * window. Returns 0 for success, 1 otherwise
59 */
60static u16 llc_util_ns_inside_rx_window(u8 ns, u8 vr, u8 rw)
61{
62 return !llc_circular_between(vr, ns,
63 (vr + rw - 1) % LLC_2_SEQ_NBR_MODULO);
64}
65
66/**
67 * llc_util_nr_inside_tx_window - check if sequence number is in tx window
68 * @sk: current connection.
69 * @nr: N(R) of received PDU.
70 *
71 * This routine checks if N(R) of received PDU is in range of transmit
72 * window; on the other hand checks if received PDU acknowledges some
73 * outstanding PDUs that are in transmit window. Returns 0 for success, 1
74 * otherwise.
75 */
76static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr)
77{
78 u8 nr1, nr2;
79 struct sk_buff *skb;
80 struct llc_pdu_sn *pdu;
81 struct llc_sock *llc = llc_sk(sk);
82 int rc = 0;
83
84 if (llc->dev->flags & IFF_LOOPBACK)
85 goto out;
86 rc = 1;
87 if (!skb_queue_len(&llc->pdu_unack_q))
88 goto out;
89 skb = skb_peek(&llc->pdu_unack_q);
90 pdu = llc_pdu_sn_hdr(skb);
91 nr1 = LLC_I_GET_NS(pdu);
92 skb = skb_peek_tail(&llc->pdu_unack_q);
93 pdu = llc_pdu_sn_hdr(skb);
94 nr2 = LLC_I_GET_NS(pdu);
95 rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO);
96out:
97 return rc;
98}
99
100int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
101{
102 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
103
104 return ev->prim == LLC_CONN_PRIM &&
105 ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
106}
107
108int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
109{
110 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
111
112 return ev->prim == LLC_DATA_PRIM &&
113 ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
114}
115
116int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
117{
118 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
119
120 return ev->prim == LLC_DISC_PRIM &&
121 ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
122}
123
124int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
125{
126 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
127
128 return ev->prim == LLC_RESET_PRIM &&
129 ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
130}
131
132int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
133{
134 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
135
136 return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
137 ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
138}
139
140int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
141{
142 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
143
144 return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
145 ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
146}
147
148int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
149{
150 return 1;
151}
152
153int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
154{
155 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
156
157 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
158 LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
159}
160
161int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
162{
163 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
164
165 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
166 LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
167}
168
169int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
170{
171 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
172
173 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
174 LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
175}
176
177int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
178{
179 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
180
181 return llc_conn_space(sk, skb) &&
182 LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
183 LLC_I_PF_IS_0(pdu) &&
184 LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
185}
186
187int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
188{
189 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
190
191 return llc_conn_space(sk, skb) &&
192 LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
193 LLC_I_PF_IS_1(pdu) &&
194 LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
195}
196
197int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
198 struct sk_buff *skb)
199{
200 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
201 u8 vr = llc_sk(sk)->vR;
202 u8 ns = LLC_I_GET_NS(pdu);
203
204 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
205 LLC_I_PF_IS_0(pdu) && ns != vr &&
206 !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
207}
208
209int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
210 struct sk_buff *skb)
211{
212 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
213 u8 vr = llc_sk(sk)->vR;
214 u8 ns = LLC_I_GET_NS(pdu);
215
216 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
217 LLC_I_PF_IS_1(pdu) && ns != vr &&
218 !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
219}
220
221int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
222 struct sk_buff *skb)
223{
224 struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
225 u8 vr = llc_sk(sk)->vR;
226 u8 ns = LLC_I_GET_NS(pdu);
227 u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
228 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
229 if (!rc)
230 dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
231 __FUNCTION__, llc_sk(sk)->state, ns, vr);
232 return rc;
233}
234
235int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
236{
237 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
238
239 return llc_conn_space(sk, skb) &&
240 LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
241 LLC_I_PF_IS_0(pdu) &&
242 LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
243}
244
245int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
246{
247 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
248
249 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
250 LLC_I_PF_IS_1(pdu) &&
251 LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
252}
253
254int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
255{
256 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
257
258 return llc_conn_space(sk, skb) &&
259 LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
260 LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
261}
262
263int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
264 struct sk_buff *skb)
265{
266 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
267 u8 vr = llc_sk(sk)->vR;
268 u8 ns = LLC_I_GET_NS(pdu);
269
270 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
271 LLC_I_PF_IS_0(pdu) && ns != vr &&
272 !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
273}
274
275int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
276 struct sk_buff *skb)
277{
278 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
279 u8 vr = llc_sk(sk)->vR;
280 u8 ns = LLC_I_GET_NS(pdu);
281
282 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
283 LLC_I_PF_IS_1(pdu) && ns != vr &&
284 !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
285}
286
287int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
288 struct sk_buff *skb)
289{
290 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
291 u8 vr = llc_sk(sk)->vR;
292 u8 ns = LLC_I_GET_NS(pdu);
293
294 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
295 !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
296}
297
298int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
299 struct sk_buff *skb)
300{
301 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
302 u8 vr = llc_sk(sk)->vR;
303 u8 ns = LLC_I_GET_NS(pdu);
304 u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
305 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
306 if (!rc)
307 dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
308 __FUNCTION__, llc_sk(sk)->state, ns, vr);
309 return rc;
310}
311
312int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
313{
314 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
315
316 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
317 LLC_S_PF_IS_0(pdu) &&
318 LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
319}
320
321int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
322{
323 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
324
325 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
326 LLC_S_PF_IS_1(pdu) &&
327 LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
328}
329
330int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
331{
332 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
333
334 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
335 LLC_S_PF_IS_0(pdu) &&
336 LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
337}
338
339int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
340{
341 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
342
343 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
344 LLC_S_PF_IS_1(pdu) &&
345 LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
346}
347
348int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
349{
350 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
351
352 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
353 LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
354}
355
356int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
357{
358 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
359
360 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
361 LLC_S_PF_IS_0(pdu) &&
362 LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
363}
364
365int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
366{
367 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
368
369 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
370 LLC_S_PF_IS_1(pdu) &&
371 LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
372}
373
374int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
375{
376 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
377
378 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
379 LLC_S_PF_IS_0(pdu) &&
380 LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
381}
382
383int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
384{
385 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
386
387 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
388 LLC_S_PF_IS_1(pdu) &&
389 LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
390}
391
392int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
393{
394 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
395
396 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
397 LLC_S_PF_IS_0(pdu) &&
398 LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
399}
400
401int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
402{
403 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
404
405 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
406 LLC_S_PF_IS_1(pdu) &&
407 LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
408}
409
410int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
411{
412 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
413
414 return llc_conn_space(sk, skb) &&
415 LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
416 LLC_S_PF_IS_0(pdu) &&
417 LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
418}
419
420int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
421{
422 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
423
424 return llc_conn_space(sk, skb) &&
425 LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
426 LLC_S_PF_IS_1(pdu) &&
427 LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
428}
429
430int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
431{
432 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
433
434 return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
435 LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
436}
437
438int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
439{
440 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
441
442 return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
443 LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
444}
445
446int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
447{
448 u16 rc = 1;
449 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
450
451 if (LLC_PDU_IS_CMD(pdu)) {
452 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
453 if (LLC_I_PF_IS_1(pdu))
454 rc = 0;
455 } else if (LLC_PDU_TYPE_IS_U(pdu) && LLC_U_PF_IS_1(pdu))
456 rc = 0;
457 }
458 return rc;
459}
460
461int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
462{
463 u16 rc = 1;
464 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
465
466 if (LLC_PDU_IS_CMD(pdu)) {
467 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
468 rc = 0;
469 else if (LLC_PDU_TYPE_IS_U(pdu))
470 switch (LLC_U_PDU_CMD(pdu)) {
471 case LLC_2_PDU_CMD_SABME:
472 case LLC_2_PDU_CMD_DISC:
473 rc = 0;
474 break;
475 }
476 }
477 return rc;
478}
479
480int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
481{
482 u16 rc = 1;
483 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
484
485 if (LLC_PDU_IS_RSP(pdu)) {
486 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
487 if (LLC_I_PF_IS_1(pdu))
488 rc = 0;
489 } else if (LLC_PDU_TYPE_IS_U(pdu))
490 switch (LLC_U_PDU_RSP(pdu)) {
491 case LLC_2_PDU_RSP_UA:
492 case LLC_2_PDU_RSP_DM:
493 case LLC_2_PDU_RSP_FRMR:
494 if (LLC_U_PF_IS_1(pdu))
495 rc = 0;
496 break;
497 }
498 }
499 return rc;
500}
501
502int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
503{
504 u16 rc = 1;
505 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
506
507 if (LLC_PDU_IS_RSP(pdu)) {
508 if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
509 rc = 0;
510 else if (LLC_PDU_TYPE_IS_U(pdu))
511 switch (LLC_U_PDU_RSP(pdu)) {
512 case LLC_2_PDU_RSP_UA:
513 case LLC_2_PDU_RSP_DM:
514 case LLC_2_PDU_RSP_FRMR:
515 rc = 0;
516 break;
517 }
518 }
519
520 return rc;
521}
522
523int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
524 struct sk_buff *skb)
525{
526 u16 rc = 1;
527 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
528 u8 vs = llc_sk(sk)->vS;
529 u8 nr = LLC_I_GET_NR(pdu);
530
531 if (LLC_PDU_IS_CMD(pdu) &&
532 (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
533 nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
534 dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
535 __FUNCTION__, llc_sk(sk)->state, vs, nr);
536 rc = 0;
537 }
538 return rc;
539}
540
541int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
542 struct sk_buff *skb)
543{
544 u16 rc = 1;
545 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
546 u8 vs = llc_sk(sk)->vS;
547 u8 nr = LLC_I_GET_NR(pdu);
548
549 if (LLC_PDU_IS_RSP(pdu) &&
550 (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
551 nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
552 rc = 0;
553 dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
554 __FUNCTION__, llc_sk(sk)->state, vs, nr);
555 }
556 return rc;
557}
558
559int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb)
560{
561 return 0;
562}
563
564int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
565{
566 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
567
568 return ev->type != LLC_CONN_EV_TYPE_P_TMR;
569}
570
571int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
572{
573 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
574
575 return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
576}
577
578int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
579{
580 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
581
582 return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
583}
584
585int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
586{
587 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
588
589 return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
590}
591
592int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
593{
594 return 1;
595}
596
597int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
598{
599 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
600
601 return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
602 ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
603}
604
605/* Event qualifier functions
606 *
607 * these functions simply verify the value of a state flag associated with
608 * the connection and return either a 0 for success or a non-zero value
609 * for not-success; verify the event is the type we expect
610 */
611int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb)
612{
613 return llc_sk(sk)->data_flag != 1;
614}
615
616int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb)
617{
618 return llc_sk(sk)->data_flag;
619}
620
621int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb)
622{
623 return llc_sk(sk)->data_flag != 2;
624}
625
626int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb)
627{
628 return llc_sk(sk)->p_flag != 1;
629}
630
631/**
632 * conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window
633 * @sk: current connection structure.
634 * @skb: current event.
635 *
636 * This function determines when frame which is sent, is last frame of
637 * transmit window, if it is then this function return zero else return
638 * one. This function is used for sending last frame of transmit window
639 * as I-format command with p-bit set to one. Returns 0 if frame is last
640 * frame, 1 otherwise.
641 */
642int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb)
643{
644 return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k);
645}
646
647/**
648 * conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window
649 * @sk: current connection structure.
650 * @skb: current event.
651 *
652 * This function determines when frame which is sent, isn't last frame of
653 * transmit window, if it isn't then this function return zero else return
654 * one. Returns 0 if frame isn't last frame, 1 otherwise.
655 */
656int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb)
657{
658 return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k;
659}
660
661int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb)
662{
663 return llc_sk(sk)->p_flag;
664}
665
666int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb)
667{
668 u8 f_bit;
669
670 llc_pdu_decode_pf_bit(skb, &f_bit);
671 return llc_sk(sk)->p_flag == f_bit ? 0 : 1;
672}
673
674int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb)
675{
676 return llc_sk(sk)->remote_busy_flag;
677}
678
679int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb)
680{
681 return !llc_sk(sk)->remote_busy_flag;
682}
683
684int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb)
685{
686 return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2);
687}
688
689int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb)
690{
691 return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2);
692}
693
694int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb)
695{
696 return !llc_sk(sk)->s_flag;
697}
698
699int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb)
700{
701 return llc_sk(sk)->s_flag;
702}
703
704int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb)
705{
706 return !llc_sk(sk)->cause_flag;
707}
708
709int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb)
710{
711 return llc_sk(sk)->cause_flag;
712}
713
714int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb)
715{
716 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
717
718 ev->status = LLC_STATUS_CONN;
719 return 0;
720}
721
722int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb)
723{
724 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
725
726 ev->status = LLC_STATUS_DISC;
727 return 0;
728}
729
730int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb)
731{
732 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
733
734 ev->status = LLC_STATUS_FAILED;
735 return 0;
736}
737
738int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
739 struct sk_buff *skb)
740{
741 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
742
743 ev->status = LLC_STATUS_REMOTE_BUSY;
744 return 0;
745}
746
747int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb)
748{
749 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
750
751 ev->status = LLC_STATUS_REFUSE;
752 return 0;
753}
754
755int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb)
756{
757 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
758
759 ev->status = LLC_STATUS_CONFLICT;
760 return 0;
761}
762
763int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb)
764{
765 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
766
767 ev->status = LLC_STATUS_RESET_DONE;
768 return 0;
769}
diff --git a/net/llc/llc_c_st.c b/net/llc/llc_c_st.c
new file mode 100644
index 000000000000..818a9428823b
--- /dev/null
+++ b/net/llc/llc_c_st.c
@@ -0,0 +1,4946 @@
1/*
2 * llc_c_st.c - This module contains state transition of connection component.
3 *
4 * Description of event functions and actions there is in 802.2 LLC standard,
5 * or in "llc_c_ac.c" and "llc_c_ev.c" modules.
6 *
7 * Copyright (c) 1997 by Procom Technology, Inc.
8 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9 *
10 * This program can be redistributed or modified under the terms of the
11 * GNU General Public License as published by the Free Software Foundation.
12 * This program is distributed without any warranty or implied warranty
13 * of merchantability or fitness for a particular purpose.
14 *
15 * See the GNU General Public License for more details.
16 */
17#include <linux/types.h>
18#include <net/llc_if.h>
19#include <net/llc_sap.h>
20#include <net/llc_c_ev.h>
21#include <net/llc_c_ac.h>
22#include <net/llc_c_st.h>
23
24#define NONE NULL
25
26/* COMMON CONNECTION STATE transitions
27 * Common transitions for
28 * LLC_CONN_STATE_NORMAL,
29 * LLC_CONN_STATE_BUSY,
30 * LLC_CONN_STATE_REJ,
31 * LLC_CONN_STATE_AWAIT,
32 * LLC_CONN_STATE_AWAIT_BUSY and
33 * LLC_CONN_STATE_AWAIT_REJ states
34 */
35/* State transitions for LLC_CONN_EV_DISC_REQ event */
36static llc_conn_action_t llc_common_actions_1[] = {
37 [0] = llc_conn_ac_send_disc_cmd_p_set_x,
38 [1] = llc_conn_ac_start_ack_timer,
39 [2] = llc_conn_ac_stop_other_timers,
40 [3] = llc_conn_ac_set_retry_cnt_0,
41 [4] = llc_conn_ac_set_cause_flag_1,
42 [5] = NULL,
43};
44
45static struct llc_conn_state_trans llc_common_state_trans_1 = {
46 .ev = llc_conn_ev_disc_req,
47 .next_state = LLC_CONN_STATE_D_CONN,
48 .ev_qualifiers = NONE,
49 .ev_actions = llc_common_actions_1,
50};
51
52/* State transitions for LLC_CONN_EV_RESET_REQ event */
53static llc_conn_action_t llc_common_actions_2[] = {
54 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
55 [1] = llc_conn_ac_start_ack_timer,
56 [2] = llc_conn_ac_stop_other_timers,
57 [3] = llc_conn_ac_set_retry_cnt_0,
58 [4] = llc_conn_ac_set_cause_flag_1,
59 [5] = NULL,
60};
61
62static struct llc_conn_state_trans llc_common_state_trans_2 = {
63 .ev = llc_conn_ev_rst_req,
64 .next_state = LLC_CONN_STATE_RESET,
65 .ev_qualifiers = NONE,
66 .ev_actions = llc_common_actions_2,
67};
68
69/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
70static llc_conn_action_t llc_common_actions_3[] = {
71 [0] = llc_conn_ac_stop_all_timers,
72 [1] = llc_conn_ac_set_vs_0,
73 [2] = llc_conn_ac_set_vr_0,
74 [3] = llc_conn_ac_send_ua_rsp_f_set_p,
75 [4] = llc_conn_ac_rst_ind,
76 [5] = llc_conn_ac_set_p_flag_0,
77 [6] = llc_conn_ac_set_remote_busy_0,
78 [7] = llc_conn_reset,
79 [8] = NULL,
80};
81
82static struct llc_conn_state_trans llc_common_state_trans_3 = {
83 .ev = llc_conn_ev_rx_sabme_cmd_pbit_set_x,
84 .next_state = LLC_CONN_STATE_NORMAL,
85 .ev_qualifiers = NONE,
86 .ev_actions = llc_common_actions_3,
87};
88
89/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
90static llc_conn_action_t llc_common_actions_4[] = {
91 [0] = llc_conn_ac_stop_all_timers,
92 [1] = llc_conn_ac_send_ua_rsp_f_set_p,
93 [2] = llc_conn_ac_disc_ind,
94 [3] = llc_conn_disc,
95 [4] = NULL,
96};
97
98static struct llc_conn_state_trans llc_common_state_trans_4 = {
99 .ev = llc_conn_ev_rx_disc_cmd_pbit_set_x,
100 .next_state = LLC_CONN_STATE_ADM,
101 .ev_qualifiers = NONE,
102 .ev_actions = llc_common_actions_4,
103};
104
105/* State transitions for LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X event */
106static llc_conn_action_t llc_common_actions_5[] = {
107 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
108 [1] = llc_conn_ac_start_ack_timer,
109 [2] = llc_conn_ac_stop_other_timers,
110 [3] = llc_conn_ac_set_retry_cnt_0,
111 [4] = llc_conn_ac_rst_ind,
112 [5] = llc_conn_ac_set_cause_flag_0,
113 [6] = llc_conn_reset,
114 [7] = NULL,
115};
116
117static struct llc_conn_state_trans llc_common_state_trans_5 = {
118 .ev = llc_conn_ev_rx_frmr_rsp_fbit_set_x,
119 .next_state = LLC_CONN_STATE_RESET,
120 .ev_qualifiers = NONE,
121 .ev_actions = llc_common_actions_5,
122};
123
124/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event */
125static llc_conn_action_t llc_common_actions_6[] = {
126 [0] = llc_conn_ac_disc_ind,
127 [1] = llc_conn_ac_stop_all_timers,
128 [2] = llc_conn_disc,
129 [3] = NULL,
130};
131
132static struct llc_conn_state_trans llc_common_state_trans_6 = {
133 .ev = llc_conn_ev_rx_dm_rsp_fbit_set_x,
134 .next_state = LLC_CONN_STATE_ADM,
135 .ev_qualifiers = NONE,
136 .ev_actions = llc_common_actions_6,
137};
138
139/* State transitions for LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr event */
140static llc_conn_action_t llc_common_actions_7a[] = {
141 [0] = llc_conn_ac_send_frmr_rsp_f_set_x,
142 [1] = llc_conn_ac_start_ack_timer,
143 [2] = llc_conn_ac_stop_other_timers,
144 [3] = llc_conn_ac_set_retry_cnt_0,
145 [4] = NULL,
146};
147
148static struct llc_conn_state_trans llc_common_state_trans_7a = {
149 .ev = llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr,
150 .next_state = LLC_CONN_STATE_ERROR,
151 .ev_qualifiers = NONE,
152 .ev_actions = llc_common_actions_7a,
153};
154
155/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns event */
156static llc_conn_action_t llc_common_actions_7b[] = {
157 [0] = llc_conn_ac_send_frmr_rsp_f_set_x,
158 [1] = llc_conn_ac_start_ack_timer,
159 [2] = llc_conn_ac_stop_other_timers,
160 [3] = llc_conn_ac_set_retry_cnt_0,
161 [4] = NULL,
162};
163
164static struct llc_conn_state_trans llc_common_state_trans_7b = {
165 .ev = llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns,
166 .next_state = LLC_CONN_STATE_ERROR,
167 .ev_qualifiers = NONE,
168 .ev_actions = llc_common_actions_7b,
169};
170
171/* State transitions for LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr event */
172static llc_conn_action_t llc_common_actions_8a[] = {
173 [0] = llc_conn_ac_send_frmr_rsp_f_set_x,
174 [1] = llc_conn_ac_start_ack_timer,
175 [2] = llc_conn_ac_stop_other_timers,
176 [3] = llc_conn_ac_set_retry_cnt_0,
177 [4] = NULL,
178};
179
180static struct llc_conn_state_trans llc_common_state_trans_8a = {
181 .ev = llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr,
182 .next_state = LLC_CONN_STATE_ERROR,
183 .ev_qualifiers = NONE,
184 .ev_actions = llc_common_actions_8a,
185};
186
187/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns event */
188static llc_conn_action_t llc_common_actions_8b[] = {
189 [0] = llc_conn_ac_send_frmr_rsp_f_set_x,
190 [1] = llc_conn_ac_start_ack_timer,
191 [2] = llc_conn_ac_stop_other_timers,
192 [3] = llc_conn_ac_set_retry_cnt_0,
193 [4] = NULL,
194};
195
196static struct llc_conn_state_trans llc_common_state_trans_8b = {
197 .ev = llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns,
198 .next_state = LLC_CONN_STATE_ERROR,
199 .ev_qualifiers = NONE,
200 .ev_actions = llc_common_actions_8b,
201};
202
203/* State transitions for LLC_CONN_EV_RX_BAD_PDU event */
204static llc_conn_action_t llc_common_actions_8c[] = {
205 [0] = llc_conn_ac_send_frmr_rsp_f_set_x,
206 [1] = llc_conn_ac_start_ack_timer,
207 [2] = llc_conn_ac_stop_other_timers,
208 [3] = llc_conn_ac_set_retry_cnt_0,
209 [4] = NULL,
210};
211
212static struct llc_conn_state_trans llc_common_state_trans_8c = {
213 .ev = llc_conn_ev_rx_bad_pdu,
214 .next_state = LLC_CONN_STATE_ERROR,
215 .ev_qualifiers = NONE,
216 .ev_actions = llc_common_actions_8c,
217};
218
219/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event */
220static llc_conn_action_t llc_common_actions_9[] = {
221 [0] = llc_conn_ac_send_frmr_rsp_f_set_x,
222 [1] = llc_conn_ac_start_ack_timer,
223 [2] = llc_conn_ac_stop_other_timers,
224 [3] = llc_conn_ac_set_retry_cnt_0,
225 [4] = NULL,
226};
227
228static struct llc_conn_state_trans llc_common_state_trans_9 = {
229 .ev = llc_conn_ev_rx_ua_rsp_fbit_set_x,
230 .next_state = LLC_CONN_STATE_ERROR,
231 .ev_qualifiers = NONE,
232 .ev_actions = llc_common_actions_9,
233};
234
235/* State transitions for LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1 event */
236#if 0
237static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_10[] = {
238 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
239 [1] = NULL,
240};
241
242static llc_conn_action_t llc_common_actions_10[] = {
243 [0] = llc_conn_ac_send_frmr_rsp_f_set_x,
244 [1] = llc_conn_ac_start_ack_timer,
245 [2] = llc_conn_ac_stop_other_timers,
246 [3] = llc_conn_ac_set_retry_cnt_0,
247 [4] = NULL,
248};
249
250static struct llc_conn_state_trans llc_common_state_trans_10 = {
251 .ev = llc_conn_ev_rx_xxx_rsp_fbit_set_1,
252 .next_state = LLC_CONN_STATE_ERROR,
253 .ev_qualifiers = llc_common_ev_qfyrs_10,
254 .ev_actions = llc_common_actions_10,
255};
256#endif
257
258/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
259static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11a[] = {
260 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
261 [1] = NULL,
262};
263
264static llc_conn_action_t llc_common_actions_11a[] = {
265 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
266 [1] = llc_conn_ac_start_ack_timer,
267 [2] = llc_conn_ac_stop_other_timers,
268 [3] = llc_conn_ac_set_retry_cnt_0,
269 [4] = llc_conn_ac_set_cause_flag_0,
270 [5] = NULL,
271};
272
273static struct llc_conn_state_trans llc_common_state_trans_11a = {
274 .ev = llc_conn_ev_p_tmr_exp,
275 .next_state = LLC_CONN_STATE_RESET,
276 .ev_qualifiers = llc_common_ev_qfyrs_11a,
277 .ev_actions = llc_common_actions_11a,
278};
279
280/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
281static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11b[] = {
282 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
283 [1] = NULL,
284};
285
286static llc_conn_action_t llc_common_actions_11b[] = {
287 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
288 [1] = llc_conn_ac_start_ack_timer,
289 [2] = llc_conn_ac_stop_other_timers,
290 [3] = llc_conn_ac_set_retry_cnt_0,
291 [4] = llc_conn_ac_set_cause_flag_0,
292 [5] = NULL,
293};
294
295static struct llc_conn_state_trans llc_common_state_trans_11b = {
296 .ev = llc_conn_ev_ack_tmr_exp,
297 .next_state = LLC_CONN_STATE_RESET,
298 .ev_qualifiers = llc_common_ev_qfyrs_11b,
299 .ev_actions = llc_common_actions_11b,
300};
301
302/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */
303static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11c[] = {
304 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
305 [1] = NULL,
306};
307
308static llc_conn_action_t llc_common_actions_11c[] = {
309 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
310 [1] = llc_conn_ac_start_ack_timer,
311 [2] = llc_conn_ac_stop_other_timers,
312 [3] = llc_conn_ac_set_retry_cnt_0,
313 [4] = llc_conn_ac_set_cause_flag_0,
314 [5] = NULL,
315};
316
317static struct llc_conn_state_trans llc_common_state_trans_11c = {
318 .ev = llc_conn_ev_rej_tmr_exp,
319 .next_state = LLC_CONN_STATE_RESET,
320 .ev_qualifiers = llc_common_ev_qfyrs_11c,
321 .ev_actions = llc_common_actions_11c,
322};
323
324/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */
325static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11d[] = {
326 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
327 [1] = NULL,
328};
329
330static llc_conn_action_t llc_common_actions_11d[] = {
331 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
332 [1] = llc_conn_ac_start_ack_timer,
333 [2] = llc_conn_ac_stop_other_timers,
334 [3] = llc_conn_ac_set_retry_cnt_0,
335 [4] = llc_conn_ac_set_cause_flag_0,
336 [5] = NULL,
337};
338
339static struct llc_conn_state_trans llc_common_state_trans_11d = {
340 .ev = llc_conn_ev_busy_tmr_exp,
341 .next_state = LLC_CONN_STATE_RESET,
342 .ev_qualifiers = llc_common_ev_qfyrs_11d,
343 .ev_actions = llc_common_actions_11d,
344};
345
346/*
347 * Common dummy state transition; must be last entry for all state
348 * transition groups - it'll be on .bss, so will be zeroed.
349 */
350static struct llc_conn_state_trans llc_common_state_trans_end;
351
352/* LLC_CONN_STATE_ADM transitions */
353/* State transitions for LLC_CONN_EV_CONN_REQ event */
354static llc_conn_action_t llc_adm_actions_1[] = {
355 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
356 [1] = llc_conn_ac_start_ack_timer,
357 [2] = llc_conn_ac_set_retry_cnt_0,
358 [3] = llc_conn_ac_set_s_flag_0,
359 [4] = NULL,
360};
361
362static struct llc_conn_state_trans llc_adm_state_trans_1 = {
363 .ev = llc_conn_ev_conn_req,
364 .next_state = LLC_CONN_STATE_SETUP,
365 .ev_qualifiers = NONE,
366 .ev_actions = llc_adm_actions_1,
367};
368
369/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
370static llc_conn_action_t llc_adm_actions_2[] = {
371 [0] = llc_conn_ac_send_ua_rsp_f_set_p,
372 [1] = llc_conn_ac_set_vs_0,
373 [2] = llc_conn_ac_set_vr_0,
374 [3] = llc_conn_ac_set_retry_cnt_0,
375 [4] = llc_conn_ac_set_p_flag_0,
376 [5] = llc_conn_ac_set_remote_busy_0,
377 [6] = llc_conn_ac_conn_ind,
378 [7] = NULL,
379};
380
381static struct llc_conn_state_trans llc_adm_state_trans_2 = {
382 .ev = llc_conn_ev_rx_sabme_cmd_pbit_set_x,
383 .next_state = LLC_CONN_STATE_NORMAL,
384 .ev_qualifiers = NONE,
385 .ev_actions = llc_adm_actions_2,
386};
387
388/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
389static llc_conn_action_t llc_adm_actions_3[] = {
390 [0] = llc_conn_ac_send_dm_rsp_f_set_p,
391 [1] = llc_conn_disc,
392 [2] = NULL,
393};
394
395static struct llc_conn_state_trans llc_adm_state_trans_3 = {
396 .ev = llc_conn_ev_rx_disc_cmd_pbit_set_x,
397 .next_state = LLC_CONN_STATE_ADM,
398 .ev_qualifiers = NONE,
399 .ev_actions = llc_adm_actions_3,
400};
401
402/* State transitions for LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1 event */
403static llc_conn_action_t llc_adm_actions_4[] = {
404 [0] = llc_conn_ac_send_dm_rsp_f_set_1,
405 [1] = llc_conn_disc,
406 [2] = NULL,
407};
408
409static struct llc_conn_state_trans llc_adm_state_trans_4 = {
410 .ev = llc_conn_ev_rx_xxx_cmd_pbit_set_1,
411 .next_state = LLC_CONN_STATE_ADM,
412 .ev_qualifiers = NONE,
413 .ev_actions = llc_adm_actions_4,
414};
415
416/* State transitions for LLC_CONN_EV_RX_XXX_YYY event */
417static llc_conn_action_t llc_adm_actions_5[] = {
418 [0] = llc_conn_disc,
419 [1] = NULL,
420};
421
422static struct llc_conn_state_trans llc_adm_state_trans_5 = {
423 .ev = llc_conn_ev_rx_any_frame,
424 .next_state = LLC_CONN_OUT_OF_SVC,
425 .ev_qualifiers = NONE,
426 .ev_actions = llc_adm_actions_5,
427};
428
429/*
430 * Array of pointers;
431 * one to each transition
432 */
433static struct llc_conn_state_trans *llc_adm_state_transitions[] = {
434 [0] = &llc_adm_state_trans_1, /* Request */
435 [1] = &llc_common_state_trans_end,
436 [2] = &llc_common_state_trans_end, /* local_busy */
437 [3] = &llc_common_state_trans_end, /* init_pf_cycle */
438 [4] = &llc_common_state_trans_end, /* timer */
439 [5] = &llc_adm_state_trans_2, /* Receive frame */
440 [6] = &llc_adm_state_trans_3,
441 [7] = &llc_adm_state_trans_4,
442 [8] = &llc_adm_state_trans_5,
443 [9] = &llc_common_state_trans_end,
444};
445
446/* LLC_CONN_STATE_SETUP transitions */
447/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
448static llc_conn_action_t llc_setup_actions_1[] = {
449 [0] = llc_conn_ac_send_ua_rsp_f_set_p,
450 [1] = llc_conn_ac_set_vs_0,
451 [2] = llc_conn_ac_set_vr_0,
452 [3] = llc_conn_ac_set_s_flag_1,
453 [4] = NULL,
454};
455
456static struct llc_conn_state_trans llc_setup_state_trans_1 = {
457 .ev = llc_conn_ev_rx_sabme_cmd_pbit_set_x,
458 .next_state = LLC_CONN_STATE_SETUP,
459 .ev_qualifiers = NONE,
460 .ev_actions = llc_setup_actions_1,
461};
462
463/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event */
464static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_2[] = {
465 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
466 [1] = llc_conn_ev_qlfy_set_status_conn,
467 [2] = NULL,
468};
469
470static llc_conn_action_t llc_setup_actions_2[] = {
471 [0] = llc_conn_ac_stop_ack_timer,
472 [1] = llc_conn_ac_set_vs_0,
473 [2] = llc_conn_ac_set_vr_0,
474 [3] = llc_conn_ac_upd_p_flag,
475 [4] = llc_conn_ac_set_remote_busy_0,
476 [5] = llc_conn_ac_conn_confirm,
477 [6] = NULL,
478};
479
480static struct llc_conn_state_trans llc_setup_state_trans_2 = {
481 .ev = llc_conn_ev_rx_ua_rsp_fbit_set_x,
482 .next_state = LLC_CONN_STATE_NORMAL,
483 .ev_qualifiers = llc_setup_ev_qfyrs_2,
484 .ev_actions = llc_setup_actions_2,
485};
486
487/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
488static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_3[] = {
489 [0] = llc_conn_ev_qlfy_s_flag_eq_1,
490 [1] = llc_conn_ev_qlfy_set_status_conn,
491 [2] = NULL,
492};
493
494static llc_conn_action_t llc_setup_actions_3[] = {
495 [0] = llc_conn_ac_set_p_flag_0,
496 [1] = llc_conn_ac_set_remote_busy_0,
497 [2] = llc_conn_ac_conn_confirm,
498 [3] = NULL,
499};
500
501static struct llc_conn_state_trans llc_setup_state_trans_3 = {
502 .ev = llc_conn_ev_ack_tmr_exp,
503 .next_state = LLC_CONN_STATE_NORMAL,
504 .ev_qualifiers = llc_setup_ev_qfyrs_3,
505 .ev_actions = llc_setup_actions_3,
506};
507
508/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
509static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_4[] = {
510 [0] = llc_conn_ev_qlfy_set_status_disc,
511 [1] = NULL,
512};
513
514static llc_conn_action_t llc_setup_actions_4[] = {
515 [0] = llc_conn_ac_send_dm_rsp_f_set_p,
516 [1] = llc_conn_ac_stop_ack_timer,
517 [2] = llc_conn_ac_conn_confirm,
518 [3] = llc_conn_disc,
519 [4] = NULL,
520};
521
522static struct llc_conn_state_trans llc_setup_state_trans_4 = {
523 .ev = llc_conn_ev_rx_disc_cmd_pbit_set_x,
524 .next_state = LLC_CONN_STATE_ADM,
525 .ev_qualifiers = llc_setup_ev_qfyrs_4,
526 .ev_actions = llc_setup_actions_4,
527};
528
529/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event */
530static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_5[] = {
531 [0] = llc_conn_ev_qlfy_set_status_disc,
532 [1] = NULL,
533};
534
535static llc_conn_action_t llc_setup_actions_5[] = {
536 [0] = llc_conn_ac_stop_ack_timer,
537 [1] = llc_conn_ac_conn_confirm,
538 [2] = llc_conn_disc,
539 [3] = NULL,
540};
541
542static struct llc_conn_state_trans llc_setup_state_trans_5 = {
543 .ev = llc_conn_ev_rx_dm_rsp_fbit_set_x,
544 .next_state = LLC_CONN_STATE_ADM,
545 .ev_qualifiers = llc_setup_ev_qfyrs_5,
546 .ev_actions = llc_setup_actions_5,
547};
548
549/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
550static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_7[] = {
551 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
552 [1] = llc_conn_ev_qlfy_s_flag_eq_0,
553 [2] = NULL,
554};
555
556static llc_conn_action_t llc_setup_actions_7[] = {
557 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
558 [1] = llc_conn_ac_start_ack_timer,
559 [2] = llc_conn_ac_inc_retry_cnt_by_1,
560 [3] = NULL,
561};
562
563static struct llc_conn_state_trans llc_setup_state_trans_7 = {
564 .ev = llc_conn_ev_ack_tmr_exp,
565 .next_state = LLC_CONN_STATE_SETUP,
566 .ev_qualifiers = llc_setup_ev_qfyrs_7,
567 .ev_actions = llc_setup_actions_7,
568};
569
570/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
571static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_8[] = {
572 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
573 [1] = llc_conn_ev_qlfy_s_flag_eq_0,
574 [2] = llc_conn_ev_qlfy_set_status_failed,
575 [3] = NULL,
576};
577
578static llc_conn_action_t llc_setup_actions_8[] = {
579 [0] = llc_conn_ac_conn_confirm,
580 [1] = llc_conn_disc,
581 [2] = NULL,
582};
583
584static struct llc_conn_state_trans llc_setup_state_trans_8 = {
585 .ev = llc_conn_ev_ack_tmr_exp,
586 .next_state = LLC_CONN_STATE_ADM,
587 .ev_qualifiers = llc_setup_ev_qfyrs_8,
588 .ev_actions = llc_setup_actions_8,
589};
590
591/*
592 * Array of pointers;
593 * one to each transition
594 */
595static struct llc_conn_state_trans *llc_setup_state_transitions[] = {
596 [0] = &llc_common_state_trans_end, /* Request */
597 [1] = &llc_common_state_trans_end, /* local busy */
598 [2] = &llc_common_state_trans_end, /* init_pf_cycle */
599 [3] = &llc_setup_state_trans_3, /* Timer */
600 [4] = &llc_setup_state_trans_7,
601 [5] = &llc_setup_state_trans_8,
602 [6] = &llc_common_state_trans_end,
603 [7] = &llc_setup_state_trans_1, /* Receive frame */
604 [8] = &llc_setup_state_trans_2,
605 [9] = &llc_setup_state_trans_4,
606 [10] = &llc_setup_state_trans_5,
607 [11] = &llc_common_state_trans_end,
608};
609
610/* LLC_CONN_STATE_NORMAL transitions */
611/* State transitions for LLC_CONN_EV_DATA_REQ event */
612static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_1[] = {
613 [0] = llc_conn_ev_qlfy_remote_busy_eq_0,
614 [1] = llc_conn_ev_qlfy_p_flag_eq_0,
615 [2] = llc_conn_ev_qlfy_last_frame_eq_0,
616 [3] = NULL,
617};
618
619static llc_conn_action_t llc_normal_actions_1[] = {
620 [0] = llc_conn_ac_send_i_as_ack,
621 [1] = llc_conn_ac_start_ack_tmr_if_not_running,
622 [2] = NULL,
623};
624
625static struct llc_conn_state_trans llc_normal_state_trans_1 = {
626 .ev = llc_conn_ev_data_req,
627 .next_state = LLC_CONN_STATE_NORMAL,
628 .ev_qualifiers = llc_normal_ev_qfyrs_1,
629 .ev_actions = llc_normal_actions_1,
630};
631
632/* State transitions for LLC_CONN_EV_DATA_REQ event */
633static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_2[] = {
634 [0] = llc_conn_ev_qlfy_remote_busy_eq_0,
635 [1] = llc_conn_ev_qlfy_p_flag_eq_0,
636 [2] = llc_conn_ev_qlfy_last_frame_eq_1,
637 [3] = NULL,
638};
639
640static llc_conn_action_t llc_normal_actions_2[] = {
641 [0] = llc_conn_ac_send_i_cmd_p_set_1,
642 [1] = llc_conn_ac_start_p_timer,
643 [2] = NULL,
644};
645
646static struct llc_conn_state_trans llc_normal_state_trans_2 = {
647 .ev = llc_conn_ev_data_req,
648 .next_state = LLC_CONN_STATE_NORMAL,
649 .ev_qualifiers = llc_normal_ev_qfyrs_2,
650 .ev_actions = llc_normal_actions_2,
651};
652
653/* State transitions for LLC_CONN_EV_DATA_REQ event */
654static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_2_1[] = {
655 [0] = llc_conn_ev_qlfy_remote_busy_eq_1,
656 [1] = llc_conn_ev_qlfy_set_status_remote_busy,
657 [2] = NULL,
658};
659
660/* just one member, NULL, .bss zeroes it */
661static llc_conn_action_t llc_normal_actions_2_1[1];
662
663static struct llc_conn_state_trans llc_normal_state_trans_2_1 = {
664 .ev = llc_conn_ev_data_req,
665 .next_state = LLC_CONN_STATE_NORMAL,
666 .ev_qualifiers = llc_normal_ev_qfyrs_2_1,
667 .ev_actions = llc_normal_actions_2_1,
668};
669
670/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
671static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_3[] = {
672 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
673 [1] = NULL,
674};
675
676static llc_conn_action_t llc_normal_actions_3[] = {
677 [0] = llc_conn_ac_rst_sendack_flag,
678 [1] = llc_conn_ac_send_rnr_xxx_x_set_0,
679 [2] = llc_conn_ac_set_data_flag_0,
680 [3] = NULL,
681};
682
683static struct llc_conn_state_trans llc_normal_state_trans_3 = {
684 .ev = llc_conn_ev_local_busy_detected,
685 .next_state = LLC_CONN_STATE_BUSY,
686 .ev_qualifiers = llc_normal_ev_qfyrs_3,
687 .ev_actions = llc_normal_actions_3,
688};
689
690/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
691static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_4[] = {
692 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
693 [1] = NULL,
694};
695
696static llc_conn_action_t llc_normal_actions_4[] = {
697 [0] = llc_conn_ac_rst_sendack_flag,
698 [1] = llc_conn_ac_send_rnr_xxx_x_set_0,
699 [2] = llc_conn_ac_set_data_flag_0,
700 [3] = NULL,
701};
702
703static struct llc_conn_state_trans llc_normal_state_trans_4 = {
704 .ev = llc_conn_ev_local_busy_detected,
705 .next_state = LLC_CONN_STATE_BUSY,
706 .ev_qualifiers = llc_normal_ev_qfyrs_4,
707 .ev_actions = llc_normal_actions_4,
708};
709
710/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
711static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_5a[] = {
712 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
713 [1] = NULL,
714};
715
716static llc_conn_action_t llc_normal_actions_5a[] = {
717 [0] = llc_conn_ac_rst_sendack_flag,
718 [1] = llc_conn_ac_send_rej_xxx_x_set_0,
719 [2] = llc_conn_ac_upd_nr_received,
720 [3] = llc_conn_ac_upd_p_flag,
721 [4] = llc_conn_ac_start_rej_timer,
722 [5] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
723 [6] = NULL,
724};
725
726static struct llc_conn_state_trans llc_normal_state_trans_5a = {
727 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
728 .next_state = LLC_CONN_STATE_REJ,
729 .ev_qualifiers = llc_normal_ev_qfyrs_5a,
730 .ev_actions = llc_normal_actions_5a,
731};
732
733/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
734static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_5b[] = {
735 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
736 [1] = NULL,
737};
738
739static llc_conn_action_t llc_normal_actions_5b[] = {
740 [0] = llc_conn_ac_rst_sendack_flag,
741 [1] = llc_conn_ac_send_rej_xxx_x_set_0,
742 [2] = llc_conn_ac_upd_nr_received,
743 [3] = llc_conn_ac_upd_p_flag,
744 [4] = llc_conn_ac_start_rej_timer,
745 [5] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
746 [6] = NULL,
747};
748
749static struct llc_conn_state_trans llc_normal_state_trans_5b = {
750 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
751 .next_state = LLC_CONN_STATE_REJ,
752 .ev_qualifiers = llc_normal_ev_qfyrs_5b,
753 .ev_actions = llc_normal_actions_5b,
754};
755
756/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
757static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_5c[] = {
758 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
759 [1] = NULL,
760};
761
762static llc_conn_action_t llc_normal_actions_5c[] = {
763 [0] = llc_conn_ac_rst_sendack_flag,
764 [1] = llc_conn_ac_send_rej_xxx_x_set_0,
765 [2] = llc_conn_ac_upd_nr_received,
766 [3] = llc_conn_ac_upd_p_flag,
767 [4] = llc_conn_ac_start_rej_timer,
768 [5] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
769 [6] = NULL,
770};
771
772static struct llc_conn_state_trans llc_normal_state_trans_5c = {
773 .ev = llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
774 .next_state = LLC_CONN_STATE_REJ,
775 .ev_qualifiers = llc_normal_ev_qfyrs_5c,
776 .ev_actions = llc_normal_actions_5c,
777};
778
779/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
780static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_6a[] = {
781 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
782 [1] = NULL,
783};
784
785static llc_conn_action_t llc_normal_actions_6a[] = {
786 [0] = llc_conn_ac_rst_sendack_flag,
787 [1] = llc_conn_ac_send_rej_xxx_x_set_0,
788 [2] = llc_conn_ac_upd_nr_received,
789 [3] = llc_conn_ac_start_rej_timer,
790 [4] = NULL,
791};
792
793static struct llc_conn_state_trans llc_normal_state_trans_6a = {
794 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
795 .next_state = LLC_CONN_STATE_REJ,
796 .ev_qualifiers = llc_normal_ev_qfyrs_6a,
797 .ev_actions = llc_normal_actions_6a,
798};
799
800/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
801static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_6b[] = {
802 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
803 [1] = NULL,
804};
805
806static llc_conn_action_t llc_normal_actions_6b[] = {
807 [0] = llc_conn_ac_rst_sendack_flag,
808 [1] = llc_conn_ac_send_rej_xxx_x_set_0,
809 [2] = llc_conn_ac_upd_nr_received,
810 [3] = llc_conn_ac_start_rej_timer,
811 [4] = NULL,
812};
813
814static struct llc_conn_state_trans llc_normal_state_trans_6b = {
815 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
816 .next_state = LLC_CONN_STATE_REJ,
817 .ev_qualifiers = llc_normal_ev_qfyrs_6b,
818 .ev_actions = llc_normal_actions_6b,
819};
820
821/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
822static llc_conn_action_t llc_normal_actions_7[] = {
823 [0] = llc_conn_ac_rst_sendack_flag,
824 [1] = llc_conn_ac_send_rej_rsp_f_set_1,
825 [2] = llc_conn_ac_upd_nr_received,
826 [3] = llc_conn_ac_start_rej_timer,
827 [4] = NULL,
828};
829
830static struct llc_conn_state_trans llc_normal_state_trans_7 = {
831 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
832 .next_state = LLC_CONN_STATE_REJ,
833 .ev_qualifiers = NONE,
834 .ev_actions = llc_normal_actions_7,
835};
836
837/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X event */
838static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_8a[] = {
839 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
840 [1] = NULL,
841};
842
843static llc_conn_action_t llc_normal_actions_8[] = {
844 [0] = llc_conn_ac_inc_vr_by_1,
845 [1] = llc_conn_ac_data_ind,
846 [2] = llc_conn_ac_upd_p_flag,
847 [3] = llc_conn_ac_upd_nr_received,
848 [4] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
849 [5] = llc_conn_ac_send_ack_if_needed,
850 [6] = NULL,
851};
852
853static struct llc_conn_state_trans llc_normal_state_trans_8a = {
854 .ev = llc_conn_ev_rx_i_rsp_fbit_set_x,
855 .next_state = LLC_CONN_STATE_NORMAL,
856 .ev_qualifiers = llc_normal_ev_qfyrs_8a,
857 .ev_actions = llc_normal_actions_8,
858};
859
860/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
861static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_8b[] = {
862 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
863 [1] = NULL,
864};
865
866static struct llc_conn_state_trans llc_normal_state_trans_8b = {
867 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0,
868 .next_state = LLC_CONN_STATE_NORMAL,
869 .ev_qualifiers = llc_normal_ev_qfyrs_8b,
870 .ev_actions = llc_normal_actions_8,
871};
872
873/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
874static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_9a[] = {
875 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
876 [1] = NULL,
877};
878
879static llc_conn_action_t llc_normal_actions_9a[] = {
880 [0] = llc_conn_ac_inc_vr_by_1,
881 [1] = llc_conn_ac_upd_nr_received,
882 [2] = llc_conn_ac_data_ind,
883 [3] = llc_conn_ac_send_ack_if_needed,
884 [4] = NULL,
885};
886
887static struct llc_conn_state_trans llc_normal_state_trans_9a = {
888 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0,
889 .next_state = LLC_CONN_STATE_NORMAL,
890 .ev_qualifiers = llc_normal_ev_qfyrs_9a,
891 .ev_actions = llc_normal_actions_9a,
892};
893
894/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
895static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_9b[] = {
896 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
897 [1] = NULL,
898};
899
900static llc_conn_action_t llc_normal_actions_9b[] = {
901 [0] = llc_conn_ac_inc_vr_by_1,
902 [1] = llc_conn_ac_upd_nr_received,
903 [2] = llc_conn_ac_data_ind,
904 [3] = llc_conn_ac_send_ack_if_needed,
905 [4] = NULL,
906};
907
908static struct llc_conn_state_trans llc_normal_state_trans_9b = {
909 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0,
910 .next_state = LLC_CONN_STATE_NORMAL,
911 .ev_qualifiers = llc_normal_ev_qfyrs_9b,
912 .ev_actions = llc_normal_actions_9b,
913};
914
915/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
916static llc_conn_action_t llc_normal_actions_10[] = {
917 [0] = llc_conn_ac_inc_vr_by_1,
918 [1] = llc_conn_ac_send_ack_rsp_f_set_1,
919 [2] = llc_conn_ac_rst_sendack_flag,
920 [3] = llc_conn_ac_upd_nr_received,
921 [4] = llc_conn_ac_data_ind,
922 [5] = NULL,
923};
924
925static struct llc_conn_state_trans llc_normal_state_trans_10 = {
926 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1,
927 .next_state = LLC_CONN_STATE_NORMAL,
928 .ev_qualifiers = NONE,
929 .ev_actions = llc_normal_actions_10,
930};
931
932/* State transitions for * LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
933static llc_conn_action_t llc_normal_actions_11a[] = {
934 [0] = llc_conn_ac_upd_p_flag,
935 [1] = llc_conn_ac_upd_nr_received,
936 [2] = llc_conn_ac_clear_remote_busy,
937 [3] = NULL,
938};
939
940static struct llc_conn_state_trans llc_normal_state_trans_11a = {
941 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_0,
942 .next_state = LLC_CONN_STATE_NORMAL,
943 .ev_qualifiers = NONE,
944 .ev_actions = llc_normal_actions_11a,
945};
946
947/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
948static llc_conn_action_t llc_normal_actions_11b[] = {
949 [0] = llc_conn_ac_upd_p_flag,
950 [1] = llc_conn_ac_upd_nr_received,
951 [2] = llc_conn_ac_clear_remote_busy,
952 [3] = NULL,
953};
954
955static struct llc_conn_state_trans llc_normal_state_trans_11b = {
956 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_0,
957 .next_state = LLC_CONN_STATE_NORMAL,
958 .ev_qualifiers = NONE,
959 .ev_actions = llc_normal_actions_11b,
960};
961
962/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
963static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_11c[] = {
964 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
965 [1] = NULL,
966};
967
968static llc_conn_action_t llc_normal_actions_11c[] = {
969 [0] = llc_conn_ac_upd_p_flag,
970 [1] = llc_conn_ac_upd_nr_received,
971 [2] = llc_conn_ac_inc_tx_win_size,
972 [3] = llc_conn_ac_clear_remote_busy,
973 [4] = NULL,
974};
975
976static struct llc_conn_state_trans llc_normal_state_trans_11c = {
977 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_1,
978 .next_state = LLC_CONN_STATE_NORMAL,
979 .ev_qualifiers = llc_normal_ev_qfyrs_11c,
980 .ev_actions = llc_normal_actions_11c,
981};
982
983/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
984static llc_conn_action_t llc_normal_actions_12[] = {
985 [0] = llc_conn_ac_send_ack_rsp_f_set_1,
986 [1] = llc_conn_ac_upd_nr_received,
987 [2] = llc_conn_ac_adjust_npta_by_rr,
988 [3] = llc_conn_ac_rst_sendack_flag,
989 [4] = llc_conn_ac_clear_remote_busy,
990 [5] = NULL,
991};
992
993static struct llc_conn_state_trans llc_normal_state_trans_12 = {
994 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_1,
995 .next_state = LLC_CONN_STATE_NORMAL,
996 .ev_qualifiers = NONE,
997 .ev_actions = llc_normal_actions_12,
998};
999
1000/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
1001static llc_conn_action_t llc_normal_actions_13a[] = {
1002 [0] = llc_conn_ac_upd_p_flag,
1003 [1] = llc_conn_ac_upd_nr_received,
1004 [2] = llc_conn_ac_set_remote_busy,
1005 [3] = NULL,
1006};
1007
1008static struct llc_conn_state_trans llc_normal_state_trans_13a = {
1009 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_0,
1010 .next_state = LLC_CONN_STATE_NORMAL,
1011 .ev_qualifiers = NONE,
1012 .ev_actions = llc_normal_actions_13a,
1013};
1014
1015/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
1016static llc_conn_action_t llc_normal_actions_13b[] = {
1017 [0] = llc_conn_ac_upd_p_flag,
1018 [1] = llc_conn_ac_upd_nr_received,
1019 [2] = llc_conn_ac_set_remote_busy,
1020 [3] = NULL,
1021};
1022
1023static struct llc_conn_state_trans llc_normal_state_trans_13b = {
1024 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_0,
1025 .next_state = LLC_CONN_STATE_NORMAL,
1026 .ev_qualifiers = NONE,
1027 .ev_actions = llc_normal_actions_13b,
1028};
1029
1030/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
1031static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_13c[] = {
1032 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1033 [1] = NULL,
1034};
1035
1036static llc_conn_action_t llc_normal_actions_13c[] = {
1037 [0] = llc_conn_ac_upd_p_flag,
1038 [1] = llc_conn_ac_upd_nr_received,
1039 [2] = llc_conn_ac_set_remote_busy,
1040 [3] = NULL,
1041};
1042
1043static struct llc_conn_state_trans llc_normal_state_trans_13c = {
1044 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_1,
1045 .next_state = LLC_CONN_STATE_NORMAL,
1046 .ev_qualifiers = llc_normal_ev_qfyrs_13c,
1047 .ev_actions = llc_normal_actions_13c,
1048};
1049
1050/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
1051static llc_conn_action_t llc_normal_actions_14[] = {
1052 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
1053 [1] = llc_conn_ac_upd_nr_received,
1054 [2] = llc_conn_ac_adjust_npta_by_rnr,
1055 [3] = llc_conn_ac_rst_sendack_flag,
1056 [4] = llc_conn_ac_set_remote_busy,
1057 [5] = NULL,
1058};
1059
1060static struct llc_conn_state_trans llc_normal_state_trans_14 = {
1061 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_1,
1062 .next_state = LLC_CONN_STATE_NORMAL,
1063 .ev_qualifiers = NONE,
1064 .ev_actions = llc_normal_actions_14,
1065};
1066
1067/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
1068static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_15a[] = {
1069 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
1070 [1] = NULL,
1071};
1072
1073static llc_conn_action_t llc_normal_actions_15a[] = {
1074 [0] = llc_conn_ac_set_vs_nr,
1075 [1] = llc_conn_ac_upd_nr_received,
1076 [2] = llc_conn_ac_upd_p_flag,
1077 [3] = llc_conn_ac_dec_tx_win_size,
1078 [4] = llc_conn_ac_resend_i_xxx_x_set_0,
1079 [5] = llc_conn_ac_clear_remote_busy,
1080 [6] = NULL,
1081};
1082
1083static struct llc_conn_state_trans llc_normal_state_trans_15a = {
1084 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_0,
1085 .next_state = LLC_CONN_STATE_NORMAL,
1086 .ev_qualifiers = llc_normal_ev_qfyrs_15a,
1087 .ev_actions = llc_normal_actions_15a,
1088};
1089
1090/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X event */
1091static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_15b[] = {
1092 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
1093 [1] = NULL,
1094};
1095
1096static llc_conn_action_t llc_normal_actions_15b[] = {
1097 [0] = llc_conn_ac_set_vs_nr,
1098 [1] = llc_conn_ac_upd_nr_received,
1099 [2] = llc_conn_ac_upd_p_flag,
1100 [3] = llc_conn_ac_dec_tx_win_size,
1101 [4] = llc_conn_ac_resend_i_xxx_x_set_0,
1102 [5] = llc_conn_ac_clear_remote_busy,
1103 [6] = NULL,
1104};
1105
1106static struct llc_conn_state_trans llc_normal_state_trans_15b = {
1107 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_x,
1108 .next_state = LLC_CONN_STATE_NORMAL,
1109 .ev_qualifiers = llc_normal_ev_qfyrs_15b,
1110 .ev_actions = llc_normal_actions_15b,
1111};
1112
1113/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
1114static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_16a[] = {
1115 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1116 [1] = NULL,
1117};
1118
1119static llc_conn_action_t llc_normal_actions_16a[] = {
1120 [0] = llc_conn_ac_set_vs_nr,
1121 [1] = llc_conn_ac_upd_nr_received,
1122 [2] = llc_conn_ac_dec_tx_win_size,
1123 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
1124 [4] = llc_conn_ac_clear_remote_busy,
1125 [5] = NULL,
1126};
1127
1128static struct llc_conn_state_trans llc_normal_state_trans_16a = {
1129 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_0,
1130 .next_state = LLC_CONN_STATE_NORMAL,
1131 .ev_qualifiers = llc_normal_ev_qfyrs_16a,
1132 .ev_actions = llc_normal_actions_16a,
1133};
1134
1135/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
1136static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_16b[] = {
1137 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1138 [1] = NULL,
1139};
1140
1141static llc_conn_action_t llc_normal_actions_16b[] = {
1142 [0] = llc_conn_ac_set_vs_nr,
1143 [1] = llc_conn_ac_upd_nr_received,
1144 [2] = llc_conn_ac_dec_tx_win_size,
1145 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
1146 [4] = llc_conn_ac_clear_remote_busy,
1147 [5] = NULL,
1148};
1149
1150static struct llc_conn_state_trans llc_normal_state_trans_16b = {
1151 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_0,
1152 .next_state = LLC_CONN_STATE_NORMAL,
1153 .ev_qualifiers = llc_normal_ev_qfyrs_16b,
1154 .ev_actions = llc_normal_actions_16b,
1155};
1156
1157/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
1158static llc_conn_action_t llc_normal_actions_17[] = {
1159 [0] = llc_conn_ac_set_vs_nr,
1160 [1] = llc_conn_ac_upd_nr_received,
1161 [2] = llc_conn_ac_dec_tx_win_size,
1162 [3] = llc_conn_ac_resend_i_rsp_f_set_1,
1163 [4] = llc_conn_ac_clear_remote_busy,
1164 [5] = NULL,
1165};
1166
1167static struct llc_conn_state_trans llc_normal_state_trans_17 = {
1168 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_1,
1169 .next_state = LLC_CONN_STATE_NORMAL,
1170 .ev_qualifiers = NONE,
1171 .ev_actions = llc_normal_actions_17,
1172};
1173
1174/* State transitions for LLC_CONN_EV_INIT_P_F_CYCLE event */
1175static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_18[] = {
1176 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
1177 [1] = NULL,
1178};
1179
1180static llc_conn_action_t llc_normal_actions_18[] = {
1181 [0] = llc_conn_ac_send_rr_cmd_p_set_1,
1182 [1] = llc_conn_ac_start_p_timer,
1183 [2] = NULL,
1184};
1185
1186static struct llc_conn_state_trans llc_normal_state_trans_18 = {
1187 .ev = llc_conn_ev_init_p_f_cycle,
1188 .next_state = LLC_CONN_STATE_NORMAL,
1189 .ev_qualifiers = llc_normal_ev_qfyrs_18,
1190 .ev_actions = llc_normal_actions_18,
1191};
1192
1193/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
1194static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_19[] = {
1195 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
1196 [1] = NULL,
1197};
1198
1199static llc_conn_action_t llc_normal_actions_19[] = {
1200 [0] = llc_conn_ac_rst_sendack_flag,
1201 [1] = llc_conn_ac_send_rr_cmd_p_set_1,
1202 [2] = llc_conn_ac_rst_vs,
1203 [3] = llc_conn_ac_start_p_timer,
1204 [4] = llc_conn_ac_inc_retry_cnt_by_1,
1205 [5] = NULL,
1206};
1207
1208static struct llc_conn_state_trans llc_normal_state_trans_19 = {
1209 .ev = llc_conn_ev_p_tmr_exp,
1210 .next_state = LLC_CONN_STATE_AWAIT,
1211 .ev_qualifiers = llc_normal_ev_qfyrs_19,
1212 .ev_actions = llc_normal_actions_19,
1213};
1214
1215/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
1216static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_20a[] = {
1217 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
1218 [1] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
1219 [2] = NULL,
1220};
1221
1222static llc_conn_action_t llc_normal_actions_20a[] = {
1223 [0] = llc_conn_ac_rst_sendack_flag,
1224 [1] = llc_conn_ac_send_rr_cmd_p_set_1,
1225 [2] = llc_conn_ac_rst_vs,
1226 [3] = llc_conn_ac_start_p_timer,
1227 [4] = llc_conn_ac_inc_retry_cnt_by_1,
1228 [5] = NULL,
1229};
1230
1231static struct llc_conn_state_trans llc_normal_state_trans_20a = {
1232 .ev = llc_conn_ev_ack_tmr_exp,
1233 .next_state = LLC_CONN_STATE_AWAIT,
1234 .ev_qualifiers = llc_normal_ev_qfyrs_20a,
1235 .ev_actions = llc_normal_actions_20a,
1236};
1237
1238/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */
1239static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_20b[] = {
1240 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
1241 [1] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
1242 [2] = NULL,
1243};
1244
1245static llc_conn_action_t llc_normal_actions_20b[] = {
1246 [0] = llc_conn_ac_rst_sendack_flag,
1247 [1] = llc_conn_ac_send_rr_cmd_p_set_1,
1248 [2] = llc_conn_ac_rst_vs,
1249 [3] = llc_conn_ac_start_p_timer,
1250 [4] = llc_conn_ac_inc_retry_cnt_by_1,
1251 [5] = NULL,
1252};
1253
1254static struct llc_conn_state_trans llc_normal_state_trans_20b = {
1255 .ev = llc_conn_ev_busy_tmr_exp,
1256 .next_state = LLC_CONN_STATE_AWAIT,
1257 .ev_qualifiers = llc_normal_ev_qfyrs_20b,
1258 .ev_actions = llc_normal_actions_20b,
1259};
1260
1261/* State transitions for LLC_CONN_EV_TX_BUFF_FULL event */
1262static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_21[] = {
1263 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
1264 [1] = NULL,
1265};
1266
1267static llc_conn_action_t llc_normal_actions_21[] = {
1268 [0] = llc_conn_ac_send_rr_cmd_p_set_1,
1269 [1] = llc_conn_ac_start_p_timer,
1270 [2] = NULL,
1271};
1272
1273static struct llc_conn_state_trans llc_normal_state_trans_21 = {
1274 .ev = llc_conn_ev_tx_buffer_full,
1275 .next_state = LLC_CONN_STATE_NORMAL,
1276 .ev_qualifiers = llc_normal_ev_qfyrs_21,
1277 .ev_actions = llc_normal_actions_21,
1278};
1279
1280/*
1281 * Array of pointers;
1282 * one to each transition
1283 */
1284static struct llc_conn_state_trans *llc_normal_state_transitions[] = {
1285 [0] = &llc_normal_state_trans_1, /* Requests */
1286 [1] = &llc_normal_state_trans_2,
1287 [2] = &llc_normal_state_trans_2_1,
1288 [3] = &llc_common_state_trans_1,
1289 [4] = &llc_common_state_trans_2,
1290 [5] = &llc_common_state_trans_end,
1291 [6] = &llc_normal_state_trans_21,
1292 [7] = &llc_normal_state_trans_3, /* Local busy */
1293 [8] = &llc_normal_state_trans_4,
1294 [9] = &llc_common_state_trans_end,
1295 [10] = &llc_normal_state_trans_18, /* Init pf cycle */
1296 [11] = &llc_common_state_trans_end,
1297 [12] = &llc_common_state_trans_11a, /* Timers */
1298 [13] = &llc_common_state_trans_11b,
1299 [14] = &llc_common_state_trans_11c,
1300 [15] = &llc_common_state_trans_11d,
1301 [16] = &llc_normal_state_trans_19,
1302 [17] = &llc_normal_state_trans_20a,
1303 [18] = &llc_normal_state_trans_20b,
1304 [19] = &llc_common_state_trans_end,
1305 [20] = &llc_normal_state_trans_8b, /* Receive frames */
1306 [21] = &llc_normal_state_trans_9b,
1307 [22] = &llc_normal_state_trans_10,
1308 [23] = &llc_normal_state_trans_11b,
1309 [24] = &llc_normal_state_trans_11c,
1310 [25] = &llc_normal_state_trans_5a,
1311 [26] = &llc_normal_state_trans_5b,
1312 [27] = &llc_normal_state_trans_5c,
1313 [28] = &llc_normal_state_trans_6a,
1314 [29] = &llc_normal_state_trans_6b,
1315 [30] = &llc_normal_state_trans_7,
1316 [31] = &llc_normal_state_trans_8a,
1317 [32] = &llc_normal_state_trans_9a,
1318 [33] = &llc_normal_state_trans_11a,
1319 [34] = &llc_normal_state_trans_12,
1320 [35] = &llc_normal_state_trans_13a,
1321 [36] = &llc_normal_state_trans_13b,
1322 [37] = &llc_normal_state_trans_13c,
1323 [38] = &llc_normal_state_trans_14,
1324 [39] = &llc_normal_state_trans_15a,
1325 [40] = &llc_normal_state_trans_15b,
1326 [41] = &llc_normal_state_trans_16a,
1327 [42] = &llc_normal_state_trans_16b,
1328 [43] = &llc_normal_state_trans_17,
1329 [44] = &llc_common_state_trans_3,
1330 [45] = &llc_common_state_trans_4,
1331 [46] = &llc_common_state_trans_5,
1332 [47] = &llc_common_state_trans_6,
1333 [48] = &llc_common_state_trans_7a,
1334 [49] = &llc_common_state_trans_7b,
1335 [50] = &llc_common_state_trans_8a,
1336 [51] = &llc_common_state_trans_8b,
1337 [52] = &llc_common_state_trans_8c,
1338 [53] = &llc_common_state_trans_9,
1339 /* [54] = &llc_common_state_trans_10, */
1340 [54] = &llc_common_state_trans_end,
1341};
1342
1343/* LLC_CONN_STATE_BUSY transitions */
1344/* State transitions for LLC_CONN_EV_DATA_REQ event */
1345static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_1[] = {
1346 [0] = llc_conn_ev_qlfy_remote_busy_eq_0,
1347 [1] = llc_conn_ev_qlfy_p_flag_eq_0,
1348 [2] = NULL,
1349};
1350
1351static llc_conn_action_t llc_busy_actions_1[] = {
1352 [0] = llc_conn_ac_send_i_xxx_x_set_0,
1353 [1] = llc_conn_ac_start_ack_tmr_if_not_running,
1354 [2] = NULL,
1355};
1356
1357static struct llc_conn_state_trans llc_busy_state_trans_1 = {
1358 .ev = llc_conn_ev_data_req,
1359 .next_state = LLC_CONN_STATE_BUSY,
1360 .ev_qualifiers = llc_busy_ev_qfyrs_1,
1361 .ev_actions = llc_busy_actions_1,
1362};
1363
1364/* State transitions for LLC_CONN_EV_DATA_REQ event */
1365static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_2[] = {
1366 [0] = llc_conn_ev_qlfy_remote_busy_eq_0,
1367 [1] = llc_conn_ev_qlfy_p_flag_eq_1,
1368 [2] = NULL,
1369};
1370
1371static llc_conn_action_t llc_busy_actions_2[] = {
1372 [0] = llc_conn_ac_send_i_xxx_x_set_0,
1373 [1] = llc_conn_ac_start_ack_tmr_if_not_running,
1374 [2] = NULL,
1375};
1376
1377static struct llc_conn_state_trans llc_busy_state_trans_2 = {
1378 .ev = llc_conn_ev_data_req,
1379 .next_state = LLC_CONN_STATE_BUSY,
1380 .ev_qualifiers = llc_busy_ev_qfyrs_2,
1381 .ev_actions = llc_busy_actions_2,
1382};
1383
1384/* State transitions for LLC_CONN_EV_DATA_REQ event */
1385static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_2_1[] = {
1386 [0] = llc_conn_ev_qlfy_remote_busy_eq_1,
1387 [1] = llc_conn_ev_qlfy_set_status_remote_busy,
1388 [2] = NULL,
1389};
1390
1391/* just one member, NULL, .bss zeroes it */
1392static llc_conn_action_t llc_busy_actions_2_1[1];
1393
1394static struct llc_conn_state_trans llc_busy_state_trans_2_1 = {
1395 .ev = llc_conn_ev_data_req,
1396 .next_state = LLC_CONN_STATE_BUSY,
1397 .ev_qualifiers = llc_busy_ev_qfyrs_2_1,
1398 .ev_actions = llc_busy_actions_2_1,
1399};
1400
1401/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
1402static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_3[] = {
1403 [0] = llc_conn_ev_qlfy_data_flag_eq_1,
1404 [1] = llc_conn_ev_qlfy_p_flag_eq_0,
1405 [2] = NULL,
1406};
1407
1408static llc_conn_action_t llc_busy_actions_3[] = {
1409 [0] = llc_conn_ac_send_rej_xxx_x_set_0,
1410 [1] = llc_conn_ac_start_rej_timer,
1411 [2] = NULL,
1412};
1413
1414static struct llc_conn_state_trans llc_busy_state_trans_3 = {
1415 .ev = llc_conn_ev_local_busy_cleared,
1416 .next_state = LLC_CONN_STATE_REJ,
1417 .ev_qualifiers = llc_busy_ev_qfyrs_3,
1418 .ev_actions = llc_busy_actions_3,
1419};
1420
1421/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
1422static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_4[] = {
1423 [0] = llc_conn_ev_qlfy_data_flag_eq_1,
1424 [1] = llc_conn_ev_qlfy_p_flag_eq_1,
1425 [2] = NULL,
1426};
1427
1428static llc_conn_action_t llc_busy_actions_4[] = {
1429 [0] = llc_conn_ac_send_rej_xxx_x_set_0,
1430 [1] = llc_conn_ac_start_rej_timer,
1431 [2] = NULL,
1432};
1433
1434static struct llc_conn_state_trans llc_busy_state_trans_4 = {
1435 .ev = llc_conn_ev_local_busy_cleared,
1436 .next_state = LLC_CONN_STATE_REJ,
1437 .ev_qualifiers = llc_busy_ev_qfyrs_4,
1438 .ev_actions = llc_busy_actions_4,
1439};
1440
1441/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
1442static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_5[] = {
1443 [0] = llc_conn_ev_qlfy_data_flag_eq_0,
1444 [1] = llc_conn_ev_qlfy_p_flag_eq_0,
1445 [2] = NULL,
1446};
1447
1448static llc_conn_action_t llc_busy_actions_5[] = {
1449 [0] = llc_conn_ac_send_rr_xxx_x_set_0,
1450 [1] = NULL,
1451};
1452
1453static struct llc_conn_state_trans llc_busy_state_trans_5 = {
1454 .ev = llc_conn_ev_local_busy_cleared,
1455 .next_state = LLC_CONN_STATE_NORMAL,
1456 .ev_qualifiers = llc_busy_ev_qfyrs_5,
1457 .ev_actions = llc_busy_actions_5,
1458};
1459
1460/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
1461static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_6[] = {
1462 [0] = llc_conn_ev_qlfy_data_flag_eq_0,
1463 [1] = llc_conn_ev_qlfy_p_flag_eq_1,
1464 [2] = NULL,
1465};
1466
1467static llc_conn_action_t llc_busy_actions_6[] = {
1468 [0] = llc_conn_ac_send_rr_xxx_x_set_0,
1469 [1] = NULL,
1470};
1471
1472static struct llc_conn_state_trans llc_busy_state_trans_6 = {
1473 .ev = llc_conn_ev_local_busy_cleared,
1474 .next_state = LLC_CONN_STATE_NORMAL,
1475 .ev_qualifiers = llc_busy_ev_qfyrs_6,
1476 .ev_actions = llc_busy_actions_6,
1477};
1478
1479/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
1480static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_7[] = {
1481 [0] = llc_conn_ev_qlfy_data_flag_eq_2,
1482 [1] = llc_conn_ev_qlfy_p_flag_eq_0,
1483 [2] = NULL,
1484};
1485
1486static llc_conn_action_t llc_busy_actions_7[] = {
1487 [0] = llc_conn_ac_send_rr_xxx_x_set_0,
1488 [1] = NULL,
1489};
1490
1491static struct llc_conn_state_trans llc_busy_state_trans_7 = {
1492 .ev = llc_conn_ev_local_busy_cleared,
1493 .next_state = LLC_CONN_STATE_REJ,
1494 .ev_qualifiers = llc_busy_ev_qfyrs_7,
1495 .ev_actions = llc_busy_actions_7,
1496};
1497
1498/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
1499static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_8[] = {
1500 [0] = llc_conn_ev_qlfy_data_flag_eq_2,
1501 [1] = llc_conn_ev_qlfy_p_flag_eq_1,
1502 [2] = NULL,
1503};
1504
1505static llc_conn_action_t llc_busy_actions_8[] = {
1506 [0] = llc_conn_ac_send_rr_xxx_x_set_0,
1507 [1] = NULL,
1508};
1509
1510static struct llc_conn_state_trans llc_busy_state_trans_8 = {
1511 .ev = llc_conn_ev_local_busy_cleared,
1512 .next_state = LLC_CONN_STATE_REJ,
1513 .ev_qualifiers = llc_busy_ev_qfyrs_8,
1514 .ev_actions = llc_busy_actions_8,
1515};
1516
1517/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns event */
1518static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_9a[] = {
1519 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
1520 [1] = NULL,
1521};
1522
1523static llc_conn_action_t llc_busy_actions_9a[] = {
1524 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
1525 [1] = llc_conn_ac_upd_p_flag,
1526 [2] = llc_conn_ac_upd_nr_received,
1527 [3] = llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
1528 [4] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
1529 [5] = NULL,
1530};
1531
1532static struct llc_conn_state_trans llc_busy_state_trans_9a = {
1533 .ev = llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns,
1534 .next_state = LLC_CONN_STATE_BUSY,
1535 .ev_qualifiers = llc_busy_ev_qfyrs_9a,
1536 .ev_actions = llc_busy_actions_9a,
1537};
1538
1539/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
1540static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_9b[] = {
1541 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
1542 [1] = NULL,
1543};
1544
1545static llc_conn_action_t llc_busy_actions_9b[] = {
1546 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
1547 [1] = llc_conn_ac_upd_p_flag,
1548 [2] = llc_conn_ac_upd_nr_received,
1549 [3] = llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
1550 [4] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
1551 [5] = NULL,
1552};
1553
1554static struct llc_conn_state_trans llc_busy_state_trans_9b = {
1555 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
1556 .next_state = LLC_CONN_STATE_BUSY,
1557 .ev_qualifiers = llc_busy_ev_qfyrs_9b,
1558 .ev_actions = llc_busy_actions_9b,
1559};
1560
1561/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
1562static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_10a[] = {
1563 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1564 [1] = NULL,
1565};
1566
1567static llc_conn_action_t llc_busy_actions_10a[] = {
1568 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
1569 [1] = llc_conn_ac_upd_nr_received,
1570 [2] = llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
1571 [3] = NULL,
1572};
1573
1574static struct llc_conn_state_trans llc_busy_state_trans_10a = {
1575 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
1576 .next_state = LLC_CONN_STATE_BUSY,
1577 .ev_qualifiers = llc_busy_ev_qfyrs_10a,
1578 .ev_actions = llc_busy_actions_10a,
1579};
1580
1581/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
1582static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_10b[] = {
1583 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1584 [1] = NULL,
1585};
1586
1587static llc_conn_action_t llc_busy_actions_10b[] = {
1588 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
1589 [1] = llc_conn_ac_upd_nr_received,
1590 [2] = llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
1591 [3] = NULL,
1592};
1593
1594static struct llc_conn_state_trans llc_busy_state_trans_10b = {
1595 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
1596 .next_state = LLC_CONN_STATE_BUSY,
1597 .ev_qualifiers = llc_busy_ev_qfyrs_10b,
1598 .ev_actions = llc_busy_actions_10b,
1599};
1600
1601/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
1602static llc_conn_action_t llc_busy_actions_11[] = {
1603 [0] = llc_conn_ac_send_rnr_rsp_f_set_1,
1604 [1] = llc_conn_ac_upd_nr_received,
1605 [2] = llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
1606 [3] = NULL,
1607};
1608
1609static struct llc_conn_state_trans llc_busy_state_trans_11 = {
1610 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
1611 .next_state = LLC_CONN_STATE_BUSY,
1612 .ev_qualifiers = NONE,
1613 .ev_actions = llc_busy_actions_11,
1614};
1615
1616/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
1617static llc_conn_action_t llc_busy_actions_12[] = {
1618 [0] = llc_conn_ac_inc_vr_by_1,
1619 [1] = llc_conn_ac_data_ind,
1620 [2] = llc_conn_ac_send_rnr_rsp_f_set_1,
1621 [3] = llc_conn_ac_upd_nr_received,
1622 [4] = llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
1623 [5] = llc_conn_ac_set_data_flag_0,
1624 [6] = NULL,
1625};
1626
1627static struct llc_conn_state_trans llc_busy_state_trans_12 = {
1628 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1,
1629 .next_state = LLC_CONN_STATE_BUSY,
1630 .ev_qualifiers = NONE,
1631 .ev_actions = llc_busy_actions_12,
1632};
1633
1634/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X event */
1635static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_13a[] = {
1636 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
1637 [1] = NULL,
1638};
1639
1640static llc_conn_action_t llc_busy_actions_13a[] = {
1641 [0] = llc_conn_ac_inc_vr_by_1,
1642 [1] = llc_conn_ac_data_ind,
1643 [2] = llc_conn_ac_upd_p_flag,
1644 [3] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
1645 [4] = llc_conn_ac_upd_nr_received,
1646 [5] = llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
1647 [6] = llc_conn_ac_set_data_flag_0,
1648 [7] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
1649 [8] = NULL,
1650};
1651
1652static struct llc_conn_state_trans llc_busy_state_trans_13a = {
1653 .ev = llc_conn_ev_rx_i_rsp_fbit_set_x,
1654 .next_state = LLC_CONN_STATE_BUSY,
1655 .ev_qualifiers = llc_busy_ev_qfyrs_13a,
1656 .ev_actions = llc_busy_actions_13a,
1657};
1658
1659/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
1660static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_13b[] = {
1661 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
1662 [1] = NULL,
1663};
1664
1665static llc_conn_action_t llc_busy_actions_13b[] = {
1666 [0] = llc_conn_ac_inc_vr_by_1,
1667 [1] = llc_conn_ac_data_ind,
1668 [2] = llc_conn_ac_upd_p_flag,
1669 [3] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
1670 [4] = llc_conn_ac_upd_nr_received,
1671 [5] = llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
1672 [6] = llc_conn_ac_set_data_flag_0,
1673 [7] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
1674 [8] = NULL,
1675};
1676
1677static struct llc_conn_state_trans llc_busy_state_trans_13b = {
1678 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0,
1679 .next_state = LLC_CONN_STATE_BUSY,
1680 .ev_qualifiers = llc_busy_ev_qfyrs_13b,
1681 .ev_actions = llc_busy_actions_13b,
1682};
1683
1684/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
1685static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_14a[] = {
1686 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1687 [1] = NULL,
1688};
1689
1690static llc_conn_action_t llc_busy_actions_14a[] = {
1691 [0] = llc_conn_ac_inc_vr_by_1,
1692 [1] = llc_conn_ac_data_ind,
1693 [2] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
1694 [3] = llc_conn_ac_upd_nr_received,
1695 [4] = llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
1696 [5] = llc_conn_ac_set_data_flag_0,
1697 [6] = NULL,
1698};
1699
1700static struct llc_conn_state_trans llc_busy_state_trans_14a = {
1701 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0,
1702 .next_state = LLC_CONN_STATE_BUSY,
1703 .ev_qualifiers = llc_busy_ev_qfyrs_14a,
1704 .ev_actions = llc_busy_actions_14a,
1705};
1706
1707/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
1708static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_14b[] = {
1709 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1710 [1] = NULL,
1711};
1712
1713static llc_conn_action_t llc_busy_actions_14b[] = {
1714 [0] = llc_conn_ac_inc_vr_by_1,
1715 [1] = llc_conn_ac_data_ind,
1716 [2] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
1717 [3] = llc_conn_ac_upd_nr_received,
1718 [4] = llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
1719 [5] = llc_conn_ac_set_data_flag_0,
1720 [6] = NULL,
1721};
1722
1723static struct llc_conn_state_trans llc_busy_state_trans_14b = {
1724 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0,
1725 .next_state = LLC_CONN_STATE_BUSY,
1726 .ev_qualifiers = llc_busy_ev_qfyrs_14b,
1727 .ev_actions = llc_busy_actions_14b,
1728};
1729
1730/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
1731static llc_conn_action_t llc_busy_actions_15a[] = {
1732 [0] = llc_conn_ac_upd_p_flag,
1733 [1] = llc_conn_ac_upd_nr_received,
1734 [2] = llc_conn_ac_clear_remote_busy,
1735 [3] = NULL,
1736};
1737
1738static struct llc_conn_state_trans llc_busy_state_trans_15a = {
1739 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_0,
1740 .next_state = LLC_CONN_STATE_BUSY,
1741 .ev_qualifiers = NONE,
1742 .ev_actions = llc_busy_actions_15a,
1743};
1744
1745/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
1746static llc_conn_action_t llc_busy_actions_15b[] = {
1747 [0] = llc_conn_ac_upd_p_flag,
1748 [1] = llc_conn_ac_upd_nr_received,
1749 [2] = llc_conn_ac_clear_remote_busy,
1750 [3] = NULL,
1751};
1752
1753static struct llc_conn_state_trans llc_busy_state_trans_15b = {
1754 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_0,
1755 .next_state = LLC_CONN_STATE_BUSY,
1756 .ev_qualifiers = NONE,
1757 .ev_actions = llc_busy_actions_15b,
1758};
1759
1760/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
1761static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_15c[] = {
1762 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1763 [1] = NULL,
1764};
1765
1766static llc_conn_action_t llc_busy_actions_15c[] = {
1767 [0] = llc_conn_ac_upd_p_flag,
1768 [1] = llc_conn_ac_upd_nr_received,
1769 [2] = llc_conn_ac_clear_remote_busy,
1770 [3] = NULL,
1771};
1772
1773static struct llc_conn_state_trans llc_busy_state_trans_15c = {
1774 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_1,
1775 .next_state = LLC_CONN_STATE_BUSY,
1776 .ev_qualifiers = llc_busy_ev_qfyrs_15c,
1777 .ev_actions = llc_busy_actions_15c,
1778};
1779
1780/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
1781static llc_conn_action_t llc_busy_actions_16[] = {
1782 [0] = llc_conn_ac_send_rnr_rsp_f_set_1,
1783 [1] = llc_conn_ac_upd_nr_received,
1784 [2] = llc_conn_ac_clear_remote_busy,
1785 [3] = NULL,
1786};
1787
1788static struct llc_conn_state_trans llc_busy_state_trans_16 = {
1789 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_1,
1790 .next_state = LLC_CONN_STATE_BUSY,
1791 .ev_qualifiers = NONE,
1792 .ev_actions = llc_busy_actions_16,
1793};
1794
1795/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
1796static llc_conn_action_t llc_busy_actions_17a[] = {
1797 [0] = llc_conn_ac_upd_p_flag,
1798 [1] = llc_conn_ac_upd_nr_received,
1799 [2] = llc_conn_ac_set_remote_busy,
1800 [3] = NULL,
1801};
1802
1803static struct llc_conn_state_trans llc_busy_state_trans_17a = {
1804 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_0,
1805 .next_state = LLC_CONN_STATE_BUSY,
1806 .ev_qualifiers = NONE,
1807 .ev_actions = llc_busy_actions_17a,
1808};
1809
1810/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
1811static llc_conn_action_t llc_busy_actions_17b[] = {
1812 [0] = llc_conn_ac_upd_p_flag,
1813 [1] = llc_conn_ac_upd_nr_received,
1814 [2] = llc_conn_ac_set_remote_busy,
1815 [3] = NULL,
1816};
1817
1818static struct llc_conn_state_trans llc_busy_state_trans_17b = {
1819 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_0,
1820 .next_state = LLC_CONN_STATE_BUSY,
1821 .ev_qualifiers = NONE,
1822 .ev_actions = llc_busy_actions_17b,
1823};
1824
1825/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
1826static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_17c[] = {
1827 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1828 [1] = NULL,
1829};
1830
1831static llc_conn_action_t llc_busy_actions_17c[] = {
1832 [0] = llc_conn_ac_upd_p_flag,
1833 [1] = llc_conn_ac_upd_nr_received,
1834 [2] = llc_conn_ac_set_remote_busy,
1835 [3] = NULL,
1836};
1837
1838static struct llc_conn_state_trans llc_busy_state_trans_17c = {
1839 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_1,
1840 .next_state = LLC_CONN_STATE_BUSY,
1841 .ev_qualifiers = llc_busy_ev_qfyrs_17c,
1842 .ev_actions = llc_busy_actions_17c,
1843};
1844
1845/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
1846static llc_conn_action_t llc_busy_actions_18[] = {
1847 [0] = llc_conn_ac_send_rnr_rsp_f_set_1,
1848 [1] = llc_conn_ac_upd_nr_received,
1849 [2] = llc_conn_ac_set_remote_busy,
1850 [3] = NULL,
1851};
1852
1853static struct llc_conn_state_trans llc_busy_state_trans_18 = {
1854 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_1,
1855 .next_state = LLC_CONN_STATE_BUSY,
1856 .ev_qualifiers = NONE,
1857 .ev_actions = llc_busy_actions_18,
1858};
1859
1860/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
1861static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_19a[] = {
1862 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
1863 [1] = NULL,
1864};
1865
1866static llc_conn_action_t llc_busy_actions_19a[] = {
1867 [0] = llc_conn_ac_set_vs_nr,
1868 [1] = llc_conn_ac_upd_nr_received,
1869 [2] = llc_conn_ac_upd_p_flag,
1870 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
1871 [4] = llc_conn_ac_clear_remote_busy,
1872 [5] = NULL,
1873};
1874
1875static struct llc_conn_state_trans llc_busy_state_trans_19a = {
1876 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_0,
1877 .next_state = LLC_CONN_STATE_BUSY,
1878 .ev_qualifiers = llc_busy_ev_qfyrs_19a,
1879 .ev_actions = llc_busy_actions_19a,
1880};
1881
1882/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X event */
1883static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_19b[] = {
1884 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
1885 [1] = NULL,
1886};
1887
1888static llc_conn_action_t llc_busy_actions_19b[] = {
1889 [0] = llc_conn_ac_set_vs_nr,
1890 [1] = llc_conn_ac_upd_nr_received,
1891 [2] = llc_conn_ac_upd_p_flag,
1892 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
1893 [4] = llc_conn_ac_clear_remote_busy,
1894 [5] = NULL,
1895};
1896
1897static struct llc_conn_state_trans llc_busy_state_trans_19b = {
1898 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_x,
1899 .next_state = LLC_CONN_STATE_BUSY,
1900 .ev_qualifiers = llc_busy_ev_qfyrs_19b,
1901 .ev_actions = llc_busy_actions_19b,
1902};
1903
1904/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
1905static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_20a[] = {
1906 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1907 [1] = NULL,
1908};
1909
1910static llc_conn_action_t llc_busy_actions_20a[] = {
1911 [0] = llc_conn_ac_set_vs_nr,
1912 [1] = llc_conn_ac_upd_nr_received,
1913 [2] = llc_conn_ac_resend_i_xxx_x_set_0,
1914 [3] = llc_conn_ac_clear_remote_busy,
1915 [4] = NULL,
1916};
1917
1918static struct llc_conn_state_trans llc_busy_state_trans_20a = {
1919 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_0,
1920 .next_state = LLC_CONN_STATE_BUSY,
1921 .ev_qualifiers = llc_busy_ev_qfyrs_20a,
1922 .ev_actions = llc_busy_actions_20a,
1923};
1924
1925/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
1926static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_20b[] = {
1927 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
1928 [1] = NULL,
1929};
1930
1931static llc_conn_action_t llc_busy_actions_20b[] = {
1932 [0] = llc_conn_ac_set_vs_nr,
1933 [1] = llc_conn_ac_upd_nr_received,
1934 [2] = llc_conn_ac_resend_i_xxx_x_set_0,
1935 [3] = llc_conn_ac_clear_remote_busy,
1936 [4] = NULL,
1937};
1938
1939static struct llc_conn_state_trans llc_busy_state_trans_20b = {
1940 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_0,
1941 .next_state = LLC_CONN_STATE_BUSY,
1942 .ev_qualifiers = llc_busy_ev_qfyrs_20b,
1943 .ev_actions = llc_busy_actions_20b,
1944};
1945
1946/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
1947static llc_conn_action_t llc_busy_actions_21[] = {
1948 [0] = llc_conn_ac_set_vs_nr,
1949 [1] = llc_conn_ac_upd_nr_received,
1950 [2] = llc_conn_ac_send_rnr_rsp_f_set_1,
1951 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
1952 [4] = llc_conn_ac_clear_remote_busy,
1953 [5] = NULL,
1954};
1955
1956static struct llc_conn_state_trans llc_busy_state_trans_21 = {
1957 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_1,
1958 .next_state = LLC_CONN_STATE_BUSY,
1959 .ev_qualifiers = NONE,
1960 .ev_actions = llc_busy_actions_21,
1961};
1962
1963/* State transitions for LLC_CONN_EV_INIT_P_F_CYCLE event */
1964static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_22[] = {
1965 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
1966 [1] = NULL,
1967};
1968
1969static llc_conn_action_t llc_busy_actions_22[] = {
1970 [0] = llc_conn_ac_send_rnr_cmd_p_set_1,
1971 [1] = llc_conn_ac_start_p_timer,
1972 [2] = NULL,
1973};
1974
1975static struct llc_conn_state_trans llc_busy_state_trans_22 = {
1976 .ev = llc_conn_ev_init_p_f_cycle,
1977 .next_state = LLC_CONN_STATE_BUSY,
1978 .ev_qualifiers = llc_busy_ev_qfyrs_22,
1979 .ev_actions = llc_busy_actions_22,
1980};
1981
1982/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
1983static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_23[] = {
1984 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
1985 [1] = NULL,
1986};
1987
1988static llc_conn_action_t llc_busy_actions_23[] = {
1989 [0] = llc_conn_ac_send_rnr_cmd_p_set_1,
1990 [1] = llc_conn_ac_rst_vs,
1991 [2] = llc_conn_ac_start_p_timer,
1992 [3] = llc_conn_ac_inc_retry_cnt_by_1,
1993 [4] = NULL,
1994};
1995
1996static struct llc_conn_state_trans llc_busy_state_trans_23 = {
1997 .ev = llc_conn_ev_p_tmr_exp,
1998 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
1999 .ev_qualifiers = llc_busy_ev_qfyrs_23,
2000 .ev_actions = llc_busy_actions_23,
2001};
2002
2003/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
2004static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_24a[] = {
2005 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2006 [1] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
2007 [2] = NULL,
2008};
2009
2010static llc_conn_action_t llc_busy_actions_24a[] = {
2011 [0] = llc_conn_ac_send_rnr_cmd_p_set_1,
2012 [1] = llc_conn_ac_start_p_timer,
2013 [2] = llc_conn_ac_inc_retry_cnt_by_1,
2014 [3] = llc_conn_ac_rst_vs,
2015 [4] = NULL,
2016};
2017
2018static struct llc_conn_state_trans llc_busy_state_trans_24a = {
2019 .ev = llc_conn_ev_ack_tmr_exp,
2020 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
2021 .ev_qualifiers = llc_busy_ev_qfyrs_24a,
2022 .ev_actions = llc_busy_actions_24a,
2023};
2024
2025/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */
2026static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_24b[] = {
2027 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2028 [1] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
2029 [2] = NULL,
2030};
2031
2032static llc_conn_action_t llc_busy_actions_24b[] = {
2033 [0] = llc_conn_ac_send_rnr_cmd_p_set_1,
2034 [1] = llc_conn_ac_start_p_timer,
2035 [2] = llc_conn_ac_inc_retry_cnt_by_1,
2036 [3] = llc_conn_ac_rst_vs,
2037 [4] = NULL,
2038};
2039
2040static struct llc_conn_state_trans llc_busy_state_trans_24b = {
2041 .ev = llc_conn_ev_busy_tmr_exp,
2042 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
2043 .ev_qualifiers = llc_busy_ev_qfyrs_24b,
2044 .ev_actions = llc_busy_actions_24b,
2045};
2046
2047/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */
2048static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_25[] = {
2049 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2050 [1] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
2051 [2] = NULL,
2052};
2053
2054static llc_conn_action_t llc_busy_actions_25[] = {
2055 [0] = llc_conn_ac_send_rnr_cmd_p_set_1,
2056 [1] = llc_conn_ac_start_p_timer,
2057 [2] = llc_conn_ac_inc_retry_cnt_by_1,
2058 [3] = llc_conn_ac_rst_vs,
2059 [4] = llc_conn_ac_set_data_flag_1,
2060 [5] = NULL,
2061};
2062
2063static struct llc_conn_state_trans llc_busy_state_trans_25 = {
2064 .ev = llc_conn_ev_rej_tmr_exp,
2065 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
2066 .ev_qualifiers = llc_busy_ev_qfyrs_25,
2067 .ev_actions = llc_busy_actions_25,
2068};
2069
2070/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */
2071static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_26[] = {
2072 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
2073 [1] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
2074 [2] = NULL,
2075};
2076
2077static llc_conn_action_t llc_busy_actions_26[] = {
2078 [0] = llc_conn_ac_set_data_flag_1,
2079 [1] = NULL,
2080};
2081
2082static struct llc_conn_state_trans llc_busy_state_trans_26 = {
2083 .ev = llc_conn_ev_rej_tmr_exp,
2084 .next_state = LLC_CONN_STATE_BUSY,
2085 .ev_qualifiers = llc_busy_ev_qfyrs_26,
2086 .ev_actions = llc_busy_actions_26,
2087};
2088
2089/*
2090 * Array of pointers;
2091 * one to each transition
2092 */
2093static struct llc_conn_state_trans *llc_busy_state_transitions[] = {
2094 [0] = &llc_common_state_trans_1, /* Request */
2095 [1] = &llc_common_state_trans_2,
2096 [2] = &llc_busy_state_trans_1,
2097 [3] = &llc_busy_state_trans_2,
2098 [4] = &llc_busy_state_trans_2_1,
2099 [5] = &llc_common_state_trans_end,
2100 [6] = &llc_busy_state_trans_3, /* Local busy */
2101 [7] = &llc_busy_state_trans_4,
2102 [8] = &llc_busy_state_trans_5,
2103 [9] = &llc_busy_state_trans_6,
2104 [10] = &llc_busy_state_trans_7,
2105 [11] = &llc_busy_state_trans_8,
2106 [12] = &llc_common_state_trans_end,
2107 [13] = &llc_busy_state_trans_22, /* Initiate PF cycle */
2108 [14] = &llc_common_state_trans_end,
2109 [15] = &llc_common_state_trans_11a, /* Timer */
2110 [16] = &llc_common_state_trans_11b,
2111 [17] = &llc_common_state_trans_11c,
2112 [18] = &llc_common_state_trans_11d,
2113 [19] = &llc_busy_state_trans_23,
2114 [20] = &llc_busy_state_trans_24a,
2115 [21] = &llc_busy_state_trans_24b,
2116 [22] = &llc_busy_state_trans_25,
2117 [23] = &llc_busy_state_trans_26,
2118 [24] = &llc_common_state_trans_end,
2119 [25] = &llc_busy_state_trans_9a, /* Receive frame */
2120 [26] = &llc_busy_state_trans_9b,
2121 [27] = &llc_busy_state_trans_10a,
2122 [28] = &llc_busy_state_trans_10b,
2123 [29] = &llc_busy_state_trans_11,
2124 [30] = &llc_busy_state_trans_12,
2125 [31] = &llc_busy_state_trans_13a,
2126 [32] = &llc_busy_state_trans_13b,
2127 [33] = &llc_busy_state_trans_14a,
2128 [34] = &llc_busy_state_trans_14b,
2129 [35] = &llc_busy_state_trans_15a,
2130 [36] = &llc_busy_state_trans_15b,
2131 [37] = &llc_busy_state_trans_15c,
2132 [38] = &llc_busy_state_trans_16,
2133 [39] = &llc_busy_state_trans_17a,
2134 [40] = &llc_busy_state_trans_17b,
2135 [41] = &llc_busy_state_trans_17c,
2136 [42] = &llc_busy_state_trans_18,
2137 [43] = &llc_busy_state_trans_19a,
2138 [44] = &llc_busy_state_trans_19b,
2139 [45] = &llc_busy_state_trans_20a,
2140 [46] = &llc_busy_state_trans_20b,
2141 [47] = &llc_busy_state_trans_21,
2142 [48] = &llc_common_state_trans_3,
2143 [49] = &llc_common_state_trans_4,
2144 [50] = &llc_common_state_trans_5,
2145 [51] = &llc_common_state_trans_6,
2146 [52] = &llc_common_state_trans_7a,
2147 [53] = &llc_common_state_trans_7b,
2148 [54] = &llc_common_state_trans_8a,
2149 [55] = &llc_common_state_trans_8b,
2150 [56] = &llc_common_state_trans_8c,
2151 [57] = &llc_common_state_trans_9,
2152 /* [58] = &llc_common_state_trans_10, */
2153 [58] = &llc_common_state_trans_end,
2154};
2155
2156/* LLC_CONN_STATE_REJ transitions */
2157/* State transitions for LLC_CONN_EV_DATA_REQ event */
2158static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_1[] = {
2159 [0] = llc_conn_ev_qlfy_remote_busy_eq_0,
2160 [1] = llc_conn_ev_qlfy_p_flag_eq_0,
2161 [2] = NULL,
2162};
2163
2164static llc_conn_action_t llc_reject_actions_1[] = {
2165 [0] = llc_conn_ac_send_i_xxx_x_set_0,
2166 [1] = NULL,
2167};
2168
2169static struct llc_conn_state_trans llc_reject_state_trans_1 = {
2170 .ev = llc_conn_ev_data_req,
2171 .next_state = LLC_CONN_STATE_REJ,
2172 .ev_qualifiers = llc_reject_ev_qfyrs_1,
2173 .ev_actions = llc_reject_actions_1,
2174};
2175
2176/* State transitions for LLC_CONN_EV_DATA_REQ event */
2177static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_2[] = {
2178 [0] = llc_conn_ev_qlfy_remote_busy_eq_0,
2179 [1] = llc_conn_ev_qlfy_p_flag_eq_1,
2180 [2] = NULL,
2181};
2182
2183static llc_conn_action_t llc_reject_actions_2[] = {
2184 [0] = llc_conn_ac_send_i_xxx_x_set_0,
2185 [1] = NULL,
2186};
2187
2188static struct llc_conn_state_trans llc_reject_state_trans_2 = {
2189 .ev = llc_conn_ev_data_req,
2190 .next_state = LLC_CONN_STATE_REJ,
2191 .ev_qualifiers = llc_reject_ev_qfyrs_2,
2192 .ev_actions = llc_reject_actions_2,
2193};
2194
2195/* State transitions for LLC_CONN_EV_DATA_REQ event */
2196static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_2_1[] = {
2197 [0] = llc_conn_ev_qlfy_remote_busy_eq_1,
2198 [1] = llc_conn_ev_qlfy_set_status_remote_busy,
2199 [2] = NULL,
2200};
2201
2202/* just one member, NULL, .bss zeroes it */
2203static llc_conn_action_t llc_reject_actions_2_1[1];
2204
2205static struct llc_conn_state_trans llc_reject_state_trans_2_1 = {
2206 .ev = llc_conn_ev_data_req,
2207 .next_state = LLC_CONN_STATE_REJ,
2208 .ev_qualifiers = llc_reject_ev_qfyrs_2_1,
2209 .ev_actions = llc_reject_actions_2_1,
2210};
2211
2212
2213/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
2214static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_3[] = {
2215 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2216 [1] = NULL,
2217};
2218
2219static llc_conn_action_t llc_reject_actions_3[] = {
2220 [0] = llc_conn_ac_send_rnr_xxx_x_set_0,
2221 [1] = llc_conn_ac_set_data_flag_2,
2222 [2] = NULL,
2223};
2224
2225static struct llc_conn_state_trans llc_reject_state_trans_3 = {
2226 .ev = llc_conn_ev_local_busy_detected,
2227 .next_state = LLC_CONN_STATE_BUSY,
2228 .ev_qualifiers = llc_reject_ev_qfyrs_3,
2229 .ev_actions = llc_reject_actions_3,
2230};
2231
2232/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
2233static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_4[] = {
2234 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
2235 [1] = NULL,
2236};
2237
2238static llc_conn_action_t llc_reject_actions_4[] = {
2239 [0] = llc_conn_ac_send_rnr_xxx_x_set_0,
2240 [1] = llc_conn_ac_set_data_flag_2,
2241 [2] = NULL,
2242};
2243
2244static struct llc_conn_state_trans llc_reject_state_trans_4 = {
2245 .ev = llc_conn_ev_local_busy_detected,
2246 .next_state = LLC_CONN_STATE_BUSY,
2247 .ev_qualifiers = llc_reject_ev_qfyrs_4,
2248 .ev_actions = llc_reject_actions_4,
2249};
2250
2251/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
2252static llc_conn_action_t llc_reject_actions_5a[] = {
2253 [0] = llc_conn_ac_upd_nr_received,
2254 [1] = llc_conn_ac_upd_p_flag,
2255 [2] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
2256 [3] = NULL,
2257};
2258
2259static struct llc_conn_state_trans llc_reject_state_trans_5a = {
2260 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
2261 .next_state = LLC_CONN_STATE_REJ,
2262 .ev_qualifiers = NONE,
2263 .ev_actions = llc_reject_actions_5a,
2264};
2265
2266/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
2267static llc_conn_action_t llc_reject_actions_5b[] = {
2268 [0] = llc_conn_ac_upd_nr_received,
2269 [1] = llc_conn_ac_upd_p_flag,
2270 [2] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
2271 [3] = NULL,
2272};
2273
2274static struct llc_conn_state_trans llc_reject_state_trans_5b = {
2275 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
2276 .next_state = LLC_CONN_STATE_REJ,
2277 .ev_qualifiers = NONE,
2278 .ev_actions = llc_reject_actions_5b,
2279};
2280
2281/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
2282static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_5c[] = {
2283 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
2284 [1] = NULL,
2285};
2286
2287static llc_conn_action_t llc_reject_actions_5c[] = {
2288 [0] = llc_conn_ac_upd_nr_received,
2289 [1] = llc_conn_ac_upd_p_flag,
2290 [2] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
2291 [3] = NULL,
2292};
2293
2294static struct llc_conn_state_trans llc_reject_state_trans_5c = {
2295 .ev = llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
2296 .next_state = LLC_CONN_STATE_REJ,
2297 .ev_qualifiers = llc_reject_ev_qfyrs_5c,
2298 .ev_actions = llc_reject_actions_5c,
2299};
2300
2301/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
2302static llc_conn_action_t llc_reject_actions_6[] = {
2303 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
2304 [1] = llc_conn_ac_upd_nr_received,
2305 [2] = NULL,
2306};
2307
2308static struct llc_conn_state_trans llc_reject_state_trans_6 = {
2309 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
2310 .next_state = LLC_CONN_STATE_REJ,
2311 .ev_qualifiers = NONE,
2312 .ev_actions = llc_reject_actions_6,
2313};
2314
2315/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X event */
2316static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_7a[] = {
2317 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
2318 [1] = NULL,
2319};
2320
2321static llc_conn_action_t llc_reject_actions_7a[] = {
2322 [0] = llc_conn_ac_inc_vr_by_1,
2323 [1] = llc_conn_ac_data_ind,
2324 [2] = llc_conn_ac_upd_p_flag,
2325 [3] = llc_conn_ac_send_ack_xxx_x_set_0,
2326 [4] = llc_conn_ac_upd_nr_received,
2327 [5] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
2328 [6] = llc_conn_ac_stop_rej_timer,
2329 [7] = NULL,
2330
2331};
2332
2333static struct llc_conn_state_trans llc_reject_state_trans_7a = {
2334 .ev = llc_conn_ev_rx_i_rsp_fbit_set_x,
2335 .next_state = LLC_CONN_STATE_NORMAL,
2336 .ev_qualifiers = llc_reject_ev_qfyrs_7a,
2337 .ev_actions = llc_reject_actions_7a,
2338};
2339
2340/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
2341static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_7b[] = {
2342 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2343 [1] = NULL,
2344};
2345
2346static llc_conn_action_t llc_reject_actions_7b[] = {
2347 [0] = llc_conn_ac_inc_vr_by_1,
2348 [1] = llc_conn_ac_data_ind,
2349 [2] = llc_conn_ac_upd_p_flag,
2350 [3] = llc_conn_ac_send_ack_xxx_x_set_0,
2351 [4] = llc_conn_ac_upd_nr_received,
2352 [5] = llc_conn_ac_clear_remote_busy_if_f_eq_1,
2353 [6] = llc_conn_ac_stop_rej_timer,
2354 [7] = NULL,
2355};
2356
2357static struct llc_conn_state_trans llc_reject_state_trans_7b = {
2358 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0,
2359 .next_state = LLC_CONN_STATE_NORMAL,
2360 .ev_qualifiers = llc_reject_ev_qfyrs_7b,
2361 .ev_actions = llc_reject_actions_7b,
2362};
2363
2364/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
2365static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_8a[] = {
2366 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
2367 [1] = NULL,
2368};
2369
2370static llc_conn_action_t llc_reject_actions_8a[] = {
2371 [0] = llc_conn_ac_inc_vr_by_1,
2372 [1] = llc_conn_ac_data_ind,
2373 [2] = llc_conn_ac_send_ack_xxx_x_set_0,
2374 [3] = llc_conn_ac_upd_nr_received,
2375 [4] = llc_conn_ac_stop_rej_timer,
2376 [5] = NULL,
2377};
2378
2379static struct llc_conn_state_trans llc_reject_state_trans_8a = {
2380 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0,
2381 .next_state = LLC_CONN_STATE_NORMAL,
2382 .ev_qualifiers = llc_reject_ev_qfyrs_8a,
2383 .ev_actions = llc_reject_actions_8a,
2384};
2385
2386/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
2387static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_8b[] = {
2388 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
2389 [1] = NULL,
2390};
2391
2392static llc_conn_action_t llc_reject_actions_8b[] = {
2393 [0] = llc_conn_ac_inc_vr_by_1,
2394 [1] = llc_conn_ac_data_ind,
2395 [2] = llc_conn_ac_send_ack_xxx_x_set_0,
2396 [3] = llc_conn_ac_upd_nr_received,
2397 [4] = llc_conn_ac_stop_rej_timer,
2398 [5] = NULL,
2399};
2400
2401static struct llc_conn_state_trans llc_reject_state_trans_8b = {
2402 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0,
2403 .next_state = LLC_CONN_STATE_NORMAL,
2404 .ev_qualifiers = llc_reject_ev_qfyrs_8b,
2405 .ev_actions = llc_reject_actions_8b,
2406};
2407
2408/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
2409static llc_conn_action_t llc_reject_actions_9[] = {
2410 [0] = llc_conn_ac_inc_vr_by_1,
2411 [1] = llc_conn_ac_data_ind,
2412 [2] = llc_conn_ac_send_ack_rsp_f_set_1,
2413 [3] = llc_conn_ac_upd_nr_received,
2414 [4] = llc_conn_ac_stop_rej_timer,
2415 [5] = NULL,
2416};
2417
2418static struct llc_conn_state_trans llc_reject_state_trans_9 = {
2419 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1,
2420 .next_state = LLC_CONN_STATE_NORMAL,
2421 .ev_qualifiers = NONE,
2422 .ev_actions = llc_reject_actions_9,
2423};
2424
2425/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
2426static llc_conn_action_t llc_reject_actions_10a[] = {
2427 [0] = llc_conn_ac_upd_p_flag,
2428 [1] = llc_conn_ac_upd_nr_received,
2429 [2] = llc_conn_ac_clear_remote_busy,
2430 [3] = NULL,
2431};
2432
2433static struct llc_conn_state_trans llc_reject_state_trans_10a = {
2434 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_0,
2435 .next_state = LLC_CONN_STATE_REJ,
2436 .ev_qualifiers = NONE,
2437 .ev_actions = llc_reject_actions_10a,
2438};
2439
2440/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
2441static llc_conn_action_t llc_reject_actions_10b[] = {
2442 [0] = llc_conn_ac_upd_p_flag,
2443 [1] = llc_conn_ac_upd_nr_received,
2444 [2] = llc_conn_ac_clear_remote_busy,
2445 [3] = NULL,
2446};
2447
2448static struct llc_conn_state_trans llc_reject_state_trans_10b = {
2449 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_0,
2450 .next_state = LLC_CONN_STATE_REJ,
2451 .ev_qualifiers = NONE,
2452 .ev_actions = llc_reject_actions_10b,
2453};
2454
2455/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
2456static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_10c[] = {
2457 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
2458 [1] = NULL,
2459};
2460
2461static llc_conn_action_t llc_reject_actions_10c[] = {
2462 [0] = llc_conn_ac_upd_p_flag,
2463 [1] = llc_conn_ac_upd_nr_received,
2464 [2] = llc_conn_ac_clear_remote_busy,
2465 [3] = NULL,
2466};
2467
2468static struct llc_conn_state_trans llc_reject_state_trans_10c = {
2469 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_1,
2470 .next_state = LLC_CONN_STATE_REJ,
2471 .ev_qualifiers = llc_reject_ev_qfyrs_10c,
2472 .ev_actions = llc_reject_actions_10c,
2473};
2474
2475/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
2476static llc_conn_action_t llc_reject_actions_11[] = {
2477 [0] = llc_conn_ac_send_ack_rsp_f_set_1,
2478 [1] = llc_conn_ac_upd_nr_received,
2479 [2] = llc_conn_ac_clear_remote_busy,
2480 [3] = NULL,
2481};
2482
2483static struct llc_conn_state_trans llc_reject_state_trans_11 = {
2484 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_1,
2485 .next_state = LLC_CONN_STATE_REJ,
2486 .ev_qualifiers = NONE,
2487 .ev_actions = llc_reject_actions_11,
2488};
2489
2490/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
2491static llc_conn_action_t llc_reject_actions_12a[] = {
2492 [0] = llc_conn_ac_upd_p_flag,
2493 [1] = llc_conn_ac_upd_nr_received,
2494 [2] = llc_conn_ac_set_remote_busy,
2495 [3] = NULL,
2496};
2497
2498static struct llc_conn_state_trans llc_reject_state_trans_12a = {
2499 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_0,
2500 .next_state = LLC_CONN_STATE_REJ,
2501 .ev_qualifiers = NONE,
2502 .ev_actions = llc_reject_actions_12a,
2503};
2504
2505/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
2506static llc_conn_action_t llc_reject_actions_12b[] = {
2507 [0] = llc_conn_ac_upd_p_flag,
2508 [1] = llc_conn_ac_upd_nr_received,
2509 [2] = llc_conn_ac_set_remote_busy,
2510 [3] = NULL,
2511};
2512
2513static struct llc_conn_state_trans llc_reject_state_trans_12b = {
2514 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_0,
2515 .next_state = LLC_CONN_STATE_REJ,
2516 .ev_qualifiers = NONE,
2517 .ev_actions = llc_reject_actions_12b,
2518};
2519
2520/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
2521static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_12c[] = {
2522 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
2523 [1] = NULL,
2524};
2525
2526static llc_conn_action_t llc_reject_actions_12c[] = {
2527 [0] = llc_conn_ac_upd_p_flag,
2528 [1] = llc_conn_ac_upd_nr_received,
2529 [2] = llc_conn_ac_set_remote_busy,
2530 [3] = NULL,
2531};
2532
2533static struct llc_conn_state_trans llc_reject_state_trans_12c = {
2534 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_1,
2535 .next_state = LLC_CONN_STATE_REJ,
2536 .ev_qualifiers = llc_reject_ev_qfyrs_12c,
2537 .ev_actions = llc_reject_actions_12c,
2538};
2539
2540/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
2541static llc_conn_action_t llc_reject_actions_13[] = {
2542 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
2543 [1] = llc_conn_ac_upd_nr_received,
2544 [2] = llc_conn_ac_set_remote_busy,
2545 [3] = NULL,
2546};
2547
2548static struct llc_conn_state_trans llc_reject_state_trans_13 = {
2549 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_1,
2550 .next_state = LLC_CONN_STATE_REJ,
2551 .ev_qualifiers = NONE,
2552 .ev_actions = llc_reject_actions_13,
2553};
2554
2555/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
2556static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_14a[] = {
2557 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2558 [1] = NULL,
2559};
2560
2561static llc_conn_action_t llc_reject_actions_14a[] = {
2562 [0] = llc_conn_ac_set_vs_nr,
2563 [1] = llc_conn_ac_upd_nr_received,
2564 [2] = llc_conn_ac_upd_p_flag,
2565 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
2566 [4] = llc_conn_ac_clear_remote_busy,
2567 [5] = NULL,
2568};
2569
2570static struct llc_conn_state_trans llc_reject_state_trans_14a = {
2571 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_0,
2572 .next_state = LLC_CONN_STATE_REJ,
2573 .ev_qualifiers = llc_reject_ev_qfyrs_14a,
2574 .ev_actions = llc_reject_actions_14a,
2575};
2576
2577/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X event */
2578static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_14b[] = {
2579 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
2580 [1] = NULL,
2581};
2582
2583static llc_conn_action_t llc_reject_actions_14b[] = {
2584 [0] = llc_conn_ac_set_vs_nr,
2585 [1] = llc_conn_ac_upd_nr_received,
2586 [2] = llc_conn_ac_upd_p_flag,
2587 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
2588 [4] = llc_conn_ac_clear_remote_busy,
2589 [5] = NULL,
2590};
2591
2592static struct llc_conn_state_trans llc_reject_state_trans_14b = {
2593 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_x,
2594 .next_state = LLC_CONN_STATE_REJ,
2595 .ev_qualifiers = llc_reject_ev_qfyrs_14b,
2596 .ev_actions = llc_reject_actions_14b,
2597};
2598
2599/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
2600static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_15a[] = {
2601 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
2602 [1] = NULL,
2603};
2604
2605static llc_conn_action_t llc_reject_actions_15a[] = {
2606 [0] = llc_conn_ac_set_vs_nr,
2607 [1] = llc_conn_ac_upd_nr_received,
2608 [2] = llc_conn_ac_resend_i_xxx_x_set_0,
2609 [3] = llc_conn_ac_clear_remote_busy,
2610 [4] = NULL,
2611};
2612
2613static struct llc_conn_state_trans llc_reject_state_trans_15a = {
2614 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_0,
2615 .next_state = LLC_CONN_STATE_REJ,
2616 .ev_qualifiers = llc_reject_ev_qfyrs_15a,
2617 .ev_actions = llc_reject_actions_15a,
2618};
2619
2620/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
2621static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_15b[] = {
2622 [0] = llc_conn_ev_qlfy_p_flag_eq_1,
2623 [1] = NULL,
2624};
2625
2626static llc_conn_action_t llc_reject_actions_15b[] = {
2627 [0] = llc_conn_ac_set_vs_nr,
2628 [1] = llc_conn_ac_upd_nr_received,
2629 [2] = llc_conn_ac_resend_i_xxx_x_set_0,
2630 [3] = llc_conn_ac_clear_remote_busy,
2631 [4] = NULL,
2632};
2633
2634static struct llc_conn_state_trans llc_reject_state_trans_15b = {
2635 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_0,
2636 .next_state = LLC_CONN_STATE_REJ,
2637 .ev_qualifiers = llc_reject_ev_qfyrs_15b,
2638 .ev_actions = llc_reject_actions_15b,
2639};
2640
2641/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
2642static llc_conn_action_t llc_reject_actions_16[] = {
2643 [0] = llc_conn_ac_set_vs_nr,
2644 [1] = llc_conn_ac_upd_nr_received,
2645 [2] = llc_conn_ac_resend_i_rsp_f_set_1,
2646 [3] = llc_conn_ac_clear_remote_busy,
2647 [4] = NULL,
2648};
2649
2650static struct llc_conn_state_trans llc_reject_state_trans_16 = {
2651 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_1,
2652 .next_state = LLC_CONN_STATE_REJ,
2653 .ev_qualifiers = NONE,
2654 .ev_actions = llc_reject_actions_16,
2655};
2656
2657/* State transitions for LLC_CONN_EV_INIT_P_F_CYCLE event */
2658static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_17[] = {
2659 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2660 [1] = NULL,
2661};
2662
2663static llc_conn_action_t llc_reject_actions_17[] = {
2664 [0] = llc_conn_ac_send_rr_cmd_p_set_1,
2665 [1] = llc_conn_ac_start_p_timer,
2666 [2] = NULL,
2667};
2668
2669static struct llc_conn_state_trans llc_reject_state_trans_17 = {
2670 .ev = llc_conn_ev_init_p_f_cycle,
2671 .next_state = LLC_CONN_STATE_REJ,
2672 .ev_qualifiers = llc_reject_ev_qfyrs_17,
2673 .ev_actions = llc_reject_actions_17,
2674};
2675
2676/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */
2677static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_18[] = {
2678 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2679 [1] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
2680 [2] = NULL,
2681};
2682
2683static llc_conn_action_t llc_reject_actions_18[] = {
2684 [0] = llc_conn_ac_send_rej_cmd_p_set_1,
2685 [1] = llc_conn_ac_start_p_timer,
2686 [2] = llc_conn_ac_start_rej_timer,
2687 [3] = llc_conn_ac_inc_retry_cnt_by_1,
2688 [4] = NULL,
2689};
2690
2691static struct llc_conn_state_trans llc_reject_state_trans_18 = {
2692 .ev = llc_conn_ev_rej_tmr_exp,
2693 .next_state = LLC_CONN_STATE_REJ,
2694 .ev_qualifiers = llc_reject_ev_qfyrs_18,
2695 .ev_actions = llc_reject_actions_18,
2696};
2697
2698/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
2699static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_19[] = {
2700 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
2701 [1] = NULL,
2702};
2703
2704static llc_conn_action_t llc_reject_actions_19[] = {
2705 [0] = llc_conn_ac_send_rr_cmd_p_set_1,
2706 [1] = llc_conn_ac_start_p_timer,
2707 [2] = llc_conn_ac_start_rej_timer,
2708 [3] = llc_conn_ac_inc_retry_cnt_by_1,
2709 [4] = llc_conn_ac_rst_vs,
2710 [5] = NULL,
2711};
2712
2713static struct llc_conn_state_trans llc_reject_state_trans_19 = {
2714 .ev = llc_conn_ev_p_tmr_exp,
2715 .next_state = LLC_CONN_STATE_AWAIT_REJ,
2716 .ev_qualifiers = llc_reject_ev_qfyrs_19,
2717 .ev_actions = llc_reject_actions_19,
2718};
2719
2720/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
2721static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_20a[] = {
2722 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2723 [1] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
2724 [2] = NULL,
2725};
2726
2727static llc_conn_action_t llc_reject_actions_20a[] = {
2728 [0] = llc_conn_ac_send_rr_cmd_p_set_1,
2729 [1] = llc_conn_ac_start_p_timer,
2730 [2] = llc_conn_ac_start_rej_timer,
2731 [3] = llc_conn_ac_inc_retry_cnt_by_1,
2732 [4] = llc_conn_ac_rst_vs,
2733 [5] = NULL,
2734};
2735
2736static struct llc_conn_state_trans llc_reject_state_trans_20a = {
2737 .ev = llc_conn_ev_ack_tmr_exp,
2738 .next_state = LLC_CONN_STATE_AWAIT_REJ,
2739 .ev_qualifiers = llc_reject_ev_qfyrs_20a,
2740 .ev_actions = llc_reject_actions_20a,
2741};
2742
2743/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */
2744static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_20b[] = {
2745 [0] = llc_conn_ev_qlfy_p_flag_eq_0,
2746 [1] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
2747 [2] = NULL,
2748};
2749
2750static llc_conn_action_t llc_reject_actions_20b[] = {
2751 [0] = llc_conn_ac_send_rr_cmd_p_set_1,
2752 [1] = llc_conn_ac_start_p_timer,
2753 [2] = llc_conn_ac_start_rej_timer,
2754 [3] = llc_conn_ac_inc_retry_cnt_by_1,
2755 [4] = llc_conn_ac_rst_vs,
2756 [5] = NULL,
2757};
2758
2759static struct llc_conn_state_trans llc_reject_state_trans_20b = {
2760 .ev = llc_conn_ev_busy_tmr_exp,
2761 .next_state = LLC_CONN_STATE_AWAIT_REJ,
2762 .ev_qualifiers = llc_reject_ev_qfyrs_20b,
2763 .ev_actions = llc_reject_actions_20b,
2764};
2765
2766/*
2767 * Array of pointers;
2768 * one to each transition
2769 */
2770static struct llc_conn_state_trans *llc_reject_state_transitions[] = {
2771 [0] = &llc_common_state_trans_1, /* Request */
2772 [1] = &llc_common_state_trans_2,
2773 [2] = &llc_common_state_trans_end,
2774 [3] = &llc_reject_state_trans_1,
2775 [4] = &llc_reject_state_trans_2,
2776 [5] = &llc_reject_state_trans_2_1,
2777 [6] = &llc_reject_state_trans_3, /* Local busy */
2778 [7] = &llc_reject_state_trans_4,
2779 [8] = &llc_common_state_trans_end,
2780 [9] = &llc_reject_state_trans_17, /* Initiate PF cycle */
2781 [10] = &llc_common_state_trans_end,
2782 [11] = &llc_common_state_trans_11a, /* Timer */
2783 [12] = &llc_common_state_trans_11b,
2784 [13] = &llc_common_state_trans_11c,
2785 [14] = &llc_common_state_trans_11d,
2786 [15] = &llc_reject_state_trans_18,
2787 [16] = &llc_reject_state_trans_19,
2788 [17] = &llc_reject_state_trans_20a,
2789 [18] = &llc_reject_state_trans_20b,
2790 [19] = &llc_common_state_trans_end,
2791 [20] = &llc_common_state_trans_3, /* Receive frame */
2792 [21] = &llc_common_state_trans_4,
2793 [22] = &llc_common_state_trans_5,
2794 [23] = &llc_common_state_trans_6,
2795 [24] = &llc_common_state_trans_7a,
2796 [25] = &llc_common_state_trans_7b,
2797 [26] = &llc_common_state_trans_8a,
2798 [27] = &llc_common_state_trans_8b,
2799 [28] = &llc_common_state_trans_8c,
2800 [29] = &llc_common_state_trans_9,
2801 /* [30] = &llc_common_state_trans_10, */
2802 [30] = &llc_reject_state_trans_5a,
2803 [31] = &llc_reject_state_trans_5b,
2804 [32] = &llc_reject_state_trans_5c,
2805 [33] = &llc_reject_state_trans_6,
2806 [34] = &llc_reject_state_trans_7a,
2807 [35] = &llc_reject_state_trans_7b,
2808 [36] = &llc_reject_state_trans_8a,
2809 [37] = &llc_reject_state_trans_8b,
2810 [38] = &llc_reject_state_trans_9,
2811 [39] = &llc_reject_state_trans_10a,
2812 [40] = &llc_reject_state_trans_10b,
2813 [41] = &llc_reject_state_trans_10c,
2814 [42] = &llc_reject_state_trans_11,
2815 [43] = &llc_reject_state_trans_12a,
2816 [44] = &llc_reject_state_trans_12b,
2817 [45] = &llc_reject_state_trans_12c,
2818 [46] = &llc_reject_state_trans_13,
2819 [47] = &llc_reject_state_trans_14a,
2820 [48] = &llc_reject_state_trans_14b,
2821 [49] = &llc_reject_state_trans_15a,
2822 [50] = &llc_reject_state_trans_15b,
2823 [51] = &llc_reject_state_trans_16,
2824 [52] = &llc_common_state_trans_end,
2825};
2826
2827/* LLC_CONN_STATE_AWAIT transitions */
2828/* State transitions for LLC_CONN_EV_DATA_REQ event */
2829static llc_conn_ev_qfyr_t llc_await_ev_qfyrs_1_0[] = {
2830 [0] = llc_conn_ev_qlfy_set_status_refuse,
2831 [1] = NULL,
2832};
2833
2834/* just one member, NULL, .bss zeroes it */
2835static llc_conn_action_t llc_await_actions_1_0[1];
2836
2837static struct llc_conn_state_trans llc_await_state_trans_1_0 = {
2838 .ev = llc_conn_ev_data_req,
2839 .next_state = LLC_CONN_STATE_AWAIT,
2840 .ev_qualifiers = llc_await_ev_qfyrs_1_0,
2841 .ev_actions = llc_await_actions_1_0,
2842};
2843
2844/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
2845static llc_conn_action_t llc_await_actions_1[] = {
2846 [0] = llc_conn_ac_send_rnr_xxx_x_set_0,
2847 [1] = llc_conn_ac_set_data_flag_0,
2848 [2] = NULL,
2849};
2850
2851static struct llc_conn_state_trans llc_await_state_trans_1 = {
2852 .ev = llc_conn_ev_local_busy_detected,
2853 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
2854 .ev_qualifiers = NONE,
2855 .ev_actions = llc_await_actions_1,
2856};
2857
2858/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
2859static llc_conn_action_t llc_await_actions_2[] = {
2860 [0] = llc_conn_ac_send_rej_xxx_x_set_0,
2861 [1] = llc_conn_ac_upd_nr_received,
2862 [2] = llc_conn_ac_upd_vs,
2863 [3] = llc_conn_ac_stop_p_timer,
2864 [4] = llc_conn_ac_resend_i_xxx_x_set_0,
2865 [5] = llc_conn_ac_start_rej_timer,
2866 [6] = llc_conn_ac_clear_remote_busy,
2867 [7] = NULL,
2868};
2869
2870static struct llc_conn_state_trans llc_await_state_trans_2 = {
2871 .ev = llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
2872 .next_state = LLC_CONN_STATE_REJ,
2873 .ev_qualifiers = NONE,
2874 .ev_actions = llc_await_actions_2,
2875};
2876
2877/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
2878static llc_conn_action_t llc_await_actions_3a[] = {
2879 [0] = llc_conn_ac_send_rej_xxx_x_set_0,
2880 [1] = llc_conn_ac_upd_nr_received,
2881 [2] = llc_conn_ac_upd_vs,
2882 [3] = llc_conn_ac_start_rej_timer,
2883 [4] = NULL,
2884};
2885
2886static struct llc_conn_state_trans llc_await_state_trans_3a = {
2887 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
2888 .next_state = LLC_CONN_STATE_AWAIT_REJ,
2889 .ev_qualifiers = NONE,
2890 .ev_actions = llc_await_actions_3a,
2891};
2892
2893/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
2894static llc_conn_action_t llc_await_actions_3b[] = {
2895 [0] = llc_conn_ac_send_rej_xxx_x_set_0,
2896 [1] = llc_conn_ac_upd_nr_received,
2897 [2] = llc_conn_ac_upd_vs,
2898 [3] = llc_conn_ac_start_rej_timer,
2899 [4] = NULL,
2900};
2901
2902static struct llc_conn_state_trans llc_await_state_trans_3b = {
2903 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
2904 .next_state = LLC_CONN_STATE_AWAIT_REJ,
2905 .ev_qualifiers = NONE,
2906 .ev_actions = llc_await_actions_3b,
2907};
2908
2909/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
2910static llc_conn_action_t llc_await_actions_4[] = {
2911 [0] = llc_conn_ac_send_rej_rsp_f_set_1,
2912 [1] = llc_conn_ac_upd_nr_received,
2913 [2] = llc_conn_ac_upd_vs,
2914 [3] = llc_conn_ac_start_rej_timer,
2915 [4] = llc_conn_ac_start_p_timer,
2916 [5] = NULL,
2917};
2918
2919static struct llc_conn_state_trans llc_await_state_trans_4 = {
2920 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
2921 .next_state = LLC_CONN_STATE_AWAIT_REJ,
2922 .ev_qualifiers = NONE,
2923 .ev_actions = llc_await_actions_4,
2924};
2925
2926/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 event */
2927static llc_conn_action_t llc_await_actions_5[] = {
2928 [0] = llc_conn_ac_inc_vr_by_1,
2929 [1] = llc_conn_ac_data_ind,
2930 [2] = llc_conn_ac_stop_p_timer,
2931 [3] = llc_conn_ac_upd_nr_received,
2932 [4] = llc_conn_ac_upd_vs,
2933 [5] = llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr,
2934 [6] = llc_conn_ac_clear_remote_busy,
2935 [7] = NULL,
2936};
2937
2938static struct llc_conn_state_trans llc_await_state_trans_5 = {
2939 .ev = llc_conn_ev_rx_i_rsp_fbit_set_1,
2940 .next_state = LLC_CONN_STATE_NORMAL,
2941 .ev_qualifiers = NONE,
2942 .ev_actions = llc_await_actions_5,
2943};
2944
2945/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
2946static llc_conn_action_t llc_await_actions_6a[] = {
2947 [0] = llc_conn_ac_inc_vr_by_1,
2948 [1] = llc_conn_ac_data_ind,
2949 [2] = llc_conn_ac_send_rr_xxx_x_set_0,
2950 [3] = llc_conn_ac_upd_nr_received,
2951 [4] = llc_conn_ac_upd_vs,
2952 [5] = NULL,
2953};
2954
2955static struct llc_conn_state_trans llc_await_state_trans_6a = {
2956 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0,
2957 .next_state = LLC_CONN_STATE_AWAIT,
2958 .ev_qualifiers = NONE,
2959 .ev_actions = llc_await_actions_6a,
2960};
2961
2962/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
2963static llc_conn_action_t llc_await_actions_6b[] = {
2964 [0] = llc_conn_ac_inc_vr_by_1,
2965 [1] = llc_conn_ac_data_ind,
2966 [2] = llc_conn_ac_send_rr_xxx_x_set_0,
2967 [3] = llc_conn_ac_upd_nr_received,
2968 [4] = llc_conn_ac_upd_vs,
2969 [5] = NULL,
2970};
2971
2972static struct llc_conn_state_trans llc_await_state_trans_6b = {
2973 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0,
2974 .next_state = LLC_CONN_STATE_AWAIT,
2975 .ev_qualifiers = NONE,
2976 .ev_actions = llc_await_actions_6b,
2977};
2978
2979/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
2980static llc_conn_action_t llc_await_actions_7[] = {
2981 [0] = llc_conn_ac_inc_vr_by_1,
2982 [1] = llc_conn_ac_data_ind,
2983 [2] = llc_conn_ac_send_rr_rsp_f_set_1,
2984 [3] = llc_conn_ac_upd_nr_received,
2985 [4] = llc_conn_ac_upd_vs,
2986 [5] = NULL,
2987};
2988
2989static struct llc_conn_state_trans llc_await_state_trans_7 = {
2990 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1,
2991 .next_state = LLC_CONN_STATE_AWAIT,
2992 .ev_qualifiers = NONE,
2993 .ev_actions = llc_await_actions_7,
2994};
2995
2996/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
2997static llc_conn_action_t llc_await_actions_8a[] = {
2998 [0] = llc_conn_ac_upd_nr_received,
2999 [1] = llc_conn_ac_upd_vs,
3000 [2] = llc_conn_ac_stop_p_timer,
3001 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
3002 [4] = llc_conn_ac_clear_remote_busy,
3003 [5] = NULL,
3004};
3005
3006static struct llc_conn_state_trans llc_await_state_trans_8a = {
3007 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_1,
3008 .next_state = LLC_CONN_STATE_NORMAL,
3009 .ev_qualifiers = NONE,
3010 .ev_actions = llc_await_actions_8a,
3011};
3012
3013/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 event */
3014static llc_conn_action_t llc_await_actions_8b[] = {
3015 [0] = llc_conn_ac_upd_nr_received,
3016 [1] = llc_conn_ac_upd_vs,
3017 [2] = llc_conn_ac_stop_p_timer,
3018 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
3019 [4] = llc_conn_ac_clear_remote_busy,
3020 [5] = NULL,
3021};
3022
3023static struct llc_conn_state_trans llc_await_state_trans_8b = {
3024 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_1,
3025 .next_state = LLC_CONN_STATE_NORMAL,
3026 .ev_qualifiers = NONE,
3027 .ev_actions = llc_await_actions_8b,
3028};
3029
3030/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
3031static llc_conn_action_t llc_await_actions_9a[] = {
3032 [0] = llc_conn_ac_upd_nr_received,
3033 [1] = llc_conn_ac_upd_vs,
3034 [2] = llc_conn_ac_clear_remote_busy,
3035 [3] = NULL,
3036};
3037
3038static struct llc_conn_state_trans llc_await_state_trans_9a = {
3039 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_0,
3040 .next_state = LLC_CONN_STATE_AWAIT,
3041 .ev_qualifiers = NONE,
3042 .ev_actions = llc_await_actions_9a,
3043};
3044
3045/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
3046static llc_conn_action_t llc_await_actions_9b[] = {
3047 [0] = llc_conn_ac_upd_nr_received,
3048 [1] = llc_conn_ac_upd_vs,
3049 [2] = llc_conn_ac_clear_remote_busy,
3050 [3] = NULL,
3051};
3052
3053static struct llc_conn_state_trans llc_await_state_trans_9b = {
3054 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_0,
3055 .next_state = LLC_CONN_STATE_AWAIT,
3056 .ev_qualifiers = NONE,
3057 .ev_actions = llc_await_actions_9b,
3058};
3059
3060/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
3061static llc_conn_action_t llc_await_actions_9c[] = {
3062 [0] = llc_conn_ac_upd_nr_received,
3063 [1] = llc_conn_ac_upd_vs,
3064 [2] = llc_conn_ac_clear_remote_busy,
3065 [3] = NULL,
3066};
3067
3068static struct llc_conn_state_trans llc_await_state_trans_9c = {
3069 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_0,
3070 .next_state = LLC_CONN_STATE_AWAIT,
3071 .ev_qualifiers = NONE,
3072 .ev_actions = llc_await_actions_9c,
3073};
3074
3075/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
3076static llc_conn_action_t llc_await_actions_9d[] = {
3077 [0] = llc_conn_ac_upd_nr_received,
3078 [1] = llc_conn_ac_upd_vs,
3079 [2] = llc_conn_ac_clear_remote_busy,
3080 [3] = NULL,
3081};
3082
3083static struct llc_conn_state_trans llc_await_state_trans_9d = {
3084 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_0,
3085 .next_state = LLC_CONN_STATE_AWAIT,
3086 .ev_qualifiers = NONE,
3087 .ev_actions = llc_await_actions_9d,
3088};
3089
3090/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
3091static llc_conn_action_t llc_await_actions_10a[] = {
3092 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
3093 [1] = llc_conn_ac_upd_nr_received,
3094 [2] = llc_conn_ac_upd_vs,
3095 [3] = llc_conn_ac_clear_remote_busy,
3096 [4] = NULL,
3097};
3098
3099static struct llc_conn_state_trans llc_await_state_trans_10a = {
3100 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_1,
3101 .next_state = LLC_CONN_STATE_AWAIT,
3102 .ev_qualifiers = NONE,
3103 .ev_actions = llc_await_actions_10a,
3104};
3105
3106/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
3107static llc_conn_action_t llc_await_actions_10b[] = {
3108 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
3109 [1] = llc_conn_ac_upd_nr_received,
3110 [2] = llc_conn_ac_upd_vs,
3111 [3] = llc_conn_ac_clear_remote_busy,
3112 [4] = NULL,
3113};
3114
3115static struct llc_conn_state_trans llc_await_state_trans_10b = {
3116 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_1,
3117 .next_state = LLC_CONN_STATE_AWAIT,
3118 .ev_qualifiers = NONE,
3119 .ev_actions = llc_await_actions_10b,
3120};
3121
3122/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
3123static llc_conn_action_t llc_await_actions_11[] = {
3124 [0] = llc_conn_ac_upd_nr_received,
3125 [1] = llc_conn_ac_upd_vs,
3126 [2] = llc_conn_ac_stop_p_timer,
3127 [3] = llc_conn_ac_set_remote_busy,
3128 [4] = NULL,
3129};
3130
3131static struct llc_conn_state_trans llc_await_state_trans_11 = {
3132 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_1,
3133 .next_state = LLC_CONN_STATE_NORMAL,
3134 .ev_qualifiers = NONE,
3135 .ev_actions = llc_await_actions_11,
3136};
3137
3138/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
3139static llc_conn_action_t llc_await_actions_12a[] = {
3140 [0] = llc_conn_ac_upd_nr_received,
3141 [1] = llc_conn_ac_upd_vs,
3142 [2] = llc_conn_ac_set_remote_busy,
3143 [3] = NULL,
3144};
3145
3146static struct llc_conn_state_trans llc_await_state_trans_12a = {
3147 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_0,
3148 .next_state = LLC_CONN_STATE_AWAIT,
3149 .ev_qualifiers = NONE,
3150 .ev_actions = llc_await_actions_12a,
3151};
3152
3153/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
3154static llc_conn_action_t llc_await_actions_12b[] = {
3155 [0] = llc_conn_ac_upd_nr_received,
3156 [1] = llc_conn_ac_upd_vs,
3157 [2] = llc_conn_ac_set_remote_busy,
3158 [3] = NULL,
3159};
3160
3161static struct llc_conn_state_trans llc_await_state_trans_12b = {
3162 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_0,
3163 .next_state = LLC_CONN_STATE_AWAIT,
3164 .ev_qualifiers = NONE,
3165 .ev_actions = llc_await_actions_12b,
3166};
3167
3168/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
3169static llc_conn_action_t llc_await_actions_13[] = {
3170 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
3171 [1] = llc_conn_ac_upd_nr_received,
3172 [2] = llc_conn_ac_upd_vs,
3173 [3] = llc_conn_ac_set_remote_busy,
3174 [4] = NULL,
3175};
3176
3177static struct llc_conn_state_trans llc_await_state_trans_13 = {
3178 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_1,
3179 .next_state = LLC_CONN_STATE_AWAIT,
3180 .ev_qualifiers = NONE,
3181 .ev_actions = llc_await_actions_13,
3182};
3183
3184/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
3185static llc_conn_ev_qfyr_t llc_await_ev_qfyrs_14[] = {
3186 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
3187 [1] = NULL,
3188};
3189
3190static llc_conn_action_t llc_await_actions_14[] = {
3191 [0] = llc_conn_ac_send_rr_cmd_p_set_1,
3192 [1] = llc_conn_ac_start_p_timer,
3193 [2] = llc_conn_ac_inc_retry_cnt_by_1,
3194 [3] = NULL,
3195};
3196
3197static struct llc_conn_state_trans llc_await_state_trans_14 = {
3198 .ev = llc_conn_ev_p_tmr_exp,
3199 .next_state = LLC_CONN_STATE_AWAIT,
3200 .ev_qualifiers = llc_await_ev_qfyrs_14,
3201 .ev_actions = llc_await_actions_14,
3202};
3203
3204/*
3205 * Array of pointers;
3206 * one to each transition
3207 */
3208static struct llc_conn_state_trans *llc_await_state_transitions[] = {
3209 [0] = &llc_common_state_trans_1, /* Request */
3210 [1] = &llc_common_state_trans_2,
3211 [2] = &llc_await_state_trans_1_0,
3212 [3] = &llc_common_state_trans_end,
3213 [4] = &llc_await_state_trans_1, /* Local busy */
3214 [5] = &llc_common_state_trans_end,
3215 [6] = &llc_common_state_trans_end, /* Initiate PF Cycle */
3216 [7] = &llc_common_state_trans_11a, /* Timer */
3217 [8] = &llc_common_state_trans_11b,
3218 [9] = &llc_common_state_trans_11c,
3219 [10] = &llc_common_state_trans_11d,
3220 [11] = &llc_await_state_trans_14,
3221 [12] = &llc_common_state_trans_end,
3222 [13] = &llc_common_state_trans_3, /* Receive frame */
3223 [14] = &llc_common_state_trans_4,
3224 [15] = &llc_common_state_trans_5,
3225 [16] = &llc_common_state_trans_6,
3226 [17] = &llc_common_state_trans_7a,
3227 [18] = &llc_common_state_trans_7b,
3228 [19] = &llc_common_state_trans_8a,
3229 [20] = &llc_common_state_trans_8b,
3230 [21] = &llc_common_state_trans_8c,
3231 [22] = &llc_common_state_trans_9,
3232 /* [23] = &llc_common_state_trans_10, */
3233 [23] = &llc_await_state_trans_2,
3234 [24] = &llc_await_state_trans_3a,
3235 [25] = &llc_await_state_trans_3b,
3236 [26] = &llc_await_state_trans_4,
3237 [27] = &llc_await_state_trans_5,
3238 [28] = &llc_await_state_trans_6a,
3239 [29] = &llc_await_state_trans_6b,
3240 [30] = &llc_await_state_trans_7,
3241 [31] = &llc_await_state_trans_8a,
3242 [32] = &llc_await_state_trans_8b,
3243 [33] = &llc_await_state_trans_9a,
3244 [34] = &llc_await_state_trans_9b,
3245 [35] = &llc_await_state_trans_9c,
3246 [36] = &llc_await_state_trans_9d,
3247 [37] = &llc_await_state_trans_10a,
3248 [38] = &llc_await_state_trans_10b,
3249 [39] = &llc_await_state_trans_11,
3250 [40] = &llc_await_state_trans_12a,
3251 [41] = &llc_await_state_trans_12b,
3252 [42] = &llc_await_state_trans_13,
3253 [43] = &llc_common_state_trans_end,
3254};
3255
3256/* LLC_CONN_STATE_AWAIT_BUSY transitions */
3257/* State transitions for LLC_CONN_EV_DATA_CONN_REQ event */
3258static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_1_0[] = {
3259 [0] = llc_conn_ev_qlfy_set_status_refuse,
3260 [1] = NULL,
3261};
3262
3263/* just one member, NULL, .bss zeroes it */
3264static llc_conn_action_t llc_await_busy_actions_1_0[1];
3265
3266static struct llc_conn_state_trans llc_await_busy_state_trans_1_0 = {
3267 .ev = llc_conn_ev_data_req,
3268 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3269 .ev_qualifiers = llc_await_busy_ev_qfyrs_1_0,
3270 .ev_actions = llc_await_busy_actions_1_0,
3271};
3272
3273/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
3274static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_1[] = {
3275 [0] = llc_conn_ev_qlfy_data_flag_eq_1,
3276 [1] = NULL,
3277};
3278
3279static llc_conn_action_t llc_await_busy_actions_1[] = {
3280 [0] = llc_conn_ac_send_rej_xxx_x_set_0,
3281 [1] = llc_conn_ac_start_rej_timer,
3282 [2] = NULL,
3283};
3284
3285static struct llc_conn_state_trans llc_await_busy_state_trans_1 = {
3286 .ev = llc_conn_ev_local_busy_cleared,
3287 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3288 .ev_qualifiers = llc_await_busy_ev_qfyrs_1,
3289 .ev_actions = llc_await_busy_actions_1,
3290};
3291
3292/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
3293static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_2[] = {
3294 [0] = llc_conn_ev_qlfy_data_flag_eq_0,
3295 [1] = NULL,
3296};
3297
3298static llc_conn_action_t llc_await_busy_actions_2[] = {
3299 [0] = llc_conn_ac_send_rr_xxx_x_set_0,
3300 [1] = NULL,
3301};
3302
3303static struct llc_conn_state_trans llc_await_busy_state_trans_2 = {
3304 .ev = llc_conn_ev_local_busy_cleared,
3305 .next_state = LLC_CONN_STATE_AWAIT,
3306 .ev_qualifiers = llc_await_busy_ev_qfyrs_2,
3307 .ev_actions = llc_await_busy_actions_2,
3308};
3309
3310/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
3311static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_3[] = {
3312 [0] = llc_conn_ev_qlfy_data_flag_eq_2,
3313 [1] = NULL,
3314};
3315
3316static llc_conn_action_t llc_await_busy_actions_3[] = {
3317 [0] = llc_conn_ac_send_rr_xxx_x_set_0,
3318 [1] = NULL,
3319};
3320
3321static struct llc_conn_state_trans llc_await_busy_state_trans_3 = {
3322 .ev = llc_conn_ev_local_busy_cleared,
3323 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3324 .ev_qualifiers = llc_await_busy_ev_qfyrs_3,
3325 .ev_actions = llc_await_busy_actions_3,
3326};
3327
3328/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
3329static llc_conn_action_t llc_await_busy_actions_4[] = {
3330 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
3331 [1] = llc_conn_ac_upd_nr_received,
3332 [2] = llc_conn_ac_upd_vs,
3333 [3] = llc_conn_ac_stop_p_timer,
3334 [4] = llc_conn_ac_set_data_flag_1,
3335 [5] = llc_conn_ac_clear_remote_busy,
3336 [6] = llc_conn_ac_resend_i_xxx_x_set_0,
3337 [7] = NULL,
3338};
3339
3340static struct llc_conn_state_trans llc_await_busy_state_trans_4 = {
3341 .ev = llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
3342 .next_state = LLC_CONN_STATE_BUSY,
3343 .ev_qualifiers = NONE,
3344 .ev_actions = llc_await_busy_actions_4,
3345};
3346
3347/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
3348static llc_conn_action_t llc_await_busy_actions_5a[] = {
3349 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
3350 [1] = llc_conn_ac_upd_nr_received,
3351 [2] = llc_conn_ac_upd_vs,
3352 [3] = llc_conn_ac_set_data_flag_1,
3353 [4] = NULL,
3354};
3355
3356static struct llc_conn_state_trans llc_await_busy_state_trans_5a = {
3357 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
3358 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3359 .ev_qualifiers = NONE,
3360 .ev_actions = llc_await_busy_actions_5a,
3361};
3362
3363/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
3364static llc_conn_action_t llc_await_busy_actions_5b[] = {
3365 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
3366 [1] = llc_conn_ac_upd_nr_received,
3367 [2] = llc_conn_ac_upd_vs,
3368 [3] = llc_conn_ac_set_data_flag_1,
3369 [4] = NULL,
3370};
3371
3372static struct llc_conn_state_trans llc_await_busy_state_trans_5b = {
3373 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
3374 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3375 .ev_qualifiers = NONE,
3376 .ev_actions = llc_await_busy_actions_5b,
3377};
3378
3379/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
3380static llc_conn_action_t llc_await_busy_actions_6[] = {
3381 [0] = llc_conn_ac_send_rnr_rsp_f_set_1,
3382 [1] = llc_conn_ac_upd_nr_received,
3383 [2] = llc_conn_ac_upd_vs,
3384 [3] = llc_conn_ac_set_data_flag_1,
3385 [4] = NULL,
3386};
3387
3388static struct llc_conn_state_trans llc_await_busy_state_trans_6 = {
3389 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
3390 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3391 .ev_qualifiers = NONE,
3392 .ev_actions = llc_await_busy_actions_6,
3393};
3394
3395/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 event */
3396static llc_conn_action_t llc_await_busy_actions_7[] = {
3397 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
3398 [1] = llc_conn_ac_inc_vr_by_1,
3399 [2] = llc_conn_ac_data_ind,
3400 [3] = llc_conn_ac_stop_p_timer,
3401 [4] = llc_conn_ac_upd_nr_received,
3402 [5] = llc_conn_ac_upd_vs,
3403 [6] = llc_conn_ac_set_data_flag_0,
3404 [7] = llc_conn_ac_clear_remote_busy,
3405 [8] = llc_conn_ac_resend_i_xxx_x_set_0,
3406 [9] = NULL,
3407};
3408
3409static struct llc_conn_state_trans llc_await_busy_state_trans_7 = {
3410 .ev = llc_conn_ev_rx_i_rsp_fbit_set_1,
3411 .next_state = LLC_CONN_STATE_BUSY,
3412 .ev_qualifiers = NONE,
3413 .ev_actions = llc_await_busy_actions_7,
3414};
3415
3416/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
3417static llc_conn_action_t llc_await_busy_actions_8a[] = {
3418 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
3419 [1] = llc_conn_ac_inc_vr_by_1,
3420 [2] = llc_conn_ac_data_ind,
3421 [3] = llc_conn_ac_upd_nr_received,
3422 [4] = llc_conn_ac_upd_vs,
3423 [5] = llc_conn_ac_set_data_flag_0,
3424 [6] = NULL,
3425};
3426
3427static struct llc_conn_state_trans llc_await_busy_state_trans_8a = {
3428 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0,
3429 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3430 .ev_qualifiers = NONE,
3431 .ev_actions = llc_await_busy_actions_8a,
3432};
3433
3434/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
3435static llc_conn_action_t llc_await_busy_actions_8b[] = {
3436 [0] = llc_conn_ac_opt_send_rnr_xxx_x_set_0,
3437 [1] = llc_conn_ac_inc_vr_by_1,
3438 [2] = llc_conn_ac_data_ind,
3439 [3] = llc_conn_ac_upd_nr_received,
3440 [4] = llc_conn_ac_upd_vs,
3441 [5] = llc_conn_ac_set_data_flag_0,
3442 [6] = NULL,
3443};
3444
3445static struct llc_conn_state_trans llc_await_busy_state_trans_8b = {
3446 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0,
3447 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3448 .ev_qualifiers = NONE,
3449 .ev_actions = llc_await_busy_actions_8b,
3450};
3451
3452/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
3453static llc_conn_action_t llc_await_busy_actions_9[] = {
3454 [0] = llc_conn_ac_send_rnr_rsp_f_set_1,
3455 [1] = llc_conn_ac_inc_vr_by_1,
3456 [2] = llc_conn_ac_data_ind,
3457 [3] = llc_conn_ac_upd_nr_received,
3458 [4] = llc_conn_ac_upd_vs,
3459 [5] = llc_conn_ac_set_data_flag_0,
3460 [6] = NULL,
3461};
3462
3463static struct llc_conn_state_trans llc_await_busy_state_trans_9 = {
3464 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1,
3465 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3466 .ev_qualifiers = NONE,
3467 .ev_actions = llc_await_busy_actions_9,
3468};
3469
3470/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
3471static llc_conn_action_t llc_await_busy_actions_10a[] = {
3472 [0] = llc_conn_ac_upd_nr_received,
3473 [1] = llc_conn_ac_upd_vs,
3474 [2] = llc_conn_ac_stop_p_timer,
3475 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
3476 [4] = llc_conn_ac_clear_remote_busy,
3477 [5] = NULL,
3478};
3479
3480static struct llc_conn_state_trans llc_await_busy_state_trans_10a = {
3481 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_1,
3482 .next_state = LLC_CONN_STATE_BUSY,
3483 .ev_qualifiers = NONE,
3484 .ev_actions = llc_await_busy_actions_10a,
3485};
3486
3487/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 event */
3488static llc_conn_action_t llc_await_busy_actions_10b[] = {
3489 [0] = llc_conn_ac_upd_nr_received,
3490 [1] = llc_conn_ac_upd_vs,
3491 [2] = llc_conn_ac_stop_p_timer,
3492 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
3493 [4] = llc_conn_ac_clear_remote_busy,
3494 [5] = NULL,
3495};
3496
3497static struct llc_conn_state_trans llc_await_busy_state_trans_10b = {
3498 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_1,
3499 .next_state = LLC_CONN_STATE_BUSY,
3500 .ev_qualifiers = NONE,
3501 .ev_actions = llc_await_busy_actions_10b,
3502};
3503
3504/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
3505static llc_conn_action_t llc_await_busy_actions_11a[] = {
3506 [0] = llc_conn_ac_upd_nr_received,
3507 [1] = llc_conn_ac_upd_vs,
3508 [2] = llc_conn_ac_clear_remote_busy,
3509 [3] = NULL,
3510};
3511
3512static struct llc_conn_state_trans llc_await_busy_state_trans_11a = {
3513 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_0,
3514 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3515 .ev_qualifiers = NONE,
3516 .ev_actions = llc_await_busy_actions_11a,
3517};
3518
3519/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
3520static llc_conn_action_t llc_await_busy_actions_11b[] = {
3521 [0] = llc_conn_ac_upd_nr_received,
3522 [1] = llc_conn_ac_upd_vs,
3523 [2] = llc_conn_ac_clear_remote_busy,
3524 [3] = NULL,
3525};
3526
3527static struct llc_conn_state_trans llc_await_busy_state_trans_11b = {
3528 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_0,
3529 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3530 .ev_qualifiers = NONE,
3531 .ev_actions = llc_await_busy_actions_11b,
3532};
3533
3534/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
3535static llc_conn_action_t llc_await_busy_actions_11c[] = {
3536 [0] = llc_conn_ac_upd_nr_received,
3537 [1] = llc_conn_ac_upd_vs,
3538 [2] = llc_conn_ac_clear_remote_busy,
3539 [3] = NULL,
3540};
3541
3542static struct llc_conn_state_trans llc_await_busy_state_trans_11c = {
3543 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_0,
3544 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3545 .ev_qualifiers = NONE,
3546 .ev_actions = llc_await_busy_actions_11c,
3547};
3548
3549/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
3550static llc_conn_action_t llc_await_busy_actions_11d[] = {
3551 [0] = llc_conn_ac_upd_nr_received,
3552 [1] = llc_conn_ac_upd_vs,
3553 [2] = llc_conn_ac_clear_remote_busy,
3554 [3] = NULL,
3555};
3556
3557static struct llc_conn_state_trans llc_await_busy_state_trans_11d = {
3558 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_0,
3559 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3560 .ev_qualifiers = NONE,
3561 .ev_actions = llc_await_busy_actions_11d,
3562};
3563
3564/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
3565static llc_conn_action_t llc_await_busy_actions_12a[] = {
3566 [0] = llc_conn_ac_send_rnr_rsp_f_set_1,
3567 [1] = llc_conn_ac_upd_nr_received,
3568 [2] = llc_conn_ac_upd_vs,
3569 [3] = llc_conn_ac_clear_remote_busy,
3570 [4] = NULL,
3571};
3572
3573static struct llc_conn_state_trans llc_await_busy_state_trans_12a = {
3574 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_1,
3575 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3576 .ev_qualifiers = NONE,
3577 .ev_actions = llc_await_busy_actions_12a,
3578};
3579
3580/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
3581static llc_conn_action_t llc_await_busy_actions_12b[] = {
3582 [0] = llc_conn_ac_send_rnr_rsp_f_set_1,
3583 [1] = llc_conn_ac_upd_nr_received,
3584 [2] = llc_conn_ac_upd_vs,
3585 [3] = llc_conn_ac_clear_remote_busy,
3586 [4] = NULL,
3587};
3588
3589static struct llc_conn_state_trans llc_await_busy_state_trans_12b = {
3590 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_1,
3591 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3592 .ev_qualifiers = NONE,
3593 .ev_actions = llc_await_busy_actions_12b,
3594};
3595
3596/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
3597static llc_conn_action_t llc_await_busy_actions_13[] = {
3598 [0] = llc_conn_ac_upd_nr_received,
3599 [1] = llc_conn_ac_upd_vs,
3600 [2] = llc_conn_ac_stop_p_timer,
3601 [3] = llc_conn_ac_set_remote_busy,
3602 [4] = NULL,
3603};
3604
3605static struct llc_conn_state_trans llc_await_busy_state_trans_13 = {
3606 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_1,
3607 .next_state = LLC_CONN_STATE_BUSY,
3608 .ev_qualifiers = NONE,
3609 .ev_actions = llc_await_busy_actions_13,
3610};
3611
3612/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
3613static llc_conn_action_t llc_await_busy_actions_14a[] = {
3614 [0] = llc_conn_ac_upd_nr_received,
3615 [1] = llc_conn_ac_upd_vs,
3616 [2] = llc_conn_ac_set_remote_busy,
3617 [3] = NULL,
3618};
3619
3620static struct llc_conn_state_trans llc_await_busy_state_trans_14a = {
3621 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_0,
3622 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3623 .ev_qualifiers = NONE,
3624 .ev_actions = llc_await_busy_actions_14a,
3625};
3626
3627/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
3628static llc_conn_action_t llc_await_busy_actions_14b[] = {
3629 [0] = llc_conn_ac_upd_nr_received,
3630 [1] = llc_conn_ac_upd_vs,
3631 [2] = llc_conn_ac_set_remote_busy,
3632 [3] = NULL,
3633};
3634
3635static struct llc_conn_state_trans llc_await_busy_state_trans_14b = {
3636 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_0,
3637 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3638 .ev_qualifiers = NONE,
3639 .ev_actions = llc_await_busy_actions_14b,
3640};
3641
3642/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
3643static llc_conn_action_t llc_await_busy_actions_15[] = {
3644 [0] = llc_conn_ac_send_rnr_rsp_f_set_1,
3645 [1] = llc_conn_ac_upd_nr_received,
3646 [2] = llc_conn_ac_upd_vs,
3647 [3] = llc_conn_ac_set_remote_busy,
3648 [4] = NULL,
3649};
3650
3651static struct llc_conn_state_trans llc_await_busy_state_trans_15 = {
3652 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_1,
3653 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3654 .ev_qualifiers = NONE,
3655 .ev_actions = llc_await_busy_actions_15,
3656};
3657
3658/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
3659static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_16[] = {
3660 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
3661 [1] = NULL,
3662};
3663
3664static llc_conn_action_t llc_await_busy_actions_16[] = {
3665 [0] = llc_conn_ac_send_rnr_cmd_p_set_1,
3666 [1] = llc_conn_ac_start_p_timer,
3667 [2] = llc_conn_ac_inc_retry_cnt_by_1,
3668 [3] = NULL,
3669};
3670
3671static struct llc_conn_state_trans llc_await_busy_state_trans_16 = {
3672 .ev = llc_conn_ev_p_tmr_exp,
3673 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3674 .ev_qualifiers = llc_await_busy_ev_qfyrs_16,
3675 .ev_actions = llc_await_busy_actions_16,
3676};
3677
3678/*
3679 * Array of pointers;
3680 * one to each transition
3681 */
3682static struct llc_conn_state_trans *llc_await_busy_state_transitions[] = {
3683 [0] = &llc_common_state_trans_1, /* Request */
3684 [1] = &llc_common_state_trans_2,
3685 [2] = &llc_await_busy_state_trans_1_0,
3686 [3] = &llc_common_state_trans_end,
3687 [4] = &llc_await_busy_state_trans_1, /* Local busy */
3688 [5] = &llc_await_busy_state_trans_2,
3689 [6] = &llc_await_busy_state_trans_3,
3690 [7] = &llc_common_state_trans_end,
3691 [8] = &llc_common_state_trans_end, /* Initiate PF cycle */
3692 [9] = &llc_common_state_trans_11a, /* Timer */
3693 [10] = &llc_common_state_trans_11b,
3694 [11] = &llc_common_state_trans_11c,
3695 [12] = &llc_common_state_trans_11d,
3696 [13] = &llc_await_busy_state_trans_16,
3697 [14] = &llc_common_state_trans_end,
3698 [15] = &llc_await_busy_state_trans_4, /* Receive frame */
3699 [16] = &llc_await_busy_state_trans_5a,
3700 [17] = &llc_await_busy_state_trans_5b,
3701 [18] = &llc_await_busy_state_trans_6,
3702 [19] = &llc_await_busy_state_trans_7,
3703 [20] = &llc_await_busy_state_trans_8a,
3704 [21] = &llc_await_busy_state_trans_8b,
3705 [22] = &llc_await_busy_state_trans_9,
3706 [23] = &llc_await_busy_state_trans_10a,
3707 [24] = &llc_await_busy_state_trans_10b,
3708 [25] = &llc_await_busy_state_trans_11a,
3709 [26] = &llc_await_busy_state_trans_11b,
3710 [27] = &llc_await_busy_state_trans_11c,
3711 [28] = &llc_await_busy_state_trans_11d,
3712 [29] = &llc_await_busy_state_trans_12a,
3713 [30] = &llc_await_busy_state_trans_12b,
3714 [31] = &llc_await_busy_state_trans_13,
3715 [32] = &llc_await_busy_state_trans_14a,
3716 [33] = &llc_await_busy_state_trans_14b,
3717 [34] = &llc_await_busy_state_trans_15,
3718 [35] = &llc_common_state_trans_3,
3719 [36] = &llc_common_state_trans_4,
3720 [37] = &llc_common_state_trans_5,
3721 [38] = &llc_common_state_trans_6,
3722 [39] = &llc_common_state_trans_7a,
3723 [40] = &llc_common_state_trans_7b,
3724 [41] = &llc_common_state_trans_8a,
3725 [42] = &llc_common_state_trans_8b,
3726 [43] = &llc_common_state_trans_8c,
3727 [44] = &llc_common_state_trans_9,
3728 /* [45] = &llc_common_state_trans_10, */
3729 [45] = &llc_common_state_trans_end,
3730};
3731
3732/* ----------------- LLC_CONN_STATE_AWAIT_REJ transitions --------------- */
3733/* State transitions for LLC_CONN_EV_DATA_CONN_REQ event */
3734static llc_conn_ev_qfyr_t llc_await_reject_ev_qfyrs_1_0[] = {
3735 [0] = llc_conn_ev_qlfy_set_status_refuse,
3736 [1] = NULL,
3737};
3738
3739/* just one member, NULL, .bss zeroes it */
3740static llc_conn_action_t llc_await_reject_actions_1_0[1];
3741
3742static struct llc_conn_state_trans llc_await_reject_state_trans_1_0 = {
3743 .ev = llc_conn_ev_data_req,
3744 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3745 .ev_qualifiers = llc_await_reject_ev_qfyrs_1_0,
3746 .ev_actions = llc_await_reject_actions_1_0,
3747};
3748
3749/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
3750static llc_conn_action_t llc_await_rejct_actions_1[] = {
3751 [0] = llc_conn_ac_send_rnr_xxx_x_set_0,
3752 [1] = llc_conn_ac_set_data_flag_2,
3753 [2] = NULL
3754};
3755
3756static struct llc_conn_state_trans llc_await_rejct_state_trans_1 = {
3757 .ev = llc_conn_ev_local_busy_detected,
3758 .next_state = LLC_CONN_STATE_AWAIT_BUSY,
3759 .ev_qualifiers = NONE,
3760 .ev_actions = llc_await_rejct_actions_1,
3761};
3762
3763/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
3764static llc_conn_action_t llc_await_rejct_actions_2a[] = {
3765 [0] = llc_conn_ac_upd_nr_received,
3766 [1] = llc_conn_ac_upd_vs,
3767 [2] = NULL
3768};
3769
3770static struct llc_conn_state_trans llc_await_rejct_state_trans_2a = {
3771 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
3772 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3773 .ev_qualifiers = NONE,
3774 .ev_actions = llc_await_rejct_actions_2a,
3775};
3776
3777/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
3778static llc_conn_action_t llc_await_rejct_actions_2b[] = {
3779 [0] = llc_conn_ac_upd_nr_received,
3780 [1] = llc_conn_ac_upd_vs,
3781 [2] = NULL
3782};
3783
3784static struct llc_conn_state_trans llc_await_rejct_state_trans_2b = {
3785 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
3786 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3787 .ev_qualifiers = NONE,
3788 .ev_actions = llc_await_rejct_actions_2b,
3789};
3790
3791/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
3792static llc_conn_action_t llc_await_rejct_actions_3[] = {
3793 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
3794 [1] = llc_conn_ac_upd_nr_received,
3795 [2] = llc_conn_ac_upd_vs,
3796 [3] = NULL
3797};
3798
3799static struct llc_conn_state_trans llc_await_rejct_state_trans_3 = {
3800 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
3801 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3802 .ev_qualifiers = NONE,
3803 .ev_actions = llc_await_rejct_actions_3,
3804};
3805
3806/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 event */
3807static llc_conn_action_t llc_await_rejct_actions_4[] = {
3808 [0] = llc_conn_ac_inc_vr_by_1,
3809 [1] = llc_conn_ac_data_ind,
3810 [2] = llc_conn_ac_stop_p_timer,
3811 [3] = llc_conn_ac_stop_rej_timer,
3812 [4] = llc_conn_ac_upd_nr_received,
3813 [5] = llc_conn_ac_upd_vs,
3814 [6] = llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr,
3815 [7] = llc_conn_ac_clear_remote_busy,
3816 [8] = NULL,
3817};
3818
3819static struct llc_conn_state_trans llc_await_rejct_state_trans_4 = {
3820 .ev = llc_conn_ev_rx_i_rsp_fbit_set_1,
3821 .next_state = LLC_CONN_STATE_NORMAL,
3822 .ev_qualifiers = NONE,
3823 .ev_actions = llc_await_rejct_actions_4,
3824};
3825
3826/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
3827static llc_conn_action_t llc_await_rejct_actions_5a[] = {
3828 [0] = llc_conn_ac_inc_vr_by_1,
3829 [1] = llc_conn_ac_data_ind,
3830 [2] = llc_conn_ac_send_rr_xxx_x_set_0,
3831 [3] = llc_conn_ac_stop_rej_timer,
3832 [4] = llc_conn_ac_upd_nr_received,
3833 [5] = llc_conn_ac_upd_vs,
3834 [6] = NULL,
3835};
3836
3837static struct llc_conn_state_trans llc_await_rejct_state_trans_5a = {
3838 .ev = llc_conn_ev_rx_i_rsp_fbit_set_0,
3839 .next_state = LLC_CONN_STATE_AWAIT,
3840 .ev_qualifiers = NONE,
3841 .ev_actions = llc_await_rejct_actions_5a,
3842};
3843
3844/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
3845static llc_conn_action_t llc_await_rejct_actions_5b[] = {
3846 [0] = llc_conn_ac_inc_vr_by_1,
3847 [1] = llc_conn_ac_data_ind,
3848 [2] = llc_conn_ac_send_rr_xxx_x_set_0,
3849 [3] = llc_conn_ac_stop_rej_timer,
3850 [4] = llc_conn_ac_upd_nr_received,
3851 [5] = llc_conn_ac_upd_vs,
3852 [6] = NULL,
3853};
3854
3855static struct llc_conn_state_trans llc_await_rejct_state_trans_5b = {
3856 .ev = llc_conn_ev_rx_i_cmd_pbit_set_0,
3857 .next_state = LLC_CONN_STATE_AWAIT,
3858 .ev_qualifiers = NONE,
3859 .ev_actions = llc_await_rejct_actions_5b,
3860};
3861
3862/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
3863static llc_conn_action_t llc_await_rejct_actions_6[] = {
3864 [0] = llc_conn_ac_inc_vr_by_1,
3865 [1] = llc_conn_ac_data_ind,
3866 [2] = llc_conn_ac_send_rr_rsp_f_set_1,
3867 [3] = llc_conn_ac_stop_rej_timer,
3868 [4] = llc_conn_ac_upd_nr_received,
3869 [5] = llc_conn_ac_upd_vs,
3870 [6] = NULL,
3871};
3872
3873static struct llc_conn_state_trans llc_await_rejct_state_trans_6 = {
3874 .ev = llc_conn_ev_rx_i_cmd_pbit_set_1,
3875 .next_state = LLC_CONN_STATE_AWAIT,
3876 .ev_qualifiers = NONE,
3877 .ev_actions = llc_await_rejct_actions_6,
3878};
3879
3880/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
3881static llc_conn_action_t llc_await_rejct_actions_7a[] = {
3882 [0] = llc_conn_ac_upd_nr_received,
3883 [1] = llc_conn_ac_upd_vs,
3884 [2] = llc_conn_ac_stop_p_timer,
3885 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
3886 [4] = llc_conn_ac_clear_remote_busy,
3887 [5] = NULL,
3888};
3889
3890static struct llc_conn_state_trans llc_await_rejct_state_trans_7a = {
3891 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_1,
3892 .next_state = LLC_CONN_STATE_REJ,
3893 .ev_qualifiers = NONE,
3894 .ev_actions = llc_await_rejct_actions_7a,
3895};
3896
3897/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 event */
3898static llc_conn_action_t llc_await_rejct_actions_7b[] = {
3899 [0] = llc_conn_ac_upd_nr_received,
3900 [1] = llc_conn_ac_upd_vs,
3901 [2] = llc_conn_ac_stop_p_timer,
3902 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
3903 [4] = llc_conn_ac_clear_remote_busy,
3904 [5] = NULL,
3905};
3906
3907static struct llc_conn_state_trans llc_await_rejct_state_trans_7b = {
3908 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_1,
3909 .next_state = LLC_CONN_STATE_REJ,
3910 .ev_qualifiers = NONE,
3911 .ev_actions = llc_await_rejct_actions_7b,
3912};
3913
3914/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
3915static llc_conn_action_t llc_await_rejct_actions_7c[] = {
3916 [0] = llc_conn_ac_upd_nr_received,
3917 [1] = llc_conn_ac_upd_vs,
3918 [2] = llc_conn_ac_stop_p_timer,
3919 [3] = llc_conn_ac_resend_i_xxx_x_set_0,
3920 [4] = llc_conn_ac_clear_remote_busy,
3921 [5] = NULL,
3922};
3923
3924static struct llc_conn_state_trans llc_await_rejct_state_trans_7c = {
3925 .ev = llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
3926 .next_state = LLC_CONN_STATE_REJ,
3927 .ev_qualifiers = NONE,
3928 .ev_actions = llc_await_rejct_actions_7c,
3929};
3930
3931/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
3932static llc_conn_action_t llc_await_rejct_actions_8a[] = {
3933 [0] = llc_conn_ac_upd_nr_received,
3934 [1] = llc_conn_ac_upd_vs,
3935 [2] = llc_conn_ac_clear_remote_busy,
3936 [3] = NULL,
3937};
3938
3939static struct llc_conn_state_trans llc_await_rejct_state_trans_8a = {
3940 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_0,
3941 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3942 .ev_qualifiers = NONE,
3943 .ev_actions = llc_await_rejct_actions_8a,
3944};
3945
3946/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
3947static llc_conn_action_t llc_await_rejct_actions_8b[] = {
3948 [0] = llc_conn_ac_upd_nr_received,
3949 [1] = llc_conn_ac_upd_vs,
3950 [2] = llc_conn_ac_clear_remote_busy,
3951 [3] = NULL,
3952};
3953
3954static struct llc_conn_state_trans llc_await_rejct_state_trans_8b = {
3955 .ev = llc_conn_ev_rx_rr_rsp_fbit_set_0,
3956 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3957 .ev_qualifiers = NONE,
3958 .ev_actions = llc_await_rejct_actions_8b,
3959};
3960
3961/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
3962static llc_conn_action_t llc_await_rejct_actions_8c[] = {
3963 [0] = llc_conn_ac_upd_nr_received,
3964 [1] = llc_conn_ac_upd_vs,
3965 [2] = llc_conn_ac_clear_remote_busy,
3966 [3] = NULL,
3967};
3968
3969static struct llc_conn_state_trans llc_await_rejct_state_trans_8c = {
3970 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_0,
3971 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3972 .ev_qualifiers = NONE,
3973 .ev_actions = llc_await_rejct_actions_8c,
3974};
3975
3976/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
3977static llc_conn_action_t llc_await_rejct_actions_8d[] = {
3978 [0] = llc_conn_ac_upd_nr_received,
3979 [1] = llc_conn_ac_upd_vs,
3980 [2] = llc_conn_ac_clear_remote_busy,
3981 [3] = NULL,
3982};
3983
3984static struct llc_conn_state_trans llc_await_rejct_state_trans_8d = {
3985 .ev = llc_conn_ev_rx_rej_rsp_fbit_set_0,
3986 .next_state = LLC_CONN_STATE_AWAIT_REJ,
3987 .ev_qualifiers = NONE,
3988 .ev_actions = llc_await_rejct_actions_8d,
3989};
3990
3991/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
3992static llc_conn_action_t llc_await_rejct_actions_9a[] = {
3993 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
3994 [1] = llc_conn_ac_upd_nr_received,
3995 [2] = llc_conn_ac_upd_vs,
3996 [3] = llc_conn_ac_clear_remote_busy,
3997 [4] = NULL,
3998};
3999
4000static struct llc_conn_state_trans llc_await_rejct_state_trans_9a = {
4001 .ev = llc_conn_ev_rx_rr_cmd_pbit_set_1,
4002 .next_state = LLC_CONN_STATE_AWAIT_REJ,
4003 .ev_qualifiers = NONE,
4004 .ev_actions = llc_await_rejct_actions_9a,
4005};
4006
4007/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
4008static llc_conn_action_t llc_await_rejct_actions_9b[] = {
4009 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
4010 [1] = llc_conn_ac_upd_nr_received,
4011 [2] = llc_conn_ac_upd_vs,
4012 [3] = llc_conn_ac_clear_remote_busy,
4013 [4] = NULL,
4014};
4015
4016static struct llc_conn_state_trans llc_await_rejct_state_trans_9b = {
4017 .ev = llc_conn_ev_rx_rej_cmd_pbit_set_1,
4018 .next_state = LLC_CONN_STATE_AWAIT_REJ,
4019 .ev_qualifiers = NONE,
4020 .ev_actions = llc_await_rejct_actions_9b,
4021};
4022
4023/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
4024static llc_conn_action_t llc_await_rejct_actions_10[] = {
4025 [0] = llc_conn_ac_upd_nr_received,
4026 [1] = llc_conn_ac_upd_vs,
4027 [2] = llc_conn_ac_stop_p_timer,
4028 [3] = llc_conn_ac_set_remote_busy,
4029 [4] = NULL,
4030};
4031
4032static struct llc_conn_state_trans llc_await_rejct_state_trans_10 = {
4033 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_1,
4034 .next_state = LLC_CONN_STATE_REJ,
4035 .ev_qualifiers = NONE,
4036 .ev_actions = llc_await_rejct_actions_10,
4037};
4038
4039/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
4040static llc_conn_action_t llc_await_rejct_actions_11a[] = {
4041 [0] = llc_conn_ac_upd_nr_received,
4042 [1] = llc_conn_ac_upd_vs,
4043 [2] = llc_conn_ac_set_remote_busy,
4044 [3] = NULL,
4045};
4046
4047static struct llc_conn_state_trans llc_await_rejct_state_trans_11a = {
4048 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_0,
4049 .next_state = LLC_CONN_STATE_AWAIT_REJ,
4050 .ev_qualifiers = NONE,
4051 .ev_actions = llc_await_rejct_actions_11a,
4052};
4053
4054/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
4055static llc_conn_action_t llc_await_rejct_actions_11b[] = {
4056 [0] = llc_conn_ac_upd_nr_received,
4057 [1] = llc_conn_ac_upd_vs,
4058 [2] = llc_conn_ac_set_remote_busy,
4059 [3] = NULL,
4060};
4061
4062static struct llc_conn_state_trans llc_await_rejct_state_trans_11b = {
4063 .ev = llc_conn_ev_rx_rnr_rsp_fbit_set_0,
4064 .next_state = LLC_CONN_STATE_AWAIT_REJ,
4065 .ev_qualifiers = NONE,
4066 .ev_actions = llc_await_rejct_actions_11b,
4067};
4068
4069/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
4070static llc_conn_action_t llc_await_rejct_actions_12[] = {
4071 [0] = llc_conn_ac_send_rr_rsp_f_set_1,
4072 [1] = llc_conn_ac_upd_nr_received,
4073 [2] = llc_conn_ac_upd_vs,
4074 [3] = llc_conn_ac_set_remote_busy,
4075 [4] = NULL,
4076};
4077
4078static struct llc_conn_state_trans llc_await_rejct_state_trans_12 = {
4079 .ev = llc_conn_ev_rx_rnr_cmd_pbit_set_1,
4080 .next_state = LLC_CONN_STATE_AWAIT_REJ,
4081 .ev_qualifiers = NONE,
4082 .ev_actions = llc_await_rejct_actions_12,
4083};
4084
4085/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
4086static llc_conn_ev_qfyr_t llc_await_rejct_ev_qfyrs_13[] = {
4087 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
4088 [1] = NULL,
4089};
4090
4091static llc_conn_action_t llc_await_rejct_actions_13[] = {
4092 [0] = llc_conn_ac_send_rej_cmd_p_set_1,
4093 [1] = llc_conn_ac_stop_p_timer,
4094 [2] = llc_conn_ac_inc_retry_cnt_by_1,
4095 [3] = NULL,
4096};
4097
4098static struct llc_conn_state_trans llc_await_rejct_state_trans_13 = {
4099 .ev = llc_conn_ev_p_tmr_exp,
4100 .next_state = LLC_CONN_STATE_AWAIT_REJ,
4101 .ev_qualifiers = llc_await_rejct_ev_qfyrs_13,
4102 .ev_actions = llc_await_rejct_actions_13,
4103};
4104
4105/*
4106 * Array of pointers;
4107 * one to each transition
4108 */
4109static struct llc_conn_state_trans *llc_await_rejct_state_transitions[] = {
4110 [0] = &llc_await_reject_state_trans_1_0,
4111 [1] = &llc_common_state_trans_1, /* requests */
4112 [2] = &llc_common_state_trans_2,
4113 [3] = &llc_common_state_trans_end,
4114 [4] = &llc_await_rejct_state_trans_1, /* local busy */
4115 [5] = &llc_common_state_trans_end,
4116 [6] = &llc_common_state_trans_end, /* Initiate PF cycle */
4117 [7] = &llc_await_rejct_state_trans_13, /* timers */
4118 [8] = &llc_common_state_trans_11a,
4119 [9] = &llc_common_state_trans_11b,
4120 [10] = &llc_common_state_trans_11c,
4121 [11] = &llc_common_state_trans_11d,
4122 [12] = &llc_common_state_trans_end,
4123 [13] = &llc_await_rejct_state_trans_2a, /* receive frames */
4124 [14] = &llc_await_rejct_state_trans_2b,
4125 [15] = &llc_await_rejct_state_trans_3,
4126 [16] = &llc_await_rejct_state_trans_4,
4127 [17] = &llc_await_rejct_state_trans_5a,
4128 [18] = &llc_await_rejct_state_trans_5b,
4129 [19] = &llc_await_rejct_state_trans_6,
4130 [20] = &llc_await_rejct_state_trans_7a,
4131 [21] = &llc_await_rejct_state_trans_7b,
4132 [22] = &llc_await_rejct_state_trans_7c,
4133 [23] = &llc_await_rejct_state_trans_8a,
4134 [24] = &llc_await_rejct_state_trans_8b,
4135 [25] = &llc_await_rejct_state_trans_8c,
4136 [26] = &llc_await_rejct_state_trans_8d,
4137 [27] = &llc_await_rejct_state_trans_9a,
4138 [28] = &llc_await_rejct_state_trans_9b,
4139 [29] = &llc_await_rejct_state_trans_10,
4140 [30] = &llc_await_rejct_state_trans_11a,
4141 [31] = &llc_await_rejct_state_trans_11b,
4142 [32] = &llc_await_rejct_state_trans_12,
4143 [33] = &llc_common_state_trans_3,
4144 [34] = &llc_common_state_trans_4,
4145 [35] = &llc_common_state_trans_5,
4146 [36] = &llc_common_state_trans_6,
4147 [37] = &llc_common_state_trans_7a,
4148 [38] = &llc_common_state_trans_7b,
4149 [39] = &llc_common_state_trans_8a,
4150 [40] = &llc_common_state_trans_8b,
4151 [41] = &llc_common_state_trans_8c,
4152 [42] = &llc_common_state_trans_9,
4153 /* [43] = &llc_common_state_trans_10, */
4154 [43] = &llc_common_state_trans_end,
4155};
4156
4157/* LLC_CONN_STATE_D_CONN transitions */
4158/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event,
4159 * cause_flag = 1 */
4160static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_1[] = {
4161 [0] = llc_conn_ev_qlfy_cause_flag_eq_1,
4162 [1] = llc_conn_ev_qlfy_set_status_conflict,
4163 [2] = NULL,
4164};
4165
4166static llc_conn_action_t llc_d_conn_actions_1[] = {
4167 [0] = llc_conn_ac_send_dm_rsp_f_set_p,
4168 [1] = llc_conn_ac_stop_ack_timer,
4169 [2] = llc_conn_ac_disc_confirm,
4170 [3] = llc_conn_disc,
4171 [4] = NULL,
4172};
4173
4174static struct llc_conn_state_trans llc_d_conn_state_trans_1 = {
4175 .ev = llc_conn_ev_rx_sabme_cmd_pbit_set_x,
4176 .next_state = LLC_CONN_STATE_ADM,
4177 .ev_qualifiers = llc_d_conn_ev_qfyrs_1,
4178 .ev_actions = llc_d_conn_actions_1,
4179};
4180
4181/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event,
4182 * cause_flag = 0
4183 */
4184static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_1_1[] = {
4185 [0] = llc_conn_ev_qlfy_cause_flag_eq_0,
4186 [1] = llc_conn_ev_qlfy_set_status_conflict,
4187 [2] = NULL,
4188};
4189
4190static llc_conn_action_t llc_d_conn_actions_1_1[] = {
4191 [0] = llc_conn_ac_send_dm_rsp_f_set_p,
4192 [1] = llc_conn_ac_stop_ack_timer,
4193 [2] = llc_conn_disc,
4194 [3] = NULL,
4195};
4196
4197static struct llc_conn_state_trans llc_d_conn_state_trans_1_1 = {
4198 .ev = llc_conn_ev_rx_sabme_cmd_pbit_set_x,
4199 .next_state = LLC_CONN_STATE_ADM,
4200 .ev_qualifiers = llc_d_conn_ev_qfyrs_1_1,
4201 .ev_actions = llc_d_conn_actions_1_1,
4202};
4203
4204/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event,
4205 * cause_flag = 1
4206 */
4207static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_2[] = {
4208 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
4209 [1] = llc_conn_ev_qlfy_cause_flag_eq_1,
4210 [2] = llc_conn_ev_qlfy_set_status_disc,
4211 [3] = NULL,
4212};
4213
4214static llc_conn_action_t llc_d_conn_actions_2[] = {
4215 [0] = llc_conn_ac_stop_ack_timer,
4216 [1] = llc_conn_ac_disc_confirm,
4217 [2] = llc_conn_disc,
4218 [3] = NULL,
4219};
4220
4221static struct llc_conn_state_trans llc_d_conn_state_trans_2 = {
4222 .ev = llc_conn_ev_rx_ua_rsp_fbit_set_x,
4223 .next_state = LLC_CONN_STATE_ADM,
4224 .ev_qualifiers = llc_d_conn_ev_qfyrs_2,
4225 .ev_actions = llc_d_conn_actions_2,
4226};
4227
4228/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event,
4229 * cause_flag = 0
4230 */
4231static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_2_1[] = {
4232 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
4233 [1] = llc_conn_ev_qlfy_cause_flag_eq_0,
4234 [2] = llc_conn_ev_qlfy_set_status_disc,
4235 [3] = NULL,
4236};
4237
4238static llc_conn_action_t llc_d_conn_actions_2_1[] = {
4239 [0] = llc_conn_ac_stop_ack_timer,
4240 [1] = llc_conn_disc,
4241 [2] = NULL,
4242};
4243
4244static struct llc_conn_state_trans llc_d_conn_state_trans_2_1 = {
4245 .ev = llc_conn_ev_rx_ua_rsp_fbit_set_x,
4246 .next_state = LLC_CONN_STATE_ADM,
4247 .ev_qualifiers = llc_d_conn_ev_qfyrs_2_1,
4248 .ev_actions = llc_d_conn_actions_2_1,
4249};
4250
4251/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
4252static llc_conn_action_t llc_d_conn_actions_3[] = {
4253 [0] = llc_conn_ac_send_ua_rsp_f_set_p,
4254 [1] = NULL,
4255};
4256
4257static struct llc_conn_state_trans llc_d_conn_state_trans_3 = {
4258 .ev = llc_conn_ev_rx_disc_cmd_pbit_set_x,
4259 .next_state = LLC_CONN_STATE_D_CONN,
4260 .ev_qualifiers = NONE,
4261 .ev_actions = llc_d_conn_actions_3,
4262};
4263
4264/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event,
4265 * cause_flag = 1
4266 */
4267static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_4[] = {
4268 [0] = llc_conn_ev_qlfy_cause_flag_eq_1,
4269 [1] = llc_conn_ev_qlfy_set_status_disc,
4270 [2] = NULL,
4271};
4272
4273static llc_conn_action_t llc_d_conn_actions_4[] = {
4274 [0] = llc_conn_ac_stop_ack_timer,
4275 [1] = llc_conn_ac_disc_confirm,
4276 [2] = llc_conn_disc,
4277 [3] = NULL,
4278};
4279
4280static struct llc_conn_state_trans llc_d_conn_state_trans_4 = {
4281 .ev = llc_conn_ev_rx_dm_rsp_fbit_set_x,
4282 .next_state = LLC_CONN_STATE_ADM,
4283 .ev_qualifiers = llc_d_conn_ev_qfyrs_4,
4284 .ev_actions = llc_d_conn_actions_4,
4285};
4286
4287/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event,
4288 * cause_flag = 0
4289 */
4290static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_4_1[] = {
4291 [0] = llc_conn_ev_qlfy_cause_flag_eq_0,
4292 [1] = llc_conn_ev_qlfy_set_status_disc,
4293 [2] = NULL,
4294};
4295
4296static llc_conn_action_t llc_d_conn_actions_4_1[] = {
4297 [0] = llc_conn_ac_stop_ack_timer,
4298 [1] = llc_conn_disc,
4299 [2] = NULL,
4300};
4301
4302static struct llc_conn_state_trans llc_d_conn_state_trans_4_1 = {
4303 .ev = llc_conn_ev_rx_dm_rsp_fbit_set_x,
4304 .next_state = LLC_CONN_STATE_ADM,
4305 .ev_qualifiers = llc_d_conn_ev_qfyrs_4_1,
4306 .ev_actions = llc_d_conn_actions_4_1,
4307};
4308
4309/*
4310 * State transition for
4311 * LLC_CONN_EV_DATA_CONN_REQ event
4312 */
4313static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_5[] = {
4314 [0] = llc_conn_ev_qlfy_set_status_refuse,
4315 [1] = NULL,
4316};
4317
4318/* just one member, NULL, .bss zeroes it */
4319static llc_conn_action_t llc_d_conn_actions_5[1];
4320
4321static struct llc_conn_state_trans llc_d_conn_state_trans_5 = {
4322 .ev = llc_conn_ev_data_req,
4323 .next_state = LLC_CONN_STATE_D_CONN,
4324 .ev_qualifiers = llc_d_conn_ev_qfyrs_5,
4325 .ev_actions = llc_d_conn_actions_5,
4326};
4327
4328/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
4329static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_6[] = {
4330 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
4331 [1] = NULL,
4332};
4333
4334static llc_conn_action_t llc_d_conn_actions_6[] = {
4335 [0] = llc_conn_ac_send_disc_cmd_p_set_x,
4336 [1] = llc_conn_ac_start_ack_timer,
4337 [2] = llc_conn_ac_inc_retry_cnt_by_1,
4338 [3] = NULL,
4339};
4340
4341static struct llc_conn_state_trans llc_d_conn_state_trans_6 = {
4342 .ev = llc_conn_ev_ack_tmr_exp,
4343 .next_state = LLC_CONN_STATE_D_CONN,
4344 .ev_qualifiers = llc_d_conn_ev_qfyrs_6,
4345 .ev_actions = llc_d_conn_actions_6,
4346};
4347
4348/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event, cause_flag = 1 */
4349static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_7[] = {
4350 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
4351 [1] = llc_conn_ev_qlfy_cause_flag_eq_1,
4352 [2] = llc_conn_ev_qlfy_set_status_failed,
4353 [3] = NULL,
4354};
4355
4356static llc_conn_action_t llc_d_conn_actions_7[] = {
4357 [0] = llc_conn_ac_disc_confirm,
4358 [1] = llc_conn_disc,
4359 [2] = NULL,
4360};
4361
4362static struct llc_conn_state_trans llc_d_conn_state_trans_7 = {
4363 .ev = llc_conn_ev_ack_tmr_exp,
4364 .next_state = LLC_CONN_STATE_ADM,
4365 .ev_qualifiers = llc_d_conn_ev_qfyrs_7,
4366 .ev_actions = llc_d_conn_actions_7,
4367};
4368
4369/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event, cause_flag = 0 */
4370static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_8[] = {
4371 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
4372 [1] = llc_conn_ev_qlfy_cause_flag_eq_0,
4373 [2] = llc_conn_ev_qlfy_set_status_failed,
4374 [3] = NULL,
4375};
4376
4377static llc_conn_action_t llc_d_conn_actions_8[] = {
4378 [0] = llc_conn_disc,
4379 [1] = NULL,
4380};
4381
4382static struct llc_conn_state_trans llc_d_conn_state_trans_8 = {
4383 .ev = llc_conn_ev_ack_tmr_exp,
4384 .next_state = LLC_CONN_STATE_ADM,
4385 .ev_qualifiers = llc_d_conn_ev_qfyrs_8,
4386 .ev_actions = llc_d_conn_actions_8,
4387};
4388
4389/*
4390 * Array of pointers;
4391 * one to each transition
4392 */
4393static struct llc_conn_state_trans *llc_d_conn_state_transitions[] = {
4394 [0] = &llc_d_conn_state_trans_5, /* Request */
4395 [1] = &llc_common_state_trans_end,
4396 [2] = &llc_common_state_trans_end, /* Local busy */
4397 [3] = &llc_common_state_trans_end, /* Initiate PF cycle */
4398 [4] = &llc_d_conn_state_trans_6, /* Timer */
4399 [5] = &llc_d_conn_state_trans_7,
4400 [6] = &llc_d_conn_state_trans_8,
4401 [7] = &llc_common_state_trans_end,
4402 [8] = &llc_d_conn_state_trans_1, /* Receive frame */
4403 [9] = &llc_d_conn_state_trans_1_1,
4404 [10] = &llc_d_conn_state_trans_2,
4405 [11] = &llc_d_conn_state_trans_2_1,
4406 [12] = &llc_d_conn_state_trans_3,
4407 [13] = &llc_d_conn_state_trans_4,
4408 [14] = &llc_d_conn_state_trans_4_1,
4409 [15] = &llc_common_state_trans_end,
4410};
4411
4412/* LLC_CONN_STATE_RESET transitions */
4413/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
4414static llc_conn_action_t llc_rst_actions_1[] = {
4415 [0] = llc_conn_ac_set_vs_0,
4416 [1] = llc_conn_ac_set_vr_0,
4417 [2] = llc_conn_ac_set_s_flag_1,
4418 [3] = llc_conn_ac_send_ua_rsp_f_set_p,
4419 [4] = NULL,
4420};
4421
4422static struct llc_conn_state_trans llc_rst_state_trans_1 = {
4423 .ev = llc_conn_ev_rx_sabme_cmd_pbit_set_x,
4424 .next_state = LLC_CONN_STATE_RESET,
4425 .ev_qualifiers = NONE,
4426 .ev_actions = llc_rst_actions_1,
4427};
4428
4429/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event,
4430 * cause_flag = 1
4431 */
4432static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_2[] = {
4433 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
4434 [1] = llc_conn_ev_qlfy_cause_flag_eq_1,
4435 [2] = llc_conn_ev_qlfy_set_status_conn,
4436 [3] = NULL,
4437};
4438
4439static llc_conn_action_t llc_rst_actions_2[] = {
4440 [0] = llc_conn_ac_stop_ack_timer,
4441 [1] = llc_conn_ac_set_vs_0,
4442 [2] = llc_conn_ac_set_vr_0,
4443 [3] = llc_conn_ac_upd_p_flag,
4444 [4] = llc_conn_ac_rst_confirm,
4445 [5] = llc_conn_ac_set_remote_busy_0,
4446 [6] = llc_conn_reset,
4447 [7] = NULL,
4448};
4449
4450static struct llc_conn_state_trans llc_rst_state_trans_2 = {
4451 .ev = llc_conn_ev_rx_ua_rsp_fbit_set_x,
4452 .next_state = LLC_CONN_STATE_NORMAL,
4453 .ev_qualifiers = llc_rst_ev_qfyrs_2,
4454 .ev_actions = llc_rst_actions_2,
4455};
4456
4457/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event,
4458 * cause_flag = 0
4459 */
4460static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_2_1[] = {
4461 [0] = llc_conn_ev_qlfy_p_flag_eq_f,
4462 [1] = llc_conn_ev_qlfy_cause_flag_eq_0,
4463 [2] = llc_conn_ev_qlfy_set_status_rst_done,
4464 [3] = NULL,
4465};
4466
4467static llc_conn_action_t llc_rst_actions_2_1[] = {
4468 [0] = llc_conn_ac_stop_ack_timer,
4469 [1] = llc_conn_ac_set_vs_0,
4470 [2] = llc_conn_ac_set_vr_0,
4471 [3] = llc_conn_ac_upd_p_flag,
4472 [4] = llc_conn_ac_rst_confirm,
4473 [5] = llc_conn_ac_set_remote_busy_0,
4474 [6] = llc_conn_reset,
4475 [7] = NULL,
4476};
4477
4478static struct llc_conn_state_trans llc_rst_state_trans_2_1 = {
4479 .ev = llc_conn_ev_rx_ua_rsp_fbit_set_x,
4480 .next_state = LLC_CONN_STATE_NORMAL,
4481 .ev_qualifiers = llc_rst_ev_qfyrs_2_1,
4482 .ev_actions = llc_rst_actions_2_1,
4483};
4484
4485/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
4486static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_3[] = {
4487 [0] = llc_conn_ev_qlfy_s_flag_eq_1,
4488 [1] = llc_conn_ev_qlfy_set_status_rst_done,
4489 [2] = NULL,
4490};
4491
4492static llc_conn_action_t llc_rst_actions_3[] = {
4493 [0] = llc_conn_ac_set_p_flag_0,
4494 [1] = llc_conn_ac_set_remote_busy_0,
4495 [2] = NULL,
4496};
4497
4498static struct llc_conn_state_trans llc_rst_state_trans_3 = {
4499 .ev = llc_conn_ev_ack_tmr_exp,
4500 .next_state = LLC_CONN_STATE_NORMAL,
4501 .ev_qualifiers = llc_rst_ev_qfyrs_3,
4502 .ev_actions = llc_rst_actions_3,
4503};
4504
4505/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event,
4506 * cause_flag = 1
4507 */
4508static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_4[] = {
4509 [0] = llc_conn_ev_qlfy_cause_flag_eq_1,
4510 [1] = llc_conn_ev_qlfy_set_status_disc,
4511 [2] = NULL,
4512};
4513static llc_conn_action_t llc_rst_actions_4[] = {
4514 [0] = llc_conn_ac_send_dm_rsp_f_set_p,
4515 [1] = llc_conn_ac_disc_ind,
4516 [2] = llc_conn_ac_stop_ack_timer,
4517 [3] = llc_conn_disc,
4518 [4] = NULL,
4519};
4520
4521static struct llc_conn_state_trans llc_rst_state_trans_4 = {
4522 .ev = llc_conn_ev_rx_disc_cmd_pbit_set_x,
4523 .next_state = LLC_CONN_STATE_ADM,
4524 .ev_qualifiers = llc_rst_ev_qfyrs_4,
4525 .ev_actions = llc_rst_actions_4,
4526};
4527
4528/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event,
4529 * cause_flag = 0
4530 */
4531static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_4_1[] = {
4532 [0] = llc_conn_ev_qlfy_cause_flag_eq_0,
4533 [1] = llc_conn_ev_qlfy_set_status_refuse,
4534 [2] = NULL,
4535};
4536
4537static llc_conn_action_t llc_rst_actions_4_1[] = {
4538 [0] = llc_conn_ac_send_dm_rsp_f_set_p,
4539 [1] = llc_conn_ac_stop_ack_timer,
4540 [2] = llc_conn_disc,
4541 [3] = NULL,
4542};
4543
4544static struct llc_conn_state_trans llc_rst_state_trans_4_1 = {
4545 .ev = llc_conn_ev_rx_disc_cmd_pbit_set_x,
4546 .next_state = LLC_CONN_STATE_ADM,
4547 .ev_qualifiers = llc_rst_ev_qfyrs_4_1,
4548 .ev_actions = llc_rst_actions_4_1,
4549};
4550
4551/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event,
4552 * cause_flag = 1
4553 */
4554static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_5[] = {
4555 [0] = llc_conn_ev_qlfy_cause_flag_eq_1,
4556 [1] = llc_conn_ev_qlfy_set_status_disc,
4557 [2] = NULL,
4558};
4559
4560static llc_conn_action_t llc_rst_actions_5[] = {
4561 [0] = llc_conn_ac_disc_ind,
4562 [1] = llc_conn_ac_stop_ack_timer,
4563 [2] = llc_conn_disc,
4564 [3] = NULL,
4565};
4566
4567static struct llc_conn_state_trans llc_rst_state_trans_5 = {
4568 .ev = llc_conn_ev_rx_dm_rsp_fbit_set_x,
4569 .next_state = LLC_CONN_STATE_ADM,
4570 .ev_qualifiers = llc_rst_ev_qfyrs_5,
4571 .ev_actions = llc_rst_actions_5,
4572};
4573
4574/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event,
4575 * cause_flag = 0
4576 */
4577static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_5_1[] = {
4578 [0] = llc_conn_ev_qlfy_cause_flag_eq_0,
4579 [1] = llc_conn_ev_qlfy_set_status_refuse,
4580 [2] = NULL,
4581};
4582
4583static llc_conn_action_t llc_rst_actions_5_1[] = {
4584 [0] = llc_conn_ac_stop_ack_timer,
4585 [1] = llc_conn_disc,
4586 [2] = NULL,
4587};
4588
4589static struct llc_conn_state_trans llc_rst_state_trans_5_1 = {
4590 .ev = llc_conn_ev_rx_dm_rsp_fbit_set_x,
4591 .next_state = LLC_CONN_STATE_ADM,
4592 .ev_qualifiers = llc_rst_ev_qfyrs_5_1,
4593 .ev_actions = llc_rst_actions_5_1,
4594};
4595
4596/* State transitions for DATA_CONN_REQ event */
4597static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_6[] = {
4598 [0] = llc_conn_ev_qlfy_set_status_refuse,
4599 [1] = NULL,
4600};
4601
4602/* just one member, NULL, .bss zeroes it */
4603static llc_conn_action_t llc_rst_actions_6[1];
4604
4605static struct llc_conn_state_trans llc_rst_state_trans_6 = {
4606 .ev = llc_conn_ev_data_req,
4607 .next_state = LLC_CONN_STATE_RESET,
4608 .ev_qualifiers = llc_rst_ev_qfyrs_6,
4609 .ev_actions = llc_rst_actions_6,
4610};
4611
4612/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
4613static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_7[] = {
4614 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
4615 [1] = llc_conn_ev_qlfy_s_flag_eq_0,
4616 [2] = NULL,
4617};
4618
4619static llc_conn_action_t llc_rst_actions_7[] = {
4620 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
4621 [1] = llc_conn_ac_start_ack_timer,
4622 [2] = llc_conn_ac_inc_retry_cnt_by_1,
4623 [3] = NULL,
4624};
4625
4626static struct llc_conn_state_trans llc_rst_state_trans_7 = {
4627 .ev = llc_conn_ev_ack_tmr_exp,
4628 .next_state = LLC_CONN_STATE_RESET,
4629 .ev_qualifiers = llc_rst_ev_qfyrs_7,
4630 .ev_actions = llc_rst_actions_7,
4631};
4632
4633/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
4634static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_8[] = {
4635 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
4636 [1] = llc_conn_ev_qlfy_s_flag_eq_0,
4637 [2] = llc_conn_ev_qlfy_cause_flag_eq_1,
4638 [3] = llc_conn_ev_qlfy_set_status_failed,
4639 [4] = NULL,
4640};
4641static llc_conn_action_t llc_rst_actions_8[] = {
4642 [0] = llc_conn_ac_disc_ind,
4643 [1] = llc_conn_disc,
4644 [2] = NULL,
4645};
4646
4647static struct llc_conn_state_trans llc_rst_state_trans_8 = {
4648 .ev = llc_conn_ev_ack_tmr_exp,
4649 .next_state = LLC_CONN_STATE_ADM,
4650 .ev_qualifiers = llc_rst_ev_qfyrs_8,
4651 .ev_actions = llc_rst_actions_8,
4652};
4653
4654/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
4655static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_8_1[] = {
4656 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
4657 [1] = llc_conn_ev_qlfy_s_flag_eq_0,
4658 [2] = llc_conn_ev_qlfy_cause_flag_eq_0,
4659 [3] = llc_conn_ev_qlfy_set_status_failed,
4660 [4] = NULL,
4661};
4662static llc_conn_action_t llc_rst_actions_8_1[] = {
4663 [0] = llc_conn_ac_disc_ind,
4664 [1] = llc_conn_disc,
4665 [2] = NULL,
4666};
4667
4668static struct llc_conn_state_trans llc_rst_state_trans_8_1 = {
4669 .ev = llc_conn_ev_ack_tmr_exp,
4670 .next_state = LLC_CONN_STATE_ADM,
4671 .ev_qualifiers = llc_rst_ev_qfyrs_8_1,
4672 .ev_actions = llc_rst_actions_8_1,
4673};
4674
4675/*
4676 * Array of pointers;
4677 * one to each transition
4678 */
4679static struct llc_conn_state_trans *llc_rst_state_transitions[] = {
4680 [0] = &llc_rst_state_trans_6, /* Request */
4681 [1] = &llc_common_state_trans_end,
4682 [2] = &llc_common_state_trans_end, /* Local busy */
4683 [3] = &llc_common_state_trans_end, /* Initiate PF cycle */
4684 [4] = &llc_rst_state_trans_3, /* Timer */
4685 [5] = &llc_rst_state_trans_7,
4686 [6] = &llc_rst_state_trans_8,
4687 [7] = &llc_rst_state_trans_8_1,
4688 [8] = &llc_common_state_trans_end,
4689 [9] = &llc_rst_state_trans_1, /* Receive frame */
4690 [10] = &llc_rst_state_trans_2,
4691 [11] = &llc_rst_state_trans_2_1,
4692 [12] = &llc_rst_state_trans_4,
4693 [13] = &llc_rst_state_trans_4_1,
4694 [14] = &llc_rst_state_trans_5,
4695 [15] = &llc_rst_state_trans_5_1,
4696 [16] = &llc_common_state_trans_end,
4697};
4698
4699/* LLC_CONN_STATE_ERROR transitions */
4700/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
4701static llc_conn_action_t llc_error_actions_1[] = {
4702 [0] = llc_conn_ac_set_vs_0,
4703 [1] = llc_conn_ac_set_vr_0,
4704 [2] = llc_conn_ac_send_ua_rsp_f_set_p,
4705 [3] = llc_conn_ac_rst_ind,
4706 [4] = llc_conn_ac_set_p_flag_0,
4707 [5] = llc_conn_ac_set_remote_busy_0,
4708 [6] = llc_conn_ac_stop_ack_timer,
4709 [7] = llc_conn_reset,
4710 [8] = NULL,
4711};
4712
4713static struct llc_conn_state_trans llc_error_state_trans_1 = {
4714 .ev = llc_conn_ev_rx_sabme_cmd_pbit_set_x,
4715 .next_state = LLC_CONN_STATE_NORMAL,
4716 .ev_qualifiers = NONE,
4717 .ev_actions = llc_error_actions_1,
4718};
4719
4720/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
4721static llc_conn_action_t llc_error_actions_2[] = {
4722 [0] = llc_conn_ac_send_ua_rsp_f_set_p,
4723 [1] = llc_conn_ac_disc_ind,
4724 [2] = llc_conn_ac_stop_ack_timer,
4725 [3] = llc_conn_disc,
4726 [4] = NULL,
4727};
4728
4729static struct llc_conn_state_trans llc_error_state_trans_2 = {
4730 .ev = llc_conn_ev_rx_disc_cmd_pbit_set_x,
4731 .next_state = LLC_CONN_STATE_ADM,
4732 .ev_qualifiers = NONE,
4733 .ev_actions = llc_error_actions_2,
4734};
4735
4736/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event */
4737static llc_conn_action_t llc_error_actions_3[] = {
4738 [0] = llc_conn_ac_disc_ind,
4739 [1] = llc_conn_ac_stop_ack_timer,
4740 [2] = llc_conn_disc,
4741 [3] = NULL,
4742};
4743
4744static struct llc_conn_state_trans llc_error_state_trans_3 = {
4745 .ev = llc_conn_ev_rx_dm_rsp_fbit_set_x,
4746 .next_state = LLC_CONN_STATE_ADM,
4747 .ev_qualifiers = NONE,
4748 .ev_actions = llc_error_actions_3,
4749};
4750
4751/* State transitions for LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X event */
4752static llc_conn_action_t llc_error_actions_4[] = {
4753 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
4754 [1] = llc_conn_ac_start_ack_timer,
4755 [2] = llc_conn_ac_set_retry_cnt_0,
4756 [3] = llc_conn_ac_set_cause_flag_0,
4757 [4] = NULL,
4758};
4759
4760static struct llc_conn_state_trans llc_error_state_trans_4 = {
4761 .ev = llc_conn_ev_rx_frmr_rsp_fbit_set_x,
4762 .next_state = LLC_CONN_STATE_RESET,
4763 .ev_qualifiers = NONE,
4764 .ev_actions = llc_error_actions_4,
4765};
4766
4767/* State transitions for LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X event */
4768static llc_conn_action_t llc_error_actions_5[] = {
4769 [0] = llc_conn_ac_resend_frmr_rsp_f_set_p,
4770 [1] = NULL,
4771};
4772
4773static struct llc_conn_state_trans llc_error_state_trans_5 = {
4774 .ev = llc_conn_ev_rx_xxx_cmd_pbit_set_x,
4775 .next_state = LLC_CONN_STATE_ERROR,
4776 .ev_qualifiers = NONE,
4777 .ev_actions = llc_error_actions_5,
4778};
4779
4780/* State transitions for LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X event */
4781static struct llc_conn_state_trans llc_error_state_trans_6 = {
4782 .ev = llc_conn_ev_rx_xxx_rsp_fbit_set_x,
4783 .next_state = LLC_CONN_STATE_ERROR,
4784 .ev_qualifiers = NONE,
4785 .ev_actions = NONE,
4786};
4787
4788/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
4789static llc_conn_ev_qfyr_t llc_error_ev_qfyrs_7[] = {
4790 [0] = llc_conn_ev_qlfy_retry_cnt_lt_n2,
4791 [1] = NULL,
4792};
4793
4794static llc_conn_action_t llc_error_actions_7[] = {
4795 [0] = llc_conn_ac_resend_frmr_rsp_f_set_0,
4796 [1] = llc_conn_ac_start_ack_timer,
4797 [2] = llc_conn_ac_inc_retry_cnt_by_1,
4798 [3] = NULL,
4799};
4800
4801static struct llc_conn_state_trans llc_error_state_trans_7 = {
4802 .ev = llc_conn_ev_ack_tmr_exp,
4803 .next_state = LLC_CONN_STATE_ERROR,
4804 .ev_qualifiers = llc_error_ev_qfyrs_7,
4805 .ev_actions = llc_error_actions_7,
4806};
4807
4808/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
4809static llc_conn_ev_qfyr_t llc_error_ev_qfyrs_8[] = {
4810 [0] = llc_conn_ev_qlfy_retry_cnt_gte_n2,
4811 [1] = NULL,
4812};
4813
4814static llc_conn_action_t llc_error_actions_8[] = {
4815 [0] = llc_conn_ac_send_sabme_cmd_p_set_x,
4816 [1] = llc_conn_ac_set_s_flag_0,
4817 [2] = llc_conn_ac_start_ack_timer,
4818 [3] = llc_conn_ac_set_retry_cnt_0,
4819 [4] = llc_conn_ac_set_cause_flag_0,
4820 [5] = NULL,
4821};
4822
4823static struct llc_conn_state_trans llc_error_state_trans_8 = {
4824 .ev = llc_conn_ev_ack_tmr_exp,
4825 .next_state = LLC_CONN_STATE_RESET,
4826 .ev_qualifiers = llc_error_ev_qfyrs_8,
4827 .ev_actions = llc_error_actions_8,
4828};
4829
4830/* State transitions for LLC_CONN_EV_DATA_CONN_REQ event */
4831static llc_conn_ev_qfyr_t llc_error_ev_qfyrs_9[] = {
4832 [0] = llc_conn_ev_qlfy_set_status_refuse,
4833 [1] = NULL,
4834};
4835
4836/* just one member, NULL, .bss zeroes it */
4837static llc_conn_action_t llc_error_actions_9[1];
4838
4839static struct llc_conn_state_trans llc_error_state_trans_9 = {
4840 .ev = llc_conn_ev_data_req,
4841 .next_state = LLC_CONN_STATE_ERROR,
4842 .ev_qualifiers = llc_error_ev_qfyrs_9,
4843 .ev_actions = llc_error_actions_9,
4844};
4845
4846/*
4847 * Array of pointers;
4848 * one to each transition
4849 */
4850static struct llc_conn_state_trans *llc_error_state_transitions[] = {
4851 [0] = &llc_error_state_trans_9, /* Request */
4852 [1] = &llc_common_state_trans_end,
4853 [2] = &llc_common_state_trans_end, /* Local busy */
4854 [3] = &llc_common_state_trans_end, /* Initiate PF cycle */
4855 [4] = &llc_error_state_trans_7, /* Timer */
4856 [5] = &llc_error_state_trans_8,
4857 [6] = &llc_common_state_trans_end,
4858 [7] = &llc_error_state_trans_1, /* Receive frame */
4859 [8] = &llc_error_state_trans_2,
4860 [9] = &llc_error_state_trans_3,
4861 [10] = &llc_error_state_trans_4,
4862 [11] = &llc_error_state_trans_5,
4863 [12] = &llc_error_state_trans_6,
4864 [13] = &llc_common_state_trans_end,
4865};
4866
4867/* LLC_CONN_STATE_TEMP transitions */
4868/* State transitions for LLC_CONN_EV_DISC_REQ event */
4869static llc_conn_action_t llc_temp_actions_1[] = {
4870 [0] = llc_conn_ac_stop_all_timers,
4871 [1] = llc_conn_ac_send_disc_cmd_p_set_x,
4872 [2] = llc_conn_disc,
4873 [3] = NULL,
4874};
4875
4876static struct llc_conn_state_trans llc_temp_state_trans_1 = {
4877 .ev = llc_conn_ev_disc_req,
4878 .next_state = LLC_CONN_STATE_ADM,
4879 .ev_qualifiers = NONE,
4880 .ev_actions = llc_temp_actions_1,
4881};
4882
4883/*
4884 * Array of pointers;
4885 * one to each transition
4886 */
4887static struct llc_conn_state_trans *llc_temp_state_transitions[] = {
4888 [0] = &llc_temp_state_trans_1, /* requests */
4889 [1] = &llc_common_state_trans_end,
4890 [2] = &llc_common_state_trans_end, /* local busy */
4891 [3] = &llc_common_state_trans_end, /* init_pf_cycle */
4892 [4] = &llc_common_state_trans_end, /* timer */
4893 [5] = &llc_common_state_trans_end, /* receive */
4894};
4895
4896/* Connection State Transition Table */
4897struct llc_conn_state llc_conn_state_table[NBR_CONN_STATES] = {
4898 [LLC_CONN_STATE_ADM - 1] = {
4899 .current_state = LLC_CONN_STATE_ADM,
4900 .transitions = llc_adm_state_transitions,
4901 },
4902 [LLC_CONN_STATE_SETUP - 1] = {
4903 .current_state = LLC_CONN_STATE_SETUP,
4904 .transitions = llc_setup_state_transitions,
4905 },
4906 [LLC_CONN_STATE_NORMAL - 1] = {
4907 .current_state = LLC_CONN_STATE_NORMAL,
4908 .transitions = llc_normal_state_transitions,
4909 },
4910 [LLC_CONN_STATE_BUSY - 1] = {
4911 .current_state = LLC_CONN_STATE_BUSY,
4912 .transitions = llc_busy_state_transitions,
4913 },
4914 [LLC_CONN_STATE_REJ - 1] = {
4915 .current_state = LLC_CONN_STATE_REJ,
4916 .transitions = llc_reject_state_transitions,
4917 },
4918 [LLC_CONN_STATE_AWAIT - 1] = {
4919 .current_state = LLC_CONN_STATE_AWAIT,
4920 .transitions = llc_await_state_transitions,
4921 },
4922 [LLC_CONN_STATE_AWAIT_BUSY - 1] = {
4923 .current_state = LLC_CONN_STATE_AWAIT_BUSY,
4924 .transitions = llc_await_busy_state_transitions,
4925 },
4926 [LLC_CONN_STATE_AWAIT_REJ - 1] = {
4927 .current_state = LLC_CONN_STATE_AWAIT_REJ,
4928 .transitions = llc_await_rejct_state_transitions,
4929 },
4930 [LLC_CONN_STATE_D_CONN - 1] = {
4931 .current_state = LLC_CONN_STATE_D_CONN,
4932 .transitions = llc_d_conn_state_transitions,
4933 },
4934 [LLC_CONN_STATE_RESET - 1] = {
4935 .current_state = LLC_CONN_STATE_RESET,
4936 .transitions = llc_rst_state_transitions,
4937 },
4938 [LLC_CONN_STATE_ERROR - 1] = {
4939 .current_state = LLC_CONN_STATE_ERROR,
4940 .transitions = llc_error_state_transitions,
4941 },
4942 [LLC_CONN_STATE_TEMP - 1] = {
4943 .current_state = LLC_CONN_STATE_TEMP,
4944 .transitions = llc_temp_state_transitions,
4945 },
4946};
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
new file mode 100644
index 000000000000..eba812a9c69c
--- /dev/null
+++ b/net/llc/llc_conn.c
@@ -0,0 +1,915 @@
1/*
2 * llc_conn.c - Driver routines for connection component.
3 *
4 * Copyright (c) 1997 by Procom Technology, Inc.
5 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License as published by the Free Software Foundation.
9 * This program is distributed without any warranty or implied warranty
10 * of merchantability or fitness for a particular purpose.
11 *
12 * See the GNU General Public License for more details.
13 */
14
15#include <linux/init.h>
16#include <net/llc_sap.h>
17#include <net/llc_conn.h>
18#include <net/sock.h>
19#include <linux/tcp.h>
20#include <net/llc_c_ev.h>
21#include <net/llc_c_ac.h>
22#include <net/llc_c_st.h>
23#include <net/llc_pdu.h>
24
25#if 0
26#define dprintk(args...) printk(KERN_DEBUG args)
27#else
28#define dprintk(args...)
29#endif
30
31static int llc_find_offset(int state, int ev_type);
32static void llc_conn_send_pdus(struct sock *sk);
33static int llc_conn_service(struct sock *sk, struct sk_buff *skb);
34static int llc_exec_conn_trans_actions(struct sock *sk,
35 struct llc_conn_state_trans *trans,
36 struct sk_buff *ev);
37static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
38 struct sk_buff *skb);
39
40/* Offset table on connection states transition diagram */
41static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
42
43/**
44 * llc_conn_state_process - sends event to connection state machine
45 * @sk: connection
46 * @skb: occurred event
47 *
48 * Sends an event to connection state machine. After processing event
49 * (executing it's actions and changing state), upper layer will be
50 * indicated or confirmed, if needed. Returns 0 for success, 1 for
51 * failure. The socket lock has to be held before calling this function.
52 */
53int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
54{
55 int rc;
56 struct llc_sock *llc = llc_sk(sk);
57 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
58
59 /*
60 * We have to hold the skb, because llc_conn_service will kfree it in
61 * the sending path and we need to look at the skb->cb, where we encode
62 * llc_conn_state_ev.
63 */
64 skb_get(skb);
65 ev->ind_prim = ev->cfm_prim = 0;
66 rc = llc_conn_service(sk, skb); /* sending event to state machine */
67 if (rc) {
68 printk(KERN_ERR "%s: llc_conn_service failed\n", __FUNCTION__);
69 goto out_kfree_skb;
70 }
71
72 if (!ev->ind_prim && !ev->cfm_prim) {
73 /* indicate or confirm not required */
74 if (!skb->list)
75 goto out_kfree_skb;
76 goto out_skb_put;
77 }
78
79 if (ev->ind_prim && ev->cfm_prim) /* Paranoia */
80 skb_get(skb);
81
82 switch (ev->ind_prim) {
83 case LLC_DATA_PRIM:
84 llc_save_primitive(skb, LLC_DATA_PRIM);
85 if (sock_queue_rcv_skb(sk, skb)) {
86 /*
87 * shouldn't happen
88 */
89 printk(KERN_ERR "%s: sock_queue_rcv_skb failed!\n",
90 __FUNCTION__);
91 kfree_skb(skb);
92 }
93 break;
94 case LLC_CONN_PRIM: {
95 struct sock *parent = skb->sk;
96
97 skb->sk = sk;
98 skb_queue_tail(&parent->sk_receive_queue, skb);
99 sk->sk_state_change(parent);
100 }
101 break;
102 case LLC_DISC_PRIM:
103 sock_hold(sk);
104 if (sk->sk_type == SOCK_STREAM &&
105 sk->sk_state == TCP_ESTABLISHED) {
106 sk->sk_shutdown = SHUTDOWN_MASK;
107 sk->sk_socket->state = SS_UNCONNECTED;
108 sk->sk_state = TCP_CLOSE;
109 if (!sock_flag(sk, SOCK_DEAD)) {
110 sk->sk_state_change(sk);
111 sock_set_flag(sk, SOCK_DEAD);
112 }
113 }
114 kfree_skb(skb);
115 sock_put(sk);
116 break;
117 case LLC_RESET_PRIM:
118 /*
119 * FIXME:
120 * RESET is not being notified to upper layers for now
121 */
122 printk(KERN_INFO "%s: received a reset ind!\n", __FUNCTION__);
123 kfree_skb(skb);
124 break;
125 default:
126 if (ev->ind_prim) {
127 printk(KERN_INFO "%s: received unknown %d prim!\n",
128 __FUNCTION__, ev->ind_prim);
129 kfree_skb(skb);
130 }
131 /* No indication */
132 break;
133 }
134
135 switch (ev->cfm_prim) {
136 case LLC_DATA_PRIM:
137 if (!llc_data_accept_state(llc->state))
138 sk->sk_write_space(sk);
139 else
140 rc = llc->failed_data_req = 1;
141 break;
142 case LLC_CONN_PRIM:
143 if (sk->sk_type == SOCK_STREAM &&
144 sk->sk_state == TCP_SYN_SENT) {
145 if (ev->status) {
146 sk->sk_socket->state = SS_UNCONNECTED;
147 sk->sk_state = TCP_CLOSE;
148 } else {
149 sk->sk_socket->state = SS_CONNECTED;
150 sk->sk_state = TCP_ESTABLISHED;
151 }
152 sk->sk_state_change(sk);
153 }
154 break;
155 case LLC_DISC_PRIM:
156 sock_hold(sk);
157 if (sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_CLOSING) {
158 sk->sk_socket->state = SS_UNCONNECTED;
159 sk->sk_state = TCP_CLOSE;
160 sk->sk_state_change(sk);
161 }
162 sock_put(sk);
163 break;
164 case LLC_RESET_PRIM:
165 /*
166 * FIXME:
167 * RESET is not being notified to upper layers for now
168 */
169 printk(KERN_INFO "%s: received a reset conf!\n", __FUNCTION__);
170 break;
171 default:
172 if (ev->cfm_prim) {
173 printk(KERN_INFO "%s: received unknown %d prim!\n",
174 __FUNCTION__, ev->cfm_prim);
175 break;
176 }
177 goto out_skb_put; /* No confirmation */
178 }
179out_kfree_skb:
180 kfree_skb(skb);
181out_skb_put:
182 kfree_skb(skb);
183 return rc;
184}
185
186void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
187{
188 /* queue PDU to send to MAC layer */
189 skb_queue_tail(&sk->sk_write_queue, skb);
190 llc_conn_send_pdus(sk);
191}
192
193/**
194 * llc_conn_rtn_pdu - sends received data pdu to upper layer
195 * @sk: Active connection
196 * @skb: Received data frame
197 *
198 * Sends received data pdu to upper layer (by using indicate function).
199 * Prepares service parameters (prim and prim_data). calling indication
200 * function will be done in llc_conn_state_process.
201 */
202void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb)
203{
204 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
205
206 ev->ind_prim = LLC_DATA_PRIM;
207}
208
209/**
210 * llc_conn_resend_i_pdu_as_cmd - resend all all unacknowledged I PDUs
211 * @sk: active connection
212 * @nr: NR
213 * @first_p_bit: p_bit value of first pdu
214 *
215 * Resend all unacknowledged I PDUs, starting with the NR; send first as
216 * command PDU with P bit equal first_p_bit; if more than one send
217 * subsequent as command PDUs with P bit equal zero (0).
218 */
219void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit)
220{
221 struct sk_buff *skb;
222 struct llc_pdu_sn *pdu;
223 u16 nbr_unack_pdus;
224 struct llc_sock *llc;
225 u8 howmany_resend = 0;
226
227 llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus);
228 if (!nbr_unack_pdus)
229 goto out;
230 /*
231 * Process unack PDUs only if unack queue is not empty; remove
232 * appropriate PDUs, fix them up, and put them on mac_pdu_q.
233 */
234 llc = llc_sk(sk);
235
236 while ((skb = skb_dequeue(&llc->pdu_unack_q)) != NULL) {
237 pdu = llc_pdu_sn_hdr(skb);
238 llc_pdu_set_cmd_rsp(skb, LLC_PDU_CMD);
239 llc_pdu_set_pf_bit(skb, first_p_bit);
240 skb_queue_tail(&sk->sk_write_queue, skb);
241 first_p_bit = 0;
242 llc->vS = LLC_I_GET_NS(pdu);
243 howmany_resend++;
244 }
245 if (howmany_resend > 0)
246 llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
247 /* any PDUs to re-send are queued up; start sending to MAC */
248 llc_conn_send_pdus(sk);
249out:;
250}
251
252/**
253 * llc_conn_resend_i_pdu_as_rsp - Resend all unacknowledged I PDUs
254 * @sk: active connection.
255 * @nr: NR
256 * @first_f_bit: f_bit value of first pdu.
257 *
258 * Resend all unacknowledged I PDUs, starting with the NR; send first as
259 * response PDU with F bit equal first_f_bit; if more than one send
260 * subsequent as response PDUs with F bit equal zero (0).
261 */
262void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit)
263{
264 struct sk_buff *skb;
265 u16 nbr_unack_pdus;
266 struct llc_sock *llc = llc_sk(sk);
267 u8 howmany_resend = 0;
268
269 llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus);
270 if (!nbr_unack_pdus)
271 goto out;
272 /*
273 * Process unack PDUs only if unack queue is not empty; remove
274 * appropriate PDUs, fix them up, and put them on mac_pdu_q
275 */
276 while ((skb = skb_dequeue(&llc->pdu_unack_q)) != NULL) {
277 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
278
279 llc_pdu_set_cmd_rsp(skb, LLC_PDU_RSP);
280 llc_pdu_set_pf_bit(skb, first_f_bit);
281 skb_queue_tail(&sk->sk_write_queue, skb);
282 first_f_bit = 0;
283 llc->vS = LLC_I_GET_NS(pdu);
284 howmany_resend++;
285 }
286 if (howmany_resend > 0)
287 llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
288 /* any PDUs to re-send are queued up; start sending to MAC */
289 llc_conn_send_pdus(sk);
290out:;
291}
292
293/**
294 * llc_conn_remove_acked_pdus - Removes acknowledged pdus from tx queue
295 * @sk: active connection
296 * nr: NR
297 * how_many_unacked: size of pdu_unack_q after removing acked pdus
298 *
299 * Removes acknowledged pdus from transmit queue (pdu_unack_q). Returns
300 * the number of pdus that removed from queue.
301 */
302int llc_conn_remove_acked_pdus(struct sock *sk, u8 nr, u16 *how_many_unacked)
303{
304 int pdu_pos, i;
305 struct sk_buff *skb;
306 struct llc_pdu_sn *pdu;
307 int nbr_acked = 0;
308 struct llc_sock *llc = llc_sk(sk);
309 int q_len = skb_queue_len(&llc->pdu_unack_q);
310
311 if (!q_len)
312 goto out;
313 skb = skb_peek(&llc->pdu_unack_q);
314 pdu = llc_pdu_sn_hdr(skb);
315
316 /* finding position of last acked pdu in queue */
317 pdu_pos = ((int)LLC_2_SEQ_NBR_MODULO + (int)nr -
318 (int)LLC_I_GET_NS(pdu)) % LLC_2_SEQ_NBR_MODULO;
319
320 for (i = 0; i < pdu_pos && i < q_len; i++) {
321 skb = skb_dequeue(&llc->pdu_unack_q);
322 if (skb)
323 kfree_skb(skb);
324 nbr_acked++;
325 }
326out:
327 *how_many_unacked = skb_queue_len(&llc->pdu_unack_q);
328 return nbr_acked;
329}
330
331/**
332 * llc_conn_send_pdus - Sends queued PDUs
333 * @sk: active connection
334 *
335 * Sends queued pdus to MAC layer for transmission.
336 */
337static void llc_conn_send_pdus(struct sock *sk)
338{
339 struct sk_buff *skb;
340
341 while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) {
342 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
343
344 if (LLC_PDU_TYPE_IS_I(pdu) &&
345 !(skb->dev->flags & IFF_LOOPBACK)) {
346 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
347
348 skb_queue_tail(&llc_sk(sk)->pdu_unack_q, skb);
349 if (!skb2)
350 break;
351 skb = skb2;
352 }
353 dev_queue_xmit(skb);
354 }
355}
356
357/**
358 * llc_conn_service - finds transition and changes state of connection
359 * @sk: connection
360 * @skb: happened event
361 *
362 * This function finds transition that matches with happened event, then
363 * executes related actions and finally changes state of connection.
364 * Returns 0 for success, 1 for failure.
365 */
366static int llc_conn_service(struct sock *sk, struct sk_buff *skb)
367{
368 int rc = 1;
369 struct llc_sock *llc = llc_sk(sk);
370 struct llc_conn_state_trans *trans;
371
372 if (llc->state > NBR_CONN_STATES)
373 goto out;
374 rc = 0;
375 trans = llc_qualify_conn_ev(sk, skb);
376 if (trans) {
377 rc = llc_exec_conn_trans_actions(sk, trans, skb);
378 if (!rc && trans->next_state != NO_STATE_CHANGE) {
379 llc->state = trans->next_state;
380 if (!llc_data_accept_state(llc->state))
381 sk->sk_state_change(sk);
382 }
383 }
384out:
385 return rc;
386}
387
388/**
389 * llc_qualify_conn_ev - finds transition for event
390 * @sk: connection
391 * @skb: happened event
392 *
393 * This function finds transition that matches with happened event.
394 * Returns pointer to found transition on success, %NULL otherwise.
395 */
396static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
397 struct sk_buff *skb)
398{
399 struct llc_conn_state_trans **next_trans;
400 llc_conn_ev_qfyr_t *next_qualifier;
401 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
402 struct llc_sock *llc = llc_sk(sk);
403 struct llc_conn_state *curr_state =
404 &llc_conn_state_table[llc->state - 1];
405
406 /* search thru events for this state until
407 * list exhausted or until no more
408 */
409 for (next_trans = curr_state->transitions +
410 llc_find_offset(llc->state - 1, ev->type);
411 (*next_trans)->ev; next_trans++) {
412 if (!((*next_trans)->ev)(sk, skb)) {
413 /* got POSSIBLE event match; the event may require
414 * qualification based on the values of a number of
415 * state flags; if all qualifications are met (i.e.,
416 * if all qualifying functions return success, or 0,
417 * then this is THE event we're looking for
418 */
419 for (next_qualifier = (*next_trans)->ev_qualifiers;
420 next_qualifier && *next_qualifier &&
421 !(*next_qualifier)(sk, skb); next_qualifier++)
422 /* nothing */;
423 if (!next_qualifier || !*next_qualifier)
424 /* all qualifiers executed successfully; this is
425 * our transition; return it so we can perform
426 * the associated actions & change the state
427 */
428 return *next_trans;
429 }
430 }
431 return NULL;
432}
433
434/**
435 * llc_exec_conn_trans_actions - executes related actions
436 * @sk: connection
437 * @trans: transition that it's actions must be performed
438 * @skb: event
439 *
440 * Executes actions that is related to happened event. Returns 0 for
441 * success, 1 to indicate failure of at least one action.
442 */
443static int llc_exec_conn_trans_actions(struct sock *sk,
444 struct llc_conn_state_trans *trans,
445 struct sk_buff *skb)
446{
447 int rc = 0;
448 llc_conn_action_t *next_action;
449
450 for (next_action = trans->ev_actions;
451 next_action && *next_action; next_action++) {
452 int rc2 = (*next_action)(sk, skb);
453
454 if (rc2 == 2) {
455 rc = rc2;
456 break;
457 } else if (rc2)
458 rc = 1;
459 }
460 return rc;
461}
462
463/**
464 * llc_lookup_established - Finds connection for the remote/local sap/mac
465 * @sap: SAP
466 * @daddr: address of remote LLC (MAC + SAP)
467 * @laddr: address of local LLC (MAC + SAP)
468 *
469 * Search connection list of the SAP and finds connection using the remote
470 * mac, remote sap, local mac, and local sap. Returns pointer for
471 * connection found, %NULL otherwise.
472 */
473struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
474 struct llc_addr *laddr)
475{
476 struct sock *rc;
477 struct hlist_node *node;
478
479 read_lock_bh(&sap->sk_list.lock);
480 sk_for_each(rc, node, &sap->sk_list.list) {
481 struct llc_sock *llc = llc_sk(rc);
482
483 if (llc->laddr.lsap == laddr->lsap &&
484 llc->daddr.lsap == daddr->lsap &&
485 llc_mac_match(llc->laddr.mac, laddr->mac) &&
486 llc_mac_match(llc->daddr.mac, daddr->mac)) {
487 sock_hold(rc);
488 goto found;
489 }
490 }
491 rc = NULL;
492found:
493 read_unlock_bh(&sap->sk_list.lock);
494 return rc;
495}
496
497/**
498 * llc_lookup_listener - Finds listener for local MAC + SAP
499 * @sap: SAP
500 * @laddr: address of local LLC (MAC + SAP)
501 *
502 * Search connection list of the SAP and finds connection listening on
503 * local mac, and local sap. Returns pointer for parent socket found,
504 * %NULL otherwise.
505 */
506static struct sock *llc_lookup_listener(struct llc_sap *sap,
507 struct llc_addr *laddr)
508{
509 struct sock *rc;
510 struct hlist_node *node;
511
512 read_lock_bh(&sap->sk_list.lock);
513 sk_for_each(rc, node, &sap->sk_list.list) {
514 struct llc_sock *llc = llc_sk(rc);
515
516 if (rc->sk_type == SOCK_STREAM && rc->sk_state == TCP_LISTEN &&
517 llc->laddr.lsap == laddr->lsap &&
518 (llc_mac_match(llc->laddr.mac, laddr->mac) ||
519 llc_mac_null(llc->laddr.mac))) {
520 sock_hold(rc);
521 goto found;
522 }
523 }
524 rc = NULL;
525found:
526 read_unlock_bh(&sap->sk_list.lock);
527 return rc;
528}
529
530/**
531 * llc_data_accept_state - designates if in this state data can be sent.
532 * @state: state of connection.
533 *
534 * Returns 0 if data can be sent, 1 otherwise.
535 */
536u8 llc_data_accept_state(u8 state)
537{
538 return state != LLC_CONN_STATE_NORMAL && state != LLC_CONN_STATE_BUSY &&
539 state != LLC_CONN_STATE_REJ;
540}
541
542/**
543 * find_next_offset - finds offset for next category of transitions
544 * @state: state table.
545 * @offset: start offset.
546 *
547 * Finds offset of next category of transitions in transition table.
548 * Returns the start index of next category.
549 */
550static u16 find_next_offset(struct llc_conn_state *state, u16 offset)
551{
552 u16 cnt = 0;
553 struct llc_conn_state_trans **next_trans;
554
555 for (next_trans = state->transitions + offset;
556 (*next_trans)->ev; next_trans++)
557 ++cnt;
558 return cnt;
559}
560
561/**
562 * llc_build_offset_table - builds offset table of connection
563 *
564 * Fills offset table of connection state transition table
565 * (llc_offset_table).
566 */
567void __init llc_build_offset_table(void)
568{
569 struct llc_conn_state *curr_state;
570 int state, ev_type, next_offset;
571
572 for (state = 0; state < NBR_CONN_STATES; state++) {
573 curr_state = &llc_conn_state_table[state];
574 next_offset = 0;
575 for (ev_type = 0; ev_type < NBR_CONN_EV; ev_type++) {
576 llc_offset_table[state][ev_type] = next_offset;
577 next_offset += find_next_offset(curr_state,
578 next_offset) + 1;
579 }
580 }
581}
582
583/**
584 * llc_find_offset - finds start offset of category of transitions
585 * @state: state of connection
586 * @ev_type: type of happened event
587 *
588 * Finds start offset of desired category of transitions. Returns the
589 * desired start offset.
590 */
591static int llc_find_offset(int state, int ev_type)
592{
593 int rc = 0;
594 /* at this stage, llc_offset_table[..][2] is not important. it is for
595 * init_pf_cycle and I don't know what is it.
596 */
597 switch (ev_type) {
598 case LLC_CONN_EV_TYPE_PRIM:
599 rc = llc_offset_table[state][0]; break;
600 case LLC_CONN_EV_TYPE_PDU:
601 rc = llc_offset_table[state][4]; break;
602 case LLC_CONN_EV_TYPE_SIMPLE:
603 rc = llc_offset_table[state][1]; break;
604 case LLC_CONN_EV_TYPE_P_TMR:
605 case LLC_CONN_EV_TYPE_ACK_TMR:
606 case LLC_CONN_EV_TYPE_REJ_TMR:
607 case LLC_CONN_EV_TYPE_BUSY_TMR:
608 rc = llc_offset_table[state][3]; break;
609 }
610 return rc;
611}
612
613/**
614 * llc_sap_add_socket - adds a socket to a SAP
615 * @sap: SAP
616 * @sk: socket
617 *
618 * This function adds a socket to sk_list of a SAP.
619 */
620void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk)
621{
622 write_lock_bh(&sap->sk_list.lock);
623 llc_sk(sk)->sap = sap;
624 sk_add_node(sk, &sap->sk_list.list);
625 write_unlock_bh(&sap->sk_list.lock);
626}
627
628/**
629 * llc_sap_remove_socket - removes a socket from SAP
630 * @sap: SAP
631 * @sk: socket
632 *
633 * This function removes a connection from sk_list.list of a SAP if
634 * the connection was in this list.
635 */
636void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk)
637{
638 write_lock_bh(&sap->sk_list.lock);
639 sk_del_node_init(sk);
640 write_unlock_bh(&sap->sk_list.lock);
641}
642
643/**
644 * llc_conn_rcv - sends received pdus to the connection state machine
645 * @sk: current connection structure.
646 * @skb: received frame.
647 *
648 * Sends received pdus to the connection state machine.
649 */
650static int llc_conn_rcv(struct sock* sk, struct sk_buff *skb)
651{
652 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
653 struct llc_sock *llc = llc_sk(sk);
654
655 if (!llc->dev)
656 llc->dev = skb->dev;
657 ev->type = LLC_CONN_EV_TYPE_PDU;
658 ev->reason = 0;
659 return llc_conn_state_process(sk, skb);
660}
661
662void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
663{
664 struct llc_addr saddr, daddr;
665 struct sock *sk;
666
667 llc_pdu_decode_sa(skb, saddr.mac);
668 llc_pdu_decode_ssap(skb, &saddr.lsap);
669 llc_pdu_decode_da(skb, daddr.mac);
670 llc_pdu_decode_dsap(skb, &daddr.lsap);
671
672 sk = llc_lookup_established(sap, &saddr, &daddr);
673 if (!sk) {
674 /*
675 * Didn't find an active connection; verify if there
676 * is a listening socket for this llc addr
677 */
678 struct llc_sock *llc;
679 struct sock *parent = llc_lookup_listener(sap, &daddr);
680
681 if (!parent) {
682 dprintk("llc_lookup_listener failed!\n");
683 goto drop;
684 }
685
686 sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC, parent->sk_prot);
687 if (!sk) {
688 sock_put(parent);
689 goto drop;
690 }
691 llc = llc_sk(sk);
692 memcpy(&llc->laddr, &daddr, sizeof(llc->laddr));
693 memcpy(&llc->daddr, &saddr, sizeof(llc->daddr));
694 llc_sap_add_socket(sap, sk);
695 sock_hold(sk);
696 sock_put(parent);
697 skb->sk = parent;
698 } else
699 skb->sk = sk;
700 bh_lock_sock(sk);
701 if (!sock_owned_by_user(sk))
702 llc_conn_rcv(sk, skb);
703 else {
704 dprintk("%s: adding to backlog...\n", __FUNCTION__);
705 llc_set_backlog_type(skb, LLC_PACKET);
706 sk_add_backlog(sk, skb);
707 }
708 bh_unlock_sock(sk);
709 sock_put(sk);
710 return;
711drop:
712 kfree_skb(skb);
713}
714
715#undef LLC_REFCNT_DEBUG
716#ifdef LLC_REFCNT_DEBUG
717static atomic_t llc_sock_nr;
718#endif
719
720/**
721 * llc_release_sockets - releases all sockets in a sap
722 * @sap: sap to release its sockets
723 *
724 * Releases all connections of a sap. Returns 0 if all actions complete
725 * successfully, nonzero otherwise
726 */
727int llc_release_sockets(struct llc_sap *sap)
728{
729 int rc = 0;
730 struct sock *sk;
731 struct hlist_node *node;
732
733 write_lock_bh(&sap->sk_list.lock);
734
735 sk_for_each(sk, node, &sap->sk_list.list) {
736 llc_sk(sk)->state = LLC_CONN_STATE_TEMP;
737
738 if (llc_send_disc(sk))
739 rc = 1;
740 }
741
742 write_unlock_bh(&sap->sk_list.lock);
743 return rc;
744}
745
746/**
747 * llc_backlog_rcv - Processes rx frames and expired timers.
748 * @sk: LLC sock (p8022 connection)
749 * @skb: queued rx frame or event
750 *
751 * This function processes frames that has received and timers that has
752 * expired during sending an I pdu (refer to data_req_handler). frames
753 * queue by llc_rcv function (llc_mac.c) and timers queue by timer
754 * callback functions(llc_c_ac.c).
755 */
756static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
757{
758 int rc = 0;
759 struct llc_sock *llc = llc_sk(sk);
760
761 if (llc_backlog_type(skb) == LLC_PACKET) {
762 if (llc->state > 1) /* not closed */
763 rc = llc_conn_rcv(sk, skb);
764 else
765 goto out_kfree_skb;
766 } else if (llc_backlog_type(skb) == LLC_EVENT) {
767 /* timer expiration event */
768 if (llc->state > 1) /* not closed */
769 rc = llc_conn_state_process(sk, skb);
770 else
771 goto out_kfree_skb;
772 } else {
773 printk(KERN_ERR "%s: invalid skb in backlog\n", __FUNCTION__);
774 goto out_kfree_skb;
775 }
776out:
777 return rc;
778out_kfree_skb:
779 kfree_skb(skb);
780 goto out;
781}
782
783/**
784 * llc_sk_init - Initializes a socket with default llc values.
785 * @sk: socket to initialize.
786 *
787 * Initializes a socket with default llc values.
788 */
789static void llc_sk_init(struct sock* sk)
790{
791 struct llc_sock *llc = llc_sk(sk);
792
793 llc->state = LLC_CONN_STATE_ADM;
794 llc->inc_cntr = llc->dec_cntr = 2;
795 llc->dec_step = llc->connect_step = 1;
796
797 init_timer(&llc->ack_timer.timer);
798 llc->ack_timer.expire = LLC_ACK_TIME;
799 llc->ack_timer.timer.data = (unsigned long)sk;
800 llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
801
802 init_timer(&llc->pf_cycle_timer.timer);
803 llc->pf_cycle_timer.expire = LLC_P_TIME;
804 llc->pf_cycle_timer.timer.data = (unsigned long)sk;
805 llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb;
806
807 init_timer(&llc->rej_sent_timer.timer);
808 llc->rej_sent_timer.expire = LLC_REJ_TIME;
809 llc->rej_sent_timer.timer.data = (unsigned long)sk;
810 llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb;
811
812 init_timer(&llc->busy_state_timer.timer);
813 llc->busy_state_timer.expire = LLC_BUSY_TIME;
814 llc->busy_state_timer.timer.data = (unsigned long)sk;
815 llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb;
816
817 llc->n2 = 2; /* max retransmit */
818 llc->k = 2; /* tx win size, will adjust dynam */
819 llc->rw = 128; /* rx win size (opt and equal to
820 * tx_win of remote LLC) */
821 skb_queue_head_init(&llc->pdu_unack_q);
822 sk->sk_backlog_rcv = llc_backlog_rcv;
823}
824
825/**
826 * llc_sk_alloc - Allocates LLC sock
827 * @family: upper layer protocol family
828 * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
829 *
830 * Allocates a LLC sock and initializes it. Returns the new LLC sock
831 * or %NULL if there's no memory available for one
832 */
833struct sock *llc_sk_alloc(int family, int priority, struct proto *prot)
834{
835 struct sock *sk = sk_alloc(family, priority, prot, 1);
836
837 if (!sk)
838 goto out;
839 llc_sk_init(sk);
840 sock_init_data(NULL, sk);
841#ifdef LLC_REFCNT_DEBUG
842 atomic_inc(&llc_sock_nr);
843 printk(KERN_DEBUG "LLC socket %p created in %s, now we have %d alive\n", sk,
844 __FUNCTION__, atomic_read(&llc_sock_nr));
845#endif
846out:
847 return sk;
848}
849
850/**
851 * llc_sk_free - Frees a LLC socket
852 * @sk - socket to free
853 *
854 * Frees a LLC socket
855 */
856void llc_sk_free(struct sock *sk)
857{
858 struct llc_sock *llc = llc_sk(sk);
859
860 llc->state = LLC_CONN_OUT_OF_SVC;
861 /* Stop all (possibly) running timers */
862 llc_conn_ac_stop_all_timers(sk, NULL);
863#ifdef DEBUG_LLC_CONN_ALLOC
864 printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __FUNCTION__,
865 skb_queue_len(&llc->pdu_unack_q),
866 skb_queue_len(&sk->sk_write_queue));
867#endif
868 skb_queue_purge(&sk->sk_receive_queue);
869 skb_queue_purge(&sk->sk_write_queue);
870 skb_queue_purge(&llc->pdu_unack_q);
871#ifdef LLC_REFCNT_DEBUG
872 if (atomic_read(&sk->sk_refcnt) != 1) {
873 printk(KERN_DEBUG "Destruction of LLC sock %p delayed in %s, cnt=%d\n",
874 sk, __FUNCTION__, atomic_read(&sk->sk_refcnt));
875 printk(KERN_DEBUG "%d LLC sockets are still alive\n",
876 atomic_read(&llc_sock_nr));
877 } else {
878 atomic_dec(&llc_sock_nr);
879 printk(KERN_DEBUG "LLC socket %p released in %s, %d are still alive\n", sk,
880 __FUNCTION__, atomic_read(&llc_sock_nr));
881 }
882#endif
883 sock_put(sk);
884}
885
886/**
887 * llc_sk_reset - resets a connection
888 * @sk: LLC socket to reset
889 *
890 * Resets a connection to the out of service state. Stops its timers
891 * and frees any frames in the queues of the connection.
892 */
893void llc_sk_reset(struct sock *sk)
894{
895 struct llc_sock *llc = llc_sk(sk);
896
897 llc_conn_ac_stop_all_timers(sk, NULL);
898 skb_queue_purge(&sk->sk_write_queue);
899 skb_queue_purge(&llc->pdu_unack_q);
900 llc->remote_busy_flag = 0;
901 llc->cause_flag = 0;
902 llc->retry_count = 0;
903 llc_conn_set_p_flag(sk, 0);
904 llc->f_flag = 0;
905 llc->s_flag = 0;
906 llc->ack_pf = 0;
907 llc->first_pdu_Ns = 0;
908 llc->ack_must_be_send = 0;
909 llc->dec_step = 1;
910 llc->inc_cntr = 2;
911 llc->dec_cntr = 2;
912 llc->X = 0;
913 llc->failed_data_req = 0 ;
914 llc->last_nr = 0;
915}
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c
new file mode 100644
index 000000000000..5ff02c080a0b
--- /dev/null
+++ b/net/llc/llc_core.c
@@ -0,0 +1,179 @@
1/*
2 * llc_core.c - Minimum needed routines for sap handling and module init/exit
3 *
4 * Copyright (c) 1997 by Procom Technology, Inc.
5 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License as published by the Free Software Foundation.
9 * This program is distributed without any warranty or implied warranty
10 * of merchantability or fitness for a particular purpose.
11 *
12 * See the GNU General Public License for more details.
13 */
14
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/if_ether.h>
18#include <linux/netdevice.h>
19#include <linux/slab.h>
20#include <linux/string.h>
21#include <linux/init.h>
22#include <net/llc.h>
23
24LIST_HEAD(llc_sap_list);
25DEFINE_RWLOCK(llc_sap_list_lock);
26
27unsigned char llc_station_mac_sa[ETH_ALEN];
28
29/**
30 * llc_sap_alloc - allocates and initializes sap.
31 *
32 * Allocates and initializes sap.
33 */
34static struct llc_sap *llc_sap_alloc(void)
35{
36 struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC);
37
38 if (sap) {
39 memset(sap, 0, sizeof(*sap));
40 sap->state = LLC_SAP_STATE_ACTIVE;
41 memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
42 rwlock_init(&sap->sk_list.lock);
43 }
44 return sap;
45}
46
47/**
48 * llc_add_sap - add sap to station list
49 * @sap: Address of the sap
50 *
51 * Adds a sap to the LLC's station sap list.
52 */
53static void llc_add_sap(struct llc_sap *sap)
54{
55 write_lock_bh(&llc_sap_list_lock);
56 list_add_tail(&sap->node, &llc_sap_list);
57 write_unlock_bh(&llc_sap_list_lock);
58}
59
60/**
61 * llc_del_sap - del sap from station list
62 * @sap: Address of the sap
63 *
64 * Removes a sap to the LLC's station sap list.
65 */
66static void llc_del_sap(struct llc_sap *sap)
67{
68 write_lock_bh(&llc_sap_list_lock);
69 list_del(&sap->node);
70 write_unlock_bh(&llc_sap_list_lock);
71}
72
73/**
74 * llc_sap_find - searchs a SAP in station
75 * @sap_value: sap to be found
76 *
77 * Searchs for a sap in the sap list of the LLC's station upon the sap ID.
78 * Returns the sap or %NULL if not found.
79 */
80struct llc_sap *llc_sap_find(unsigned char sap_value)
81{
82 struct llc_sap* sap;
83
84 read_lock_bh(&llc_sap_list_lock);
85 list_for_each_entry(sap, &llc_sap_list, node)
86 if (sap->laddr.lsap == sap_value)
87 goto out;
88 sap = NULL;
89out:
90 read_unlock_bh(&llc_sap_list_lock);
91 return sap;
92}
93
94/**
95 * llc_sap_open - open interface to the upper layers.
96 * @lsap: SAP number.
97 * @func: rcv func for datalink protos
98 *
99 * Interface function to upper layer. Each one who wants to get a SAP
100 * (for example NetBEUI) should call this function. Returns the opened
101 * SAP for success, NULL for failure.
102 */
103struct llc_sap *llc_sap_open(unsigned char lsap,
104 int (*func)(struct sk_buff *skb,
105 struct net_device *dev,
106 struct packet_type *pt))
107{
108 struct llc_sap *sap = llc_sap_find(lsap);
109
110 if (sap) { /* SAP already exists */
111 sap = NULL;
112 goto out;
113 }
114 sap = llc_sap_alloc();
115 if (!sap)
116 goto out;
117 sap->laddr.lsap = lsap;
118 sap->rcv_func = func;
119 llc_add_sap(sap);
120out:
121 return sap;
122}
123
124/**
125 * llc_sap_close - close interface for upper layers.
126 * @sap: SAP to be closed.
127 *
128 * Close interface function to upper layer. Each one who wants to
129 * close an open SAP (for example NetBEUI) should call this function.
130 * Removes this sap from the list of saps in the station and then
131 * frees the memory for this sap.
132 */
133void llc_sap_close(struct llc_sap *sap)
134{
135 WARN_ON(!hlist_empty(&sap->sk_list.list));
136 llc_del_sap(sap);
137 kfree(sap);
138}
139
140static struct packet_type llc_packet_type = {
141 .type = __constant_htons(ETH_P_802_2),
142 .func = llc_rcv,
143};
144
145static struct packet_type llc_tr_packet_type = {
146 .type = __constant_htons(ETH_P_TR_802_2),
147 .func = llc_rcv,
148};
149
150static int __init llc_init(void)
151{
152 if (dev_base->next)
153 memcpy(llc_station_mac_sa, dev_base->next->dev_addr, ETH_ALEN);
154 else
155 memset(llc_station_mac_sa, 0, ETH_ALEN);
156 dev_add_pack(&llc_packet_type);
157 dev_add_pack(&llc_tr_packet_type);
158 return 0;
159}
160
161static void __exit llc_exit(void)
162{
163 dev_remove_pack(&llc_packet_type);
164 dev_remove_pack(&llc_tr_packet_type);
165}
166
167module_init(llc_init);
168module_exit(llc_exit);
169
170EXPORT_SYMBOL(llc_station_mac_sa);
171EXPORT_SYMBOL(llc_sap_list);
172EXPORT_SYMBOL(llc_sap_list_lock);
173EXPORT_SYMBOL(llc_sap_find);
174EXPORT_SYMBOL(llc_sap_open);
175EXPORT_SYMBOL(llc_sap_close);
176
177MODULE_LICENSE("GPL");
178MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
179MODULE_DESCRIPTION("LLC IEEE 802.2 core support");
diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c
new file mode 100644
index 000000000000..0f9fc48aeaf9
--- /dev/null
+++ b/net/llc/llc_if.c
@@ -0,0 +1,157 @@
1/*
2 * llc_if.c - Defines LLC interface to upper layer
3 *
4 * Copyright (c) 1997 by Procom Technology, Inc.
5 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License as published by the Free Software Foundation.
9 * This program is distributed without any warranty or implied warranty
10 * of merchantability or fitness for a particular purpose.
11 *
12 * See the GNU General Public License for more details.
13 */
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/netdevice.h>
18#include <linux/tcp.h>
19#include <asm/errno.h>
20#include <net/llc_if.h>
21#include <net/llc_sap.h>
22#include <net/llc_s_ev.h>
23#include <net/llc_conn.h>
24#include <net/sock.h>
25#include <net/llc_c_ev.h>
26#include <net/llc_c_ac.h>
27#include <net/llc_c_st.h>
28
29u8 llc_mac_null_var[IFHWADDRLEN];
30
31/**
32 * llc_build_and_send_pkt - Connection data sending for upper layers.
33 * @sk: connection
34 * @skb: packet to send
35 *
36 * This function is called when upper layer wants to send data using
37 * connection oriented communication mode. During sending data, connection
38 * will be locked and received frames and expired timers will be queued.
39 * Returns 0 for success, -ECONNABORTED when the connection already
40 * closed and -EBUSY when sending data is not permitted in this state or
41 * LLC has send an I pdu with p bit set to 1 and is waiting for it's
42 * response.
43 */
44int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
45{
46 struct llc_conn_state_ev *ev;
47 int rc = -ECONNABORTED;
48 struct llc_sock *llc = llc_sk(sk);
49
50 if (llc->state == LLC_CONN_STATE_ADM)
51 goto out;
52 rc = -EBUSY;
53 if (llc_data_accept_state(llc->state)) { /* data_conn_refuse */
54 llc->failed_data_req = 1;
55 goto out;
56 }
57 if (llc->p_flag) {
58 llc->failed_data_req = 1;
59 goto out;
60 }
61 ev = llc_conn_ev(skb);
62 ev->type = LLC_CONN_EV_TYPE_PRIM;
63 ev->prim = LLC_DATA_PRIM;
64 ev->prim_type = LLC_PRIM_TYPE_REQ;
65 skb->dev = llc->dev;
66 rc = llc_conn_state_process(sk, skb);
67out:
68 return rc;
69}
70
71/**
72 * llc_establish_connection - Called by upper layer to establish a conn
73 * @sk: connection
74 * @lmac: local mac address
75 * @dmac: destination mac address
76 * @dsap: destination sap
77 *
78 * Upper layer calls this to establish an LLC connection with a remote
79 * machine. This function packages a proper event and sends it connection
80 * component state machine. Success or failure of connection
81 * establishment will inform to upper layer via calling it's confirm
82 * function and passing proper information.
83 */
84int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
85{
86 int rc = -EISCONN;
87 struct llc_addr laddr, daddr;
88 struct sk_buff *skb;
89 struct llc_sock *llc = llc_sk(sk);
90 struct sock *existing;
91
92 laddr.lsap = llc->sap->laddr.lsap;
93 daddr.lsap = dsap;
94 memcpy(daddr.mac, dmac, sizeof(daddr.mac));
95 memcpy(laddr.mac, lmac, sizeof(laddr.mac));
96 existing = llc_lookup_established(llc->sap, &daddr, &laddr);
97 if (existing) {
98 if (existing->sk_state == TCP_ESTABLISHED) {
99 sk = existing;
100 goto out_put;
101 } else
102 sock_put(existing);
103 }
104 sock_hold(sk);
105 rc = -ENOMEM;
106 skb = alloc_skb(0, GFP_ATOMIC);
107 if (skb) {
108 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
109
110 ev->type = LLC_CONN_EV_TYPE_PRIM;
111 ev->prim = LLC_CONN_PRIM;
112 ev->prim_type = LLC_PRIM_TYPE_REQ;
113 rc = llc_conn_state_process(sk, skb);
114 }
115out_put:
116 sock_put(sk);
117 return rc;
118}
119
120/**
121 * llc_send_disc - Called by upper layer to close a connection
122 * @sk: connection to be closed
123 *
124 * Upper layer calls this when it wants to close an established LLC
125 * connection with a remote machine. This function packages a proper event
126 * and sends it to connection component state machine. Returns 0 for
127 * success, 1 otherwise.
128 */
129int llc_send_disc(struct sock *sk)
130{
131 u16 rc = 1;
132 struct llc_conn_state_ev *ev;
133 struct sk_buff *skb;
134
135 sock_hold(sk);
136 if (sk->sk_type != SOCK_STREAM || sk->sk_state != TCP_ESTABLISHED ||
137 llc_sk(sk)->state == LLC_CONN_STATE_ADM ||
138 llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC)
139 goto out;
140 /*
141 * Postpone unassigning the connection from its SAP and returning the
142 * connection until all ACTIONs have been completely executed
143 */
144 skb = alloc_skb(0, GFP_ATOMIC);
145 if (!skb)
146 goto out;
147 sk->sk_state = TCP_CLOSING;
148 ev = llc_conn_ev(skb);
149 ev->type = LLC_CONN_EV_TYPE_PRIM;
150 ev->prim = LLC_DISC_PRIM;
151 ev->prim_type = LLC_PRIM_TYPE_REQ;
152 rc = llc_conn_state_process(sk, skb);
153out:
154 sock_put(sk);
155 return rc;
156}
157
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c
new file mode 100644
index 000000000000..4da6976efc9c
--- /dev/null
+++ b/net/llc/llc_input.c
@@ -0,0 +1,189 @@
1/*
2 * llc_input.c - Minimal input path for LLC
3 *
4 * Copyright (c) 1997 by Procom Technology, Inc.
5 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License as published by the Free Software Foundation.
9 * This program is distributed without any warranty or implied warranty
10 * of merchantability or fitness for a particular purpose.
11 *
12 * See the GNU General Public License for more details.
13 */
14#include <linux/netdevice.h>
15#include <net/llc.h>
16#include <net/llc_pdu.h>
17#include <net/llc_sap.h>
18
19#if 0
20#define dprintk(args...) printk(KERN_DEBUG args)
21#else
22#define dprintk(args...)
23#endif
24
25/*
26 * Packet handler for the station, registerable because in the minimal
27 * LLC core that is taking shape only the very minimal subset of LLC that
28 * is needed for things like IPX, Appletalk, etc will stay, with all the
29 * rest in the llc1 and llc2 modules.
30 */
31static void (*llc_station_handler)(struct sk_buff *skb);
32
33/*
34 * Packet handlers for LLC_DEST_SAP and LLC_DEST_CONN.
35 */
36static void (*llc_type_handlers[2])(struct llc_sap *sap,
37 struct sk_buff *skb);
38
39void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
40 struct sk_buff *skb))
41{
42 if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
43 llc_type_handlers[type - 1] = handler;
44}
45
46void llc_remove_pack(int type)
47{
48 if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
49 llc_type_handlers[type - 1] = NULL;
50}
51
52void llc_set_station_handler(void (*handler)(struct sk_buff *skb))
53{
54 llc_station_handler = handler;
55}
56
57/**
58 * llc_pdu_type - returns which LLC component must handle for PDU
59 * @skb: input skb
60 *
61 * This function returns which LLC component must handle this PDU.
62 */
63static __inline__ int llc_pdu_type(struct sk_buff *skb)
64{
65 int type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
66 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
67
68 if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
69 goto out;
70 switch (LLC_U_PDU_CMD(pdu)) {
71 case LLC_1_PDU_CMD_XID:
72 case LLC_1_PDU_CMD_UI:
73 case LLC_1_PDU_CMD_TEST:
74 type = LLC_DEST_SAP;
75 break;
76 case LLC_2_PDU_CMD_SABME:
77 case LLC_2_PDU_CMD_DISC:
78 case LLC_2_PDU_RSP_UA:
79 case LLC_2_PDU_RSP_DM:
80 case LLC_2_PDU_RSP_FRMR:
81 break;
82 default:
83 type = LLC_DEST_INVALID;
84 break;
85 }
86out:
87 return type;
88}
89
90/**
91 * llc_fixup_skb - initializes skb pointers
92 * @skb: This argument points to incoming skb
93 *
94 * Initializes internal skb pointer to start of network layer by deriving
95 * length of LLC header; finds length of LLC control field in LLC header
96 * by looking at the two lowest-order bits of the first control field
97 * byte; field is either 3 or 4 bytes long.
98 */
99static inline int llc_fixup_skb(struct sk_buff *skb)
100{
101 u8 llc_len = 2;
102 struct llc_pdu_sn *pdu;
103
104 if (!pskb_may_pull(skb, sizeof(*pdu)))
105 return 0;
106
107 pdu = (struct llc_pdu_sn *)skb->data;
108 if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U)
109 llc_len = 1;
110 llc_len += 2;
111 skb->h.raw += llc_len;
112 skb_pull(skb, llc_len);
113 if (skb->protocol == htons(ETH_P_802_2)) {
114 u16 pdulen = eth_hdr(skb)->h_proto,
115 data_size = ntohs(pdulen) - llc_len;
116
117 skb_trim(skb, data_size);
118 }
119 return 1;
120}
121
122/**
123 * llc_rcv - 802.2 entry point from net lower layers
124 * @skb: received pdu
125 * @dev: device that receive pdu
126 * @pt: packet type
127 *
128 * When the system receives a 802.2 frame this function is called. It
129 * checks SAP and connection of received pdu and passes frame to
130 * llc_{station,sap,conn}_rcv for sending to proper state machine. If
131 * the frame is related to a busy connection (a connection is sending
132 * data now), it queues this frame in the connection's backlog.
133 */
134int llc_rcv(struct sk_buff *skb, struct net_device *dev,
135 struct packet_type *pt)
136{
137 struct llc_sap *sap;
138 struct llc_pdu_sn *pdu;
139 int dest;
140
141 /*
142 * When the interface is in promisc. mode, drop all the crap that it
143 * receives, do not try to analyse it.
144 */
145 if (unlikely(skb->pkt_type == PACKET_OTHERHOST)) {
146 dprintk("%s: PACKET_OTHERHOST\n", __FUNCTION__);
147 goto drop;
148 }
149 skb = skb_share_check(skb, GFP_ATOMIC);
150 if (unlikely(!skb))
151 goto out;
152 if (unlikely(!llc_fixup_skb(skb)))
153 goto drop;
154 pdu = llc_pdu_sn_hdr(skb);
155 if (unlikely(!pdu->dsap)) /* NULL DSAP, refer to station */
156 goto handle_station;
157 sap = llc_sap_find(pdu->dsap);
158 if (unlikely(!sap)) {/* unknown SAP */
159 dprintk("%s: llc_sap_find(%02X) failed!\n", __FUNCTION__,
160 pdu->dsap);
161 goto drop;
162 }
163 /*
164 * First the upper layer protocols that don't need the full
165 * LLC functionality
166 */
167 if (sap->rcv_func) {
168 sap->rcv_func(skb, dev, pt);
169 goto out;
170 }
171 dest = llc_pdu_type(skb);
172 if (unlikely(!dest || !llc_type_handlers[dest - 1]))
173 goto drop;
174 llc_type_handlers[dest - 1](sap, skb);
175out:
176 return 0;
177drop:
178 kfree_skb(skb);
179 goto out;
180handle_station:
181 if (!llc_station_handler)
182 goto drop;
183 llc_station_handler(skb);
184 goto out;
185}
186
187EXPORT_SYMBOL(llc_add_pack);
188EXPORT_SYMBOL(llc_remove_pack);
189EXPORT_SYMBOL(llc_set_station_handler);
diff --git a/net/llc/llc_output.c b/net/llc/llc_output.c
new file mode 100644
index 000000000000..ab5784cf163e
--- /dev/null
+++ b/net/llc/llc_output.c
@@ -0,0 +1,107 @@
1/*
2 * llc_output.c - LLC minimal output path
3 *
4 * Copyright (c) 1997 by Procom Technology, Inc.
5 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License version 2 as published by the Free Software
9 * Foundation.
10 * This program is distributed without any warranty or implied warranty
11 * of merchantability or fitness for a particular purpose.
12 *
13 * See the GNU General Public License version 2 for more details.
14 */
15
16#include <linux/if_arp.h>
17#include <linux/if_tr.h>
18#include <linux/netdevice.h>
19#include <linux/trdevice.h>
20#include <linux/skbuff.h>
21#include <net/llc.h>
22#include <net/llc_pdu.h>
23
24/**
25 * llc_mac_hdr_init - fills MAC header fields
26 * @skb: Address of the frame to initialize its MAC header
27 * @sa: The MAC source address
28 * @da: The MAC destination address
29 *
30 * Fills MAC header fields, depending on MAC type. Returns 0, If MAC type
31 * is a valid type and initialization completes correctly 1, otherwise.
32 */
33int llc_mac_hdr_init(struct sk_buff *skb, unsigned char *sa, unsigned char *da)
34{
35 int rc = 0;
36
37 switch (skb->dev->type) {
38#ifdef CONFIG_TR
39 case ARPHRD_IEEE802_TR: {
40 struct net_device *dev = skb->dev;
41 struct trh_hdr *trh;
42
43 skb->mac.raw = skb_push(skb, sizeof(*trh));
44 trh = tr_hdr(skb);
45 trh->ac = AC;
46 trh->fc = LLC_FRAME;
47 if (sa)
48 memcpy(trh->saddr, sa, dev->addr_len);
49 else
50 memset(trh->saddr, 0, dev->addr_len);
51 if (da) {
52 memcpy(trh->daddr, da, dev->addr_len);
53 tr_source_route(skb, trh, dev);
54 skb->mac.raw = skb->data;
55 }
56 break;
57 }
58#endif
59 case ARPHRD_ETHER:
60 case ARPHRD_LOOPBACK: {
61 unsigned short len = skb->len;
62 struct ethhdr *eth;
63
64 skb->mac.raw = skb_push(skb, sizeof(*eth));
65 eth = eth_hdr(skb);
66 eth->h_proto = htons(len);
67 memcpy(eth->h_dest, da, ETH_ALEN);
68 memcpy(eth->h_source, sa, ETH_ALEN);
69 break;
70 }
71 default:
72 printk(KERN_WARNING "device type not supported: %d\n",
73 skb->dev->type);
74 rc = -EINVAL;
75 }
76 return rc;
77}
78
79/**
80 * llc_build_and_send_ui_pkt - unitdata request interface for upper layers
81 * @sap: sap to use
82 * @skb: packet to send
83 * @dmac: destination mac address
84 * @dsap: destination sap
85 *
86 * Upper layers calls this function when upper layer wants to send data
87 * using connection-less mode communication (UI pdu).
88 *
89 * Accept data frame from network layer to be sent using connection-
90 * less mode communication; timeout/retries handled by network layer;
91 * package primitive as an event and send to SAP event handler
92 */
93int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
94 unsigned char *dmac, unsigned char dsap)
95{
96 int rc;
97 llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
98 dsap, LLC_PDU_CMD);
99 llc_pdu_init_as_ui_cmd(skb);
100 rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
101 if (!rc)
102 rc = dev_queue_xmit(skb);
103 return rc;
104}
105
106EXPORT_SYMBOL(llc_mac_hdr_init);
107EXPORT_SYMBOL(llc_build_and_send_ui_pkt);
diff --git a/net/llc/llc_output.h b/net/llc/llc_output.h
new file mode 100644
index 000000000000..179edf753f00
--- /dev/null
+++ b/net/llc/llc_output.h
@@ -0,0 +1,20 @@
1#ifndef LLC_OUTPUT_H
2#define LLC_OUTPUT_H
3/*
4 * Copyright (c) 1997 by Procom Technology, Inc.
5 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License version 2 as published by the Free Software
9 * Foundation.
10 * This program is distributed without any warranty or implied warranty
11 * of merchantability or fitness for a particular purpose.
12 *
13 * See the GNU General Public License version 2 for more details.
14 */
15
16struct sk_buff;
17
18int llc_mac_hdr_init(struct sk_buff *skb, unsigned char *sa, unsigned char *da);
19
20#endif /* LLC_OUTPUT_H */
diff --git a/net/llc/llc_pdu.c b/net/llc/llc_pdu.c
new file mode 100644
index 000000000000..a28ce525d201
--- /dev/null
+++ b/net/llc/llc_pdu.c
@@ -0,0 +1,372 @@
1/*
2 * llc_pdu.c - access to PDU internals
3 *
4 * Copyright (c) 1997 by Procom Technology, Inc.
5 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License as published by the Free Software Foundation.
9 * This program is distributed without any warranty or implied warranty
10 * of merchantability or fitness for a particular purpose.
11 *
12 * See the GNU General Public License for more details.
13 */
14
15#include <linux/netdevice.h>
16#include <net/llc_pdu.h>
17
18static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type);
19static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu);
20
21void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type)
22{
23 llc_pdu_un_hdr(skb)->ssap |= pdu_type;
24}
25
26/**
27 * pdu_set_pf_bit - sets poll/final bit in LLC header
28 * @pdu_frame: input frame that p/f bit must be set into it.
29 * @bit_value: poll/final bit (0 or 1).
30 *
31 * This function sets poll/final bit in LLC header (based on type of PDU).
32 * in I or S pdus, p/f bit is right bit of fourth byte in header. in U
33 * pdus p/f bit is fifth bit of third byte.
34 */
35void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value)
36{
37 u8 pdu_type;
38 struct llc_pdu_sn *pdu;
39
40 llc_pdu_decode_pdu_type(skb, &pdu_type);
41 pdu = llc_pdu_sn_hdr(skb);
42
43 switch (pdu_type) {
44 case LLC_PDU_TYPE_I:
45 case LLC_PDU_TYPE_S:
46 pdu->ctrl_2 = (pdu->ctrl_2 & 0xFE) | bit_value;
47 break;
48 case LLC_PDU_TYPE_U:
49 pdu->ctrl_1 |= (pdu->ctrl_1 & 0xEF) | (bit_value << 4);
50 break;
51 }
52}
53
54/**
55 * llc_pdu_decode_pf_bit - extracs poll/final bit from LLC header
56 * @skb: input skb that p/f bit must be extracted from it
57 * @pf_bit: poll/final bit (0 or 1)
58 *
59 * This function extracts poll/final bit from LLC header (based on type of
60 * PDU). In I or S pdus, p/f bit is right bit of fourth byte in header. In
61 * U pdus p/f bit is fifth bit of third byte.
62 */
63void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit)
64{
65 u8 pdu_type;
66 struct llc_pdu_sn *pdu;
67
68 llc_pdu_decode_pdu_type(skb, &pdu_type);
69 pdu = llc_pdu_sn_hdr(skb);
70
71 switch (pdu_type) {
72 case LLC_PDU_TYPE_I:
73 case LLC_PDU_TYPE_S:
74 *pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK;
75 break;
76 case LLC_PDU_TYPE_U:
77 *pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4;
78 break;
79 }
80}
81
82/**
83 * llc_pdu_init_as_disc_cmd - Builds DISC PDU
84 * @skb: Address of the skb to build
85 * @p_bit: The P bit to set in the PDU
86 *
87 * Builds a pdu frame as a DISC command.
88 */
89void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit)
90{
91 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
92
93 pdu->ctrl_1 = LLC_PDU_TYPE_U;
94 pdu->ctrl_1 |= LLC_2_PDU_CMD_DISC;
95 pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
96}
97
98/**
99 * llc_pdu_init_as_i_cmd - builds I pdu
100 * @skb: Address of the skb to build
101 * @p_bit: The P bit to set in the PDU
102 * @ns: The sequence number of the data PDU
103 * @nr: The seq. number of the expected I PDU from the remote
104 *
105 * Builds a pdu frame as an I command.
106 */
107void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr)
108{
109 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
110
111 pdu->ctrl_1 = LLC_PDU_TYPE_I;
112 pdu->ctrl_2 = 0;
113 pdu->ctrl_2 |= (p_bit & LLC_I_PF_BIT_MASK); /* p/f bit */
114 pdu->ctrl_1 |= (ns << 1) & 0xFE; /* set N(S) in bits 2..8 */
115 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
116}
117
118/**
119 * llc_pdu_init_as_rej_cmd - builds REJ PDU
120 * @skb: Address of the skb to build
121 * @p_bit: The P bit to set in the PDU
122 * @nr: The seq. number of the expected I PDU from the remote
123 *
124 * Builds a pdu frame as a REJ command.
125 */
126void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
127{
128 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
129
130 pdu->ctrl_1 = LLC_PDU_TYPE_S;
131 pdu->ctrl_1 |= LLC_2_PDU_CMD_REJ;
132 pdu->ctrl_2 = 0;
133 pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK;
134 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
135 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
136}
137
138/**
139 * llc_pdu_init_as_rnr_cmd - builds RNR pdu
140 * @skb: Address of the skb to build
141 * @p_bit: The P bit to set in the PDU
142 * @nr: The seq. number of the expected I PDU from the remote
143 *
144 * Builds a pdu frame as an RNR command.
145 */
146void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
147{
148 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
149
150 pdu->ctrl_1 = LLC_PDU_TYPE_S;
151 pdu->ctrl_1 |= LLC_2_PDU_CMD_RNR;
152 pdu->ctrl_2 = 0;
153 pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK;
154 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
155 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
156}
157
158/**
159 * llc_pdu_init_as_rr_cmd - Builds RR pdu
160 * @skb: Address of the skb to build
161 * @p_bit: The P bit to set in the PDU
162 * @nr: The seq. number of the expected I PDU from the remote
163 *
164 * Builds a pdu frame as an RR command.
165 */
166void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
167{
168 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
169
170 pdu->ctrl_1 = LLC_PDU_TYPE_S;
171 pdu->ctrl_1 |= LLC_2_PDU_CMD_RR;
172 pdu->ctrl_2 = p_bit & LLC_S_PF_BIT_MASK;
173 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
174 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
175}
176
177/**
178 * llc_pdu_init_as_sabme_cmd - builds SABME pdu
179 * @skb: Address of the skb to build
180 * @p_bit: The P bit to set in the PDU
181 *
182 * Builds a pdu frame as an SABME command.
183 */
184void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit)
185{
186 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
187
188 pdu->ctrl_1 = LLC_PDU_TYPE_U;
189 pdu->ctrl_1 |= LLC_2_PDU_CMD_SABME;
190 pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
191}
192
193/**
194 * llc_pdu_init_as_dm_rsp - builds DM response pdu
195 * @skb: Address of the skb to build
196 * @f_bit: The F bit to set in the PDU
197 *
198 * Builds a pdu frame as a DM response.
199 */
200void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit)
201{
202 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
203
204 pdu->ctrl_1 = LLC_PDU_TYPE_U;
205 pdu->ctrl_1 |= LLC_2_PDU_RSP_DM;
206 pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
207}
208
209/**
210 * llc_pdu_init_as_frmr_rsp - builds FRMR response PDU
211 * @skb: Address of the frame to build
212 * @prev_pdu: The rejected PDU frame
213 * @f_bit: The F bit to set in the PDU
214 * @vs: tx state vari value for the data link conn at the rejecting LLC
215 * @vr: rx state var value for the data link conn at the rejecting LLC
216 * @vzyxw: completely described in the IEEE Std 802.2 document (Pg 55)
217 *
218 * Builds a pdu frame as a FRMR response.
219 */
220void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
221 u8 f_bit, u8 vs, u8 vr, u8 vzyxw)
222{
223 struct llc_frmr_info *frmr_info;
224 u8 prev_pf = 0;
225 u8 *ctrl;
226 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
227
228 pdu->ctrl_1 = LLC_PDU_TYPE_U;
229 pdu->ctrl_1 |= LLC_2_PDU_RSP_FRMR;
230 pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
231
232 frmr_info = (struct llc_frmr_info *)&pdu->ctrl_2;
233 ctrl = (u8 *)&prev_pdu->ctrl_1;
234 FRMR_INFO_SET_REJ_CNTRL(frmr_info,ctrl);
235 FRMR_INFO_SET_Vs(frmr_info, vs);
236 FRMR_INFO_SET_Vr(frmr_info, vr);
237 prev_pf = llc_pdu_get_pf_bit(prev_pdu);
238 FRMR_INFO_SET_C_R_BIT(frmr_info, prev_pf);
239 FRMR_INFO_SET_INVALID_PDU_CTRL_IND(frmr_info, vzyxw);
240 FRMR_INFO_SET_INVALID_PDU_INFO_IND(frmr_info, vzyxw);
241 FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw);
242 FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw);
243 FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw);
244 skb_put(skb, 5);
245}
246
247/**
248 * llc_pdu_init_as_rr_rsp - builds RR response pdu
249 * @skb: Address of the skb to build
250 * @f_bit: The F bit to set in the PDU
251 * @nr: The seq. number of the expected data PDU from the remote
252 *
253 * Builds a pdu frame as an RR response.
254 */
255void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
256{
257 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
258
259 pdu->ctrl_1 = LLC_PDU_TYPE_S;
260 pdu->ctrl_1 |= LLC_2_PDU_RSP_RR;
261 pdu->ctrl_2 = 0;
262 pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK;
263 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
264 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
265}
266
267/**
268 * llc_pdu_init_as_rej_rsp - builds REJ response pdu
269 * @skb: Address of the skb to build
270 * @f_bit: The F bit to set in the PDU
271 * @nr: The seq. number of the expected data PDU from the remote
272 *
273 * Builds a pdu frame as a REJ response.
274 */
275void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
276{
277 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
278
279 pdu->ctrl_1 = LLC_PDU_TYPE_S;
280 pdu->ctrl_1 |= LLC_2_PDU_RSP_REJ;
281 pdu->ctrl_2 = 0;
282 pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK;
283 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
284 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
285}
286
287/**
288 * llc_pdu_init_as_rnr_rsp - builds RNR response pdu
289 * @skb: Address of the frame to build
290 * @f_bit: The F bit to set in the PDU
291 * @nr: The seq. number of the expected data PDU from the remote
292 *
293 * Builds a pdu frame as an RNR response.
294 */
295void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
296{
297 struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
298
299 pdu->ctrl_1 = LLC_PDU_TYPE_S;
300 pdu->ctrl_1 |= LLC_2_PDU_RSP_RNR;
301 pdu->ctrl_2 = 0;
302 pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK;
303 pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
304 pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
305}
306
307/**
308 * llc_pdu_init_as_ua_rsp - builds UA response pdu
309 * @skb: Address of the frame to build
310 * @f_bit: The F bit to set in the PDU
311 *
312 * Builds a pdu frame as a UA response.
313 */
314void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit)
315{
316 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
317
318 pdu->ctrl_1 = LLC_PDU_TYPE_U;
319 pdu->ctrl_1 |= LLC_2_PDU_RSP_UA;
320 pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
321}
322
323/**
324 * llc_pdu_decode_pdu_type - designates PDU type
325 * @skb: input skb that type of it must be designated.
326 * @type: type of PDU (output argument).
327 *
328 * This function designates type of PDU (I, S or U).
329 */
330static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type)
331{
332 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
333
334 if (pdu->ctrl_1 & 1) {
335 if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U)
336 *type = LLC_PDU_TYPE_U;
337 else
338 *type = LLC_PDU_TYPE_S;
339 } else
340 *type = LLC_PDU_TYPE_I;
341}
342
343/**
344 * llc_pdu_get_pf_bit - extracts p/f bit of input PDU
345 * @pdu: pointer to LLC header.
346 *
347 * This function extracts p/f bit of input PDU. at first examines type of
348 * PDU and then extracts p/f bit. Returns the p/f bit.
349 */
350static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu)
351{
352 u8 pdu_type;
353 u8 pf_bit = 0;
354
355 if (pdu->ctrl_1 & 1) {
356 if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U)
357 pdu_type = LLC_PDU_TYPE_U;
358 else
359 pdu_type = LLC_PDU_TYPE_S;
360 } else
361 pdu_type = LLC_PDU_TYPE_I;
362 switch (pdu_type) {
363 case LLC_PDU_TYPE_I:
364 case LLC_PDU_TYPE_S:
365 pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK;
366 break;
367 case LLC_PDU_TYPE_U:
368 pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4;
369 break;
370 }
371 return pf_bit;
372}
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c
new file mode 100644
index 000000000000..36e8db3fa1a2
--- /dev/null
+++ b/net/llc/llc_proc.c
@@ -0,0 +1,267 @@
1/*
2 * proc_llc.c - proc interface for LLC
3 *
4 * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
5 * 2002-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License as published by the Free Software Foundation.
9 * This program is distributed without any warranty or implied warranty
10 * of merchantability or fitness for a particular purpose.
11 *
12 * See the GNU General Public License for more details.
13 */
14
15#include <linux/config.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/proc_fs.h>
19#include <linux/errno.h>
20#include <linux/seq_file.h>
21#include <net/sock.h>
22#include <net/llc.h>
23#include <net/llc_c_ac.h>
24#include <net/llc_c_ev.h>
25#include <net/llc_c_st.h>
26#include <net/llc_conn.h>
27
28static void llc_ui_format_mac(struct seq_file *seq, unsigned char *mac)
29{
30 seq_printf(seq, "%02X:%02X:%02X:%02X:%02X:%02X",
31 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
32}
33
34static struct sock *llc_get_sk_idx(loff_t pos)
35{
36 struct list_head *sap_entry;
37 struct llc_sap *sap;
38 struct hlist_node *node;
39 struct sock *sk = NULL;
40
41 list_for_each(sap_entry, &llc_sap_list) {
42 sap = list_entry(sap_entry, struct llc_sap, node);
43
44 read_lock_bh(&sap->sk_list.lock);
45 sk_for_each(sk, node, &sap->sk_list.list) {
46 if (!pos)
47 goto found;
48 --pos;
49 }
50 read_unlock_bh(&sap->sk_list.lock);
51 }
52 sk = NULL;
53found:
54 return sk;
55}
56
57static void *llc_seq_start(struct seq_file *seq, loff_t *pos)
58{
59 loff_t l = *pos;
60
61 read_lock_bh(&llc_sap_list_lock);
62 return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN;
63}
64
65static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
66{
67 struct sock* sk, *next;
68 struct llc_sock *llc;
69 struct llc_sap *sap;
70
71 ++*pos;
72 if (v == SEQ_START_TOKEN) {
73 sk = llc_get_sk_idx(0);
74 goto out;
75 }
76 sk = v;
77 next = sk_next(sk);
78 if (next) {
79 sk = next;
80 goto out;
81 }
82 llc = llc_sk(sk);
83 sap = llc->sap;
84 read_unlock_bh(&sap->sk_list.lock);
85 sk = NULL;
86 for (;;) {
87 if (sap->node.next == &llc_sap_list)
88 break;
89 sap = list_entry(sap->node.next, struct llc_sap, node);
90 read_lock_bh(&sap->sk_list.lock);
91 if (!hlist_empty(&sap->sk_list.list)) {
92 sk = sk_head(&sap->sk_list.list);
93 break;
94 }
95 read_unlock_bh(&sap->sk_list.lock);
96 }
97out:
98 return sk;
99}
100
101static void llc_seq_stop(struct seq_file *seq, void *v)
102{
103 if (v && v != SEQ_START_TOKEN) {
104 struct sock *sk = v;
105 struct llc_sock *llc = llc_sk(sk);
106 struct llc_sap *sap = llc->sap;
107
108 read_unlock_bh(&sap->sk_list.lock);
109 }
110 read_unlock_bh(&llc_sap_list_lock);
111}
112
113static int llc_seq_socket_show(struct seq_file *seq, void *v)
114{
115 struct sock* sk;
116 struct llc_sock *llc;
117
118 if (v == SEQ_START_TOKEN) {
119 seq_puts(seq, "SKt Mc local_mac_sap remote_mac_sap "
120 " tx_queue rx_queue st uid link\n");
121 goto out;
122 }
123 sk = v;
124 llc = llc_sk(sk);
125
126 /* FIXME: check if the address is multicast */
127 seq_printf(seq, "%2X %2X ", sk->sk_type, 0);
128
129 if (llc->dev)
130 llc_ui_format_mac(seq, llc->dev->dev_addr);
131 else
132 seq_printf(seq, "00:00:00:00:00:00");
133 seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
134 llc_ui_format_mac(seq, llc->daddr.mac);
135 seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap,
136 atomic_read(&sk->sk_wmem_alloc),
137 atomic_read(&sk->sk_rmem_alloc),
138 sk->sk_state,
139 sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1,
140 llc->link);
141out:
142 return 0;
143}
144
145static char *llc_conn_state_names[] = {
146 [LLC_CONN_STATE_ADM] = "adm",
147 [LLC_CONN_STATE_SETUP] = "setup",
148 [LLC_CONN_STATE_NORMAL] = "normal",
149 [LLC_CONN_STATE_BUSY] = "busy",
150 [LLC_CONN_STATE_REJ] = "rej",
151 [LLC_CONN_STATE_AWAIT] = "await",
152 [LLC_CONN_STATE_AWAIT_BUSY] = "await_busy",
153 [LLC_CONN_STATE_AWAIT_REJ] = "await_rej",
154 [LLC_CONN_STATE_D_CONN] = "d_conn",
155 [LLC_CONN_STATE_RESET] = "reset",
156 [LLC_CONN_STATE_ERROR] = "error",
157 [LLC_CONN_STATE_TEMP] = "temp",
158};
159
160static int llc_seq_core_show(struct seq_file *seq, void *v)
161{
162 struct sock* sk;
163 struct llc_sock *llc;
164
165 if (v == SEQ_START_TOKEN) {
166 seq_puts(seq, "Connection list:\n"
167 "dsap state retr txw rxw pf ff sf df rs cs "
168 "tack tpfc trs tbs blog busr\n");
169 goto out;
170 }
171 sk = v;
172 llc = llc_sk(sk);
173
174 seq_printf(seq, " %02X %-10s %3d %3d %3d %2d %2d %2d %2d %2d %2d "
175 "%4d %4d %3d %3d %4d %4d\n",
176 llc->daddr.lsap, llc_conn_state_names[llc->state],
177 llc->retry_count, llc->k, llc->rw, llc->p_flag, llc->f_flag,
178 llc->s_flag, llc->data_flag, llc->remote_busy_flag,
179 llc->cause_flag, timer_pending(&llc->ack_timer.timer),
180 timer_pending(&llc->pf_cycle_timer.timer),
181 timer_pending(&llc->rej_sent_timer.timer),
182 timer_pending(&llc->busy_state_timer.timer),
183 !!sk->sk_backlog.tail, !!sock_owned_by_user(sk));
184out:
185 return 0;
186}
187
188static struct seq_operations llc_seq_socket_ops = {
189 .start = llc_seq_start,
190 .next = llc_seq_next,
191 .stop = llc_seq_stop,
192 .show = llc_seq_socket_show,
193};
194
195static struct seq_operations llc_seq_core_ops = {
196 .start = llc_seq_start,
197 .next = llc_seq_next,
198 .stop = llc_seq_stop,
199 .show = llc_seq_core_show,
200};
201
202static int llc_seq_socket_open(struct inode *inode, struct file *file)
203{
204 return seq_open(file, &llc_seq_socket_ops);
205}
206
207static int llc_seq_core_open(struct inode *inode, struct file *file)
208{
209 return seq_open(file, &llc_seq_core_ops);
210}
211
212static struct file_operations llc_seq_socket_fops = {
213 .owner = THIS_MODULE,
214 .open = llc_seq_socket_open,
215 .read = seq_read,
216 .llseek = seq_lseek,
217 .release = seq_release,
218};
219
220static struct file_operations llc_seq_core_fops = {
221 .owner = THIS_MODULE,
222 .open = llc_seq_core_open,
223 .read = seq_read,
224 .llseek = seq_lseek,
225 .release = seq_release,
226};
227
228static struct proc_dir_entry *llc_proc_dir;
229
230int __init llc_proc_init(void)
231{
232 int rc = -ENOMEM;
233 struct proc_dir_entry *p;
234
235 llc_proc_dir = proc_mkdir("llc", proc_net);
236 if (!llc_proc_dir)
237 goto out;
238 llc_proc_dir->owner = THIS_MODULE;
239
240 p = create_proc_entry("socket", S_IRUGO, llc_proc_dir);
241 if (!p)
242 goto out_socket;
243
244 p->proc_fops = &llc_seq_socket_fops;
245
246 p = create_proc_entry("core", S_IRUGO, llc_proc_dir);
247 if (!p)
248 goto out_core;
249
250 p->proc_fops = &llc_seq_core_fops;
251
252 rc = 0;
253out:
254 return rc;
255out_core:
256 remove_proc_entry("socket", llc_proc_dir);
257out_socket:
258 remove_proc_entry("llc", proc_net);
259 goto out;
260}
261
262void llc_proc_exit(void)
263{
264 remove_proc_entry("socket", llc_proc_dir);
265 remove_proc_entry("core", llc_proc_dir);
266 remove_proc_entry("llc", proc_net);
267}
diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
new file mode 100644
index 000000000000..ed8ba7de6122
--- /dev/null
+++ b/net/llc/llc_s_ac.c
@@ -0,0 +1,205 @@
1/*
2 * llc_s_ac.c - actions performed during sap state transition.
3 *
4 * Description :
5 * Functions in this module are implementation of sap component actions.
6 * Details of actions can be found in IEEE-802.2 standard document.
7 * All functions have one sap and one event as input argument. All of
8 * them return 0 On success and 1 otherwise.
9 *
10 * Copyright (c) 1997 by Procom Technology, Inc.
11 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
12 *
13 * This program can be redistributed or modified under the terms of the
14 * GNU General Public License as published by the Free Software Foundation.
15 * This program is distributed without any warranty or implied warranty
16 * of merchantability or fitness for a particular purpose.
17 *
18 * See the GNU General Public License for more details.
19 */
20
21#include <linux/netdevice.h>
22#include <net/llc.h>
23#include <net/llc_pdu.h>
24#include <net/llc_s_ac.h>
25#include <net/llc_s_ev.h>
26#include <net/llc_sap.h>
27#include "llc_output.h"
28
29/**
30 * llc_sap_action_unit_data_ind - forward UI PDU to network layer
31 * @sap: SAP
32 * @skb: the event to forward
33 *
34 * Received a UI PDU from MAC layer; forward to network layer as a
35 * UNITDATA INDICATION; verify our event is the kind we expect
36 */
37int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb)
38{
39 llc_sap_rtn_pdu(sap, skb);
40 return 0;
41}
42
43/**
44 * llc_sap_action_send_ui - sends UI PDU resp to UNITDATA REQ to MAC layer
45 * @sap: SAP
46 * @skb: the event to send
47 *
48 * Sends a UI PDU to the MAC layer in response to a UNITDATA REQUEST
49 * primitive from the network layer. Verifies event is a primitive type of
50 * event. Verify the primitive is a UNITDATA REQUEST.
51 */
52int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
53{
54 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
55 int rc;
56
57 llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
58 ev->daddr.lsap, LLC_PDU_CMD);
59 llc_pdu_init_as_ui_cmd(skb);
60 rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
61 if (!rc)
62 rc = dev_queue_xmit(skb);
63 return rc;
64}
65
66/**
67 * llc_sap_action_send_xid_c - send XID PDU as response to XID REQ
68 * @sap: SAP
69 * @skb: the event to send
70 *
71 * Send a XID command PDU to MAC layer in response to a XID REQUEST
72 * primitive from the network layer. Verify event is a primitive type
73 * event. Verify the primitive is a XID REQUEST.
74 */
75int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
76{
77 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
78 int rc;
79
80 llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
81 ev->daddr.lsap, LLC_PDU_CMD);
82 llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
83 rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
84 if (!rc)
85 rc = dev_queue_xmit(skb);
86 return rc;
87}
88
89/**
90 * llc_sap_action_send_xid_r - send XID PDU resp to MAC for received XID
91 * @sap: SAP
92 * @skb: the event to send
93 *
94 * Send XID response PDU to MAC in response to an earlier received XID
95 * command PDU. Verify event is a PDU type event
96 */
97int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
98{
99 u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
100 int rc = 1;
101 struct sk_buff *nskb;
102
103 llc_pdu_decode_sa(skb, mac_da);
104 llc_pdu_decode_da(skb, mac_sa);
105 llc_pdu_decode_ssap(skb, &dsap);
106 nskb = llc_alloc_frame();
107 if (!nskb)
108 goto out;
109 nskb->dev = skb->dev;
110 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
111 LLC_PDU_RSP);
112 llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);
113 rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
114 if (!rc)
115 rc = dev_queue_xmit(nskb);
116out:
117 return rc;
118}
119
120/**
121 * llc_sap_action_send_test_c - send TEST PDU to MAC in resp to TEST REQ
122 * @sap: SAP
123 * @skb: the event to send
124 *
125 * Send a TEST command PDU to the MAC layer in response to a TEST REQUEST
126 * primitive from the network layer. Verify event is a primitive type
127 * event; verify the primitive is a TEST REQUEST.
128 */
129int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)
130{
131 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
132 int rc;
133
134 llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
135 ev->daddr.lsap, LLC_PDU_CMD);
136 llc_pdu_init_as_test_cmd(skb);
137 rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
138 if (!rc)
139 rc = dev_queue_xmit(skb);
140 return rc;
141}
142
143int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
144{
145 u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
146 struct sk_buff *nskb;
147 int rc = 1;
148
149 llc_pdu_decode_sa(skb, mac_da);
150 llc_pdu_decode_da(skb, mac_sa);
151 llc_pdu_decode_ssap(skb, &dsap);
152 nskb = llc_alloc_frame();
153 if (!nskb)
154 goto out;
155 nskb->dev = skb->dev;
156 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
157 LLC_PDU_RSP);
158 llc_pdu_init_as_test_rsp(nskb, skb);
159 rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
160 if (!rc)
161 rc = dev_queue_xmit(nskb);
162out:
163 return rc;
164}
165
166/**
167 * llc_sap_action_report_status - report data link status to layer mgmt
168 * @sap: SAP
169 * @skb: the event to send
170 *
171 * Report data link status to layer management. Verify our event is the
172 * kind we expect.
173 */
174int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb)
175{
176 return 0;
177}
178
179/**
180 * llc_sap_action_xid_ind - send XID PDU resp to net layer via XID IND
181 * @sap: SAP
182 * @skb: the event to send
183 *
184 * Send a XID response PDU to the network layer via a XID INDICATION
185 * primitive.
186 */
187int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb)
188{
189 llc_sap_rtn_pdu(sap, skb);
190 return 0;
191}
192
193/**
194 * llc_sap_action_test_ind - send TEST PDU to net layer via TEST IND
195 * @sap: SAP
196 * @skb: the event to send
197 *
198 * Send a TEST response PDU to the network layer via a TEST INDICATION
199 * primitive. Verify our event is a PDU type event.
200 */
201int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb)
202{
203 llc_sap_rtn_pdu(sap, skb);
204 return 0;
205}
diff --git a/net/llc/llc_s_ev.c b/net/llc/llc_s_ev.c
new file mode 100644
index 000000000000..a74d2a1d6581
--- /dev/null
+++ b/net/llc/llc_s_ev.c
@@ -0,0 +1,115 @@
1/*
2 * llc_s_ev.c - Defines SAP component events
3 *
4 * The followed event functions are SAP component events which are described
5 * in 802.2 LLC protocol standard document.
6 *
7 * Copyright (c) 1997 by Procom Technology, Inc.
8 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9 *
10 * This program can be redistributed or modified under the terms of the
11 * GNU General Public License as published by the Free Software Foundation.
12 * This program is distributed without any warranty or implied warranty
13 * of merchantability or fitness for a particular purpose.
14 *
15 * See the GNU General Public License for more details.
16 */
17#include <linux/socket.h>
18#include <net/sock.h>
19#include <net/llc_if.h>
20#include <net/llc_s_ev.h>
21#include <net/llc_pdu.h>
22
23int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb)
24{
25 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
26
27 return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
28 ev->prim_type == LLC_SAP_EV_ACTIVATION_REQ ? 0 : 1;
29}
30
31int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb)
32{
33 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
34 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
35
36 return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_CMD(pdu) &&
37 LLC_PDU_TYPE_IS_U(pdu) &&
38 LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_UI ? 0 : 1;
39}
40
41int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb)
42{
43 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
44
45 return ev->type == LLC_SAP_EV_TYPE_PRIM &&
46 ev->prim == LLC_DATAUNIT_PRIM &&
47 ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
48
49}
50
51int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb)
52{
53 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
54
55 return ev->type == LLC_SAP_EV_TYPE_PRIM &&
56 ev->prim == LLC_XID_PRIM &&
57 ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
58}
59
60int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb)
61{
62 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
63 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
64
65 return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_CMD(pdu) &&
66 LLC_PDU_TYPE_IS_U(pdu) &&
67 LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1;
68}
69
70int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb)
71{
72 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
73 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
74
75 return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_RSP(pdu) &&
76 LLC_PDU_TYPE_IS_U(pdu) &&
77 LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1;
78}
79
80int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb)
81{
82 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
83
84 return ev->type == LLC_SAP_EV_TYPE_PRIM &&
85 ev->prim == LLC_TEST_PRIM &&
86 ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
87}
88
89int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb)
90{
91 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
92 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
93
94 return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_CMD(pdu) &&
95 LLC_PDU_TYPE_IS_U(pdu) &&
96 LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1;
97}
98
99int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb)
100{
101 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
102 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
103
104 return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_RSP(pdu) &&
105 LLC_PDU_TYPE_IS_U(pdu) &&
106 LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1;
107}
108
109int llc_sap_ev_deactivation_req(struct llc_sap *sap, struct sk_buff *skb)
110{
111 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
112
113 return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
114 ev->prim_type == LLC_SAP_EV_DEACTIVATION_REQ ? 0 : 1;
115}
diff --git a/net/llc/llc_s_st.c b/net/llc/llc_s_st.c
new file mode 100644
index 000000000000..6a43201aa32e
--- /dev/null
+++ b/net/llc/llc_s_st.c
@@ -0,0 +1,183 @@
1/*
2 * llc_s_st.c - Defines SAP component state machine transitions.
3 *
4 * The followed transitions are SAP component state machine transitions
5 * which are described in 802.2 LLC protocol standard document.
6 *
7 * Copyright (c) 1997 by Procom Technology, Inc.
8 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9 *
10 * This program can be redistributed or modified under the terms of the
11 * GNU General Public License as published by the Free Software Foundation.
12 * This program is distributed without any warranty or implied warranty
13 * of merchantability or fitness for a particular purpose.
14 *
15 * See the GNU General Public License for more details.
16 */
17#include <linux/types.h>
18#include <net/llc_if.h>
19#include <net/llc_s_ev.h>
20#include <net/llc_s_ac.h>
21#include <net/llc_s_st.h>
22
23/* dummy last-transition indicator; common to all state transition groups
24 * last entry for this state
25 * all members are zeros, .bss zeroes it
26 */
27static struct llc_sap_state_trans llc_sap_state_trans_end;
28
29/* state LLC_SAP_STATE_INACTIVE transition for
30 * LLC_SAP_EV_ACTIVATION_REQ event
31 */
32static llc_sap_action_t llc_sap_inactive_state_actions_1[] = {
33 [0] = llc_sap_action_report_status,
34 [1] = NULL,
35};
36
37static struct llc_sap_state_trans llc_sap_inactive_state_trans_1 = {
38 .ev = llc_sap_ev_activation_req,
39 .next_state = LLC_SAP_STATE_ACTIVE,
40 .ev_actions = llc_sap_inactive_state_actions_1,
41};
42
43/* array of pointers; one to each transition */
44static struct llc_sap_state_trans *llc_sap_inactive_state_transitions[] = {
45 [0] = &llc_sap_inactive_state_trans_1,
46 [1] = &llc_sap_state_trans_end,
47};
48
49/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_UI event */
50static llc_sap_action_t llc_sap_active_state_actions_1[] = {
51 [0] = llc_sap_action_unitdata_ind,
52 [1] = NULL,
53};
54
55static struct llc_sap_state_trans llc_sap_active_state_trans_1 = {
56 .ev = llc_sap_ev_rx_ui,
57 .next_state = LLC_SAP_STATE_ACTIVE,
58 .ev_actions = llc_sap_active_state_actions_1,
59};
60
61/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_UNITDATA_REQ event */
62static llc_sap_action_t llc_sap_active_state_actions_2[] = {
63 [0] = llc_sap_action_send_ui,
64 [1] = NULL,
65};
66
67static struct llc_sap_state_trans llc_sap_active_state_trans_2 = {
68 .ev = llc_sap_ev_unitdata_req,
69 .next_state = LLC_SAP_STATE_ACTIVE,
70 .ev_actions = llc_sap_active_state_actions_2,
71};
72
73/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_XID_REQ event */
74static llc_sap_action_t llc_sap_active_state_actions_3[] = {
75 [0] = llc_sap_action_send_xid_c,
76 [1] = NULL,
77};
78
79static struct llc_sap_state_trans llc_sap_active_state_trans_3 = {
80 .ev = llc_sap_ev_xid_req,
81 .next_state = LLC_SAP_STATE_ACTIVE,
82 .ev_actions = llc_sap_active_state_actions_3,
83};
84
85/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_XID_C event */
86static llc_sap_action_t llc_sap_active_state_actions_4[] = {
87 [0] = llc_sap_action_send_xid_r,
88 [1] = NULL,
89};
90
91static struct llc_sap_state_trans llc_sap_active_state_trans_4 = {
92 .ev = llc_sap_ev_rx_xid_c,
93 .next_state = LLC_SAP_STATE_ACTIVE,
94 .ev_actions = llc_sap_active_state_actions_4,
95};
96
97/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_XID_R event */
98static llc_sap_action_t llc_sap_active_state_actions_5[] = {
99 [0] = llc_sap_action_xid_ind,
100 [1] = NULL,
101};
102
103static struct llc_sap_state_trans llc_sap_active_state_trans_5 = {
104 .ev = llc_sap_ev_rx_xid_r,
105 .next_state = LLC_SAP_STATE_ACTIVE,
106 .ev_actions = llc_sap_active_state_actions_5,
107};
108
109/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_TEST_REQ event */
110static llc_sap_action_t llc_sap_active_state_actions_6[] = {
111 [0] = llc_sap_action_send_test_c,
112 [1] = NULL,
113};
114
115static struct llc_sap_state_trans llc_sap_active_state_trans_6 = {
116 .ev = llc_sap_ev_test_req,
117 .next_state = LLC_SAP_STATE_ACTIVE,
118 .ev_actions = llc_sap_active_state_actions_6,
119};
120
121/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_TEST_C event */
122static llc_sap_action_t llc_sap_active_state_actions_7[] = {
123 [0] = llc_sap_action_send_test_r,
124 [1] = NULL,
125};
126
127static struct llc_sap_state_trans llc_sap_active_state_trans_7 = {
128 .ev = llc_sap_ev_rx_test_c,
129 .next_state = LLC_SAP_STATE_ACTIVE,
130 .ev_actions = llc_sap_active_state_actions_7
131};
132
133/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_TEST_R event */
134static llc_sap_action_t llc_sap_active_state_actions_8[] = {
135 [0] = llc_sap_action_test_ind,
136 [1] = NULL,
137};
138
139static struct llc_sap_state_trans llc_sap_active_state_trans_8 = {
140 .ev = llc_sap_ev_rx_test_r,
141 .next_state = LLC_SAP_STATE_ACTIVE,
142 .ev_actions = llc_sap_active_state_actions_8,
143};
144
145/* state LLC_SAP_STATE_ACTIVE transition for
146 * LLC_SAP_EV_DEACTIVATION_REQ event
147 */
148static llc_sap_action_t llc_sap_active_state_actions_9[] = {
149 [0] = llc_sap_action_report_status,
150 [1] = NULL,
151};
152
153static struct llc_sap_state_trans llc_sap_active_state_trans_9 = {
154 .ev = llc_sap_ev_deactivation_req,
155 .next_state = LLC_SAP_STATE_INACTIVE,
156 .ev_actions = llc_sap_active_state_actions_9
157};
158
159/* array of pointers; one to each transition */
160static struct llc_sap_state_trans *llc_sap_active_state_transitions[] = {
161 [0] = &llc_sap_active_state_trans_2,
162 [1] = &llc_sap_active_state_trans_1,
163 [2] = &llc_sap_active_state_trans_3,
164 [3] = &llc_sap_active_state_trans_4,
165 [4] = &llc_sap_active_state_trans_5,
166 [5] = &llc_sap_active_state_trans_6,
167 [6] = &llc_sap_active_state_trans_7,
168 [7] = &llc_sap_active_state_trans_8,
169 [8] = &llc_sap_active_state_trans_9,
170 [9] = &llc_sap_state_trans_end,
171};
172
173/* SAP state transition table */
174struct llc_sap_state llc_sap_state_table[LLC_NR_SAP_STATES] = {
175 [LLC_SAP_STATE_INACTIVE - 1] = {
176 .curr_state = LLC_SAP_STATE_INACTIVE,
177 .transitions = llc_sap_inactive_state_transitions,
178 },
179 [LLC_SAP_STATE_ACTIVE - 1] = {
180 .curr_state = LLC_SAP_STATE_ACTIVE,
181 .transitions = llc_sap_active_state_transitions,
182 },
183};
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
new file mode 100644
index 000000000000..965c94eb4bbc
--- /dev/null
+++ b/net/llc/llc_sap.c
@@ -0,0 +1,316 @@
1/*
2 * llc_sap.c - driver routines for SAP component.
3 *
4 * Copyright (c) 1997 by Procom Technology, Inc.
5 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License as published by the Free Software Foundation.
9 * This program is distributed without any warranty or implied warranty
10 * of merchantability or fitness for a particular purpose.
11 *
12 * See the GNU General Public License for more details.
13 */
14
15#include <net/llc.h>
16#include <net/llc_if.h>
17#include <net/llc_conn.h>
18#include <net/llc_pdu.h>
19#include <net/llc_sap.h>
20#include <net/llc_s_ac.h>
21#include <net/llc_s_ev.h>
22#include <net/llc_s_st.h>
23#include <net/sock.h>
24#include <linux/tcp.h>
25#include <linux/llc.h>
26
27/**
28 * llc_alloc_frame - allocates sk_buff for frame
29 *
30 * Allocates an sk_buff for frame and initializes sk_buff fields.
31 * Returns allocated skb or %NULL when out of memory.
32 */
33struct sk_buff *llc_alloc_frame(void)
34{
35 struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
36
37 if (skb) {
38 skb_reserve(skb, 50);
39 skb->nh.raw = skb->h.raw = skb->data;
40 skb->protocol = htons(ETH_P_802_2);
41 skb->dev = dev_base->next;
42 skb->mac.raw = skb->head;
43 }
44 return skb;
45}
46
47void llc_save_primitive(struct sk_buff* skb, u8 prim)
48{
49 struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
50
51 /* save primitive for use by the user. */
52 addr->sllc_family = skb->sk->sk_family;
53 addr->sllc_arphrd = skb->dev->type;
54 addr->sllc_test = prim == LLC_TEST_PRIM;
55 addr->sllc_xid = prim == LLC_XID_PRIM;
56 addr->sllc_ua = prim == LLC_DATAUNIT_PRIM;
57 llc_pdu_decode_sa(skb, addr->sllc_mac);
58 llc_pdu_decode_ssap(skb, &addr->sllc_sap);
59}
60
61/**
62 * llc_sap_rtn_pdu - Informs upper layer on rx of an UI, XID or TEST pdu.
63 * @sap: pointer to SAP
64 * @skb: received pdu
65 */
66void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb)
67{
68 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
69 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
70
71 switch (LLC_U_PDU_RSP(pdu)) {
72 case LLC_1_PDU_CMD_TEST:
73 ev->prim = LLC_TEST_PRIM; break;
74 case LLC_1_PDU_CMD_XID:
75 ev->prim = LLC_XID_PRIM; break;
76 case LLC_1_PDU_CMD_UI:
77 ev->prim = LLC_DATAUNIT_PRIM; break;
78 }
79 ev->ind_cfm_flag = LLC_IND;
80}
81
82/**
83 * llc_find_sap_trans - finds transition for event
84 * @sap: pointer to SAP
85 * @skb: happened event
86 *
87 * This function finds transition that matches with happened event.
88 * Returns the pointer to found transition on success or %NULL for
89 * failure.
90 */
91static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
92 struct sk_buff* skb)
93{
94 int i = 0;
95 struct llc_sap_state_trans *rc = NULL;
96 struct llc_sap_state_trans **next_trans;
97 struct llc_sap_state *curr_state = &llc_sap_state_table[sap->state - 1];
98 /*
99 * Search thru events for this state until list exhausted or until
100 * its obvious the event is not valid for the current state
101 */
102 for (next_trans = curr_state->transitions; next_trans[i]->ev; i++)
103 if (!next_trans[i]->ev(sap, skb)) {
104 rc = next_trans[i]; /* got event match; return it */
105 break;
106 }
107 return rc;
108}
109
110/**
111 * llc_exec_sap_trans_actions - execute actions related to event
112 * @sap: pointer to SAP
113 * @trans: pointer to transition that it's actions must be performed
114 * @skb: happened event.
115 *
116 * This function executes actions that is related to happened event.
117 * Returns 0 for success and 1 for failure of at least one action.
118 */
119static int llc_exec_sap_trans_actions(struct llc_sap *sap,
120 struct llc_sap_state_trans *trans,
121 struct sk_buff *skb)
122{
123 int rc = 0;
124 llc_sap_action_t *next_action = trans->ev_actions;
125
126 for (; next_action && *next_action; next_action++)
127 if ((*next_action)(sap, skb))
128 rc = 1;
129 return rc;
130}
131
132/**
133 * llc_sap_next_state - finds transition, execs actions & change SAP state
134 * @sap: pointer to SAP
135 * @skb: happened event
136 *
137 * This function finds transition that matches with happened event, then
138 * executes related actions and finally changes state of SAP. It returns
139 * 0 on success and 1 for failure.
140 */
141static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb)
142{
143 int rc = 1;
144 struct llc_sap_state_trans *trans;
145
146 if (sap->state > LLC_NR_SAP_STATES)
147 goto out;
148 trans = llc_find_sap_trans(sap, skb);
149 if (!trans)
150 goto out;
151 /*
152 * Got the state to which we next transition; perform the actions
153 * associated with this transition before actually transitioning to the
154 * next state
155 */
156 rc = llc_exec_sap_trans_actions(sap, trans, skb);
157 if (rc)
158 goto out;
159 /*
160 * Transition SAP to next state if all actions execute successfully
161 */
162 sap->state = trans->next_state;
163out:
164 return rc;
165}
166
167/**
168 * llc_sap_state_process - sends event to SAP state machine
169 * @sap: sap to use
170 * @skb: pointer to occurred event
171 *
172 * After executing actions of the event, upper layer will be indicated
173 * if needed(on receiving an UI frame). sk can be null for the
174 * datalink_proto case.
175 */
176static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
177{
178 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
179
180 /*
181 * We have to hold the skb, because llc_sap_next_state
182 * will kfree it in the sending path and we need to
183 * look at the skb->cb, where we encode llc_sap_state_ev.
184 */
185 skb_get(skb);
186 ev->ind_cfm_flag = 0;
187 llc_sap_next_state(sap, skb);
188 if (ev->ind_cfm_flag == LLC_IND) {
189 if (skb->sk->sk_state == TCP_LISTEN)
190 kfree_skb(skb);
191 else {
192 llc_save_primitive(skb, ev->prim);
193
194 /* queue skb to the user. */
195 if (sock_queue_rcv_skb(skb->sk, skb))
196 kfree_skb(skb);
197 }
198 }
199 kfree_skb(skb);
200}
201
202/**
203 * llc_build_and_send_test_pkt - TEST interface for upper layers.
204 * @sap: sap to use
205 * @skb: packet to send
206 * @dmac: destination mac address
207 * @dsap: destination sap
208 *
209 * This function is called when upper layer wants to send a TEST pdu.
210 * Returns 0 for success, 1 otherwise.
211 */
212void llc_build_and_send_test_pkt(struct llc_sap *sap,
213 struct sk_buff *skb, u8 *dmac, u8 dsap)
214{
215 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
216
217 ev->saddr.lsap = sap->laddr.lsap;
218 ev->daddr.lsap = dsap;
219 memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
220 memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
221
222 ev->type = LLC_SAP_EV_TYPE_PRIM;
223 ev->prim = LLC_TEST_PRIM;
224 ev->prim_type = LLC_PRIM_TYPE_REQ;
225 llc_sap_state_process(sap, skb);
226}
227
228/**
229 * llc_build_and_send_xid_pkt - XID interface for upper layers
230 * @sap: sap to use
231 * @skb: packet to send
232 * @dmac: destination mac address
233 * @dsap: destination sap
234 *
235 * This function is called when upper layer wants to send a XID pdu.
236 * Returns 0 for success, 1 otherwise.
237 */
238void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
239 u8 *dmac, u8 dsap)
240{
241 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
242
243 ev->saddr.lsap = sap->laddr.lsap;
244 ev->daddr.lsap = dsap;
245 memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
246 memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
247
248 ev->type = LLC_SAP_EV_TYPE_PRIM;
249 ev->prim = LLC_XID_PRIM;
250 ev->prim_type = LLC_PRIM_TYPE_REQ;
251 llc_sap_state_process(sap, skb);
252}
253
254/**
255 * llc_sap_rcv - sends received pdus to the sap state machine
256 * @sap: current sap component structure.
257 * @skb: received frame.
258 *
259 * Sends received pdus to the sap state machine.
260 */
261static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb)
262{
263 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
264
265 ev->type = LLC_SAP_EV_TYPE_PDU;
266 ev->reason = 0;
267 llc_sap_state_process(sap, skb);
268}
269
270/**
271 * llc_lookup_dgram - Finds dgram socket for the local sap/mac
272 * @sap: SAP
273 * @laddr: address of local LLC (MAC + SAP)
274 *
275 * Search socket list of the SAP and finds connection using the local
276 * mac, and local sap. Returns pointer for socket found, %NULL otherwise.
277 */
278static struct sock *llc_lookup_dgram(struct llc_sap *sap,
279 struct llc_addr *laddr)
280{
281 struct sock *rc;
282 struct hlist_node *node;
283
284 read_lock_bh(&sap->sk_list.lock);
285 sk_for_each(rc, node, &sap->sk_list.list) {
286 struct llc_sock *llc = llc_sk(rc);
287
288 if (rc->sk_type == SOCK_DGRAM &&
289 llc->laddr.lsap == laddr->lsap &&
290 llc_mac_match(llc->laddr.mac, laddr->mac)) {
291 sock_hold(rc);
292 goto found;
293 }
294 }
295 rc = NULL;
296found:
297 read_unlock_bh(&sap->sk_list.lock);
298 return rc;
299}
300
301void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
302{
303 struct llc_addr laddr;
304 struct sock *sk;
305
306 llc_pdu_decode_da(skb, laddr.mac);
307 llc_pdu_decode_dsap(skb, &laddr.lsap);
308
309 sk = llc_lookup_dgram(sap, &laddr);
310 if (sk) {
311 skb->sk = sk;
312 llc_sap_rcv(sap, skb);
313 sock_put(sk);
314 } else
315 kfree_skb(skb);
316}
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c
new file mode 100644
index 000000000000..8fe48a24bad5
--- /dev/null
+++ b/net/llc/llc_station.c
@@ -0,0 +1,713 @@
1/*
2 * llc_station.c - station component of LLC
3 *
4 * Copyright (c) 1997 by Procom Technology, Inc.
5 * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 *
7 * This program can be redistributed or modified under the terms of the
8 * GNU General Public License as published by the Free Software Foundation.
9 * This program is distributed without any warranty or implied warranty
10 * of merchantability or fitness for a particular purpose.
11 *
12 * See the GNU General Public License for more details.
13 */
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/module.h>
17#include <net/llc.h>
18#include <net/llc_sap.h>
19#include <net/llc_conn.h>
20#include <net/llc_c_ac.h>
21#include <net/llc_s_ac.h>
22#include <net/llc_c_ev.h>
23#include <net/llc_c_st.h>
24#include <net/llc_s_ev.h>
25#include <net/llc_s_st.h>
26#include <net/llc_pdu.h>
27
28/**
29 * struct llc_station - LLC station component
30 *
31 * SAP and connection resource manager, one per adapter.
32 *
33 * @state - state of station
34 * @xid_r_count - XID response PDU counter
35 * @mac_sa - MAC source address
36 * @sap_list - list of related SAPs
37 * @ev_q - events entering state mach.
38 * @mac_pdu_q - PDUs ready to send to MAC
39 */
40struct llc_station {
41 u8 state;
42 u8 xid_r_count;
43 struct timer_list ack_timer;
44 u8 retry_count;
45 u8 maximum_retry;
46 struct {
47 struct sk_buff_head list;
48 spinlock_t lock;
49 } ev_q;
50 struct sk_buff_head mac_pdu_q;
51};
52
53/* Types of events (possible values in 'ev->type') */
54#define LLC_STATION_EV_TYPE_SIMPLE 1
55#define LLC_STATION_EV_TYPE_CONDITION 2
56#define LLC_STATION_EV_TYPE_PRIM 3
57#define LLC_STATION_EV_TYPE_PDU 4 /* command/response PDU */
58#define LLC_STATION_EV_TYPE_ACK_TMR 5
59#define LLC_STATION_EV_TYPE_RPT_STATUS 6
60
61/* Events */
62#define LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK 1
63#define LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK 2
64#define LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY 3
65#define LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY 4
66#define LLC_STATION_EV_RX_NULL_DSAP_XID_C 5
67#define LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ 6
68#define LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ 7
69#define LLC_STATION_EV_RX_NULL_DSAP_TEST_C 8
70#define LLC_STATION_EV_DISABLE_REQ 9
71
72struct llc_station_state_ev {
73 u8 type;
74 u8 prim;
75 u8 prim_type;
76 u8 reason;
77 struct list_head node; /* node in station->ev_q.list */
78};
79
80static __inline__ struct llc_station_state_ev *
81 llc_station_ev(struct sk_buff *skb)
82{
83 return (struct llc_station_state_ev *)skb->cb;
84}
85
86typedef int (*llc_station_ev_t)(struct sk_buff *skb);
87
88#define LLC_STATION_STATE_DOWN 1 /* initial state */
89#define LLC_STATION_STATE_DUP_ADDR_CHK 2
90#define LLC_STATION_STATE_UP 3
91
92#define LLC_NBR_STATION_STATES 3 /* size of state table */
93
94typedef int (*llc_station_action_t)(struct sk_buff *skb);
95
96/* Station component state table structure */
97struct llc_station_state_trans {
98 llc_station_ev_t ev;
99 u8 next_state;
100 llc_station_action_t *ev_actions;
101};
102
103struct llc_station_state {
104 u8 curr_state;
105 struct llc_station_state_trans **transitions;
106};
107
108static struct llc_station llc_main_station;
109
110static int llc_stat_ev_enable_with_dup_addr_check(struct sk_buff *skb)
111{
112 struct llc_station_state_ev *ev = llc_station_ev(skb);
113
114 return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
115 ev->prim_type ==
116 LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK ? 0 : 1;
117}
118
119static int llc_stat_ev_enable_without_dup_addr_check(struct sk_buff *skb)
120{
121 struct llc_station_state_ev *ev = llc_station_ev(skb);
122
123 return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
124 ev->prim_type ==
125 LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK ? 0 : 1;
126}
127
128static int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct sk_buff *skb)
129{
130 struct llc_station_state_ev *ev = llc_station_ev(skb);
131
132 return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
133 llc_main_station.retry_count <
134 llc_main_station.maximum_retry ? 0 : 1;
135}
136
137static int llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry(struct sk_buff *skb)
138{
139 struct llc_station_state_ev *ev = llc_station_ev(skb);
140
141 return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
142 llc_main_station.retry_count ==
143 llc_main_station.maximum_retry ? 0 : 1;
144}
145
146static int llc_stat_ev_rx_null_dsap_xid_c(struct sk_buff *skb)
147{
148 struct llc_station_state_ev *ev = llc_station_ev(skb);
149 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
150
151 return ev->type == LLC_STATION_EV_TYPE_PDU &&
152 LLC_PDU_IS_CMD(pdu) && /* command PDU */
153 LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
154 LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID &&
155 !pdu->dsap ? 0 : 1; /* NULL DSAP value */
156}
157
158static int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct sk_buff *skb)
159{
160 struct llc_station_state_ev *ev = llc_station_ev(skb);
161 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
162
163 return ev->type == LLC_STATION_EV_TYPE_PDU &&
164 LLC_PDU_IS_RSP(pdu) && /* response PDU */
165 LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
166 LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
167 !pdu->dsap && /* NULL DSAP value */
168 !llc_main_station.xid_r_count ? 0 : 1;
169}
170
171static int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct sk_buff *skb)
172{
173 struct llc_station_state_ev *ev = llc_station_ev(skb);
174 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
175
176 return ev->type == LLC_STATION_EV_TYPE_PDU &&
177 LLC_PDU_IS_RSP(pdu) && /* response PDU */
178 LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
179 LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
180 !pdu->dsap && /* NULL DSAP value */
181 llc_main_station.xid_r_count == 1 ? 0 : 1;
182}
183
184static int llc_stat_ev_rx_null_dsap_test_c(struct sk_buff *skb)
185{
186 struct llc_station_state_ev *ev = llc_station_ev(skb);
187 struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
188
189 return ev->type == LLC_STATION_EV_TYPE_PDU &&
190 LLC_PDU_IS_CMD(pdu) && /* command PDU */
191 LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
192 LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST &&
193 !pdu->dsap ? 0 : 1; /* NULL DSAP */
194}
195
196static int llc_stat_ev_disable_req(struct sk_buff *skb)
197{
198 struct llc_station_state_ev *ev = llc_station_ev(skb);
199
200 return ev->type == LLC_STATION_EV_TYPE_PRIM &&
201 ev->prim == LLC_DISABLE_PRIM &&
202 ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
203}
204
205/**
206 * llc_station_send_pdu - queues PDU to send
207 * @skb: Address of the PDU
208 *
209 * Queues a PDU to send to the MAC layer.
210 */
211static void llc_station_send_pdu(struct sk_buff *skb)
212{
213 skb_queue_tail(&llc_main_station.mac_pdu_q, skb);
214 while ((skb = skb_dequeue(&llc_main_station.mac_pdu_q)) != NULL)
215 if (dev_queue_xmit(skb))
216 break;
217}
218
219static int llc_station_ac_start_ack_timer(struct sk_buff *skb)
220{
221 mod_timer(&llc_main_station.ack_timer, jiffies + LLC_ACK_TIME * HZ);
222 return 0;
223}
224
225static int llc_station_ac_set_retry_cnt_0(struct sk_buff *skb)
226{
227 llc_main_station.retry_count = 0;
228 return 0;
229}
230
231static int llc_station_ac_inc_retry_cnt_by_1(struct sk_buff *skb)
232{
233 llc_main_station.retry_count++;
234 return 0;
235}
236
237static int llc_station_ac_set_xid_r_cnt_0(struct sk_buff *skb)
238{
239 llc_main_station.xid_r_count = 0;
240 return 0;
241}
242
243static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb)
244{
245 llc_main_station.xid_r_count++;
246 return 0;
247}
248
249static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
250{
251 int rc = 1;
252 struct sk_buff *nskb = llc_alloc_frame();
253
254 if (!nskb)
255 goto out;
256 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
257 llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
258 rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa);
259 if (rc)
260 goto free;
261 llc_station_send_pdu(nskb);
262out:
263 return rc;
264free:
265 kfree_skb(skb);
266 goto out;
267}
268
269static int llc_station_ac_send_xid_r(struct sk_buff *skb)
270{
271 u8 mac_da[ETH_ALEN], dsap;
272 int rc = 1;
273 struct sk_buff* nskb = llc_alloc_frame();
274
275 if (!nskb)
276 goto out;
277 rc = 0;
278 nskb->dev = skb->dev;
279 llc_pdu_decode_sa(skb, mac_da);
280 llc_pdu_decode_ssap(skb, &dsap);
281 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
282 llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
283 rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
284 if (rc)
285 goto free;
286 llc_station_send_pdu(nskb);
287out:
288 return rc;
289free:
290 kfree_skb(skb);
291 goto out;
292}
293
294static int llc_station_ac_send_test_r(struct sk_buff *skb)
295{
296 u8 mac_da[ETH_ALEN], dsap;
297 int rc = 1;
298 struct sk_buff *nskb = llc_alloc_frame();
299
300 if (!nskb)
301 goto out;
302 rc = 0;
303 nskb->dev = skb->dev;
304 llc_pdu_decode_sa(skb, mac_da);
305 llc_pdu_decode_ssap(skb, &dsap);
306 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
307 llc_pdu_init_as_test_rsp(nskb, skb);
308 rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
309 if (rc)
310 goto free;
311 llc_station_send_pdu(nskb);
312out:
313 return rc;
314free:
315 kfree_skb(skb);
316 goto out;
317}
318
319static int llc_station_ac_report_status(struct sk_buff *skb)
320{
321 return 0;
322}
323
324/* COMMON STATION STATE transitions */
325
326/* dummy last-transition indicator; common to all state transition groups
327 * last entry for this state
328 * all members are zeros, .bss zeroes it
329 */
330static struct llc_station_state_trans llc_stat_state_trans_end;
331
332/* DOWN STATE transitions */
333
334/* state transition for LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK event */
335static llc_station_action_t llc_stat_down_state_actions_1[] = {
336 [0] = llc_station_ac_start_ack_timer,
337 [1] = llc_station_ac_set_retry_cnt_0,
338 [2] = llc_station_ac_set_xid_r_cnt_0,
339 [3] = llc_station_ac_send_null_dsap_xid_c,
340 [4] = NULL,
341};
342
343static struct llc_station_state_trans llc_stat_down_state_trans_1 = {
344 .ev = llc_stat_ev_enable_with_dup_addr_check,
345 .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
346 .ev_actions = llc_stat_down_state_actions_1,
347};
348
349/* state transition for LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK event */
350static llc_station_action_t llc_stat_down_state_actions_2[] = {
351 [0] = llc_station_ac_report_status, /* STATION UP */
352 [1] = NULL,
353};
354
355static struct llc_station_state_trans llc_stat_down_state_trans_2 = {
356 .ev = llc_stat_ev_enable_without_dup_addr_check,
357 .next_state = LLC_STATION_STATE_UP,
358 .ev_actions = llc_stat_down_state_actions_2,
359};
360
361/* array of pointers; one to each transition */
362static struct llc_station_state_trans *llc_stat_dwn_state_trans[] = {
363 [0] = &llc_stat_down_state_trans_1,
364 [1] = &llc_stat_down_state_trans_2,
365 [2] = &llc_stat_state_trans_end,
366};
367
368/* UP STATE transitions */
369/* state transition for LLC_STATION_EV_DISABLE_REQ event */
370static llc_station_action_t llc_stat_up_state_actions_1[] = {
371 [0] = llc_station_ac_report_status, /* STATION DOWN */
372 [1] = NULL,
373};
374
375static struct llc_station_state_trans llc_stat_up_state_trans_1 = {
376 .ev = llc_stat_ev_disable_req,
377 .next_state = LLC_STATION_STATE_DOWN,
378 .ev_actions = llc_stat_up_state_actions_1,
379};
380
381/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */
382static llc_station_action_t llc_stat_up_state_actions_2[] = {
383 [0] = llc_station_ac_send_xid_r,
384 [1] = NULL,
385};
386
387static struct llc_station_state_trans llc_stat_up_state_trans_2 = {
388 .ev = llc_stat_ev_rx_null_dsap_xid_c,
389 .next_state = LLC_STATION_STATE_UP,
390 .ev_actions = llc_stat_up_state_actions_2,
391};
392
393/* state transition for LLC_STATION_EV_RX_NULL_DSAP_TEST_C event */
394static llc_station_action_t llc_stat_up_state_actions_3[] = {
395 [0] = llc_station_ac_send_test_r,
396 [1] = NULL,
397};
398
399static struct llc_station_state_trans llc_stat_up_state_trans_3 = {
400 .ev = llc_stat_ev_rx_null_dsap_test_c,
401 .next_state = LLC_STATION_STATE_UP,
402 .ev_actions = llc_stat_up_state_actions_3,
403};
404
405/* array of pointers; one to each transition */
406static struct llc_station_state_trans *llc_stat_up_state_trans [] = {
407 [0] = &llc_stat_up_state_trans_1,
408 [1] = &llc_stat_up_state_trans_2,
409 [2] = &llc_stat_up_state_trans_3,
410 [3] = &llc_stat_state_trans_end,
411};
412
413/* DUP ADDR CHK STATE transitions */
414/* state transition for LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ
415 * event
416 */
417static llc_station_action_t llc_stat_dupaddr_state_actions_1[] = {
418 [0] = llc_station_ac_inc_xid_r_cnt_by_1,
419 [1] = NULL,
420};
421
422static struct llc_station_state_trans llc_stat_dupaddr_state_trans_1 = {
423 .ev = llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq,
424 .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
425 .ev_actions = llc_stat_dupaddr_state_actions_1,
426};
427
428/* state transition for LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ
429 * event
430 */
431static llc_station_action_t llc_stat_dupaddr_state_actions_2[] = {
432 [0] = llc_station_ac_report_status, /* DUPLICATE ADDRESS FOUND */
433 [1] = NULL,
434};
435
436static struct llc_station_state_trans llc_stat_dupaddr_state_trans_2 = {
437 .ev = llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq,
438 .next_state = LLC_STATION_STATE_DOWN,
439 .ev_actions = llc_stat_dupaddr_state_actions_2,
440};
441
442/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */
443static llc_station_action_t llc_stat_dupaddr_state_actions_3[] = {
444 [0] = llc_station_ac_send_xid_r,
445 [1] = NULL,
446};
447
448static struct llc_station_state_trans llc_stat_dupaddr_state_trans_3 = {
449 .ev = llc_stat_ev_rx_null_dsap_xid_c,
450 .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
451 .ev_actions = llc_stat_dupaddr_state_actions_3,
452};
453
454/* state transition for LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY
455 * event
456 */
457static llc_station_action_t llc_stat_dupaddr_state_actions_4[] = {
458 [0] = llc_station_ac_start_ack_timer,
459 [1] = llc_station_ac_inc_retry_cnt_by_1,
460 [2] = llc_station_ac_set_xid_r_cnt_0,
461 [3] = llc_station_ac_send_null_dsap_xid_c,
462 [4] = NULL,
463};
464
465static struct llc_station_state_trans llc_stat_dupaddr_state_trans_4 = {
466 .ev = llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry,
467 .next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
468 .ev_actions = llc_stat_dupaddr_state_actions_4,
469};
470
471/* state transition for LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY
472 * event
473 */
474static llc_station_action_t llc_stat_dupaddr_state_actions_5[] = {
475 [0] = llc_station_ac_report_status, /* STATION UP */
476 [1] = NULL,
477};
478
479static struct llc_station_state_trans llc_stat_dupaddr_state_trans_5 = {
480 .ev = llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry,
481 .next_state = LLC_STATION_STATE_UP,
482 .ev_actions = llc_stat_dupaddr_state_actions_5,
483};
484
485/* state transition for LLC_STATION_EV_DISABLE_REQ event */
486static llc_station_action_t llc_stat_dupaddr_state_actions_6[] = {
487 [0] = llc_station_ac_report_status, /* STATION DOWN */
488 [1] = NULL,
489};
490
491static struct llc_station_state_trans llc_stat_dupaddr_state_trans_6 = {
492 .ev = llc_stat_ev_disable_req,
493 .next_state = LLC_STATION_STATE_DOWN,
494 .ev_actions = llc_stat_dupaddr_state_actions_6,
495};
496
497/* array of pointers; one to each transition */
498static struct llc_station_state_trans *llc_stat_dupaddr_state_trans[] = {
499 [0] = &llc_stat_dupaddr_state_trans_6, /* Request */
500 [1] = &llc_stat_dupaddr_state_trans_4, /* Timer */
501 [2] = &llc_stat_dupaddr_state_trans_5,
502 [3] = &llc_stat_dupaddr_state_trans_1, /* Receive frame */
503 [4] = &llc_stat_dupaddr_state_trans_2,
504 [5] = &llc_stat_dupaddr_state_trans_3,
505 [6] = &llc_stat_state_trans_end,
506};
507
508static struct llc_station_state
509 llc_station_state_table[LLC_NBR_STATION_STATES] = {
510 [LLC_STATION_STATE_DOWN - 1] = {
511 .curr_state = LLC_STATION_STATE_DOWN,
512 .transitions = llc_stat_dwn_state_trans,
513 },
514 [LLC_STATION_STATE_DUP_ADDR_CHK - 1] = {
515 .curr_state = LLC_STATION_STATE_DUP_ADDR_CHK,
516 .transitions = llc_stat_dupaddr_state_trans,
517 },
518 [LLC_STATION_STATE_UP - 1] = {
519 .curr_state = LLC_STATION_STATE_UP,
520 .transitions = llc_stat_up_state_trans,
521 },
522};
523
524/**
525 * llc_exec_station_trans_actions - executes actions for transition
526 * @trans: Address of the transition
527 * @skb: Address of the event that caused the transition
528 *
529 * Executes actions of a transition of the station state machine. Returns
530 * 0 if all actions complete successfully, nonzero otherwise.
531 */
532static u16 llc_exec_station_trans_actions(struct llc_station_state_trans *trans,
533 struct sk_buff *skb)
534{
535 u16 rc = 0;
536 llc_station_action_t *next_action = trans->ev_actions;
537
538 for (; next_action && *next_action; next_action++)
539 if ((*next_action)(skb))
540 rc = 1;
541 return rc;
542}
543
544/**
545 * llc_find_station_trans - finds transition for this event
546 * @skb: Address of the event
547 *
548 * Search thru events of the current state of the station until list
549 * exhausted or it's obvious that the event is not valid for the current
550 * state. Returns the address of the transition if cound, %NULL otherwise.
551 */
552static struct llc_station_state_trans *
553 llc_find_station_trans(struct sk_buff *skb)
554{
555 int i = 0;
556 struct llc_station_state_trans *rc = NULL;
557 struct llc_station_state_trans **next_trans;
558 struct llc_station_state *curr_state =
559 &llc_station_state_table[llc_main_station.state - 1];
560
561 for (next_trans = curr_state->transitions; next_trans[i]->ev; i++)
562 if (!next_trans[i]->ev(skb)) {
563 rc = next_trans[i];
564 break;
565 }
566 return rc;
567}
568
569/**
570 * llc_station_free_ev - frees an event
571 * @skb: Address of the event
572 *
573 * Frees an event.
574 */
575static void llc_station_free_ev(struct sk_buff *skb)
576{
577 struct llc_station_state_ev *ev = llc_station_ev(skb);
578
579 if (ev->type == LLC_STATION_EV_TYPE_PDU)
580 kfree_skb(skb);
581}
582
583/**
584 * llc_station_next_state - processes event and goes to the next state
585 * @skb: Address of the event
586 *
587 * Processes an event, executes any transitions related to that event and
588 * updates the state of the station.
589 */
590static u16 llc_station_next_state(struct sk_buff *skb)
591{
592 u16 rc = 1;
593 struct llc_station_state_trans *trans;
594
595 if (llc_main_station.state > LLC_NBR_STATION_STATES)
596 goto out;
597 trans = llc_find_station_trans(skb);
598 if (trans) {
599 /* got the state to which we next transition; perform the
600 * actions associated with this transition before actually
601 * transitioning to the next state
602 */
603 rc = llc_exec_station_trans_actions(trans, skb);
604 if (!rc)
605 /* transition station to next state if all actions
606 * execute successfully; done; wait for next event
607 */
608 llc_main_station.state = trans->next_state;
609 } else
610 /* event not recognized in current state; re-queue it for
611 * processing again at a later time; return failure
612 */
613 rc = 0;
614out:
615 llc_station_free_ev(skb);
616 return rc;
617}
618
619/**
620 * llc_station_service_events - service events in the queue
621 *
622 * Get an event from the station event queue (if any); attempt to service
623 * the event; if event serviced, get the next event (if any) on the event
624 * queue; if event not service, re-queue the event on the event queue and
625 * attempt to service the next event; when serviced all events in queue,
626 * finished; if don't transition to different state, just service all
627 * events once; if transition to new state, service all events again.
628 * Caller must hold llc_main_station.ev_q.lock.
629 */
630static void llc_station_service_events(void)
631{
632 struct sk_buff *skb;
633
634 while ((skb = skb_dequeue(&llc_main_station.ev_q.list)) != NULL)
635 llc_station_next_state(skb);
636}
637
638/**
639 * llc_station_state_process: queue event and try to process queue.
640 * @skb: Address of the event
641 *
642 * Queues an event (on the station event queue) for handling by the
643 * station state machine and attempts to process any queued-up events.
644 */
645static void llc_station_state_process(struct sk_buff *skb)
646{
647 spin_lock_bh(&llc_main_station.ev_q.lock);
648 skb_queue_tail(&llc_main_station.ev_q.list, skb);
649 llc_station_service_events();
650 spin_unlock_bh(&llc_main_station.ev_q.lock);
651}
652
653static void llc_station_ack_tmr_cb(unsigned long timeout_data)
654{
655 struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
656
657 if (skb) {
658 struct llc_station_state_ev *ev = llc_station_ev(skb);
659
660 ev->type = LLC_STATION_EV_TYPE_ACK_TMR;
661 llc_station_state_process(skb);
662 }
663}
664
665/*
666 * llc_station_rcv - send received pdu to the station state machine
667 * @skb: received frame.
668 *
669 * Sends data unit to station state machine.
670 */
671static void llc_station_rcv(struct sk_buff *skb)
672{
673 struct llc_station_state_ev *ev = llc_station_ev(skb);
674
675 ev->type = LLC_STATION_EV_TYPE_PDU;
676 ev->reason = 0;
677 llc_station_state_process(skb);
678}
679
680int __init llc_station_init(void)
681{
682 u16 rc = -ENOBUFS;
683 struct sk_buff *skb;
684 struct llc_station_state_ev *ev;
685
686 skb_queue_head_init(&llc_main_station.mac_pdu_q);
687 skb_queue_head_init(&llc_main_station.ev_q.list);
688 spin_lock_init(&llc_main_station.ev_q.lock);
689 init_timer(&llc_main_station.ack_timer);
690 llc_main_station.ack_timer.data = (unsigned long)&llc_main_station;
691 llc_main_station.ack_timer.function = llc_station_ack_tmr_cb;
692
693 skb = alloc_skb(0, GFP_ATOMIC);
694 if (!skb)
695 goto out;
696 rc = 0;
697 llc_set_station_handler(llc_station_rcv);
698 ev = llc_station_ev(skb);
699 memset(ev, 0, sizeof(*ev));
700 llc_main_station.ack_timer.expires = jiffies + 3 * HZ;
701 llc_main_station.maximum_retry = 1;
702 llc_main_station.state = LLC_STATION_STATE_DOWN;
703 ev->type = LLC_STATION_EV_TYPE_SIMPLE;
704 ev->prim_type = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
705 rc = llc_station_next_state(skb);
706out:
707 return rc;
708}
709
710void __exit llc_station_exit(void)
711{
712 llc_set_station_handler(NULL);
713}