3 * IPACX specific routines
5 * Author Joerg Petersohn
6 * Derived from hisax_isac.c, isac.c, hscx.c and others
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
12 #include <linux/kernel.h>
13 #include <linux/config.h>
14 #include <linux/init.h>
20 #define DBUSY_TIMER_VALUE 80
21 #define TIMER3_VALUE 7000
22 #define MAX_DFRAME_LEN_L1 300
23 #define B_FIFO_SIZE 64
24 #define D_FIFO_SIZE 32
27 // ipacx interrupt mask values
28 #define _MASK_IMASK 0x2E // global mask
29 #define _MASKB_IMASK 0x0B
30 #define _MASKD_IMASK 0x03 // all on
32 //----------------------------------------------------------
33 // local function declarations
34 //----------------------------------------------------------
35 static void ph_command(struct IsdnCardState
*cs
, unsigned int command
);
36 static inline void cic_int(struct IsdnCardState
*cs
);
37 static void dch_l2l1(struct PStack
*st
, int pr
, void *arg
);
38 static void dbusy_timer_handler(struct IsdnCardState
*cs
);
39 static void ipacx_new_ph(struct IsdnCardState
*cs
);
40 static void dch_bh(struct IsdnCardState
*cs
);
41 static void dch_empty_fifo(struct IsdnCardState
*cs
, int count
);
42 static void dch_fill_fifo(struct IsdnCardState
*cs
);
43 static inline void dch_int(struct IsdnCardState
*cs
);
44 static void __devinit
dch_setstack(struct PStack
*st
, struct IsdnCardState
*cs
);
45 static void __devinit
dch_init(struct IsdnCardState
*cs
);
46 static void bch_l2l1(struct PStack
*st
, int pr
, void *arg
);
47 static void bch_empty_fifo(struct BCState
*bcs
, int count
);
48 static void bch_fill_fifo(struct BCState
*bcs
);
49 static void bch_int(struct IsdnCardState
*cs
, u_char hscx
);
50 static void bch_mode(struct BCState
*bcs
, int mode
, int bc
);
51 static void bch_close_state(struct BCState
*bcs
);
52 static int bch_open_state(struct IsdnCardState
*cs
, struct BCState
*bcs
);
53 static int bch_setstack(struct PStack
*st
, struct BCState
*bcs
);
54 static void __devinit
bch_init(struct IsdnCardState
*cs
, int hscx
);
55 static void __init
clear_pending_ints(struct IsdnCardState
*cs
);
57 //----------------------------------------------------------
58 // Issue Layer 1 command to chip
59 //----------------------------------------------------------
61 ph_command(struct IsdnCardState
*cs
, unsigned int command
)
63 if (cs
->debug
&L1_DEB_ISAC
)
64 debugl1(cs
, "ph_command (%#x) in (%#x)", command
,
65 cs
->dc
.isac
.ph_state
);
66 //###################################
67 // printk(KERN_INFO "ph_command (%#x)\n", command);
68 //###################################
69 cs
->writeisac(cs
, IPACX_CIX0
, (command
<< 4) | 0x0E);
72 //----------------------------------------------------------
73 // Transceiver interrupt handler
74 //----------------------------------------------------------
76 cic_int(struct IsdnCardState
*cs
)
80 event
= cs
->readisac(cs
, IPACX_CIR0
) >> 4;
81 if (cs
->debug
&L1_DEB_ISAC
) debugl1(cs
, "cic_int(event=%#x)", event
);
82 //#########################################
83 // printk(KERN_INFO "cic_int(%x)\n", event);
84 //#########################################
85 cs
->dc
.isac
.ph_state
= event
;
86 schedule_event(cs
, D_L1STATECHANGE
);
89 //==========================================================
90 // D channel functions
91 //==========================================================
93 //----------------------------------------------------------
94 // Command entry point
95 //----------------------------------------------------------
97 dch_l2l1(struct PStack
*st
, int pr
, void *arg
)
99 struct IsdnCardState
*cs
= (struct IsdnCardState
*) st
->l1
.hardware
;
100 struct sk_buff
*skb
= arg
;
101 u_char cda1_cr
, cda2_cr
;
104 case (PH_DATA
|REQUEST
):
105 if (cs
->debug
&DEB_DLOG_HEX
) LogFrame(cs
, skb
->data
, skb
->len
);
106 if (cs
->debug
&DEB_DLOG_VERBOSE
) dlogframe(cs
, skb
, 0);
108 skb_queue_tail(&cs
->sq
, skb
);
110 if (cs
->debug
&L1_DEB_LAPD
) Logl2Frame(cs
, skb
, "PH_DATA Queued", 0);
116 if (cs
->debug
&L1_DEB_LAPD
) Logl2Frame(cs
, skb
, "PH_DATA", 0);
122 case (PH_PULL
|INDICATION
):
124 if (cs
->debug
& L1_DEB_WARN
)
125 debugl1(cs
, " l2l1 tx_skb exist this shouldn't happen");
126 skb_queue_tail(&cs
->sq
, skb
);
129 if (cs
->debug
& DEB_DLOG_HEX
) LogFrame(cs
, skb
->data
, skb
->len
);
130 if (cs
->debug
& DEB_DLOG_VERBOSE
) dlogframe(cs
, skb
, 0);
134 if (cs
->debug
& L1_DEB_LAPD
) Logl2Frame(cs
, skb
, "PH_DATA_PULLED", 0);
139 case (PH_PULL
| REQUEST
):
141 if (cs
->debug
& L1_DEB_LAPD
) debugl1(cs
, "-> PH_REQUEST_PULL");
144 clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
145 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
147 set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
150 case (HW_RESET
| REQUEST
):
151 case (HW_ENABLE
| REQUEST
):
152 if ((cs
->dc
.isac
.ph_state
== IPACX_IND_RES
) ||
153 (cs
->dc
.isac
.ph_state
== IPACX_IND_DR
) ||
154 (cs
->dc
.isac
.ph_state
== IPACX_IND_DC
))
155 ph_command(cs
, IPACX_CMD_TIM
);
157 ph_command(cs
, IPACX_CMD_RES
);
160 case (HW_INFO3
| REQUEST
):
161 ph_command(cs
, IPACX_CMD_AR8
);
164 case (HW_TESTLOOP
| REQUEST
):
165 cs
->writeisac(cs
, IPACX_CDA_TSDP10
, 0x80); // Timeslot 0 is B1
166 cs
->writeisac(cs
, IPACX_CDA_TSDP11
, 0x81); // Timeslot 0 is B1
167 cda1_cr
= cs
->readisac(cs
, IPACX_CDA1_CR
);
168 cda2_cr
= cs
->readisac(cs
, IPACX_CDA2_CR
);
169 if ((long)arg
&1) { // loop B1
170 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
|0x0a);
173 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
&~0x0a);
175 if ((long)arg
&2) { // loop B2
176 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
|0x14);
179 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
&~0x14);
183 case (HW_DEACTIVATE
| RESPONSE
):
184 skb_queue_purge(&cs
->rq
);
185 skb_queue_purge(&cs
->sq
);
187 dev_kfree_skb_any(cs
->tx_skb
);
190 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
191 del_timer(&cs
->dbusytimer
);
195 if (cs
->debug
&L1_DEB_WARN
) debugl1(cs
, "dch_l2l1 unknown %04x", pr
);
200 //----------------------------------------------------------
201 //----------------------------------------------------------
203 dbusy_timer_handler(struct IsdnCardState
*cs
)
208 if (test_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
209 rbchd
= cs
->readisac(cs
, IPACX_RBCHD
);
210 stard
= cs
->readisac(cs
, IPACX_STARD
);
212 debugl1(cs
, "D-Channel Busy RBCHD %02x STARD %02x", rbchd
, stard
);
213 if (!(stard
&0x40)) { // D-Channel Busy
214 set_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
);
215 for (st
= cs
->stlist
; st
; st
= st
->next
) {
216 st
->l1
.l1l2(st
, PH_PAUSE
| INDICATION
, NULL
); // flow control on
219 // seems we lost an interrupt; reset transceiver */
220 clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
);
222 dev_kfree_skb_any(cs
->tx_skb
);
226 printk(KERN_WARNING
"HiSax: ISAC D-Channel Busy no skb\n");
227 debugl1(cs
, "D-Channel Busy no skb");
229 cs
->writeisac(cs
, IPACX_CMDRD
, 0x01); // Tx reset, generates XPR
234 //----------------------------------------------------------
235 // L1 state machine intermediate layer to isdnl1 module
236 //----------------------------------------------------------
238 ipacx_new_ph(struct IsdnCardState
*cs
)
240 switch (cs
->dc
.isac
.ph_state
) {
241 case (IPACX_IND_RES
):
242 ph_command(cs
, IPACX_CMD_DI
);
243 l1_msg(cs
, HW_RESET
| INDICATION
, NULL
);
247 l1_msg(cs
, HW_DEACTIVATE
| CONFIRM
, NULL
);
251 l1_msg(cs
, HW_DEACTIVATE
| INDICATION
, NULL
);
255 l1_msg(cs
, HW_POWERUP
| CONFIRM
, NULL
);
258 case (IPACX_IND_RSY
):
259 l1_msg(cs
, HW_RSYNC
| INDICATION
, NULL
);
263 l1_msg(cs
, HW_INFO2
| INDICATION
, NULL
);
266 case (IPACX_IND_AI8
):
267 l1_msg(cs
, HW_INFO4_P8
| INDICATION
, NULL
);
270 case (IPACX_IND_AI10
):
271 l1_msg(cs
, HW_INFO4_P10
| INDICATION
, NULL
);
279 //----------------------------------------------------------
280 // bottom half handler for D channel
281 //----------------------------------------------------------
283 dch_bh(struct IsdnCardState
*cs
)
289 if (test_and_clear_bit(D_CLEARBUSY
, &cs
->event
)) {
290 if (cs
->debug
) debugl1(cs
, "D-Channel Busy cleared");
291 for (st
= cs
->stlist
; st
; st
= st
->next
) {
292 st
->l1
.l1l2(st
, PH_PAUSE
| CONFIRM
, NULL
);
296 if (test_and_clear_bit(D_RCVBUFREADY
, &cs
->event
)) {
297 DChannel_proc_rcv(cs
);
300 if (test_and_clear_bit(D_XMTBUFREADY
, &cs
->event
)) {
301 DChannel_proc_xmt(cs
);
304 if (test_and_clear_bit(D_L1STATECHANGE
, &cs
->event
)) {
309 //----------------------------------------------------------
310 // Fill buffer from receive FIFO
311 //----------------------------------------------------------
313 dch_empty_fifo(struct IsdnCardState
*cs
, int count
)
317 if ((cs
->debug
&L1_DEB_ISAC
) && !(cs
->debug
&L1_DEB_ISAC_FIFO
))
318 debugl1(cs
, "dch_empty_fifo()");
320 // message too large, remove
321 if ((cs
->rcvidx
+ count
) >= MAX_DFRAME_LEN_L1
) {
322 if (cs
->debug
&L1_DEB_WARN
)
323 debugl1(cs
, "dch_empty_fifo() incoming message too large");
324 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
329 ptr
= cs
->rcvbuf
+ cs
->rcvidx
;
332 cs
->readisacfifo(cs
, ptr
, count
);
333 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
335 if (cs
->debug
&L1_DEB_ISAC_FIFO
) {
338 t
+= sprintf(t
, "dch_empty_fifo() cnt %d", count
);
339 QuickHex(t
, ptr
, count
);
340 debugl1(cs
, cs
->dlog
);
344 //----------------------------------------------------------
345 // Fill transmit FIFO
346 //----------------------------------------------------------
348 dch_fill_fifo(struct IsdnCardState
*cs
)
353 if ((cs
->debug
&L1_DEB_ISAC
) && !(cs
->debug
&L1_DEB_ISAC_FIFO
))
354 debugl1(cs
, "dch_fill_fifo()");
356 if (!cs
->tx_skb
) return;
357 count
= cs
->tx_skb
->len
;
358 if (count
<= 0) return;
360 if (count
> D_FIFO_SIZE
) {
364 cmd
= 0x0A; // XTF | XME
367 ptr
= cs
->tx_skb
->data
;
368 skb_pull(cs
->tx_skb
, count
);
370 cs
->writeisacfifo(cs
, ptr
, count
);
371 cs
->writeisac(cs
, IPACX_CMDRD
, cmd
);
373 // set timeout for transmission contol
374 if (test_and_set_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
375 debugl1(cs
, "dch_fill_fifo dbusytimer running");
376 del_timer(&cs
->dbusytimer
);
378 init_timer(&cs
->dbusytimer
);
379 cs
->dbusytimer
.expires
= jiffies
+ ((DBUSY_TIMER_VALUE
* HZ
)/1000);
380 add_timer(&cs
->dbusytimer
);
382 if (cs
->debug
&L1_DEB_ISAC_FIFO
) {
385 t
+= sprintf(t
, "dch_fill_fifo() cnt %d", count
);
386 QuickHex(t
, ptr
, count
);
387 debugl1(cs
, cs
->dlog
);
391 //----------------------------------------------------------
392 // D channel interrupt handler
393 //----------------------------------------------------------
395 dch_int(struct IsdnCardState
*cs
)
401 istad
= cs
->readisac(cs
, IPACX_ISTAD
);
402 //##############################################
403 // printk(KERN_WARNING "dch_int(istad=%02x)\n", istad);
404 //##############################################
406 if (istad
&0x80) { // RME
407 rstad
= cs
->readisac(cs
, IPACX_RSTAD
);
408 if ((rstad
&0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
410 if (cs
->debug
&L1_DEB_WARN
)
411 debugl1(cs
, "dch_int(): invalid frame");
413 if (cs
->debug
&L1_DEB_WARN
)
414 debugl1(cs
, "dch_int(): RDO");
416 if (cs
->debug
&L1_DEB_WARN
)
417 debugl1(cs
, "dch_int(): CRC error");
418 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
419 } else { // received frame ok
420 count
= cs
->readisac(cs
, IPACX_RBCLD
);
421 if (count
) count
--; // RSTAB is last byte
422 count
&= D_FIFO_SIZE
-1;
423 if (count
== 0) count
= D_FIFO_SIZE
;
424 dch_empty_fifo(cs
, count
);
425 if ((count
= cs
->rcvidx
) > 0) {
427 if (!(skb
= dev_alloc_skb(count
)))
428 printk(KERN_WARNING
"HiSax dch_int(): receive out of memory\n");
430 memcpy(skb_put(skb
, count
), cs
->rcvbuf
, count
);
431 skb_queue_tail(&cs
->rq
, skb
);
436 schedule_event(cs
, D_RCVBUFREADY
);
439 if (istad
&0x40) { // RPF
440 dch_empty_fifo(cs
, D_FIFO_SIZE
);
443 if (istad
&0x20) { // RFO
444 if (cs
->debug
&L1_DEB_WARN
) debugl1(cs
, "dch_int(): RFO");
445 cs
->writeisac(cs
, IPACX_CMDRD
, 0x40); //RRES
448 if (istad
&0x10) { // XPR
449 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
450 del_timer(&cs
->dbusytimer
);
451 if (test_and_clear_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
))
452 schedule_event(cs
, D_CLEARBUSY
);
454 if (cs
->tx_skb
->len
) {
459 dev_kfree_skb_irq(cs
->tx_skb
);
464 if ((cs
->tx_skb
= skb_dequeue(&cs
->sq
))) {
469 schedule_event(cs
, D_XMTBUFREADY
);
474 if (istad
&0x0C) { // XDU or XMR
475 if (cs
->debug
&L1_DEB_WARN
) debugl1(cs
, "dch_int(): XDU");
477 skb_push(cs
->tx_skb
, cs
->tx_cnt
); // retransmit
481 printk(KERN_WARNING
"HiSax: ISAC XDU no skb\n");
482 debugl1(cs
, "ISAC XDU no skb");
487 //----------------------------------------------------------
488 //----------------------------------------------------------
489 static void __devinit
490 dch_setstack(struct PStack
*st
, struct IsdnCardState
*cs
)
492 st
->l1
.l1hw
= dch_l2l1
;
495 //----------------------------------------------------------
496 //----------------------------------------------------------
497 static void __devinit
498 dch_init(struct IsdnCardState
*cs
)
500 printk(KERN_INFO
"HiSax: IPACX ISDN driver v0.1.0\n");
502 cs
->setstack_d
= dch_setstack
;
504 cs
->dbusytimer
.function
= (void *) dbusy_timer_handler
;
505 cs
->dbusytimer
.data
= (long) cs
;
506 init_timer(&cs
->dbusytimer
);
508 cs
->writeisac(cs
, IPACX_TR_CONF0
, 0x00); // clear LDD
509 cs
->writeisac(cs
, IPACX_TR_CONF2
, 0x00); // enable transmitter
510 cs
->writeisac(cs
, IPACX_MODED
, 0xC9); // transparent mode 0, RAC, stop/go
511 cs
->writeisac(cs
, IPACX_MON_CR
, 0x00); // disable monitor channel
515 //==========================================================
516 // B channel functions
517 //==========================================================
519 //----------------------------------------------------------
520 // Entry point for commands
521 //----------------------------------------------------------
523 bch_l2l1(struct PStack
*st
, int pr
, void *arg
)
525 struct BCState
*bcs
= st
->l1
.bcs
;
526 struct sk_buff
*skb
= arg
;
530 case (PH_DATA
| REQUEST
):
531 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
533 skb_queue_tail(&bcs
->squeue
, skb
);
536 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
537 bcs
->hw
.hscx
.count
= 0;
540 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
542 case (PH_PULL
| INDICATION
):
543 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
545 printk(KERN_WARNING
"HiSax bch_l2l1(): this shouldn't happen\n");
547 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
549 bcs
->hw
.hscx
.count
= 0;
552 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
554 case (PH_PULL
| REQUEST
):
556 clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
557 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
559 set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
561 case (PH_ACTIVATE
| REQUEST
):
562 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
563 set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
564 bch_mode(bcs
, st
->l1
.mode
, st
->l1
.bc
);
565 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
566 l1_msg_b(st
, pr
, arg
);
568 case (PH_DEACTIVATE
| REQUEST
):
569 l1_msg_b(st
, pr
, arg
);
571 case (PH_DEACTIVATE
| CONFIRM
):
572 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
573 clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
574 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
575 bch_mode(bcs
, 0, st
->l1
.bc
);
576 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
577 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
582 //----------------------------------------------------------
583 // Read B channel fifo to receive buffer
584 //----------------------------------------------------------
586 bch_empty_fifo(struct BCState
*bcs
, int count
)
589 struct IsdnCardState
*cs
;
593 hscx
= bcs
->hw
.hscx
.hscx
;
594 if ((cs
->debug
&L1_DEB_HSCX
) && !(cs
->debug
&L1_DEB_HSCX_FIFO
))
595 debugl1(cs
, "bch_empty_fifo()");
597 // message too large, remove
598 if (bcs
->hw
.hscx
.rcvidx
+ count
> HSCX_BUFMAX
) {
599 if (cs
->debug
&L1_DEB_WARN
)
600 debugl1(cs
, "bch_empty_fifo() incoming packet too large");
601 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
602 bcs
->hw
.hscx
.rcvidx
= 0;
606 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
608 while (cnt
--) *ptr
++ = cs
->BC_Read_Reg(cs
, hscx
, IPACX_RFIFOB
);
609 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
611 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
612 bcs
->hw
.hscx
.rcvidx
+= count
;
614 if (cs
->debug
&L1_DEB_HSCX_FIFO
) {
617 t
+= sprintf(t
, "bch_empty_fifo() B-%d cnt %d", hscx
, count
);
618 QuickHex(t
, ptr
, count
);
619 debugl1(cs
, bcs
->blog
);
623 //----------------------------------------------------------
624 // Fill buffer to transmit FIFO
625 //----------------------------------------------------------
627 bch_fill_fifo(struct BCState
*bcs
)
629 struct IsdnCardState
*cs
;
630 int more
, count
, cnt
;
631 u_char
*ptr
, *p
, hscx
;
634 if ((cs
->debug
&L1_DEB_HSCX
) && !(cs
->debug
&L1_DEB_HSCX_FIFO
))
635 debugl1(cs
, "bch_fill_fifo()");
637 if (!bcs
->tx_skb
) return;
638 if (bcs
->tx_skb
->len
<= 0) return;
640 hscx
= bcs
->hw
.hscx
.hscx
;
641 more
= (bcs
->mode
== L1_MODE_TRANS
) ? 1 : 0;
642 if (bcs
->tx_skb
->len
> B_FIFO_SIZE
) {
646 count
= bcs
->tx_skb
->len
;
650 p
= ptr
= bcs
->tx_skb
->data
;
651 skb_pull(bcs
->tx_skb
, count
);
652 bcs
->tx_cnt
-= count
;
653 bcs
->hw
.hscx
.count
+= count
;
654 while (cnt
--) cs
->BC_Write_Reg(cs
, hscx
, IPACX_XFIFOB
, *p
++);
655 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, (more
? 0x08 : 0x0a));
657 if (cs
->debug
&L1_DEB_HSCX_FIFO
) {
660 t
+= sprintf(t
, "chb_fill_fifo() B-%d cnt %d", hscx
, count
);
661 QuickHex(t
, ptr
, count
);
662 debugl1(cs
, bcs
->blog
);
666 //----------------------------------------------------------
667 // B channel interrupt handler
668 //----------------------------------------------------------
670 bch_int(struct IsdnCardState
*cs
, u_char hscx
)
678 bcs
= cs
->bcs
+ hscx
;
679 istab
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_ISTAB
);
680 //##############################################
681 // printk(KERN_WARNING "bch_int(istab=%02x)\n", istab);
682 //##############################################
683 if (!test_bit(BC_FLG_INIT
, &bcs
->Flag
)) return;
685 if (istab
&0x80) { // RME
686 rstab
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_RSTAB
);
687 if ((rstab
&0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
689 if (cs
->debug
&L1_DEB_WARN
)
690 debugl1(cs
, "bch_int() B-%d: invalid frame", hscx
);
691 if ((rstab
&0x40) && (bcs
->mode
!= L1_MODE_NULL
))
692 if (cs
->debug
&L1_DEB_WARN
)
693 debugl1(cs
, "bch_int() B-%d: RDO mode=%d", hscx
, bcs
->mode
);
695 if (cs
->debug
&L1_DEB_WARN
)
696 debugl1(cs
, "bch_int() B-%d: CRC error", hscx
);
697 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
699 else { // received frame ok
700 count
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_RBCLB
) &(B_FIFO_SIZE
-1);
701 if (count
== 0) count
= B_FIFO_SIZE
;
702 bch_empty_fifo(bcs
, count
);
703 if ((count
= bcs
->hw
.hscx
.rcvidx
- 1) > 0) {
704 if (cs
->debug
&L1_DEB_HSCX_FIFO
)
705 debugl1(cs
, "bch_int Frame %d", count
);
706 if (!(skb
= dev_alloc_skb(count
)))
707 printk(KERN_WARNING
"HiSax bch_int(): receive frame out of memory\n");
709 memcpy(skb_put(skb
, count
), bcs
->hw
.hscx
.rcvbuf
, count
);
710 skb_queue_tail(&bcs
->rqueue
, skb
);
714 bcs
->hw
.hscx
.rcvidx
= 0;
715 schedule_event(bcs
, B_RCVBUFREADY
);
718 if (istab
&0x40) { // RPF
719 bch_empty_fifo(bcs
, B_FIFO_SIZE
);
721 if (bcs
->mode
== L1_MODE_TRANS
) { // queue every chunk
722 // receive transparent audio data
723 if (!(skb
= dev_alloc_skb(B_FIFO_SIZE
)))
724 printk(KERN_WARNING
"HiSax bch_int(): receive transparent out of memory\n");
726 memcpy(skb_put(skb
, B_FIFO_SIZE
), bcs
->hw
.hscx
.rcvbuf
, B_FIFO_SIZE
);
727 skb_queue_tail(&bcs
->rqueue
, skb
);
729 bcs
->hw
.hscx
.rcvidx
= 0;
730 schedule_event(bcs
, B_RCVBUFREADY
);
734 if (istab
&0x20) { // RFO
735 if (cs
->debug
&L1_DEB_WARN
)
736 debugl1(cs
, "bch_int() B-%d: RFO error", hscx
);
737 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x40); // RRES
740 if (istab
&0x10) { // XPR
742 if (bcs
->tx_skb
->len
) {
746 if (test_bit(FLG_LLI_L1WAKEUP
,&bcs
->st
->lli
.flag
) &&
747 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
749 spin_lock_irqsave(&bcs
->aclock
, flags
);
750 bcs
->ackcnt
+= bcs
->hw
.hscx
.count
;
751 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
752 schedule_event(bcs
, B_ACKPENDING
);
755 dev_kfree_skb_irq(bcs
->tx_skb
);
756 bcs
->hw
.hscx
.count
= 0;
759 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
760 bcs
->hw
.hscx
.count
= 0;
761 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
764 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
765 schedule_event(bcs
, B_XMTBUFREADY
);
770 if (istab
&0x04) { // XDU
771 if (bcs
->mode
== L1_MODE_TRANS
) {
775 if (bcs
->tx_skb
) { // restart transmitting the whole frame
776 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
777 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
778 bcs
->hw
.hscx
.count
= 0;
780 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x01); // XRES
781 if (cs
->debug
&L1_DEB_WARN
)
782 debugl1(cs
, "bch_int() B-%d XDU error", hscx
);
787 //----------------------------------------------------------
788 //----------------------------------------------------------
790 bch_mode(struct BCState
*bcs
, int mode
, int bc
)
792 struct IsdnCardState
*cs
= bcs
->cs
;
793 int hscx
= bcs
->hw
.hscx
.hscx
;
795 bc
= bc
? 1 : 0; // in case bc is greater than 1
796 if (cs
->debug
& L1_DEB_HSCX
)
797 debugl1(cs
, "mode_bch() switch B-% mode %d chan %d", hscx
, mode
, bc
);
801 // map controller to according timeslot
804 cs
->writeisac(cs
, IPACX_BCHA_TSDP_BC1
, 0x80 | bc
);
805 cs
->writeisac(cs
, IPACX_BCHA_CR
, 0x88);
809 cs
->writeisac(cs
, IPACX_BCHB_TSDP_BC1
, 0x80 | bc
);
810 cs
->writeisac(cs
, IPACX_BCHB_CR
, 0x88);
815 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0xC0); // rec off
816 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x30); // std adj.
817 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, 0xFF); // ints off
818 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
820 case (L1_MODE_TRANS
):
821 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0x88); // ext transp mode
822 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x00); // xxx00000
823 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
824 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, _MASKB_IMASK
);
827 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0xC8); // transp mode 0
828 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x01); // idle=hdlc flags crc enabled
829 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
830 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, _MASKB_IMASK
);
835 //----------------------------------------------------------
836 //----------------------------------------------------------
838 bch_close_state(struct BCState
*bcs
)
840 bch_mode(bcs
, 0, bcs
->channel
);
841 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
842 if (bcs
->hw
.hscx
.rcvbuf
) {
843 kfree(bcs
->hw
.hscx
.rcvbuf
);
844 bcs
->hw
.hscx
.rcvbuf
= NULL
;
850 skb_queue_purge(&bcs
->rqueue
);
851 skb_queue_purge(&bcs
->squeue
);
853 dev_kfree_skb_any(bcs
->tx_skb
);
855 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
860 //----------------------------------------------------------
861 //----------------------------------------------------------
863 bch_open_state(struct IsdnCardState
*cs
, struct BCState
*bcs
)
865 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
866 if (!(bcs
->hw
.hscx
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
868 "HiSax open_bchstate(): No memory for hscx.rcvbuf\n");
869 clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
872 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
874 "HiSax open_bchstate: No memory for bcs->blog\n");
875 clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
876 kfree(bcs
->hw
.hscx
.rcvbuf
);
877 bcs
->hw
.hscx
.rcvbuf
= NULL
;
880 skb_queue_head_init(&bcs
->rqueue
);
881 skb_queue_head_init(&bcs
->squeue
);
884 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
886 bcs
->hw
.hscx
.rcvidx
= 0;
891 //----------------------------------------------------------
892 //----------------------------------------------------------
894 bch_setstack(struct PStack
*st
, struct BCState
*bcs
)
896 bcs
->channel
= st
->l1
.bc
;
897 if (bch_open_state(st
->l1
.hardware
, bcs
)) return (-1);
899 st
->l2
.l2l1
= bch_l2l1
;
900 setstack_manager(st
);
906 //----------------------------------------------------------
907 //----------------------------------------------------------
908 static void __devinit
909 bch_init(struct IsdnCardState
*cs
, int hscx
)
911 cs
->bcs
[hscx
].BC_SetStack
= bch_setstack
;
912 cs
->bcs
[hscx
].BC_Close
= bch_close_state
;
913 cs
->bcs
[hscx
].hw
.hscx
.hscx
= hscx
;
914 cs
->bcs
[hscx
].cs
= cs
;
915 bch_mode(cs
->bcs
+ hscx
, 0, hscx
);
919 //==========================================================
921 //==========================================================
923 //----------------------------------------------------------
924 // Main interrupt handler
925 //----------------------------------------------------------
927 interrupt_ipacx(struct IsdnCardState
*cs
)
931 while ((ista
= cs
->readisac(cs
, IPACX_ISTA
))) {
932 //#################################################
933 // printk(KERN_WARNING "interrupt_ipacx(ista=%02x)\n", ista);
934 //#################################################
935 if (ista
&0x80) bch_int(cs
, 0); // B channel interrupts
936 if (ista
&0x40) bch_int(cs
, 1);
938 if (ista
&0x01) dch_int(cs
); // D channel
939 if (ista
&0x10) cic_int(cs
); // Layer 1 state
943 //----------------------------------------------------------
944 // Clears chip interrupt status
945 //----------------------------------------------------------
947 clear_pending_ints(struct IsdnCardState
*cs
)
951 // all interrupts off
952 cs
->writeisac(cs
, IPACX_MASK
, 0xff);
953 cs
->writeisac(cs
, IPACX_MASKD
, 0xff);
954 cs
->BC_Write_Reg(cs
, 0, IPACX_MASKB
, 0xff);
955 cs
->BC_Write_Reg(cs
, 1, IPACX_MASKB
, 0xff);
957 ista
= cs
->readisac(cs
, IPACX_ISTA
);
958 if (ista
&0x80) cs
->BC_Read_Reg(cs
, 0, IPACX_ISTAB
);
959 if (ista
&0x40) cs
->BC_Read_Reg(cs
, 1, IPACX_ISTAB
);
960 if (ista
&0x10) cs
->readisac(cs
, IPACX_CIR0
);
961 if (ista
&0x01) cs
->readisac(cs
, IPACX_ISTAD
);
964 //----------------------------------------------------------
965 // Does chip configuration work
966 // Work to do depends on bit mask in part
967 //----------------------------------------------------------
969 init_ipacx(struct IsdnCardState
*cs
, int part
)
971 if (part
&1) { // initialise chip
972 //##################################################
973 // printk(KERN_INFO "init_ipacx(%x)\n", part);
974 //##################################################
975 clear_pending_ints(cs
);
980 if (part
&2) { // reenable all interrupts and start chip
981 cs
->BC_Write_Reg(cs
, 0, IPACX_MASKB
, _MASKB_IMASK
);
982 cs
->BC_Write_Reg(cs
, 1, IPACX_MASKB
, _MASKB_IMASK
);
983 cs
->writeisac(cs
, IPACX_MASKD
, _MASKD_IMASK
);
984 cs
->writeisac(cs
, IPACX_MASK
, _MASK_IMASK
); // global mask register
986 // reset HDLC Transmitters/receivers
987 cs
->writeisac(cs
, IPACX_CMDRD
, 0x41);
988 cs
->BC_Write_Reg(cs
, 0, IPACX_CMDRB
, 0x41);
989 cs
->BC_Write_Reg(cs
, 1, IPACX_CMDRB
, 0x41);
990 ph_command(cs
, IPACX_CMD_RES
);
996 setup_ipacx(struct IsdnCardState
*cs
)
998 INIT_WORK(&cs
->tqueue
, (void *)(void *) dch_bh
, cs
);
999 cs
->dbusytimer
.function
= (void *) dbusy_timer_handler
;
1000 cs
->dbusytimer
.data
= (long) cs
;
1001 init_timer(&cs
->dbusytimer
);
1003 //----------------- end of file -----------------------