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