Add the ISDN itjc hardware driver. This driver supports the NETJet-S cards
from Traverse Technology and also the Teles PCI-TJ cards both based on the chipset combination of the Siemens ISAC and the TJNet Tiger300/320 chips. The itjc/i4b_hdlc.h file will hopefully soon be merged with the file /usr/src/sys/i4b/layer1/i4b_hdlc.h. Submitted by: Sergio de Souza Prallon <prallon@tmp.com.br>
This commit is contained in:
parent
6624680fec
commit
2fbe70cb49
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Hellmuth Michaelis. All rights reserved.
|
||||
* Copyright (c) 2000, 2001 Hellmuth Michaelis. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -27,11 +27,9 @@
|
||||
* i4b_l1.h - isdn4bsd layer 1 header file
|
||||
* ---------------------------------------
|
||||
*
|
||||
* $Id: i4b_l1.h,v 1.15 2000/06/02 16:14:36 hm Exp $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* last edit-date: [Thu Oct 26 08:42:44 2000]
|
||||
* last edit-date: [Wed Jan 10 16:42:27 2001]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -71,6 +69,7 @@
|
||||
#define FLAG_ACER_P10 26
|
||||
#define FLAG_TELEINT_NO_1 27
|
||||
#define FLAG_CCD_HFCS_PCI 28
|
||||
#define FLAG_NETJET_S 29
|
||||
|
||||
#define SEC_DELAY 1000000 /* one second DELAY for DELAY*/
|
||||
|
||||
@ -91,6 +90,7 @@
|
||||
#define L0IHFCUNIT(u) ( (((L1DRVR_IHFC) << 8) & 0xff00) | ((u) & 0xff))
|
||||
#define L0IFPNPUNIT(u) ( (((L1DRVR_IFPNP) << 8) & 0xff00) | ((u) & 0xff))
|
||||
#define L0ICCHPUNIT(u) ( (((L1DRVR_ICCHP) << 8) & 0xff00) | ((u) & 0xff))
|
||||
#define L0ITJCUNIT(u) ( (((L1DRVR_ITJC) << 8) & 0xff00) | ((u) & 0xff))
|
||||
|
||||
/* jump table for the multiplex functions */
|
||||
struct i4b_l1mux_func {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Hellmuth Michaelis. All rights reserved.
|
||||
* Copyright (c) 2000, 2001 Hellmuth Michaelis. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -27,11 +27,9 @@
|
||||
* i4b_l1dmux.c - isdn4bsd layer 1 driver multiplexer
|
||||
* --------------------------------------------------
|
||||
*
|
||||
* $Id: i4b_l1dmux.c,v 1.12 2000/06/02 16:14:36 hm Exp $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* last edit-date: [Fri Jun 2 14:37:39 2000]
|
||||
* last edit-date: [Wed Jan 10 16:43:24 2001]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -40,11 +38,11 @@
|
||||
#include "ifpi.h"
|
||||
#include "ifpnp.h"
|
||||
#include "ihfc.h"
|
||||
#include "itjc.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
|
||||
#include <machine/i4b_debug.h>
|
||||
#include <machine/i4b_ioctl.h>
|
||||
#include <machine/i4b_trace.h>
|
||||
@ -105,6 +103,10 @@ static int l1ihfcunittab[MAXL1UNITS];
|
||||
static int l1ifpnpunittab[MAXL1UNITS];
|
||||
#endif
|
||||
|
||||
#if NITJC > 0
|
||||
static int l1itjcunittab[MAXL1UNITS];
|
||||
#endif
|
||||
|
||||
static int numl1units = 0;
|
||||
|
||||
static int l1drvunittab[MAXL1UNITS];
|
||||
@ -184,6 +186,11 @@ getl1tab(int drv)
|
||||
case L1DRVR_IFPNP:
|
||||
return(l1ifpnpunittab);
|
||||
break;
|
||||
#endif
|
||||
#if NITJC > 0
|
||||
case L1DRVR_ITJC:
|
||||
return(l1itjcunittab);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return(NULL);
|
||||
@ -316,6 +323,12 @@ i4b_l1_mph_status_ind(int drv_unit, int status, int parm, struct i4b_l1mux_func
|
||||
#if NIHFC > 0
|
||||
case L1DRVR_IHFC:
|
||||
printf("ihfc%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units);
|
||||
break;
|
||||
#endif
|
||||
#if NITJC > 0
|
||||
case L1DRVR_ITJC:
|
||||
printf("itjc%d: passive stack unit %d\n", L0UNIT(drv_unit), numl1units);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
412
sys/i4b/layer1/itjc/i4b_hdlc.h
Normal file
412
sys/i4b/layer1/itjc/i4b_hdlc.h
Normal file
@ -0,0 +1,412 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Hans Petter Selasky. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* i4b_hdlc.h - software-HDLC header file
|
||||
* --------------------------------------
|
||||
*
|
||||
* $Id: i4b_hdlc.h,v 1.5 2000/08/28 07:41:19 hm Exp $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* last edit-date: [Thu Jan 11 11:31:01 2001]
|
||||
*
|
||||
* Please conform "ihfc/i4b_ihfc_drv.c" (ihfc_hdlc_Bxxxx)
|
||||
* for correct usage! (-hp)
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _I4B_HDLC_H_
|
||||
#define _I4B_HDLC_H_
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* HDLC CRC table
|
||||
*
|
||||
* Usage:
|
||||
* crc = (HDLC_FCS_TAB[(u_char)(crc ^ byte of data)] ^ (u_char)(crc >> 8));
|
||||
*
|
||||
* For more information see RFC 1662 (p. 10)
|
||||
*---------------------------------------------------------------------------*/
|
||||
static const u_short HDLC_FCS_TAB[256] = { 0x0000,
|
||||
0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48,
|
||||
0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081,
|
||||
0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9,
|
||||
0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102,
|
||||
0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a,
|
||||
0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183,
|
||||
0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb,
|
||||
0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204,
|
||||
0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c,
|
||||
0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285,
|
||||
0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd,
|
||||
0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306,
|
||||
0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e,
|
||||
0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387,
|
||||
0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf,
|
||||
0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408,
|
||||
0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840,
|
||||
0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489,
|
||||
0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1,
|
||||
0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a,
|
||||
0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942,
|
||||
0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b,
|
||||
0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3,
|
||||
0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c,
|
||||
0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44,
|
||||
0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d,
|
||||
0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5,
|
||||
0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e,
|
||||
0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46,
|
||||
0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f,
|
||||
0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7,
|
||||
0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* HDLC bit table
|
||||
* ==============
|
||||
*
|
||||
* bits[0..3]: A value which tells how many set bits there are at the
|
||||
* beginning of the byte.
|
||||
*
|
||||
* bits[4..7]: Special bytes like 0x7e, 0x7d, 0xfd ... are flagged here
|
||||
* NOTE: Special bytes also means 'abort' bytes (7 or more
|
||||
* continuous set bits)
|
||||
*
|
||||
* bits[8..11]: A copy of bits[0..3] but only incremented by one.
|
||||
* NOTE: 0x7e has value '8' instead of '0'. Internal reasons.
|
||||
*
|
||||
* bits[12..15]: A value which tells how many set bits there are at the
|
||||
* end of the byte.
|
||||
* NOTE: 0xff has both '8' incoming and '8' outgoing bits.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
static const u_short HDLC_BIT_TAB[256] = { 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0605, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0160, 0x0706, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0605, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100,
|
||||
0x0201, 0x0100, 0x0302, 0x01a0, 0x02a1, 0x0860, 0x0807, 0x1100,
|
||||
0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100,
|
||||
0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1504, 0x1100,
|
||||
0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100,
|
||||
0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1605, 0x1100,
|
||||
0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100,
|
||||
0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1504, 0x1100,
|
||||
0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100,
|
||||
0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1160, 0x1706, 0x2100,
|
||||
0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2403, 0x2100,
|
||||
0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2504, 0x2100,
|
||||
0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2403, 0x2100,
|
||||
0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2605, 0x3100,
|
||||
0x3201, 0x3100, 0x3302, 0x3100, 0x3201, 0x3100, 0x3403, 0x3100,
|
||||
0x3201, 0x3100, 0x3302, 0x3100, 0x3201, 0x3100, 0x3504, 0x4100,
|
||||
0x4201, 0x4100, 0x4302, 0x4100, 0x4201, 0x4100, 0x4403, 0x5100,
|
||||
0x5201, 0x5100, 0x5302, 0x6180, 0x6281, 0x7150, 0x8908
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* HDLC_DECODE
|
||||
* ===========
|
||||
*
|
||||
* u_char: flag, blevel
|
||||
* u_short: crc, ib, tmp, tmp2, len
|
||||
*
|
||||
* next: 'continue' or 'goto xxx'
|
||||
*
|
||||
* cfr: complete frame
|
||||
* nfr: new frame
|
||||
* NOTE: must setup 'len' and 'dst', so that 'dst' may be written
|
||||
* at most 'len' times.
|
||||
*
|
||||
* rab: abort
|
||||
* rdd: read data (read byte is stored in 'tmp2')
|
||||
* rdo: overflow
|
||||
*
|
||||
* d: dummy
|
||||
*
|
||||
* NOTE: setting flag to '0' and len to '0' => recover from rdu
|
||||
* NOTE: bits[8 .. ] of tmp2 may be used to store custom data/flags
|
||||
* NOTE: these variables have to be 'suspended' / 'resumed' somehow:
|
||||
* flag, blevel, crc, ib, tmp, len
|
||||
* NOTE: zero is default value for all variables.
|
||||
* NOTE: each time 'dst' is written, 'len' is decreased by one.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#define HDLC_DECODE(dst, len, tmp, tmp2, blevel, ib, crc, flag, rddcmd, nfrcmd, \
|
||||
cfrcmd, rabcmd, rdocmd, nextcmd, d) \
|
||||
\
|
||||
rddcmd; \
|
||||
\
|
||||
ib += HDLC_BIT_TAB[(u_char)tmp2]; \
|
||||
\
|
||||
if ((u_char)ib >= 5) \
|
||||
{ \
|
||||
if (ib & 0x20) /* de-stuff (msb) */ \
|
||||
{ \
|
||||
if ((u_char)tmp2 == 0x7e) goto j0##d; \
|
||||
tmp2 += tmp2 & 0x7f; \
|
||||
blevel--; \
|
||||
\
|
||||
if ((ib += 0x100) & 0xc) tmp2 |= 1; /* */ \
|
||||
} \
|
||||
\
|
||||
ib &= ~0xe0; \
|
||||
\
|
||||
if ((u_char)ib == 6) /* flag seq (lsb) */ \
|
||||
{ \
|
||||
j0##d: if (flag >= 2) \
|
||||
{ \
|
||||
len += (4 - flag) & 3; /* remove CRC bytes */ \
|
||||
crc ^= 0xf0b8; \
|
||||
cfrcmd; \
|
||||
len = 0; \
|
||||
} \
|
||||
\
|
||||
flag = 1; \
|
||||
\
|
||||
blevel = (ib >> 8) & 0xf; \
|
||||
tmp = ((u_char)tmp2) >> blevel; \
|
||||
blevel = 8 - blevel; \
|
||||
\
|
||||
ib >>= 12; \
|
||||
\
|
||||
nextcmd; \
|
||||
} \
|
||||
if ((u_char)ib >= 7) /* abort (msb & lsb) */ \
|
||||
{ \
|
||||
if (flag >= 2) \
|
||||
{ \
|
||||
rabcmd; \
|
||||
len = 0; \
|
||||
} \
|
||||
\
|
||||
flag = 0; \
|
||||
\
|
||||
ib >>= 12; \
|
||||
\
|
||||
nextcmd; \
|
||||
} \
|
||||
if ((u_char)ib == 5) /* de-stuff (lsb) */ \
|
||||
{ \
|
||||
tmp2 = (tmp2 | (tmp2 + 1)) & ~0x1; \
|
||||
blevel--; \
|
||||
} \
|
||||
if (blevel > 7) /* EO - bits */ \
|
||||
{ \
|
||||
tmp |= (u_char)tmp2 >> (8 - (blevel &= 7)); \
|
||||
\
|
||||
ib >>= 12; \
|
||||
\
|
||||
nextcmd; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
tmp |= (u_char)tmp2 << blevel; \
|
||||
\
|
||||
if (!len--) \
|
||||
{ \
|
||||
len++; \
|
||||
\
|
||||
if (!flag++) { flag--; goto j5##d;} /* hunt mode */ \
|
||||
\
|
||||
switch (flag) \
|
||||
{ case 2: /* new frame */ \
|
||||
nfrcmd; \
|
||||
crc = -1; \
|
||||
if (!len--) { len++; flag++; goto j4##d; } \
|
||||
goto j3##d; \
|
||||
case 3: /* CRC (lsb's) */ \
|
||||
case 4: /* CRC (msb's) */ \
|
||||
goto j4##d; \
|
||||
case 5: /* RDO */ \
|
||||
rdocmd; \
|
||||
flag = 0; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
j3##d: dst = (u_char)tmp; \
|
||||
j4##d: crc = (HDLC_FCS_TAB[(u_char)(tmp ^ crc)] ^ (u_char)(crc >> 8)); \
|
||||
} \
|
||||
\
|
||||
j5##d: ib >>= 12; \
|
||||
tmp >>= 8; \
|
||||
|
||||
/*------ end of HDLC_DECODE -------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* HDLC_ENCODE
|
||||
* ===========
|
||||
*
|
||||
* u_char: flag, src
|
||||
* u_short: tmp2, blevel, ib, crc, len
|
||||
* u_int: tmp
|
||||
*
|
||||
* gfr: This is the place where you free the last [mbuf] chain, and get
|
||||
* the next one. If a mbuf is available the code should setup 'len'
|
||||
* and 'src' so that 'src' may be read 'len' times. If no mbuf is
|
||||
* available leave 'len' and 'src' untouched.
|
||||
*
|
||||
* nmb: If your implementation accept/use chained mbufs, this is the
|
||||
* place where you update 'len' and 'src' to the next mbuf of
|
||||
* the chain that makes up a frame. If no further mbuf is
|
||||
* available leave 'len' and 'src' untouched. This is not the
|
||||
* place where you free the mbuf. Leave the block empty if your
|
||||
* implementation does not accept/use chained mbufs.
|
||||
*
|
||||
* wrd: write data (output = (u_char)tmp)
|
||||
*
|
||||
* d: dummy
|
||||
*
|
||||
* NOTE: setting flag to '-2' and len to '0' => abort bytes will be sent
|
||||
* NOTE: these variables have to be 'suspended' / 'resumed' somehow:
|
||||
* flag, blevel, crc, ib, tmp, len
|
||||
* NOTE: zero is default value for all variables.
|
||||
* NOTE: each time 'src' is read, 'len' is decreased by one.
|
||||
* NOTE: neither cmd's should exit through 'goto' or 'break' statements.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#define HDLC_ENCODE(src, len, tmp, tmp2, blevel, ib, crc, flag, gfrcmd, nmbcmd, wrdcmd, d) \
|
||||
\
|
||||
if (blevel >= 0x800) { blevel -= 0x800; goto j4##d; } \
|
||||
\
|
||||
if (!len--) \
|
||||
{ \
|
||||
len++; \
|
||||
\
|
||||
switch(++flag) \
|
||||
{ default: /* abort */ \
|
||||
tmp = blevel = 0; /* zero is default */ \
|
||||
tmp2 = 0xff; \
|
||||
goto j3##d; \
|
||||
case 1: /* 1st time FS */ \
|
||||
case 2: /* 2nd time FS */ \
|
||||
tmp2 = 0x7e; \
|
||||
goto j3##d; \
|
||||
case 3: \
|
||||
gfrcmd; /* get new frame */ \
|
||||
if (!len--) \
|
||||
{ \
|
||||
len++; \
|
||||
flag--; /* don't proceed */ \
|
||||
tmp2 = 0x7e; \
|
||||
goto j3##d; /* final FS */ \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
crc = -1; \
|
||||
ib = 0; \
|
||||
goto j1##d; /* first byte */ \
|
||||
} \
|
||||
case 4: \
|
||||
nmbcmd; /* get next mbuf in chain */ \
|
||||
if (!len--) \
|
||||
{ \
|
||||
len++; \
|
||||
crc ^= -1; \
|
||||
tmp2 = (u_char)crc; \
|
||||
goto j2##d; /* CRC (lsb's) */ \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
flag--; \
|
||||
goto j1##d; /* proceed with the frame */ \
|
||||
} \
|
||||
case 5: \
|
||||
tmp2 = (u_char)(crc >> 8); \
|
||||
flag = 1; \
|
||||
goto j2##d; /* CRC (msb's) */ \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ j1##d : \
|
||||
tmp2 = (u_char)src; \
|
||||
crc =(HDLC_FCS_TAB[(u_char)(crc ^ tmp2)] ^ (u_char)(crc >> 8)); \
|
||||
j2##d: \
|
||||
\
|
||||
ib >>= 12; \
|
||||
ib += HDLC_BIT_TAB[(u_char)tmp2]; \
|
||||
\
|
||||
if ((u_char)ib >= 5) /* stuffing */ \
|
||||
{ \
|
||||
blevel &= ~0xff; \
|
||||
\
|
||||
if (ib & 0xc0) /* bit stuff (msb) */ \
|
||||
{ \
|
||||
tmp2 += tmp2 & (0xff * (ib & 0xc0)); \
|
||||
ib %= 0x5000; \
|
||||
blevel++; \
|
||||
} \
|
||||
\
|
||||
ib &= ~0xf0; \
|
||||
\
|
||||
if ((u_char)ib >= 5) /* bit stuff (lsb) */ \
|
||||
{ \
|
||||
tmp2 += tmp2 & ~0x1f >> ((ib - (ib >> 8) + 1) \
|
||||
& 7); \
|
||||
blevel++; \
|
||||
\
|
||||
if ((u_char)ib >= 10) /* bit stuff (msb) */ \
|
||||
{ \
|
||||
tmp2 += tmp2 & ~0x7ff >> ((ib - \
|
||||
(ib >> 8) + 1) & 7); \
|
||||
blevel++; \
|
||||
} \
|
||||
if (ib & 0x8000) /* bit walk */ \
|
||||
{ \
|
||||
ib = ((u_char)ib % 5) << 12; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
tmp |= tmp2 << (u_char)(blevel >> 8); \
|
||||
blevel += (u_char)blevel << 8; \
|
||||
} \
|
||||
else /* no stuffing */ \
|
||||
{ \
|
||||
j3##d:tmp |= tmp2 << (u_char)(blevel >> 8); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
j4##d: wrdcmd; \
|
||||
tmp >>= 8; \
|
||||
|
||||
/*------ end of HDLC_ENCODE -------------------------------------------------*/
|
||||
|
||||
|
||||
#endif /* _I4B_HDLC_H_ */
|
59
sys/i4b/layer1/itjc/i4b_itjc_ext.h
Normal file
59
sys/i4b/layer1/itjc/i4b_itjc_ext.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Sergio Prallon. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* i4b_itjc - NetJet PCI for split layers
|
||||
* ------------------------------------------
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* last edit-date: [Wed Jan 10 17:15:31 2001]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _I4B_ITJC_EXT_H_
|
||||
#define _I4B_ITJC_EXT_H_
|
||||
|
||||
#include <i4b/include/i4b_l3l4.h>
|
||||
|
||||
void itjc_set_linktab(int unit, int channel, drvr_link_t * dlt);
|
||||
isdn_link_t *itjc_ret_linktab(int unit, int channel);
|
||||
|
||||
int itjc_ph_data_req(int unit, struct mbuf *m, int freeflag);
|
||||
int itjc_ph_activate_req(int unit);
|
||||
int itjc_mph_command_req(int unit, int command, void *parm);
|
||||
|
||||
void itjc_isac_irq(struct l1_softc *sc, int ista);
|
||||
void itjc_isac_l1_cmd(struct l1_softc *sc, int command);
|
||||
int itjc_isac_init(struct l1_softc *sc);
|
||||
|
||||
void itjc_recover(struct l1_softc *sc);
|
||||
char * itjc_printstate(struct l1_softc *sc);
|
||||
void itjc_next_state(struct l1_softc *sc, int event);
|
||||
|
||||
#define ITJC_MAXUNIT 4
|
||||
extern struct l1_softc *itjc_scp[ITJC_MAXUNIT];
|
||||
|
||||
#endif /* _I4B_ITJC_EXT_H_ */
|
552
sys/i4b/layer1/itjc/i4b_itjc_isac.c
Normal file
552
sys/i4b/layer1/itjc/i4b_itjc_isac.c
Normal file
@ -0,0 +1,552 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* i4b_itjc_isac.c - i4b NetJet-S ISAC handler
|
||||
* --------------------------------------------
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* last edit-date: [Wed Jan 10 17:15:54 2001]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "itjc.h"
|
||||
#include "pci.h"
|
||||
|
||||
#if (NITJC > 0)
|
||||
|
||||
#include "opt_i4b.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <machine/i4b_debug.h>
|
||||
#include <machine/i4b_ioctl.h>
|
||||
#include <machine/i4b_trace.h>
|
||||
|
||||
#include <i4b/layer1/i4b_l1.h>
|
||||
|
||||
#include <i4b/layer1/isic/i4b_isic.h>
|
||||
#include <i4b/layer1/isic/i4b_isac.h>
|
||||
|
||||
#include <i4b/layer1/itjc/i4b_itjc_ext.h>
|
||||
|
||||
#include <i4b/include/i4b_global.h>
|
||||
#include <i4b/include/i4b_mbuf.h>
|
||||
|
||||
static u_char itjc_isac_exir_hdlr(register struct l1_softc *sc, u_char exir);
|
||||
static void itjc_isac_ind_hdlr(register struct l1_softc *sc, int ind);
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* ISAC interrupt service routine
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
itjc_isac_irq(struct l1_softc *sc, int ista)
|
||||
{
|
||||
register u_char c = 0;
|
||||
NDBGL1(L1_F_MSG, "unit %d: ista = 0x%02x", sc->sc_unit, ista);
|
||||
|
||||
if(ista & ISAC_ISTA_EXI) /* extended interrupt */
|
||||
{
|
||||
c |= itjc_isac_exir_hdlr(sc, ISAC_READ(I_EXIR));
|
||||
}
|
||||
|
||||
if(ista & ISAC_ISTA_RME) /* receive message end */
|
||||
{
|
||||
register int rest;
|
||||
u_char rsta;
|
||||
|
||||
/* get rx status register */
|
||||
|
||||
rsta = ISAC_READ(I_RSTA);
|
||||
|
||||
if((rsta & ISAC_RSTA_MASK) != 0x20)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if(!(rsta & ISAC_RSTA_CRC)) /* CRC error */
|
||||
{
|
||||
error++;
|
||||
NDBGL1(L1_I_ERR, "unit %d: CRC error", sc->sc_unit);
|
||||
}
|
||||
|
||||
if(rsta & ISAC_RSTA_RDO) /* ReceiveDataOverflow */
|
||||
{
|
||||
error++;
|
||||
NDBGL1(L1_I_ERR, "unit %d: Data Overrun error", sc->sc_unit);
|
||||
}
|
||||
|
||||
if(rsta & ISAC_RSTA_RAB) /* ReceiveABorted */
|
||||
{
|
||||
error++;
|
||||
NDBGL1(L1_I_ERR, "unit %d: Receive Aborted error", sc->sc_unit);
|
||||
}
|
||||
|
||||
if(error == 0)
|
||||
NDBGL1(L1_I_ERR, "unit %d: RME unknown error, RSTA = 0x%02x!", sc->sc_unit, rsta);
|
||||
|
||||
i4b_Dfreembuf(sc->sc_ibuf);
|
||||
|
||||
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
|
||||
|
||||
sc->sc_ibuf = NULL;
|
||||
sc->sc_ib = NULL;
|
||||
sc->sc_ilen = 0;
|
||||
|
||||
ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES);
|
||||
ISACCMDRWRDELAY();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1));
|
||||
|
||||
if(rest == 0)
|
||||
rest = ISAC_FIFO_LEN;
|
||||
|
||||
if(sc->sc_ibuf == NULL)
|
||||
{
|
||||
if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL)
|
||||
sc->sc_ib = sc->sc_ibuf->m_data;
|
||||
else
|
||||
panic("itjc_isac_irq: RME, i4b_Dgetmbuf returns NULL!\n");
|
||||
sc->sc_ilen = 0;
|
||||
}
|
||||
|
||||
if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest))
|
||||
{
|
||||
ISAC_RDFIFO(sc->sc_ib, rest);
|
||||
sc->sc_ilen += rest;
|
||||
|
||||
sc->sc_ibuf->m_pkthdr.len =
|
||||
sc->sc_ibuf->m_len = sc->sc_ilen;
|
||||
|
||||
if(sc->sc_trace & TRACE_D_RX)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
hdr.unit = L0ITJCUNIT(sc->sc_unit);
|
||||
hdr.type = TRC_CH_D;
|
||||
hdr.dir = FROM_NT;
|
||||
hdr.count = ++sc->sc_trace_dcount;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
|
||||
}
|
||||
|
||||
c |= ISAC_CMDR_RMC;
|
||||
|
||||
if(sc->sc_enabled &&
|
||||
(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S))
|
||||
{
|
||||
i4b_l1_ph_data_ind(L0ITJCUNIT(sc->sc_unit), sc->sc_ibuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
i4b_Dfreembuf(sc->sc_ibuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
|
||||
i4b_Dfreembuf(sc->sc_ibuf);
|
||||
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
|
||||
}
|
||||
|
||||
sc->sc_ibuf = NULL;
|
||||
sc->sc_ib = NULL;
|
||||
sc->sc_ilen = 0;
|
||||
}
|
||||
|
||||
if(ista & ISAC_ISTA_RPF) /* receive fifo full */
|
||||
{
|
||||
if(sc->sc_ibuf == NULL)
|
||||
{
|
||||
if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL)
|
||||
sc->sc_ib= sc->sc_ibuf->m_data;
|
||||
else
|
||||
panic("itjc_isac_irq: RPF, i4b_Dgetmbuf returns NULL!\n");
|
||||
sc->sc_ilen = 0;
|
||||
}
|
||||
|
||||
if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN))
|
||||
{
|
||||
ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN);
|
||||
sc->sc_ilen += ISAC_FIFO_LEN;
|
||||
sc->sc_ib += ISAC_FIFO_LEN;
|
||||
c |= ISAC_CMDR_RMC;
|
||||
}
|
||||
else
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
|
||||
i4b_Dfreembuf(sc->sc_ibuf);
|
||||
sc->sc_ibuf = NULL;
|
||||
sc->sc_ib = NULL;
|
||||
sc->sc_ilen = 0;
|
||||
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
|
||||
}
|
||||
}
|
||||
|
||||
if(ista & ISAC_ISTA_XPR) /* transmit fifo empty (XPR bit set) */
|
||||
{
|
||||
if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL))
|
||||
{
|
||||
sc->sc_freeflag = sc->sc_freeflag2;
|
||||
sc->sc_obuf = sc->sc_obuf2;
|
||||
sc->sc_op = sc->sc_obuf->m_data;
|
||||
sc->sc_ol = sc->sc_obuf->m_len;
|
||||
sc->sc_obuf2 = NULL;
|
||||
}
|
||||
|
||||
if(sc->sc_obuf)
|
||||
{
|
||||
ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN));
|
||||
|
||||
if(sc->sc_ol > ISAC_FIFO_LEN) /* length > 32 ? */
|
||||
{
|
||||
sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */
|
||||
sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */
|
||||
c |= ISAC_CMDR_XTF; /* set XTF bit */
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sc->sc_freeflag)
|
||||
{
|
||||
i4b_Dfreembuf(sc->sc_obuf);
|
||||
sc->sc_freeflag = 0;
|
||||
}
|
||||
sc->sc_obuf = NULL;
|
||||
sc->sc_op = NULL;
|
||||
sc->sc_ol = 0;
|
||||
|
||||
c |= ISAC_CMDR_XTF | ISAC_CMDR_XME;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc->sc_state &= ~ISAC_TX_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
if(ista & ISAC_ISTA_CISQ) /* channel status change CISQ */
|
||||
{
|
||||
register u_char ci;
|
||||
|
||||
/* get command/indication rx register*/
|
||||
|
||||
ci = ISAC_READ(I_CIRR);
|
||||
|
||||
/* if S/Q IRQ, read SQC reg to clr SQC IRQ */
|
||||
|
||||
if(ci & ISAC_CIRR_SQC)
|
||||
(void) ISAC_READ(I_SQRR);
|
||||
|
||||
/* C/I code change IRQ (flag already cleared by CIRR read) */
|
||||
|
||||
if(ci & ISAC_CIRR_CIC0)
|
||||
itjc_isac_ind_hdlr(sc, (ci >> 2) & 0xf);
|
||||
}
|
||||
|
||||
if(c)
|
||||
{
|
||||
ISAC_WRITE(I_CMDR, c);
|
||||
ISACCMDRWRDELAY();
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* ISAC L1 Extended IRQ handler
|
||||
*---------------------------------------------------------------------------*/
|
||||
static u_char
|
||||
itjc_isac_exir_hdlr(register struct l1_softc *sc, u_char exir)
|
||||
{
|
||||
u_char c = 0;
|
||||
|
||||
if(exir & ISAC_EXIR_XMR)
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat");
|
||||
|
||||
c |= ISAC_CMDR_XRES;
|
||||
}
|
||||
|
||||
if(exir & ISAC_EXIR_XDU)
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun");
|
||||
|
||||
c |= ISAC_CMDR_XRES;
|
||||
}
|
||||
|
||||
if(exir & ISAC_EXIR_PCE)
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "EXIRQ Protocol Error");
|
||||
}
|
||||
|
||||
if(exir & ISAC_EXIR_RFO)
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow");
|
||||
|
||||
c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
|
||||
}
|
||||
|
||||
if(exir & ISAC_EXIR_SOV)
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow");
|
||||
}
|
||||
|
||||
if(exir & ISAC_EXIR_MOS)
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "EXIRQ Monitor Status");
|
||||
}
|
||||
|
||||
if(exir & ISAC_EXIR_SAW)
|
||||
{
|
||||
/* cannot happen, STCR:TSF is set to 0 */
|
||||
|
||||
NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake");
|
||||
}
|
||||
|
||||
if(exir & ISAC_EXIR_WOV)
|
||||
{
|
||||
/* cannot happen, STCR:TSF is set to 0 */
|
||||
|
||||
NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow");
|
||||
}
|
||||
|
||||
return(c);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* ISAC L1 Indication handler
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
itjc_isac_ind_hdlr(register struct l1_softc *sc, int ind)
|
||||
{
|
||||
register int event;
|
||||
|
||||
switch(ind)
|
||||
{
|
||||
case ISAC_CIRR_IAI8:
|
||||
NDBGL1(L1_I_CICO, "rx AI8 in state %s", itjc_printstate(sc));
|
||||
itjc_isac_l1_cmd(sc, CMD_AR8);
|
||||
event = EV_INFO48;
|
||||
i4b_l1_mph_status_ind(L0ITJCUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_IAI10:
|
||||
NDBGL1(L1_I_CICO, "rx AI10 in state %s", itjc_printstate(sc));
|
||||
itjc_isac_l1_cmd(sc, CMD_AR10);
|
||||
event = EV_INFO410;
|
||||
i4b_l1_mph_status_ind(L0ITJCUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_IRSY:
|
||||
NDBGL1(L1_I_CICO, "rx RSY in state %s", itjc_printstate(sc));
|
||||
event = EV_RSY;
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_IPU:
|
||||
NDBGL1(L1_I_CICO, "rx PU in state %s", itjc_printstate(sc));
|
||||
event = EV_PU;
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_IDR:
|
||||
NDBGL1(L1_I_CICO, "rx DR in state %s", itjc_printstate(sc));
|
||||
itjc_isac_l1_cmd(sc, CMD_DIU);
|
||||
event = EV_DR;
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_IDID:
|
||||
NDBGL1(L1_I_CICO, "rx DID in state %s", itjc_printstate(sc));
|
||||
event = EV_INFO0;
|
||||
i4b_l1_mph_status_ind(L0ITJCUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL);
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_IDIS:
|
||||
NDBGL1(L1_I_CICO, "rx DIS in state %s", itjc_printstate(sc));
|
||||
event = EV_DIS;
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_IEI:
|
||||
NDBGL1(L1_I_CICO, "rx EI in state %s", itjc_printstate(sc));
|
||||
itjc_isac_l1_cmd(sc, CMD_DIU);
|
||||
event = EV_EI;
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_IARD:
|
||||
NDBGL1(L1_I_CICO, "rx ARD in state %s", itjc_printstate(sc));
|
||||
event = EV_INFO2;
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_ITI:
|
||||
NDBGL1(L1_I_CICO, "rx TI in state %s", itjc_printstate(sc));
|
||||
event = EV_INFO0;
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_IATI:
|
||||
NDBGL1(L1_I_CICO, "rx ATI in state %s", itjc_printstate(sc));
|
||||
event = EV_INFO0;
|
||||
break;
|
||||
|
||||
case ISAC_CIRR_ISD:
|
||||
NDBGL1(L1_I_CICO, "rx SD in state %s", itjc_printstate(sc));
|
||||
event = EV_INFO0;
|
||||
break;
|
||||
|
||||
default:
|
||||
NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, itjc_printstate(sc));
|
||||
event = EV_INFO0;
|
||||
break;
|
||||
}
|
||||
itjc_next_state(sc, event);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* execute a layer 1 command
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
itjc_isac_l1_cmd(struct l1_softc *sc, int command)
|
||||
{
|
||||
u_char cmd;
|
||||
|
||||
if(command < 0 || command > CMD_ILL)
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, itjc_printstate(sc));
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = ISAC_CIX0_LOW;
|
||||
|
||||
switch(command)
|
||||
{
|
||||
case CMD_TIM:
|
||||
NDBGL1(L1_I_CICO, "tx TIM in state %s", itjc_printstate(sc));
|
||||
cmd |= (ISAC_CIXR_CTIM << 2);
|
||||
break;
|
||||
|
||||
case CMD_RS:
|
||||
NDBGL1(L1_I_CICO, "tx RS in state %s", itjc_printstate(sc));
|
||||
cmd |= (ISAC_CIXR_CRS << 2);
|
||||
break;
|
||||
|
||||
case CMD_AR8:
|
||||
NDBGL1(L1_I_CICO, "tx AR8 in state %s", itjc_printstate(sc));
|
||||
cmd |= (ISAC_CIXR_CAR8 << 2);
|
||||
break;
|
||||
|
||||
case CMD_AR10:
|
||||
NDBGL1(L1_I_CICO, "tx AR10 in state %s", itjc_printstate(sc));
|
||||
cmd |= (ISAC_CIXR_CAR10 << 2);
|
||||
break;
|
||||
|
||||
case CMD_DIU:
|
||||
NDBGL1(L1_I_CICO, "tx DIU in state %s", itjc_printstate(sc));
|
||||
cmd |= (ISAC_CIXR_CDIU << 2);
|
||||
break;
|
||||
}
|
||||
ISAC_WRITE(I_CIXR, cmd);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* L1 ISAC initialization
|
||||
*---------------------------------------------------------------------------*/
|
||||
int
|
||||
itjc_isac_init(struct l1_softc *sc)
|
||||
{
|
||||
ISAC_IMASK = 0xff; /* disable all irqs */
|
||||
|
||||
ISAC_WRITE(I_MASK, ISAC_IMASK);
|
||||
|
||||
NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode");
|
||||
|
||||
/* ADF2: Select mode IOM-2 */
|
||||
ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS);
|
||||
|
||||
/* SPCR: serial port control register:
|
||||
* SPU - software power up = 0
|
||||
* SPM - timing mode 0
|
||||
* TLP - test loop = 0
|
||||
* C1C, C2C - B1 + C1 and B2 + IC2 monitoring
|
||||
*/
|
||||
ISAC_WRITE(I_SPCR, 0x00);
|
||||
|
||||
/* SQXR: S/Q channel xmit register:
|
||||
* IDC - IOM direction = 0 (master)
|
||||
* CFS - Config Select = 0 (clock always active)
|
||||
* CI1E - C/I channel 1 IRQ enable = 0
|
||||
* SQIE - S/Q IRQ enable = 0
|
||||
* SQX1-4 - Fa bits = 1
|
||||
*/
|
||||
ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4);
|
||||
|
||||
/* ADF1: additional feature reg 1:
|
||||
* WTC - watchdog = 0
|
||||
* TEM - test mode = 0
|
||||
* PFS - pre-filter = 0
|
||||
* IOF - IOM i/f off = 0
|
||||
* ITF - interframe fill = idle
|
||||
*/
|
||||
ISAC_WRITE(I_ADF1, 0x00);
|
||||
|
||||
/* STCR: sync transfer control reg:
|
||||
* TSF - terminal secific functions = 0
|
||||
* TBA - TIC bus address = 7
|
||||
* STx/SCx = 0
|
||||
*/
|
||||
ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
|
||||
|
||||
/* MODE: Mode Register:
|
||||
* MDSx - transparent mode 2
|
||||
* TMD - timer mode = external
|
||||
* RAC - Receiver enabled
|
||||
* DIMx - digital i/f mode
|
||||
*/
|
||||
ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
|
||||
|
||||
/* enabled interrupts:
|
||||
* ===================
|
||||
* RME - receive message end
|
||||
* RPF - receive pool full
|
||||
* XPR - transmit pool ready
|
||||
* CISQ - CI or S/Q channel change
|
||||
* EXI - extended interrupt
|
||||
*/
|
||||
|
||||
ISAC_IMASK = ISAC_MASK_RSC | /* auto mode only */
|
||||
ISAC_MASK_TIN | /* timer irq */
|
||||
ISAC_MASK_SIN; /* sync xfer irq */
|
||||
|
||||
ISAC_WRITE(I_MASK, ISAC_IMASK);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif /* NITJC > 0 */
|
243
sys/i4b/layer1/itjc/i4b_itjc_l1.c
Normal file
243
sys/i4b/layer1/itjc/i4b_itjc_l1.c
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* i4b_itjc_l1.c - NetJet-S layer 1 handler
|
||||
* ---------------------------------------------
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* last edit-date: [Wed Jan 10 17:16:19 2001]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "itjc.h"
|
||||
#include "pci.h"
|
||||
|
||||
#if (NITJC > 0) && (NPCI > 0)
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <machine/i4b_debug.h>
|
||||
#include <machine/i4b_ioctl.h>
|
||||
#include <machine/i4b_trace.h>
|
||||
|
||||
#include <i4b/layer1/isic/i4b_isic.h>
|
||||
#include <i4b/layer1/isic/i4b_isac.h>
|
||||
|
||||
#include <i4b/layer1/itjc/i4b_itjc_ext.h>
|
||||
|
||||
#include <i4b/layer1/i4b_l1.h>
|
||||
|
||||
#include <i4b/include/i4b_mbuf.h>
|
||||
#include <i4b/include/i4b_global.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
*
|
||||
* L2 -> L1: PH-DATA-REQUEST
|
||||
* =========================
|
||||
*
|
||||
* parms:
|
||||
* unit physical interface unit number
|
||||
* m mbuf containing L2 frame to be sent out
|
||||
* freeflag MBUF_FREE: free mbuf here after having sent
|
||||
* it out
|
||||
* MBUF_DONTFREE: mbuf is freed by Layer 2
|
||||
* returns:
|
||||
* ==0 fail, nothing sent out
|
||||
* !=0 ok, frame sent out
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
int
|
||||
itjc_ph_data_req(int unit, struct mbuf *m, int freeflag)
|
||||
{
|
||||
u_char cmd;
|
||||
int s;
|
||||
struct l1_softc *sc = itjc_scp[unit];
|
||||
|
||||
NDBGL1(L1_PRIM, "PH-DATA-REQ, unit %d, freeflag=%d", unit, freeflag);
|
||||
|
||||
if(m == NULL) /* failsafe */
|
||||
return (0);
|
||||
|
||||
s = SPLI4B();
|
||||
|
||||
if(sc->sc_I430state == ST_F3) /* layer 1 not running ? */
|
||||
{
|
||||
NDBGL1(L1_I_ERR, "still in state F3!");
|
||||
itjc_ph_activate_req(unit);
|
||||
}
|
||||
|
||||
if(sc->sc_state & ISAC_TX_ACTIVE)
|
||||
{
|
||||
if(sc->sc_obuf2 == NULL)
|
||||
{
|
||||
sc->sc_obuf2 = m; /* save mbuf ptr */
|
||||
|
||||
if(freeflag)
|
||||
sc->sc_freeflag2 = 1; /* IRQ must mfree */
|
||||
else
|
||||
sc->sc_freeflag2 = 0; /* IRQ must not mfree */
|
||||
|
||||
NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", itjc_printstate(sc));
|
||||
|
||||
if(sc->sc_trace & TRACE_D_TX)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
hdr.unit = L0ITJCUNIT(unit);
|
||||
hdr.type = TRC_CH_D;
|
||||
hdr.dir = FROM_TE;
|
||||
hdr.count = ++sc->sc_trace_dcount;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
|
||||
}
|
||||
splx(s);
|
||||
return(1);
|
||||
}
|
||||
|
||||
NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", itjc_printstate(sc));
|
||||
|
||||
if(freeflag == MBUF_FREE)
|
||||
i4b_Dfreembuf(m);
|
||||
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if(sc->sc_trace & TRACE_D_TX)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
hdr.unit = L0ITJCUNIT(unit);
|
||||
hdr.type = TRC_CH_D;
|
||||
hdr.dir = FROM_TE;
|
||||
hdr.count = ++sc->sc_trace_dcount;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
|
||||
}
|
||||
|
||||
sc->sc_state |= ISAC_TX_ACTIVE; /* set transmitter busy flag */
|
||||
|
||||
NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set");
|
||||
|
||||
sc->sc_freeflag = 0; /* IRQ must NOT mfree */
|
||||
|
||||
ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */
|
||||
|
||||
if(m->m_len > ISAC_FIFO_LEN) /* message > 32 bytes ? */
|
||||
{
|
||||
sc->sc_obuf = m; /* save mbuf ptr */
|
||||
sc->sc_op = m->m_data + ISAC_FIFO_LEN; /* ptr for irq hdl */
|
||||
sc->sc_ol = m->m_len - ISAC_FIFO_LEN; /* length for irq hdl */
|
||||
|
||||
if(freeflag)
|
||||
sc->sc_freeflag = 1; /* IRQ must mfree */
|
||||
|
||||
cmd = ISAC_CMDR_XTF;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc->sc_obuf = NULL;
|
||||
sc->sc_op = NULL;
|
||||
sc->sc_ol = 0;
|
||||
|
||||
if(freeflag)
|
||||
i4b_Dfreembuf(m);
|
||||
|
||||
cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME;
|
||||
}
|
||||
|
||||
ISAC_WRITE(I_CMDR, cmd);
|
||||
ISACCMDRWRDELAY();
|
||||
|
||||
splx(s);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
*
|
||||
* L2 -> L1: PH-ACTIVATE-REQUEST
|
||||
* =============================
|
||||
*
|
||||
* parms:
|
||||
* unit physical interface unit number
|
||||
*
|
||||
* returns:
|
||||
* ==0
|
||||
* !=0
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
int
|
||||
itjc_ph_activate_req(int unit)
|
||||
{
|
||||
struct l1_softc *sc = itjc_scp[unit];
|
||||
NDBGL1(L1_PRIM, "PH-ACTIVATE-REQ, unit %d", unit);
|
||||
itjc_next_state(sc, EV_PHAR);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* command from the upper layers
|
||||
*---------------------------------------------------------------------------*/
|
||||
int
|
||||
itjc_mph_command_req(int unit, int command, void *parm)
|
||||
{
|
||||
struct l1_softc *sc = itjc_scp[unit];
|
||||
|
||||
switch(command)
|
||||
{
|
||||
case CMR_DOPEN: /* daemon running */
|
||||
NDBGL1(L1_PRIM, "unit %d, command = CMR_DOPEN", unit);
|
||||
sc->sc_enabled = 1;
|
||||
break;
|
||||
|
||||
case CMR_DCLOSE: /* daemon not running */
|
||||
NDBGL1(L1_PRIM, "unit %d, command = CMR_DCLOSE", unit);
|
||||
sc->sc_enabled = 0;
|
||||
break;
|
||||
|
||||
case CMR_SETTRACE:
|
||||
NDBGL1(L1_PRIM, "unit %d, command = CMR_SETTRACE, parm = %d", unit, (unsigned int)parm);
|
||||
sc->sc_trace = (unsigned int)parm;
|
||||
break;
|
||||
|
||||
default:
|
||||
NDBGL1(L1_ERROR, "ERROR, unknown command = %d, unit = %d, parm = %d", command, unit, (unsigned int)parm);
|
||||
break;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif /* NITJC > 0 */
|
520
sys/i4b/layer1/itjc/i4b_itjc_l1fsm.c
Normal file
520
sys/i4b/layer1/itjc/i4b_itjc_l1fsm.c
Normal file
@ -0,0 +1,520 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* i4b_itjc_l1fsm.c - NetJet-S layer 1 I.430 state machine
|
||||
* ------------------------------------------------------------
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* last edit-date: [Wed Jan 10 17:16:33 2001]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "itjc.h"
|
||||
#include "pci.h"
|
||||
|
||||
#if (NITJC > 0) && (NPCI > 0)
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <machine/i4b_debug.h>
|
||||
#include <machine/i4b_ioctl.h>
|
||||
#include <machine/i4b_trace.h>
|
||||
|
||||
#include <i4b/layer1/isic/i4b_isic.h>
|
||||
#include <i4b/layer1/isic/i4b_isac.h>
|
||||
#include <i4b/layer1/isic/i4b_hscx.h>
|
||||
|
||||
#include <i4b/layer1/i4b_l1.h>
|
||||
|
||||
#include <i4b/include/i4b_global.h>
|
||||
|
||||
#include <i4b/include/i4b_mbuf.h>
|
||||
|
||||
#include <i4b/layer1/itjc/i4b_itjc_ext.h>
|
||||
|
||||
#if DO_I4B_DEBUG
|
||||
static char *state_text[N_STATES] = {
|
||||
"F3 Deactivated",
|
||||
"F4 Awaiting Signal",
|
||||
"F5 Identifying Input",
|
||||
"F6 Synchronized",
|
||||
"F7 Activated",
|
||||
"F8 Lost Framing",
|
||||
"Illegal State"
|
||||
};
|
||||
|
||||
static char *event_text[N_EVENTS] = {
|
||||
"EV_PHAR PH_ACT_REQ",
|
||||
"EV_T3 Timer 3 expired",
|
||||
"EV_INFO0 INFO0 received",
|
||||
"EV_RSY Level Detected",
|
||||
"EV_INFO2 INFO2 received",
|
||||
"EV_INFO48 INFO4 received",
|
||||
"EV_INFO410 INFO4 received",
|
||||
"EV_DR Deactivate Req",
|
||||
"EV_PU Power UP",
|
||||
"EV_DIS Disconnected",
|
||||
"EV_EI Error Ind",
|
||||
"Illegal Event"
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
static void timer3_expired (struct l1_softc *sc);
|
||||
static void T3_start (struct l1_softc *sc);
|
||||
static void T3_stop (struct l1_softc *sc);
|
||||
static void F_T3ex (struct l1_softc *sc);
|
||||
static void timer4_expired (struct l1_softc *sc);
|
||||
static void T4_start (struct l1_softc *sc);
|
||||
static void T4_stop (struct l1_softc *sc);
|
||||
static void F_AI8 (struct l1_softc *sc);
|
||||
static void F_AI10 (struct l1_softc *sc);
|
||||
static void F_I01 (struct l1_softc *sc);
|
||||
static void F_I02 (struct l1_softc *sc);
|
||||
static void F_I03 (struct l1_softc *sc);
|
||||
static void F_I2 (struct l1_softc *sc);
|
||||
static void F_ill (struct l1_softc *sc);
|
||||
static void F_NULL (struct l1_softc *sc);
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* I.430 Timer T3 expire function
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
timer3_expired(struct l1_softc *sc)
|
||||
{
|
||||
if(sc->sc_I430T3)
|
||||
{
|
||||
NDBGL1(L1_T_ERR, "state = %s", itjc_printstate(sc));
|
||||
sc->sc_I430T3 = 0;
|
||||
|
||||
/* XXX try some recovery here XXX */
|
||||
|
||||
itjc_recover(sc);
|
||||
|
||||
sc->sc_init_tries++; /* increment retry count */
|
||||
|
||||
/*XXX*/ if(sc->sc_init_tries > 4)
|
||||
{
|
||||
int s = SPLI4B();
|
||||
|
||||
sc->sc_init_tries = 0;
|
||||
|
||||
if(sc->sc_obuf2 != NULL)
|
||||
{
|
||||
i4b_Dfreembuf(sc->sc_obuf2);
|
||||
sc->sc_obuf2 = NULL;
|
||||
}
|
||||
if(sc->sc_obuf != NULL)
|
||||
{
|
||||
i4b_Dfreembuf(sc->sc_obuf);
|
||||
sc->sc_obuf = NULL;
|
||||
sc->sc_freeflag = 0;
|
||||
sc->sc_op = NULL;
|
||||
sc->sc_ol = 0;
|
||||
}
|
||||
|
||||
splx(s);
|
||||
|
||||
i4b_l1_mph_status_ind(L0ITJCUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL);
|
||||
}
|
||||
|
||||
itjc_next_state(sc, EV_T3);
|
||||
}
|
||||
else
|
||||
{
|
||||
NDBGL1(L1_T_ERR, "expired without starting it ....");
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* I.430 Timer T3 start
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
T3_start(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_T_MSG, "state = %s", itjc_printstate(sc));
|
||||
sc->sc_I430T3 = 1;
|
||||
sc->sc_T3_callout = timeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, 2*hz);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* I.430 Timer T3 stop
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
T3_stop(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_T_MSG, "state = %s", itjc_printstate(sc));
|
||||
|
||||
sc->sc_init_tries = 0; /* init connect retry count */
|
||||
|
||||
if(sc->sc_I430T3)
|
||||
{
|
||||
sc->sc_I430T3 = 0;
|
||||
untimeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, sc->sc_T3_callout);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* I.430 Timer T3 expiry
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_T3ex(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_F_MSG, "FSM function F_T3ex executing");
|
||||
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
|
||||
i4b_l1_ph_deactivate_ind(L0ITJCUNIT(sc->sc_unit));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Timer T4 expire function
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
timer4_expired(struct l1_softc *sc)
|
||||
{
|
||||
if(sc->sc_I430T4)
|
||||
{
|
||||
NDBGL1(L1_T_MSG, "state = %s", itjc_printstate(sc));
|
||||
sc->sc_I430T4 = 0;
|
||||
i4b_l1_mph_status_ind(L0ITJCUNIT(sc->sc_unit), STI_PDEACT, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
NDBGL1(L1_T_ERR, "expired without starting it ....");
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Timer T4 start
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
T4_start(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_T_MSG, "state = %s", itjc_printstate(sc));
|
||||
sc->sc_I430T4 = 1;
|
||||
sc->sc_T4_callout = timeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, hz);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Timer T4 stop
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
T4_stop(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_T_MSG, "state = %s", itjc_printstate(sc));
|
||||
|
||||
if(sc->sc_I430T4)
|
||||
{
|
||||
sc->sc_I430T4 = 0;
|
||||
untimeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, sc->sc_T4_callout);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* FSM function: received AI8
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_AI8(struct l1_softc *sc)
|
||||
{
|
||||
T4_stop(sc);
|
||||
|
||||
NDBGL1(L1_F_MSG, "FSM function F_AI8 executing");
|
||||
|
||||
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
|
||||
i4b_l1_ph_activate_ind(L0ITJCUNIT(sc->sc_unit));
|
||||
|
||||
T3_stop(sc);
|
||||
|
||||
if(sc->sc_trace & TRACE_I)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
char info = INFO4_8;
|
||||
|
||||
hdr.unit = L0ITJCUNIT(sc->sc_unit);
|
||||
hdr.type = TRC_CH_I;
|
||||
hdr.dir = FROM_NT;
|
||||
hdr.count = 0;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, 1, &info);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* FSM function: received AI10
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_AI10(struct l1_softc *sc)
|
||||
{
|
||||
T4_stop(sc);
|
||||
|
||||
NDBGL1(L1_F_MSG, "FSM function F_AI10 executing");
|
||||
|
||||
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
|
||||
i4b_l1_ph_activate_ind(L0ITJCUNIT(sc->sc_unit));
|
||||
|
||||
T3_stop(sc);
|
||||
|
||||
if(sc->sc_trace & TRACE_I)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
char info = INFO4_10;
|
||||
|
||||
hdr.unit = L0ITJCUNIT(sc->sc_unit);
|
||||
hdr.type = TRC_CH_I;
|
||||
hdr.dir = FROM_NT;
|
||||
hdr.count = 0;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, 1, &info);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* FSM function: received INFO 0 in states F3 .. F5
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_I01(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_F_MSG, "FSM function F_I01 executing");
|
||||
|
||||
if(sc->sc_trace & TRACE_I)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
char info = INFO0;
|
||||
|
||||
hdr.unit = L0ITJCUNIT(sc->sc_unit);
|
||||
hdr.type = TRC_CH_I;
|
||||
hdr.dir = FROM_NT;
|
||||
hdr.count = 0;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, 1, &info);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* FSM function: received INFO 0 in state F6
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_I02(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_F_MSG, "FSM function F_I02 executing");
|
||||
|
||||
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
|
||||
i4b_l1_ph_deactivate_ind(L0ITJCUNIT(sc->sc_unit));
|
||||
|
||||
if(sc->sc_trace & TRACE_I)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
char info = INFO0;
|
||||
|
||||
hdr.unit = L0ITJCUNIT(sc->sc_unit);
|
||||
hdr.type = TRC_CH_I;
|
||||
hdr.dir = FROM_NT;
|
||||
hdr.count = 0;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, 1, &info);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* FSM function: received INFO 0 in state F7 or F8
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_I03(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_F_MSG, "FSM function F_I03 executing");
|
||||
|
||||
if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
|
||||
i4b_l1_ph_deactivate_ind(L0ITJCUNIT(sc->sc_unit));
|
||||
|
||||
T4_start(sc);
|
||||
|
||||
if(sc->sc_trace & TRACE_I)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
char info = INFO0;
|
||||
|
||||
hdr.unit = L0ITJCUNIT(sc->sc_unit);
|
||||
hdr.type = TRC_CH_I;
|
||||
hdr.dir = FROM_NT;
|
||||
hdr.count = 0;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, 1, &info);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* FSM function: activate request
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_AR(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_F_MSG, "FSM function F_AR executing");
|
||||
|
||||
if(sc->sc_trace & TRACE_I)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
char info = INFO1_8;
|
||||
|
||||
hdr.unit = L0ITJCUNIT(sc->sc_unit);
|
||||
hdr.type = TRC_CH_I;
|
||||
hdr.dir = FROM_TE;
|
||||
hdr.count = 0;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, 1, &info);
|
||||
}
|
||||
|
||||
itjc_isac_l1_cmd(sc, CMD_AR8);
|
||||
|
||||
T3_start(sc);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* FSM function: received INFO2
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_I2(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_F_MSG, "FSM function F_I2 executing");
|
||||
|
||||
if(sc->sc_trace & TRACE_I)
|
||||
{
|
||||
i4b_trace_hdr_t hdr;
|
||||
char info = INFO2;
|
||||
|
||||
hdr.unit = L0ITJCUNIT(sc->sc_unit);
|
||||
hdr.type = TRC_CH_I;
|
||||
hdr.dir = FROM_NT;
|
||||
hdr.count = 0;
|
||||
MICROTIME(hdr.time);
|
||||
i4b_l1_trace_ind(&hdr, 1, &info);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* illegal state default action
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_ill(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_F_ERR, "FSM function F_ill executing");
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* No action
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
F_NULL(struct l1_softc *sc)
|
||||
{
|
||||
NDBGL1(L1_F_MSG, "FSM function F_NULL executing");
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* layer 1 state transition table
|
||||
*---------------------------------------------------------------------------*/
|
||||
struct itjc_state_tab {
|
||||
void (*func) (struct l1_softc *sc); /* function to execute */
|
||||
int newstate; /* next state */
|
||||
} itjc_state_tab[N_EVENTS][N_STATES] = {
|
||||
|
||||
/* STATE: F3 F4 F5 F6 F7 F8 ILLEGAL STATE */
|
||||
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* EV_PHAR x*/ {{F_AR, ST_F4}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_ill, ST_ILL}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
|
||||
/* EV_T3 x*/ {{F_NULL, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
|
||||
/* EV_INFO0 */ {{F_I01, ST_F3}, {F_I01, ST_F4}, {F_I01, ST_F5}, {F_I02, ST_F3}, {F_I03, ST_F3}, {F_I03, ST_F3}, {F_ill, ST_ILL}},
|
||||
/* EV_RSY x*/ {{F_NULL, ST_F3}, {F_NULL, ST_F5}, {F_NULL, ST_F5}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
|
||||
/* EV_INFO2 */ {{F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_ill, ST_ILL}},
|
||||
/* EV_INFO48*/ {{F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_NULL, ST_F7}, {F_AI8, ST_F7}, {F_ill, ST_ILL}},
|
||||
/* EV_INFO41*/ {{F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_NULL, ST_F7}, {F_AI10, ST_F7}, {F_ill, ST_ILL}},
|
||||
/* EV_DR */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
|
||||
/* EV_PU */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
|
||||
/* EV_DIS */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}},
|
||||
/* EV_EI */ {{F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_ill, ST_ILL}},
|
||||
/* EV_ILL */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}}
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* event handler
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
itjc_next_state(struct l1_softc *sc, int event)
|
||||
{
|
||||
int currstate, newstate;
|
||||
|
||||
if(event >= N_EVENTS)
|
||||
panic("i4b_l1fsm.c: event >= N_EVENTS\n");
|
||||
|
||||
currstate = sc->sc_I430state;
|
||||
|
||||
if(currstate >= N_STATES)
|
||||
panic("i4b_l1fsm.c: currstate >= N_STATES\n");
|
||||
|
||||
newstate = itjc_state_tab[event][currstate].newstate;
|
||||
|
||||
if(newstate >= N_STATES)
|
||||
panic("i4b_l1fsm.c: newstate >= N_STATES\n");
|
||||
|
||||
NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event],
|
||||
state_text[currstate],
|
||||
state_text[newstate]);
|
||||
|
||||
(*itjc_state_tab[event][currstate].func)(sc);
|
||||
|
||||
if(newstate == ST_ILL)
|
||||
{
|
||||
newstate = ST_F3;
|
||||
NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!",
|
||||
state_text[currstate],
|
||||
state_text[newstate],
|
||||
event_text[event]);
|
||||
}
|
||||
|
||||
sc->sc_I430state = newstate;
|
||||
}
|
||||
|
||||
#if DO_I4B_DEBUG
|
||||
/*---------------------------------------------------------------------------*
|
||||
* return pointer to current state description
|
||||
*---------------------------------------------------------------------------*/
|
||||
char *
|
||||
itjc_printstate(struct l1_softc *sc)
|
||||
{
|
||||
return((char *) state_text[sc->sc_I430state]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NITJC > 0 */
|
2134
sys/i4b/layer1/itjc/i4b_itjc_pci.c
Normal file
2134
sys/i4b/layer1/itjc/i4b_itjc_pci.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user