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
, "%s", 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
, "%s", 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 setup_timer(&cs
->dbusytimer
, (void *)dbusy_timer_handler
, (long)cs
);
429 cs
->writeisac(cs
, IPACX_TR_CONF0
, 0x00); // clear LDD
430 cs
->writeisac(cs
, IPACX_TR_CONF2
, 0x00); // enable transmitter
431 cs
->writeisac(cs
, IPACX_MODED
, 0xC9); // transparent mode 0, RAC, stop/go
432 cs
->writeisac(cs
, IPACX_MON_CR
, 0x00); // disable monitor channel
436 //==========================================================
437 // B channel functions
438 //==========================================================
440 //----------------------------------------------------------
441 // Entry point for commands
442 //----------------------------------------------------------
444 bch_l2l1(struct PStack
*st
, int pr
, void *arg
)
446 struct BCState
*bcs
= st
->l1
.bcs
;
447 struct sk_buff
*skb
= arg
;
451 case (PH_DATA
| REQUEST
):
452 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
454 skb_queue_tail(&bcs
->squeue
, skb
);
457 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
458 bcs
->hw
.hscx
.count
= 0;
461 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
463 case (PH_PULL
| INDICATION
):
464 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
466 printk(KERN_WARNING
"HiSax bch_l2l1(): this shouldn't happen\n");
468 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
470 bcs
->hw
.hscx
.count
= 0;
473 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
475 case (PH_PULL
| REQUEST
):
477 clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
478 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
480 set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
482 case (PH_ACTIVATE
| REQUEST
):
483 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
484 set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
485 bch_mode(bcs
, st
->l1
.mode
, st
->l1
.bc
);
486 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
487 l1_msg_b(st
, pr
, arg
);
489 case (PH_DEACTIVATE
| REQUEST
):
490 l1_msg_b(st
, pr
, arg
);
492 case (PH_DEACTIVATE
| CONFIRM
):
493 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
494 clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
495 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
496 bch_mode(bcs
, 0, st
->l1
.bc
);
497 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
498 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
503 //----------------------------------------------------------
504 // Read B channel fifo to receive buffer
505 //----------------------------------------------------------
507 bch_empty_fifo(struct BCState
*bcs
, int count
)
510 struct IsdnCardState
*cs
;
514 hscx
= bcs
->hw
.hscx
.hscx
;
515 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
516 debugl1(cs
, "bch_empty_fifo()");
518 // message too large, remove
519 if (bcs
->hw
.hscx
.rcvidx
+ count
> HSCX_BUFMAX
) {
520 if (cs
->debug
& L1_DEB_WARN
)
521 debugl1(cs
, "bch_empty_fifo() incoming packet too large");
522 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
523 bcs
->hw
.hscx
.rcvidx
= 0;
527 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
529 while (cnt
--) *ptr
++ = cs
->BC_Read_Reg(cs
, hscx
, IPACX_RFIFOB
);
530 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
532 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
533 bcs
->hw
.hscx
.rcvidx
+= count
;
535 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
538 t
+= sprintf(t
, "bch_empty_fifo() B-%d cnt %d", hscx
, count
);
539 QuickHex(t
, ptr
, count
);
540 debugl1(cs
, "%s", bcs
->blog
);
544 //----------------------------------------------------------
545 // Fill buffer to transmit FIFO
546 //----------------------------------------------------------
548 bch_fill_fifo(struct BCState
*bcs
)
550 struct IsdnCardState
*cs
;
551 int more
, count
, cnt
;
552 u_char
*ptr
, *p
, hscx
;
555 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
556 debugl1(cs
, "bch_fill_fifo()");
558 if (!bcs
->tx_skb
) return;
559 if (bcs
->tx_skb
->len
<= 0) return;
561 hscx
= bcs
->hw
.hscx
.hscx
;
562 more
= (bcs
->mode
== L1_MODE_TRANS
) ? 1 : 0;
563 if (bcs
->tx_skb
->len
> B_FIFO_SIZE
) {
567 count
= bcs
->tx_skb
->len
;
571 p
= ptr
= bcs
->tx_skb
->data
;
572 skb_pull(bcs
->tx_skb
, count
);
573 bcs
->tx_cnt
-= count
;
574 bcs
->hw
.hscx
.count
+= count
;
575 while (cnt
--) cs
->BC_Write_Reg(cs
, hscx
, IPACX_XFIFOB
, *p
++);
576 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, (more
? 0x08 : 0x0a));
578 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
581 t
+= sprintf(t
, "%s() B-%d cnt %d", __func__
, hscx
, count
);
582 QuickHex(t
, ptr
, count
);
583 debugl1(cs
, "%s", bcs
->blog
);
587 //----------------------------------------------------------
588 // B channel interrupt handler
589 //----------------------------------------------------------
591 bch_int(struct IsdnCardState
*cs
, u_char hscx
)
599 bcs
= cs
->bcs
+ hscx
;
600 istab
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_ISTAB
);
601 //##############################################
602 // printk(KERN_WARNING "bch_int(istab=%02x)\n", istab);
603 //##############################################
604 if (!test_bit(BC_FLG_INIT
, &bcs
->Flag
)) return;
606 if (istab
& 0x80) { // RME
607 rstab
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_RSTAB
);
608 if ((rstab
& 0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
610 if (cs
->debug
& L1_DEB_WARN
)
611 debugl1(cs
, "bch_int() B-%d: invalid frame", hscx
);
612 if ((rstab
& 0x40) && (bcs
->mode
!= L1_MODE_NULL
))
613 if (cs
->debug
& L1_DEB_WARN
)
614 debugl1(cs
, "bch_int() B-%d: RDO mode=%d", hscx
, bcs
->mode
);
616 if (cs
->debug
& L1_DEB_WARN
)
617 debugl1(cs
, "bch_int() B-%d: CRC error", hscx
);
618 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
620 else { // received frame ok
621 count
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_RBCLB
) & (B_FIFO_SIZE
- 1);
622 if (count
== 0) count
= B_FIFO_SIZE
;
623 bch_empty_fifo(bcs
, count
);
624 if ((count
= bcs
->hw
.hscx
.rcvidx
- 1) > 0) {
625 if (cs
->debug
& L1_DEB_HSCX_FIFO
)
626 debugl1(cs
, "bch_int Frame %d", count
);
627 if (!(skb
= dev_alloc_skb(count
)))
628 printk(KERN_WARNING
"HiSax bch_int(): receive frame out of memory\n");
630 memcpy(skb_put(skb
, count
), bcs
->hw
.hscx
.rcvbuf
, count
);
631 skb_queue_tail(&bcs
->rqueue
, skb
);
635 bcs
->hw
.hscx
.rcvidx
= 0;
636 schedule_event(bcs
, B_RCVBUFREADY
);
639 if (istab
& 0x40) { // RPF
640 bch_empty_fifo(bcs
, B_FIFO_SIZE
);
642 if (bcs
->mode
== L1_MODE_TRANS
) { // queue every chunk
643 // receive transparent audio data
644 if (!(skb
= dev_alloc_skb(B_FIFO_SIZE
)))
645 printk(KERN_WARNING
"HiSax bch_int(): receive transparent out of memory\n");
647 memcpy(skb_put(skb
, B_FIFO_SIZE
), bcs
->hw
.hscx
.rcvbuf
, B_FIFO_SIZE
);
648 skb_queue_tail(&bcs
->rqueue
, skb
);
650 bcs
->hw
.hscx
.rcvidx
= 0;
651 schedule_event(bcs
, B_RCVBUFREADY
);
655 if (istab
& 0x20) { // RFO
656 if (cs
->debug
& L1_DEB_WARN
)
657 debugl1(cs
, "bch_int() B-%d: RFO error", hscx
);
658 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x40); // RRES
661 if (istab
& 0x10) { // XPR
663 if (bcs
->tx_skb
->len
) {
667 if (test_bit(FLG_LLI_L1WAKEUP
, &bcs
->st
->lli
.flag
) &&
668 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
670 spin_lock_irqsave(&bcs
->aclock
, flags
);
671 bcs
->ackcnt
+= bcs
->hw
.hscx
.count
;
672 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
673 schedule_event(bcs
, B_ACKPENDING
);
676 dev_kfree_skb_irq(bcs
->tx_skb
);
677 bcs
->hw
.hscx
.count
= 0;
680 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
681 bcs
->hw
.hscx
.count
= 0;
682 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
685 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
686 schedule_event(bcs
, B_XMTBUFREADY
);
691 if (istab
& 0x04) { // XDU
692 if (bcs
->mode
== L1_MODE_TRANS
) {
696 if (bcs
->tx_skb
) { // restart transmitting the whole frame
697 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
698 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
699 bcs
->hw
.hscx
.count
= 0;
701 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x01); // XRES
702 if (cs
->debug
& L1_DEB_WARN
)
703 debugl1(cs
, "bch_int() B-%d XDU error", hscx
);
708 //----------------------------------------------------------
709 //----------------------------------------------------------
711 bch_mode(struct BCState
*bcs
, int mode
, int bc
)
713 struct IsdnCardState
*cs
= bcs
->cs
;
714 int hscx
= bcs
->hw
.hscx
.hscx
;
716 bc
= bc
? 1 : 0; // in case bc is greater than 1
717 if (cs
->debug
& L1_DEB_HSCX
)
718 debugl1(cs
, "mode_bch() switch B-%d mode %d chan %d", hscx
, mode
, bc
);
722 // map controller to according timeslot
725 cs
->writeisac(cs
, IPACX_BCHA_TSDP_BC1
, 0x80 | bc
);
726 cs
->writeisac(cs
, IPACX_BCHA_CR
, 0x88);
730 cs
->writeisac(cs
, IPACX_BCHB_TSDP_BC1
, 0x80 | bc
);
731 cs
->writeisac(cs
, IPACX_BCHB_CR
, 0x88);
736 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0xC0); // rec off
737 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x30); // std adj.
738 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, 0xFF); // ints off
739 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
741 case (L1_MODE_TRANS
):
742 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0x88); // ext transp mode
743 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x00); // xxx00000
744 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
745 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, _MASKB_IMASK
);
748 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0xC8); // transp mode 0
749 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x01); // idle=hdlc flags crc enabled
750 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
751 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, _MASKB_IMASK
);
756 //----------------------------------------------------------
757 //----------------------------------------------------------
759 bch_close_state(struct BCState
*bcs
)
761 bch_mode(bcs
, 0, bcs
->channel
);
762 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
763 kfree(bcs
->hw
.hscx
.rcvbuf
);
764 bcs
->hw
.hscx
.rcvbuf
= NULL
;
767 skb_queue_purge(&bcs
->rqueue
);
768 skb_queue_purge(&bcs
->squeue
);
770 dev_kfree_skb_any(bcs
->tx_skb
);
772 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
777 //----------------------------------------------------------
778 //----------------------------------------------------------
780 bch_open_state(struct IsdnCardState
*cs
, struct BCState
*bcs
)
782 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
783 if (!(bcs
->hw
.hscx
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
785 "HiSax open_bchstate(): No memory for hscx.rcvbuf\n");
786 clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
789 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
791 "HiSax open_bchstate: No memory for bcs->blog\n");
792 clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
793 kfree(bcs
->hw
.hscx
.rcvbuf
);
794 bcs
->hw
.hscx
.rcvbuf
= NULL
;
797 skb_queue_head_init(&bcs
->rqueue
);
798 skb_queue_head_init(&bcs
->squeue
);
801 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
803 bcs
->hw
.hscx
.rcvidx
= 0;
808 //----------------------------------------------------------
809 //----------------------------------------------------------
811 bch_setstack(struct PStack
*st
, struct BCState
*bcs
)
813 bcs
->channel
= st
->l1
.bc
;
814 if (bch_open_state(st
->l1
.hardware
, bcs
)) return (-1);
816 st
->l2
.l2l1
= bch_l2l1
;
817 setstack_manager(st
);
823 //----------------------------------------------------------
824 //----------------------------------------------------------
826 bch_init(struct IsdnCardState
*cs
, int hscx
)
828 cs
->bcs
[hscx
].BC_SetStack
= bch_setstack
;
829 cs
->bcs
[hscx
].BC_Close
= bch_close_state
;
830 cs
->bcs
[hscx
].hw
.hscx
.hscx
= hscx
;
831 cs
->bcs
[hscx
].cs
= cs
;
832 bch_mode(cs
->bcs
+ hscx
, 0, hscx
);
836 //==========================================================
838 //==========================================================
840 //----------------------------------------------------------
841 // Main interrupt handler
842 //----------------------------------------------------------
844 interrupt_ipacx(struct IsdnCardState
*cs
)
848 while ((ista
= cs
->readisac(cs
, IPACX_ISTA
))) {
849 //#################################################
850 // printk(KERN_WARNING "interrupt_ipacx(ista=%02x)\n", ista);
851 //#################################################
852 if (ista
& 0x80) bch_int(cs
, 0); // B channel interrupts
853 if (ista
& 0x40) bch_int(cs
, 1);
855 if (ista
& 0x01) dch_int(cs
); // D channel
856 if (ista
& 0x10) cic_int(cs
); // Layer 1 state
860 //----------------------------------------------------------
861 // Clears chip interrupt status
862 //----------------------------------------------------------
864 clear_pending_ints(struct IsdnCardState
*cs
)
868 // all interrupts off
869 cs
->writeisac(cs
, IPACX_MASK
, 0xff);
870 cs
->writeisac(cs
, IPACX_MASKD
, 0xff);
871 cs
->BC_Write_Reg(cs
, 0, IPACX_MASKB
, 0xff);
872 cs
->BC_Write_Reg(cs
, 1, IPACX_MASKB
, 0xff);
874 ista
= cs
->readisac(cs
, IPACX_ISTA
);
875 if (ista
& 0x80) cs
->BC_Read_Reg(cs
, 0, IPACX_ISTAB
);
876 if (ista
& 0x40) cs
->BC_Read_Reg(cs
, 1, IPACX_ISTAB
);
877 if (ista
& 0x10) cs
->readisac(cs
, IPACX_CIR0
);
878 if (ista
& 0x01) cs
->readisac(cs
, IPACX_ISTAD
);
881 //----------------------------------------------------------
882 // Does chip configuration work
883 // Work to do depends on bit mask in part
884 //----------------------------------------------------------
886 init_ipacx(struct IsdnCardState
*cs
, int part
)
888 if (part
& 1) { // initialise chip
889 //##################################################
890 // printk(KERN_INFO "init_ipacx(%x)\n", part);
891 //##################################################
892 clear_pending_ints(cs
);
897 if (part
& 2) { // reenable all interrupts and start chip
898 cs
->BC_Write_Reg(cs
, 0, IPACX_MASKB
, _MASKB_IMASK
);
899 cs
->BC_Write_Reg(cs
, 1, IPACX_MASKB
, _MASKB_IMASK
);
900 cs
->writeisac(cs
, IPACX_MASKD
, _MASKD_IMASK
);
901 cs
->writeisac(cs
, IPACX_MASK
, _MASK_IMASK
); // global mask register
903 // reset HDLC Transmitters/receivers
904 cs
->writeisac(cs
, IPACX_CMDRD
, 0x41);
905 cs
->BC_Write_Reg(cs
, 0, IPACX_CMDRB
, 0x41);
906 cs
->BC_Write_Reg(cs
, 1, IPACX_CMDRB
, 0x41);
907 ph_command(cs
, IPACX_CMD_RES
);
911 //----------------- end of file -----------------------