1 /* $Id: netjet.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
3 * low level stuff for Traverse Technologie NETJet ISDN cards
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
11 * Thanks to Traverse Technologies Australia for documents and information
13 * 16-Apr-2002 - led code added - Guy Ellis (guy@traverse.com.au)
17 #define __NO_VERSION__
18 #include <linux/init.h>
23 #include <linux/pci.h>
24 #include <linux/interrupt.h>
25 #include <linux/ppp_defs.h>
29 const char *NETjet_revision = "$Revision: 1.1.4.1 $";
31 /* Interface functions */
34 NETjet_ReadIC(struct IsdnCardState *cs, u_char offset)
41 cs->hw.njet.auxd &= 0xfc;
42 cs->hw.njet.auxd |= (offset>>4) & 3;
43 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
44 ret = bytein(cs->hw.njet.isac + ((offset & 0xf)<<2));
50 NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value)
56 cs->hw.njet.auxd &= 0xfc;
57 cs->hw.njet.auxd |= (offset>>4) & 3;
58 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
59 byteout(cs->hw.njet.isac + ((offset & 0xf)<<2), value);
64 NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size)
66 cs->hw.njet.auxd &= 0xfc;
67 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
68 insb(cs->hw.njet.isac, data, size);
73 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
74 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
75 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
76 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
77 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
78 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
79 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
80 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
81 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
82 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
83 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
84 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
85 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
86 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
87 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
88 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
89 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
90 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
91 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
92 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
93 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
94 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
95 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
96 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
97 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
98 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
99 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
100 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
101 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
102 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
103 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
104 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
108 NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size)
110 cs->hw.njet.auxd &= 0xfc;
111 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
112 outsb(cs->hw.njet.isac, data, size);
115 void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
117 u_int mask=0x000000ff, val = 0, *p=pos;
126 for (i=0; i<cnt; i++) {
129 if (p > bcs->hw.tiger.s_end)
130 p = bcs->hw.tiger.send;
135 mode_tiger(struct BCState *bcs, int mode, int bc)
137 struct IsdnCardState *cs = bcs->cs;
140 if (cs->debug & L1_DEB_HSCX)
141 debugl1(cs, "Tiger mode %d bchan %d/%d",
142 mode, bc, bcs->channel);
147 fill_mem(bcs, bcs->hw.tiger.send,
148 NETJET_DMA_TXSIZE, bc, 0xff);
149 if (cs->debug & L1_DEB_HSCX)
150 debugl1(cs, "Tiger stat rec %d/%d send %d",
151 bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err,
152 bcs->hw.tiger.s_tot);
153 if ((cs->bcs[0].mode == L1_MODE_NULL) &&
154 (cs->bcs[1].mode == L1_MODE_NULL)) {
155 cs->hw.njet.dmactrl = 0;
156 byteout(cs->hw.njet.base + NETJET_DMACTRL,
157 cs->hw.njet.dmactrl);
158 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
160 if (cs->typ == ISDN_CTYPE_NETJET_S)
164 led = 0x01 << (6 + led); // convert to mask
166 cs->hw.njet.auxd &= led;
167 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
170 case (L1_MODE_TRANS):
172 case (L1_MODE_HDLC_56K):
174 fill_mem(bcs, bcs->hw.tiger.send,
175 NETJET_DMA_TXSIZE, bc, 0xff);
176 bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH;
177 bcs->hw.tiger.r_tot = 0;
178 bcs->hw.tiger.r_bitcnt = 0;
179 bcs->hw.tiger.r_one = 0;
180 bcs->hw.tiger.r_err = 0;
181 bcs->hw.tiger.s_tot = 0;
182 if (! cs->hw.njet.dmactrl) {
183 fill_mem(bcs, bcs->hw.tiger.send,
184 NETJET_DMA_TXSIZE, !bc, 0xff);
185 cs->hw.njet.dmactrl = 1;
186 byteout(cs->hw.njet.base + NETJET_DMACTRL,
187 cs->hw.njet.dmactrl);
188 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x0f);
189 /* was 0x3f now 0x0f for TJ300 and TJ320 GE 13/07/00 */
191 bcs->hw.tiger.sendp = bcs->hw.tiger.send;
192 bcs->hw.tiger.free = NETJET_DMA_TXSIZE;
193 test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
194 if (cs->typ == ISDN_CTYPE_NETJET_S)
198 led = 0x01 << (6 + led); // convert to mask
199 cs->hw.njet.auxd |= led;
200 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
204 if (cs->debug & L1_DEB_HSCX)
205 debugl1(cs, "tiger: set %x %x %x %x/%x pulse=%d",
206 bytein(cs->hw.njet.base + NETJET_DMACTRL),
207 bytein(cs->hw.njet.base + NETJET_IRQMASK0),
208 bytein(cs->hw.njet.base + NETJET_IRQSTAT0),
209 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
210 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
211 bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
214 static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s) {
220 t += sprintf(t, "tiger %s(%4d)", s, count);
231 t += sprintf(t, "tiger %s ", s);
237 #define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
248 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
258 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
264 static int make_raw_data(struct BCState *bcs) {
265 // this make_raw is for 64k
266 register u_int i,s_cnt=0;
269 register u_char s_one = 0;
270 register u_char s_val = 0;
271 register u_char bitcnt = 0;
275 debugl1(bcs->cs, "tiger make_raw: NULL skb");
278 bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE;
280 for (i=0; i<bcs->tx_skb->len; i++) {
281 val = bcs->tx_skb->data[i];
282 fcs = PPP_FCS (fcs, val);
288 val = (fcs>>8) & 0xff;
290 val = HDLC_FLAG_VALUE;
291 for (j=0; j<8; j++) {
299 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
304 if (bcs->cs->debug & L1_DEB_HSCX)
305 debugl1(bcs->cs,"tiger make_raw: in %ld out %d.%d",
306 bcs->tx_skb->len, s_cnt, bitcnt);
312 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
313 bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix
315 bcs->hw.tiger.sendcnt = s_cnt;
316 bcs->tx_cnt -= bcs->tx_skb->len;
317 bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
323 #define MAKE_RAW_BYTE_56K for (j=0; j<8; j++) { \
336 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
348 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
354 static int make_raw_data_56k(struct BCState *bcs) {
355 // this make_raw is for 56k
356 register u_int i,s_cnt=0;
359 register u_char s_one = 0;
360 register u_char s_val = 0;
361 register u_char bitcnt = 0;
365 debugl1(bcs->cs, "tiger make_raw_56k: NULL skb");
368 val = HDLC_FLAG_VALUE;
369 for (j=0; j<8; j++) {
379 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
385 for (i=0; i<bcs->tx_skb->len; i++) {
386 val = bcs->tx_skb->data[i];
387 fcs = PPP_FCS (fcs, val);
393 val = (fcs>>8) & 0xff;
395 val = HDLC_FLAG_VALUE;
396 for (j=0; j<8; j++) {
406 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
411 if (bcs->cs->debug & L1_DEB_HSCX)
412 debugl1(bcs->cs,"tiger make_raw_56k: in %ld out %d.%d",
413 bcs->tx_skb->len, s_cnt, bitcnt);
419 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
420 bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix
422 bcs->hw.tiger.sendcnt = s_cnt;
423 bcs->tx_cnt -= bcs->tx_skb->len;
424 bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
428 static void got_frame(struct BCState *bcs, int count) {
431 if (!(skb = dev_alloc_skb(count)))
432 printk(KERN_WARNING "TIGER: receive out of memory\n");
434 memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count);
435 skb_queue_tail(&bcs->rqueue, skb);
437 bcs->event |= 1 << B_RCVBUFREADY;
438 queue_task(&bcs->tqueue, &tq_immediate);
439 mark_bh(IMMEDIATE_BH);
441 if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME)
442 printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec");
447 static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
451 u_int *pend = bcs->hw.tiger.rec +NETJET_DMA_RXSIZE -1;
452 register u_char state = bcs->hw.tiger.r_state;
453 register u_char r_one = bcs->hw.tiger.r_one;
454 register u_char r_val = bcs->hw.tiger.r_val;
455 register u_int bitcnt = bcs->hw.tiger.r_bitcnt;
460 if (bcs->mode == L1_MODE_HDLC) { // it's 64k
468 for (i=0;i<cnt;i++) {
469 val = bcs->channel ? ((*p>>8) & 0xff) : (*p & 0xff);
472 p = bcs->hw.tiger.rec;
473 if ((val & mask) == mask) {
474 state = HDLC_ZERO_SEARCH;
475 bcs->hw.tiger.r_tot++;
480 for (j=0;j<bits;j++) {
481 if (state == HDLC_ZERO_SEARCH) {
486 state= HDLC_FLAG_SEARCH;
487 if (bcs->cs->debug & L1_DEB_HSCX)
488 debugl1(bcs->cs,"tiger read_raw: zBit(%d,%d,%d) %x",
489 bcs->hw.tiger.r_tot,i,j,val);
491 } else if (state == HDLC_FLAG_SEARCH) {
495 state=HDLC_ZERO_SEARCH;
501 state=HDLC_FLAG_FOUND;
502 if (bcs->cs->debug & L1_DEB_HSCX)
503 debugl1(bcs->cs,"tiger read_raw: flag(%d,%d,%d) %x",
504 bcs->hw.tiger.r_tot,i,j,val);
508 } else if (state == HDLC_FLAG_FOUND) {
512 state=HDLC_ZERO_SEARCH;
525 } else if (r_one!=5) {
532 if ((state != HDLC_ZERO_SEARCH) &&
534 state=HDLC_FRAME_FOUND;
535 bcs->hw.tiger.r_fcs = PPP_INITFCS;
536 bcs->hw.tiger.rcvbuf[0] = r_val;
537 bcs->hw.tiger.r_fcs = PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
538 if (bcs->cs->debug & L1_DEB_HSCX)
539 debugl1(bcs->cs,"tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x",
540 bcs->hw.tiger.r_tot,i,j,r_val,val,
541 bcs->cs->hw.njet.irqstat0);
543 } else if (state == HDLC_FRAME_FOUND) {
547 state=HDLC_ZERO_SEARCH;
560 debugl1(bcs->cs, "tiger: frame not byte aligned");
561 state=HDLC_FLAG_SEARCH;
562 bcs->hw.tiger.r_err++;
563 #ifdef ERROR_STATISTIC
567 if (bcs->cs->debug & L1_DEB_HSCX)
568 debugl1(bcs->cs,"tiger frame end(%d,%d): fcs(%x) i %x",
569 i,j,bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0);
570 if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) {
571 got_frame(bcs, (bitcnt>>3)-3);
573 if (bcs->cs->debug) {
574 debugl1(bcs->cs, "tiger FCS error");
575 printframe(bcs->cs, bcs->hw.tiger.rcvbuf,
576 (bitcnt>>3)-1, "rec");
577 bcs->hw.tiger.r_err++;
579 #ifdef ERROR_STATISTIC
583 state=HDLC_FLAG_FOUND;
586 } else if (r_one==5) {
597 if ((state == HDLC_FRAME_FOUND) &&
599 if ((bitcnt>>3)>=HSCX_BUFMAX) {
600 debugl1(bcs->cs, "tiger: frame too big");
602 state=HDLC_FLAG_SEARCH;
603 bcs->hw.tiger.r_err++;
604 #ifdef ERROR_STATISTIC
608 bcs->hw.tiger.rcvbuf[(bitcnt>>3)-1] = r_val;
609 bcs->hw.tiger.r_fcs =
610 PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
616 bcs->hw.tiger.r_tot++;
618 bcs->hw.tiger.r_state = state;
619 bcs->hw.tiger.r_one = r_one;
620 bcs->hw.tiger.r_val = r_val;
621 bcs->hw.tiger.r_bitcnt = bitcnt;
624 void read_tiger(struct IsdnCardState *cs) {
626 int cnt = NETJET_DMA_RXSIZE/2;
628 if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) {
629 debugl1(cs,"tiger warn read double dma %x/%x",
630 cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
631 #ifdef ERROR_STATISTIC
633 cs->bcs[0].err_rdo++;
635 cs->bcs[1].err_rdo++;
639 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ;
640 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ);
642 if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1)
643 p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1;
645 p = cs->bcs[0].hw.tiger.rec + cnt - 1;
646 if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))
647 read_raw(cs->bcs, p, cnt);
649 if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))
650 read_raw(cs->bcs + 1, p, cnt);
651 cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ;
654 static void write_raw(struct BCState *bcs, u_int *buf, int cnt);
656 void netjet_fill_dma(struct BCState *bcs)
658 register u_int *p, *sp;
663 if (bcs->cs->debug & L1_DEB_HSCX)
664 debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel,
666 if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag))
668 if (bcs->mode == L1_MODE_HDLC) { // it's 64k
669 if (make_raw_data(bcs))
673 if (make_raw_data_56k(bcs))
676 if (bcs->cs->debug & L1_DEB_HSCX)
677 debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel,
679 if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
680 write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
681 } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {
682 p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));
683 sp = bcs->hw.tiger.sendp;
684 if (p == bcs->hw.tiger.s_end)
685 p = bcs->hw.tiger.send -1;
686 if (sp == bcs->hw.tiger.s_end)
687 sp = bcs->hw.tiger.send -1;
690 write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
694 if (p > bcs->hw.tiger.s_end)
695 p = bcs->hw.tiger.send;
698 if (p > bcs->hw.tiger.s_end)
699 p = bcs->hw.tiger.send;
700 write_raw(bcs, p, bcs->hw.tiger.free - cnt);
702 } else if (test_and_clear_bit(BC_FLG_EMPTY, &bcs->Flag)) {
703 p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));
704 cnt = bcs->hw.tiger.s_end - p;
706 p = bcs->hw.tiger.send + 1;
707 cnt = NETJET_DMA_TXSIZE/2 - 2;
711 if (cnt <= (NETJET_DMA_TXSIZE/2))
712 cnt += NETJET_DMA_TXSIZE/2;
716 write_raw(bcs, p, cnt);
718 if (bcs->cs->debug & L1_DEB_HSCX)
719 debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel,
723 static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
724 u_int mask, val, *p=buf;
729 if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {
730 if (bcs->hw.tiger.sendcnt> cnt) {
732 bcs->hw.tiger.sendcnt -= cnt;
734 s_cnt = bcs->hw.tiger.sendcnt;
735 bcs->hw.tiger.sendcnt = 0;
741 for (i=0; i<s_cnt; i++) {
742 val = bcs->channel ? ((bcs->hw.tiger.sp[i] <<8) & 0xff00) :
743 (bcs->hw.tiger.sp[i]);
746 if (p>bcs->hw.tiger.s_end)
747 p = bcs->hw.tiger.send;
749 bcs->hw.tiger.s_tot += s_cnt;
750 if (bcs->cs->debug & L1_DEB_HSCX)
751 debugl1(bcs->cs,"tiger write_raw: c%d %x-%x %d/%d %d %x", bcs->channel,
752 (u_int)buf, (u_int)p, s_cnt, cnt,
753 bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0);
754 if (bcs->cs->debug & L1_DEB_HSCX_FIFO)
755 printframe(bcs->cs, bcs->hw.tiger.sp, s_cnt, "snd");
756 bcs->hw.tiger.sp += s_cnt;
757 bcs->hw.tiger.sendp = p;
758 if (!bcs->hw.tiger.sendcnt) {
760 debugl1(bcs->cs,"tiger write_raw: NULL skb s_cnt %d", s_cnt);
762 if (bcs->st->lli.l1writewakeup &&
763 (PACKET_NOACK != bcs->tx_skb->pkt_type))
764 bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
765 dev_kfree_skb_any(bcs->tx_skb);
768 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
769 bcs->hw.tiger.free = cnt - s_cnt;
770 if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE/2))
771 test_and_set_bit(BC_FLG_HALF, &bcs->Flag);
773 test_and_clear_bit(BC_FLG_HALF, &bcs->Flag);
774 test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag);
776 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
777 netjet_fill_dma(bcs);
781 for (i=s_cnt; i<cnt;i++) {
783 if (p>bcs->hw.tiger.s_end)
784 p = bcs->hw.tiger.send;
786 if (bcs->cs->debug & L1_DEB_HSCX)
787 debugl1(bcs->cs, "tiger write_raw: fill rest %d",
790 bcs->event |= 1 << B_XMTBUFREADY;
791 queue_task(&bcs->tqueue, &tq_immediate);
792 mark_bh(IMMEDIATE_BH);
795 } else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
796 test_and_set_bit(BC_FLG_HALF, &bcs->Flag);
797 fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
798 bcs->hw.tiger.free += cnt;
799 if (bcs->cs->debug & L1_DEB_HSCX)
800 debugl1(bcs->cs,"tiger write_raw: fill half");
801 } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {
802 test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
803 fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
804 if (bcs->cs->debug & L1_DEB_HSCX)
805 debugl1(bcs->cs,"tiger write_raw: fill full");
809 void write_tiger(struct IsdnCardState *cs) {
810 u_int *p, cnt = NETJET_DMA_TXSIZE/2;
812 if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) {
813 debugl1(cs,"tiger warn write double dma %x/%x",
814 cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
815 #ifdef ERROR_STATISTIC
823 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE;
824 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE);
826 if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE_1)
827 p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
829 p = cs->bcs[0].hw.tiger.send + cnt - 1;
830 if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))
831 write_raw(cs->bcs, p, cnt);
832 if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))
833 write_raw(cs->bcs + 1, p, cnt);
834 cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE;
838 tiger_l2l1(struct PStack *st, int pr, void *arg)
840 struct sk_buff *skb = arg;
844 case (PH_DATA | REQUEST):
847 if (st->l1.bcs->tx_skb) {
848 skb_queue_tail(&st->l1.bcs->squeue, skb);
849 restore_flags(flags);
851 st->l1.bcs->tx_skb = skb;
852 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
853 restore_flags(flags);
856 case (PH_PULL | INDICATION):
857 if (st->l1.bcs->tx_skb) {
858 printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n");
863 st->l1.bcs->tx_skb = skb;
864 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
865 restore_flags(flags);
867 case (PH_PULL | REQUEST):
868 if (!st->l1.bcs->tx_skb) {
869 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
870 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
872 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
874 case (PH_ACTIVATE | REQUEST):
875 test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
876 mode_tiger(st->l1.bcs, st->l1.mode, st->l1.bc);
877 /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
878 st->l1.bcs->cs->cardmsg(st->l1.bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc));
879 l1_msg_b(st, pr, arg);
881 case (PH_DEACTIVATE | REQUEST):
882 /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
883 st->l1.bcs->cs->cardmsg(st->l1.bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc));
884 l1_msg_b(st, pr, arg);
886 case (PH_DEACTIVATE | CONFIRM):
887 test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
888 test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
889 mode_tiger(st->l1.bcs, 0, st->l1.bc);
890 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
897 close_tigerstate(struct BCState *bcs)
899 mode_tiger(bcs, 0, bcs->channel);
900 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
901 if (bcs->hw.tiger.rcvbuf) {
902 kfree(bcs->hw.tiger.rcvbuf);
903 bcs->hw.tiger.rcvbuf = NULL;
905 if (bcs->hw.tiger.sendbuf) {
906 kfree(bcs->hw.tiger.sendbuf);
907 bcs->hw.tiger.sendbuf = NULL;
909 skb_queue_purge(&bcs->rqueue);
910 skb_queue_purge(&bcs->squeue);
912 dev_kfree_skb_any(bcs->tx_skb);
914 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
920 open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs)
922 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
923 if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
925 "HiSax: No memory for tiger.rcvbuf\n");
928 if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) {
930 "HiSax: No memory for tiger.sendbuf\n");
933 skb_queue_head_init(&bcs->rqueue);
934 skb_queue_head_init(&bcs->squeue);
937 bcs->hw.tiger.sendcnt = 0;
938 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
945 setstack_tiger(struct PStack *st, struct BCState *bcs)
947 bcs->channel = st->l1.bc;
948 if (open_tigerstate(st->l1.hardware, bcs))
951 st->l2.l2l1 = tiger_l2l1;
952 setstack_manager(st);
960 inittiger(struct IsdnCardState *cs)
962 if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int),
963 GFP_KERNEL | GFP_DMA))) {
965 "HiSax: No memory for tiger.send\n");
968 cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE/2 - 1;
969 cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
970 cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send;
971 cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq;
972 cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end;
974 memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int));
975 debugl1(cs, "tiger: send buf %x - %x", (u_int)cs->bcs[0].hw.tiger.send,
976 (u_int)(cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1));
977 outl(virt_to_bus(cs->bcs[0].hw.tiger.send),
978 cs->hw.njet.base + NETJET_DMA_READ_START);
979 outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq),
980 cs->hw.njet.base + NETJET_DMA_READ_IRQ);
981 outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end),
982 cs->hw.njet.base + NETJET_DMA_READ_END);
983 if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_RXSIZE * sizeof(unsigned int),
984 GFP_KERNEL | GFP_DMA))) {
986 "HiSax: No memory for tiger.rec\n");
989 debugl1(cs, "tiger: rec buf %x - %x", (u_int)cs->bcs[0].hw.tiger.rec,
990 (u_int)(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1));
991 cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec;
992 memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int));
993 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec),
994 cs->hw.njet.base + NETJET_DMA_WRITE_START);
995 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE/2 - 1),
996 cs->hw.njet.base + NETJET_DMA_WRITE_IRQ);
997 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1),
998 cs->hw.njet.base + NETJET_DMA_WRITE_END);
999 debugl1(cs, "tiger: dmacfg %x/%x pulse=%d",
1000 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
1001 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
1002 bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
1003 cs->hw.njet.last_is0 = 0;
1004 cs->bcs[0].BC_SetStack = setstack_tiger;
1005 cs->bcs[1].BC_SetStack = setstack_tiger;
1006 cs->bcs[0].BC_Close = close_tigerstate;
1007 cs->bcs[1].BC_Close = close_tigerstate;
1011 releasetiger(struct IsdnCardState *cs)
1013 if (cs->bcs[0].hw.tiger.send) {
1014 kfree(cs->bcs[0].hw.tiger.send);
1015 cs->bcs[0].hw.tiger.send = NULL;
1017 if (cs->bcs[1].hw.tiger.send) {
1018 cs->bcs[1].hw.tiger.send = NULL;
1020 if (cs->bcs[0].hw.tiger.rec) {
1021 kfree(cs->bcs[0].hw.tiger.rec);
1022 cs->bcs[0].hw.tiger.rec = NULL;
1024 if (cs->bcs[1].hw.tiger.rec) {
1025 cs->bcs[1].hw.tiger.rec = NULL;
1030 release_io_netjet(struct IsdnCardState *cs)
1032 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
1033 byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
1035 release_region(cs->hw.njet.base, 256);