1 /* $Id: jade_irq.c,v 1.7.2.4 2004/02/11 13:21:34 keil Exp $
3 * Low level JADE IRQ stuff (derived from original hscx_irq.c)
5 * Author Roland Klabunde
6 * Copyright by Roland Klabunde <R.Klabunde@Berkom.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
14 waitforCEC(struct IsdnCardState
*cs
, int jade
, int reg
)
17 int mask
= (reg
== jade_HDLC_XCMD
? jadeSTAR_XCEC
: jadeSTAR_RCEC
);
18 while ((READJADE(cs
, jade
, jade_HDLC_STAR
) & mask
) && to
) {
23 printk(KERN_WARNING
"HiSax: waitforCEC (jade) timeout\n");
28 waitforXFW(struct IsdnCardState
*cs
, int jade
)
30 /* Does not work on older jade versions, don't care */
34 WriteJADECMDR(struct IsdnCardState
*cs
, int jade
, int reg
, u_char data
)
36 waitforCEC(cs
, jade
, reg
);
37 WRITEJADE(cs
, jade
, reg
, data
);
43 jade_empty_fifo(struct BCState
*bcs
, int count
)
46 struct IsdnCardState
*cs
= bcs
->cs
;
48 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
49 debugl1(cs
, "jade_empty_fifo");
51 if (bcs
->hw
.hscx
.rcvidx
+ count
> HSCX_BUFMAX
) {
52 if (cs
->debug
& L1_DEB_WARN
)
53 debugl1(cs
, "jade_empty_fifo: incoming packet too large");
54 WriteJADECMDR(cs
, bcs
->hw
.hscx
.hscx
, jade_HDLC_RCMD
, jadeRCMD_RMC
);
55 bcs
->hw
.hscx
.rcvidx
= 0;
58 ptr
= bcs
->hw
.hscx
.rcvbuf
+ bcs
->hw
.hscx
.rcvidx
;
59 bcs
->hw
.hscx
.rcvidx
+= count
;
60 READJADEFIFO(cs
, bcs
->hw
.hscx
.hscx
, ptr
, count
);
61 WriteJADECMDR(cs
, bcs
->hw
.hscx
.hscx
, jade_HDLC_RCMD
, jadeRCMD_RMC
);
62 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
65 t
+= sprintf(t
, "jade_empty_fifo %c cnt %d",
66 bcs
->hw
.hscx
.hscx
? 'B' : 'A', count
);
67 QuickHex(t
, ptr
, count
);
68 debugl1(cs
, "%s", bcs
->blog
);
73 jade_fill_fifo(struct BCState
*bcs
)
75 struct IsdnCardState
*cs
= bcs
->cs
;
80 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
81 debugl1(cs
, "jade_fill_fifo");
85 if (bcs
->tx_skb
->len
<= 0)
88 more
= (bcs
->mode
== L1_MODE_TRANS
) ? 1 : 0;
89 if (bcs
->tx_skb
->len
> fifo_size
) {
93 count
= bcs
->tx_skb
->len
;
95 waitforXFW(cs
, bcs
->hw
.hscx
.hscx
);
96 ptr
= bcs
->tx_skb
->data
;
97 skb_pull(bcs
->tx_skb
, count
);
99 bcs
->hw
.hscx
.count
+= count
;
100 WRITEJADEFIFO(cs
, bcs
->hw
.hscx
.hscx
, ptr
, count
);
101 WriteJADECMDR(cs
, bcs
->hw
.hscx
.hscx
, jade_HDLC_XCMD
, more
? jadeXCMD_XF
: (jadeXCMD_XF
| jadeXCMD_XME
));
102 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
105 t
+= sprintf(t
, "jade_fill_fifo %c cnt %d",
106 bcs
->hw
.hscx
.hscx
? 'B' : 'A', count
);
107 QuickHex(t
, ptr
, count
);
108 debugl1(cs
, "%s", bcs
->blog
);
114 jade_interrupt(struct IsdnCardState
*cs
, u_char val
, u_char jade
)
117 struct BCState
*bcs
= cs
->bcs
+ jade
;
121 int i_jade
= (int) jade
; /* To satisfy the compiler */
123 if (!test_bit(BC_FLG_INIT
, &bcs
->Flag
))
126 if (val
& 0x80) { /* RME */
127 r
= READJADE(cs
, i_jade
, jade_HDLC_RSTA
);
128 if ((r
& 0xf0) != 0xa0) {
130 if (cs
->debug
& L1_DEB_WARN
)
131 debugl1(cs
, "JADE %s invalid frame", (jade
? "B" : "A"));
132 if ((r
& 0x40) && bcs
->mode
)
133 if (cs
->debug
& L1_DEB_WARN
)
134 debugl1(cs
, "JADE %c RDO mode=%d", 'A' + jade
, bcs
->mode
);
136 if (cs
->debug
& L1_DEB_WARN
)
137 debugl1(cs
, "JADE %c CRC error", 'A' + jade
);
138 WriteJADECMDR(cs
, jade
, jade_HDLC_RCMD
, jadeRCMD_RMC
);
140 count
= READJADE(cs
, i_jade
, jade_HDLC_RBCL
) & 0x1F;
143 jade_empty_fifo(bcs
, count
);
144 if ((count
= bcs
->hw
.hscx
.rcvidx
- 1) > 0) {
145 if (cs
->debug
& L1_DEB_HSCX_FIFO
)
146 debugl1(cs
, "HX Frame %d", count
);
147 if (!(skb
= dev_alloc_skb(count
)))
148 printk(KERN_WARNING
"JADE %s receive out of memory\n", (jade
? "B" : "A"));
150 skb_put_data(skb
, bcs
->hw
.hscx
.rcvbuf
,
152 skb_queue_tail(&bcs
->rqueue
, skb
);
156 bcs
->hw
.hscx
.rcvidx
= 0;
157 schedule_event(bcs
, B_RCVBUFREADY
);
159 if (val
& 0x40) { /* RPF */
160 jade_empty_fifo(bcs
, fifo_size
);
161 if (bcs
->mode
== L1_MODE_TRANS
) {
162 /* receive audio data */
163 if (!(skb
= dev_alloc_skb(fifo_size
)))
164 printk(KERN_WARNING
"HiSax: receive out of memory\n");
166 skb_put_data(skb
, bcs
->hw
.hscx
.rcvbuf
,
168 skb_queue_tail(&bcs
->rqueue
, skb
);
170 bcs
->hw
.hscx
.rcvidx
= 0;
171 schedule_event(bcs
, B_RCVBUFREADY
);
174 if (val
& 0x10) { /* XPR */
176 if (bcs
->tx_skb
->len
) {
180 if (test_bit(FLG_LLI_L1WAKEUP
, &bcs
->st
->lli
.flag
) &&
181 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
183 spin_lock_irqsave(&bcs
->aclock
, flags
);
184 bcs
->ackcnt
+= bcs
->hw
.hscx
.count
;
185 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
186 schedule_event(bcs
, B_ACKPENDING
);
188 dev_kfree_skb_irq(bcs
->tx_skb
);
189 bcs
->hw
.hscx
.count
= 0;
193 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
194 bcs
->hw
.hscx
.count
= 0;
195 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
198 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
199 schedule_event(bcs
, B_XMTBUFREADY
);
205 jade_int_main(struct IsdnCardState
*cs
, u_char val
, int jade
)
208 bcs
= cs
->bcs
+ jade
;
210 if (val
& jadeISR_RFO
) {
211 /* handled with RDO */
214 if (val
& jadeISR_XDU
) {
215 /* relevant in HDLC mode only */
216 /* don't reset XPR here */
220 /* Here we lost an TX interrupt, so
221 * restart transmitting the whole frame.
224 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
225 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
226 bcs
->hw
.hscx
.count
= 0;
228 WriteJADECMDR(cs
, bcs
->hw
.hscx
.hscx
, jade_HDLC_XCMD
, jadeXCMD_XRES
);
229 if (cs
->debug
& L1_DEB_WARN
)
230 debugl1(cs
, "JADE %c EXIR %x Lost TX", 'A' + jade
, val
);
233 if (val
& (jadeISR_RME
| jadeISR_RPF
| jadeISR_XPR
)) {
234 if (cs
->debug
& L1_DEB_HSCX
)
235 debugl1(cs
, "JADE %c interrupt %x", 'A' + jade
, val
);
236 jade_interrupt(cs
, val
, jade
);