1 /* $Id: netjet.c,v 1.20 2000/06/26 08:59:14 keil Exp $
3 * netjet.c low level stuff for Traverse Technologie NETJet ISDN cards
5 * Author Karsten Keil (keil@isdn4linux.de)
7 * Thanks to Traverse Technologie Australia for documents and informations
9 * This file is (c) under GNU PUBLIC LICENSE
13 #define __NO_VERSION__
14 #include <linux/config.h>
19 #include <linux/pci.h>
20 #include <linux/interrupt.h>
21 #include <linux/ppp_defs.h>
24 #define bus_to_virt (u_int *)
28 #define virt_to_bus (u_int)
31 extern const char *CardType
[];
33 const char *NETjet_revision
= "$Revision: 1.18 $";
35 #define byteout(addr,val) outb(val,addr)
36 #define bytein(addr) inb(addr)
39 #define PCI_VENDOR_TRAVERSE_TECH 0xe159
40 #define PCI_NETJET_ID 0x0001
42 #define NETJET_CTRL 0x00
43 #define NETJET_DMACTRL 0x01
44 #define NETJET_AUXCTRL 0x02
45 #define NETJET_AUXDATA 0x03
46 #define NETJET_IRQMASK0 0x04
47 #define NETJET_IRQMASK1 0x05
48 #define NETJET_IRQSTAT0 0x06
49 #define NETJET_IRQSTAT1 0x07
50 #define NETJET_DMA_READ_START 0x08
51 #define NETJET_DMA_READ_IRQ 0x0c
52 #define NETJET_DMA_READ_END 0x10
53 #define NETJET_DMA_READ_ADR 0x14
54 #define NETJET_DMA_WRITE_START 0x18
55 #define NETJET_DMA_WRITE_IRQ 0x1c
56 #define NETJET_DMA_WRITE_END 0x20
57 #define NETJET_DMA_WRITE_ADR 0x24
58 #define NETJET_PULSE_CNT 0x28
60 #define NETJET_ISAC_OFF 0xc0
61 #define NETJET_ISACIRQ 0x10
62 #define NETJET_IRQM0_READ 0x0c
63 #define NETJET_IRQM0_READ_1 0x04
64 #define NETJET_IRQM0_READ_2 0x08
65 #define NETJET_IRQM0_WRITE 0x03
66 #define NETJET_IRQM0_WRITE_1 0x01
67 #define NETJET_IRQM0_WRITE_2 0x02
69 #define NETJET_DMA_TXSIZE 512
70 #define NETJET_DMA_RXSIZE 128
72 #define HDLC_ZERO_SEARCH 0
73 #define HDLC_FLAG_SEARCH 1
74 #define HDLC_FLAG_FOUND 2
75 #define HDLC_FRAME_FOUND 3
80 #define HDLC_FLAG_VALUE 0x7e
82 /* Interface functions */
85 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
92 cs
->hw
.njet
.auxd
&= 0xfc;
93 cs
->hw
.njet
.auxd
|= (offset
>>4) & 3;
94 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
95 ret
= bytein(cs
->hw
.njet
.isac
+ ((offset
& 0xf)<<2));
101 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
107 cs
->hw
.njet
.auxd
&= 0xfc;
108 cs
->hw
.njet
.auxd
|= (offset
>>4) & 3;
109 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
110 byteout(cs
->hw
.njet
.isac
+ ((offset
& 0xf)<<2), value
);
111 restore_flags(flags
);
115 ReadISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
117 cs
->hw
.njet
.auxd
&= 0xfc;
118 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
119 insb(cs
->hw
.njet
.isac
, data
, size
);
124 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
125 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
126 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
127 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
128 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
129 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
130 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
131 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
132 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
133 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
134 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
135 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
136 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
137 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
138 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
139 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
140 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
141 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
142 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
143 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
144 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
145 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
146 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
147 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
148 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
149 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
150 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
151 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
152 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
153 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
154 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
155 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
159 WriteISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
161 cs
->hw
.njet
.auxd
&= 0xfc;
162 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
163 outsb(cs
->hw
.njet
.isac
, data
, size
);
166 void fill_mem(struct BCState
*bcs
, u_int
*pos
, u_int cnt
, int chan
, u_char fill
)
168 u_int mask
=0x000000ff, val
= 0, *p
=pos
;
177 for (i
=0; i
<cnt
; i
++) {
180 if (p
> bcs
->hw
.tiger
.s_end
)
181 p
= bcs
->hw
.tiger
.send
;
186 mode_tiger(struct BCState
*bcs
, int mode
, int bc
)
188 struct IsdnCardState
*cs
= bcs
->cs
;
190 if (cs
->debug
& L1_DEB_HSCX
)
191 debugl1(cs
, "Tiger mode %d bchan %d/%d",
192 mode
, bc
, bcs
->channel
);
197 fill_mem(bcs
, bcs
->hw
.tiger
.send
,
198 NETJET_DMA_TXSIZE
, bc
, 0xff);
199 if (cs
->debug
& L1_DEB_HSCX
)
200 debugl1(cs
, "Tiger stat rec %d/%d send %d",
201 bcs
->hw
.tiger
.r_tot
, bcs
->hw
.tiger
.r_err
,
202 bcs
->hw
.tiger
.s_tot
);
203 if ((cs
->bcs
[0].mode
== L1_MODE_NULL
) &&
204 (cs
->bcs
[1].mode
== L1_MODE_NULL
)) {
205 cs
->hw
.njet
.dmactrl
= 0;
206 byteout(cs
->hw
.njet
.base
+ NETJET_DMACTRL
,
207 cs
->hw
.njet
.dmactrl
);
208 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK0
, 0);
211 case (L1_MODE_TRANS
):
214 fill_mem(bcs
, bcs
->hw
.tiger
.send
,
215 NETJET_DMA_TXSIZE
, bc
, 0xff);
216 bcs
->hw
.tiger
.r_state
= HDLC_ZERO_SEARCH
;
217 bcs
->hw
.tiger
.r_tot
= 0;
218 bcs
->hw
.tiger
.r_bitcnt
= 0;
219 bcs
->hw
.tiger
.r_one
= 0;
220 bcs
->hw
.tiger
.r_err
= 0;
221 bcs
->hw
.tiger
.s_tot
= 0;
222 if (! cs
->hw
.njet
.dmactrl
) {
223 fill_mem(bcs
, bcs
->hw
.tiger
.send
,
224 NETJET_DMA_TXSIZE
, !bc
, 0xff);
225 cs
->hw
.njet
.dmactrl
= 1;
226 byteout(cs
->hw
.njet
.base
+ NETJET_DMACTRL
,
227 cs
->hw
.njet
.dmactrl
);
228 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK0
, 0x3f);
230 bcs
->hw
.tiger
.sendp
= bcs
->hw
.tiger
.send
;
231 bcs
->hw
.tiger
.free
= NETJET_DMA_TXSIZE
;
232 test_and_set_bit(BC_FLG_EMPTY
, &bcs
->Flag
);
235 if (cs
->debug
& L1_DEB_HSCX
)
236 debugl1(cs
, "tiger: set %x %x %x %x/%x pulse=%d",
237 bytein(cs
->hw
.njet
.base
+ NETJET_DMACTRL
),
238 bytein(cs
->hw
.njet
.base
+ NETJET_IRQMASK0
),
239 bytein(cs
->hw
.njet
.base
+ NETJET_IRQSTAT0
),
240 inl(cs
->hw
.njet
.base
+ NETJET_DMA_READ_ADR
),
241 inl(cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_ADR
),
242 bytein(cs
->hw
.njet
.base
+ NETJET_PULSE_CNT
));
245 static u_char
dummyrr(struct IsdnCardState
*cs
, int chan
, u_char off
)
250 static void dummywr(struct IsdnCardState
*cs
, int chan
, u_char off
, u_char value
)
254 static void printframe(struct IsdnCardState
*cs
, u_char
*buf
, int count
, char *s
) {
260 t
+= sprintf(t
, "tiger %s(%4d)", s
, count
);
271 t
+= sprintf(t
, "tiger %s ", s
);
275 #define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
286 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
296 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
302 static int make_raw_data(struct BCState
*bcs
) {
303 register u_int i
,s_cnt
=0;
306 register u_char s_one
= 0;
307 register u_char s_val
= 0;
308 register u_char bitcnt
= 0;
312 debugl1(bcs
->cs
, "tiger make_raw: NULL skb");
315 bcs
->hw
.tiger
.sendbuf
[s_cnt
++] = HDLC_FLAG_VALUE
;
317 for (i
=0; i
<bcs
->tx_skb
->len
; i
++) {
318 val
= bcs
->tx_skb
->data
[i
];
319 fcs
= PPP_FCS (fcs
, val
);
325 val
= (fcs
>>8) & 0xff;
327 val
= HDLC_FLAG_VALUE
;
328 for (j
=0; j
<8; j
++) {
336 bcs
->hw
.tiger
.sendbuf
[s_cnt
++] = s_val
;
341 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
342 debugl1(bcs
->cs
,"tiger make_raw: in %ld out %d.%d",
343 bcs
->tx_skb
->len
, s_cnt
, bitcnt
);
349 bcs
->hw
.tiger
.sendbuf
[s_cnt
++] = s_val
;
350 bcs
->hw
.tiger
.sendbuf
[s_cnt
++] = 0xff; // NJ<->NJ thoughput bug fix
352 bcs
->hw
.tiger
.sendcnt
= s_cnt
;
353 bcs
->tx_cnt
-= bcs
->tx_skb
->len
;
354 bcs
->hw
.tiger
.sp
= bcs
->hw
.tiger
.sendbuf
;
358 static void got_frame(struct BCState
*bcs
, int count
) {
361 if (!(skb
= dev_alloc_skb(count
)))
362 printk(KERN_WARNING
"TIGER: receive out of memory\n");
364 memcpy(skb_put(skb
, count
), bcs
->hw
.tiger
.rcvbuf
, count
);
365 skb_queue_tail(&bcs
->rqueue
, skb
);
367 bcs
->event
|= 1 << B_RCVBUFREADY
;
368 queue_task(&bcs
->tqueue
, &tq_immediate
);
369 mark_bh(IMMEDIATE_BH
);
371 if (bcs
->cs
->debug
& L1_DEB_RECEIVE_FRAME
)
372 printframe(bcs
->cs
, bcs
->hw
.tiger
.rcvbuf
, count
, "rec");
377 static void read_raw(struct BCState
*bcs
, u_int
*buf
, int cnt
){
381 u_int
*pend
= bcs
->hw
.tiger
.rec
+NETJET_DMA_RXSIZE
-1;
382 register u_char state
= bcs
->hw
.tiger
.r_state
;
383 register u_char r_one
= bcs
->hw
.tiger
.r_one
;
384 register u_char r_val
= bcs
->hw
.tiger
.r_val
;
385 register u_int bitcnt
= bcs
->hw
.tiger
.r_bitcnt
;
388 for (i
=0;i
<cnt
;i
++) {
389 val
= bcs
->channel
? ((*p
>>8) & 0xff) : (*p
& 0xff);
392 p
= bcs
->hw
.tiger
.rec
;
394 state
= HDLC_ZERO_SEARCH
;
395 bcs
->hw
.tiger
.r_tot
++;
401 if (state
== HDLC_ZERO_SEARCH
) {
406 state
= HDLC_FLAG_SEARCH
;
407 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
408 debugl1(bcs
->cs
,"tiger read_raw: zBit(%d,%d,%d) %x",
409 bcs
->hw
.tiger
.r_tot
,i
,j
,val
);
411 } else if (state
== HDLC_FLAG_SEARCH
) {
415 state
=HDLC_ZERO_SEARCH
;
421 state
=HDLC_FLAG_FOUND
;
422 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
423 debugl1(bcs
->cs
,"tiger read_raw: flag(%d,%d,%d) %x",
424 bcs
->hw
.tiger
.r_tot
,i
,j
,val
);
428 } else if (state
== HDLC_FLAG_FOUND
) {
432 state
=HDLC_ZERO_SEARCH
;
445 } else if (r_one
!=5) {
452 if ((state
!= HDLC_ZERO_SEARCH
) &&
454 state
=HDLC_FRAME_FOUND
;
455 bcs
->hw
.tiger
.r_fcs
= PPP_INITFCS
;
456 bcs
->hw
.tiger
.rcvbuf
[0] = r_val
;
457 bcs
->hw
.tiger
.r_fcs
= PPP_FCS (bcs
->hw
.tiger
.r_fcs
, r_val
);
458 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
459 debugl1(bcs
->cs
,"tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x",
460 bcs
->hw
.tiger
.r_tot
,i
,j
,r_val
,val
,
461 bcs
->cs
->hw
.njet
.irqstat0
);
463 } else if (state
== HDLC_FRAME_FOUND
) {
467 state
=HDLC_ZERO_SEARCH
;
480 debugl1(bcs
->cs
, "tiger: frame not byte aligned");
481 state
=HDLC_FLAG_SEARCH
;
482 bcs
->hw
.tiger
.r_err
++;
483 #ifdef ERROR_STATISTIC
487 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
488 debugl1(bcs
->cs
,"tiger frame end(%d,%d): fcs(%x) i %x",
489 i
,j
,bcs
->hw
.tiger
.r_fcs
, bcs
->cs
->hw
.njet
.irqstat0
);
490 if (bcs
->hw
.tiger
.r_fcs
== PPP_GOODFCS
) {
491 got_frame(bcs
, (bitcnt
>>3)-3);
493 if (bcs
->cs
->debug
) {
494 debugl1(bcs
->cs
, "tiger FCS error");
495 printframe(bcs
->cs
, bcs
->hw
.tiger
.rcvbuf
,
496 (bitcnt
>>3)-1, "rec");
497 bcs
->hw
.tiger
.r_err
++;
499 #ifdef ERROR_STATISTIC
503 state
=HDLC_FLAG_FOUND
;
506 } else if (r_one
==5) {
517 if ((state
== HDLC_FRAME_FOUND
) &&
519 if ((bitcnt
>>3)>=HSCX_BUFMAX
) {
520 debugl1(bcs
->cs
, "tiger: frame too big");
522 state
=HDLC_FLAG_SEARCH
;
523 bcs
->hw
.tiger
.r_err
++;
524 #ifdef ERROR_STATISTIC
528 bcs
->hw
.tiger
.rcvbuf
[(bitcnt
>>3)-1] = r_val
;
529 bcs
->hw
.tiger
.r_fcs
=
530 PPP_FCS (bcs
->hw
.tiger
.r_fcs
, r_val
);
536 bcs
->hw
.tiger
.r_tot
++;
538 bcs
->hw
.tiger
.r_state
= state
;
539 bcs
->hw
.tiger
.r_one
= r_one
;
540 bcs
->hw
.tiger
.r_val
= r_val
;
541 bcs
->hw
.tiger
.r_bitcnt
= bitcnt
;
544 static void read_tiger(struct IsdnCardState
*cs
) {
546 int cnt
= NETJET_DMA_RXSIZE
/2;
548 if ((cs
->hw
.njet
.irqstat0
& cs
->hw
.njet
.last_is0
) & NETJET_IRQM0_READ
) {
549 debugl1(cs
,"tiger warn read double dma %x/%x",
550 cs
->hw
.njet
.irqstat0
, cs
->hw
.njet
.last_is0
);
551 #ifdef ERROR_STATISTIC
553 cs
->bcs
[0].err_rdo
++;
555 cs
->bcs
[1].err_rdo
++;
559 cs
->hw
.njet
.last_is0
&= ~NETJET_IRQM0_READ
;
560 cs
->hw
.njet
.last_is0
|= (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_READ
);
562 if (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_READ_1
)
563 p
= cs
->bcs
[0].hw
.tiger
.rec
+ NETJET_DMA_RXSIZE
- 1;
565 p
= cs
->bcs
[0].hw
.tiger
.rec
+ cnt
- 1;
566 if (cs
->bcs
[0].mode
== L1_MODE_HDLC
)
567 read_raw(cs
->bcs
, p
, cnt
);
568 if (cs
->bcs
[1].mode
== L1_MODE_HDLC
)
569 read_raw(cs
->bcs
+ 1, p
, cnt
);
570 cs
->hw
.njet
.irqstat0
&= ~NETJET_IRQM0_READ
;
573 static void write_raw(struct BCState
*bcs
, u_int
*buf
, int cnt
);
575 static void fill_dma(struct BCState
*bcs
)
577 register u_int
*p
, *sp
;
582 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
583 debugl1(bcs
->cs
,"tiger fill_dma1: c%d %4x", bcs
->channel
,
585 if (test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
))
587 if (make_raw_data(bcs
))
589 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
590 debugl1(bcs
->cs
,"tiger fill_dma2: c%d %4x", bcs
->channel
,
592 if (test_and_clear_bit(BC_FLG_NOFRAME
, &bcs
->Flag
)) {
593 write_raw(bcs
, bcs
->hw
.tiger
.sendp
, bcs
->hw
.tiger
.free
);
594 } else if (test_and_clear_bit(BC_FLG_HALF
, &bcs
->Flag
)) {
595 p
= bus_to_virt(inl(bcs
->cs
->hw
.njet
.base
+ NETJET_DMA_READ_ADR
));
596 sp
= bcs
->hw
.tiger
.sendp
;
597 if (p
== bcs
->hw
.tiger
.s_end
)
598 p
= bcs
->hw
.tiger
.send
-1;
599 if (sp
== bcs
->hw
.tiger
.s_end
)
600 sp
= bcs
->hw
.tiger
.send
-1;
603 write_raw(bcs
, bcs
->hw
.tiger
.sendp
, bcs
->hw
.tiger
.free
);
607 if (p
> bcs
->hw
.tiger
.s_end
)
608 p
= bcs
->hw
.tiger
.send
;
611 if (p
> bcs
->hw
.tiger
.s_end
)
612 p
= bcs
->hw
.tiger
.send
;
613 write_raw(bcs
, p
, bcs
->hw
.tiger
.free
- cnt
);
615 } else if (test_and_clear_bit(BC_FLG_EMPTY
, &bcs
->Flag
)) {
616 p
= bus_to_virt(inl(bcs
->cs
->hw
.njet
.base
+ NETJET_DMA_READ_ADR
));
617 cnt
= bcs
->hw
.tiger
.s_end
- p
;
619 p
= bcs
->hw
.tiger
.send
+ 1;
620 cnt
= NETJET_DMA_TXSIZE
/2 - 2;
624 if (cnt
<= (NETJET_DMA_TXSIZE
/2))
625 cnt
+= NETJET_DMA_TXSIZE
/2;
629 write_raw(bcs
, p
, cnt
);
631 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
632 debugl1(bcs
->cs
,"tiger fill_dma3: c%d %4x", bcs
->channel
,
636 static void write_raw(struct BCState
*bcs
, u_int
*buf
, int cnt
) {
637 u_int mask
, val
, *p
=buf
;
642 if (test_bit(BC_FLG_BUSY
, &bcs
->Flag
)) {
643 if (bcs
->hw
.tiger
.sendcnt
> cnt
) {
645 bcs
->hw
.tiger
.sendcnt
-= cnt
;
647 s_cnt
= bcs
->hw
.tiger
.sendcnt
;
648 bcs
->hw
.tiger
.sendcnt
= 0;
654 for (i
=0; i
<s_cnt
; i
++) {
655 val
= bcs
->channel
? ((bcs
->hw
.tiger
.sp
[i
] <<8) & 0xff00) :
656 (bcs
->hw
.tiger
.sp
[i
]);
659 if (p
>bcs
->hw
.tiger
.s_end
)
660 p
= bcs
->hw
.tiger
.send
;
662 bcs
->hw
.tiger
.s_tot
+= s_cnt
;
663 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
664 debugl1(bcs
->cs
,"tiger write_raw: c%d %x-%x %d/%d %d %x", bcs
->channel
,
665 (u_int
)buf
, (u_int
)p
, s_cnt
, cnt
,
666 bcs
->hw
.tiger
.sendcnt
, bcs
->cs
->hw
.njet
.irqstat0
);
667 if (bcs
->cs
->debug
& L1_DEB_HSCX_FIFO
)
668 printframe(bcs
->cs
, bcs
->hw
.tiger
.sp
, s_cnt
, "snd");
669 bcs
->hw
.tiger
.sp
+= s_cnt
;
670 bcs
->hw
.tiger
.sendp
= p
;
671 if (!bcs
->hw
.tiger
.sendcnt
) {
673 debugl1(bcs
->cs
,"tiger write_raw: NULL skb s_cnt %d", s_cnt
);
675 if (bcs
->st
->lli
.l1writewakeup
&&
676 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
))
677 bcs
->st
->lli
.l1writewakeup(bcs
->st
, bcs
->tx_skb
->len
);
678 dev_kfree_skb_any(bcs
->tx_skb
);
681 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
682 bcs
->hw
.tiger
.free
= cnt
- s_cnt
;
683 if (bcs
->hw
.tiger
.free
> (NETJET_DMA_TXSIZE
/2))
684 test_and_set_bit(BC_FLG_HALF
, &bcs
->Flag
);
686 test_and_clear_bit(BC_FLG_HALF
, &bcs
->Flag
);
687 test_and_set_bit(BC_FLG_NOFRAME
, &bcs
->Flag
);
689 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
694 for (i
=s_cnt
; i
<cnt
;i
++) {
696 if (p
>bcs
->hw
.tiger
.s_end
)
697 p
= bcs
->hw
.tiger
.send
;
699 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
700 debugl1(bcs
->cs
, "tiger write_raw: fill rest %d",
703 bcs
->event
|= 1 << B_XMTBUFREADY
;
704 queue_task(&bcs
->tqueue
, &tq_immediate
);
705 mark_bh(IMMEDIATE_BH
);
708 } else if (test_and_clear_bit(BC_FLG_NOFRAME
, &bcs
->Flag
)) {
709 test_and_set_bit(BC_FLG_HALF
, &bcs
->Flag
);
710 fill_mem(bcs
, buf
, cnt
, bcs
->channel
, 0xff);
711 bcs
->hw
.tiger
.free
+= cnt
;
712 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
713 debugl1(bcs
->cs
,"tiger write_raw: fill half");
714 } else if (test_and_clear_bit(BC_FLG_HALF
, &bcs
->Flag
)) {
715 test_and_set_bit(BC_FLG_EMPTY
, &bcs
->Flag
);
716 fill_mem(bcs
, buf
, cnt
, bcs
->channel
, 0xff);
717 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
718 debugl1(bcs
->cs
,"tiger write_raw: fill full");
722 static void write_tiger(struct IsdnCardState
*cs
) {
723 u_int
*p
, cnt
= NETJET_DMA_TXSIZE
/2;
725 if ((cs
->hw
.njet
.irqstat0
& cs
->hw
.njet
.last_is0
) & NETJET_IRQM0_WRITE
) {
726 debugl1(cs
,"tiger warn write double dma %x/%x",
727 cs
->hw
.njet
.irqstat0
, cs
->hw
.njet
.last_is0
);
728 #ifdef ERROR_STATISTIC
736 cs
->hw
.njet
.last_is0
&= ~NETJET_IRQM0_WRITE
;
737 cs
->hw
.njet
.last_is0
|= (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_WRITE
);
739 if (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_WRITE_1
)
740 p
= cs
->bcs
[0].hw
.tiger
.send
+ NETJET_DMA_TXSIZE
- 1;
742 p
= cs
->bcs
[0].hw
.tiger
.send
+ cnt
- 1;
743 if (cs
->bcs
[0].mode
== L1_MODE_HDLC
)
744 write_raw(cs
->bcs
, p
, cnt
);
745 if (cs
->bcs
[1].mode
== L1_MODE_HDLC
)
746 write_raw(cs
->bcs
+ 1, p
, cnt
);
747 cs
->hw
.njet
.irqstat0
&= ~NETJET_IRQM0_WRITE
;
751 tiger_l2l1(struct PStack
*st
, int pr
, void *arg
)
753 struct sk_buff
*skb
= arg
;
757 case (PH_DATA
| REQUEST
):
760 if (st
->l1
.bcs
->tx_skb
) {
761 skb_queue_tail(&st
->l1
.bcs
->squeue
, skb
);
762 restore_flags(flags
);
764 st
->l1
.bcs
->tx_skb
= skb
;
765 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
766 restore_flags(flags
);
769 case (PH_PULL
| INDICATION
):
770 if (st
->l1
.bcs
->tx_skb
) {
771 printk(KERN_WARNING
"tiger_l2l1: this shouldn't happen\n");
776 st
->l1
.bcs
->tx_skb
= skb
;
777 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
778 restore_flags(flags
);
780 case (PH_PULL
| REQUEST
):
781 if (!st
->l1
.bcs
->tx_skb
) {
782 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
783 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
785 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
787 case (PH_ACTIVATE
| REQUEST
):
788 test_and_set_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
789 mode_tiger(st
->l1
.bcs
, st
->l1
.mode
, st
->l1
.bc
);
790 l1_msg_b(st
, pr
, arg
);
792 case (PH_DEACTIVATE
| REQUEST
):
793 l1_msg_b(st
, pr
, arg
);
795 case (PH_DEACTIVATE
| CONFIRM
):
796 test_and_clear_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
797 test_and_clear_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
798 mode_tiger(st
->l1
.bcs
, 0, st
->l1
.bc
);
799 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
806 close_tigerstate(struct BCState
*bcs
)
808 mode_tiger(bcs
, 0, bcs
->channel
);
809 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
810 if (bcs
->hw
.tiger
.rcvbuf
) {
811 kfree(bcs
->hw
.tiger
.rcvbuf
);
812 bcs
->hw
.tiger
.rcvbuf
= NULL
;
814 if (bcs
->hw
.tiger
.sendbuf
) {
815 kfree(bcs
->hw
.tiger
.sendbuf
);
816 bcs
->hw
.tiger
.sendbuf
= NULL
;
818 discard_queue(&bcs
->rqueue
);
819 discard_queue(&bcs
->squeue
);
821 dev_kfree_skb_any(bcs
->tx_skb
);
823 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
829 open_tigerstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
831 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
832 if (!(bcs
->hw
.tiger
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
834 "HiSax: No memory for tiger.rcvbuf\n");
837 if (!(bcs
->hw
.tiger
.sendbuf
= kmalloc(RAW_BUFMAX
, GFP_ATOMIC
))) {
839 "HiSax: No memory for tiger.sendbuf\n");
842 skb_queue_head_init(&bcs
->rqueue
);
843 skb_queue_head_init(&bcs
->squeue
);
846 bcs
->hw
.tiger
.sendcnt
= 0;
847 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
854 setstack_tiger(struct PStack
*st
, struct BCState
*bcs
)
856 bcs
->channel
= st
->l1
.bc
;
857 if (open_tigerstate(st
->l1
.hardware
, bcs
))
860 st
->l2
.l2l1
= tiger_l2l1
;
861 setstack_manager(st
);
869 inittiger(struct IsdnCardState
*cs
))
871 if (!(cs
->bcs
[0].hw
.tiger
.send
= kmalloc(NETJET_DMA_TXSIZE
* sizeof(unsigned int),
872 GFP_KERNEL
| GFP_DMA
))) {
874 "HiSax: No memory for tiger.send\n");
877 cs
->bcs
[0].hw
.tiger
.s_irq
= cs
->bcs
[0].hw
.tiger
.send
+ NETJET_DMA_TXSIZE
/2 - 1;
878 cs
->bcs
[0].hw
.tiger
.s_end
= cs
->bcs
[0].hw
.tiger
.send
+ NETJET_DMA_TXSIZE
- 1;
879 cs
->bcs
[1].hw
.tiger
.send
= cs
->bcs
[0].hw
.tiger
.send
;
880 cs
->bcs
[1].hw
.tiger
.s_irq
= cs
->bcs
[0].hw
.tiger
.s_irq
;
881 cs
->bcs
[1].hw
.tiger
.s_end
= cs
->bcs
[0].hw
.tiger
.s_end
;
883 memset(cs
->bcs
[0].hw
.tiger
.send
, 0xff, NETJET_DMA_TXSIZE
* sizeof(unsigned int));
884 debugl1(cs
, "tiger: send buf %x - %x", (u_int
)cs
->bcs
[0].hw
.tiger
.send
,
885 (u_int
)(cs
->bcs
[0].hw
.tiger
.send
+ NETJET_DMA_TXSIZE
- 1));
886 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.send
),
887 cs
->hw
.njet
.base
+ NETJET_DMA_READ_START
);
888 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.s_irq
),
889 cs
->hw
.njet
.base
+ NETJET_DMA_READ_IRQ
);
890 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.s_end
),
891 cs
->hw
.njet
.base
+ NETJET_DMA_READ_END
);
892 if (!(cs
->bcs
[0].hw
.tiger
.rec
= kmalloc(NETJET_DMA_RXSIZE
* sizeof(unsigned int),
893 GFP_KERNEL
| GFP_DMA
))) {
895 "HiSax: No memory for tiger.rec\n");
898 debugl1(cs
, "tiger: rec buf %x - %x", (u_int
)cs
->bcs
[0].hw
.tiger
.rec
,
899 (u_int
)(cs
->bcs
[0].hw
.tiger
.rec
+ NETJET_DMA_RXSIZE
- 1));
900 cs
->bcs
[1].hw
.tiger
.rec
= cs
->bcs
[0].hw
.tiger
.rec
;
901 memset(cs
->bcs
[0].hw
.tiger
.rec
, 0xff, NETJET_DMA_RXSIZE
* sizeof(unsigned int));
902 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.rec
),
903 cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_START
);
904 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.rec
+ NETJET_DMA_RXSIZE
/2 - 1),
905 cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_IRQ
);
906 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.rec
+ NETJET_DMA_RXSIZE
- 1),
907 cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_END
);
908 debugl1(cs
, "tiger: dmacfg %x/%x pulse=%d",
909 inl(cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_ADR
),
910 inl(cs
->hw
.njet
.base
+ NETJET_DMA_READ_ADR
),
911 bytein(cs
->hw
.njet
.base
+ NETJET_PULSE_CNT
));
912 cs
->hw
.njet
.last_is0
= 0;
913 cs
->bcs
[0].BC_SetStack
= setstack_tiger
;
914 cs
->bcs
[1].BC_SetStack
= setstack_tiger
;
915 cs
->bcs
[0].BC_Close
= close_tigerstate
;
916 cs
->bcs
[1].BC_Close
= close_tigerstate
;
920 releasetiger(struct IsdnCardState
*cs
)
922 if (cs
->bcs
[0].hw
.tiger
.send
) {
923 kfree(cs
->bcs
[0].hw
.tiger
.send
);
924 cs
->bcs
[0].hw
.tiger
.send
= NULL
;
926 if (cs
->bcs
[1].hw
.tiger
.send
) {
927 cs
->bcs
[1].hw
.tiger
.send
= NULL
;
929 if (cs
->bcs
[0].hw
.tiger
.rec
) {
930 kfree(cs
->bcs
[0].hw
.tiger
.rec
);
931 cs
->bcs
[0].hw
.tiger
.rec
= NULL
;
933 if (cs
->bcs
[1].hw
.tiger
.rec
) {
934 cs
->bcs
[1].hw
.tiger
.rec
= NULL
;
939 netjet_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
941 struct IsdnCardState
*cs
= dev_id
;
946 printk(KERN_WARNING
"NETjet: Spurious interrupt!\n");
949 if (!((sval
= bytein(cs
->hw
.njet
.base
+ NETJET_IRQSTAT1
)) &
951 val
= ReadISAC(cs
, ISAC_ISTA
);
952 if (cs
->debug
& L1_DEB_ISAC
)
953 debugl1(cs
, "tiger: i1 %x %x", sval
, val
);
955 isac_interrupt(cs
, val
);
956 WriteISAC(cs
, ISAC_MASK
, 0xFF);
957 WriteISAC(cs
, ISAC_MASK
, 0x0);
962 if ((sval
= bytein(cs
->hw
.njet
.base
+ NETJET_IRQSTAT0
))) {
963 if (test_and_set_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
)) {
964 restore_flags(flags
);
967 cs
->hw
.njet
.irqstat0
= sval
;
968 restore_flags(flags
);
969 /* debugl1(cs, "tiger: ist0 %x %x %x %x/%x pulse=%d",
971 bytein(cs->hw.njet.base + NETJET_DMACTRL),
972 bytein(cs->hw.njet.base + NETJET_IRQMASK0),
973 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
974 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
975 bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
977 /* cs->hw.njet.irqmask0 = ((0x0f & cs->hw.njet.irqstat0) ^ 0x0f) | 0x30;
978 */ byteout(cs
->hw
.njet
.base
+ NETJET_IRQSTAT0
, cs
->hw
.njet
.irqstat0
);
979 /* byteout(cs->hw.njet.base + NETJET_IRQMASK0, cs->hw.njet.irqmask0);
980 */ if (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_READ
)
982 if (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_WRITE
)
984 test_and_clear_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
);
986 restore_flags(flags
);
989 cs->hw.njet.dmactrl = 0;
990 byteout(cs->hw.njet.base + NETJET_DMACTRL,
991 cs->hw.njet.dmactrl);
992 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
998 reset_netjet(struct IsdnCardState
*cs
)
1004 cs
->hw
.njet
.ctrl_reg
= 0xff; /* Reset On */
1005 byteout(cs
->hw
.njet
.base
+ NETJET_CTRL
, cs
->hw
.njet
.ctrl_reg
);
1006 set_current_state(TASK_UNINTERRUPTIBLE
);
1007 schedule_timeout((10*HZ
)/1000); /* Timeout 10ms */
1008 cs
->hw
.njet
.ctrl_reg
= 0x00; /* Reset Off and status read clear */
1009 byteout(cs
->hw
.njet
.base
+ NETJET_CTRL
, cs
->hw
.njet
.ctrl_reg
);
1010 set_current_state(TASK_UNINTERRUPTIBLE
);
1011 schedule_timeout((10*HZ
)/1000); /* Timeout 10ms */
1012 restore_flags(flags
);
1013 cs
->hw
.njet
.auxd
= 0;
1014 cs
->hw
.njet
.dmactrl
= 0;
1015 byteout(cs
->hw
.njet
.base
+ NETJET_AUXCTRL
, ~NETJET_ISACIRQ
);
1016 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK1
, NETJET_ISACIRQ
);
1017 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
1021 release_io_netjet(struct IsdnCardState
*cs
)
1023 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK0
, 0);
1024 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK1
, 0);
1026 release_region(cs
->hw
.njet
.base
, 256);
1031 NETjet_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
1038 release_io_netjet(cs
);
1042 clear_pending_isac_ints(cs
);
1044 /* Reenable all IRQ */
1045 cs
->writeisac(cs
, ISAC_MASK
, 0);
1053 static struct pci_dev
*dev_netjet __initdata
= NULL
;
1056 setup_netjet(struct IsdnCard
*card
))
1059 struct IsdnCardState
*cs
= card
->cs
;
1063 strcpy(tmp
, NETjet_revision
);
1064 printk(KERN_INFO
"HiSax: Traverse Tech. NETjet driver Rev. %s\n", HiSax_getrev(tmp
));
1065 if (cs
->typ
!= ISDN_CTYPE_NETJET
)
1067 test_and_clear_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
);
1069 if (!pci_present()) {
1070 printk(KERN_ERR
"Netjet: no PCI bus present\n");
1073 if ((dev_netjet
= pci_find_device(PCI_VENDOR_TRAVERSE_TECH
,
1074 PCI_NETJET_ID
, dev_netjet
))) {
1075 if (pci_enable_device(dev_netjet
))
1077 cs
->irq
= dev_netjet
->irq
;
1079 printk(KERN_WARNING
"NETjet: No IRQ for PCI card found\n");
1082 cs
->hw
.njet
.base
= pci_resource_start(dev_netjet
, 0);
1083 if (!cs
->hw
.njet
.base
) {
1084 printk(KERN_WARNING
"NETjet: No IO-Adr for PCI card found\n");
1088 printk(KERN_WARNING
"NETjet: No PCI card found\n");
1091 cs
->hw
.njet
.auxa
= cs
->hw
.njet
.base
+ NETJET_AUXDATA
;
1092 cs
->hw
.njet
.isac
= cs
->hw
.njet
.base
| NETJET_ISAC_OFF
;
1095 printk(KERN_WARNING
"NETjet: NO_PCI_BIOS\n");
1096 printk(KERN_WARNING
"NETjet: unable to config NETJET PCI\n");
1098 #endif /* CONFIG_PCI */
1100 "NETjet: PCI card configured at 0x%x IRQ %d\n",
1101 cs
->hw
.njet
.base
, cs
->irq
);
1102 if (check_region(cs
->hw
.njet
.base
, bytecnt
)) {
1104 "HiSax: %s config port %x-%x already in use\n",
1105 CardType
[card
->typ
],
1107 cs
->hw
.njet
.base
+ bytecnt
);
1110 request_region(cs
->hw
.njet
.base
, bytecnt
, "netjet isdn");
1113 cs
->readisac
= &ReadISAC
;
1114 cs
->writeisac
= &WriteISAC
;
1115 cs
->readisacfifo
= &ReadISACfifo
;
1116 cs
->writeisacfifo
= &WriteISACfifo
;
1117 cs
->BC_Read_Reg
= &dummyrr
;
1118 cs
->BC_Write_Reg
= &dummywr
;
1119 cs
->BC_Send_Data
= &fill_dma
;
1120 cs
->cardmsg
= &NETjet_card_msg
;
1121 cs
->irq_func
= &netjet_interrupt
;
1122 cs
->irq_flags
|= SA_SHIRQ
;
1123 ISACVersion(cs
, "NETjet:");