1 /* $Id: isac.c,v 1.18 1998/11/15 23:54:51 keil Exp $
3 * isac.c ISAC specific routines
5 * Author Karsten Keil (keil@isdn4linux.de)
7 * This file is (c) under GNU PUBLIC LICENSE
8 * For changes and modifications please read
9 * ../../../Documentation/isdn/HiSax.cert
12 * Revision 1.18 1998/11/15 23:54:51 keil
15 * Revision 1.17 1998/08/13 23:36:37 keil
16 * HiSax 3.1 - don't work stable with current LinkLevel
18 * Revision 1.16 1998/05/25 12:58:01 keil
19 * HiSax golden code from certification, Don't use !!!
20 * No leased lines, no X75, but many changes.
22 * Revision 1.15 1998/04/15 16:45:32 keil
25 * Revision 1.14 1998/04/10 10:35:26 paul
26 * fixed (silly?) warnings from egcs on Alpha.
28 * Revision 1.13 1998/03/07 22:57:01 tsbogend
29 * made HiSax working on Linux/Alpha
31 * Revision 1.12 1998/02/12 23:07:40 keil
32 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
34 * Revision 1.11 1998/02/09 10:54:49 keil
35 * fixes for leased mode
37 * Revision 1.10 1998/02/02 13:37:37 keil
40 * Revision 1.9 1997/11/06 17:09:07 keil
43 * Revision 1.8 1997/10/29 19:00:03 keil
44 * new layer1,changes for 2.1
46 * Revision 1.7 1997/10/01 09:21:37 fritz
47 * Removed old compatibility stuff for 2.0.X kernels.
48 * From now on, this code is for 2.1.X ONLY!
49 * Old stuff is still in the separate branch.
51 * Revision 1.6 1997/08/15 17:47:08 keil
52 * avoid oops because a uninitialised timer
54 * Revision 1.5 1997/08/07 17:48:49 keil
55 * fix wrong parenthesis
57 * Revision 1.4 1997/07/30 17:11:59 keil
60 * Revision 1.3 1997/07/27 21:37:40 keil
61 * T3 implemented; supervisor l1timer; B-channel TEST_LOOP
63 * Revision 1.2 1997/06/26 11:16:15 keil
69 #define __NO_VERSION__
73 #include <linux/interrupt.h>
75 #define DBUSY_TIMER_VALUE 80
78 static char *ISACVer
[] HISAX_INITDATA
=
79 {"2086/2186 V1.1", "2085 B1", "2085 B2",
83 ISACVersion(struct IsdnCardState
*cs
, char *s
)
87 val
= cs
->readisac(cs
, ISAC_RBCH
);
88 printk(KERN_INFO
"%s ISAC version (%x): %s\n", s
, val
, ISACVer
[(val
>> 5) & 3]);
92 ph_command(struct IsdnCardState
*cs
, unsigned int command
)
94 if (cs
->debug
& L1_DEB_ISAC
)
95 debugl1(cs
, "ph_command %x", command
);
96 cs
->writeisac(cs
, ISAC_CIX0
, (command
<< 2) | 3);
101 isac_new_ph(struct IsdnCardState
*cs
)
103 switch (cs
->ph_state
) {
106 ph_command(cs
, ISAC_CMD_DUI
);
107 l1_msg(cs
, HW_RESET
| INDICATION
, NULL
);
110 l1_msg(cs
, HW_DEACTIVATE
| CONFIRM
, NULL
);
113 l1_msg(cs
, HW_DEACTIVATE
| INDICATION
, NULL
);
116 l1_msg(cs
, HW_POWERUP
| CONFIRM
, NULL
);
119 l1_msg(cs
, HW_RSYNC
| INDICATION
, NULL
);
122 l1_msg(cs
, HW_INFO2
| INDICATION
, NULL
);
125 l1_msg(cs
, HW_INFO4_P8
| INDICATION
, NULL
);
127 case (ISAC_IND_AI10
):
128 l1_msg(cs
, HW_INFO4_P10
| INDICATION
, NULL
);
136 isac_bh(struct IsdnCardState
*cs
)
138 struct PStack
*stptr
;
142 if (test_and_clear_bit(D_CLEARBUSY
, &cs
->event
)) {
144 debugl1(cs
, "D-Channel Busy cleared");
146 while (stptr
!= NULL
) {
147 stptr
->l1
.l1l2(stptr
, PH_PAUSE
| CONFIRM
, NULL
);
151 if (test_and_clear_bit(D_L1STATECHANGE
, &cs
->event
))
153 if (test_and_clear_bit(D_RCVBUFREADY
, &cs
->event
))
154 DChannel_proc_rcv(cs
);
155 if (test_and_clear_bit(D_XMTBUFREADY
, &cs
->event
))
156 DChannel_proc_xmt(cs
);
157 if (test_and_clear_bit(D_RX_MON0
, &cs
->event
))
158 test_and_set_bit(HW_MON0_RX_END
, &cs
->HW_Flags
);
159 if (test_and_clear_bit(D_RX_MON1
, &cs
->event
))
160 test_and_set_bit(HW_MON1_RX_END
, &cs
->HW_Flags
);
161 if (test_and_clear_bit(D_TX_MON0
, &cs
->event
))
162 test_and_set_bit(HW_MON0_TX_END
, &cs
->HW_Flags
);
163 if (test_and_clear_bit(D_TX_MON1
, &cs
->event
))
164 test_and_set_bit(HW_MON1_TX_END
, &cs
->HW_Flags
);
168 isac_empty_fifo(struct IsdnCardState
*cs
, int count
)
173 if ((cs
->debug
& L1_DEB_ISAC
) && !(cs
->debug
& L1_DEB_ISAC_FIFO
))
174 debugl1(cs
, "isac_empty_fifo");
176 if ((cs
->rcvidx
+ count
) >= MAX_DFRAME_LEN_L1
) {
177 if (cs
->debug
& L1_DEB_WARN
)
178 debugl1(cs
, "isac_empty_fifo overrun %d",
180 cs
->writeisac(cs
, ISAC_CMDR
, 0x80);
184 ptr
= cs
->rcvbuf
+ cs
->rcvidx
;
188 cs
->readisacfifo(cs
, ptr
, count
);
189 cs
->writeisac(cs
, ISAC_CMDR
, 0x80);
190 restore_flags(flags
);
191 if (cs
->debug
& L1_DEB_ISAC_FIFO
) {
194 t
+= sprintf(t
, "isac_empty_fifo cnt %d", count
);
195 QuickHex(t
, ptr
, count
);
196 debugl1(cs
, cs
->dlog
);
201 isac_fill_fifo(struct IsdnCardState
*cs
)
207 if ((cs
->debug
& L1_DEB_ISAC
) && !(cs
->debug
& L1_DEB_ISAC_FIFO
))
208 debugl1(cs
, "isac_fill_fifo");
213 count
= cs
->tx_skb
->len
;
224 ptr
= cs
->tx_skb
->data
;
225 skb_pull(cs
->tx_skb
, count
);
227 cs
->writeisacfifo(cs
, ptr
, count
);
228 cs
->writeisac(cs
, ISAC_CMDR
, more
? 0x8 : 0xa);
229 restore_flags(flags
);
230 if (test_and_set_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
231 debugl1(cs
, "isac_fill_fifo dbusytimer running");
232 del_timer(&cs
->dbusytimer
);
234 init_timer(&cs
->dbusytimer
);
235 cs
->dbusytimer
.expires
= jiffies
+ ((DBUSY_TIMER_VALUE
* HZ
)/1000);
236 add_timer(&cs
->dbusytimer
);
237 if (cs
->debug
& L1_DEB_ISAC_FIFO
) {
240 t
+= sprintf(t
, "isac_fill_fifo cnt %d", count
);
241 QuickHex(t
, ptr
, count
);
242 debugl1(cs
, cs
->dlog
);
247 isac_sched_event(struct IsdnCardState
*cs
, int event
)
249 test_and_set_bit(event
, &cs
->event
);
250 queue_task(&cs
->tqueue
, &tq_immediate
);
251 mark_bh(IMMEDIATE_BH
);
255 isac_interrupt(struct IsdnCardState
*cs
, u_char val
)
262 if (cs
->debug
& L1_DEB_ISAC
)
263 debugl1(cs
, "ISAC interrupt %x", val
);
264 if (val
& 0x80) { /* RME */
265 exval
= cs
->readisac(cs
, ISAC_RSTA
);
266 if ((exval
& 0x70) != 0x20) {
268 if (cs
->debug
& L1_DEB_WARN
)
269 debugl1(cs
, "ISAC RDO");
271 if (cs
->debug
& L1_DEB_WARN
)
272 debugl1(cs
, "ISAC CRC error");
273 cs
->writeisac(cs
, ISAC_CMDR
, 0x80);
275 count
= cs
->readisac(cs
, ISAC_RBCL
) & 0x1f;
278 isac_empty_fifo(cs
, count
);
281 if ((count
= cs
->rcvidx
) > 0) {
283 if (!(skb
= alloc_skb(count
, GFP_ATOMIC
)))
284 printk(KERN_WARNING
"HiSax: D receive out of memory\n");
286 memcpy(skb_put(skb
, count
), cs
->rcvbuf
, count
);
287 skb_queue_tail(&cs
->rq
, skb
);
290 restore_flags(flags
);
293 isac_sched_event(cs
, D_RCVBUFREADY
);
295 if (val
& 0x40) { /* RPF */
296 isac_empty_fifo(cs
, 32);
298 if (val
& 0x20) { /* RSC */
300 if (cs
->debug
& L1_DEB_WARN
)
301 debugl1(cs
, "ISAC RSC interrupt");
303 if (val
& 0x10) { /* XPR */
304 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
305 del_timer(&cs
->dbusytimer
);
306 if (test_and_clear_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
))
307 isac_sched_event(cs
, D_CLEARBUSY
);
309 if (cs
->tx_skb
->len
) {
313 dev_kfree_skb(cs
->tx_skb
);
318 if ((cs
->tx_skb
= skb_dequeue(&cs
->sq
))) {
322 isac_sched_event(cs
, D_XMTBUFREADY
);
325 if (val
& 0x04) { /* CISQ */
326 exval
= cs
->readisac(cs
, ISAC_CIR0
);
327 if (cs
->debug
& L1_DEB_ISAC
)
328 debugl1(cs
, "ISAC CIR0 %02X", exval
);
330 cs
->ph_state
= (exval
>> 2) & 0xf;
331 if (cs
->debug
& L1_DEB_ISAC
)
332 debugl1(cs
, "ph_state change %x", cs
->ph_state
);
333 isac_sched_event(cs
, D_L1STATECHANGE
);
336 exval
= cs
->readisac(cs
, ISAC_CIR1
);
337 if (cs
->debug
& L1_DEB_ISAC
)
338 debugl1(cs
, "ISAC CIR1 %02X", exval
);
341 if (val
& 0x02) { /* SIN */
343 if (cs
->debug
& L1_DEB_WARN
)
344 debugl1(cs
, "ISAC SIN interrupt");
346 if (val
& 0x01) { /* EXI */
347 exval
= cs
->readisac(cs
, ISAC_EXIR
);
348 if (cs
->debug
& L1_DEB_WARN
)
349 debugl1(cs
, "ISAC EXIR %02x", exval
);
351 v1
= cs
->readisac(cs
, ISAC_MOSR
);
352 if (cs
->debug
& L1_DEB_MONITOR
)
353 debugl1(cs
, "ISAC MOSR %02x", v1
);
357 if (!(cs
->mon_rx
= kmalloc(MAX_MON_FRAME
, GFP_ATOMIC
))) {
358 if (cs
->debug
& L1_DEB_WARN
)
359 debugl1(cs
, "ISAC MON RX out of memory!");
362 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
367 if (cs
->mon_rxp
>= MAX_MON_FRAME
) {
370 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
372 if (cs
->debug
& L1_DEB_WARN
)
373 debugl1(cs
, "ISAC MON RX overflow!");
376 cs
->mon_rx
[cs
->mon_rxp
++] = cs
->readisac(cs
, ISAC_MOR0
);
377 if (cs
->debug
& L1_DEB_MONITOR
)
378 debugl1(cs
, "ISAC MOR0 %02x", cs
->mon_rx
[cs
->mon_rxp
-1]);
379 if (cs
->mon_rxp
== 1) {
381 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
387 if (!(cs
->mon_rx
= kmalloc(MAX_MON_FRAME
, GFP_ATOMIC
))) {
388 if (cs
->debug
& L1_DEB_WARN
)
389 debugl1(cs
, "ISAC MON RX out of memory!");
392 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
397 if (cs
->mon_rxp
>= MAX_MON_FRAME
) {
400 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
402 if (cs
->debug
& L1_DEB_WARN
)
403 debugl1(cs
, "ISAC MON RX overflow!");
406 cs
->mon_rx
[cs
->mon_rxp
++] = cs
->readisac(cs
, ISAC_MOR1
);
407 if (cs
->debug
& L1_DEB_MONITOR
)
408 debugl1(cs
, "ISAC MOR1 %02x", cs
->mon_rx
[cs
->mon_rxp
-1]);
410 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
415 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
417 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
418 test_and_set_bit(HW_MON0_RX_END
, &cs
->HW_Flags
);
422 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
424 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
425 test_and_set_bit(HW_MON1_RX_END
, &cs
->HW_Flags
);
428 if ((!cs
->mon_tx
) || (cs
->mon_txc
&&
429 (cs
->mon_txp
>= cs
->mon_txc
) &&
432 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
434 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
436 (cs
->mon_txp
>= cs
->mon_txc
))
437 test_and_set_bit(HW_MON0_TX_END
, &cs
->HW_Flags
);
440 if (cs
->mon_txc
&& (cs
->mon_txp
>= cs
->mon_txc
)) {
441 test_and_set_bit(HW_MON0_TX_END
, &cs
->HW_Flags
);
444 cs
->writeisac(cs
, ISAC_MOX0
,
445 cs
->mon_tx
[cs
->mon_txp
++]);
446 if (cs
->debug
& L1_DEB_MONITOR
)
447 debugl1(cs
, "ISAC %02x -> MOX0", cs
->mon_tx
[cs
->mon_txp
-1]);
451 if ((!cs
->mon_tx
) || (cs
->mon_txc
&&
452 (cs
->mon_txp
>= cs
->mon_txc
) &&
455 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
457 cs
->writeisac(cs
, ISAC_MOCR
, cs
->mocr
);
459 (cs
->mon_txp
>= cs
->mon_txc
))
460 test_and_set_bit(HW_MON1_TX_END
, &cs
->HW_Flags
);
463 if (cs
->mon_txc
&& (cs
->mon_txp
>= cs
->mon_txc
)) {
464 test_and_set_bit(HW_MON1_TX_END
, &cs
->HW_Flags
);
467 cs
->writeisac(cs
, ISAC_MOX1
,
468 cs
->mon_tx
[cs
->mon_txp
++]);
469 if (cs
->debug
& L1_DEB_MONITOR
)
470 debugl1(cs
, "ISAC %02x -> MOX1", cs
->mon_tx
[cs
->mon_txp
-1]);
479 ISAC_l1hw(struct PStack
*st
, int pr
, void *arg
)
481 struct IsdnCardState
*cs
= (struct IsdnCardState
*) st
->l1
.hardware
;
482 struct sk_buff
*skb
= arg
;
486 case (PH_DATA
|REQUEST
):
487 if (cs
->debug
& DEB_DLOG_HEX
)
488 LogFrame(cs
, skb
->data
, skb
->len
);
489 if (cs
->debug
& DEB_DLOG_VERBOSE
)
490 dlogframe(cs
, skb
, 0);
492 skb_queue_tail(&cs
->sq
, skb
);
493 #ifdef L2FRAME_DEBUG /* psa */
494 if (cs
->debug
& L1_DEB_LAPD
)
495 Logl2Frame(cs
, skb
, "PH_DATA Queued", 0);
500 #ifdef L2FRAME_DEBUG /* psa */
501 if (cs
->debug
& L1_DEB_LAPD
)
502 Logl2Frame(cs
, skb
, "PH_DATA", 0);
507 case (PH_PULL
|INDICATION
):
509 if (cs
->debug
& L1_DEB_WARN
)
510 debugl1(cs
, " l2l1 tx_skb exist this shouldn't happen");
511 skb_queue_tail(&cs
->sq
, skb
);
514 if (cs
->debug
& DEB_DLOG_HEX
)
515 LogFrame(cs
, skb
->data
, skb
->len
);
516 if (cs
->debug
& DEB_DLOG_VERBOSE
)
517 dlogframe(cs
, skb
, 0);
520 #ifdef L2FRAME_DEBUG /* psa */
521 if (cs
->debug
& L1_DEB_LAPD
)
522 Logl2Frame(cs
, skb
, "PH_DATA_PULLED", 0);
526 case (PH_PULL
| REQUEST
):
527 #ifdef L2FRAME_DEBUG /* psa */
528 if (cs
->debug
& L1_DEB_LAPD
)
529 debugl1(cs
, "-> PH_REQUEST_PULL");
532 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
533 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
535 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
537 case (HW_RESET
| REQUEST
):
538 if ((cs
->ph_state
== ISAC_IND_EI
) ||
539 (cs
->ph_state
== ISAC_IND_DR
) ||
540 (cs
->ph_state
== ISAC_IND_RS
))
541 ph_command(cs
, ISAC_CMD_TIM
);
543 ph_command(cs
, ISAC_CMD_RS
);
545 case (HW_ENABLE
| REQUEST
):
546 ph_command(cs
, ISAC_CMD_TIM
);
548 case (HW_INFO3
| REQUEST
):
549 ph_command(cs
, ISAC_CMD_AR8
);
551 case (HW_TESTLOOP
| REQUEST
):
557 if (test_bit(HW_IOM1
, &cs
->HW_Flags
)) {
560 cs
->writeisac(cs
, ISAC_SPCR
, 0xa);
561 cs
->writeisac(cs
, ISAC_ADF1
, 0x2);
563 cs
->writeisac(cs
, ISAC_SPCR
, val
);
564 cs
->writeisac(cs
, ISAC_ADF1
, 0xa);
568 cs
->writeisac(cs
, ISAC_SPCR
, val
);
570 cs
->writeisac(cs
, ISAC_ADF1
, 0x8);
572 cs
->writeisac(cs
, ISAC_ADF1
, 0x0);
575 case (HW_DEACTIVATE
| RESPONSE
):
576 discard_queue(&cs
->rq
);
577 discard_queue(&cs
->sq
);
579 dev_kfree_skb(cs
->tx_skb
);
582 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
583 del_timer(&cs
->dbusytimer
);
584 if (test_and_clear_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
))
585 isac_sched_event(cs
, D_CLEARBUSY
);
588 if (cs
->debug
& L1_DEB_WARN
)
589 debugl1(cs
, "isac_l1hw unknown %04x", pr
);
595 setstack_isac(struct PStack
*st
, struct IsdnCardState
*cs
)
597 st
->l1
.l1hw
= ISAC_l1hw
;
601 dbusy_timer_handler(struct IsdnCardState
*cs
)
603 struct PStack
*stptr
;
606 if (test_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
608 debugl1(cs
, "D-Channel Busy");
609 val
= cs
->readisac(cs
, ISAC_RBCH
);
610 if (val
& ISAC_RBCH_XAC
)
611 debugl1(cs
, "ISAC XAC");
613 debugl1(cs
, "ISAC No XAC");
615 test_and_set_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
);
618 while (stptr
!= NULL
) {
619 stptr
->l1
.l1l2(stptr
, PH_PAUSE
| INDICATION
, NULL
);
626 initisac(struct IsdnCardState
*cs
))
628 cs
->tqueue
.routine
= (void *) (void *) isac_bh
;
629 cs
->setstack_d
= setstack_isac
;
630 cs
->dbusytimer
.function
= (void *) dbusy_timer_handler
;
631 cs
->dbusytimer
.data
= (long) cs
;
632 init_timer(&cs
->dbusytimer
);
633 cs
->writeisac(cs
, ISAC_MASK
, 0xff);
635 if (test_bit(HW_IOM1
, &cs
->HW_Flags
)) {
637 cs
->writeisac(cs
, ISAC_ADF2
, 0x0);
638 cs
->writeisac(cs
, ISAC_SPCR
, 0xa);
639 cs
->writeisac(cs
, ISAC_ADF1
, 0x2);
640 cs
->writeisac(cs
, ISAC_STCR
, 0x70);
641 cs
->writeisac(cs
, ISAC_MODE
, 0xc9);
644 cs
->writeisac(cs
, ISAC_ADF2
, 0x80);
645 cs
->writeisac(cs
, ISAC_SQXR
, 0x2f);
646 cs
->writeisac(cs
, ISAC_SPCR
, 0x00);
647 cs
->writeisac(cs
, ISAC_STCR
, 0x70);
648 cs
->writeisac(cs
, ISAC_MODE
, 0xc9);
649 cs
->writeisac(cs
, ISAC_TIMR
, 0x00);
650 cs
->writeisac(cs
, ISAC_ADF1
, 0x00);
652 ph_command(cs
, ISAC_CMD_RS
);
653 cs
->writeisac(cs
, ISAC_MASK
, 0x0);
657 clear_pending_isac_ints(struct IsdnCardState
*cs
))
661 val
= cs
->readisac(cs
, ISAC_STAR
);
662 debugl1(cs
, "ISAC STAR %x", val
);
663 val
= cs
->readisac(cs
, ISAC_MODE
);
664 debugl1(cs
, "ISAC MODE %x", val
);
665 val
= cs
->readisac(cs
, ISAC_ADF2
);
666 debugl1(cs
, "ISAC ADF2 %x", val
);
667 val
= cs
->readisac(cs
, ISAC_ISTA
);
668 debugl1(cs
, "ISAC ISTA %x", val
);
670 eval
= cs
->readisac(cs
, ISAC_EXIR
);
671 debugl1(cs
, "ISAC EXIR %x", eval
);
673 val
= cs
->readisac(cs
, ISAC_CIR0
);
674 debugl1(cs
, "ISAC CIR0 %x", val
);
675 cs
->ph_state
= (val
>> 2) & 0xf;
676 isac_sched_event(cs
, D_L1STATECHANGE
);
677 /* Disable all IRQ */
678 cs
->writeisac(cs
, ISAC_MASK
, 0xFF);