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 memcpy(skb_put(skb
, count
), bcs
->hw
.hscx
.rcvbuf
, count
);
151 skb_queue_tail(&bcs
->rqueue
, skb
);
155 bcs
->hw
.hscx
.rcvidx
= 0;
156 schedule_event(bcs
, B_RCVBUFREADY
);
158 if (val
& 0x40) { /* RPF */
159 jade_empty_fifo(bcs
, fifo_size
);
160 if (bcs
->mode
== L1_MODE_TRANS
) {
161 /* receive audio data */
162 if (!(skb
= dev_alloc_skb(fifo_size
)))
163 printk(KERN_WARNING
"HiSax: receive out of memory\n");
165 memcpy(skb_put(skb
, fifo_size
), bcs
->hw
.hscx
.rcvbuf
, fifo_size
);
166 skb_queue_tail(&bcs
->rqueue
, skb
);
168 bcs
->hw
.hscx
.rcvidx
= 0;
169 schedule_event(bcs
, B_RCVBUFREADY
);
172 if (val
& 0x10) { /* XPR */
174 if (bcs
->tx_skb
->len
) {
178 if (test_bit(FLG_LLI_L1WAKEUP
, &bcs
->st
->lli
.flag
) &&
179 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
181 spin_lock_irqsave(&bcs
->aclock
, flags
);
182 bcs
->ackcnt
+= bcs
->hw
.hscx
.count
;
183 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
184 schedule_event(bcs
, B_ACKPENDING
);
186 dev_kfree_skb_irq(bcs
->tx_skb
);
187 bcs
->hw
.hscx
.count
= 0;
191 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
192 bcs
->hw
.hscx
.count
= 0;
193 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
196 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
197 schedule_event(bcs
, B_XMTBUFREADY
);
203 jade_int_main(struct IsdnCardState
*cs
, u_char val
, int jade
)
206 bcs
= cs
->bcs
+ jade
;
208 if (val
& jadeISR_RFO
) {
209 /* handled with RDO */
212 if (val
& jadeISR_XDU
) {
213 /* relevant in HDLC mode only */
214 /* don't reset XPR here */
218 /* Here we lost an TX interrupt, so
219 * restart transmitting the whole frame.
222 skb_push(bcs
->tx_skb
, bcs
->hw
.hscx
.count
);
223 bcs
->tx_cnt
+= bcs
->hw
.hscx
.count
;
224 bcs
->hw
.hscx
.count
= 0;
226 WriteJADECMDR(cs
, bcs
->hw
.hscx
.hscx
, jade_HDLC_XCMD
, jadeXCMD_XRES
);
227 if (cs
->debug
& L1_DEB_WARN
)
228 debugl1(cs
, "JADE %c EXIR %x Lost TX", 'A' + jade
, val
);
231 if (val
& (jadeISR_RME
| jadeISR_RPF
| jadeISR_XPR
)) {
232 if (cs
->debug
& L1_DEB_HSCX
)
233 debugl1(cs
, "JADE %c interrupt %x", 'A' + jade
, val
);
234 jade_interrupt(cs
, val
, jade
);