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 timer_list
*t
);
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 timer_list
*t
)
203 struct IsdnCardState
*cs
= from_timer(cs
, t
, dbusytimer
);
207 if (test_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
208 rbchd
= cs
->readisac(cs
, IPACX_RBCHD
);
209 stard
= cs
->readisac(cs
, IPACX_STARD
);
211 debugl1(cs
, "D-Channel Busy RBCHD %02x STARD %02x", rbchd
, stard
);
212 if (!(stard
& 0x40)) { // D-Channel Busy
213 set_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
);
214 for (st
= cs
->stlist
; st
; st
= st
->next
) {
215 st
->l1
.l1l2(st
, PH_PAUSE
| INDICATION
, NULL
); // flow control on
218 // seems we lost an interrupt; reset transceiver */
219 clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
);
221 dev_kfree_skb_any(cs
->tx_skb
);
225 printk(KERN_WARNING
"HiSax: ISAC D-Channel Busy no skb\n");
226 debugl1(cs
, "D-Channel Busy no skb");
228 cs
->writeisac(cs
, IPACX_CMDRD
, 0x01); // Tx reset, generates XPR
233 //----------------------------------------------------------
234 // Fill buffer from receive FIFO
235 //----------------------------------------------------------
237 dch_empty_fifo(struct IsdnCardState
*cs
, int count
)
241 if ((cs
->debug
& L1_DEB_ISAC
) && !(cs
->debug
& L1_DEB_ISAC_FIFO
))
242 debugl1(cs
, "dch_empty_fifo()");
244 // message too large, remove
245 if ((cs
->rcvidx
+ count
) >= MAX_DFRAME_LEN_L1
) {
246 if (cs
->debug
& L1_DEB_WARN
)
247 debugl1(cs
, "dch_empty_fifo() incoming message too large");
248 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
253 ptr
= cs
->rcvbuf
+ cs
->rcvidx
;
256 cs
->readisacfifo(cs
, ptr
, count
);
257 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
259 if (cs
->debug
& L1_DEB_ISAC_FIFO
) {
262 t
+= sprintf(t
, "dch_empty_fifo() cnt %d", count
);
263 QuickHex(t
, ptr
, count
);
264 debugl1(cs
, "%s", cs
->dlog
);
268 //----------------------------------------------------------
269 // Fill transmit FIFO
270 //----------------------------------------------------------
272 dch_fill_fifo(struct IsdnCardState
*cs
)
277 if ((cs
->debug
& L1_DEB_ISAC
) && !(cs
->debug
& L1_DEB_ISAC_FIFO
))
278 debugl1(cs
, "dch_fill_fifo()");
280 if (!cs
->tx_skb
) return;
281 count
= cs
->tx_skb
->len
;
282 if (count
<= 0) return;
284 if (count
> D_FIFO_SIZE
) {
288 cmd
= 0x0A; // XTF | XME
291 ptr
= cs
->tx_skb
->data
;
292 skb_pull(cs
->tx_skb
, count
);
294 cs
->writeisacfifo(cs
, ptr
, count
);
295 cs
->writeisac(cs
, IPACX_CMDRD
, cmd
);
297 // set timeout for transmission contol
298 if (test_and_set_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
299 debugl1(cs
, "dch_fill_fifo dbusytimer running");
300 del_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 skb_put_data(skb
, 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 timer_setup(&cs
->dbusytimer
, dbusy_timer_handler
, 0);
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 skb_put_data(skb
, bcs
->hw
.hscx
.rcvbuf
,
632 skb_queue_tail(&bcs
->rqueue
, skb
);
636 bcs
->hw
.hscx
.rcvidx
= 0;
637 schedule_event(bcs
, B_RCVBUFREADY
);
640 if (istab
& 0x40) { // RPF
641 bch_empty_fifo(bcs
, B_FIFO_SIZE
);
643 if (bcs
->mode
== L1_MODE_TRANS
) { // queue every chunk
644 // receive transparent audio data
645 if (!(skb
= dev_alloc_skb(B_FIFO_SIZE
)))
646 printk(KERN_WARNING
"HiSax bch_int(): receive transparent out of memory\n");
648 skb_put_data(skb
, bcs
->hw
.hscx
.rcvbuf
,
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 -----------------------