^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * LAPB release 002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This code REQUIRES 2.1.15 or higher/ NET3.038
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * History
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * LAPB 001 Jonathan Naulor Started Coding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * LAPB 002 Jonathan Naylor New timer architecture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * 2000-10-29 Henner Eisen lapb_data_indication() return status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/sockios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <net/lapb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * State machine for state 0, Disconnected State.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * The handling of the timer(s) is in file lapb_timer.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static void lapb_state0_machine(struct lapb_cb *lapb, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct lapb_frame *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) switch (frame->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) case LAPB_SABM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) lapb_dbg(1, "(%p) S0 RX SABM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (lapb->mode & LAPB_EXTENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) lapb_dbg(1, "(%p) S0 TX DM(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) lapb_send_control(lapb, LAPB_DM, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) lapb_dbg(1, "(%p) S0 TX UA(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) lapb_dbg(0, "(%p) S0 -> S3\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) lapb_send_control(lapb, LAPB_UA, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) lapb_stop_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) lapb->state = LAPB_STATE_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) lapb->condition = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) lapb->vs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) lapb->vr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) lapb->va = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) lapb_connect_indication(lapb, LAPB_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case LAPB_SABME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) lapb_dbg(1, "(%p) S0 RX SABME(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (lapb->mode & LAPB_EXTENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) lapb_dbg(1, "(%p) S0 TX UA(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) lapb_dbg(0, "(%p) S0 -> S3\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) lapb_send_control(lapb, LAPB_UA, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) lapb_stop_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) lapb->state = LAPB_STATE_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) lapb->condition = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) lapb->vs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) lapb->vr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) lapb->va = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) lapb_connect_indication(lapb, LAPB_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) lapb_dbg(1, "(%p) S0 TX DM(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) lapb_send_control(lapb, LAPB_DM, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case LAPB_DISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) lapb_dbg(1, "(%p) S0 RX DISC(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) lapb_dbg(1, "(%p) S0 TX UA(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * State machine for state 1, Awaiting Connection State.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * The handling of the timer(s) is in file lapb_timer.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void lapb_state1_machine(struct lapb_cb *lapb, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct lapb_frame *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) switch (frame->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case LAPB_SABM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) lapb_dbg(1, "(%p) S1 RX SABM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (lapb->mode & LAPB_EXTENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) lapb_dbg(1, "(%p) S1 TX DM(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) lapb_send_control(lapb, LAPB_DM, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) lapb_dbg(1, "(%p) S1 TX UA(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) lapb_send_control(lapb, LAPB_UA, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) case LAPB_SABME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) lapb_dbg(1, "(%p) S1 RX SABME(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (lapb->mode & LAPB_EXTENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) lapb_dbg(1, "(%p) S1 TX UA(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) lapb_send_control(lapb, LAPB_UA, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) lapb_dbg(1, "(%p) S1 TX DM(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) lapb_send_control(lapb, LAPB_DM, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case LAPB_DISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) lapb_dbg(1, "(%p) S1 RX DISC(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) lapb_dbg(1, "(%p) S1 TX DM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case LAPB_UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) lapb_dbg(1, "(%p) S1 RX UA(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (frame->pf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) lapb_dbg(0, "(%p) S1 -> S3\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) lapb_stop_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) lapb->state = LAPB_STATE_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) lapb->condition = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) lapb->vs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) lapb->vr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) lapb->va = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) lapb_connect_confirmation(lapb, LAPB_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case LAPB_DM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) lapb_dbg(1, "(%p) S1 RX DM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (frame->pf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) lapb_clear_queues(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) lapb->state = LAPB_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) lapb_disconnect_indication(lapb, LAPB_REFUSED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * State machine for state 2, Awaiting Release State.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * The handling of the timer(s) is in file lapb_timer.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static void lapb_state2_machine(struct lapb_cb *lapb, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct lapb_frame *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) switch (frame->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case LAPB_SABM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case LAPB_SABME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) lapb_dbg(1, "(%p) S2 RX {SABM,SABME}(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) lapb_dbg(1, "(%p) S2 TX DM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case LAPB_DISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) lapb_dbg(1, "(%p) S2 RX DISC(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) lapb_dbg(1, "(%p) S2 TX UA(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case LAPB_UA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) lapb_dbg(1, "(%p) S2 RX UA(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (frame->pf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) lapb->state = LAPB_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) lapb_disconnect_confirmation(lapb, LAPB_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case LAPB_DM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) lapb_dbg(1, "(%p) S2 RX DM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (frame->pf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) lapb->state = LAPB_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) lapb_disconnect_confirmation(lapb, LAPB_NOTCONNECTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case LAPB_I:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case LAPB_REJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case LAPB_RNR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case LAPB_RR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) lapb_dbg(1, "(%p) S2 RX {I,REJ,RNR,RR}(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) lapb_dbg(1, "(%p) S2 RX DM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (frame->pf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) lapb_send_control(lapb, LAPB_DM, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * State machine for state 3, Connected State.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * The handling of the timer(s) is in file lapb_timer.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct lapb_frame *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int queued = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) LAPB_SMODULUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) switch (frame->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case LAPB_SABM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) lapb_dbg(1, "(%p) S3 RX SABM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (lapb->mode & LAPB_EXTENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) lapb_dbg(1, "(%p) S3 TX DM(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) lapb_send_control(lapb, LAPB_DM, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) lapb_dbg(1, "(%p) S3 TX UA(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) lapb_send_control(lapb, LAPB_UA, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) lapb_stop_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) lapb->condition = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) lapb->vs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) lapb->vr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) lapb->va = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) lapb_requeue_frames(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case LAPB_SABME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) lapb_dbg(1, "(%p) S3 RX SABME(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (lapb->mode & LAPB_EXTENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) lapb_dbg(1, "(%p) S3 TX UA(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) lapb_send_control(lapb, LAPB_UA, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) lapb_stop_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) lapb->condition = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) lapb->vs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) lapb->vr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) lapb->va = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) lapb_requeue_frames(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) lapb_dbg(1, "(%p) S3 TX DM(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) lapb_send_control(lapb, LAPB_DM, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) case LAPB_DISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) lapb_dbg(1, "(%p) S3 RX DISC(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) lapb_clear_queues(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) lapb->state = LAPB_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) lapb_disconnect_indication(lapb, LAPB_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case LAPB_DM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) lapb_dbg(1, "(%p) S3 RX DM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) lapb_clear_queues(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) lapb->state = LAPB_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) lapb_disconnect_indication(lapb, LAPB_NOTCONNECTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) case LAPB_RNR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) lapb_dbg(1, "(%p) S3 RX RNR(%d) R%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) lapb->dev, frame->pf, frame->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) lapb_check_need_response(lapb, frame->cr, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (lapb_validate_nr(lapb, frame->nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) lapb_check_iframes_acked(lapb, frame->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) lapb->frmr_data = *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) lapb->frmr_type = LAPB_FRMR_Z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) lapb_transmit_frmr(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) lapb->state = LAPB_STATE_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case LAPB_RR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) lapb_dbg(1, "(%p) S3 RX RR(%d) R%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) lapb->dev, frame->pf, frame->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) lapb_check_need_response(lapb, frame->cr, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (lapb_validate_nr(lapb, frame->nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) lapb_check_iframes_acked(lapb, frame->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) lapb->frmr_data = *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) lapb->frmr_type = LAPB_FRMR_Z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) lapb_transmit_frmr(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) lapb->state = LAPB_STATE_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case LAPB_REJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) lapb_dbg(1, "(%p) S3 RX REJ(%d) R%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) lapb->dev, frame->pf, frame->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) lapb_check_need_response(lapb, frame->cr, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (lapb_validate_nr(lapb, frame->nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) lapb_frames_acked(lapb, frame->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) lapb_stop_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) lapb_requeue_frames(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) lapb->frmr_data = *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) lapb->frmr_type = LAPB_FRMR_Z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) lapb_transmit_frmr(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) lapb->state = LAPB_STATE_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case LAPB_I:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) lapb_dbg(1, "(%p) S3 RX I(%d) S%d R%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) lapb->dev, frame->pf, frame->ns, frame->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (!lapb_validate_nr(lapb, frame->nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) lapb->frmr_data = *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) lapb->frmr_type = LAPB_FRMR_Z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) lapb_transmit_frmr(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) lapb->state = LAPB_STATE_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (lapb->condition & LAPB_PEER_RX_BUSY_CONDITION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) lapb_frames_acked(lapb, frame->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) lapb_check_iframes_acked(lapb, frame->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (frame->ns == lapb->vr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int cn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) cn = lapb_data_indication(lapb, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) queued = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * If upper layer has dropped the frame, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * basically ignore any further protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * processing. This will cause the peer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * to re-transmit the frame later like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * a frame lost on the wire.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (cn == NET_RX_DROP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pr_debug("rx congestion\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) lapb->vr = (lapb->vr + 1) % modulus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) lapb->condition &= ~LAPB_REJECT_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (frame->pf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) lapb_enquiry_response(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (!(lapb->condition &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) LAPB_ACK_PENDING_CONDITION)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) lapb->condition |= LAPB_ACK_PENDING_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) lapb_start_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (lapb->condition & LAPB_REJECT_CONDITION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (frame->pf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) lapb_enquiry_response(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) lapb_dbg(1, "(%p) S3 TX REJ(%d) R%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) lapb->dev, frame->pf, lapb->vr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) lapb->condition |= LAPB_REJECT_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) lapb_send_control(lapb, LAPB_REJ, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case LAPB_FRMR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) lapb_dbg(1, "(%p) S3 RX FRMR(%d) %5ph\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) lapb->dev, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) lapb_establish_data_link(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) lapb_dbg(0, "(%p) S3 -> S1\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) lapb_requeue_frames(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) lapb->state = LAPB_STATE_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) case LAPB_ILLEGAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) lapb_dbg(1, "(%p) S3 RX ILLEGAL(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) lapb->frmr_data = *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) lapb->frmr_type = LAPB_FRMR_W;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) lapb_transmit_frmr(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) lapb_start_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) lapb->state = LAPB_STATE_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (!queued)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * State machine for state 4, Frame Reject State.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * The handling of the timer(s) is in file lapb_timer.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static void lapb_state4_machine(struct lapb_cb *lapb, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct lapb_frame *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) switch (frame->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) case LAPB_SABM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) lapb_dbg(1, "(%p) S4 RX SABM(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (lapb->mode & LAPB_EXTENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) lapb_dbg(1, "(%p) S4 TX DM(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) lapb_send_control(lapb, LAPB_DM, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) lapb_dbg(1, "(%p) S4 TX UA(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) lapb_send_control(lapb, LAPB_UA, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) lapb_stop_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) lapb->state = LAPB_STATE_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) lapb->condition = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) lapb->vs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) lapb->vr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) lapb->va = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) lapb_connect_indication(lapb, LAPB_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) case LAPB_SABME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) lapb_dbg(1, "(%p) S4 RX SABME(%d)\n", lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (lapb->mode & LAPB_EXTENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) lapb_dbg(1, "(%p) S4 TX UA(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) lapb_send_control(lapb, LAPB_UA, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) lapb_stop_t1timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) lapb_stop_t2timer(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) lapb->state = LAPB_STATE_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) lapb->condition = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) lapb->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) lapb->vs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) lapb->vr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) lapb->va = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) lapb_connect_indication(lapb, LAPB_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) lapb_dbg(1, "(%p) S4 TX DM(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) lapb->dev, frame->pf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) lapb_send_control(lapb, LAPB_DM, frame->pf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) LAPB_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * Process an incoming LAPB frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct lapb_frame frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (lapb_decode(lapb, skb, &frame) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) switch (lapb->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) case LAPB_STATE_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) lapb_state0_machine(lapb, skb, &frame); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case LAPB_STATE_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) lapb_state1_machine(lapb, skb, &frame); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case LAPB_STATE_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) lapb_state2_machine(lapb, skb, &frame); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) case LAPB_STATE_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) lapb_state3_machine(lapb, skb, &frame); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) case LAPB_STATE_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) lapb_state4_machine(lapb, skb, &frame); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) lapb_kick(lapb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }