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
NETjet_ReadIC(struct IsdnCardState * cs,u_char offset)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
NETjet_WriteIC(struct IsdnCardState * cs,u_char offset,u_char value)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
NETjet_ReadICfifo(struct IsdnCardState * cs,u_char * data,int size)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
NETjet_WriteICfifo(struct IsdnCardState * cs,u_char * data,int size)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
fill_mem(struct BCState * bcs,u_int * pos,u_int cnt,int chan,u_char fill)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
mode_tiger(struct BCState * bcs,int mode,int bc)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
printframe(struct IsdnCardState * cs,u_char * buf,int count,char * s)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
make_raw_data(struct BCState * bcs)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
make_raw_data_56k(struct BCState * bcs)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
got_frame(struct BCState * bcs,int count)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
read_raw(struct BCState * bcs,u_int * buf,int cnt)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
read_tiger(struct IsdnCardState * cs)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
netjet_fill_dma(struct BCState * bcs)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
write_raw(struct BCState * bcs,u_int * buf,int cnt)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
write_tiger(struct IsdnCardState * cs)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
tiger_l2l1(struct PStack * st,int pr,void * arg)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
close_tigerstate(struct BCState * bcs)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
open_tigerstate(struct IsdnCardState * cs,struct BCState * bcs)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
setstack_tiger(struct PStack * st,struct BCState * bcs)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
inittiger(struct IsdnCardState * cs)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
releasetiger(struct IsdnCardState * cs)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
release_io_netjet(struct IsdnCardState * cs)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
1038