1 // SPDX-License-Identifier: GPL-2.0-only
3 * isac.c ISAC specific routines
5 * Author Karsten Keil <keil@isdn4linux.de>
7 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
10 #include <linux/irqreturn.h>
11 #include <linux/slab.h>
12 #include <linux/module.h>
13 #include <linux/mISDNhw.h>
17 #define DBUSY_TIMER_VALUE 80
20 #define ISAC_REV "2.0"
22 MODULE_AUTHOR("Karsten Keil");
23 MODULE_VERSION(ISAC_REV
);
24 MODULE_DESCRIPTION("mISDN driver for ISAC specific functions");
25 MODULE_LICENSE("GPL v2");
27 #define ReadISAC(is, o) (is->read_reg(is->dch.hw, o + is->off))
28 #define WriteISAC(is, o, v) (is->write_reg(is->dch.hw, o + is->off, v))
29 #define ReadHSCX(h, o) (h->ip->read_reg(h->ip->hw, h->off + o))
30 #define WriteHSCX(h, o, v) (h->ip->write_reg(h->ip->hw, h->off + o, v))
31 #define ReadIPAC(ip, o) (ip->read_reg(ip->hw, o))
32 #define WriteIPAC(ip, o, v) (ip->write_reg(ip->hw, o, v))
35 ph_command(struct isac_hw
*isac
, u8 command
)
37 pr_debug("%s: ph_command %x\n", isac
->name
, command
);
38 if (isac
->type
& IPAC_TYPE_ISACX
)
39 WriteISAC(isac
, ISACX_CIX0
, (command
<< 4) | 0xE);
41 WriteISAC(isac
, ISAC_CIX0
, (command
<< 2) | 3);
45 isac_ph_state_change(struct isac_hw
*isac
)
47 switch (isac
->state
) {
50 ph_command(isac
, ISAC_CMD_DUI
);
52 schedule_event(&isac
->dch
, FLG_PHCHANGE
);
56 isac_ph_state_bh(struct dchannel
*dch
)
58 struct isac_hw
*isac
= container_of(dch
, struct isac_hw
, dch
);
60 switch (isac
->state
) {
64 l1_event(dch
->l1
, HW_RESET_IND
);
68 l1_event(dch
->l1
, HW_DEACT_CNF
);
73 l1_event(dch
->l1
, HW_DEACT_IND
);
77 l1_event(dch
->l1
, HW_POWERUP_IND
);
80 if (dch
->state
<= 5) {
82 l1_event(dch
->l1
, ANYSIGNAL
);
85 l1_event(dch
->l1
, LOSTFRAMING
);
90 l1_event(dch
->l1
, INFO2
);
94 l1_event(dch
->l1
, INFO4_P8
);
98 l1_event(dch
->l1
, INFO4_P10
);
101 pr_debug("%s: TE newstate %x\n", isac
->name
, dch
->state
);
105 isac_empty_fifo(struct isac_hw
*isac
, int count
)
109 pr_debug("%s: %s %d\n", isac
->name
, __func__
, count
);
111 if (!isac
->dch
.rx_skb
) {
112 isac
->dch
.rx_skb
= mI_alloc_skb(isac
->dch
.maxlen
, GFP_ATOMIC
);
113 if (!isac
->dch
.rx_skb
) {
114 pr_info("%s: D receive out of memory\n", isac
->name
);
115 WriteISAC(isac
, ISAC_CMDR
, 0x80);
119 if ((isac
->dch
.rx_skb
->len
+ count
) >= isac
->dch
.maxlen
) {
120 pr_debug("%s: %s overrun %d\n", isac
->name
, __func__
,
121 isac
->dch
.rx_skb
->len
+ count
);
122 WriteISAC(isac
, ISAC_CMDR
, 0x80);
125 ptr
= skb_put(isac
->dch
.rx_skb
, count
);
126 isac
->read_fifo(isac
->dch
.hw
, isac
->off
, ptr
, count
);
127 WriteISAC(isac
, ISAC_CMDR
, 0x80);
128 if (isac
->dch
.debug
& DEBUG_HW_DFIFO
) {
129 char pfx
[MISDN_MAX_IDLEN
+ 16];
131 snprintf(pfx
, MISDN_MAX_IDLEN
+ 15, "D-recv %s %d ",
133 print_hex_dump_bytes(pfx
, DUMP_PREFIX_OFFSET
, ptr
, count
);
138 isac_fill_fifo(struct isac_hw
*isac
)
143 if (!isac
->dch
.tx_skb
)
145 count
= isac
->dch
.tx_skb
->len
- isac
->dch
.tx_idx
;
154 pr_debug("%s: %s %d\n", isac
->name
, __func__
, count
);
155 ptr
= isac
->dch
.tx_skb
->data
+ isac
->dch
.tx_idx
;
156 isac
->dch
.tx_idx
+= count
;
157 isac
->write_fifo(isac
->dch
.hw
, isac
->off
, ptr
, count
);
158 WriteISAC(isac
, ISAC_CMDR
, more
? 0x8 : 0xa);
159 if (test_and_set_bit(FLG_BUSY_TIMER
, &isac
->dch
.Flags
)) {
160 pr_debug("%s: %s dbusytimer running\n", isac
->name
, __func__
);
161 del_timer(&isac
->dch
.timer
);
163 isac
->dch
.timer
.expires
= jiffies
+ ((DBUSY_TIMER_VALUE
* HZ
)/1000);
164 add_timer(&isac
->dch
.timer
);
165 if (isac
->dch
.debug
& DEBUG_HW_DFIFO
) {
166 char pfx
[MISDN_MAX_IDLEN
+ 16];
168 snprintf(pfx
, MISDN_MAX_IDLEN
+ 15, "D-send %s %d ",
170 print_hex_dump_bytes(pfx
, DUMP_PREFIX_OFFSET
, ptr
, count
);
175 isac_rme_irq(struct isac_hw
*isac
)
179 val
= ReadISAC(isac
, ISAC_RSTA
);
180 if ((val
& 0x70) != 0x20) {
182 pr_debug("%s: ISAC RDO\n", isac
->name
);
183 #ifdef ERROR_STATISTIC
188 pr_debug("%s: ISAC CRC error\n", isac
->name
);
189 #ifdef ERROR_STATISTIC
193 WriteISAC(isac
, ISAC_CMDR
, 0x80);
194 dev_kfree_skb(isac
->dch
.rx_skb
);
195 isac
->dch
.rx_skb
= NULL
;
197 count
= ReadISAC(isac
, ISAC_RBCL
) & 0x1f;
200 isac_empty_fifo(isac
, count
);
201 recv_Dchannel(&isac
->dch
);
206 isac_xpr_irq(struct isac_hw
*isac
)
208 if (test_and_clear_bit(FLG_BUSY_TIMER
, &isac
->dch
.Flags
))
209 del_timer(&isac
->dch
.timer
);
210 if (isac
->dch
.tx_skb
&& isac
->dch
.tx_idx
< isac
->dch
.tx_skb
->len
) {
211 isac_fill_fifo(isac
);
213 dev_kfree_skb(isac
->dch
.tx_skb
);
214 if (get_next_dframe(&isac
->dch
))
215 isac_fill_fifo(isac
);
220 isac_retransmit(struct isac_hw
*isac
)
222 if (test_and_clear_bit(FLG_BUSY_TIMER
, &isac
->dch
.Flags
))
223 del_timer(&isac
->dch
.timer
);
224 if (test_bit(FLG_TX_BUSY
, &isac
->dch
.Flags
)) {
226 isac
->dch
.tx_idx
= 0;
227 isac_fill_fifo(isac
);
228 } else if (isac
->dch
.tx_skb
) { /* should not happen */
229 pr_info("%s: tx_skb exist but not busy\n", isac
->name
);
230 test_and_set_bit(FLG_TX_BUSY
, &isac
->dch
.Flags
);
231 isac
->dch
.tx_idx
= 0;
232 isac_fill_fifo(isac
);
234 pr_info("%s: ISAC XDU no TX_BUSY\n", isac
->name
);
235 if (get_next_dframe(&isac
->dch
))
236 isac_fill_fifo(isac
);
241 isac_mos_irq(struct isac_hw
*isac
)
246 val
= ReadISAC(isac
, ISAC_MOSR
);
247 pr_debug("%s: ISAC MOSR %02x\n", isac
->name
, val
);
251 isac
->mon_rx
= kmalloc(MAX_MON_FRAME
, GFP_ATOMIC
);
253 pr_info("%s: ISAC MON RX out of memory!\n",
257 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
262 if (isac
->mon_rxp
>= MAX_MON_FRAME
) {
265 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
267 pr_debug("%s: ISAC MON RX overflow!\n", isac
->name
);
270 isac
->mon_rx
[isac
->mon_rxp
++] = ReadISAC(isac
, ISAC_MOR0
);
271 pr_debug("%s: ISAC MOR0 %02x\n", isac
->name
,
272 isac
->mon_rx
[isac
->mon_rxp
- 1]);
273 if (isac
->mon_rxp
== 1) {
275 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
281 isac
->mon_rx
= kmalloc(MAX_MON_FRAME
, GFP_ATOMIC
);
283 pr_info("%s: ISAC MON RX out of memory!\n",
287 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
292 if (isac
->mon_rxp
>= MAX_MON_FRAME
) {
295 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
297 pr_debug("%s: ISAC MON RX overflow!\n", isac
->name
);
300 isac
->mon_rx
[isac
->mon_rxp
++] = ReadISAC(isac
, ISAC_MOR1
);
301 pr_debug("%s: ISAC MOR1 %02x\n", isac
->name
,
302 isac
->mon_rx
[isac
->mon_rxp
- 1]);
304 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
309 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
311 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
313 ret
= isac
->monitor(isac
->dch
.hw
, MONITOR_RX_0
,
314 isac
->mon_rx
, isac
->mon_rxp
);
318 pr_info("%s: MONITOR 0 received %d but no user\n",
319 isac
->name
, isac
->mon_rxp
);
327 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
329 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
331 ret
= isac
->monitor(isac
->dch
.hw
, MONITOR_RX_1
,
332 isac
->mon_rx
, isac
->mon_rxp
);
336 pr_info("%s: MONITOR 1 received %d but no user\n",
337 isac
->name
, isac
->mon_rxp
);
344 if ((!isac
->mon_tx
) || (isac
->mon_txc
&&
345 (isac
->mon_txp
>= isac
->mon_txc
) && !(val
& 0x08))) {
347 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
349 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
350 if (isac
->mon_txc
&& (isac
->mon_txp
>= isac
->mon_txc
)) {
352 isac
->monitor(isac
->dch
.hw
,
353 MONITOR_TX_0
, NULL
, 0);
361 if (isac
->mon_txc
&& (isac
->mon_txp
>= isac
->mon_txc
)) {
363 isac
->monitor(isac
->dch
.hw
,
364 MONITOR_TX_0
, NULL
, 0);
371 WriteISAC(isac
, ISAC_MOX0
, isac
->mon_tx
[isac
->mon_txp
++]);
372 pr_debug("%s: ISAC %02x -> MOX0\n", isac
->name
,
373 isac
->mon_tx
[isac
->mon_txp
- 1]);
377 if ((!isac
->mon_tx
) || (isac
->mon_txc
&&
378 (isac
->mon_txp
>= isac
->mon_txc
) && !(val
& 0x80))) {
380 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
382 WriteISAC(isac
, ISAC_MOCR
, isac
->mocr
);
383 if (isac
->mon_txc
&& (isac
->mon_txp
>= isac
->mon_txc
)) {
385 isac
->monitor(isac
->dch
.hw
,
386 MONITOR_TX_1
, NULL
, 0);
394 if (isac
->mon_txc
&& (isac
->mon_txp
>= isac
->mon_txc
)) {
396 isac
->monitor(isac
->dch
.hw
,
397 MONITOR_TX_1
, NULL
, 0);
404 WriteISAC(isac
, ISAC_MOX1
, isac
->mon_tx
[isac
->mon_txp
++]);
405 pr_debug("%s: ISAC %02x -> MOX1\n", isac
->name
,
406 isac
->mon_tx
[isac
->mon_txp
- 1]);
409 val
= 0; /* dummy to avoid warning */
414 isac_cisq_irq(struct isac_hw
*isac
) {
417 val
= ReadISAC(isac
, ISAC_CIR0
);
418 pr_debug("%s: ISAC CIR0 %02X\n", isac
->name
, val
);
420 pr_debug("%s: ph_state change %x->%x\n", isac
->name
,
421 isac
->state
, (val
>> 2) & 0xf);
422 isac
->state
= (val
>> 2) & 0xf;
423 isac_ph_state_change(isac
);
426 val
= ReadISAC(isac
, ISAC_CIR1
);
427 pr_debug("%s: ISAC CIR1 %02X\n", isac
->name
, val
);
432 isacsx_cic_irq(struct isac_hw
*isac
)
436 val
= ReadISAC(isac
, ISACX_CIR0
);
437 pr_debug("%s: ISACX CIR0 %02X\n", isac
->name
, val
);
438 if (val
& ISACX_CIR0_CIC0
) {
439 pr_debug("%s: ph_state change %x->%x\n", isac
->name
,
440 isac
->state
, val
>> 4);
441 isac
->state
= val
>> 4;
442 isac_ph_state_change(isac
);
447 isacsx_rme_irq(struct isac_hw
*isac
)
452 val
= ReadISAC(isac
, ISACX_RSTAD
);
453 if ((val
& (ISACX_RSTAD_VFR
|
457 != (ISACX_RSTAD_VFR
| ISACX_RSTAD_CRC
)) {
458 pr_debug("%s: RSTAD %#x, dropped\n", isac
->name
, val
);
459 #ifdef ERROR_STATISTIC
460 if (val
& ISACX_RSTAD_CRC
)
465 WriteISAC(isac
, ISACX_CMDRD
, ISACX_CMDRD_RMC
);
466 dev_kfree_skb(isac
->dch
.rx_skb
);
467 isac
->dch
.rx_skb
= NULL
;
469 count
= ReadISAC(isac
, ISACX_RBCLD
) & 0x1f;
472 isac_empty_fifo(isac
, count
);
473 if (isac
->dch
.rx_skb
) {
474 skb_trim(isac
->dch
.rx_skb
, isac
->dch
.rx_skb
->len
- 1);
475 pr_debug("%s: dchannel received %d\n", isac
->name
,
476 isac
->dch
.rx_skb
->len
);
477 recv_Dchannel(&isac
->dch
);
483 mISDNisac_irq(struct isac_hw
*isac
, u8 val
)
487 pr_debug("%s: ISAC interrupt %02x\n", isac
->name
, val
);
488 if (isac
->type
& IPAC_TYPE_ISACX
) {
489 if (val
& ISACX__CIC
)
490 isacsx_cic_irq(isac
);
491 if (val
& ISACX__ICD
) {
492 val
= ReadISAC(isac
, ISACX_ISTAD
);
493 pr_debug("%s: ISTAD %02x\n", isac
->name
, val
);
494 if (val
& ISACX_D_XDU
) {
495 pr_debug("%s: ISAC XDU\n", isac
->name
);
496 #ifdef ERROR_STATISTIC
499 isac_retransmit(isac
);
501 if (val
& ISACX_D_XMR
) {
502 pr_debug("%s: ISAC XMR\n", isac
->name
);
503 #ifdef ERROR_STATISTIC
506 isac_retransmit(isac
);
508 if (val
& ISACX_D_XPR
)
510 if (val
& ISACX_D_RFO
) {
511 pr_debug("%s: ISAC RFO\n", isac
->name
);
512 WriteISAC(isac
, ISACX_CMDRD
, ISACX_CMDRD_RMC
);
514 if (val
& ISACX_D_RME
)
515 isacsx_rme_irq(isac
);
516 if (val
& ISACX_D_RPF
)
517 isac_empty_fifo(isac
, 0x20);
520 if (val
& 0x80) /* RME */
522 if (val
& 0x40) /* RPF */
523 isac_empty_fifo(isac
, 32);
524 if (val
& 0x10) /* XPR */
526 if (val
& 0x04) /* CISQ */
528 if (val
& 0x20) /* RSC - never */
529 pr_debug("%s: ISAC RSC interrupt\n", isac
->name
);
530 if (val
& 0x02) /* SIN - never */
531 pr_debug("%s: ISAC SIN interrupt\n", isac
->name
);
532 if (val
& 0x01) { /* EXI */
533 val
= ReadISAC(isac
, ISAC_EXIR
);
534 pr_debug("%s: ISAC EXIR %02x\n", isac
->name
, val
);
535 if (val
& 0x80) /* XMR */
536 pr_debug("%s: ISAC XMR\n", isac
->name
);
537 if (val
& 0x40) { /* XDU */
538 pr_debug("%s: ISAC XDU\n", isac
->name
);
539 #ifdef ERROR_STATISTIC
542 isac_retransmit(isac
);
544 if (val
& 0x04) /* MOS */
550 EXPORT_SYMBOL(mISDNisac_irq
);
553 isac_l1hw(struct mISDNchannel
*ch
, struct sk_buff
*skb
)
555 struct mISDNdevice
*dev
= container_of(ch
, struct mISDNdevice
, D
);
556 struct dchannel
*dch
= container_of(dev
, struct dchannel
, dev
);
557 struct isac_hw
*isac
= container_of(dch
, struct isac_hw
, dch
);
559 struct mISDNhead
*hh
= mISDN_HEAD_P(skb
);
565 spin_lock_irqsave(isac
->hwlock
, flags
);
566 ret
= dchannel_senddata(dch
, skb
);
567 if (ret
> 0) { /* direct TX */
568 id
= hh
->id
; /* skb can be freed */
569 isac_fill_fifo(isac
);
571 spin_unlock_irqrestore(isac
->hwlock
, flags
);
572 queue_ch_frame(ch
, PH_DATA_CNF
, id
, NULL
);
574 spin_unlock_irqrestore(isac
->hwlock
, flags
);
576 case PH_ACTIVATE_REQ
:
577 ret
= l1_event(dch
->l1
, hh
->prim
);
579 case PH_DEACTIVATE_REQ
:
580 test_and_clear_bit(FLG_L2_ACTIVATED
, &dch
->Flags
);
581 ret
= l1_event(dch
->l1
, hh
->prim
);
591 isac_ctrl(struct isac_hw
*isac
, u32 cmd
, unsigned long para
)
599 spin_lock_irqsave(isac
->hwlock
, flags
);
600 if (!(isac
->type
& IPAC_TYPE_ISACX
)) {
601 /* TODO: implement for IPAC_TYPE_ISACX */
602 if (para
& 1) /* B1 */
604 else if (para
& 2) /* B2 */
606 /* we only support IOM2 mode */
607 WriteISAC(isac
, ISAC_SPCR
, tl
);
609 WriteISAC(isac
, ISAC_ADF1
, 0x8);
611 WriteISAC(isac
, ISAC_ADF1
, 0x0);
613 spin_unlock_irqrestore(isac
->hwlock
, flags
);
615 case HW_TIMER3_VALUE
:
616 ret
= l1_event(isac
->dch
.l1
, HW_TIMER3_VALUE
| (para
& 0xff));
619 pr_debug("%s: %s unknown command %x %lx\n", isac
->name
,
620 __func__
, cmd
, para
);
627 isac_l1cmd(struct dchannel
*dch
, u32 cmd
)
629 struct isac_hw
*isac
= container_of(dch
, struct isac_hw
, dch
);
632 pr_debug("%s: cmd(%x) state(%02x)\n", isac
->name
, cmd
, isac
->state
);
635 spin_lock_irqsave(isac
->hwlock
, flags
);
636 ph_command(isac
, ISAC_CMD_AR8
);
637 spin_unlock_irqrestore(isac
->hwlock
, flags
);
640 spin_lock_irqsave(isac
->hwlock
, flags
);
641 ph_command(isac
, ISAC_CMD_AR10
);
642 spin_unlock_irqrestore(isac
->hwlock
, flags
);
645 spin_lock_irqsave(isac
->hwlock
, flags
);
646 if ((isac
->state
== ISAC_IND_EI
) ||
647 (isac
->state
== ISAC_IND_DR
) ||
648 (isac
->state
== ISAC_IND_DR6
) ||
649 (isac
->state
== ISAC_IND_RS
))
650 ph_command(isac
, ISAC_CMD_TIM
);
652 ph_command(isac
, ISAC_CMD_RS
);
653 spin_unlock_irqrestore(isac
->hwlock
, flags
);
656 skb_queue_purge(&dch
->squeue
);
658 dev_kfree_skb(dch
->tx_skb
);
663 dev_kfree_skb(dch
->rx_skb
);
666 test_and_clear_bit(FLG_TX_BUSY
, &dch
->Flags
);
667 if (test_and_clear_bit(FLG_BUSY_TIMER
, &dch
->Flags
))
668 del_timer(&dch
->timer
);
671 spin_lock_irqsave(isac
->hwlock
, flags
);
672 ph_command(isac
, ISAC_CMD_TIM
);
673 spin_unlock_irqrestore(isac
->hwlock
, flags
);
675 case PH_ACTIVATE_IND
:
676 test_and_set_bit(FLG_ACTIVE
, &dch
->Flags
);
677 _queue_data(&dch
->dev
.D
, cmd
, MISDN_ID_ANY
, 0, NULL
,
680 case PH_DEACTIVATE_IND
:
681 test_and_clear_bit(FLG_ACTIVE
, &dch
->Flags
);
682 _queue_data(&dch
->dev
.D
, cmd
, MISDN_ID_ANY
, 0, NULL
,
686 pr_debug("%s: %s unknown command %x\n", isac
->name
,
694 isac_release(struct isac_hw
*isac
)
696 if (isac
->type
& IPAC_TYPE_ISACX
)
697 WriteISAC(isac
, ISACX_MASK
, 0xff);
698 else if (isac
->type
!= 0)
699 WriteISAC(isac
, ISAC_MASK
, 0xff);
700 if (isac
->dch
.timer
.function
!= NULL
) {
701 del_timer(&isac
->dch
.timer
);
702 isac
->dch
.timer
.function
= NULL
;
709 l1_event(isac
->dch
.l1
, CLOSE_CHANNEL
);
710 mISDN_freedchannel(&isac
->dch
);
714 dbusy_timer_handler(struct timer_list
*t
)
716 struct isac_hw
*isac
= from_timer(isac
, t
, dch
.timer
);
720 if (test_bit(FLG_BUSY_TIMER
, &isac
->dch
.Flags
)) {
721 spin_lock_irqsave(isac
->hwlock
, flags
);
722 rbch
= ReadISAC(isac
, ISAC_RBCH
);
723 star
= ReadISAC(isac
, ISAC_STAR
);
724 pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
725 isac
->name
, rbch
, star
);
726 if (rbch
& ISAC_RBCH_XAC
) /* D-Channel Busy */
727 test_and_set_bit(FLG_L1_BUSY
, &isac
->dch
.Flags
);
729 /* discard frame; reset transceiver */
730 test_and_clear_bit(FLG_BUSY_TIMER
, &isac
->dch
.Flags
);
731 if (isac
->dch
.tx_idx
)
732 isac
->dch
.tx_idx
= 0;
734 pr_info("%s: ISAC D-Channel Busy no tx_idx\n",
736 /* Transmitter reset */
737 WriteISAC(isac
, ISAC_CMDR
, 0x01);
739 spin_unlock_irqrestore(isac
->hwlock
, flags
);
744 open_dchannel_caller(struct isac_hw
*isac
, struct channel_req
*rq
, void *caller
)
746 pr_debug("%s: %s dev(%d) open from %p\n", isac
->name
, __func__
,
747 isac
->dch
.dev
.id
, caller
);
748 if (rq
->protocol
!= ISDN_P_TE_S0
)
750 if (rq
->adr
.channel
== 1)
751 /* E-Channel not supported */
753 rq
->ch
= &isac
->dch
.dev
.D
;
754 rq
->ch
->protocol
= rq
->protocol
;
755 if (isac
->dch
.state
== 7)
756 _queue_data(rq
->ch
, PH_ACTIVATE_IND
, MISDN_ID_ANY
,
757 0, NULL
, GFP_KERNEL
);
762 open_dchannel(struct isac_hw
*isac
, struct channel_req
*rq
)
764 return open_dchannel_caller(isac
, rq
, __builtin_return_address(0));
767 static const char *ISACVer
[] =
768 {"2086/2186 V1.1", "2085 B1", "2085 B2",
772 isac_init(struct isac_hw
*isac
)
778 err
= create_l1(&isac
->dch
, isac_l1cmd
);
784 timer_setup(&isac
->dch
.timer
, dbusy_timer_handler
, 0);
786 if (isac
->type
& IPAC_TYPE_ISACX
) {
787 /* Disable all IRQ */
788 WriteISAC(isac
, ISACX_MASK
, 0xff);
789 val
= ReadISAC(isac
, ISACX_STARD
);
790 pr_debug("%s: ISACX STARD %x\n", isac
->name
, val
);
791 val
= ReadISAC(isac
, ISACX_ISTAD
);
792 pr_debug("%s: ISACX ISTAD %x\n", isac
->name
, val
);
793 val
= ReadISAC(isac
, ISACX_ISTA
);
794 pr_debug("%s: ISACX ISTA %x\n", isac
->name
, val
);
796 WriteISAC(isac
, ISACX_TR_CONF0
, 0x00);
797 /* enable transmitter */
798 WriteISAC(isac
, ISACX_TR_CONF2
, 0x00);
799 /* transparent mode 0, RAC, stop/go */
800 WriteISAC(isac
, ISACX_MODED
, 0xc9);
801 /* all HDLC IRQ unmasked */
802 val
= ReadISAC(isac
, ISACX_ID
);
803 if (isac
->dch
.debug
& DEBUG_HW
)
804 pr_notice("%s: ISACX Design ID %x\n",
805 isac
->name
, val
& 0x3f);
806 val
= ReadISAC(isac
, ISACX_CIR0
);
807 pr_debug("%s: ISACX CIR0 %02X\n", isac
->name
, val
);
808 isac
->state
= val
>> 4;
809 isac_ph_state_change(isac
);
810 ph_command(isac
, ISAC_CMD_RS
);
811 WriteISAC(isac
, ISACX_MASK
, IPACX__ON
);
812 WriteISAC(isac
, ISACX_MASKD
, 0x00);
813 } else { /* old isac */
814 WriteISAC(isac
, ISAC_MASK
, 0xff);
815 val
= ReadISAC(isac
, ISAC_STAR
);
816 pr_debug("%s: ISAC STAR %x\n", isac
->name
, val
);
817 val
= ReadISAC(isac
, ISAC_MODE
);
818 pr_debug("%s: ISAC MODE %x\n", isac
->name
, val
);
819 val
= ReadISAC(isac
, ISAC_ADF2
);
820 pr_debug("%s: ISAC ADF2 %x\n", isac
->name
, val
);
821 val
= ReadISAC(isac
, ISAC_ISTA
);
822 pr_debug("%s: ISAC ISTA %x\n", isac
->name
, val
);
824 val
= ReadISAC(isac
, ISAC_EXIR
);
825 pr_debug("%s: ISAC EXIR %x\n", isac
->name
, val
);
827 val
= ReadISAC(isac
, ISAC_RBCH
);
828 if (isac
->dch
.debug
& DEBUG_HW
)
829 pr_notice("%s: ISAC version (%x): %s\n", isac
->name
,
830 val
, ISACVer
[(val
>> 5) & 3]);
831 isac
->type
|= ((val
>> 5) & 3);
834 if (!(isac
->adf2
& 0x80)) { /* only IOM 2 Mode */
835 pr_info("%s: only support IOM2 mode but adf2=%02x\n",
836 isac
->name
, isac
->adf2
);
840 WriteISAC(isac
, ISAC_ADF2
, isac
->adf2
);
841 WriteISAC(isac
, ISAC_SQXR
, 0x2f);
842 WriteISAC(isac
, ISAC_SPCR
, 0x00);
843 WriteISAC(isac
, ISAC_STCR
, 0x70);
844 WriteISAC(isac
, ISAC_MODE
, 0xc9);
845 WriteISAC(isac
, ISAC_TIMR
, 0x00);
846 WriteISAC(isac
, ISAC_ADF1
, 0x00);
847 val
= ReadISAC(isac
, ISAC_CIR0
);
848 pr_debug("%s: ISAC CIR0 %x\n", isac
->name
, val
);
849 isac
->state
= (val
>> 2) & 0xf;
850 isac_ph_state_change(isac
);
851 ph_command(isac
, ISAC_CMD_RS
);
852 WriteISAC(isac
, ISAC_MASK
, 0);
858 mISDNisac_init(struct isac_hw
*isac
, void *hw
)
860 mISDN_initdchannel(&isac
->dch
, MAX_DFRAME_LEN_L1
, isac_ph_state_bh
);
862 isac
->dch
.dev
.D
.send
= isac_l1hw
;
863 isac
->init
= isac_init
;
864 isac
->release
= isac_release
;
865 isac
->ctrl
= isac_ctrl
;
866 isac
->open
= open_dchannel
;
867 isac
->dch
.dev
.Dprotocols
= (1 << ISDN_P_TE_S0
);
868 isac
->dch
.dev
.nrbchan
= 2;
871 EXPORT_SYMBOL(mISDNisac_init
);
874 waitforCEC(struct hscx_hw
*hx
)
879 starb
= ReadHSCX(hx
, IPAC_STARB
);
886 pr_debug("%s: B%1d CEC %d us\n", hx
->ip
->name
, hx
->bch
.nr
,
889 pr_info("%s: B%1d CEC timeout\n", hx
->ip
->name
, hx
->bch
.nr
);
894 waitforXFW(struct hscx_hw
*hx
)
899 starb
= ReadHSCX(hx
, IPAC_STARB
);
900 if ((starb
& 0x44) == 0x40)
906 pr_debug("%s: B%1d XFW %d us\n", hx
->ip
->name
, hx
->bch
.nr
,
909 pr_info("%s: B%1d XFW timeout\n", hx
->ip
->name
, hx
->bch
.nr
);
913 hscx_cmdr(struct hscx_hw
*hx
, u8 cmd
)
915 if (hx
->ip
->type
& IPAC_TYPE_IPACX
)
916 WriteHSCX(hx
, IPACX_CMDRB
, cmd
);
919 WriteHSCX(hx
, IPAC_CMDRB
, cmd
);
924 hscx_empty_fifo(struct hscx_hw
*hscx
, u8 count
)
929 pr_debug("%s: B%1d %d\n", hscx
->ip
->name
, hscx
->bch
.nr
, count
);
930 if (test_bit(FLG_RX_OFF
, &hscx
->bch
.Flags
)) {
931 hscx
->bch
.dropcnt
+= count
;
932 hscx_cmdr(hscx
, 0x80); /* RMC */
935 maxlen
= bchannel_get_rxbuf(&hscx
->bch
, count
);
937 hscx_cmdr(hscx
, 0x80); /* RMC */
938 if (hscx
->bch
.rx_skb
)
939 skb_trim(hscx
->bch
.rx_skb
, 0);
940 pr_warn("%s.B%d: No bufferspace for %d bytes\n",
941 hscx
->ip
->name
, hscx
->bch
.nr
, count
);
944 p
= skb_put(hscx
->bch
.rx_skb
, count
);
946 if (hscx
->ip
->type
& IPAC_TYPE_IPACX
)
947 hscx
->ip
->read_fifo(hscx
->ip
->hw
,
948 hscx
->off
+ IPACX_RFIFOB
, p
, count
);
950 hscx
->ip
->read_fifo(hscx
->ip
->hw
,
951 hscx
->off
, p
, count
);
953 hscx_cmdr(hscx
, 0x80); /* RMC */
955 if (hscx
->bch
.debug
& DEBUG_HW_BFIFO
) {
956 snprintf(hscx
->log
, 64, "B%1d-recv %s %d ",
957 hscx
->bch
.nr
, hscx
->ip
->name
, count
);
958 print_hex_dump_bytes(hscx
->log
, DUMP_PREFIX_OFFSET
, p
, count
);
963 hscx_fill_fifo(struct hscx_hw
*hscx
)
968 if (!hscx
->bch
.tx_skb
) {
969 if (!test_bit(FLG_TX_EMPTY
, &hscx
->bch
.Flags
))
971 count
= hscx
->fifo_size
;
974 memset(p
, hscx
->bch
.fill
[0], count
);
976 count
= hscx
->bch
.tx_skb
->len
- hscx
->bch
.tx_idx
;
979 p
= hscx
->bch
.tx_skb
->data
+ hscx
->bch
.tx_idx
;
981 more
= test_bit(FLG_TRANSPARENT
, &hscx
->bch
.Flags
) ? 1 : 0;
982 if (count
> hscx
->fifo_size
) {
983 count
= hscx
->fifo_size
;
986 pr_debug("%s: B%1d %d/%d/%d\n", hscx
->ip
->name
, hscx
->bch
.nr
,
987 count
, hscx
->bch
.tx_idx
, hscx
->bch
.tx_skb
->len
);
988 hscx
->bch
.tx_idx
+= count
;
990 if (hscx
->ip
->type
& IPAC_TYPE_IPACX
)
991 hscx
->ip
->write_fifo(hscx
->ip
->hw
,
992 hscx
->off
+ IPACX_XFIFOB
, p
, count
);
995 hscx
->ip
->write_fifo(hscx
->ip
->hw
,
996 hscx
->off
, p
, count
);
998 hscx_cmdr(hscx
, more
? 0x08 : 0x0a);
1000 if (hscx
->bch
.tx_skb
&& (hscx
->bch
.debug
& DEBUG_HW_BFIFO
)) {
1001 snprintf(hscx
->log
, 64, "B%1d-send %s %d ",
1002 hscx
->bch
.nr
, hscx
->ip
->name
, count
);
1003 print_hex_dump_bytes(hscx
->log
, DUMP_PREFIX_OFFSET
, p
, count
);
1008 hscx_xpr(struct hscx_hw
*hx
)
1010 if (hx
->bch
.tx_skb
&& hx
->bch
.tx_idx
< hx
->bch
.tx_skb
->len
) {
1013 dev_kfree_skb(hx
->bch
.tx_skb
);
1014 if (get_next_bframe(&hx
->bch
)) {
1016 test_and_clear_bit(FLG_TX_EMPTY
, &hx
->bch
.Flags
);
1017 } else if (test_bit(FLG_TX_EMPTY
, &hx
->bch
.Flags
)) {
1024 ipac_rme(struct hscx_hw
*hx
)
1029 if (hx
->ip
->type
& IPAC_TYPE_IPACX
)
1030 rstab
= ReadHSCX(hx
, IPACX_RSTAB
);
1032 rstab
= ReadHSCX(hx
, IPAC_RSTAB
);
1033 pr_debug("%s: B%1d RSTAB %02x\n", hx
->ip
->name
, hx
->bch
.nr
, rstab
);
1034 if ((rstab
& 0xf0) != 0xa0) {
1035 /* !(VFR && !RDO && CRC && !RAB) */
1036 if (!(rstab
& 0x80)) {
1037 if (hx
->bch
.debug
& DEBUG_HW_BCHANNEL
)
1038 pr_notice("%s: B%1d invalid frame\n",
1039 hx
->ip
->name
, hx
->bch
.nr
);
1042 if (hx
->bch
.debug
& DEBUG_HW_BCHANNEL
)
1043 pr_notice("%s: B%1d RDO proto=%x\n",
1044 hx
->ip
->name
, hx
->bch
.nr
,
1047 if (!(rstab
& 0x20)) {
1048 if (hx
->bch
.debug
& DEBUG_HW_BCHANNEL
)
1049 pr_notice("%s: B%1d CRC error\n",
1050 hx
->ip
->name
, hx
->bch
.nr
);
1052 hscx_cmdr(hx
, 0x80); /* Do RMC */
1055 if (hx
->ip
->type
& IPAC_TYPE_IPACX
)
1056 count
= ReadHSCX(hx
, IPACX_RBCLB
);
1058 count
= ReadHSCX(hx
, IPAC_RBCLB
);
1059 count
&= (hx
->fifo_size
- 1);
1061 count
= hx
->fifo_size
;
1062 hscx_empty_fifo(hx
, count
);
1063 if (!hx
->bch
.rx_skb
)
1065 if (hx
->bch
.rx_skb
->len
< 2) {
1066 pr_debug("%s: B%1d frame too short %d\n",
1067 hx
->ip
->name
, hx
->bch
.nr
, hx
->bch
.rx_skb
->len
);
1068 skb_trim(hx
->bch
.rx_skb
, 0);
1070 skb_trim(hx
->bch
.rx_skb
, hx
->bch
.rx_skb
->len
- 1);
1071 recv_Bchannel(&hx
->bch
, 0, false);
1076 ipac_irq(struct hscx_hw
*hx
, u8 ista
)
1078 u8 istab
, m
, exirb
= 0;
1080 if (hx
->ip
->type
& IPAC_TYPE_IPACX
)
1081 istab
= ReadHSCX(hx
, IPACX_ISTAB
);
1082 else if (hx
->ip
->type
& IPAC_TYPE_IPAC
) {
1083 istab
= ReadHSCX(hx
, IPAC_ISTAB
);
1084 m
= (hx
->bch
.nr
& 1) ? IPAC__EXA
: IPAC__EXB
;
1086 exirb
= ReadHSCX(hx
, IPAC_EXIRB
);
1087 pr_debug("%s: B%1d EXIRB %02x\n", hx
->ip
->name
,
1090 } else if (hx
->bch
.nr
& 2) { /* HSCX B */
1091 if (ista
& (HSCX__EXA
| HSCX__ICA
))
1092 ipac_irq(&hx
->ip
->hscx
[0], ista
);
1093 if (ista
& HSCX__EXB
) {
1094 exirb
= ReadHSCX(hx
, IPAC_EXIRB
);
1095 pr_debug("%s: B%1d EXIRB %02x\n", hx
->ip
->name
,
1098 istab
= ista
& 0xF8;
1099 } else { /* HSCX A */
1100 istab
= ReadHSCX(hx
, IPAC_ISTAB
);
1101 if (ista
& HSCX__EXA
) {
1102 exirb
= ReadHSCX(hx
, IPAC_EXIRB
);
1103 pr_debug("%s: B%1d EXIRB %02x\n", hx
->ip
->name
,
1106 istab
= istab
& 0xF8;
1108 if (exirb
& IPAC_B_XDU
)
1109 istab
|= IPACX_B_XDU
;
1110 if (exirb
& IPAC_B_RFO
)
1111 istab
|= IPACX_B_RFO
;
1112 pr_debug("%s: B%1d ISTAB %02x\n", hx
->ip
->name
, hx
->bch
.nr
, istab
);
1114 if (!test_bit(FLG_ACTIVE
, &hx
->bch
.Flags
))
1117 if (istab
& IPACX_B_RME
)
1120 if (istab
& IPACX_B_RPF
) {
1121 hscx_empty_fifo(hx
, hx
->fifo_size
);
1122 if (test_bit(FLG_TRANSPARENT
, &hx
->bch
.Flags
))
1123 recv_Bchannel(&hx
->bch
, 0, false);
1126 if (istab
& IPACX_B_RFO
) {
1127 pr_debug("%s: B%1d RFO error\n", hx
->ip
->name
, hx
->bch
.nr
);
1128 hscx_cmdr(hx
, 0x40); /* RRES */
1131 if (istab
& IPACX_B_XPR
)
1134 if (istab
& IPACX_B_XDU
) {
1135 if (test_bit(FLG_TRANSPARENT
, &hx
->bch
.Flags
)) {
1136 if (test_bit(FLG_FILLEMPTY
, &hx
->bch
.Flags
))
1137 test_and_set_bit(FLG_TX_EMPTY
, &hx
->bch
.Flags
);
1141 pr_debug("%s: B%1d XDU error at len %d\n", hx
->ip
->name
,
1142 hx
->bch
.nr
, hx
->bch
.tx_idx
);
1144 hscx_cmdr(hx
, 0x01); /* XRES */
1149 mISDNipac_irq(struct ipac_hw
*ipac
, int maxloop
)
1151 int cnt
= maxloop
+ 1;
1153 struct isac_hw
*isac
= &ipac
->isac
;
1155 if (ipac
->type
& IPAC_TYPE_IPACX
) {
1156 ista
= ReadIPAC(ipac
, ISACX_ISTA
);
1157 while (ista
&& --cnt
) {
1158 pr_debug("%s: ISTA %02x\n", ipac
->name
, ista
);
1159 if (ista
& IPACX__ICA
)
1160 ipac_irq(&ipac
->hscx
[0], ista
);
1161 if (ista
& IPACX__ICB
)
1162 ipac_irq(&ipac
->hscx
[1], ista
);
1163 if (ista
& (ISACX__ICD
| ISACX__CIC
))
1164 mISDNisac_irq(&ipac
->isac
, ista
);
1165 ista
= ReadIPAC(ipac
, ISACX_ISTA
);
1167 } else if (ipac
->type
& IPAC_TYPE_IPAC
) {
1168 ista
= ReadIPAC(ipac
, IPAC_ISTA
);
1169 while (ista
&& --cnt
) {
1170 pr_debug("%s: ISTA %02x\n", ipac
->name
, ista
);
1171 if (ista
& (IPAC__ICD
| IPAC__EXD
)) {
1172 istad
= ReadISAC(isac
, ISAC_ISTA
);
1173 pr_debug("%s: ISTAD %02x\n", ipac
->name
, istad
);
1174 if (istad
& IPAC_D_TIN2
)
1175 pr_debug("%s TIN2 irq\n", ipac
->name
);
1176 if (ista
& IPAC__EXD
)
1177 istad
|= 1; /* ISAC EXI */
1178 mISDNisac_irq(isac
, istad
);
1180 if (ista
& (IPAC__ICA
| IPAC__EXA
))
1181 ipac_irq(&ipac
->hscx
[0], ista
);
1182 if (ista
& (IPAC__ICB
| IPAC__EXB
))
1183 ipac_irq(&ipac
->hscx
[1], ista
);
1184 ista
= ReadIPAC(ipac
, IPAC_ISTA
);
1186 } else if (ipac
->type
& IPAC_TYPE_HSCX
) {
1188 ista
= ReadIPAC(ipac
, IPAC_ISTAB
+ ipac
->hscx
[1].off
);
1189 pr_debug("%s: B2 ISTA %02x\n", ipac
->name
, ista
);
1191 ipac_irq(&ipac
->hscx
[1], ista
);
1192 istad
= ReadISAC(isac
, ISAC_ISTA
);
1193 pr_debug("%s: ISTAD %02x\n", ipac
->name
, istad
);
1195 mISDNisac_irq(isac
, istad
);
1196 if (0 == (ista
| istad
))
1200 if (cnt
> maxloop
) /* only for ISAC/HSCX without PCI IRQ test */
1203 pr_debug("%s: %d irqloops cpu%d\n", ipac
->name
,
1204 maxloop
- cnt
, smp_processor_id());
1205 if (maxloop
&& !cnt
)
1206 pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac
->name
,
1207 maxloop
, smp_processor_id());
1210 EXPORT_SYMBOL(mISDNipac_irq
);
1213 hscx_mode(struct hscx_hw
*hscx
, u32 bprotocol
)
1215 pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx
->ip
->name
,
1216 '@' + hscx
->bch
.nr
, hscx
->bch
.state
, bprotocol
, hscx
->bch
.nr
);
1217 if (hscx
->ip
->type
& IPAC_TYPE_IPACX
) {
1218 if (hscx
->bch
.nr
& 1) { /* B1 and ICA */
1219 WriteIPAC(hscx
->ip
, ISACX_BCHA_TSDP_BC1
, 0x80);
1220 WriteIPAC(hscx
->ip
, ISACX_BCHA_CR
, 0x88);
1221 } else { /* B2 and ICB */
1222 WriteIPAC(hscx
->ip
, ISACX_BCHB_TSDP_BC1
, 0x81);
1223 WriteIPAC(hscx
->ip
, ISACX_BCHB_CR
, 0x88);
1225 switch (bprotocol
) {
1226 case ISDN_P_NONE
: /* init */
1227 WriteHSCX(hscx
, IPACX_MODEB
, 0xC0); /* rec off */
1228 WriteHSCX(hscx
, IPACX_EXMB
, 0x30); /* std adj. */
1229 WriteHSCX(hscx
, IPACX_MASKB
, 0xFF); /* ints off */
1230 hscx_cmdr(hscx
, 0x41);
1231 test_and_clear_bit(FLG_HDLC
, &hscx
->bch
.Flags
);
1232 test_and_clear_bit(FLG_TRANSPARENT
, &hscx
->bch
.Flags
);
1235 WriteHSCX(hscx
, IPACX_MODEB
, 0x88); /* ex trans */
1236 WriteHSCX(hscx
, IPACX_EXMB
, 0x00); /* trans */
1237 hscx_cmdr(hscx
, 0x41);
1238 WriteHSCX(hscx
, IPACX_MASKB
, IPACX_B_ON
);
1239 test_and_set_bit(FLG_TRANSPARENT
, &hscx
->bch
.Flags
);
1242 WriteHSCX(hscx
, IPACX_MODEB
, 0xC0); /* trans */
1243 WriteHSCX(hscx
, IPACX_EXMB
, 0x00); /* hdlc,crc */
1244 hscx_cmdr(hscx
, 0x41);
1245 WriteHSCX(hscx
, IPACX_MASKB
, IPACX_B_ON
);
1246 test_and_set_bit(FLG_HDLC
, &hscx
->bch
.Flags
);
1249 pr_info("%s: protocol not known %x\n", hscx
->ip
->name
,
1251 return -ENOPROTOOPT
;
1253 } else if (hscx
->ip
->type
& IPAC_TYPE_IPAC
) { /* IPAC */
1254 WriteHSCX(hscx
, IPAC_CCR1
, 0x82);
1255 WriteHSCX(hscx
, IPAC_CCR2
, 0x30);
1256 WriteHSCX(hscx
, IPAC_XCCR
, 0x07);
1257 WriteHSCX(hscx
, IPAC_RCCR
, 0x07);
1258 WriteHSCX(hscx
, IPAC_TSAX
, hscx
->slot
);
1259 WriteHSCX(hscx
, IPAC_TSAR
, hscx
->slot
);
1260 switch (bprotocol
) {
1262 WriteHSCX(hscx
, IPAC_TSAX
, 0x1F);
1263 WriteHSCX(hscx
, IPAC_TSAR
, 0x1F);
1264 WriteHSCX(hscx
, IPAC_MODEB
, 0x84);
1265 WriteHSCX(hscx
, IPAC_CCR1
, 0x82);
1266 WriteHSCX(hscx
, IPAC_MASKB
, 0xFF); /* ints off */
1267 test_and_clear_bit(FLG_HDLC
, &hscx
->bch
.Flags
);
1268 test_and_clear_bit(FLG_TRANSPARENT
, &hscx
->bch
.Flags
);
1271 WriteHSCX(hscx
, IPAC_MODEB
, 0xe4); /* ex trans */
1272 WriteHSCX(hscx
, IPAC_CCR1
, 0x82);
1273 hscx_cmdr(hscx
, 0x41);
1274 WriteHSCX(hscx
, IPAC_MASKB
, 0);
1275 test_and_set_bit(FLG_TRANSPARENT
, &hscx
->bch
.Flags
);
1278 WriteHSCX(hscx
, IPAC_MODEB
, 0x8c);
1279 WriteHSCX(hscx
, IPAC_CCR1
, 0x8a);
1280 hscx_cmdr(hscx
, 0x41);
1281 WriteHSCX(hscx
, IPAC_MASKB
, 0);
1282 test_and_set_bit(FLG_HDLC
, &hscx
->bch
.Flags
);
1285 pr_info("%s: protocol not known %x\n", hscx
->ip
->name
,
1287 return -ENOPROTOOPT
;
1289 } else if (hscx
->ip
->type
& IPAC_TYPE_HSCX
) { /* HSCX */
1290 WriteHSCX(hscx
, IPAC_CCR1
, 0x85);
1291 WriteHSCX(hscx
, IPAC_CCR2
, 0x30);
1292 WriteHSCX(hscx
, IPAC_XCCR
, 0x07);
1293 WriteHSCX(hscx
, IPAC_RCCR
, 0x07);
1294 WriteHSCX(hscx
, IPAC_TSAX
, hscx
->slot
);
1295 WriteHSCX(hscx
, IPAC_TSAR
, hscx
->slot
);
1296 switch (bprotocol
) {
1298 WriteHSCX(hscx
, IPAC_TSAX
, 0x1F);
1299 WriteHSCX(hscx
, IPAC_TSAR
, 0x1F);
1300 WriteHSCX(hscx
, IPAC_MODEB
, 0x84);
1301 WriteHSCX(hscx
, IPAC_CCR1
, 0x85);
1302 WriteHSCX(hscx
, IPAC_MASKB
, 0xFF); /* ints off */
1303 test_and_clear_bit(FLG_HDLC
, &hscx
->bch
.Flags
);
1304 test_and_clear_bit(FLG_TRANSPARENT
, &hscx
->bch
.Flags
);
1307 WriteHSCX(hscx
, IPAC_MODEB
, 0xe4); /* ex trans */
1308 WriteHSCX(hscx
, IPAC_CCR1
, 0x85);
1309 hscx_cmdr(hscx
, 0x41);
1310 WriteHSCX(hscx
, IPAC_MASKB
, 0);
1311 test_and_set_bit(FLG_TRANSPARENT
, &hscx
->bch
.Flags
);
1314 WriteHSCX(hscx
, IPAC_MODEB
, 0x8c);
1315 WriteHSCX(hscx
, IPAC_CCR1
, 0x8d);
1316 hscx_cmdr(hscx
, 0x41);
1317 WriteHSCX(hscx
, IPAC_MASKB
, 0);
1318 test_and_set_bit(FLG_HDLC
, &hscx
->bch
.Flags
);
1321 pr_info("%s: protocol not known %x\n", hscx
->ip
->name
,
1323 return -ENOPROTOOPT
;
1327 hscx
->bch
.state
= bprotocol
;
1332 hscx_l2l1(struct mISDNchannel
*ch
, struct sk_buff
*skb
)
1334 struct bchannel
*bch
= container_of(ch
, struct bchannel
, ch
);
1335 struct hscx_hw
*hx
= container_of(bch
, struct hscx_hw
, bch
);
1337 struct mISDNhead
*hh
= mISDN_HEAD_P(skb
);
1338 unsigned long flags
;
1342 spin_lock_irqsave(hx
->ip
->hwlock
, flags
);
1343 ret
= bchannel_senddata(bch
, skb
);
1344 if (ret
> 0) { /* direct TX */
1348 spin_unlock_irqrestore(hx
->ip
->hwlock
, flags
);
1350 case PH_ACTIVATE_REQ
:
1351 spin_lock_irqsave(hx
->ip
->hwlock
, flags
);
1352 if (!test_and_set_bit(FLG_ACTIVE
, &bch
->Flags
))
1353 ret
= hscx_mode(hx
, ch
->protocol
);
1356 spin_unlock_irqrestore(hx
->ip
->hwlock
, flags
);
1358 _queue_data(ch
, PH_ACTIVATE_IND
, MISDN_ID_ANY
, 0,
1361 case PH_DEACTIVATE_REQ
:
1362 spin_lock_irqsave(hx
->ip
->hwlock
, flags
);
1363 mISDN_clear_bchannel(bch
);
1364 hscx_mode(hx
, ISDN_P_NONE
);
1365 spin_unlock_irqrestore(hx
->ip
->hwlock
, flags
);
1366 _queue_data(ch
, PH_DEACTIVATE_IND
, MISDN_ID_ANY
, 0,
1371 pr_info("%s: %s unknown prim(%x,%x)\n",
1372 hx
->ip
->name
, __func__
, hh
->prim
, hh
->id
);
1381 channel_bctrl(struct bchannel
*bch
, struct mISDN_ctrl_req
*cq
)
1383 return mISDN_ctrl_bchannel(bch
, cq
);
1387 hscx_bctrl(struct mISDNchannel
*ch
, u32 cmd
, void *arg
)
1389 struct bchannel
*bch
= container_of(ch
, struct bchannel
, ch
);
1390 struct hscx_hw
*hx
= container_of(bch
, struct hscx_hw
, bch
);
1394 pr_debug("%s: %s cmd:%x %p\n", hx
->ip
->name
, __func__
, cmd
, arg
);
1397 test_and_clear_bit(FLG_OPEN
, &bch
->Flags
);
1398 cancel_work_sync(&bch
->workq
);
1399 spin_lock_irqsave(hx
->ip
->hwlock
, flags
);
1400 mISDN_clear_bchannel(bch
);
1401 hscx_mode(hx
, ISDN_P_NONE
);
1402 spin_unlock_irqrestore(hx
->ip
->hwlock
, flags
);
1403 ch
->protocol
= ISDN_P_NONE
;
1405 module_put(hx
->ip
->owner
);
1408 case CONTROL_CHANNEL
:
1409 ret
= channel_bctrl(bch
, arg
);
1412 pr_info("%s: %s unknown prim(%x)\n",
1413 hx
->ip
->name
, __func__
, cmd
);
1419 free_ipac(struct ipac_hw
*ipac
)
1421 isac_release(&ipac
->isac
);
1424 static const char *HSCXVer
[] =
1425 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
1426 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
1431 hscx_init(struct hscx_hw
*hx
)
1435 WriteHSCX(hx
, IPAC_RAH2
, 0xFF);
1436 WriteHSCX(hx
, IPAC_XBCH
, 0x00);
1437 WriteHSCX(hx
, IPAC_RLCR
, 0x00);
1439 if (hx
->ip
->type
& IPAC_TYPE_HSCX
) {
1440 WriteHSCX(hx
, IPAC_CCR1
, 0x85);
1441 val
= ReadHSCX(hx
, HSCX_VSTR
);
1442 pr_debug("%s: HSCX VSTR %02x\n", hx
->ip
->name
, val
);
1443 if (hx
->bch
.debug
& DEBUG_HW
)
1444 pr_notice("%s: HSCX version %s\n", hx
->ip
->name
,
1445 HSCXVer
[val
& 0x0f]);
1447 WriteHSCX(hx
, IPAC_CCR1
, 0x82);
1448 WriteHSCX(hx
, IPAC_CCR2
, 0x30);
1449 WriteHSCX(hx
, IPAC_XCCR
, 0x07);
1450 WriteHSCX(hx
, IPAC_RCCR
, 0x07);
1454 ipac_init(struct ipac_hw
*ipac
)
1458 if (ipac
->type
& IPAC_TYPE_HSCX
) {
1459 hscx_init(&ipac
->hscx
[0]);
1460 hscx_init(&ipac
->hscx
[1]);
1461 val
= ReadIPAC(ipac
, IPAC_ID
);
1462 } else if (ipac
->type
& IPAC_TYPE_IPAC
) {
1463 hscx_init(&ipac
->hscx
[0]);
1464 hscx_init(&ipac
->hscx
[1]);
1465 WriteIPAC(ipac
, IPAC_MASK
, IPAC__ON
);
1466 val
= ReadIPAC(ipac
, IPAC_CONF
);
1467 /* conf is default 0, but can be overwritten by card setup */
1468 pr_debug("%s: IPAC CONF %02x/%02x\n", ipac
->name
,
1470 WriteIPAC(ipac
, IPAC_CONF
, ipac
->conf
);
1471 val
= ReadIPAC(ipac
, IPAC_ID
);
1472 if (ipac
->hscx
[0].bch
.debug
& DEBUG_HW
)
1473 pr_notice("%s: IPAC Design ID %02x\n", ipac
->name
, val
);
1475 /* nothing special for IPACX to do here */
1476 return isac_init(&ipac
->isac
);
1480 open_bchannel(struct ipac_hw
*ipac
, struct channel_req
*rq
)
1482 struct bchannel
*bch
;
1484 if (rq
->adr
.channel
== 0 || rq
->adr
.channel
> 2)
1486 if (rq
->protocol
== ISDN_P_NONE
)
1488 bch
= &ipac
->hscx
[rq
->adr
.channel
- 1].bch
;
1489 if (test_and_set_bit(FLG_OPEN
, &bch
->Flags
))
1490 return -EBUSY
; /* b-channel can be only open once */
1491 test_and_clear_bit(FLG_FILLEMPTY
, &bch
->Flags
);
1492 bch
->ch
.protocol
= rq
->protocol
;
1498 channel_ctrl(struct ipac_hw
*ipac
, struct mISDN_ctrl_req
*cq
)
1503 case MISDN_CTRL_GETOP
:
1504 cq
->op
= MISDN_CTRL_LOOP
| MISDN_CTRL_L1_TIMER3
;
1506 case MISDN_CTRL_LOOP
:
1507 /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
1508 if (cq
->channel
< 0 || cq
->channel
> 3) {
1512 ret
= ipac
->ctrl(ipac
, HW_TESTLOOP
, cq
->channel
);
1514 case MISDN_CTRL_L1_TIMER3
:
1515 ret
= ipac
->isac
.ctrl(&ipac
->isac
, HW_TIMER3_VALUE
, cq
->p1
);
1518 pr_info("%s: unknown CTRL OP %x\n", ipac
->name
, cq
->op
);
1526 ipac_dctrl(struct mISDNchannel
*ch
, u32 cmd
, void *arg
)
1528 struct mISDNdevice
*dev
= container_of(ch
, struct mISDNdevice
, D
);
1529 struct dchannel
*dch
= container_of(dev
, struct dchannel
, dev
);
1530 struct isac_hw
*isac
= container_of(dch
, struct isac_hw
, dch
);
1531 struct ipac_hw
*ipac
= container_of(isac
, struct ipac_hw
, isac
);
1532 struct channel_req
*rq
;
1535 pr_debug("%s: DCTRL: %x %p\n", ipac
->name
, cmd
, arg
);
1539 if (rq
->protocol
== ISDN_P_TE_S0
)
1540 err
= open_dchannel_caller(isac
, rq
, __builtin_return_address(0));
1542 err
= open_bchannel(ipac
, rq
);
1545 if (!try_module_get(ipac
->owner
))
1546 pr_info("%s: cannot get module\n", ipac
->name
);
1549 pr_debug("%s: dev(%d) close from %p\n", ipac
->name
,
1550 dch
->dev
.id
, __builtin_return_address(0));
1551 module_put(ipac
->owner
);
1553 case CONTROL_CHANNEL
:
1554 err
= channel_ctrl(ipac
, arg
);
1557 pr_debug("%s: unknown DCTRL command %x\n", ipac
->name
, cmd
);
1564 mISDNipac_init(struct ipac_hw
*ipac
, void *hw
)
1570 if (ipac
->isac
.dch
.debug
& DEBUG_HW
)
1571 pr_notice("%s: ipac type %x\n", ipac
->name
, ipac
->type
);
1572 if (ipac
->type
& IPAC_TYPE_HSCX
) {
1573 ipac
->isac
.type
= IPAC_TYPE_ISAC
;
1574 ipac
->hscx
[0].off
= 0;
1575 ipac
->hscx
[1].off
= 0x40;
1576 ipac
->hscx
[0].fifo_size
= 32;
1577 ipac
->hscx
[1].fifo_size
= 32;
1578 } else if (ipac
->type
& IPAC_TYPE_IPAC
) {
1579 ipac
->isac
.type
= IPAC_TYPE_IPAC
| IPAC_TYPE_ISAC
;
1580 ipac
->hscx
[0].off
= 0;
1581 ipac
->hscx
[1].off
= 0x40;
1582 ipac
->hscx
[0].fifo_size
= 64;
1583 ipac
->hscx
[1].fifo_size
= 64;
1584 } else if (ipac
->type
& IPAC_TYPE_IPACX
) {
1585 ipac
->isac
.type
= IPAC_TYPE_IPACX
| IPAC_TYPE_ISACX
;
1586 ipac
->hscx
[0].off
= IPACX_OFF_ICA
;
1587 ipac
->hscx
[1].off
= IPACX_OFF_ICB
;
1588 ipac
->hscx
[0].fifo_size
= 64;
1589 ipac
->hscx
[1].fifo_size
= 64;
1593 mISDNisac_init(&ipac
->isac
, hw
);
1595 ipac
->isac
.dch
.dev
.D
.ctrl
= ipac_dctrl
;
1597 for (i
= 0; i
< 2; i
++) {
1598 ipac
->hscx
[i
].bch
.nr
= i
+ 1;
1599 set_channelmap(i
+ 1, ipac
->isac
.dch
.dev
.channelmap
);
1600 list_add(&ipac
->hscx
[i
].bch
.ch
.list
,
1601 &ipac
->isac
.dch
.dev
.bchannels
);
1602 mISDN_initbchannel(&ipac
->hscx
[i
].bch
, MAX_DATA_MEM
,
1603 ipac
->hscx
[i
].fifo_size
);
1604 ipac
->hscx
[i
].bch
.ch
.nr
= i
+ 1;
1605 ipac
->hscx
[i
].bch
.ch
.send
= &hscx_l2l1
;
1606 ipac
->hscx
[i
].bch
.ch
.ctrl
= hscx_bctrl
;
1607 ipac
->hscx
[i
].bch
.hw
= hw
;
1608 ipac
->hscx
[i
].ip
= ipac
;
1609 /* default values for IOM time slots
1610 * can be overwritten by card */
1611 ipac
->hscx
[i
].slot
= (i
== 0) ? 0x2f : 0x03;
1614 ipac
->init
= ipac_init
;
1615 ipac
->release
= free_ipac
;
1617 ret
= (1 << (ISDN_P_B_RAW
& ISDN_P_B_MASK
)) |
1618 (1 << (ISDN_P_B_HDLC
& ISDN_P_B_MASK
));
1621 EXPORT_SYMBOL(mISDNipac_init
);
1626 pr_notice("mISDNipac module version %s\n", ISAC_REV
);
1631 isac_mod_cleanup(void)
1633 pr_notice("mISDNipac module unloaded\n");
1635 module_init(isac_mod_init
);
1636 module_exit(isac_mod_cleanup
);