1/* $Id: netjet.c,v 1.1.1.1 2008/10/15 03:26:33 james26_jang 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
29const char *NETjet_revision = "$Revision: 1.1.1.1 $";
30
31/* Interface functions */
32
33u_char
34NETjet_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
49void
50NETjet_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
63void
64NETjet_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
107void
108NETjet_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
115void 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
134void
135mode_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
214static 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
264static 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
354static 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
428static 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
447static 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
624void 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
654static void write_raw(struct BCState *bcs, u_int *buf, int cnt);
655
656void 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
723static 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
809void 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
837static void
838tiger_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
896void
897close_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
919static int
920open_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
944int
945setstack_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
959void __init
960inittiger(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
1010void
1011releasetiger(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
1029void
1030release_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