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/init.h>
19 #define DBUSY_TIMER_VALUE 80
20 #define TIMER3_VALUE 7000
21 #define MAX_DFRAME_LEN_L1 300
22 #define B_FIFO_SIZE 64
23 #define D_FIFO_SIZE 32
26 // ipacx interrupt mask values
27 #define _MASK_IMASK 0x2E // global mask
28 #define _MASKB_IMASK 0x0B
29 #define _MASKD_IMASK 0x03 // all on
31 //----------------------------------------------------------
32 // local function declarations
33 //----------------------------------------------------------
34 static void ph_command(struct IsdnCardState
*cs
, unsigned int command
);
35 static inline void cic_int(struct IsdnCardState
*cs
);
36 static void dch_l2l1(struct PStack
*st
, int pr
, void *arg
);
37 static void dbusy_timer_handler(struct IsdnCardState
*cs
);
38 static void dch_empty_fifo(struct IsdnCardState
*cs
, int count
);
39 static void dch_fill_fifo(struct IsdnCardState
*cs
);
40 static inline void dch_int(struct IsdnCardState
*cs
);
41 static void dch_setstack(struct PStack
*st
, struct IsdnCardState
*cs
);
42 static void dch_init(struct IsdnCardState
*cs
);
43 static void bch_l2l1(struct PStack
*st
, int pr
, void *arg
);
44 static void bch_empty_fifo(struct BCState
*bcs
, int count
);
45 static void bch_fill_fifo(struct BCState
*bcs
);
46 static void bch_int(struct IsdnCardState
*cs
, u_char hscx
);
47 static void bch_mode(struct BCState
*bcs
, int mode
, int bc
);
48 static void bch_close_state(struct BCState
*bcs
);
49 static int bch_open_state(struct IsdnCardState
*cs
, struct BCState
*bcs
);
50 static int bch_setstack(struct PStack
*st
, struct BCState
*bcs
);
51 static void bch_init(struct IsdnCardState
*cs
, int hscx
);
52 static void clear_pending_ints(struct IsdnCardState
*cs
);
54 //----------------------------------------------------------
55 // Issue Layer 1 command to chip
56 //----------------------------------------------------------
58 ph_command(struct IsdnCardState
*cs
, unsigned int command
)
60 if (cs
->debug
&L1_DEB_ISAC
)
61 debugl1(cs
, "ph_command (%#x) in (%#x)", command
,
62 cs
->dc
.isac
.ph_state
);
63 //###################################
64 // printk(KERN_INFO "ph_command (%#x)\n", command);
65 //###################################
66 cs
->writeisac(cs
, IPACX_CIX0
, (command
<< 4) | 0x0E);
69 //----------------------------------------------------------
70 // Transceiver interrupt handler
71 //----------------------------------------------------------
73 cic_int(struct IsdnCardState
*cs
)
77 event
= cs
->readisac(cs
, IPACX_CIR0
) >> 4;
78 if (cs
->debug
&L1_DEB_ISAC
) debugl1(cs
, "cic_int(event=%#x)", event
);
79 //#########################################
80 // printk(KERN_INFO "cic_int(%x)\n", event);
81 //#########################################
82 cs
->dc
.isac
.ph_state
= event
;
83 schedule_event(cs
, D_L1STATECHANGE
);
86 //==========================================================
87 // D channel functions
88 //==========================================================
90 //----------------------------------------------------------
91 // Command entry point
92 //----------------------------------------------------------
94 dch_l2l1(struct PStack
*st
, int pr
, void *arg
)
96 struct IsdnCardState
*cs
= (struct IsdnCardState
*) st
->l1
.hardware
;
97 struct sk_buff
*skb
= arg
;
98 u_char cda1_cr
, cda2_cr
;
101 case (PH_DATA
|REQUEST
):
102 if (cs
->debug
&DEB_DLOG_HEX
) LogFrame(cs
, skb
->data
, skb
->len
);
103 if (cs
->debug
&DEB_DLOG_VERBOSE
) dlogframe(cs
, skb
, 0);
105 skb_queue_tail(&cs
->sq
, skb
);
107 if (cs
->debug
&L1_DEB_LAPD
) Logl2Frame(cs
, skb
, "PH_DATA Queued", 0);
113 if (cs
->debug
&L1_DEB_LAPD
) Logl2Frame(cs
, skb
, "PH_DATA", 0);
119 case (PH_PULL
|INDICATION
):
121 if (cs
->debug
& L1_DEB_WARN
)
122 debugl1(cs
, " l2l1 tx_skb exist this shouldn't happen");
123 skb_queue_tail(&cs
->sq
, skb
);
126 if (cs
->debug
& DEB_DLOG_HEX
) LogFrame(cs
, skb
->data
, skb
->len
);
127 if (cs
->debug
& DEB_DLOG_VERBOSE
) dlogframe(cs
, skb
, 0);
131 if (cs
->debug
& L1_DEB_LAPD
) Logl2Frame(cs
, skb
, "PH_DATA_PULLED", 0);
136 case (PH_PULL
| REQUEST
):
138 if (cs
->debug
& L1_DEB_LAPD
) debugl1(cs
, "-> PH_REQUEST_PULL");
141 clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
142 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
144 set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
147 case (HW_RESET
| REQUEST
):
148 case (HW_ENABLE
| REQUEST
):
149 if ((cs
->dc
.isac
.ph_state
== IPACX_IND_RES
) ||
150 (cs
->dc
.isac
.ph_state
== IPACX_IND_DR
) ||
151 (cs
->dc
.isac
.ph_state
== IPACX_IND_DC
))
152 ph_command(cs
, IPACX_CMD_TIM
);
154 ph_command(cs
, IPACX_CMD_RES
);
157 case (HW_INFO3
| REQUEST
):
158 ph_command(cs
, IPACX_CMD_AR8
);
161 case (HW_TESTLOOP
| REQUEST
):
162 cs
->writeisac(cs
, IPACX_CDA_TSDP10
, 0x80); // Timeslot 0 is B1
163 cs
->writeisac(cs
, IPACX_CDA_TSDP11
, 0x81); // Timeslot 0 is B1
164 cda1_cr
= cs
->readisac(cs
, IPACX_CDA1_CR
);
165 cda2_cr
= cs
->readisac(cs
, IPACX_CDA2_CR
);
166 if ((long)arg
&1) { // loop B1
167 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
|0x0a);
170 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
&~0x0a);
172 if ((long)arg
&2) { // loop B2
173 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
|0x14);
176 cs
->writeisac(cs
, IPACX_CDA1_CR
, cda1_cr
&~0x14);
180 case (HW_DEACTIVATE
| RESPONSE
):
181 skb_queue_purge(&cs
->rq
);
182 skb_queue_purge(&cs
->sq
);
184 dev_kfree_skb_any(cs
->tx_skb
);
187 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
188 del_timer(&cs
->dbusytimer
);
192 if (cs
->debug
&L1_DEB_WARN
) debugl1(cs
, "dch_l2l1 unknown %04x", pr
);
197 //----------------------------------------------------------
198 //----------------------------------------------------------
200 dbusy_timer_handler(struct IsdnCardState
*cs
)
205 if (test_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
206 rbchd
= cs
->readisac(cs
, IPACX_RBCHD
);
207 stard
= cs
->readisac(cs
, IPACX_STARD
);
209 debugl1(cs
, "D-Channel Busy RBCHD %02x STARD %02x", rbchd
, stard
);
210 if (!(stard
&0x40)) { // D-Channel Busy
211 set_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
);
212 for (st
= cs
->stlist
; st
; st
= st
->next
) {
213 st
->l1
.l1l2(st
, PH_PAUSE
| INDICATION
, NULL
); // flow control on
216 // seems we lost an interrupt; reset transceiver */
217 clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
);
219 dev_kfree_skb_any(cs
->tx_skb
);
223 printk(KERN_WARNING
"HiSax: ISAC D-Channel Busy no skb\n");
224 debugl1(cs
, "D-Channel Busy no skb");
226 cs
->writeisac(cs
, IPACX_CMDRD
, 0x01); // Tx reset, generates XPR
231 //----------------------------------------------------------
232 // Fill buffer from receive FIFO
233 //----------------------------------------------------------
235 dch_empty_fifo(struct IsdnCardState
*cs
, int count
)
239 if ((cs
->debug
&L1_DEB_ISAC
) && !(cs
->debug
&L1_DEB_ISAC_FIFO
))
240 debugl1(cs
, "dch_empty_fifo()");
242 // message too large, remove
243 if ((cs
->rcvidx
+ count
) >= MAX_DFRAME_LEN_L1
) {
244 if (cs
->debug
&L1_DEB_WARN
)
245 debugl1(cs
, "dch_empty_fifo() incoming message too large");
246 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
251 ptr
= cs
->rcvbuf
+ cs
->rcvidx
;
254 cs
->readisacfifo(cs
, ptr
, count
);
255 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
257 if (cs
->debug
&L1_DEB_ISAC_FIFO
) {
260 t
+= sprintf(t
, "dch_empty_fifo() cnt %d", count
);
261 QuickHex(t
, ptr
, count
);
262 debugl1(cs
, cs
->dlog
);
266 //----------------------------------------------------------
267 // Fill transmit FIFO
268 //----------------------------------------------------------
270 dch_fill_fifo(struct IsdnCardState
*cs
)
275 if ((cs
->debug
&L1_DEB_ISAC
) && !(cs
->debug
&L1_DEB_ISAC_FIFO
))
276 debugl1(cs
, "dch_fill_fifo()");
278 if (!cs
->tx_skb
) return;
279 count
= cs
->tx_skb
->len
;
280 if (count
<= 0) return;
282 if (count
> D_FIFO_SIZE
) {
286 cmd
= 0x0A; // XTF | XME
289 ptr
= cs
->tx_skb
->data
;
290 skb_pull(cs
->tx_skb
, count
);
292 cs
->writeisacfifo(cs
, ptr
, count
);
293 cs
->writeisac(cs
, IPACX_CMDRD
, cmd
);
295 // set timeout for transmission contol
296 if (test_and_set_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
297 debugl1(cs
, "dch_fill_fifo dbusytimer running");
298 del_timer(&cs
->dbusytimer
);
300 init_timer(&cs
->dbusytimer
);
301 cs
->dbusytimer
.expires
= jiffies
+ ((DBUSY_TIMER_VALUE
* HZ
)/1000);
302 add_timer(&cs
->dbusytimer
);
304 if (cs
->debug
&L1_DEB_ISAC_FIFO
) {
307 t
+= sprintf(t
, "dch_fill_fifo() cnt %d", count
);
308 QuickHex(t
, ptr
, count
);
309 debugl1(cs
, cs
->dlog
);
313 //----------------------------------------------------------
314 // D channel interrupt handler
315 //----------------------------------------------------------
317 dch_int(struct IsdnCardState
*cs
)
323 istad
= cs
->readisac(cs
, IPACX_ISTAD
);
324 //##############################################
325 // printk(KERN_WARNING "dch_int(istad=%02x)\n", istad);
326 //##############################################
328 if (istad
&0x80) { // RME
329 rstad
= cs
->readisac(cs
, IPACX_RSTAD
);
330 if ((rstad
&0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
332 if (cs
->debug
&L1_DEB_WARN
)
333 debugl1(cs
, "dch_int(): invalid frame");
335 if (cs
->debug
&L1_DEB_WARN
)
336 debugl1(cs
, "dch_int(): RDO");
338 if (cs
->debug
&L1_DEB_WARN
)
339 debugl1(cs
, "dch_int(): CRC error");
340 cs
->writeisac(cs
, IPACX_CMDRD
, 0x80); // RMC
341 } else { // received frame ok
342 count
= cs
->readisac(cs
, IPACX_RBCLD
);
343 if (count
) count
--; // RSTAB is last byte
344 count
&= D_FIFO_SIZE
-1;
345 if (count
== 0) count
= D_FIFO_SIZE
;
346 dch_empty_fifo(cs
, count
);
347 if ((count
= cs
->rcvidx
) > 0) {
349 if (!(skb
= dev_alloc_skb(count
)))
350 printk(KERN_WARNING
"HiSax dch_int(): receive out of memory\n");
352 memcpy(skb_put(skb
, count
), cs
->rcvbuf
, count
);
353 skb_queue_tail(&cs
->rq
, skb
);
358 schedule_event(cs
, D_RCVBUFREADY
);
361 if (istad
&0x40) { // RPF
362 dch_empty_fifo(cs
, D_FIFO_SIZE
);
365 if (istad
&0x20) { // RFO
366 if (cs
->debug
&L1_DEB_WARN
) debugl1(cs
, "dch_int(): RFO");
367 cs
->writeisac(cs
, IPACX_CMDRD
, 0x40); //RRES
370 if (istad
&0x10) { // XPR
371 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
372 del_timer(&cs
->dbusytimer
);
373 if (test_and_clear_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
))
374 schedule_event(cs
, D_CLEARBUSY
);
376 if (cs
->tx_skb
->len
) {
381 dev_kfree_skb_irq(cs
->tx_skb
);
386 if ((cs
->tx_skb
= skb_dequeue(&cs
->sq
))) {
391 schedule_event(cs
, D_XMTBUFREADY
);
396 if (istad
&0x0C) { // XDU or XMR
397 if (cs
->debug
&L1_DEB_WARN
) debugl1(cs
, "dch_int(): XDU");
399 skb_push(cs
->tx_skb
, cs
->tx_cnt
); // retransmit
403 printk(KERN_WARNING
"HiSax: ISAC XDU no skb\n");
404 debugl1(cs
, "ISAC XDU no skb");
409 //----------------------------------------------------------
410 //----------------------------------------------------------
412 dch_setstack(struct PStack
*st
, struct IsdnCardState
*cs
)
414 st
->l1
.l1hw
= dch_l2l1
;
417 //----------------------------------------------------------
418 //----------------------------------------------------------
420 dch_init(struct IsdnCardState
*cs
)
422 printk(KERN_INFO
"HiSax: IPACX ISDN driver v0.1.0\n");
424 cs
->setstack_d
= dch_setstack
;
426 cs
->dbusytimer
.function
= (void *) dbusy_timer_handler
;
427 cs
->dbusytimer
.data
= (long) cs
;
428 init_timer(&cs
->dbusytimer
);
430 cs
->writeisac(cs
, IPACX_TR_CONF0
, 0x00); // clear LDD
431 cs
->writeisac(cs
, IPACX_TR_CONF2
, 0x00); // enable transmitter
432 cs
->writeisac(cs
, IPACX_MODED
, 0xC9); // transparent mode 0, RAC, stop/go
433 cs
->writeisac(cs
, IPACX_MON_CR
, 0x00); // disable monitor channel
437 //==========================================================
438 // B channel functions
439 //==========================================================
441 //----------------------------------------------------------
442 // Entry point for commands
443 //----------------------------------------------------------
445 bch_l2l1(struct PStack
*st
, int pr
, void *arg
)
447 struct BCState
*bcs
= st
->l1
.bcs
;
448 struct sk_buff
*skb
= arg
;
452 case (PH_DATA
| REQUEST
):
453 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
455 skb_queue_tail(&bcs
->squeue
, skb
);
458 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
459 bcs
->hw
.hscx
.count
= 0;
462 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
464 case (PH_PULL
| INDICATION
):
465 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
467 printk(KERN_WARNING
"HiSax bch_l2l1(): this shouldn't happen\n");
469 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
471 bcs
->hw
.hscx
.count
= 0;
474 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
476 case (PH_PULL
| REQUEST
):
478 clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
479 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
481 set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
483 case (PH_ACTIVATE
| REQUEST
):
484 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
485 set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
486 bch_mode(bcs
, st
->l1
.mode
, st
->l1
.bc
);
487 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
488 l1_msg_b(st
, pr
, arg
);
490 case (PH_DEACTIVATE
| REQUEST
):
491 l1_msg_b(st
, pr
, arg
);
493 case (PH_DEACTIVATE
| CONFIRM
):
494 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
495 clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
496 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
497 bch_mode(bcs
, 0, st
->l1
.bc
);
498 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
499 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
504 //----------------------------------------------------------
505 // Read B channel fifo to receive buffer
506 //----------------------------------------------------------
508 bch_empty_fifo(struct BCState
*bcs
, int count
)
511 struct IsdnCardState
*cs
;
515 hscx
= bcs
->hw
.hscx
.hscx
;
516 if ((cs
->debug
&L1_DEB_HSCX
) && !(cs
->debug
&L1_DEB_HSCX_FIFO
))
517 debugl1(cs
, "bch_empty_fifo()");
519 // message too large, remove
520 if (bcs
->hw
.hscx
.rcvidx
+ count
> HSCX_BUFMAX
) {
521 if (cs
->debug
&L1_DEB_WARN
)
522 debugl1(cs
, "bch_empty_fifo() incoming packet too large");
523 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
524 bcs
->hw
.hscx
.rcvidx
= 0;
528 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
530 while (cnt
--) *ptr
++ = cs
->BC_Read_Reg(cs
, hscx
, IPACX_RFIFOB
);
531 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
533 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
534 bcs
->hw
.hscx
.rcvidx
+= count
;
536 if (cs
->debug
&L1_DEB_HSCX_FIFO
) {
539 t
+= sprintf(t
, "bch_empty_fifo() B-%d cnt %d", hscx
, count
);
540 QuickHex(t
, ptr
, count
);
541 debugl1(cs
, bcs
->blog
);
545 //----------------------------------------------------------
546 // Fill buffer to transmit FIFO
547 //----------------------------------------------------------
549 bch_fill_fifo(struct BCState
*bcs
)
551 struct IsdnCardState
*cs
;
552 int more
, count
, cnt
;
553 u_char
*ptr
, *p
, hscx
;
556 if ((cs
->debug
&L1_DEB_HSCX
) && !(cs
->debug
&L1_DEB_HSCX_FIFO
))
557 debugl1(cs
, "bch_fill_fifo()");
559 if (!bcs
->tx_skb
) return;
560 if (bcs
->tx_skb
->len
<= 0) return;
562 hscx
= bcs
->hw
.hscx
.hscx
;
563 more
= (bcs
->mode
== L1_MODE_TRANS
) ? 1 : 0;
564 if (bcs
->tx_skb
->len
> B_FIFO_SIZE
) {
568 count
= bcs
->tx_skb
->len
;
572 p
= ptr
= bcs
->tx_skb
->data
;
573 skb_pull(bcs
->tx_skb
, count
);
574 bcs
->tx_cnt
-= count
;
575 bcs
->hw
.hscx
.count
+= count
;
576 while (cnt
--) cs
->BC_Write_Reg(cs
, hscx
, IPACX_XFIFOB
, *p
++);
577 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, (more
? 0x08 : 0x0a));
579 if (cs
->debug
&L1_DEB_HSCX_FIFO
) {
582 t
+= sprintf(t
, "chb_fill_fifo() B-%d cnt %d", hscx
, count
);
583 QuickHex(t
, ptr
, count
);
584 debugl1(cs
, bcs
->blog
);
588 //----------------------------------------------------------
589 // B channel interrupt handler
590 //----------------------------------------------------------
592 bch_int(struct IsdnCardState
*cs
, u_char hscx
)
600 bcs
= cs
->bcs
+ hscx
;
601 istab
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_ISTAB
);
602 //##############################################
603 // printk(KERN_WARNING "bch_int(istab=%02x)\n", istab);
604 //##############################################
605 if (!test_bit(BC_FLG_INIT
, &bcs
->Flag
)) return;
607 if (istab
&0x80) { // RME
608 rstab
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_RSTAB
);
609 if ((rstab
&0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
611 if (cs
->debug
&L1_DEB_WARN
)
612 debugl1(cs
, "bch_int() B-%d: invalid frame", hscx
);
613 if ((rstab
&0x40) && (bcs
->mode
!= L1_MODE_NULL
))
614 if (cs
->debug
&L1_DEB_WARN
)
615 debugl1(cs
, "bch_int() B-%d: RDO mode=%d", hscx
, bcs
->mode
);
617 if (cs
->debug
&L1_DEB_WARN
)
618 debugl1(cs
, "bch_int() B-%d: CRC error", hscx
);
619 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x80); // RMC
621 else { // received frame ok
622 count
= cs
->BC_Read_Reg(cs
, hscx
, IPACX_RBCLB
) &(B_FIFO_SIZE
-1);
623 if (count
== 0) count
= B_FIFO_SIZE
;
624 bch_empty_fifo(bcs
, count
);
625 if ((count
= bcs
->hw
.hscx
.rcvidx
- 1) > 0) {
626 if (cs
->debug
&L1_DEB_HSCX_FIFO
)
627 debugl1(cs
, "bch_int Frame %d", count
);
628 if (!(skb
= dev_alloc_skb(count
)))
629 printk(KERN_WARNING
"HiSax bch_int(): receive frame out of memory\n");
631 memcpy(skb_put(skb
, count
), bcs
->hw
.hscx
.rcvbuf
, count
);
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 memcpy(skb_put(skb
, B_FIFO_SIZE
), bcs
->hw
.hscx
.rcvbuf
, B_FIFO_SIZE
);
649 skb_queue_tail(&bcs
->rqueue
, skb
);
651 bcs
->hw
.hscx
.rcvidx
= 0;
652 schedule_event(bcs
, B_RCVBUFREADY
);
656 if (istab
&0x20) { // RFO
657 if (cs
->debug
&L1_DEB_WARN
)
658 debugl1(cs
, "bch_int() B-%d: RFO error", hscx
);
659 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x40); // RRES
662 if (istab
&0x10) { // XPR
664 if (bcs
->tx_skb
->len
) {
668 if (test_bit(FLG_LLI_L1WAKEUP
,&bcs
->st
->lli
.flag
) &&
669 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
671 spin_lock_irqsave(&bcs
->aclock
, flags
);
672 bcs
->ackcnt
+= bcs
->hw
.hscx
.count
;
673 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
674 schedule_event(bcs
, B_ACKPENDING
);
677 dev_kfree_skb_irq(bcs
->tx_skb
);
678 bcs
->hw
.hscx
.count
= 0;
681 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
682 bcs
->hw
.hscx
.count
= 0;
683 set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
686 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
687 schedule_event(bcs
, B_XMTBUFREADY
);
692 if (istab
&0x04) { // XDU
693 if (bcs
->mode
== L1_MODE_TRANS
) {
697 if (bcs
->tx_skb
) { // restart transmitting the whole frame
698 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
699 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
700 bcs
->hw
.hscx
.count
= 0;
702 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x01); // XRES
703 if (cs
->debug
&L1_DEB_WARN
)
704 debugl1(cs
, "bch_int() B-%d XDU error", hscx
);
709 //----------------------------------------------------------
710 //----------------------------------------------------------
712 bch_mode(struct BCState
*bcs
, int mode
, int bc
)
714 struct IsdnCardState
*cs
= bcs
->cs
;
715 int hscx
= bcs
->hw
.hscx
.hscx
;
717 bc
= bc
? 1 : 0; // in case bc is greater than 1
718 if (cs
->debug
& L1_DEB_HSCX
)
719 debugl1(cs
, "mode_bch() switch B-% mode %d chan %d", hscx
, mode
, bc
);
723 // map controller to according timeslot
726 cs
->writeisac(cs
, IPACX_BCHA_TSDP_BC1
, 0x80 | bc
);
727 cs
->writeisac(cs
, IPACX_BCHA_CR
, 0x88);
731 cs
->writeisac(cs
, IPACX_BCHB_TSDP_BC1
, 0x80 | bc
);
732 cs
->writeisac(cs
, IPACX_BCHB_CR
, 0x88);
737 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0xC0); // rec off
738 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x30); // std adj.
739 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, 0xFF); // ints off
740 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
742 case (L1_MODE_TRANS
):
743 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0x88); // ext transp mode
744 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x00); // xxx00000
745 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
746 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, _MASKB_IMASK
);
749 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MODEB
, 0xC8); // transp mode 0
750 cs
->BC_Write_Reg(cs
, hscx
, IPACX_EXMB
, 0x01); // idle=hdlc flags crc enabled
751 cs
->BC_Write_Reg(cs
, hscx
, IPACX_CMDRB
, 0x41); // validate adjustments
752 cs
->BC_Write_Reg(cs
, hscx
, IPACX_MASKB
, _MASKB_IMASK
);
757 //----------------------------------------------------------
758 //----------------------------------------------------------
760 bch_close_state(struct BCState
*bcs
)
762 bch_mode(bcs
, 0, bcs
->channel
);
763 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
764 kfree(bcs
->hw
.hscx
.rcvbuf
);
765 bcs
->hw
.hscx
.rcvbuf
= NULL
;
768 skb_queue_purge(&bcs
->rqueue
);
769 skb_queue_purge(&bcs
->squeue
);
771 dev_kfree_skb_any(bcs
->tx_skb
);
773 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
778 //----------------------------------------------------------
779 //----------------------------------------------------------
781 bch_open_state(struct IsdnCardState
*cs
, struct BCState
*bcs
)
783 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
784 if (!(bcs
->hw
.hscx
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
786 "HiSax open_bchstate(): No memory for hscx.rcvbuf\n");
787 clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
790 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
792 "HiSax open_bchstate: No memory for bcs->blog\n");
793 clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
794 kfree(bcs
->hw
.hscx
.rcvbuf
);
795 bcs
->hw
.hscx
.rcvbuf
= NULL
;
798 skb_queue_head_init(&bcs
->rqueue
);
799 skb_queue_head_init(&bcs
->squeue
);
802 clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
804 bcs
->hw
.hscx
.rcvidx
= 0;
809 //----------------------------------------------------------
810 //----------------------------------------------------------
812 bch_setstack(struct PStack
*st
, struct BCState
*bcs
)
814 bcs
->channel
= st
->l1
.bc
;
815 if (bch_open_state(st
->l1
.hardware
, bcs
)) return (-1);
817 st
->l2
.l2l1
= bch_l2l1
;
818 setstack_manager(st
);
824 //----------------------------------------------------------
825 //----------------------------------------------------------
827 bch_init(struct IsdnCardState
*cs
, int hscx
)
829 cs
->bcs
[hscx
].BC_SetStack
= bch_setstack
;
830 cs
->bcs
[hscx
].BC_Close
= bch_close_state
;
831 cs
->bcs
[hscx
].hw
.hscx
.hscx
= hscx
;
832 cs
->bcs
[hscx
].cs
= cs
;
833 bch_mode(cs
->bcs
+ hscx
, 0, hscx
);
837 //==========================================================
839 //==========================================================
841 //----------------------------------------------------------
842 // Main interrupt handler
843 //----------------------------------------------------------
845 interrupt_ipacx(struct IsdnCardState
*cs
)
849 while ((ista
= cs
->readisac(cs
, IPACX_ISTA
))) {
850 //#################################################
851 // printk(KERN_WARNING "interrupt_ipacx(ista=%02x)\n", ista);
852 //#################################################
853 if (ista
&0x80) bch_int(cs
, 0); // B channel interrupts
854 if (ista
&0x40) bch_int(cs
, 1);
856 if (ista
&0x01) dch_int(cs
); // D channel
857 if (ista
&0x10) cic_int(cs
); // Layer 1 state
861 //----------------------------------------------------------
862 // Clears chip interrupt status
863 //----------------------------------------------------------
865 clear_pending_ints(struct IsdnCardState
*cs
)
869 // all interrupts off
870 cs
->writeisac(cs
, IPACX_MASK
, 0xff);
871 cs
->writeisac(cs
, IPACX_MASKD
, 0xff);
872 cs
->BC_Write_Reg(cs
, 0, IPACX_MASKB
, 0xff);
873 cs
->BC_Write_Reg(cs
, 1, IPACX_MASKB
, 0xff);
875 ista
= cs
->readisac(cs
, IPACX_ISTA
);
876 if (ista
&0x80) cs
->BC_Read_Reg(cs
, 0, IPACX_ISTAB
);
877 if (ista
&0x40) cs
->BC_Read_Reg(cs
, 1, IPACX_ISTAB
);
878 if (ista
&0x10) cs
->readisac(cs
, IPACX_CIR0
);
879 if (ista
&0x01) cs
->readisac(cs
, IPACX_ISTAD
);
882 //----------------------------------------------------------
883 // Does chip configuration work
884 // Work to do depends on bit mask in part
885 //----------------------------------------------------------
887 init_ipacx(struct IsdnCardState
*cs
, int part
)
889 if (part
&1) { // initialise chip
890 //##################################################
891 // printk(KERN_INFO "init_ipacx(%x)\n", part);
892 //##################################################
893 clear_pending_ints(cs
);
898 if (part
&2) { // reenable all interrupts and start chip
899 cs
->BC_Write_Reg(cs
, 0, IPACX_MASKB
, _MASKB_IMASK
);
900 cs
->BC_Write_Reg(cs
, 1, IPACX_MASKB
, _MASKB_IMASK
);
901 cs
->writeisac(cs
, IPACX_MASKD
, _MASKD_IMASK
);
902 cs
->writeisac(cs
, IPACX_MASK
, _MASK_IMASK
); // global mask register
904 // reset HDLC Transmitters/receivers
905 cs
->writeisac(cs
, IPACX_CMDRD
, 0x41);
906 cs
->BC_Write_Reg(cs
, 0, IPACX_CMDRB
, 0x41);
907 cs
->BC_Write_Reg(cs
, 1, IPACX_CMDRB
, 0x41);
908 ph_command(cs
, IPACX_CMD_RES
);
912 //----------------- end of file -----------------------