]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/i4b/layer1/isic/i4b_isac.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / i4b / layer1 / isic / i4b_isac.c
1 /*-
2  * Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25
26 /*---------------------------------------------------------------------------
27  *
28  *      i4b_isac.c - i4b siemens isdn chipset driver ISAC handler
29  *      ---------------------------------------------------------
30  *      last edit-date: [Wed Jan 24 09:10:36 2001]
31  *
32  *---------------------------------------------------------------------------*/
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include "opt_i4b.h"
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/mbuf.h>
42 #include <sys/socket.h>
43
44 #include <net/if.h>
45
46 #include <i4b/include/i4b_debug.h>
47 #include <i4b/include/i4b_ioctl.h>
48 #include <i4b/include/i4b_trace.h>
49
50 #include <i4b/layer1/i4b_l1.h>
51
52 #include <i4b/layer1/isic/i4b_isic.h>
53 #include <i4b/layer1/isic/i4b_isac.h>
54 #include <i4b/layer1/isic/i4b_hscx.h>
55
56 #include <i4b/include/i4b_global.h>
57 #include <i4b/include/i4b_mbuf.h>
58
59 static u_char isic_isac_exir_hdlr(register struct l1_softc *sc, u_char exir);
60 static void isic_isac_ind_hdlr(register struct l1_softc *sc, int ind);
61
62 /*---------------------------------------------------------------------------*
63  *      ISAC interrupt service routine
64  *---------------------------------------------------------------------------*/
65 void
66 isic_isac_irq(struct l1_softc *sc, int ista)
67 {
68         register u_char c = 0;
69         NDBGL1(L1_F_MSG, "unit %d: ista = 0x%02x", sc->sc_unit, ista);
70
71         if(ista & ISAC_ISTA_EXI)        /* extended interrupt */
72         {
73                 c |= isic_isac_exir_hdlr(sc, ISAC_READ(I_EXIR));
74         }
75         
76         if(ista & ISAC_ISTA_RME)        /* receive message end */
77         {
78                 register int rest;
79                 u_char rsta;
80
81                 /* get rx status register */
82                 
83                 rsta = ISAC_READ(I_RSTA);
84
85                 if((rsta & ISAC_RSTA_MASK) != 0x20)
86                 {
87                         int error = 0;
88                         
89                         if(!(rsta & ISAC_RSTA_CRC))     /* CRC error */
90                         {
91                                 error++;
92                                 NDBGL1(L1_I_ERR, "unit %d: CRC error", sc->sc_unit);
93                         }
94         
95                         if(rsta & ISAC_RSTA_RDO)        /* ReceiveDataOverflow */
96                         {
97                                 error++;
98                                 NDBGL1(L1_I_ERR, "unit %d: Data Overrun error", sc->sc_unit);
99                         }
100         
101                         if(rsta & ISAC_RSTA_RAB)        /* ReceiveABorted */
102                         {
103                                 error++;
104                                 NDBGL1(L1_I_ERR, "unit %d: Receive Aborted error", sc->sc_unit);
105                         }
106
107                         if(error == 0)                  
108                                 NDBGL1(L1_I_ERR, "unit %d: RME unknown error, RSTA = 0x%02x!", sc->sc_unit, rsta);
109
110                         i4b_Dfreembuf(sc->sc_ibuf);
111
112                         c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
113
114                         sc->sc_ibuf = NULL;
115                         sc->sc_ib = NULL;
116                         sc->sc_ilen = 0;
117
118                         ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES);
119                         ISACCMDRWRDELAY();
120
121                         return;
122                 }
123
124                 rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1));
125
126                 if(rest == 0)
127                         rest = ISAC_FIFO_LEN;
128
129                 if(sc->sc_ibuf == NULL)
130                 {
131                         if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL)
132                                 sc->sc_ib = sc->sc_ibuf->m_data;
133                         else
134                                 panic("isic_isac_irq: RME, i4b_Dgetmbuf returns NULL!\n");
135                         sc->sc_ilen = 0;
136                 }
137
138                 if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest))
139                 {
140                         ISAC_RDFIFO(sc->sc_ib, rest);
141                         sc->sc_ilen += rest;
142                         
143                         sc->sc_ibuf->m_pkthdr.len =
144                                 sc->sc_ibuf->m_len = sc->sc_ilen;
145
146                         if(sc->sc_trace & TRACE_D_RX)
147                         {
148                                 i4b_trace_hdr_t hdr;
149                                 hdr.unit = L0ISICUNIT(sc->sc_unit);
150                                 hdr.type = TRC_CH_D;
151                                 hdr.dir = FROM_NT;
152                                 hdr.count = ++sc->sc_trace_dcount;
153                                 MICROTIME(hdr.time);
154                                 i4b_l1_trace_ind(&hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
155                         }
156
157                         c |= ISAC_CMDR_RMC;
158
159                         if(sc->sc_enabled &&
160                            (ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S))
161                         {
162                                 i4b_l1_ph_data_ind(L0ISICUNIT(sc->sc_unit), sc->sc_ibuf);
163                         }
164                         else
165                         {
166                                 i4b_Dfreembuf(sc->sc_ibuf);
167                         }
168                 }
169                 else
170                 {
171                         NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
172                         i4b_Dfreembuf(sc->sc_ibuf);
173                         c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
174                 }
175
176                 sc->sc_ibuf = NULL;
177                 sc->sc_ib = NULL;
178                 sc->sc_ilen = 0;
179         }
180
181         if(ista & ISAC_ISTA_RPF)        /* receive fifo full */
182         {
183                 if(sc->sc_ibuf == NULL)
184                 {
185                         if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL)
186                                 sc->sc_ib= sc->sc_ibuf->m_data;
187                         else
188                                 panic("isic_isac_irq: RPF, i4b_Dgetmbuf returns NULL!\n");
189                         sc->sc_ilen = 0;
190                 }
191
192                 if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN))
193                 {
194                         ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN);
195                         sc->sc_ilen += ISAC_FIFO_LEN;                   
196                         sc->sc_ib += ISAC_FIFO_LEN;
197                         c |= ISAC_CMDR_RMC;
198                 }
199                 else
200                 {
201                         NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
202                         i4b_Dfreembuf(sc->sc_ibuf);
203                         sc->sc_ibuf = NULL;
204                         sc->sc_ib = NULL;
205                         sc->sc_ilen = 0;
206                         c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;                      
207                 }
208         }
209
210         if(ista & ISAC_ISTA_XPR)        /* transmit fifo empty (XPR bit set) */
211         {
212                 if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL))
213                 {
214                         sc->sc_freeflag = sc->sc_freeflag2;
215                         sc->sc_obuf = sc->sc_obuf2;
216                         sc->sc_op = sc->sc_obuf->m_data;
217                         sc->sc_ol = sc->sc_obuf->m_len;
218                         sc->sc_obuf2 = NULL;
219 #ifdef NOTDEF                   
220                         printf("ob2=%x, op=%x, ol=%d, f=%d #",
221                                 sc->sc_obuf,
222                                 sc->sc_op,
223                                 sc->sc_ol,
224                                 sc->sc_state);
225 #endif                          
226                 }
227                 else
228                 {
229 #ifdef NOTDEF
230                         printf("ob=%x, op=%x, ol=%d, f=%d #",
231                                 sc->sc_obuf,
232                                 sc->sc_op,
233                                 sc->sc_ol,
234                                 sc->sc_state);
235 #endif
236                 }                       
237                 
238                 if(sc->sc_obuf)
239                 {                       
240                         ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN));
241         
242                         if(sc->sc_ol > ISAC_FIFO_LEN)   /* length > 32 ? */
243                         {
244                                 sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */
245                                 sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */
246                                 c |= ISAC_CMDR_XTF;         /* set XTF bit */
247                         }
248                         else
249                         {
250                                 if(sc->sc_freeflag)
251                                 {
252                                         i4b_Dfreembuf(sc->sc_obuf);
253                                         sc->sc_freeflag = 0;
254                                 }
255                                 sc->sc_obuf = NULL;
256                                 sc->sc_op = NULL;
257                                 sc->sc_ol = 0;
258         
259                                 c |= ISAC_CMDR_XTF | ISAC_CMDR_XME;
260                         }
261                 }
262                 else
263                 {
264                         sc->sc_state &= ~ISAC_TX_ACTIVE;
265                 }
266         }
267         
268         if(ista & ISAC_ISTA_CISQ)       /* channel status change CISQ */
269         {
270                 register u_char ci;
271         
272                 /* get command/indication rx register*/
273         
274                 ci = ISAC_READ(I_CIRR);
275
276                 /* if S/Q IRQ, read SQC reg to clr SQC IRQ */
277         
278                 if(ci & ISAC_CIRR_SQC)
279                         (void) ISAC_READ(I_SQRR);
280
281                 /* C/I code change IRQ (flag already cleared by CIRR read) */
282         
283                 if(ci & ISAC_CIRR_CIC0)
284                         isic_isac_ind_hdlr(sc, (ci >> 2) & 0xf);
285         }
286         
287         if(c)
288         {
289                 ISAC_WRITE(I_CMDR, c);
290                 ISACCMDRWRDELAY();
291         }
292 }
293
294 /*---------------------------------------------------------------------------*
295  *      ISAC L1 Extended IRQ handler
296  *---------------------------------------------------------------------------*/
297 static u_char
298 isic_isac_exir_hdlr(register struct l1_softc *sc, u_char exir)
299 {
300         u_char c = 0;
301         
302         if(exir & ISAC_EXIR_XMR)
303         {
304                 NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat");
305
306                 c |= ISAC_CMDR_XRES;
307         }
308         
309         if(exir & ISAC_EXIR_XDU)
310         {
311                 NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun");
312
313                 c |= ISAC_CMDR_XRES;
314         }
315
316         if(exir & ISAC_EXIR_PCE)
317         {
318                 NDBGL1(L1_I_ERR, "EXIRQ Protocol Error");
319         }
320
321         if(exir & ISAC_EXIR_RFO)
322         {
323                 NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow");
324
325                 c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
326         }
327
328         if(exir & ISAC_EXIR_SOV)
329         {
330                 NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow");
331         }
332
333         if(exir & ISAC_EXIR_MOS)
334         {
335                 NDBGL1(L1_I_ERR, "EXIRQ Monitor Status");
336         }
337
338         if(exir & ISAC_EXIR_SAW)
339         {
340                 /* cannot happen, STCR:TSF is set to 0 */
341                 
342                 NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake");
343         }
344
345         if(exir & ISAC_EXIR_WOV)
346         {
347                 /* cannot happen, STCR:TSF is set to 0 */
348
349                 NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow");
350         }
351
352         return(c);
353 }
354
355 /*---------------------------------------------------------------------------*
356  *      ISAC L1 Indication handler
357  *---------------------------------------------------------------------------*/
358 static void
359 isic_isac_ind_hdlr(register struct l1_softc *sc, int ind)
360 {
361         register int event;
362         
363         switch(ind)
364         {
365                 case ISAC_CIRR_IAI8:
366                         NDBGL1(L1_I_CICO, "rx AI8 in state %s", isic_printstate(sc));
367                         if(sc->sc_bustyp == BUS_TYPE_IOM2)
368                                 isic_isac_l1_cmd(sc, CMD_AR8);
369                         event = EV_INFO48;
370                         i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
371                         break;
372                         
373                 case ISAC_CIRR_IAI10:
374                         NDBGL1(L1_I_CICO, "rx AI10 in state %s", isic_printstate(sc));
375                         if(sc->sc_bustyp == BUS_TYPE_IOM2)
376                                 isic_isac_l1_cmd(sc, CMD_AR10);
377                         event = EV_INFO410;
378                         i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_ACTIVE, NULL);
379                         break;
380
381                 case ISAC_CIRR_IRSY:
382                         NDBGL1(L1_I_CICO, "rx RSY in state %s", isic_printstate(sc));
383                         event = EV_RSY;
384                         break;
385
386                 case ISAC_CIRR_IPU:
387                         NDBGL1(L1_I_CICO, "rx PU in state %s", isic_printstate(sc));
388                         event = EV_PU;
389                         break;
390
391                 case ISAC_CIRR_IDR:
392                         NDBGL1(L1_I_CICO, "rx DR in state %s", isic_printstate(sc));
393                         isic_isac_l1_cmd(sc, CMD_DIU);
394                         event = EV_DR;                  
395                         break;
396                         
397                 case ISAC_CIRR_IDID:
398                         NDBGL1(L1_I_CICO, "rx DID in state %s", isic_printstate(sc));
399                         event = EV_INFO0;
400                         i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_L1STAT, LAYER_IDLE, NULL);
401                         break;
402
403                 case ISAC_CIRR_IDIS:
404                         NDBGL1(L1_I_CICO, "rx DIS in state %s", isic_printstate(sc));
405                         event = EV_DIS;
406                         break;
407
408                 case ISAC_CIRR_IEI:
409                         NDBGL1(L1_I_CICO, "rx EI in state %s", isic_printstate(sc));
410                         isic_isac_l1_cmd(sc, CMD_DIU);
411                         event = EV_EI;
412                         break;
413
414                 case ISAC_CIRR_IARD:
415                         NDBGL1(L1_I_CICO, "rx ARD in state %s", isic_printstate(sc));
416                         event = EV_INFO2;
417                         break;
418
419                 case ISAC_CIRR_ITI:
420                         NDBGL1(L1_I_CICO, "rx TI in state %s", isic_printstate(sc));
421                         event = EV_INFO0;
422                         break;
423
424                 case ISAC_CIRR_IATI:
425                         NDBGL1(L1_I_CICO, "rx ATI in state %s", isic_printstate(sc));
426                         event = EV_INFO0;
427                         break;
428
429                 case ISAC_CIRR_ISD:
430                         NDBGL1(L1_I_CICO, "rx SD in state %s", isic_printstate(sc));
431                         event = EV_INFO0;
432                         break;
433                 
434                 default:
435                         NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, isic_printstate(sc));
436                         event = EV_INFO0;
437                         break;
438         }
439         isic_next_state(sc, event);
440 }
441
442 /*---------------------------------------------------------------------------*
443  *      execute a layer 1 command
444  *---------------------------------------------------------------------------*/ 
445 void
446 isic_isac_l1_cmd(struct l1_softc *sc, int command)
447 {
448         u_char cmd;
449
450 #ifdef I4B_SMP_WORKAROUND
451
452         /* XXXXXXXXXXXXXXXXXXX */
453         
454         /*
455          * patch from Wolfgang Helbig:
456          *
457          * Here is a patch that makes i4b work on an SMP:
458          * The card (TELES 16.3) didn't interrupt on an SMP machine.
459          * This is a gross workaround, but anyway it works *and* provides
460          * some information as how to finally fix this problem.
461          */
462         
463         HSCX_WRITE(0, H_MASK, 0xff);
464         HSCX_WRITE(1, H_MASK, 0xff);
465         ISAC_WRITE(I_MASK, 0xff);
466         DELAY(100);
467         HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
468         HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
469         ISAC_WRITE(I_MASK, ISAC_IMASK);
470
471         /* XXXXXXXXXXXXXXXXXXX */
472         
473 #endif /* I4B_SMP_WORKAROUND */
474
475         if(command < 0 || command > CMD_ILL)
476         {
477                 NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, isic_printstate(sc));
478                 return;
479         }
480                                            
481         if(sc->sc_bustyp == BUS_TYPE_IOM2)
482                 cmd = ISAC_CIX0_LOW;
483         else
484                 cmd = 0;
485
486         switch(command)
487         {
488                 case CMD_TIM:
489                         NDBGL1(L1_I_CICO, "tx TIM in state %s", isic_printstate(sc));
490                         cmd |= (ISAC_CIXR_CTIM << 2);
491                         break;
492
493                 case CMD_RS:
494                         NDBGL1(L1_I_CICO, "tx RS in state %s", isic_printstate(sc));
495                         cmd |= (ISAC_CIXR_CRS << 2);
496                         break;
497
498                 case CMD_AR8:
499                         NDBGL1(L1_I_CICO, "tx AR8 in state %s", isic_printstate(sc));
500                         cmd |= (ISAC_CIXR_CAR8 << 2);
501                         break;
502
503                 case CMD_AR10:
504                         NDBGL1(L1_I_CICO, "tx AR10 in state %s", isic_printstate(sc));
505                         cmd |= (ISAC_CIXR_CAR10 << 2);
506                         break;
507
508                 case CMD_DIU:
509                         NDBGL1(L1_I_CICO, "tx DIU in state %s", isic_printstate(sc));
510                         cmd |= (ISAC_CIXR_CDIU << 2);
511                         break;
512         }
513         ISAC_WRITE(I_CIXR, cmd);
514 }
515
516 /*---------------------------------------------------------------------------*
517  *      L1 ISAC initialization
518  *---------------------------------------------------------------------------*/
519 int
520 isic_isac_init(struct l1_softc *sc)
521 {
522         ISAC_IMASK = 0xff;              /* disable all irqs */
523
524         ISAC_WRITE(I_MASK, ISAC_IMASK);
525
526         if(sc->sc_bustyp != BUS_TYPE_IOM2)
527         {
528                 NDBGL1(L1_I_SETUP, "configuring for IOM-1 mode");
529
530                 /* ADF2: Select mode IOM-1 */           
531                 ISAC_WRITE(I_ADF2, 0x00);
532
533                 /* SPCR: serial port control register:
534                  *      SPU - software power up = 0
535                  *      SAC - SIP port high Z
536                  *      SPM - timing mode 0
537                  *      TLP - test loop = 0
538                  *      C1C, C2C - B1 and B2 switched to/from SPa
539                  */
540                 ISAC_WRITE(I_SPCR, ISAC_SPCR_C1C1|ISAC_SPCR_C2C1);
541
542                 /* SQXR: S/Q channel xmit register:
543                  *      SQIE - S/Q IRQ enable = 0
544                  *      SQX1-4 - Fa bits = 1
545                  */
546                 ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4);
547
548                 /* ADF1: additional feature reg 1:
549                  *      WTC - watchdog = 0
550                  *      TEM - test mode = 0
551                  *      PFS - pre-filter = 0
552                  *      CFS - IOM clock/frame always active
553                  *      FSC1/2 - polarity of 8kHz strobe
554                  *      ITF - interframe fill = idle
555                  */     
556                 ISAC_WRITE(I_ADF1, ISAC_ADF1_FC2);      /* ADF1 */
557
558                 /* STCR: sync transfer control reg:
559                  *      TSF - terminal secific functions = 0
560                  *      TBA - TIC bus address = 7
561                  *      STx/SCx = 0
562                  */
563                 ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
564
565                 /* MODE: Mode Register:
566                  *      MDSx - transparent mode 2
567                  *      TMD  - timer mode = external
568                  *      RAC  - Receiver enabled
569                  *      DIMx - digital i/f mode
570                  */
571                 ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
572         }
573         else
574         {
575                 NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode");
576
577                 /* ADF2: Select mode IOM-2 */           
578                 ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS);
579
580                 /* SPCR: serial port control register:
581                  *      SPU - software power up = 0
582                  *      SPM - timing mode 0
583                  *      TLP - test loop = 0
584                  *      C1C, C2C - B1 + C1 and B2 + IC2 monitoring
585                  */
586                 ISAC_WRITE(I_SPCR, 0x00);
587
588                 /* SQXR: S/Q channel xmit register:
589                  *      IDC  - IOM direction = 0 (master)
590                  *      CFS  - Config Select = 0 (clock always active)
591                  *      CI1E - C/I channel 1 IRQ enable = 0
592                  *      SQIE - S/Q IRQ enable = 0
593                  *      SQX1-4 - Fa bits = 1
594                  */
595                 ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4);
596
597                 /* ADF1: additional feature reg 1:
598                  *      WTC - watchdog = 0
599                  *      TEM - test mode = 0
600                  *      PFS - pre-filter = 0
601                  *      IOF - IOM i/f off = 0
602                  *      ITF - interframe fill = idle
603                  */     
604                 ISAC_WRITE(I_ADF1, 0x00);
605
606                 /* STCR: sync transfer control reg:
607                  *      TSF - terminal secific functions = 0
608                  *      TBA - TIC bus address = 7
609                  *      STx/SCx = 0
610                  */
611                 ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
612
613                 /* MODE: Mode Register:
614                  *      MDSx - transparent mode 2
615                  *      TMD  - timer mode = external
616                  *      RAC  - Receiver enabled
617                  *      DIMx - digital i/f mode
618                  */
619                 ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
620         }
621
622 #ifdef NOTDEF
623         /*
624          * XXX a transmitter reset causes an ISAC tx IRQ which will not
625          * be serviced at attach time under some circumstances leaving
626          * the associated IRQ line on the ISA bus active. This prevents
627          * any further interrupts to be serviced because no low -> high
628          * transition can take place anymore. (-hm)
629          */
630          
631         /* command register:
632          *      RRES - HDLC receiver reset
633          *      XRES - transmitter reset
634          */
635         ISAC_WRITE(I_CMDR, ISAC_CMDR_RRES|ISAC_CMDR_XRES);
636         ISACCMDRWRDELAY();
637 #endif
638         
639         /* enabled interrupts:
640          * ===================
641          * RME  - receive message end
642          * RPF  - receive pool full
643          * XPR  - transmit pool ready
644          * CISQ - CI or S/Q channel change
645          * EXI  - extended interrupt
646          */
647
648         ISAC_IMASK = ISAC_MASK_RSC |    /* auto mode only       */
649                      ISAC_MASK_TIN |    /* timer irq            */
650                      ISAC_MASK_SIN;     /* sync xfer irq        */
651
652         ISAC_WRITE(I_MASK, ISAC_IMASK);
653
654         return(0);
655 }