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/slab.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 dch_empty_fifo(struct IsdnCardState
*cs
, int count
);
40 static void dch_fill_fifo(struct IsdnCardState
*cs
);
41 static inline void dch_int(struct IsdnCardState
*cs
);
42 static void dch_setstack(struct PStack
*st
, struct IsdnCardState
*cs
);
43 static void dch_init(struct IsdnCardState
*cs
);
44 static void bch_l2l1(struct PStack
*st
, int pr
, void *arg
);
45 static void bch_empty_fifo(struct BCState
*bcs
, int count
);
46 static void bch_fill_fifo(struct BCState
*bcs
);
47 static void bch_int(struct IsdnCardState
*cs
, u_char hscx
);
48 static void bch_mode(struct BCState
*bcs
, int mode
, int bc
);
49 static void bch_close_state(struct BCState
*bcs
);
50 static int bch_open_state(struct IsdnCardState
*cs
, struct BCState
*bcs
);
51 static int bch_setstack(struct PStack
*st
, struct BCState
*bcs
);
52 static void bch_init(struct IsdnCardState
*cs
, int hscx
);
53 static void clear_pending_ints(struct IsdnCardState
*cs
);
55 //----------------------------------------------------------
56 // Issue Layer 1 command to chip
57 //----------------------------------------------------------
59 ph_command(struct IsdnCardState
*cs
, unsigned int command
)
61 if (cs
->debug
&L1_DEB_ISAC
)
62 debugl1(cs
, "ph_command (%#x) in (%#x)", command
,
63 cs
->dc
.isac
.ph_state
);
64 //###################################
65 // printk(KERN_INFO "ph_command (%#x)\n", command);
66 //###################################
67 cs
->writeisac(cs
, IPACX_CIX0
, (command
<< 4) | 0x0E);
70 //----------------------------------------------------------
71 // Transceiver interrupt handler
72 //----------------------------------------------------------
74 cic_int(struct IsdnCardState
*cs
)
78 event
= cs
->readisac(cs
, IPACX_CIR0
) >> 4;
79 if (cs
->debug
&L1_DEB_ISAC
) debugl1(cs
, "cic_int(event=%#x)", event
);
80 //#########################################
81 // printk(KERN_INFO "cic_int(%x)\n", event);
82 //#########################################
83 cs
->dc
.isac
.ph_state
= event
;
84 schedule_event(cs
, D_L1STATECHANGE
);
87 //==========================================================
88 // D channel functions
89 //==========================================================
91 //----------------------------------------------------------
92 // Command entry point
93 //----------------------------------------------------------
95 dch_l2l1(struct PStack
*st
, int pr
, void *arg
)
97 struct IsdnCardState
*cs
= (struct IsdnCardState
*) st
->l1
.hardware
;
98 struct sk_buff
*skb
= arg
;
102 case (PH_DATA
|REQUEST
):
103 if (cs
->debug
&DEB_DLOG_HEX
) LogFrame(cs
, skb
->data
, skb
->len
);
104 if (cs
->debug
&DEB_DLOG_VERBOSE
) dlogframe(cs
, skb
, 0);
106 skb_queue_tail(&cs
->sq
, skb
);
108 if (cs
->debug
&L1_DEB_LAPD
) Logl2Frame(cs
, skb
, "PH_DATA Queued", 0);
114 if (cs
->debug
&L1_DEB_LAPD
) Logl2Frame(cs
, skb
, "PH_DATA", 0);
120 case (PH_PULL
|INDICATION
):
122 if (cs
->debug
& L1_DEB_WARN
)
123 debugl1(cs
, " l2l1 tx_skb exist this shouldn't happen");
124 skb_queue_tail(&cs
->sq
, skb
);
127 if (cs
->debug
& DEB_DLOG_HEX
) LogFrame(cs
, skb
->data
, skb
->len
);
128 if (cs
->debug
& DEB_DLOG_VERBOSE
) dlogframe(cs
, skb
, 0);
132 if (cs
->debug
& L1_DEB_LAPD
) Logl2Frame(cs
, skb
, "PH_DATA_PULLED", 0);
137 case (PH_PULL
| REQUEST
):
139 if (cs
->debug
& L1_DEB_LAPD
) debugl1(cs
, "-> PH_REQUEST_PULL");
142 clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
143 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
145 set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
148 case (HW_RESET
| REQUEST
):
149 case (HW_ENABLE
| REQUEST
):
150 if ((cs
->dc
.isac
.ph_state
== IPACX_IND_RES
) ||
151 (cs
->dc
.isac
.ph_state
== IPACX_IND_DR
) ||
152 (cs
->dc
.isac
.ph_state
== IPACX_IND_DC
))
153 ph_command(cs
, IPACX_CMD_TIM
);
155 ph_command(cs
, IPACX_CMD_RES
);
158 case (HW_INFO3
| REQUEST
):
159 ph_command(cs
, IPACX_CMD_AR8
);
162 case (HW_TESTLOOP
| REQUEST
):
163 cs
->writeisac(cs
, IPACX_CDA_TSDP10
, 0x80); // Timeslot 0 is B1
164 cs
->writeisac(cs
, IPACX_CDA_TSDP11
, 0x81); // Timeslot 0 is B1
165 cda1_cr
= cs
->readisac(cs
, IPACX_CDA1_CR
);
166 (void) cs
->readisac(cs
, IPACX_CDA2_CR
);
167 if ((long)arg
&1) { // loop B1
168 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
|0x0a);
171 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
&~0x0a);
173 if ((long)arg
&2) { // loop B2
174 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
|0x14);
177 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
&~0x14);
181 case (HW_DEACTIVATE
| RESPONSE
):
182 skb_queue_purge(&cs
->rq
);
183 skb_queue_purge(&cs
->sq
);
185 dev_kfree_skb_any(cs
->tx_skb
);
188 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
189 del_timer(&cs
->dbusytimer
);
193 if (cs
->debug
&L1_DEB_WARN
) debugl1(cs
, "dch_l2l1 unknown %04x", pr
);
198 //----------------------------------------------------------
199 //----------------------------------------------------------
201 dbusy_timer_handler(struct IsdnCardState
*cs
)
206 if (test_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
207 rbchd
= cs
->readisac(cs
, IPACX_RBCHD
);
208 stard
= cs
->readisac(cs
, IPACX_STARD
);
210 debugl1(cs
, "D-Channel Busy RBCHD %02x STARD %02x", rbchd
, stard
);
211 if (!(stard
&0x40)) { // D-Channel Busy
212 set_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
);
213 for (st
= cs
->stlist
; st
; st
= st
->next
) {
214 st
->l1
.l1l2(st
, PH_PAUSE
| INDICATION
, NULL
); // flow control on
217 // seems we lost an interrupt; reset transceiver */
218 clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
);
220 dev_kfree_skb_any(cs
->tx_skb
);
224 printk(KERN_WARNING
"HiSax: ISAC D-Channel Busy no skb\n");
225 debugl1(cs
, "D-Channel Busy no skb");
227 cs
->writeisac(cs
, IPACX_CMDRD
, 0x01); // Tx reset, generates XPR
232 //----------------------------------------------------------
233 // Fill buffer from receive FIFO
234 //----------------------------------------------------------
236 dch_empty_fifo(struct IsdnCardState
*cs
, int count
)
240 if ((cs
->debug
&L1_DEB_ISAC
) && !(cs
->debug
&L1_DEB_ISAC_FIFO
))
241 debugl1(cs
, "dch_empty_fifo()");
243 // message too large, remove
244 if ((cs
->rcvidx
+ count
) >= MAX_DFRAME_LEN_L1
) {
245 if (cs
->debug
&L1_DEB_WARN
)
246 debugl1(cs
, "dch_empty_fifo() incoming message too large");
247 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
252 ptr
= cs
->rcvbuf
+ cs
->rcvidx
;
255 cs
->readisacfifo(cs
, ptr
, count
);
256 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
258 if (cs
->debug
&L1_DEB_ISAC_FIFO
) {
261 t
+= sprintf(t
, "dch_empty_fifo() cnt %d", count
);
262 QuickHex(t
, ptr
, count
);
263 debugl1(cs
, cs
->dlog
);
267 //----------------------------------------------------------
268 // Fill transmit FIFO
269 //----------------------------------------------------------
271 dch_fill_fifo(struct IsdnCardState
*cs
)
276 if ((cs
->debug
&L1_DEB_ISAC
) && !(cs
->debug
&L1_DEB_ISAC_FIFO
))
277 debugl1(cs
, "dch_fill_fifo()");
279 if (!cs
->tx_skb
) return;
280 count
= cs
->tx_skb
->len
;
281 if (count
<= 0) return;
283 if (count
> D_FIFO_SIZE
) {
287 cmd
= 0x0A; // XTF | XME
290 ptr
= cs
->tx_skb
->data
;
291 skb_pull(cs
->tx_skb
, count
);
293 cs
->writeisacfifo(cs
, ptr
, count
);
294 cs
->writeisac(cs
, IPACX_CMDRD
, cmd
);
296 // set timeout for transmission contol
297 if (test_and_set_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
298 debugl1(cs
, "dch_fill_fifo dbusytimer running");
299 del_timer(&cs
->dbusytimer
);
301 init_timer(&cs
->dbusytimer
);
302 cs
->dbusytimer
.expires
= jiffies
+ ((DBUSY_TIMER_VALUE
* HZ
)/1000);
303 add_timer(&cs
->dbusytimer
);
305 if (cs
->debug
&L1_DEB_ISAC_FIFO
) {
308 t
+= sprintf(t
, "dch_fill_fifo() cnt %d", count
);
309 QuickHex(t
, ptr
, count
);
310 debugl1(cs
, cs
->dlog
);
314 //----------------------------------------------------------
315 // D channel interrupt handler
316 //----------------------------------------------------------
318 dch_int(struct IsdnCardState
*cs
)
324 istad
= cs
->readisac(cs
, IPACX_ISTAD
);
325 //##############################################
326 // printk(KERN_WARNING "dch_int(istad=%02x)\n", istad);
327 //##############################################
329 if (istad
&0x80) { // RME
330 rstad
= cs
->readisac(cs
, IPACX_RSTAD
);
331 if ((rstad
&0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
333 if (cs
->debug
&L1_DEB_WARN
)
334 debugl1(cs
, "dch_int(): invalid frame");
336 if (cs
->debug
&L1_DEB_WARN
)
337 debugl1(cs
, "dch_int(): RDO");
339 if (cs
->debug
&L1_DEB_WARN
)
340 debugl1(cs
, "dch_int(): CRC error");
341 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
342 } else { // received frame ok
343 count
= cs
->readisac(cs
, IPACX_RBCLD
);
344 if (count
) count
--; // RSTAB is last byte
345 count
&= D_FIFO_SIZE
-1;
346 if (count
== 0) count
= D_FIFO_SIZE
;
347 dch_empty_fifo(cs
, count
);
348 if ((count
= cs
->rcvidx
) > 0) {
350 if (!(skb
= dev_alloc_skb(count
)))
351 printk(KERN_WARNING
"HiSax dch_int(): receive out of memory\n");
353 memcpy(skb_put(skb
, count
), cs
->rcvbuf
, count
);
354 skb_queue_tail(&cs
->rq
, skb
);
359 schedule_event(cs
, D_RCVBUFREADY
);
362 if (istad
&0x40) { // RPF
363 dch_empty_fifo(cs
, D_FIFO_SIZE
);
366 if (istad
&0x20) { // RFO
367 if (cs
->debug
&L1_DEB_WARN
) debugl1(cs
, "dch_int(): RFO");
368 cs
->writeisac(cs
, IPACX_CMDRD
, 0x40); //RRES
371 if (istad
&0x10) { // XPR
372 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
373 del_timer(&cs
->dbusytimer
);
374 if (test_and_clear_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
))
375 schedule_event(cs
, D_CLEARBUSY
);
377 if (cs
->tx_skb
->len
) {
382 dev_kfree_skb_irq(cs
->tx_skb
);
387 if ((cs
->tx_skb
= skb_dequeue(&cs
->sq
))) {
392 schedule_event(cs
, D_XMTBUFREADY
);
397 if (istad
&0x0C) { // XDU or XMR
398 if (cs
->debug
&L1_DEB_WARN
) debugl1(cs
, "dch_int(): XDU");
400 skb_push(cs
->tx_skb
, cs
->tx_cnt
); // retransmit
404 printk(KERN_WARNING
"HiSax: ISAC XDU no skb\n");
405 debugl1(cs
, "ISAC XDU no skb");
410 //----------------------------------------------------------
411 //----------------------------------------------------------
413 dch_setstack(struct PStack
*st
, struct IsdnCardState
*cs
)
415 st
->l1
.l1hw
= dch_l2l1
;
418 //----------------------------------------------------------
419 //----------------------------------------------------------
421 dch_init(struct IsdnCardState
*cs
)
423 printk(KERN_INFO
"HiSax: IPACX ISDN driver v0.1.0\n");
425 cs
->setstack_d
= dch_setstack
;
427 cs
->dbusytimer
.function
= (void *) dbusy_timer_handler
;
428 cs
->dbusytimer
.data
= (long) cs
;
429 init_timer(&cs
->dbusytimer
);
431 cs
->writeisac(cs
, IPACX_TR_CONF0
, 0x00); // clear LDD
432 cs
->writeisac(cs
, IPACX_TR_CONF2
, 0x00); // enable transmitter
433 cs
->writeisac(cs
, IPACX_MODED
, 0xC9); // transparent mode 0, RAC, stop/go
434 cs
->writeisac(cs
, IPACX_MON_CR
, 0x00); // disable monitor channel
438 //==========================================================
439 // B channel functions
440 //==========================================================
442 //----------------------------------------------------------
443 // Entry point for commands
444 //----------------------------------------------------------
446 bch_l2l1(struct PStack
*st
, int pr
, void *arg
)
448 struct BCState
*bcs
= st
->l1
.bcs
;
449 struct sk_buff
*skb
= arg
;
453 case (PH_DATA
| REQUEST
):
454 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
456 skb_queue_tail(&bcs
->squeue
, skb
);
459 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
460 bcs
->hw
.hscx
.count
= 0;
463 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
465 case (PH_PULL
| INDICATION
):
466 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
468 printk(KERN_WARNING
"HiSax bch_l2l1(): this shouldn't happen\n");
470 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
472 bcs
->hw
.hscx
.count
= 0;
475 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
477 case (PH_PULL
| REQUEST
):
479 clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
480 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
482 set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
484 case (PH_ACTIVATE
| REQUEST
):
485 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
486 set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
487 bch_mode(bcs
, st
->l1
.mode
, st
->l1
.bc
);
488 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
489 l1_msg_b(st
, pr
, arg
);
491 case (PH_DEACTIVATE
| REQUEST
):
492 l1_msg_b(st
, pr
, arg
);
494 case (PH_DEACTIVATE
| CONFIRM
):
495 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
496 clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
497 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
498 bch_mode(bcs
, 0, st
->l1
.bc
);
499 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
500 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
505 //----------------------------------------------------------
506 // Read B channel fifo to receive buffer
507 //----------------------------------------------------------
509 bch_empty_fifo(struct BCState
*bcs
, int count
)
512 struct IsdnCardState
*cs
;
516 hscx
= bcs
->hw
.hscx
.hscx
;
517 if ((cs
->debug
&L1_DEB_HSCX
) && !(cs
->debug
&L1_DEB_HSCX_FIFO
))
518 debugl1(cs
, "bch_empty_fifo()");
520 // message too large, remove
521 if (bcs
->hw
.hscx
.rcvidx
+ count
> HSCX_BUFMAX
) {
522 if (cs
->debug
&L1_DEB_WARN
)
523 debugl1(cs
, "bch_empty_fifo() incoming packet too large");
524 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
525 bcs
->hw
.hscx
.rcvidx
= 0;
529 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
531 while (cnt
--) *ptr
++ = cs
->BC_Read_Reg(cs
, hscx
, IPACX_RFIFOB
);
532 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
534 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
535 bcs
->hw
.hscx
.rcvidx
+= count
;
537 if (cs
->debug
&L1_DEB_HSCX_FIFO
) {
540 t
+= sprintf(t
, "bch_empty_fifo() B-%d cnt %d", hscx
, count
);
541 QuickHex(t
, ptr
, count
);
542 debugl1(cs
, bcs
->blog
);
546 //----------------------------------------------------------
547 // Fill buffer to transmit FIFO
548 //----------------------------------------------------------
550 bch_fill_fifo(struct BCState
*bcs
)
552 struct IsdnCardState
*cs
;
553 int more
, count
, cnt
;
554 u_char
*ptr
, *p
, hscx
;
557 if ((cs
->debug
&L1_DEB_HSCX
) && !(cs
->debug
&L1_DEB_HSCX_FIFO
))
558 debugl1(cs
, "bch_fill_fifo()");
560 if (!bcs
->tx_skb
) return;
561 if (bcs
->tx_skb
->len
<= 0) return;
563 hscx
= bcs
->hw
.hscx
.hscx
;
564 more
= (bcs
->mode
== L1_MODE_TRANS
) ? 1 : 0;
565 if (bcs
->tx_skb
->len
> B_FIFO_SIZE
) {
569 count
= bcs
->tx_skb
->len
;
573 p
= ptr
= bcs
->tx_skb
->data
;
574 skb_pull(bcs
->tx_skb
, count
);
575 bcs
->tx_cnt
-= count
;
576 bcs
->hw
.hscx
.count
+= count
;
577 while (cnt
--) cs
->BC_Write_Reg(cs
, hscx
, IPACX_XFIFOB
, *p
++);
578 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, (more
? 0x08 : 0x0a));
580 if (cs
->debug
&L1_DEB_HSCX_FIFO
) {
583 t
+= sprintf(t
, "chb_fill_fifo() B-%d cnt %d", hscx
, count
);
584 QuickHex(t
, ptr
, count
);
585 debugl1(cs
, bcs
->blog
);
589 //----------------------------------------------------------
590 // B channel interrupt handler
591 //----------------------------------------------------------
593 bch_int(struct IsdnCardState
*cs
, u_char hscx
)
601 bcs
= cs
->bcs
+ hscx
;
602 istab
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_ISTAB
);
603 //##############################################
604 // printk(KERN_WARNING "bch_int(istab=%02x)\n", istab);
605 //##############################################
606 if (!test_bit(BC_FLG_INIT
, &bcs
->Flag
)) return;
608 if (istab
&0x80) { // RME
609 rstab
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_RSTAB
);
610 if ((rstab
&0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
612 if (cs
->debug
&L1_DEB_WARN
)
613 debugl1(cs
, "bch_int() B-%d: invalid frame", hscx
);
614 if ((rstab
&0x40) && (bcs
->mode
!= L1_MODE_NULL
))
615 if (cs
->debug
&L1_DEB_WARN
)
616 debugl1(cs
, "bch_int() B-%d: RDO mode=%d", hscx
, bcs
->mode
);
618 if (cs
->debug
&L1_DEB_WARN
)
619 debugl1(cs
, "bch_int() B-%d: CRC error", hscx
);
620 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
622 else { // received frame ok
623 count
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_RBCLB
) &(B_FIFO_SIZE
-1);
624 if (count
== 0) count
= B_FIFO_SIZE
;
625 bch_empty_fifo(bcs
, count
);
626 if ((count
= bcs
->hw
.hscx
.rcvidx
- 1) > 0) {
627 if (cs
->debug
&L1_DEB_HSCX_FIFO
)
628 debugl1(cs
, "bch_int Frame %d", count
);
629 if (!(skb
= dev_alloc_skb(count
)))
630 printk(KERN_WARNING
"HiSax bch_int(): receive frame out of memory\n");
632 memcpy(skb_put(skb
, count
), bcs
->hw
.hscx
.rcvbuf
, count
);
633 skb_queue_tail(&bcs
->rqueue
, skb
);
637 bcs
->hw
.hscx
.rcvidx
= 0;
638 schedule_event(bcs
, B_RCVBUFREADY
);
641 if (istab
&0x40) { // RPF
642 bch_empty_fifo(bcs
, B_FIFO_SIZE
);
644 if (bcs
->mode
== L1_MODE_TRANS
) { // queue every chunk
645 // receive transparent audio data
646 if (!(skb
= dev_alloc_skb(B_FIFO_SIZE
)))
647 printk(KERN_WARNING
"HiSax bch_int(): receive transparent out of memory\n");
649 memcpy(skb_put(skb
, B_FIFO_SIZE
), bcs
->hw
.hscx
.rcvbuf
, B_FIFO_SIZE
);
650 skb_queue_tail(&bcs
->rqueue
, skb
);
652 bcs
->hw
.hscx
.rcvidx
= 0;
653 schedule_event(bcs
, B_RCVBUFREADY
);
657 if (istab
&0x20) { // RFO
658 if (cs
->debug
&L1_DEB_WARN
)
659 debugl1(cs
, "bch_int() B-%d: RFO error", hscx
);
660 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x40); // RRES
663 if (istab
&0x10) { // XPR
665 if (bcs
->tx_skb
->len
) {
669 if (test_bit(FLG_LLI_L1WAKEUP
,&bcs
->st
->lli
.flag
) &&
670 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
672 spin_lock_irqsave(&bcs
->aclock
, flags
);
673 bcs
->ackcnt
+= bcs
->hw
.hscx
.count
;
674 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
675 schedule_event(bcs
, B_ACKPENDING
);
678 dev_kfree_skb_irq(bcs
->tx_skb
);
679 bcs
->hw
.hscx
.count
= 0;
682 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
683 bcs
->hw
.hscx
.count
= 0;
684 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
687 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
688 schedule_event(bcs
, B_XMTBUFREADY
);
693 if (istab
&0x04) { // XDU
694 if (bcs
->mode
== L1_MODE_TRANS
) {
698 if (bcs
->tx_skb
) { // restart transmitting the whole frame
699 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
700 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
701 bcs
->hw
.hscx
.count
= 0;
703 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x01); // XRES
704 if (cs
->debug
&L1_DEB_WARN
)
705 debugl1(cs
, "bch_int() B-%d XDU error", hscx
);
710 //----------------------------------------------------------
711 //----------------------------------------------------------
713 bch_mode(struct BCState
*bcs
, int mode
, int bc
)
715 struct IsdnCardState
*cs
= bcs
->cs
;
716 int hscx
= bcs
->hw
.hscx
.hscx
;
718 bc
= bc
? 1 : 0; // in case bc is greater than 1
719 if (cs
->debug
& L1_DEB_HSCX
)
720 debugl1(cs
, "mode_bch() switch B-%d mode %d chan %d", hscx
, mode
, bc
);
724 // map controller to according timeslot
727 cs
->writeisac(cs
, IPACX_BCHA_TSDP_BC1
, 0x80 | bc
);
728 cs
->writeisac(cs
, IPACX_BCHA_CR
, 0x88);
732 cs
->writeisac(cs
, IPACX_BCHB_TSDP_BC1
, 0x80 | bc
);
733 cs
->writeisac(cs
, IPACX_BCHB_CR
, 0x88);
738 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0xC0); // rec off
739 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x30); // std adj.
740 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, 0xFF); // ints off
741 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
743 case (L1_MODE_TRANS
):
744 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0x88); // ext transp mode
745 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x00); // xxx00000
746 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
747 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, _MASKB_IMASK
);
750 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0xC8); // transp mode 0
751 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x01); // idle=hdlc flags crc enabled
752 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
753 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, _MASKB_IMASK
);
758 //----------------------------------------------------------
759 //----------------------------------------------------------
761 bch_close_state(struct BCState
*bcs
)
763 bch_mode(bcs
, 0, bcs
->channel
);
764 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
765 kfree(bcs
->hw
.hscx
.rcvbuf
);
766 bcs
->hw
.hscx
.rcvbuf
= NULL
;
769 skb_queue_purge(&bcs
->rqueue
);
770 skb_queue_purge(&bcs
->squeue
);
772 dev_kfree_skb_any(bcs
->tx_skb
);
774 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
779 //----------------------------------------------------------
780 //----------------------------------------------------------
782 bch_open_state(struct IsdnCardState
*cs
, struct BCState
*bcs
)
784 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
785 if (!(bcs
->hw
.hscx
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
787 "HiSax open_bchstate(): No memory for hscx.rcvbuf\n");
788 clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
791 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
793 "HiSax open_bchstate: No memory for bcs->blog\n");
794 clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
795 kfree(bcs
->hw
.hscx
.rcvbuf
);
796 bcs
->hw
.hscx
.rcvbuf
= NULL
;
799 skb_queue_head_init(&bcs
->rqueue
);
800 skb_queue_head_init(&bcs
->squeue
);
803 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
805 bcs
->hw
.hscx
.rcvidx
= 0;
810 //----------------------------------------------------------
811 //----------------------------------------------------------
813 bch_setstack(struct PStack
*st
, struct BCState
*bcs
)
815 bcs
->channel
= st
->l1
.bc
;
816 if (bch_open_state(st
->l1
.hardware
, bcs
)) return (-1);
818 st
->l2
.l2l1
= bch_l2l1
;
819 setstack_manager(st
);
825 //----------------------------------------------------------
826 //----------------------------------------------------------
828 bch_init(struct IsdnCardState
*cs
, int hscx
)
830 cs
->bcs
[hscx
].BC_SetStack
= bch_setstack
;
831 cs
->bcs
[hscx
].BC_Close
= bch_close_state
;
832 cs
->bcs
[hscx
].hw
.hscx
.hscx
= hscx
;
833 cs
->bcs
[hscx
].cs
= cs
;
834 bch_mode(cs
->bcs
+ hscx
, 0, hscx
);
838 //==========================================================
840 //==========================================================
842 //----------------------------------------------------------
843 // Main interrupt handler
844 //----------------------------------------------------------
846 interrupt_ipacx(struct IsdnCardState
*cs
)
850 while ((ista
= cs
->readisac(cs
, IPACX_ISTA
))) {
851 //#################################################
852 // printk(KERN_WARNING "interrupt_ipacx(ista=%02x)\n", ista);
853 //#################################################
854 if (ista
&0x80) bch_int(cs
, 0); // B channel interrupts
855 if (ista
&0x40) bch_int(cs
, 1);
857 if (ista
&0x01) dch_int(cs
); // D channel
858 if (ista
&0x10) cic_int(cs
); // Layer 1 state
862 //----------------------------------------------------------
863 // Clears chip interrupt status
864 //----------------------------------------------------------
866 clear_pending_ints(struct IsdnCardState
*cs
)
870 // all interrupts off
871 cs
->writeisac(cs
, IPACX_MASK
, 0xff);
872 cs
->writeisac(cs
, IPACX_MASKD
, 0xff);
873 cs
->BC_Write_Reg(cs
, 0, IPACX_MASKB
, 0xff);
874 cs
->BC_Write_Reg(cs
, 1, IPACX_MASKB
, 0xff);
876 ista
= cs
->readisac(cs
, IPACX_ISTA
);
877 if (ista
&0x80) cs
->BC_Read_Reg(cs
, 0, IPACX_ISTAB
);
878 if (ista
&0x40) cs
->BC_Read_Reg(cs
, 1, IPACX_ISTAB
);
879 if (ista
&0x10) cs
->readisac(cs
, IPACX_CIR0
);
880 if (ista
&0x01) cs
->readisac(cs
, IPACX_ISTAD
);
883 //----------------------------------------------------------
884 // Does chip configuration work
885 // Work to do depends on bit mask in part
886 //----------------------------------------------------------
888 init_ipacx(struct IsdnCardState
*cs
, int part
)
890 if (part
&1) { // initialise chip
891 //##################################################
892 // printk(KERN_INFO "init_ipacx(%x)\n", part);
893 //##################################################
894 clear_pending_ints(cs
);
899 if (part
&2) { // reenable all interrupts and start chip
900 cs
->BC_Write_Reg(cs
, 0, IPACX_MASKB
, _MASKB_IMASK
);
901 cs
->BC_Write_Reg(cs
, 1, IPACX_MASKB
, _MASKB_IMASK
);
902 cs
->writeisac(cs
, IPACX_MASKD
, _MASKD_IMASK
);
903 cs
->writeisac(cs
, IPACX_MASK
, _MASK_IMASK
); // global mask register
905 // reset HDLC Transmitters/receivers
906 cs
->writeisac(cs
, IPACX_CMDRD
, 0x41);
907 cs
->BC_Write_Reg(cs
, 0, IPACX_CMDRB
, 0x41);
908 cs
->BC_Write_Reg(cs
, 1, IPACX_CMDRB
, 0x41);
909 ph_command(cs
, IPACX_CMD_RES
);
913 //----------------- end of file -----------------------