import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / drivers / isdn / hisax / netjet.c
1 /* $Id: netjet.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
2  *
3  * low level stuff for Traverse Technologie NETJet ISDN cards
4  *
5  * Author       Karsten Keil
6  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
7  * 
8  * This software may be used and distributed according to the terms
9  * of the GNU General Public License, incorporated herein by reference.
10  *
11  * Thanks to Traverse Technologies Australia for documents and information
12  *
13  * 16-Apr-2002 - led code added - Guy Ellis (guy@traverse.com.au)
14  *
15  */
16
17 #define __NO_VERSION__
18 #include <linux/init.h>
19 #include "hisax.h"
20 #include "isac.h"
21 #include "hscx.h"
22 #include "isdnl1.h"
23 #include <linux/pci.h>
24 #include <linux/interrupt.h>
25 #include <linux/ppp_defs.h>
26 #include <asm/io.h>
27 #include "netjet.h"
28
29 const char *NETjet_revision = "$Revision: 1.1.4.1 $";
30
31 /* Interface functions */
32
33 u_char
34 NETjet_ReadIC(struct IsdnCardState *cs, u_char offset)
35 {
36         long flags;
37         u_char ret;
38         
39         save_flags(flags);
40         cli();
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));
45         restore_flags(flags);
46         return(ret);
47 }
48
49 void
50 NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value)
51 {
52         long flags;
53         
54         save_flags(flags);
55         cli();
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);
60         restore_flags(flags);
61 }
62
63 void
64 NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size)
65 {
66         cs->hw.njet.auxd &= 0xfc;
67         byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
68         insb(cs->hw.njet.isac, data, size);
69 }
70
71 __u16 fcstab[256] =
72 {
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
105 };
106
107 void 
108 NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size)
109 {
110         cs->hw.njet.auxd &= 0xfc;
111         byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
112         outsb(cs->hw.njet.isac, data, size);
113 }
114
115 void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
116 {
117         u_int mask=0x000000ff, val = 0, *p=pos;
118         u_int i;
119         
120         val |= fill;
121         if (chan) {
122                 val  <<= 8;
123                 mask <<= 8;
124         }
125         mask ^= 0xffffffff;
126         for (i=0; i<cnt; i++) {
127                 *p   &= mask;
128                 *p++ |= val;
129                 if (p > bcs->hw.tiger.s_end)
130                         p = bcs->hw.tiger.send;
131         }
132 }
133
134 void
135 mode_tiger(struct BCState *bcs, int mode, int bc)
136 {
137         struct IsdnCardState *cs = bcs->cs;
138         u_char led;
139
140         if (cs->debug & L1_DEB_HSCX)
141                 debugl1(cs, "Tiger mode %d bchan %d/%d",
142                         mode, bc, bcs->channel);
143         bcs->mode = mode;
144         bcs->channel = bc;
145         switch (mode) {
146                 case (L1_MODE_NULL):
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);
159                         }
160                         if (cs->typ == ISDN_CTYPE_NETJET_S)
161                         {
162                                 // led off
163                                 led = bc & 0x01;
164                                 led = 0x01 << (6 + led); // convert to mask
165                                 led = ~led;
166                                 cs->hw.njet.auxd &= led;
167                                 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
168                         }
169                         break;
170                 case (L1_MODE_TRANS):
171                         break;
172                 case (L1_MODE_HDLC_56K):
173                 case (L1_MODE_HDLC):
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 */
190                         }
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)
195                         {
196                                 // led on
197                                 led = bc & 0x01;
198                                 led = 0x01 << (6 + led); // convert to mask
199                                 cs->hw.njet.auxd |= led;
200                                 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
201                         }
202                         break;
203         }
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));
212 }
213
214 static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s) {
215         char tmp[128];
216         char *t = tmp;
217         int i=count,j;
218         u_char *p = buf;
219
220         t += sprintf(t, "tiger %s(%4d)", s, count);
221         while (i>0) {
222                 if (i>16)
223                         j=16;
224                 else
225                         j=i;
226                 QuickHex(t, p, j);
227                 debugl1(cs, tmp);
228                 p += j;
229                 i -= j;
230                 t = tmp;
231                 t += sprintf(t, "tiger %s      ", s);
232         }
233 }
234
235 // macro for 64k
236
237 #define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
238                         bitcnt++;\
239                         s_val >>= 1;\
240                         if (val & 1) {\
241                                 s_one++;\
242                                 s_val |= 0x80;\
243                         } else {\
244                                 s_one = 0;\
245                                 s_val &= 0x7f;\
246                         }\
247                         if (bitcnt==8) {\
248                                 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
249                                 bitcnt = 0;\
250                         }\
251                         if (s_one == 5) {\
252                                 s_val >>= 1;\
253                                 s_val &= 0x7f;\
254                                 bitcnt++;\
255                                 s_one = 0;\
256                         }\
257                         if (bitcnt==8) {\
258                                 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
259                                 bitcnt = 0;\
260                         }\
261                         val >>= 1;\
262                 }
263
264 static int make_raw_data(struct BCState *bcs) {
265 // this make_raw is for 64k
266         register u_int i,s_cnt=0;
267         register u_char j;
268         register u_char val;
269         register u_char s_one = 0;
270         register u_char s_val = 0;
271         register u_char bitcnt = 0;
272         u_int fcs;
273         
274         if (!bcs->tx_skb) {
275                 debugl1(bcs->cs, "tiger make_raw: NULL skb");
276                 return(1);
277         }
278         bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE;
279         fcs = PPP_INITFCS;
280         for (i=0; i<bcs->tx_skb->len; i++) {
281                 val = bcs->tx_skb->data[i];
282                 fcs = PPP_FCS (fcs, val);
283                 MAKE_RAW_BYTE;
284         }
285         fcs ^= 0xffff;
286         val = fcs & 0xff;
287         MAKE_RAW_BYTE;
288         val = (fcs>>8) & 0xff;
289         MAKE_RAW_BYTE;
290         val = HDLC_FLAG_VALUE;
291         for (j=0; j<8; j++) { 
292                 bitcnt++;
293                 s_val >>= 1;
294                 if (val & 1)
295                         s_val |= 0x80;
296                 else
297                         s_val &= 0x7f;
298                 if (bitcnt==8) {
299                         bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
300                         bitcnt = 0;
301                 }
302                 val >>= 1;
303         }
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);
307         if (bitcnt) {
308                 while (8>bitcnt++) {
309                         s_val >>= 1;
310                         s_val |= 0x80;
311                 }
312                 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
313                 bcs->hw.tiger.sendbuf[s_cnt++] = 0xff;  // NJ<->NJ thoughput bug fix
314         }
315         bcs->hw.tiger.sendcnt = s_cnt;
316         bcs->tx_cnt -= bcs->tx_skb->len;
317         bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
318         return(0);
319 }
320
321 // macro for 56k
322
323 #define MAKE_RAW_BYTE_56K for (j=0; j<8; j++) { \
324                         bitcnt++;\
325                         s_val >>= 1;\
326                         if (val & 1) {\
327                                 s_one++;\
328                                 s_val |= 0x80;\
329                         } else {\
330                                 s_one = 0;\
331                                 s_val &= 0x7f;\
332                         }\
333                         if (bitcnt==7) {\
334                                 s_val >>= 1;\
335                                 s_val |= 0x80;\
336                                 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
337                                 bitcnt = 0;\
338                         }\
339                         if (s_one == 5) {\
340                                 s_val >>= 1;\
341                                 s_val &= 0x7f;\
342                                 bitcnt++;\
343                                 s_one = 0;\
344                         }\
345                         if (bitcnt==7) {\
346                                 s_val >>= 1;\
347                                 s_val |= 0x80;\
348                                 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
349                                 bitcnt = 0;\
350                         }\
351                         val >>= 1;\
352                 }
353
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;
357         register u_char j;
358         register u_char val;
359         register u_char s_one = 0;
360         register u_char s_val = 0;
361         register u_char bitcnt = 0;
362         u_int fcs;
363         
364         if (!bcs->tx_skb) {
365                 debugl1(bcs->cs, "tiger make_raw_56k: NULL skb");
366                 return(1);
367         }
368         val = HDLC_FLAG_VALUE;
369         for (j=0; j<8; j++) { 
370                 bitcnt++;
371                 s_val >>= 1;
372                 if (val & 1)
373                         s_val |= 0x80;
374                 else
375                         s_val &= 0x7f;
376                 if (bitcnt==7) {
377                         s_val >>= 1;
378                         s_val |= 0x80;
379                         bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
380                         bitcnt = 0;
381                 }
382                 val >>= 1;
383         };
384         fcs = PPP_INITFCS;
385         for (i=0; i<bcs->tx_skb->len; i++) {
386                 val = bcs->tx_skb->data[i];
387                 fcs = PPP_FCS (fcs, val);
388                 MAKE_RAW_BYTE_56K;
389         }
390         fcs ^= 0xffff;
391         val = fcs & 0xff;
392         MAKE_RAW_BYTE_56K;
393         val = (fcs>>8) & 0xff;
394         MAKE_RAW_BYTE_56K;
395         val = HDLC_FLAG_VALUE;
396         for (j=0; j<8; j++) { 
397                 bitcnt++;
398                 s_val >>= 1;
399                 if (val & 1)
400                         s_val |= 0x80;
401                 else
402                         s_val &= 0x7f;
403                 if (bitcnt==7) {
404                         s_val >>= 1;
405                         s_val |= 0x80;
406                         bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
407                         bitcnt = 0;
408                 }
409                 val >>= 1;
410         }
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);
414         if (bitcnt) {
415                 while (8>bitcnt++) {
416                         s_val >>= 1;
417                         s_val |= 0x80;
418                 }
419                 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
420                 bcs->hw.tiger.sendbuf[s_cnt++] = 0xff;  // NJ<->NJ thoughput bug fix
421         }
422         bcs->hw.tiger.sendcnt = s_cnt;
423         bcs->tx_cnt -= bcs->tx_skb->len;
424         bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
425         return(0);
426 }
427
428 static void got_frame(struct BCState *bcs, int count) {
429         struct sk_buff *skb;
430                 
431         if (!(skb = dev_alloc_skb(count)))
432                 printk(KERN_WARNING "TIGER: receive out of memory\n");
433         else {
434                 memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count);
435                 skb_queue_tail(&bcs->rqueue, skb);
436         }
437         bcs->event |= 1 << B_RCVBUFREADY;
438         queue_task(&bcs->tqueue, &tq_immediate);
439         mark_bh(IMMEDIATE_BH);
440         
441         if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME)
442                 printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec");
443 }
444
445
446
447 static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
448         int i;
449         register u_char j;
450         register u_char val;
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;
456         u_int *p = buf;
457         int bits;
458         u_char mask;
459
460         if (bcs->mode == L1_MODE_HDLC) { // it's 64k
461                 mask = 0xff;
462                 bits = 8;
463         }
464         else { // it's 56K
465                 mask = 0x7f;
466                 bits = 7;
467         };
468         for (i=0;i<cnt;i++) {
469                 val = bcs->channel ? ((*p>>8) & 0xff) : (*p & 0xff);
470                 p++;
471                 if (p > pend)
472                         p = bcs->hw.tiger.rec;
473                 if ((val & mask) == mask) {
474                         state = HDLC_ZERO_SEARCH;
475                         bcs->hw.tiger.r_tot++;
476                         bitcnt = 0;
477                         r_one = 0;
478                         continue;
479                 }
480                 for (j=0;j<bits;j++) {
481                         if (state == HDLC_ZERO_SEARCH) {
482                                 if (val & 1) {
483                                         r_one++;
484                                 } else {
485                                         r_one=0;
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);
490                                 }
491                         } else if (state == HDLC_FLAG_SEARCH) { 
492                                 if (val & 1) {
493                                         r_one++;
494                                         if (r_one>6) {
495                                                 state=HDLC_ZERO_SEARCH;
496                                         }
497                                 } else {
498                                         if (r_one==6) {
499                                                 bitcnt=0;
500                                                 r_val=0;
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);
505                                         }
506                                         r_one=0;
507                                 }
508                         } else if (state ==  HDLC_FLAG_FOUND) {
509                                 if (val & 1) {
510                                         r_one++;
511                                         if (r_one>6) {
512                                                 state=HDLC_ZERO_SEARCH;
513                                         } else {
514                                                 r_val >>= 1;
515                                                 r_val |= 0x80;
516                                                 bitcnt++;
517                                         }
518                                 } else {
519                                         if (r_one==6) {
520                                                 bitcnt=0;
521                                                 r_val=0;
522                                                 r_one=0;
523                                                 val >>= 1;
524                                                 continue;
525                                         } else if (r_one!=5) {
526                                                 r_val >>= 1;
527                                                 r_val &= 0x7f;
528                                                 bitcnt++;
529                                         }
530                                         r_one=0;        
531                                 }
532                                 if ((state != HDLC_ZERO_SEARCH) &&
533                                         !(bitcnt & 7)) {
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);
542                                 }
543                         } else if (state ==  HDLC_FRAME_FOUND) {
544                                 if (val & 1) {
545                                         r_one++;
546                                         if (r_one>6) {
547                                                 state=HDLC_ZERO_SEARCH;
548                                                 bitcnt=0;
549                                         } else {
550                                                 r_val >>= 1;
551                                                 r_val |= 0x80;
552                                                 bitcnt++;
553                                         }
554                                 } else {
555                                         if (r_one==6) {
556                                                 r_val=0; 
557                                                 r_one=0;
558                                                 bitcnt++;
559                                                 if (bitcnt & 7) {
560                                                         debugl1(bcs->cs, "tiger: frame not byte aligned");
561                                                         state=HDLC_FLAG_SEARCH;
562                                                         bcs->hw.tiger.r_err++;
563 #ifdef ERROR_STATISTIC
564                                                         bcs->err_inv++;
565 #endif
566                                                 } else {
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);
572                                                         } else {
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++;
578                                                                 }
579 #ifdef ERROR_STATISTIC
580                                                         bcs->err_crc++;
581 #endif
582                                                         }
583                                                         state=HDLC_FLAG_FOUND;
584                                                 }
585                                                 bitcnt=0;
586                                         } else if (r_one==5) {
587                                                 val >>= 1;
588                                                 r_one=0;
589                                                 continue;
590                                         } else {
591                                                 r_val >>= 1;
592                                                 r_val &= 0x7f;
593                                                 bitcnt++;
594                                         }
595                                         r_one=0;        
596                                 }
597                                 if ((state == HDLC_FRAME_FOUND) &&
598                                         !(bitcnt & 7)) {
599                                         if ((bitcnt>>3)>=HSCX_BUFMAX) {
600                                                 debugl1(bcs->cs, "tiger: frame too big");
601                                                 r_val=0; 
602                                                 state=HDLC_FLAG_SEARCH;
603                                                 bcs->hw.tiger.r_err++;
604 #ifdef ERROR_STATISTIC
605                                                 bcs->err_inv++;
606 #endif
607                                         } else {
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);
611                                         }
612                                 }
613                         }
614                         val >>= 1;
615                 }
616                 bcs->hw.tiger.r_tot++;
617         }
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;
622 }
623
624 void read_tiger(struct IsdnCardState *cs) {
625         u_int *p;
626         int cnt = NETJET_DMA_RXSIZE/2;
627         
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
632                 if (cs->bcs[0].mode)
633                         cs->bcs[0].err_rdo++;
634                 if (cs->bcs[1].mode)
635                         cs->bcs[1].err_rdo++;
636 #endif
637                 return;
638         } else {
639                 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ;
640                 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ);
641         }       
642         if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1)
643                 p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1;
644         else
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);
648
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;
652 }
653
654 static void write_raw(struct BCState *bcs, u_int *buf, int cnt);
655
656 void netjet_fill_dma(struct BCState *bcs)
657 {
658         register u_int *p, *sp;
659         register int cnt;
660
661         if (!bcs->tx_skb)
662                 return;
663         if (bcs->cs->debug & L1_DEB_HSCX)
664                 debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel,
665                         bcs->Flag);
666         if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag))
667                 return;
668         if (bcs->mode == L1_MODE_HDLC) { // it's 64k
669                 if (make_raw_data(bcs))
670                         return;         
671         }
672         else { // it's 56k
673                 if (make_raw_data_56k(bcs))
674                         return;         
675         };
676         if (bcs->cs->debug & L1_DEB_HSCX)
677                 debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel,
678                         bcs->Flag);
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;
688                 cnt = p - sp;
689                 if (cnt <0) {
690                         write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
691                 } else {
692                         p++;
693                         cnt++;
694                         if (p > bcs->hw.tiger.s_end)
695                                 p = bcs->hw.tiger.send;
696                         p++;
697                         cnt++;
698                         if (p > bcs->hw.tiger.s_end)
699                                 p = bcs->hw.tiger.send;
700                         write_raw(bcs, p, bcs->hw.tiger.free - cnt);
701                 }
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;
705                 if (cnt < 2) {
706                         p = bcs->hw.tiger.send + 1;
707                         cnt = NETJET_DMA_TXSIZE/2 - 2;
708                 } else {
709                         p++;
710                         p++;
711                         if (cnt <= (NETJET_DMA_TXSIZE/2))
712                                 cnt += NETJET_DMA_TXSIZE/2;
713                         cnt--;
714                         cnt--;
715                 }
716                 write_raw(bcs, p, cnt);
717         }
718         if (bcs->cs->debug & L1_DEB_HSCX)
719                 debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel,
720                         bcs->Flag);
721 }
722
723 static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
724         u_int mask, val, *p=buf;
725         u_int i, s_cnt;
726         
727         if (cnt <= 0)
728                 return;
729         if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {
730                 if (bcs->hw.tiger.sendcnt> cnt) {
731                         s_cnt = cnt;
732                         bcs->hw.tiger.sendcnt -= cnt;
733                 } else {
734                         s_cnt = bcs->hw.tiger.sendcnt;
735                         bcs->hw.tiger.sendcnt = 0;
736                 }
737                 if (bcs->channel)
738                         mask = 0xffff00ff;
739                 else
740                         mask = 0xffffff00;
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]);
744                         *p   &= mask;
745                         *p++ |= val;
746                         if (p>bcs->hw.tiger.s_end)
747                                 p = bcs->hw.tiger.send;
748                 }
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) {
759                         if (!bcs->tx_skb) {
760                                 debugl1(bcs->cs,"tiger write_raw: NULL skb s_cnt %d", s_cnt);
761                         } else {
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);
766                                 bcs->tx_skb = NULL;
767                         }
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);
772                         else {
773                                 test_and_clear_bit(BC_FLG_HALF, &bcs->Flag);
774                                 test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag);
775                         }
776                         if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
777                                 netjet_fill_dma(bcs);
778                         } else {
779                                 mask ^= 0xffffffff;
780                                 if (s_cnt < cnt) {
781                                         for (i=s_cnt; i<cnt;i++) {
782                                                 *p++ |= mask;
783                                                 if (p>bcs->hw.tiger.s_end)
784                                                         p = bcs->hw.tiger.send;
785                                         }
786                                         if (bcs->cs->debug & L1_DEB_HSCX)
787                                                 debugl1(bcs->cs, "tiger write_raw: fill rest %d",
788                                                         cnt - s_cnt);
789                                 }
790                                 bcs->event |= 1 << B_XMTBUFREADY;
791                                 queue_task(&bcs->tqueue, &tq_immediate);
792                                 mark_bh(IMMEDIATE_BH);
793                         }
794                 }
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");
806         }
807 }
808
809 void write_tiger(struct IsdnCardState *cs) {
810         u_int *p, cnt = NETJET_DMA_TXSIZE/2;
811         
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
816                 if (cs->bcs[0].mode)
817                         cs->bcs[0].err_tx++;
818                 if (cs->bcs[1].mode)
819                         cs->bcs[1].err_tx++;
820 #endif
821                 return;
822         } else {
823                 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE;
824                 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE);
825         }       
826         if (cs->hw.njet.irqstat0  & NETJET_IRQM0_WRITE_1)
827                 p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
828         else
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;
835 }
836
837 static void
838 tiger_l2l1(struct PStack *st, int pr, void *arg)
839 {
840         struct sk_buff *skb = arg;
841         long flags;
842
843         switch (pr) {
844                 case (PH_DATA | REQUEST):
845                         save_flags(flags);
846                         cli();
847                         if (st->l1.bcs->tx_skb) {
848                                 skb_queue_tail(&st->l1.bcs->squeue, skb);
849                                 restore_flags(flags);
850                         } else {
851                                 st->l1.bcs->tx_skb = skb;
852                                 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
853                                 restore_flags(flags);
854                         }
855                         break;
856                 case (PH_PULL | INDICATION):
857                         if (st->l1.bcs->tx_skb) {
858                                 printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n");
859                                 break;
860                         }
861                         save_flags(flags);
862                         cli();
863                         st->l1.bcs->tx_skb = skb;
864                         st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
865                         restore_flags(flags);
866                         break;
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);
871                         } else
872                                 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
873                         break;
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);
880                         break;
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);
885                         break;
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);
891                         break;
892         }
893 }
894
895
896 void
897 close_tigerstate(struct BCState *bcs)
898 {
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;
904                 }
905                 if (bcs->hw.tiger.sendbuf) {
906                         kfree(bcs->hw.tiger.sendbuf);
907                         bcs->hw.tiger.sendbuf = NULL;
908                 }
909                 skb_queue_purge(&bcs->rqueue);
910                 skb_queue_purge(&bcs->squeue);
911                 if (bcs->tx_skb) {
912                         dev_kfree_skb_any(bcs->tx_skb);
913                         bcs->tx_skb = NULL;
914                         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
915                 }
916         }
917 }
918
919 static int
920 open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs)
921 {
922         if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
923                 if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
924                         printk(KERN_WARNING
925                                "HiSax: No memory for tiger.rcvbuf\n");
926                         return (1);
927                 }
928                 if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) {
929                         printk(KERN_WARNING
930                                "HiSax: No memory for tiger.sendbuf\n");
931                         return (1);
932                 }
933                 skb_queue_head_init(&bcs->rqueue);
934                 skb_queue_head_init(&bcs->squeue);
935         }
936         bcs->tx_skb = NULL;
937         bcs->hw.tiger.sendcnt = 0;
938         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
939         bcs->event = 0;
940         bcs->tx_cnt = 0;
941         return (0);
942 }
943
944 int
945 setstack_tiger(struct PStack *st, struct BCState *bcs)
946 {
947         bcs->channel = st->l1.bc;
948         if (open_tigerstate(st->l1.hardware, bcs))
949                 return (-1);
950         st->l1.bcs = bcs;
951         st->l2.l2l1 = tiger_l2l1;
952         setstack_manager(st);
953         bcs->st = st;
954         setstack_l1_B(st);
955         return (0);
956 }
957
958  
959 void __init
960 inittiger(struct IsdnCardState *cs)
961 {
962         if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int),
963                 GFP_KERNEL | GFP_DMA))) {
964                 printk(KERN_WARNING
965                        "HiSax: No memory for tiger.send\n");
966                 return;
967         }
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;
973         
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))) {
985                 printk(KERN_WARNING
986                        "HiSax: No memory for tiger.rec\n");
987                 return;
988         }
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;
1008 }
1009
1010 void
1011 releasetiger(struct IsdnCardState *cs)
1012 {
1013         if (cs->bcs[0].hw.tiger.send) {
1014                 kfree(cs->bcs[0].hw.tiger.send);
1015                 cs->bcs[0].hw.tiger.send = NULL;
1016         }
1017         if (cs->bcs[1].hw.tiger.send) {
1018                 cs->bcs[1].hw.tiger.send = NULL;
1019         }
1020         if (cs->bcs[0].hw.tiger.rec) {
1021                 kfree(cs->bcs[0].hw.tiger.rec);
1022                 cs->bcs[0].hw.tiger.rec = NULL;
1023         }
1024         if (cs->bcs[1].hw.tiger.rec) {
1025                 cs->bcs[1].hw.tiger.rec = NULL;
1026         }
1027 }
1028
1029 void
1030 release_io_netjet(struct IsdnCardState *cs)
1031 {
1032         byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
1033         byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
1034         releasetiger(cs);
1035         release_region(cs->hw.njet.base, 256);
1036 }
1037