1 /* $Id: netjet.c,v 1.8 1998/11/15 23:55: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
11 * Revision 1.8 1998/11/15 23:55:14 keil
14 * Revision 1.7 1998/09/30 22:24:48 keil
15 * Fix missing line in setstack*
17 * Revision 1.6 1998/08/13 23:36:54 keil
18 * HiSax 3.1 - don't work stable with current LinkLevel
20 * Revision 1.5 1998/05/25 12:58:21 keil
21 * HiSax golden code from certification, Don't use !!!
22 * No leased lines, no X75, but many changes.
24 * Revision 1.4 1998/04/15 16:42:35 keil
26 * new PCI init (2.1.94)
28 * Revision 1.3 1998/02/12 23:08:05 keil
29 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
31 * Revision 1.2 1998/02/02 13:32:06 keil
38 #define __NO_VERSION__
39 #include <linux/config.h>
44 #include <linux/pci.h>
45 #include <linux/interrupt.h>
46 #include <linux/ppp_defs.h>
48 extern const char *CardType
[];
50 const char *NETjet_revision
= "$Revision: 1.8 $";
52 #define byteout(addr,val) outb(val,addr)
53 #define bytein(addr) inb(addr)
56 #define PCI_VENDOR_TRAVERSE_TECH 0xe159
57 #define PCI_NETJET_ID 0x0001
59 #define NETJET_CTRL 0x00
60 #define NETJET_DMACTRL 0x01
61 #define NETJET_AUXCTRL 0x02
62 #define NETJET_AUXDATA 0x03
63 #define NETJET_IRQMASK0 0x04
64 #define NETJET_IRQMASK1 0x05
65 #define NETJET_IRQSTAT0 0x06
66 #define NETJET_IRQSTAT1 0x07
67 #define NETJET_DMA_READ_START 0x08
68 #define NETJET_DMA_READ_IRQ 0x0c
69 #define NETJET_DMA_READ_END 0x10
70 #define NETJET_DMA_READ_ADR 0x14
71 #define NETJET_DMA_WRITE_START 0x18
72 #define NETJET_DMA_WRITE_IRQ 0x1c
73 #define NETJET_DMA_WRITE_END 0x20
74 #define NETJET_DMA_WRITE_ADR 0x24
75 #define NETJET_PULSE_CNT 0x28
77 #define NETJET_ISAC_OFF 0xc0
78 #define NETJET_ISACIRQ 0x10
79 #define NETJET_IRQM0_READ 0x0c
80 #define NETJET_IRQM0_READ_1 0x04
81 #define NETJET_IRQM0_READ_2 0x08
82 #define NETJET_IRQM0_WRITE 0x03
83 #define NETJET_IRQM0_WRITE_1 0x01
84 #define NETJET_IRQM0_WRITE_2 0x02
86 #define NETJET_DMA_SIZE 512
88 #define HDLC_ZERO_SEARCH 0
89 #define HDLC_FLAG_SEARCH 1
90 #define HDLC_FLAG_FOUND 2
91 #define HDLC_FRAME_FOUND 3
96 #define HDLC_FLAG_VALUE 0x7e
98 /* Interface functions */
101 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
108 cs
->hw
.njet
.auxd
&= 0xfc;
109 cs
->hw
.njet
.auxd
|= (offset
>>4) & 3;
110 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
111 ret
= bytein(cs
->hw
.njet
.isac
+ ((offset
& 0xf)<<2));
112 restore_flags(flags
);
117 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
123 cs
->hw
.njet
.auxd
&= 0xfc;
124 cs
->hw
.njet
.auxd
|= (offset
>>4) & 3;
125 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
126 byteout(cs
->hw
.njet
.isac
+ ((offset
& 0xf)<<2), value
);
127 restore_flags(flags
);
131 ReadISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
133 cs
->hw
.njet
.auxd
&= 0xfc;
134 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
135 insb(cs
->hw
.njet
.isac
, data
, size
);
140 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
141 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
142 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
143 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
144 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
145 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
146 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
147 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
148 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
149 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
150 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
151 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
152 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
153 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
154 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
155 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
156 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
157 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
158 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
159 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
160 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
161 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
162 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
163 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
164 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
165 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
166 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
167 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
168 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
169 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
170 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
171 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
175 WriteISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
177 cs
->hw
.njet
.auxd
&= 0xfc;
178 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
179 outsb(cs
->hw
.njet
.isac
, data
, size
);
182 void fill_mem(struct BCState
*bcs
, u_int
*pos
, u_int cnt
, int chan
, u_char fill
)
184 u_int mask
=0x000000ff, val
= 0, *p
=pos
;
193 for (i
=0; i
<cnt
; i
++) {
196 if (p
> bcs
->hw
.tiger
.s_end
)
197 p
= bcs
->hw
.tiger
.send
;
202 mode_tiger(struct BCState
*bcs
, int mode
, int bc
)
204 struct IsdnCardState
*cs
= bcs
->cs
;
206 if (cs
->debug
& L1_DEB_HSCX
)
207 debugl1(cs
, "Tiger mode %d bchan %d/%d",
208 mode
, bc
, bcs
->channel
);
213 fill_mem(bcs
, bcs
->hw
.tiger
.send
,
214 NETJET_DMA_SIZE
, bc
, 0xff);
215 if (cs
->debug
& L1_DEB_HSCX
)
216 debugl1(cs
, "Tiger stat rec %d/%d send %d",
217 bcs
->hw
.tiger
.r_tot
, bcs
->hw
.tiger
.r_err
,
218 bcs
->hw
.tiger
.s_tot
);
219 if ((cs
->bcs
[0].mode
== L1_MODE_NULL
) &&
220 (cs
->bcs
[1].mode
== L1_MODE_NULL
)) {
221 cs
->hw
.njet
.dmactrl
= 0;
222 byteout(cs
->hw
.njet
.base
+ NETJET_DMACTRL
,
223 cs
->hw
.njet
.dmactrl
);
224 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK0
, 0);
227 case (L1_MODE_TRANS
):
230 fill_mem(bcs
, bcs
->hw
.tiger
.send
,
231 NETJET_DMA_SIZE
, bc
, 0xff);
232 bcs
->hw
.tiger
.r_state
= HDLC_ZERO_SEARCH
;
233 bcs
->hw
.tiger
.r_tot
= 0;
234 bcs
->hw
.tiger
.r_bitcnt
= 0;
235 bcs
->hw
.tiger
.r_one
= 0;
236 bcs
->hw
.tiger
.r_err
= 0;
237 bcs
->hw
.tiger
.s_tot
= 0;
238 if (! cs
->hw
.njet
.dmactrl
) {
239 fill_mem(bcs
, bcs
->hw
.tiger
.send
,
240 NETJET_DMA_SIZE
, !bc
, 0xff);
241 cs
->hw
.njet
.dmactrl
= 1;
242 byteout(cs
->hw
.njet
.base
+ NETJET_DMACTRL
,
243 cs
->hw
.njet
.dmactrl
);
244 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK0
, 0x3f);
246 bcs
->hw
.tiger
.sendp
= bcs
->hw
.tiger
.send
;
247 bcs
->hw
.tiger
.free
= NETJET_DMA_SIZE
;
248 test_and_set_bit(BC_FLG_EMPTY
, &bcs
->Flag
);
251 if (cs
->debug
& L1_DEB_HSCX
)
252 debugl1(cs
, "tiger: set %x %x %x %x/%x pulse=%d",
253 bytein(cs
->hw
.njet
.base
+ NETJET_DMACTRL
),
254 bytein(cs
->hw
.njet
.base
+ NETJET_IRQMASK0
),
255 bytein(cs
->hw
.njet
.base
+ NETJET_IRQSTAT0
),
256 inl(cs
->hw
.njet
.base
+ NETJET_DMA_READ_ADR
),
257 inl(cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_ADR
),
258 bytein(cs
->hw
.njet
.base
+ NETJET_PULSE_CNT
));
261 static u_char
dummyrr(struct IsdnCardState
*cs
, int chan
, u_char off
)
266 static void dummywr(struct IsdnCardState
*cs
, int chan
, u_char off
, u_char value
)
270 static void printframe(struct IsdnCardState
*cs
, u_char
*buf
, int count
, char *s
) {
276 t
+= sprintf(t
, "tiger %s(%4d)", s
, count
);
287 t
+= sprintf(t
, "tiger %s ", s
);
291 #define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
302 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
312 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
318 static int make_raw_data(struct BCState
*bcs
) {
319 register u_int i
,s_cnt
=0;
322 register u_char s_one
= 0;
323 register u_char s_val
= 0;
324 register u_char bitcnt
= 0;
328 debugl1(bcs
->cs
, "tiger make_raw: NULL skb");
331 bcs
->hw
.tiger
.sendbuf
[s_cnt
++] = HDLC_FLAG_VALUE
;
333 for (i
=0; i
<bcs
->tx_skb
->len
; i
++) {
334 val
= bcs
->tx_skb
->data
[i
];
335 fcs
= PPP_FCS (fcs
, val
);
341 val
= (fcs
>>8) & 0xff;
343 val
= HDLC_FLAG_VALUE
;
344 for (j
=0; j
<8; j
++) {
352 bcs
->hw
.tiger
.sendbuf
[s_cnt
++] = s_val
;
357 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
358 debugl1(bcs
->cs
,"tiger make_raw: in %ld out %d.%d",
359 bcs
->tx_skb
->len
, s_cnt
, bitcnt
);
365 bcs
->hw
.tiger
.sendbuf
[s_cnt
++] = s_val
;
367 bcs
->hw
.tiger
.sendcnt
= s_cnt
;
368 bcs
->tx_cnt
-= bcs
->tx_skb
->len
;
369 bcs
->hw
.tiger
.sp
= bcs
->hw
.tiger
.sendbuf
;
373 static void got_frame(struct BCState
*bcs
, int count
) {
376 if (!(skb
= dev_alloc_skb(count
)))
377 printk(KERN_WARNING
"TIGER: receive out of memory\n");
379 memcpy(skb_put(skb
, count
), bcs
->hw
.tiger
.rcvbuf
, count
);
380 skb_queue_tail(&bcs
->rqueue
, skb
);
382 bcs
->event
|= 1 << B_RCVBUFREADY
;
383 queue_task(&bcs
->tqueue
, &tq_immediate
);
384 mark_bh(IMMEDIATE_BH
);
386 if (bcs
->cs
->debug
& L1_DEB_RECEIVE_FRAME
)
387 printframe(bcs
->cs
, bcs
->hw
.tiger
.rcvbuf
, count
, "rec");
392 static void read_raw(struct BCState
*bcs
, u_int
*buf
, int cnt
){
396 u_int
*pend
= bcs
->hw
.tiger
.rec
+NETJET_DMA_SIZE
-1;
397 register u_char state
= bcs
->hw
.tiger
.r_state
;
398 register u_char r_one
= bcs
->hw
.tiger
.r_one
;
399 register u_char r_val
= bcs
->hw
.tiger
.r_val
;
400 register u_int bitcnt
= bcs
->hw
.tiger
.r_bitcnt
;
403 for (i
=0;i
<cnt
;i
++) {
404 val
= bcs
->channel
? ((*p
>>8) & 0xff) : (*p
& 0xff);
407 p
= bcs
->hw
.tiger
.rec
;
409 state
= HDLC_ZERO_SEARCH
;
410 bcs
->hw
.tiger
.r_tot
++;
416 if (state
== HDLC_ZERO_SEARCH
) {
421 state
= HDLC_FLAG_SEARCH
;
422 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
423 debugl1(bcs
->cs
,"tiger read_raw: zBit(%d,%d,%d) %x",
424 bcs
->hw
.tiger
.r_tot
,i
,j
,val
);
426 } else if (state
== HDLC_FLAG_SEARCH
) {
430 state
=HDLC_ZERO_SEARCH
;
436 state
=HDLC_FLAG_FOUND
;
437 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
438 debugl1(bcs
->cs
,"tiger read_raw: flag(%d,%d,%d) %x",
439 bcs
->hw
.tiger
.r_tot
,i
,j
,val
);
443 } else if (state
== HDLC_FLAG_FOUND
) {
447 state
=HDLC_ZERO_SEARCH
;
460 } else if (r_one
!=5) {
467 if ((state
!= HDLC_ZERO_SEARCH
) &&
469 state
=HDLC_FRAME_FOUND
;
470 bcs
->hw
.tiger
.r_fcs
= PPP_INITFCS
;
471 bcs
->hw
.tiger
.rcvbuf
[0] = r_val
;
472 bcs
->hw
.tiger
.r_fcs
= PPP_FCS (bcs
->hw
.tiger
.r_fcs
, r_val
);
473 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
474 debugl1(bcs
->cs
,"tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x",
475 bcs
->hw
.tiger
.r_tot
,i
,j
,r_val
,val
,
476 bcs
->cs
->hw
.njet
.irqstat0
);
478 } else if (state
== HDLC_FRAME_FOUND
) {
482 state
=HDLC_ZERO_SEARCH
;
495 debugl1(bcs
->cs
, "tiger: frame not byte aligned");
496 state
=HDLC_FLAG_SEARCH
;
497 bcs
->hw
.tiger
.r_err
++;
499 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
500 debugl1(bcs
->cs
,"tiger frame end(%d,%d): fcs(%x) i %x",
501 i
,j
,bcs
->hw
.tiger
.r_fcs
, bcs
->cs
->hw
.njet
.irqstat0
);
502 if (bcs
->hw
.tiger
.r_fcs
== PPP_GOODFCS
) {
503 got_frame(bcs
, (bitcnt
>>3)-3);
505 if (bcs
->cs
->debug
) {
506 debugl1(bcs
->cs
, "tiger FCS error");
507 printframe(bcs
->cs
, bcs
->hw
.tiger
.rcvbuf
,
508 (bitcnt
>>3)-1, "rec");
509 bcs
->hw
.tiger
.r_err
++;
511 state
=HDLC_FLAG_FOUND
;
514 } else if (r_one
==5) {
525 if ((state
== HDLC_FRAME_FOUND
) &&
527 if ((bitcnt
>>3)>=HSCX_BUFMAX
) {
528 debugl1(bcs
->cs
, "tiger: frame to big");
530 state
=HDLC_FLAG_SEARCH
;
531 bcs
->hw
.tiger
.r_err
++;
533 bcs
->hw
.tiger
.rcvbuf
[(bitcnt
>>3)-1] = r_val
;
534 bcs
->hw
.tiger
.r_fcs
=
535 PPP_FCS (bcs
->hw
.tiger
.r_fcs
, r_val
);
541 bcs
->hw
.tiger
.r_tot
++;
543 bcs
->hw
.tiger
.r_state
= state
;
544 bcs
->hw
.tiger
.r_one
= r_one
;
545 bcs
->hw
.tiger
.r_val
= r_val
;
546 bcs
->hw
.tiger
.r_bitcnt
= bitcnt
;
549 static void read_tiger(struct IsdnCardState
*cs
) {
551 int cnt
= NETJET_DMA_SIZE
/2;
553 if ((cs
->hw
.njet
.irqstat0
& cs
->hw
.njet
.last_is0
) & NETJET_IRQM0_READ
) {
554 debugl1(cs
,"tiger warn read double dma %x/%x",
555 cs
->hw
.njet
.irqstat0
, cs
->hw
.njet
.last_is0
);
558 cs
->hw
.njet
.last_is0
&= ~NETJET_IRQM0_READ
;
559 cs
->hw
.njet
.last_is0
|= (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_READ
);
561 if (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_READ_1
)
562 p
= cs
->bcs
[0].hw
.tiger
.rec
+ NETJET_DMA_SIZE
- 1;
564 p
= cs
->bcs
[0].hw
.tiger
.rec
+ cnt
- 1;
565 if (cs
->bcs
[0].mode
== L1_MODE_HDLC
)
566 read_raw(cs
->bcs
, p
, cnt
);
567 if (cs
->bcs
[1].mode
== L1_MODE_HDLC
)
568 read_raw(cs
->bcs
+ 1, p
, cnt
);
569 cs
->hw
.njet
.irqstat0
&= ~NETJET_IRQM0_READ
;
572 static void write_raw(struct BCState
*bcs
, u_int
*buf
, int cnt
);
574 static void fill_dma(struct BCState
*bcs
)
576 register u_int
*p
, *sp
;
581 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
582 debugl1(bcs
->cs
,"tiger fill_dma1: c%d %4x", bcs
->channel
,
584 if (test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
))
586 if (make_raw_data(bcs
))
588 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
589 debugl1(bcs
->cs
,"tiger fill_dma2: c%d %4x", bcs
->channel
,
591 if (test_and_clear_bit(BC_FLG_NOFRAME
, &bcs
->Flag
)) {
592 write_raw(bcs
, bcs
->hw
.tiger
.sendp
, bcs
->hw
.tiger
.free
);
593 } else if (test_and_clear_bit(BC_FLG_HALF
, &bcs
->Flag
)) {
594 p
= bus_to_virt(inl(bcs
->cs
->hw
.njet
.base
+ NETJET_DMA_READ_ADR
));
595 sp
= bcs
->hw
.tiger
.sendp
;
596 if (p
== bcs
->hw
.tiger
.s_end
)
597 p
= bcs
->hw
.tiger
.send
-1;
598 if (sp
== bcs
->hw
.tiger
.s_end
)
599 sp
= bcs
->hw
.tiger
.send
-1;
602 write_raw(bcs
, bcs
->hw
.tiger
.sendp
, bcs
->hw
.tiger
.free
);
606 if (p
> bcs
->hw
.tiger
.s_end
)
607 p
= bcs
->hw
.tiger
.send
;
610 if (p
> bcs
->hw
.tiger
.s_end
)
611 p
= bcs
->hw
.tiger
.send
;
612 write_raw(bcs
, p
, bcs
->hw
.tiger
.free
- cnt
);
614 } else if (test_and_clear_bit(BC_FLG_EMPTY
, &bcs
->Flag
)) {
615 p
= bus_to_virt(inl(bcs
->cs
->hw
.njet
.base
+ NETJET_DMA_READ_ADR
));
616 cnt
= bcs
->hw
.tiger
.s_end
- p
;
618 p
= bcs
->hw
.tiger
.send
+ 1;
619 cnt
= NETJET_DMA_SIZE
/2 - 2;
623 if (cnt
<= (NETJET_DMA_SIZE
/2))
624 cnt
+= NETJET_DMA_SIZE
/2;
628 write_raw(bcs
, p
, cnt
);
630 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
631 debugl1(bcs
->cs
,"tiger fill_dma3: c%d %4x", bcs
->channel
,
635 static void write_raw(struct BCState
*bcs
, u_int
*buf
, int cnt
) {
636 u_int mask
, val
, *p
=buf
;
641 if (test_bit(BC_FLG_BUSY
, &bcs
->Flag
)) {
642 if (bcs
->hw
.tiger
.sendcnt
> cnt
) {
644 bcs
->hw
.tiger
.sendcnt
-= cnt
;
646 s_cnt
= bcs
->hw
.tiger
.sendcnt
;
647 bcs
->hw
.tiger
.sendcnt
= 0;
653 for (i
=0; i
<s_cnt
; i
++) {
654 val
= bcs
->channel
? ((bcs
->hw
.tiger
.sp
[i
] <<8) & 0xff00) :
655 (bcs
->hw
.tiger
.sp
[i
]);
658 if (p
>bcs
->hw
.tiger
.s_end
)
659 p
= bcs
->hw
.tiger
.send
;
661 bcs
->hw
.tiger
.s_tot
+= s_cnt
;
662 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
663 debugl1(bcs
->cs
,"tiger write_raw: c%d %x-%x %d/%d %d %x", bcs
->channel
,
664 (u_int
)buf
, (u_int
)p
, s_cnt
, cnt
,
665 bcs
->hw
.tiger
.sendcnt
, bcs
->cs
->hw
.njet
.irqstat0
);
666 if (bcs
->cs
->debug
& L1_DEB_HSCX_FIFO
)
667 printframe(bcs
->cs
, bcs
->hw
.tiger
.sp
, s_cnt
, "snd");
668 bcs
->hw
.tiger
.sp
+= s_cnt
;
669 bcs
->hw
.tiger
.sendp
= p
;
670 if (!bcs
->hw
.tiger
.sendcnt
) {
672 debugl1(bcs
->cs
,"tiger write_raw: NULL skb s_cnt %d", s_cnt
);
674 if (bcs
->st
->lli
.l1writewakeup
&&
675 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
))
676 bcs
->st
->lli
.l1writewakeup(bcs
->st
, bcs
->tx_skb
->len
);
677 dev_kfree_skb(bcs
->tx_skb
);
680 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
681 bcs
->hw
.tiger
.free
= cnt
- s_cnt
;
682 if (bcs
->hw
.tiger
.free
> (NETJET_DMA_SIZE
/2))
683 test_and_set_bit(BC_FLG_HALF
, &bcs
->Flag
);
685 test_and_clear_bit(BC_FLG_HALF
, &bcs
->Flag
);
686 test_and_set_bit(BC_FLG_NOFRAME
, &bcs
->Flag
);
688 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
693 for (i
=s_cnt
; i
<cnt
;i
++) {
695 if (p
>bcs
->hw
.tiger
.s_end
)
696 p
= bcs
->hw
.tiger
.send
;
698 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
699 debugl1(bcs
->cs
, "tiger write_raw: fill rest %d",
702 bcs
->event
|= 1 << B_XMTBUFREADY
;
703 queue_task(&bcs
->tqueue
, &tq_immediate
);
704 mark_bh(IMMEDIATE_BH
);
707 } else if (test_and_clear_bit(BC_FLG_NOFRAME
, &bcs
->Flag
)) {
708 test_and_set_bit(BC_FLG_HALF
, &bcs
->Flag
);
709 fill_mem(bcs
, buf
, cnt
, bcs
->channel
, 0xff);
710 bcs
->hw
.tiger
.free
+= cnt
;
711 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
712 debugl1(bcs
->cs
,"tiger write_raw: fill half");
713 } else if (test_and_clear_bit(BC_FLG_HALF
, &bcs
->Flag
)) {
714 test_and_set_bit(BC_FLG_EMPTY
, &bcs
->Flag
);
715 fill_mem(bcs
, buf
, cnt
, bcs
->channel
, 0xff);
716 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
717 debugl1(bcs
->cs
,"tiger write_raw: fill full");
721 static void write_tiger(struct IsdnCardState
*cs
) {
722 u_int
*p
, cnt
= NETJET_DMA_SIZE
/2;
724 if ((cs
->hw
.njet
.irqstat0
& cs
->hw
.njet
.last_is0
) & NETJET_IRQM0_WRITE
) {
725 debugl1(cs
,"tiger warn write double dma %x/%x",
726 cs
->hw
.njet
.irqstat0
, cs
->hw
.njet
.last_is0
);
729 cs
->hw
.njet
.last_is0
&= ~NETJET_IRQM0_WRITE
;
730 cs
->hw
.njet
.last_is0
|= (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_WRITE
);
732 if (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_WRITE_1
)
733 p
= cs
->bcs
[0].hw
.tiger
.send
+ NETJET_DMA_SIZE
- 1;
735 p
= cs
->bcs
[0].hw
.tiger
.send
+ cnt
- 1;
736 if (cs
->bcs
[0].mode
== L1_MODE_HDLC
)
737 write_raw(cs
->bcs
, p
, cnt
);
738 if (cs
->bcs
[1].mode
== L1_MODE_HDLC
)
739 write_raw(cs
->bcs
+ 1, p
, cnt
);
740 cs
->hw
.njet
.irqstat0
&= ~NETJET_IRQM0_WRITE
;
744 tiger_l2l1(struct PStack
*st
, int pr
, void *arg
)
746 struct sk_buff
*skb
= arg
;
750 case (PH_DATA
| REQUEST
):
753 if (st
->l1
.bcs
->tx_skb
) {
754 skb_queue_tail(&st
->l1
.bcs
->squeue
, skb
);
755 restore_flags(flags
);
757 st
->l1
.bcs
->tx_skb
= skb
;
758 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
759 restore_flags(flags
);
762 case (PH_PULL
| INDICATION
):
763 if (st
->l1
.bcs
->tx_skb
) {
764 printk(KERN_WARNING
"tiger_l2l1: this shouldn't happen\n");
769 st
->l1
.bcs
->tx_skb
= skb
;
770 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
771 restore_flags(flags
);
773 case (PH_PULL
| REQUEST
):
774 if (!st
->l1
.bcs
->tx_skb
) {
775 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
776 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
778 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
780 case (PH_ACTIVATE
| REQUEST
):
781 test_and_set_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
782 mode_tiger(st
->l1
.bcs
, st
->l1
.mode
, st
->l1
.bc
);
783 l1_msg_b(st
, pr
, arg
);
785 case (PH_DEACTIVATE
| REQUEST
):
786 l1_msg_b(st
, pr
, arg
);
788 case (PH_DEACTIVATE
| CONFIRM
):
789 test_and_clear_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
790 test_and_clear_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
791 mode_tiger(st
->l1
.bcs
, 0, st
->l1
.bc
);
792 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
799 close_tigerstate(struct BCState
*bcs
)
801 mode_tiger(bcs
, 0, bcs
->channel
);
802 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
803 if (bcs
->hw
.tiger
.rcvbuf
) {
804 kfree(bcs
->hw
.tiger
.rcvbuf
);
805 bcs
->hw
.tiger
.rcvbuf
= NULL
;
807 if (bcs
->hw
.tiger
.sendbuf
) {
808 kfree(bcs
->hw
.tiger
.sendbuf
);
809 bcs
->hw
.tiger
.sendbuf
= NULL
;
811 discard_queue(&bcs
->rqueue
);
812 discard_queue(&bcs
->squeue
);
814 dev_kfree_skb(bcs
->tx_skb
);
816 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
822 open_tigerstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
824 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
825 if (!(bcs
->hw
.tiger
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
827 "HiSax: No memory for tiger.rcvbuf\n");
830 if (!(bcs
->hw
.tiger
.sendbuf
= kmalloc(RAW_BUFMAX
, GFP_ATOMIC
))) {
832 "HiSax: No memory for tiger.sendbuf\n");
835 skb_queue_head_init(&bcs
->rqueue
);
836 skb_queue_head_init(&bcs
->squeue
);
839 bcs
->hw
.tiger
.sendcnt
= 0;
840 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
847 setstack_tiger(struct PStack
*st
, struct BCState
*bcs
)
849 bcs
->channel
= st
->l1
.bc
;
850 if (open_tigerstate(st
->l1
.hardware
, bcs
))
853 st
->l2
.l2l1
= tiger_l2l1
;
854 setstack_manager(st
);
862 inittiger(struct IsdnCardState
*cs
)
864 if (!(cs
->bcs
[0].hw
.tiger
.send
= kmalloc(NETJET_DMA_SIZE
* sizeof(unsigned int),
865 GFP_KERNEL
| GFP_DMA
))) {
867 "HiSax: No memory for tiger.send\n");
870 cs
->bcs
[0].hw
.tiger
.s_irq
= cs
->bcs
[0].hw
.tiger
.send
+ NETJET_DMA_SIZE
/2 - 1;
871 cs
->bcs
[0].hw
.tiger
.s_end
= cs
->bcs
[0].hw
.tiger
.send
+ NETJET_DMA_SIZE
- 1;
872 cs
->bcs
[1].hw
.tiger
.send
= cs
->bcs
[0].hw
.tiger
.send
;
873 cs
->bcs
[1].hw
.tiger
.s_irq
= cs
->bcs
[0].hw
.tiger
.s_irq
;
874 cs
->bcs
[1].hw
.tiger
.s_end
= cs
->bcs
[0].hw
.tiger
.s_end
;
876 memset(cs
->bcs
[0].hw
.tiger
.send
, 0xff, NETJET_DMA_SIZE
* sizeof(unsigned int));
877 debugl1(cs
, "tiger: send buf %x - %x", (u_int
)cs
->bcs
[0].hw
.tiger
.send
,
878 (u_int
)(cs
->bcs
[0].hw
.tiger
.send
+ NETJET_DMA_SIZE
- 1));
879 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.send
),
880 cs
->hw
.njet
.base
+ NETJET_DMA_READ_START
);
881 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.s_irq
),
882 cs
->hw
.njet
.base
+ NETJET_DMA_READ_IRQ
);
883 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.s_end
),
884 cs
->hw
.njet
.base
+ NETJET_DMA_READ_END
);
885 if (!(cs
->bcs
[0].hw
.tiger
.rec
= kmalloc(NETJET_DMA_SIZE
* sizeof(unsigned int),
886 GFP_KERNEL
| GFP_DMA
))) {
888 "HiSax: No memory for tiger.rec\n");
891 debugl1(cs
, "tiger: rec buf %x - %x", (u_int
)cs
->bcs
[0].hw
.tiger
.rec
,
892 (u_int
)(cs
->bcs
[0].hw
.tiger
.rec
+ NETJET_DMA_SIZE
- 1));
893 cs
->bcs
[1].hw
.tiger
.rec
= cs
->bcs
[0].hw
.tiger
.rec
;
894 memset(cs
->bcs
[0].hw
.tiger
.rec
, 0xff, NETJET_DMA_SIZE
* sizeof(unsigned int));
895 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.rec
),
896 cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_START
);
897 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.rec
+ NETJET_DMA_SIZE
/2 - 1),
898 cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_IRQ
);
899 outl(virt_to_bus(cs
->bcs
[0].hw
.tiger
.rec
+ NETJET_DMA_SIZE
- 1),
900 cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_END
);
901 debugl1(cs
, "tiger: dmacfg %x/%x pulse=%d",
902 inl(cs
->hw
.njet
.base
+ NETJET_DMA_WRITE_ADR
),
903 inl(cs
->hw
.njet
.base
+ NETJET_DMA_READ_ADR
),
904 bytein(cs
->hw
.njet
.base
+ NETJET_PULSE_CNT
));
905 cs
->hw
.njet
.last_is0
= 0;
906 cs
->bcs
[0].BC_SetStack
= setstack_tiger
;
907 cs
->bcs
[1].BC_SetStack
= setstack_tiger
;
908 cs
->bcs
[0].BC_Close
= close_tigerstate
;
909 cs
->bcs
[1].BC_Close
= close_tigerstate
;
913 releasetiger(struct IsdnCardState
*cs
)
915 if (cs
->bcs
[0].hw
.tiger
.send
) {
916 kfree(cs
->bcs
[0].hw
.tiger
.send
);
917 cs
->bcs
[0].hw
.tiger
.send
= NULL
;
919 if (cs
->bcs
[1].hw
.tiger
.send
) {
920 cs
->bcs
[1].hw
.tiger
.send
= NULL
;
922 if (cs
->bcs
[0].hw
.tiger
.rec
) {
923 kfree(cs
->bcs
[0].hw
.tiger
.rec
);
924 cs
->bcs
[0].hw
.tiger
.rec
= NULL
;
926 if (cs
->bcs
[1].hw
.tiger
.rec
) {
927 cs
->bcs
[1].hw
.tiger
.rec
= NULL
;
932 netjet_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
934 struct IsdnCardState
*cs
= dev_id
;
939 printk(KERN_WARNING
"NETjet: Spurious interrupt!\n");
942 if (!((sval
= bytein(cs
->hw
.njet
.base
+ NETJET_IRQSTAT1
)) &
944 val
= ReadISAC(cs
, ISAC_ISTA
);
945 if (cs
->debug
& L1_DEB_ISAC
)
946 debugl1(cs
, "tiger: i1 %x %x", sval
, val
);
948 isac_interrupt(cs
, val
);
949 WriteISAC(cs
, ISAC_MASK
, 0xFF);
950 WriteISAC(cs
, ISAC_MASK
, 0x0);
955 if ((sval
= bytein(cs
->hw
.njet
.base
+ NETJET_IRQSTAT0
))) {
956 if (test_and_set_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
)) {
957 restore_flags(flags
);
960 cs
->hw
.njet
.irqstat0
= sval
;
961 restore_flags(flags
);
962 /* debugl1(cs, "tiger: ist0 %x %x %x %x/%x pulse=%d",
964 bytein(cs->hw.njet.base + NETJET_DMACTRL),
965 bytein(cs->hw.njet.base + NETJET_IRQMASK0),
966 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
967 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
968 bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
970 /* cs->hw.njet.irqmask0 = ((0x0f & cs->hw.njet.irqstat0) ^ 0x0f) | 0x30;
971 */ byteout(cs
->hw
.njet
.base
+ NETJET_IRQSTAT0
, cs
->hw
.njet
.irqstat0
);
972 /* byteout(cs->hw.njet.base + NETJET_IRQMASK0, cs->hw.njet.irqmask0);
973 */ if (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_READ
)
975 if (cs
->hw
.njet
.irqstat0
& NETJET_IRQM0_WRITE
)
977 test_and_clear_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
);
979 restore_flags(flags
);
982 cs->hw.njet.dmactrl = 0;
983 byteout(cs->hw.njet.base + NETJET_DMACTRL,
984 cs->hw.njet.dmactrl);
985 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
991 reset_netjet(struct IsdnCardState
*cs
)
997 cs
->hw
.njet
.ctrl_reg
= 0xff; /* Reset On */
998 byteout(cs
->hw
.njet
.base
+ NETJET_CTRL
, cs
->hw
.njet
.ctrl_reg
);
999 current
->state
= TASK_INTERRUPTIBLE
;
1000 schedule_timeout((10*HZ
)/1000); /* Timeout 10ms */
1001 cs
->hw
.njet
.ctrl_reg
= 0x00; /* Reset Off and status read clear */
1002 byteout(cs
->hw
.njet
.base
+ NETJET_CTRL
, cs
->hw
.njet
.ctrl_reg
);
1003 current
->state
= TASK_INTERRUPTIBLE
;
1004 schedule_timeout((10*HZ
)/1000); /* Timeout 10ms */
1005 restore_flags(flags
);
1006 cs
->hw
.njet
.auxd
= 0;
1007 cs
->hw
.njet
.dmactrl
= 0;
1008 byteout(cs
->hw
.njet
.base
+ NETJET_AUXCTRL
, ~NETJET_ISACIRQ
);
1009 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK1
, NETJET_ISACIRQ
);
1010 byteout(cs
->hw
.njet
.auxa
, cs
->hw
.njet
.auxd
);
1014 release_io_netjet(struct IsdnCardState
*cs
)
1016 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK0
, 0);
1017 byteout(cs
->hw
.njet
.base
+ NETJET_IRQMASK1
, 0);
1019 release_region(cs
->hw
.njet
.base
, 256);
1024 NETjet_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
1031 release_io_netjet(cs
);
1034 return(request_irq(cs
->irq
, &netjet_interrupt
,
1035 I4L_IRQ_FLAG
| SA_SHIRQ
, "HiSax", cs
));
1038 clear_pending_isac_ints(cs
);
1040 /* Reenable all IRQ */
1041 cs
->writeisac(cs
, ISAC_MASK
, 0);
1051 static struct pci_dev
*dev_netjet __initdata
= NULL
;
1054 setup_netjet(struct IsdnCard
*card
)
1057 struct IsdnCardState
*cs
= card
->cs
;
1060 strcpy(tmp
, NETjet_revision
);
1061 printk(KERN_INFO
"HiSax: Traverse Tech. NETjet driver Rev. %s\n", HiSax_getrev(tmp
));
1062 if (cs
->typ
!= ISDN_CTYPE_NETJET
)
1064 test_and_clear_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
);
1066 if (!pci_present()) {
1067 printk(KERN_ERR
"Netjet: no PCI bus present\n");
1070 if ((dev_netjet
= pci_find_device(PCI_VENDOR_TRAVERSE_TECH
,
1071 PCI_NETJET_ID
, dev_netjet
))) {
1072 cs
->irq
= dev_netjet
->irq
;
1074 printk(KERN_WARNING
"NETjet: No IRQ for PCI card found\n");
1077 cs
->hw
.njet
.base
= dev_netjet
->base_address
[0] &
1078 PCI_BASE_ADDRESS_IO_MASK
;
1079 if (!cs
->hw
.njet
.base
) {
1080 printk(KERN_WARNING
"NETjet: No IO-Adr for PCI card found\n");
1083 cs
->hw
.njet
.auxa
= cs
->hw
.njet
.base
+ NETJET_AUXDATA
;
1084 cs
->hw
.njet
.isac
= cs
->hw
.njet
.base
| NETJET_ISAC_OFF
;
1087 printk(KERN_WARNING
"NETjet: No PCI card found\n");
1091 printk(KERN_WARNING
"NETjet: NO_PCI_BIOS\n");
1092 printk(KERN_WARNING
"NETjet: unable to config NETJET PCI\n");
1094 #endif /* CONFIG_PCI */
1096 "NETjet: PCI card configured at 0x%x IRQ %d\n",
1097 cs
->hw
.njet
.base
, cs
->irq
);
1098 if (check_region(cs
->hw
.njet
.base
, bytecnt
)) {
1100 "HiSax: %s config port %x-%x already in use\n",
1101 CardType
[card
->typ
],
1103 cs
->hw
.njet
.base
+ bytecnt
);
1106 request_region(cs
->hw
.njet
.base
, bytecnt
, "netjet isdn");
1109 cs
->readisac
= &ReadISAC
;
1110 cs
->writeisac
= &WriteISAC
;
1111 cs
->readisacfifo
= &ReadISACfifo
;
1112 cs
->writeisacfifo
= &WriteISACfifo
;
1113 cs
->BC_Read_Reg
= &dummyrr
;
1114 cs
->BC_Write_Reg
= &dummywr
;
1115 cs
->BC_Send_Data
= &fill_dma
;
1116 cs
->cardmsg
= &NETjet_card_msg
;
1117 ISACVersion(cs
, "NETjet:");