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