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:
Hellmuth Michaelis 2001-01-11 14:35:45 +00:00
parent 6624680fec
commit 2fbe70cb49
8 changed files with 3942 additions and 9 deletions

View File

@ -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 {

View File

@ -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
}

View 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_ */

View 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_ */

View 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 */

View 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 */

View 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 */

File diff suppressed because it is too large Load Diff