aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hisax/l3_1tr6.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2019-04-18 22:47:35 +0200
committerArnd Bergmann <arnd@arndb.de>2019-05-31 11:12:45 +0200
commit85993b8c9786fb24975dbcabebb1c75790d4fb6a (patch)
tree48b6d667c6258b44a4915acbd403f17c1b1c9cf5 /drivers/isdn/hisax/l3_1tr6.c
parentisdn: gigaset: remove i4l support (diff)
downloadlinux-dev-85993b8c9786fb24975dbcabebb1c75790d4fb6a.tar.xz
linux-dev-85993b8c9786fb24975dbcabebb1c75790d4fb6a.zip
isdn: remove hisax driver
With the decline of ISDN, this seems to have become almost completely obsolete, and even in the past years before that, almost all remaining users appear to have used mISDN instead. Birger Harzenetter noted that he is still using i4l/hisax to take advantage of the 'divert' driver for call diversion, but otherwise uses mISDN on the same hardware. This is a rare edge case as far as I can tell, but we are still breaking an actively used work flow (see https://xkcd.com/1172/). We debated moving i4l/hisax to staging as an intermediate step, but as he is not likely to change the setup, and that would just delay breaking this use case. The alternatives here are to stay on stable kernels < 5.2, to create an external driver repository for isdn4linux, or to add divert functionality to mISDN. Cc: Birger Harzenetter <WIMPy@yeti.dk> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/isdn/hisax/l3_1tr6.c')
-rw-r--r--drivers/isdn/hisax/l3_1tr6.c932
1 files changed, 0 insertions, 932 deletions
diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c
deleted file mode 100644
index 98f60d1523f4..000000000000
--- a/drivers/isdn/hisax/l3_1tr6.c
+++ /dev/null
@@ -1,932 +0,0 @@
-/* $Id: l3_1tr6.c,v 2.15.2.3 2004/01/13 14:31:25 keil Exp $
- *
- * German 1TR6 D-channel protocol
- *
- * Author Karsten Keil
- * Copyright by Karsten Keil <keil@isdn4linux.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * For changes and modifications please read
- * Documentation/isdn/HiSax.cert
- *
- */
-
-#include "hisax.h"
-#include "l3_1tr6.h"
-#include "isdnl3.h"
-#include <linux/ctype.h>
-
-extern char *HiSax_getrev(const char *revision);
-static const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $";
-
-#define MsgHead(ptr, cref, mty, dis) \
- *ptr++ = dis; \
- *ptr++ = 0x1; \
- *ptr++ = cref ^ 0x80; \
- *ptr++ = mty
-
-static void
-l3_1TR6_message(struct l3_process *pc, u_char mt, u_char pd)
-{
- struct sk_buff *skb;
- u_char *p;
-
- if (!(skb = l3_alloc_skb(4)))
- return;
- p = skb_put(skb, 4);
- MsgHead(p, pc->callref, mt, pd);
- l3_msg(pc->st, DL_DATA | REQUEST, skb);
-}
-
-static void
-l3_1tr6_release_req(struct l3_process *pc, u_char pr, void *arg)
-{
- StopAllL3Timer(pc);
- newl3state(pc, 19);
- l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1);
- L3AddTimer(&pc->timer, T308, CC_T308_1);
-}
-
-static void
-l3_1tr6_invalid(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb = arg;
-
- dev_kfree_skb(skb);
- l3_1tr6_release_req(pc, 0, NULL);
-}
-
-static void
-l3_1tr6_error(struct l3_process *pc, u_char *msg, struct sk_buff *skb)
-{
- dev_kfree_skb(skb);
- if (pc->st->l3.debug & L3_DEB_WARN)
- l3_debug(pc->st, "%s", msg);
- l3_1tr6_release_req(pc, 0, NULL);
-}
-
-static void
-l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb;
- u_char tmp[128];
- u_char *p = tmp;
- u_char *teln;
- u_char *eaz;
- u_char channel = 0;
- int l;
-
- MsgHead(p, pc->callref, MT_N1_SETUP, PROTO_DIS_N1);
- teln = pc->para.setup.phone;
- pc->para.spv = 0;
- if (!isdigit(*teln)) {
- switch (0x5f & *teln) {
- case 'S':
- pc->para.spv = 1;
- break;
- case 'C':
- channel = 0x08;
- /* fall through */
- case 'P':
- channel |= 0x80;
- teln++;
- if (*teln == '1')
- channel |= 0x01;
- else
- channel |= 0x02;
- break;
- default:
- if (pc->st->l3.debug & L3_DEB_WARN)
- l3_debug(pc->st, "Wrong MSN Code");
- break;
- }
- teln++;
- }
- if (channel) {
- *p++ = 0x18; /* channel indicator */
- *p++ = 1;
- *p++ = channel;
- }
- if (pc->para.spv) { /* SPV ? */
- /* NSF SPV */
- *p++ = WE0_netSpecFac;
- *p++ = 4; /* Laenge */
- *p++ = 0;
- *p++ = FAC_SPV; /* SPV */
- *p++ = pc->para.setup.si1; /* 0 for all Services */
- *p++ = pc->para.setup.si2; /* 0 for all Services */
- *p++ = WE0_netSpecFac;
- *p++ = 4; /* Laenge */
- *p++ = 0;
- *p++ = FAC_Activate; /* aktiviere SPV (default) */
- *p++ = pc->para.setup.si1; /* 0 for all Services */
- *p++ = pc->para.setup.si2; /* 0 for all Services */
- }
- eaz = pc->para.setup.eazmsn;
- if (*eaz) {
- *p++ = WE0_origAddr;
- *p++ = strlen(eaz) + 1;
- /* Classify as AnyPref. */
- *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
- while (*eaz)
- *p++ = *eaz++ & 0x7f;
- }
- *p++ = WE0_destAddr;
- *p++ = strlen(teln) + 1;
- /* Classify as AnyPref. */
- *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
- while (*teln)
- *p++ = *teln++ & 0x7f;
-
- *p++ = WE_Shift_F6;
- /* Codesatz 6 fuer Service */
- *p++ = WE6_serviceInd;
- *p++ = 2; /* len=2 info,info2 */
- *p++ = pc->para.setup.si1;
- *p++ = pc->para.setup.si2;
-
- l = p - tmp;
- if (!(skb = l3_alloc_skb(l)))
- return;
- skb_put_data(skb, tmp, l);
- L3DelTimer(&pc->timer);
- L3AddTimer(&pc->timer, T303, CC_T303);
- newl3state(pc, 1);
- l3_msg(pc->st, DL_DATA | REQUEST, skb);
-}
-
-static void
-l3_1tr6_setup(struct l3_process *pc, u_char pr, void *arg)
-{
- u_char *p;
- int bcfound = 0;
- struct sk_buff *skb = arg;
-
- /* Channel Identification */
- p = findie(skb->data, skb->len, WE0_chanID, 0);
- if (p) {
- if (p[1] != 1) {
- l3_1tr6_error(pc, "setup wrong chanID len", skb);
- return;
- }
- if ((p[2] & 0xf4) != 0x80) {
- l3_1tr6_error(pc, "setup wrong WE0_chanID", skb);
- return;
- }
- if ((pc->para.bchannel = p[2] & 0x3))
- bcfound++;
- } else {
- l3_1tr6_error(pc, "missing setup chanID", skb);
- return;
- }
-
- p = skb->data;
- if ((p = findie(p, skb->len, WE6_serviceInd, 6))) {
- pc->para.setup.si1 = p[2];
- pc->para.setup.si2 = p[3];
- } else {
- l3_1tr6_error(pc, "missing setup SI", skb);
- return;
- }
-
- p = skb->data;
- if ((p = findie(p, skb->len, WE0_destAddr, 0)))
- iecpy(pc->para.setup.eazmsn, p, 1);
- else
- pc->para.setup.eazmsn[0] = 0;
-
- p = skb->data;
- if ((p = findie(p, skb->len, WE0_origAddr, 0))) {
- iecpy(pc->para.setup.phone, p, 1);
- } else
- pc->para.setup.phone[0] = 0;
-
- p = skb->data;
- pc->para.spv = 0;
- if ((p = findie(p, skb->len, WE0_netSpecFac, 0))) {
- if ((FAC_SPV == p[3]) || (FAC_Activate == p[3]))
- pc->para.spv = 1;
- }
- dev_kfree_skb(skb);
-
- /* Signal all services, linklevel takes care of Service-Indicator */
- if (bcfound) {
- if ((pc->para.setup.si1 != 7) && (pc->st->l3.debug & L3_DEB_WARN)) {
- l3_debug(pc->st, "non-digital call: %s -> %s",
- pc->para.setup.phone,
- pc->para.setup.eazmsn);
- }
- newl3state(pc, 6);
- pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc);
- } else
- release_l3_process(pc);
-}
-
-static void
-l3_1tr6_setup_ack(struct l3_process *pc, u_char pr, void *arg)
-{
- u_char *p;
- struct sk_buff *skb = arg;
-
- L3DelTimer(&pc->timer);
- p = skb->data;
- newl3state(pc, 2);
- if ((p = findie(p, skb->len, WE0_chanID, 0))) {
- if (p[1] != 1) {
- l3_1tr6_error(pc, "setup_ack wrong chanID len", skb);
- return;
- }
- if ((p[2] & 0xf4) != 0x80) {
- l3_1tr6_error(pc, "setup_ack wrong WE0_chanID", skb);
- return;
- }
- pc->para.bchannel = p[2] & 0x3;
- } else {
- l3_1tr6_error(pc, "missing setup_ack WE0_chanID", skb);
- return;
- }
- dev_kfree_skb(skb);
- L3AddTimer(&pc->timer, T304, CC_T304);
- pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
-}
-
-static void
-l3_1tr6_call_sent(struct l3_process *pc, u_char pr, void *arg)
-{
- u_char *p;
- struct sk_buff *skb = arg;
-
- L3DelTimer(&pc->timer);
- p = skb->data;
- if ((p = findie(p, skb->len, WE0_chanID, 0))) {
- if (p[1] != 1) {
- l3_1tr6_error(pc, "call sent wrong chanID len", skb);
- return;
- }
- if ((p[2] & 0xf4) != 0x80) {
- l3_1tr6_error(pc, "call sent wrong WE0_chanID", skb);
- return;
- }
- if ((pc->state == 2) && (pc->para.bchannel != (p[2] & 0x3))) {
- l3_1tr6_error(pc, "call sent wrong chanID value", skb);
- return;
- }
- pc->para.bchannel = p[2] & 0x3;
- } else {
- l3_1tr6_error(pc, "missing call sent WE0_chanID", skb);
- return;
- }
- dev_kfree_skb(skb);
- L3AddTimer(&pc->timer, T310, CC_T310);
- newl3state(pc, 3);
- pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc);
-}
-
-static void
-l3_1tr6_alert(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb = arg;
-
- dev_kfree_skb(skb);
- L3DelTimer(&pc->timer); /* T304 */
- newl3state(pc, 4);
- pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc);
-}
-
-static void
-l3_1tr6_info(struct l3_process *pc, u_char pr, void *arg)
-{
- u_char *p;
- int i, tmpcharge = 0;
- char a_charge[8];
- struct sk_buff *skb = arg;
-
- p = skb->data;
- if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) {
- iecpy(a_charge, p, 1);
- for (i = 0; i < strlen(a_charge); i++) {
- tmpcharge *= 10;
- tmpcharge += a_charge[i] & 0xf;
- }
- if (tmpcharge > pc->para.chargeinfo) {
- pc->para.chargeinfo = tmpcharge;
- pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
- }
- if (pc->st->l3.debug & L3_DEB_CHARGE) {
- l3_debug(pc->st, "charging info %d",
- pc->para.chargeinfo);
- }
- } else if (pc->st->l3.debug & L3_DEB_CHARGE)
- l3_debug(pc->st, "charging info not found");
- dev_kfree_skb(skb);
-
-}
-
-static void
-l3_1tr6_info_s2(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb = arg;
-
- dev_kfree_skb(skb);
-}
-
-static void
-l3_1tr6_connect(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb = arg;
-
- L3DelTimer(&pc->timer); /* T310 */
- if (!findie(skb->data, skb->len, WE6_date, 6)) {
- l3_1tr6_error(pc, "missing connect date", skb);
- return;
- }
- newl3state(pc, 10);
- dev_kfree_skb(skb);
- pc->para.chargeinfo = 0;
- pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc);
-}
-
-static void
-l3_1tr6_rel(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb = arg;
- u_char *p;
-
- p = skb->data;
- if ((p = findie(p, skb->len, WE0_cause, 0))) {
- if (p[1] > 0) {
- pc->para.cause = p[2];
- if (p[1] > 1)
- pc->para.loc = p[3];
- else
- pc->para.loc = 0;
- } else {
- pc->para.cause = 0;
- pc->para.loc = 0;
- }
- } else {
- pc->para.cause = NO_CAUSE;
- l3_1tr6_error(pc, "missing REL cause", skb);
- return;
- }
- dev_kfree_skb(skb);
- StopAllL3Timer(pc);
- newl3state(pc, 0);
- l3_1TR6_message(pc, MT_N1_REL_ACK, PROTO_DIS_N1);
- pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
- release_l3_process(pc);
-}
-
-static void
-l3_1tr6_rel_ack(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb = arg;
-
- dev_kfree_skb(skb);
- StopAllL3Timer(pc);
- newl3state(pc, 0);
- pc->para.cause = NO_CAUSE;
- pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc);
- release_l3_process(pc);
-}
-
-static void
-l3_1tr6_disc(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb = arg;
- u_char *p;
- int i, tmpcharge = 0;
- char a_charge[8];
-
- StopAllL3Timer(pc);
- p = skb->data;
- if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) {
- iecpy(a_charge, p, 1);
- for (i = 0; i < strlen(a_charge); i++) {
- tmpcharge *= 10;
- tmpcharge += a_charge[i] & 0xf;
- }
- if (tmpcharge > pc->para.chargeinfo) {
- pc->para.chargeinfo = tmpcharge;
- pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
- }
- if (pc->st->l3.debug & L3_DEB_CHARGE) {
- l3_debug(pc->st, "charging info %d",
- pc->para.chargeinfo);
- }
- } else if (pc->st->l3.debug & L3_DEB_CHARGE)
- l3_debug(pc->st, "charging info not found");
-
-
- p = skb->data;
- if ((p = findie(p, skb->len, WE0_cause, 0))) {
- if (p[1] > 0) {
- pc->para.cause = p[2];
- if (p[1] > 1)
- pc->para.loc = p[3];
- else
- pc->para.loc = 0;
- } else {
- pc->para.cause = 0;
- pc->para.loc = 0;
- }
- } else {
- if (pc->st->l3.debug & L3_DEB_WARN)
- l3_debug(pc->st, "cause not found");
- pc->para.cause = NO_CAUSE;
- }
- if (!findie(skb->data, skb->len, WE6_date, 6)) {
- l3_1tr6_error(pc, "missing connack date", skb);
- return;
- }
- dev_kfree_skb(skb);
- newl3state(pc, 12);
- pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
-}
-
-
-static void
-l3_1tr6_connect_ack(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb = arg;
-
- if (!findie(skb->data, skb->len, WE6_date, 6)) {
- l3_1tr6_error(pc, "missing connack date", skb);
- return;
- }
- dev_kfree_skb(skb);
- newl3state(pc, 10);
- pc->para.chargeinfo = 0;
- L3DelTimer(&pc->timer);
- pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc);
-}
-
-static void
-l3_1tr6_alert_req(struct l3_process *pc, u_char pr, void *arg)
-{
- newl3state(pc, 7);
- l3_1TR6_message(pc, MT_N1_ALERT, PROTO_DIS_N1);
-}
-
-static void
-l3_1tr6_setup_rsp(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb;
- u_char tmp[24];
- u_char *p = tmp;
- int l;
-
- MsgHead(p, pc->callref, MT_N1_CONN, PROTO_DIS_N1);
- if (pc->para.spv) { /* SPV ? */
- /* NSF SPV */
- *p++ = WE0_netSpecFac;
- *p++ = 4; /* Laenge */
- *p++ = 0;
- *p++ = FAC_SPV; /* SPV */
- *p++ = pc->para.setup.si1;
- *p++ = pc->para.setup.si2;
- *p++ = WE0_netSpecFac;
- *p++ = 4; /* Laenge */
- *p++ = 0;
- *p++ = FAC_Activate; /* aktiviere SPV */
- *p++ = pc->para.setup.si1;
- *p++ = pc->para.setup.si2;
- }
- newl3state(pc, 8);
- l = p - tmp;
- if (!(skb = l3_alloc_skb(l)))
- return;
- skb_put_data(skb, tmp, l);
- l3_msg(pc->st, DL_DATA | REQUEST, skb);
- L3DelTimer(&pc->timer);
- L3AddTimer(&pc->timer, T313, CC_T313);
-}
-
-static void
-l3_1tr6_reset(struct l3_process *pc, u_char pr, void *arg)
-{
- release_l3_process(pc);
-}
-
-static void
-l3_1tr6_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb;
- u_char tmp[16];
- u_char *p = tmp;
- int l;
- u_char cause = 0x10;
- u_char clen = 1;
-
- if (pc->para.cause > 0)
- cause = pc->para.cause;
- /* Map DSS1 causes */
- switch (cause & 0x7f) {
- case 0x10:
- clen = 0;
- break;
- case 0x11:
- cause = CAUSE_UserBusy;
- break;
- case 0x15:
- cause = CAUSE_CallRejected;
- break;
- }
- StopAllL3Timer(pc);
- MsgHead(p, pc->callref, MT_N1_DISC, PROTO_DIS_N1);
- *p++ = WE0_cause;
- *p++ = clen; /* Laenge */
- if (clen)
- *p++ = cause | 0x80;
- newl3state(pc, 11);
- l = p - tmp;
- if (!(skb = l3_alloc_skb(l)))
- return;
- skb_put_data(skb, tmp, l);
- l3_msg(pc->st, DL_DATA | REQUEST, skb);
- L3AddTimer(&pc->timer, T305, CC_T305);
-}
-
-static void
-l3_1tr6_t303(struct l3_process *pc, u_char pr, void *arg)
-{
- if (pc->N303 > 0) {
- pc->N303--;
- L3DelTimer(&pc->timer);
- l3_1tr6_setup_req(pc, pr, arg);
- } else {
- L3DelTimer(&pc->timer);
- pc->para.cause = 0;
- l3_1tr6_disconnect_req(pc, 0, NULL);
- }
-}
-
-static void
-l3_1tr6_t304(struct l3_process *pc, u_char pr, void *arg)
-{
- L3DelTimer(&pc->timer);
- pc->para.cause = 0xE6;
- l3_1tr6_disconnect_req(pc, pr, NULL);
- pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
-}
-
-static void
-l3_1tr6_t305(struct l3_process *pc, u_char pr, void *arg)
-{
- struct sk_buff *skb;
- u_char tmp[16];
- u_char *p = tmp;
- int l;
- u_char cause = 0x90;
- u_char clen = 1;
-
- L3DelTimer(&pc->timer);
- if (pc->para.cause != NO_CAUSE)
- cause = pc->para.cause;
- /* Map DSS1 causes */
- switch (cause & 0x7f) {
- case 0x10:
- clen = 0;
- break;
- case 0x15:
- cause = CAUSE_CallRejected;
- break;
- }
- MsgHead(p, pc->callref, MT_N1_REL, PROTO_DIS_N1);
- *p++ = WE0_cause;
- *p++ = clen; /* Laenge */
- if (clen)
- *p++ = cause;
- newl3state(pc, 19);
- l = p - tmp;
- if (!(skb = l3_alloc_skb(l)))
- return;
- skb_put_data(skb, tmp, l);
- l3_msg(pc->st, DL_DATA | REQUEST, skb);
- L3AddTimer(&pc->timer, T308, CC_T308_1);
-}
-
-static void
-l3_1tr6_t310(struct l3_process *pc, u_char pr, void *arg)
-{
- L3DelTimer(&pc->timer);
- pc->para.cause = 0xE6;
- l3_1tr6_disconnect_req(pc, pr, NULL);
- pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
-}
-
-static void
-l3_1tr6_t313(struct l3_process *pc, u_char pr, void *arg)
-{
- L3DelTimer(&pc->timer);
- pc->para.cause = 0xE6;
- l3_1tr6_disconnect_req(pc, pr, NULL);
- pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc);
-}
-
-static void
-l3_1tr6_t308_1(struct l3_process *pc, u_char pr, void *arg)
-{
- L3DelTimer(&pc->timer);
- l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1);
- L3AddTimer(&pc->timer, T308, CC_T308_2);
- newl3state(pc, 19);
-}
-
-static void
-l3_1tr6_t308_2(struct l3_process *pc, u_char pr, void *arg)
-{
- L3DelTimer(&pc->timer);
- pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc);
- release_l3_process(pc);
-}
-
-static void
-l3_1tr6_dl_reset(struct l3_process *pc, u_char pr, void *arg)
-{
- pc->para.cause = CAUSE_LocalProcErr;
- l3_1tr6_disconnect_req(pc, pr, NULL);
- pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
-}
-
-static void
-l3_1tr6_dl_release(struct l3_process *pc, u_char pr, void *arg)
-{
- newl3state(pc, 0);
- pc->para.cause = 0x1b; /* Destination out of order */
- pc->para.loc = 0;
- pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
- release_l3_process(pc);
-}
-
-/* *INDENT-OFF* */
-static struct stateentry downstl[] =
-{
- {SBIT(0),
- CC_SETUP | REQUEST, l3_1tr6_setup_req},
- {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) |
- SBIT(10),
- CC_DISCONNECT | REQUEST, l3_1tr6_disconnect_req},
- {SBIT(12),
- CC_RELEASE | REQUEST, l3_1tr6_release_req},
- {SBIT(6),
- CC_IGNORE | REQUEST, l3_1tr6_reset},
- {SBIT(6),
- CC_REJECT | REQUEST, l3_1tr6_disconnect_req},
- {SBIT(6),
- CC_ALERTING | REQUEST, l3_1tr6_alert_req},
- {SBIT(6) | SBIT(7),
- CC_SETUP | RESPONSE, l3_1tr6_setup_rsp},
- {SBIT(1),
- CC_T303, l3_1tr6_t303},
- {SBIT(2),
- CC_T304, l3_1tr6_t304},
- {SBIT(3),
- CC_T310, l3_1tr6_t310},
- {SBIT(8),
- CC_T313, l3_1tr6_t313},
- {SBIT(11),
- CC_T305, l3_1tr6_t305},
- {SBIT(19),
- CC_T308_1, l3_1tr6_t308_1},
- {SBIT(19),
- CC_T308_2, l3_1tr6_t308_2},
-};
-
-static struct stateentry datastln1[] =
-{
- {SBIT(0),
- MT_N1_INVALID, l3_1tr6_invalid},
- {SBIT(0),
- MT_N1_SETUP, l3_1tr6_setup},
- {SBIT(1),
- MT_N1_SETUP_ACK, l3_1tr6_setup_ack},
- {SBIT(1) | SBIT(2),
- MT_N1_CALL_SENT, l3_1tr6_call_sent},
- {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
- MT_N1_DISC, l3_1tr6_disc},
- {SBIT(2) | SBIT(3) | SBIT(4),
- MT_N1_ALERT, l3_1tr6_alert},
- {SBIT(2) | SBIT(3) | SBIT(4),
- MT_N1_CONN, l3_1tr6_connect},
- {SBIT(2),
- MT_N1_INFO, l3_1tr6_info_s2},
- {SBIT(8),
- MT_N1_CONN_ACK, l3_1tr6_connect_ack},
- {SBIT(10),
- MT_N1_INFO, l3_1tr6_info},
- {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
- SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
- MT_N1_REL, l3_1tr6_rel},
- {SBIT(19),
- MT_N1_REL, l3_1tr6_rel_ack},
- {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
- SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
- MT_N1_REL_ACK, l3_1tr6_invalid},
- {SBIT(19),
- MT_N1_REL_ACK, l3_1tr6_rel_ack}
-};
-
-static struct stateentry manstatelist[] =
-{
- {SBIT(2),
- DL_ESTABLISH | INDICATION, l3_1tr6_dl_reset},
- {ALL_STATES,
- DL_RELEASE | INDICATION, l3_1tr6_dl_release},
-};
-
-/* *INDENT-ON* */
-
-static void
-up1tr6(struct PStack *st, int pr, void *arg)
-{
- int i, mt, cr;
- struct l3_process *proc;
- struct sk_buff *skb = arg;
-
- switch (pr) {
- case (DL_DATA | INDICATION):
- case (DL_UNIT_DATA | INDICATION):
- break;
- case (DL_ESTABLISH | CONFIRM):
- case (DL_ESTABLISH | INDICATION):
- case (DL_RELEASE | INDICATION):
- case (DL_RELEASE | CONFIRM):
- l3_msg(st, pr, arg);
- return;
- break;
- }
- if (skb->len < 4) {
- if (st->l3.debug & L3_DEB_PROTERR) {
- l3_debug(st, "up1tr6 len only %d", skb->len);
- }
- dev_kfree_skb(skb);
- return;
- }
- if ((skb->data[0] & 0xfe) != PROTO_DIS_N0) {
- if (st->l3.debug & L3_DEB_PROTERR) {
- l3_debug(st, "up1tr6%sunexpected discriminator %x message len %d",
- (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
- skb->data[0], skb->len);
- }
- dev_kfree_skb(skb);
- return;
- }
- if (skb->data[1] != 1) {
- if (st->l3.debug & L3_DEB_PROTERR) {
- l3_debug(st, "up1tr6 CR len not 1");
- }
- dev_kfree_skb(skb);
- return;
- }
- cr = skb->data[2];
- mt = skb->data[3];
- if (skb->data[0] == PROTO_DIS_N0) {
- dev_kfree_skb(skb);
- if (st->l3.debug & L3_DEB_STATE) {
- l3_debug(st, "up1tr6%s N0 mt %x unhandled",
- (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt);
- }
- } else if (skb->data[0] == PROTO_DIS_N1) {
- if (!(proc = getl3proc(st, cr))) {
- if (mt == MT_N1_SETUP) {
- if (cr < 128) {
- if (!(proc = new_l3_process(st, cr))) {
- if (st->l3.debug & L3_DEB_PROTERR) {
- l3_debug(st, "up1tr6 no roc mem");
- }
- dev_kfree_skb(skb);
- return;
- }
- } else {
- dev_kfree_skb(skb);
- return;
- }
- } else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) ||
- (mt == MT_N1_CANC_ACK) || (mt == MT_N1_CANC_REJ) ||
- (mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) ||
- (mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) ||
- (mt == MT_N1_INFO)) {
- dev_kfree_skb(skb);
- return;
- } else {
- if (!(proc = new_l3_process(st, cr))) {
- if (st->l3.debug & L3_DEB_PROTERR) {
- l3_debug(st, "up1tr6 no roc mem");
- }
- dev_kfree_skb(skb);
- return;
- }
- mt = MT_N1_INVALID;
- }
- }
- for (i = 0; i < ARRAY_SIZE(datastln1); i++)
- if ((mt == datastln1[i].primitive) &&
- ((1 << proc->state) & datastln1[i].state))
- break;
- if (i == ARRAY_SIZE(datastln1)) {
- dev_kfree_skb(skb);
- if (st->l3.debug & L3_DEB_STATE) {
- l3_debug(st, "up1tr6%sstate %d mt %x unhandled",
- (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
- proc->state, mt);
- }
- return;
- } else {
- if (st->l3.debug & L3_DEB_STATE) {
- l3_debug(st, "up1tr6%sstate %d mt %x",
- (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
- proc->state, mt);
- }
- datastln1[i].rout(proc, pr, skb);
- }
- }
-}
-
-static void
-down1tr6(struct PStack *st, int pr, void *arg)
-{
- int i, cr;
- struct l3_process *proc;
- struct Channel *chan;
-
- if ((DL_ESTABLISH | REQUEST) == pr) {
- l3_msg(st, pr, NULL);
- return;
- } else if ((CC_SETUP | REQUEST) == pr) {
- chan = arg;
- cr = newcallref();
- cr |= 0x80;
- if (!(proc = new_l3_process(st, cr))) {
- return;
- } else {
- proc->chan = chan;
- chan->proc = proc;
- memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm));
- proc->callref = cr;
- }
- } else {
- proc = arg;
- }
-
- for (i = 0; i < ARRAY_SIZE(downstl); i++)
- if ((pr == downstl[i].primitive) &&
- ((1 << proc->state) & downstl[i].state))
- break;
- if (i == ARRAY_SIZE(downstl)) {
- if (st->l3.debug & L3_DEB_STATE) {
- l3_debug(st, "down1tr6 state %d prim %d unhandled",
- proc->state, pr);
- }
- } else {
- if (st->l3.debug & L3_DEB_STATE) {
- l3_debug(st, "down1tr6 state %d prim %d",
- proc->state, pr);
- }
- downstl[i].rout(proc, pr, arg);
- }
-}
-
-static void
-man1tr6(struct PStack *st, int pr, void *arg)
-{
- int i;
- struct l3_process *proc = arg;
-
- if (!proc) {
- printk(KERN_ERR "HiSax man1tr6 without proc pr=%04x\n", pr);
- return;
- }
- for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
- if ((pr == manstatelist[i].primitive) &&
- ((1 << proc->state) & manstatelist[i].state))
- break;
- if (i == ARRAY_SIZE(manstatelist)) {
- if (st->l3.debug & L3_DEB_STATE) {
- l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled",
- proc->callref & 0x7f, proc->state, pr);
- }
- } else {
- if (st->l3.debug & L3_DEB_STATE) {
- l3_debug(st, "cr %d man1tr6 state %d prim %d",
- proc->callref & 0x7f, proc->state, pr);
- }
- manstatelist[i].rout(proc, pr, arg);
- }
-}
-
-void
-setstack_1tr6(struct PStack *st)
-{
- char tmp[64];
-
- st->lli.l4l3 = down1tr6;
- st->l2.l2l3 = up1tr6;
- st->l3.l3ml3 = man1tr6;
- st->l3.N303 = 0;
-
- strcpy(tmp, l3_1tr6_revision);
- printk(KERN_INFO "HiSax: 1TR6 Rev. %s\n", HiSax_getrev(tmp));
-}