• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/isdn/hisax/
1/* $Id: netjet.c,v 1.29.2.4 2004/02/11 13:21:34 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#include <linux/init.h>
18#include "hisax.h"
19#include "isac.h"
20#include "hscx.h"
21#include "isdnl1.h"
22#include <linux/interrupt.h>
23#include <linux/ppp_defs.h>
24#include <linux/slab.h>
25#include <asm/io.h>
26#include "netjet.h"
27
28/* Interface functions */
29
30u_char
31NETjet_ReadIC(struct IsdnCardState *cs, u_char offset)
32{
33	u_char ret;
34
35	cs->hw.njet.auxd &= 0xfc;
36	cs->hw.njet.auxd |= (offset>>4) & 3;
37	byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
38	ret = bytein(cs->hw.njet.isac + ((offset & 0xf)<<2));
39	return(ret);
40}
41
42void
43NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value)
44{
45	cs->hw.njet.auxd &= 0xfc;
46	cs->hw.njet.auxd |= (offset>>4) & 3;
47	byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
48	byteout(cs->hw.njet.isac + ((offset & 0xf)<<2), value);
49}
50
51void
52NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size)
53{
54	cs->hw.njet.auxd &= 0xfc;
55	byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
56	insb(cs->hw.njet.isac, data, size);
57}
58
59void
60NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size)
61{
62	cs->hw.njet.auxd &= 0xfc;
63	byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
64	outsb(cs->hw.njet.isac, data, size);
65}
66
67static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
68{
69	u_int mask=0x000000ff, val = 0, *p=pos;
70	u_int i;
71
72	val |= fill;
73	if (chan) {
74		val  <<= 8;
75		mask <<= 8;
76	}
77	mask ^= 0xffffffff;
78	for (i=0; i<cnt; i++) {
79		*p   &= mask;
80		*p++ |= val;
81		if (p > bcs->hw.tiger.s_end)
82			p = bcs->hw.tiger.send;
83	}
84}
85
86static void
87mode_tiger(struct BCState *bcs, int mode, int bc)
88{
89	struct IsdnCardState *cs = bcs->cs;
90        u_char led;
91
92	if (cs->debug & L1_DEB_HSCX)
93		debugl1(cs, "Tiger mode %d bchan %d/%d",
94			mode, bc, bcs->channel);
95	bcs->mode = mode;
96	bcs->channel = bc;
97	switch (mode) {
98		case (L1_MODE_NULL):
99			fill_mem(bcs, bcs->hw.tiger.send,
100				NETJET_DMA_TXSIZE, bc, 0xff);
101			if (cs->debug & L1_DEB_HSCX)
102				debugl1(cs, "Tiger stat rec %d/%d send %d",
103					bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err,
104					bcs->hw.tiger.s_tot);
105			if ((cs->bcs[0].mode == L1_MODE_NULL) &&
106				(cs->bcs[1].mode == L1_MODE_NULL)) {
107				cs->hw.njet.dmactrl = 0;
108				byteout(cs->hw.njet.base + NETJET_DMACTRL,
109					cs->hw.njet.dmactrl);
110				byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
111			}
112                        if (cs->typ == ISDN_CTYPE_NETJET_S)
113                        {
114                                // led off
115                                led = bc & 0x01;
116                                led = 0x01 << (6 + led); // convert to mask
117                                led = ~led;
118                                cs->hw.njet.auxd &= led;
119                                byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
120                        }
121			break;
122		case (L1_MODE_TRANS):
123			break;
124		case (L1_MODE_HDLC_56K):
125		case (L1_MODE_HDLC):
126			fill_mem(bcs, bcs->hw.tiger.send,
127				NETJET_DMA_TXSIZE, bc, 0xff);
128			bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH;
129			bcs->hw.tiger.r_tot = 0;
130			bcs->hw.tiger.r_bitcnt = 0;
131			bcs->hw.tiger.r_one = 0;
132			bcs->hw.tiger.r_err = 0;
133			bcs->hw.tiger.s_tot = 0;
134			if (! cs->hw.njet.dmactrl) {
135				fill_mem(bcs, bcs->hw.tiger.send,
136					NETJET_DMA_TXSIZE, !bc, 0xff);
137				cs->hw.njet.dmactrl = 1;
138				byteout(cs->hw.njet.base + NETJET_DMACTRL,
139					cs->hw.njet.dmactrl);
140				byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x0f);
141			/* was 0x3f now 0x0f for TJ300 and TJ320  GE 13/07/00 */
142			}
143			bcs->hw.tiger.sendp = bcs->hw.tiger.send;
144			bcs->hw.tiger.free = NETJET_DMA_TXSIZE;
145			test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
146                        if (cs->typ == ISDN_CTYPE_NETJET_S)
147                        {
148                                // led on
149                                led = bc & 0x01;
150                                led = 0x01 << (6 + led); // convert to mask
151                                cs->hw.njet.auxd |= led;
152                                byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
153                        }
154			break;
155	}
156	if (cs->debug & L1_DEB_HSCX)
157		debugl1(cs, "tiger: set %x %x %x  %x/%x  pulse=%d",
158			bytein(cs->hw.njet.base + NETJET_DMACTRL),
159			bytein(cs->hw.njet.base + NETJET_IRQMASK0),
160			bytein(cs->hw.njet.base + NETJET_IRQSTAT0),
161			inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
162			inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
163			bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
164}
165
166static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s) {
167	char tmp[128];
168	char *t = tmp;
169	int i=count,j;
170	u_char *p = buf;
171
172	t += sprintf(t, "tiger %s(%4d)", s, count);
173	while (i>0) {
174		if (i>16)
175			j=16;
176		else
177			j=i;
178		QuickHex(t, p, j);
179		debugl1(cs, tmp);
180		p += j;
181		i -= j;
182		t = tmp;
183		t += sprintf(t, "tiger %s      ", s);
184	}
185}
186
187// macro for 64k
188
189#define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
190			bitcnt++;\
191			s_val >>= 1;\
192			if (val & 1) {\
193				s_one++;\
194				s_val |= 0x80;\
195			} else {\
196				s_one = 0;\
197				s_val &= 0x7f;\
198			}\
199			if (bitcnt==8) {\
200				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
201				bitcnt = 0;\
202			}\
203			if (s_one == 5) {\
204				s_val >>= 1;\
205				s_val &= 0x7f;\
206				bitcnt++;\
207				s_one = 0;\
208			}\
209			if (bitcnt==8) {\
210				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
211				bitcnt = 0;\
212			}\
213			val >>= 1;\
214		}
215
216static int make_raw_data(struct BCState *bcs) {
217// this make_raw is for 64k
218	register u_int i,s_cnt=0;
219	register u_char j;
220	register u_char val;
221	register u_char s_one = 0;
222	register u_char s_val = 0;
223	register u_char bitcnt = 0;
224	u_int fcs;
225
226	if (!bcs->tx_skb) {
227		debugl1(bcs->cs, "tiger make_raw: NULL skb");
228		return(1);
229	}
230	bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE;
231	fcs = PPP_INITFCS;
232	for (i=0; i<bcs->tx_skb->len; i++) {
233		val = bcs->tx_skb->data[i];
234		fcs = PPP_FCS (fcs, val);
235		MAKE_RAW_BYTE;
236	}
237	fcs ^= 0xffff;
238	val = fcs & 0xff;
239	MAKE_RAW_BYTE;
240	val = (fcs>>8) & 0xff;
241	MAKE_RAW_BYTE;
242	val = HDLC_FLAG_VALUE;
243	for (j=0; j<8; j++) {
244		bitcnt++;
245		s_val >>= 1;
246		if (val & 1)
247			s_val |= 0x80;
248		else
249			s_val &= 0x7f;
250		if (bitcnt==8) {
251			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
252			bitcnt = 0;
253		}
254		val >>= 1;
255	}
256	if (bcs->cs->debug & L1_DEB_HSCX)
257		debugl1(bcs->cs,"tiger make_raw: in %ld out %d.%d",
258			bcs->tx_skb->len, s_cnt, bitcnt);
259	if (bitcnt) {
260		while (8>bitcnt++) {
261			s_val >>= 1;
262			s_val |= 0x80;
263		}
264		bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
265		bcs->hw.tiger.sendbuf[s_cnt++] = 0xff;	// NJ<->NJ thoughput bug fix
266	}
267	bcs->hw.tiger.sendcnt = s_cnt;
268	bcs->tx_cnt -= bcs->tx_skb->len;
269	bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
270	return(0);
271}
272
273// macro for 56k
274
275#define MAKE_RAW_BYTE_56K for (j=0; j<8; j++) { \
276			bitcnt++;\
277			s_val >>= 1;\
278			if (val & 1) {\
279				s_one++;\
280				s_val |= 0x80;\
281			} else {\
282				s_one = 0;\
283				s_val &= 0x7f;\
284			}\
285			if (bitcnt==7) {\
286				s_val >>= 1;\
287				s_val |= 0x80;\
288				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
289				bitcnt = 0;\
290			}\
291			if (s_one == 5) {\
292				s_val >>= 1;\
293				s_val &= 0x7f;\
294				bitcnt++;\
295				s_one = 0;\
296			}\
297			if (bitcnt==7) {\
298				s_val >>= 1;\
299				s_val |= 0x80;\
300				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
301				bitcnt = 0;\
302			}\
303			val >>= 1;\
304		}
305
306static int make_raw_data_56k(struct BCState *bcs) {
307// this make_raw is for 56k
308	register u_int i,s_cnt=0;
309	register u_char j;
310	register u_char val;
311	register u_char s_one = 0;
312	register u_char s_val = 0;
313	register u_char bitcnt = 0;
314	u_int fcs;
315
316	if (!bcs->tx_skb) {
317		debugl1(bcs->cs, "tiger make_raw_56k: NULL skb");
318		return(1);
319	}
320	val = HDLC_FLAG_VALUE;
321	for (j=0; j<8; j++) {
322		bitcnt++;
323		s_val >>= 1;
324		if (val & 1)
325			s_val |= 0x80;
326		else
327			s_val &= 0x7f;
328		if (bitcnt==7) {
329			s_val >>= 1;
330			s_val |= 0x80;
331			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
332			bitcnt = 0;
333		}
334		val >>= 1;
335	};
336	fcs = PPP_INITFCS;
337	for (i=0; i<bcs->tx_skb->len; i++) {
338		val = bcs->tx_skb->data[i];
339		fcs = PPP_FCS (fcs, val);
340		MAKE_RAW_BYTE_56K;
341	}
342	fcs ^= 0xffff;
343	val = fcs & 0xff;
344	MAKE_RAW_BYTE_56K;
345	val = (fcs>>8) & 0xff;
346	MAKE_RAW_BYTE_56K;
347	val = HDLC_FLAG_VALUE;
348	for (j=0; j<8; j++) {
349		bitcnt++;
350		s_val >>= 1;
351		if (val & 1)
352			s_val |= 0x80;
353		else
354			s_val &= 0x7f;
355		if (bitcnt==7) {
356			s_val >>= 1;
357			s_val |= 0x80;
358			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
359			bitcnt = 0;
360		}
361		val >>= 1;
362	}
363	if (bcs->cs->debug & L1_DEB_HSCX)
364		debugl1(bcs->cs,"tiger make_raw_56k: in %ld out %d.%d",
365			bcs->tx_skb->len, s_cnt, bitcnt);
366	if (bitcnt) {
367		while (8>bitcnt++) {
368			s_val >>= 1;
369			s_val |= 0x80;
370		}
371		bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
372		bcs->hw.tiger.sendbuf[s_cnt++] = 0xff;	// NJ<->NJ thoughput bug fix
373	}
374	bcs->hw.tiger.sendcnt = s_cnt;
375	bcs->tx_cnt -= bcs->tx_skb->len;
376	bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
377	return(0);
378}
379
380static void got_frame(struct BCState *bcs, int count) {
381	struct sk_buff *skb;
382
383	if (!(skb = dev_alloc_skb(count)))
384		printk(KERN_WARNING "TIGER: receive out of memory\n");
385	else {
386		memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count);
387		skb_queue_tail(&bcs->rqueue, skb);
388	}
389	test_and_set_bit(B_RCVBUFREADY, &bcs->event);
390	schedule_work(&bcs->tqueue);
391
392	if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME)
393		printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec");
394}
395
396
397
398static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
399	int i;
400	register u_char j;
401	register u_char val;
402	u_int  *pend = bcs->hw.tiger.rec +NETJET_DMA_RXSIZE -1;
403	register u_char state = bcs->hw.tiger.r_state;
404	register u_char r_one = bcs->hw.tiger.r_one;
405	register u_char r_val = bcs->hw.tiger.r_val;
406	register u_int bitcnt = bcs->hw.tiger.r_bitcnt;
407	u_int *p = buf;
408	int bits;
409	u_char mask;
410
411        if (bcs->mode == L1_MODE_HDLC) { // it's 64k
412		mask = 0xff;
413		bits = 8;
414	}
415	else { // it's 56K
416		mask = 0x7f;
417		bits = 7;
418	};
419	for (i=0;i<cnt;i++) {
420		val = bcs->channel ? ((*p>>8) & 0xff) : (*p & 0xff);
421		p++;
422		if (p > pend)
423			p = bcs->hw.tiger.rec;
424		if ((val & mask) == mask) {
425			state = HDLC_ZERO_SEARCH;
426			bcs->hw.tiger.r_tot++;
427			bitcnt = 0;
428			r_one = 0;
429			continue;
430		}
431		for (j=0;j<bits;j++) {
432			if (state == HDLC_ZERO_SEARCH) {
433				if (val & 1) {
434					r_one++;
435				} else {
436					r_one=0;
437					state= HDLC_FLAG_SEARCH;
438					if (bcs->cs->debug & L1_DEB_HSCX)
439						debugl1(bcs->cs,"tiger read_raw: zBit(%d,%d,%d) %x",
440							bcs->hw.tiger.r_tot,i,j,val);
441				}
442			} else if (state == HDLC_FLAG_SEARCH) {
443				if (val & 1) {
444					r_one++;
445					if (r_one>6) {
446						state=HDLC_ZERO_SEARCH;
447					}
448				} else {
449					if (r_one==6) {
450						bitcnt=0;
451						r_val=0;
452						state=HDLC_FLAG_FOUND;
453						if (bcs->cs->debug & L1_DEB_HSCX)
454							debugl1(bcs->cs,"tiger read_raw: flag(%d,%d,%d) %x",
455								bcs->hw.tiger.r_tot,i,j,val);
456					}
457					r_one=0;
458				}
459			} else if (state ==  HDLC_FLAG_FOUND) {
460				if (val & 1) {
461					r_one++;
462					if (r_one>6) {
463						state=HDLC_ZERO_SEARCH;
464					} else {
465						r_val >>= 1;
466						r_val |= 0x80;
467						bitcnt++;
468					}
469				} else {
470					if (r_one==6) {
471						bitcnt=0;
472						r_val=0;
473						r_one=0;
474						val >>= 1;
475						continue;
476					} else if (r_one!=5) {
477						r_val >>= 1;
478						r_val &= 0x7f;
479						bitcnt++;
480					}
481					r_one=0;
482				}
483				if ((state != HDLC_ZERO_SEARCH) &&
484					!(bitcnt & 7)) {
485					state=HDLC_FRAME_FOUND;
486					bcs->hw.tiger.r_fcs = PPP_INITFCS;
487					bcs->hw.tiger.rcvbuf[0] = r_val;
488					bcs->hw.tiger.r_fcs = PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
489					if (bcs->cs->debug & L1_DEB_HSCX)
490						debugl1(bcs->cs,"tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x",
491							bcs->hw.tiger.r_tot,i,j,r_val,val,
492							bcs->cs->hw.njet.irqstat0);
493				}
494			} else if (state ==  HDLC_FRAME_FOUND) {
495				if (val & 1) {
496					r_one++;
497					if (r_one>6) {
498						state=HDLC_ZERO_SEARCH;
499						bitcnt=0;
500					} else {
501						r_val >>= 1;
502						r_val |= 0x80;
503						bitcnt++;
504					}
505				} else {
506					if (r_one==6) {
507						r_val=0;
508						r_one=0;
509						bitcnt++;
510						if (bitcnt & 7) {
511							debugl1(bcs->cs, "tiger: frame not byte aligned");
512							state=HDLC_FLAG_SEARCH;
513							bcs->hw.tiger.r_err++;
514#ifdef ERROR_STATISTIC
515							bcs->err_inv++;
516#endif
517						} else {
518							if (bcs->cs->debug & L1_DEB_HSCX)
519								debugl1(bcs->cs,"tiger frame end(%d,%d): fcs(%x) i %x",
520									i,j,bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0);
521							if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) {
522								got_frame(bcs, (bitcnt>>3)-3);
523							} else {
524								if (bcs->cs->debug) {
525									debugl1(bcs->cs, "tiger FCS error");
526									printframe(bcs->cs, bcs->hw.tiger.rcvbuf,
527										(bitcnt>>3)-1, "rec");
528									bcs->hw.tiger.r_err++;
529								}
530#ifdef ERROR_STATISTIC
531							bcs->err_crc++;
532#endif
533							}
534							state=HDLC_FLAG_FOUND;
535						}
536						bitcnt=0;
537					} else if (r_one==5) {
538						val >>= 1;
539						r_one=0;
540						continue;
541					} else {
542						r_val >>= 1;
543						r_val &= 0x7f;
544						bitcnt++;
545					}
546					r_one=0;
547				}
548				if ((state == HDLC_FRAME_FOUND) &&
549					!(bitcnt & 7)) {
550					if ((bitcnt>>3)>=HSCX_BUFMAX) {
551						debugl1(bcs->cs, "tiger: frame too big");
552						r_val=0;
553						state=HDLC_FLAG_SEARCH;
554						bcs->hw.tiger.r_err++;
555#ifdef ERROR_STATISTIC
556						bcs->err_inv++;
557#endif
558					} else {
559						bcs->hw.tiger.rcvbuf[(bitcnt>>3)-1] = r_val;
560						bcs->hw.tiger.r_fcs =
561							PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
562					}
563				}
564			}
565			val >>= 1;
566		}
567		bcs->hw.tiger.r_tot++;
568	}
569	bcs->hw.tiger.r_state = state;
570	bcs->hw.tiger.r_one = r_one;
571	bcs->hw.tiger.r_val = r_val;
572	bcs->hw.tiger.r_bitcnt = bitcnt;
573}
574
575void read_tiger(struct IsdnCardState *cs) {
576	u_int *p;
577	int cnt = NETJET_DMA_RXSIZE/2;
578
579	if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) {
580		debugl1(cs,"tiger warn read double dma %x/%x",
581			cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
582#ifdef ERROR_STATISTIC
583		if (cs->bcs[0].mode)
584			cs->bcs[0].err_rdo++;
585		if (cs->bcs[1].mode)
586			cs->bcs[1].err_rdo++;
587#endif
588		return;
589	} else {
590		cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ;
591		cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ);
592	}
593	if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1)
594		p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1;
595	else
596		p = cs->bcs[0].hw.tiger.rec + cnt - 1;
597	if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))
598		read_raw(cs->bcs, p, cnt);
599
600	if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))
601		read_raw(cs->bcs + 1, p, cnt);
602	cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ;
603}
604
605static void write_raw(struct BCState *bcs, u_int *buf, int cnt);
606
607void netjet_fill_dma(struct BCState *bcs)
608{
609	register u_int *p, *sp;
610	register int cnt;
611
612	if (!bcs->tx_skb)
613		return;
614	if (bcs->cs->debug & L1_DEB_HSCX)
615		debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel,
616			bcs->Flag);
617	if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag))
618		return;
619	if (bcs->mode == L1_MODE_HDLC) { // it's 64k
620		if (make_raw_data(bcs))
621			return;
622	}
623	else { // it's 56k
624		if (make_raw_data_56k(bcs))
625			return;
626	};
627	if (bcs->cs->debug & L1_DEB_HSCX)
628		debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel,
629			bcs->Flag);
630	if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
631		write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
632	} else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {
633		p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));
634		sp = bcs->hw.tiger.sendp;
635		if (p == bcs->hw.tiger.s_end)
636			p = bcs->hw.tiger.send -1;
637		if (sp == bcs->hw.tiger.s_end)
638			sp = bcs->hw.tiger.send -1;
639		cnt = p - sp;
640		if (cnt <0) {
641			write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
642		} else {
643			p++;
644			cnt++;
645			if (p > bcs->hw.tiger.s_end)
646				p = bcs->hw.tiger.send;
647			p++;
648			cnt++;
649			if (p > bcs->hw.tiger.s_end)
650				p = bcs->hw.tiger.send;
651			write_raw(bcs, p, bcs->hw.tiger.free - cnt);
652		}
653	} else if (test_and_clear_bit(BC_FLG_EMPTY, &bcs->Flag)) {
654		p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));
655		cnt = bcs->hw.tiger.s_end - p;
656		if (cnt < 2) {
657			p = bcs->hw.tiger.send + 1;
658			cnt = NETJET_DMA_TXSIZE/2 - 2;
659		} else {
660			p++;
661			p++;
662			if (cnt <= (NETJET_DMA_TXSIZE/2))
663				cnt += NETJET_DMA_TXSIZE/2;
664			cnt--;
665			cnt--;
666		}
667		write_raw(bcs, p, cnt);
668	}
669	if (bcs->cs->debug & L1_DEB_HSCX)
670		debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel,
671			bcs->Flag);
672}
673
674static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
675	u_int mask, val, *p=buf;
676	u_int i, s_cnt;
677
678        if (cnt <= 0)
679        	return;
680	if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {
681		if (bcs->hw.tiger.sendcnt> cnt) {
682			s_cnt = cnt;
683			bcs->hw.tiger.sendcnt -= cnt;
684		} else {
685			s_cnt = bcs->hw.tiger.sendcnt;
686			bcs->hw.tiger.sendcnt = 0;
687		}
688		if (bcs->channel)
689			mask = 0xffff00ff;
690		else
691			mask = 0xffffff00;
692		for (i=0; i<s_cnt; i++) {
693			val = bcs->channel ? ((bcs->hw.tiger.sp[i] <<8) & 0xff00) :
694				(bcs->hw.tiger.sp[i]);
695			*p   &= mask;
696			*p++ |= val;
697			if (p>bcs->hw.tiger.s_end)
698				p = bcs->hw.tiger.send;
699		}
700		bcs->hw.tiger.s_tot += s_cnt;
701		if (bcs->cs->debug & L1_DEB_HSCX)
702			debugl1(bcs->cs,"tiger write_raw: c%d %p-%p %d/%d %d %x", bcs->channel,
703				buf, p, s_cnt, cnt,
704				bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0);
705		if (bcs->cs->debug & L1_DEB_HSCX_FIFO)
706			printframe(bcs->cs, bcs->hw.tiger.sp, s_cnt, "snd");
707		bcs->hw.tiger.sp += s_cnt;
708		bcs->hw.tiger.sendp = p;
709		if (!bcs->hw.tiger.sendcnt) {
710			if (!bcs->tx_skb) {
711				debugl1(bcs->cs,"tiger write_raw: NULL skb s_cnt %d", s_cnt);
712			} else {
713				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
714					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
715					u_long	flags;
716					spin_lock_irqsave(&bcs->aclock, flags);
717					bcs->ackcnt += bcs->tx_skb->len;
718					spin_unlock_irqrestore(&bcs->aclock, flags);
719					schedule_event(bcs, B_ACKPENDING);
720				}
721				dev_kfree_skb_any(bcs->tx_skb);
722				bcs->tx_skb = NULL;
723			}
724			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
725			bcs->hw.tiger.free = cnt - s_cnt;
726			if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE/2))
727				test_and_set_bit(BC_FLG_HALF, &bcs->Flag);
728			else {
729				test_and_clear_bit(BC_FLG_HALF, &bcs->Flag);
730				test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag);
731			}
732			if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
733				netjet_fill_dma(bcs);
734			} else {
735				mask ^= 0xffffffff;
736				if (s_cnt < cnt) {
737					for (i=s_cnt; i<cnt;i++) {
738						*p++ |= mask;
739						if (p>bcs->hw.tiger.s_end)
740							p = bcs->hw.tiger.send;
741					}
742					if (bcs->cs->debug & L1_DEB_HSCX)
743						debugl1(bcs->cs, "tiger write_raw: fill rest %d",
744							cnt - s_cnt);
745				}
746				test_and_set_bit(B_XMTBUFREADY, &bcs->event);
747				schedule_work(&bcs->tqueue);
748			}
749		}
750	} else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
751		test_and_set_bit(BC_FLG_HALF, &bcs->Flag);
752		fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
753		bcs->hw.tiger.free += cnt;
754		if (bcs->cs->debug & L1_DEB_HSCX)
755			debugl1(bcs->cs,"tiger write_raw: fill half");
756	} else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {
757		test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
758		fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
759		if (bcs->cs->debug & L1_DEB_HSCX)
760			debugl1(bcs->cs,"tiger write_raw: fill full");
761	}
762}
763
764void write_tiger(struct IsdnCardState *cs) {
765	u_int *p, cnt = NETJET_DMA_TXSIZE/2;
766
767	if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) {
768		debugl1(cs,"tiger warn write double dma %x/%x",
769			cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
770#ifdef ERROR_STATISTIC
771		if (cs->bcs[0].mode)
772			cs->bcs[0].err_tx++;
773		if (cs->bcs[1].mode)
774			cs->bcs[1].err_tx++;
775#endif
776		return;
777	} else {
778		cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE;
779		cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE);
780	}
781	if (cs->hw.njet.irqstat0  & NETJET_IRQM0_WRITE_1)
782		p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
783	else
784		p = cs->bcs[0].hw.tiger.send + cnt - 1;
785	if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))
786		write_raw(cs->bcs, p, cnt);
787	if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))
788		write_raw(cs->bcs + 1, p, cnt);
789	cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE;
790}
791
792static void
793tiger_l2l1(struct PStack *st, int pr, void *arg)
794{
795	struct BCState *bcs = st->l1.bcs;
796	struct sk_buff *skb = arg;
797	u_long flags;
798
799	switch (pr) {
800		case (PH_DATA | REQUEST):
801			spin_lock_irqsave(&bcs->cs->lock, flags);
802			if (bcs->tx_skb) {
803				skb_queue_tail(&bcs->squeue, skb);
804			} else {
805				bcs->tx_skb = skb;
806				bcs->cs->BC_Send_Data(bcs);
807			}
808			spin_unlock_irqrestore(&bcs->cs->lock, flags);
809			break;
810		case (PH_PULL | INDICATION):
811			spin_lock_irqsave(&bcs->cs->lock, flags);
812			if (bcs->tx_skb) {
813				printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n");
814			} else {
815				bcs->tx_skb = skb;
816				bcs->cs->BC_Send_Data(bcs);
817			}
818			spin_unlock_irqrestore(&bcs->cs->lock, flags);
819			break;
820		case (PH_PULL | REQUEST):
821			if (!bcs->tx_skb) {
822				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
823				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
824			} else
825				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
826			break;
827		case (PH_ACTIVATE | REQUEST):
828			spin_lock_irqsave(&bcs->cs->lock, flags);
829			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
830			mode_tiger(bcs, st->l1.mode, st->l1.bc);
831			/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
832			spin_unlock_irqrestore(&bcs->cs->lock, flags);
833			bcs->cs->cardmsg(bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc));
834			l1_msg_b(st, pr, arg);
835			break;
836		case (PH_DEACTIVATE | REQUEST):
837			/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
838			bcs->cs->cardmsg(bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc));
839			l1_msg_b(st, pr, arg);
840			break;
841		case (PH_DEACTIVATE | CONFIRM):
842			spin_lock_irqsave(&bcs->cs->lock, flags);
843			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
844			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
845			mode_tiger(bcs, 0, st->l1.bc);
846			spin_unlock_irqrestore(&bcs->cs->lock, flags);
847			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
848			break;
849	}
850}
851
852
853static void
854close_tigerstate(struct BCState *bcs)
855{
856	mode_tiger(bcs, 0, bcs->channel);
857	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
858		kfree(bcs->hw.tiger.rcvbuf);
859		bcs->hw.tiger.rcvbuf = NULL;
860		kfree(bcs->hw.tiger.sendbuf);
861		bcs->hw.tiger.sendbuf = NULL;
862		skb_queue_purge(&bcs->rqueue);
863		skb_queue_purge(&bcs->squeue);
864		if (bcs->tx_skb) {
865			dev_kfree_skb_any(bcs->tx_skb);
866			bcs->tx_skb = NULL;
867			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
868		}
869	}
870}
871
872static int
873open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs)
874{
875	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
876		if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
877			printk(KERN_WARNING
878			       "HiSax: No memory for tiger.rcvbuf\n");
879			return (1);
880		}
881		if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) {
882			printk(KERN_WARNING
883			       "HiSax: No memory for tiger.sendbuf\n");
884			return (1);
885		}
886		skb_queue_head_init(&bcs->rqueue);
887		skb_queue_head_init(&bcs->squeue);
888	}
889	bcs->tx_skb = NULL;
890	bcs->hw.tiger.sendcnt = 0;
891	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
892	bcs->event = 0;
893	bcs->tx_cnt = 0;
894	return (0);
895}
896
897static int
898setstack_tiger(struct PStack *st, struct BCState *bcs)
899{
900	bcs->channel = st->l1.bc;
901	if (open_tigerstate(st->l1.hardware, bcs))
902		return (-1);
903	st->l1.bcs = bcs;
904	st->l2.l2l1 = tiger_l2l1;
905	setstack_manager(st);
906	bcs->st = st;
907	setstack_l1_B(st);
908	return (0);
909}
910
911
912void
913inittiger(struct IsdnCardState *cs)
914{
915	if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int),
916		GFP_KERNEL | GFP_DMA))) {
917		printk(KERN_WARNING
918		       "HiSax: No memory for tiger.send\n");
919		return;
920	}
921	cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE/2 - 1;
922	cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
923	cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send;
924	cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq;
925	cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end;
926
927	memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int));
928	debugl1(cs, "tiger: send buf %p - %p", cs->bcs[0].hw.tiger.send,
929		cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1);
930	outl(virt_to_bus(cs->bcs[0].hw.tiger.send),
931		cs->hw.njet.base + NETJET_DMA_READ_START);
932	outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq),
933		cs->hw.njet.base + NETJET_DMA_READ_IRQ);
934	outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end),
935		cs->hw.njet.base + NETJET_DMA_READ_END);
936	if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_RXSIZE * sizeof(unsigned int),
937		GFP_KERNEL | GFP_DMA))) {
938		printk(KERN_WARNING
939		       "HiSax: No memory for tiger.rec\n");
940		return;
941	}
942	debugl1(cs, "tiger: rec buf %p - %p", cs->bcs[0].hw.tiger.rec,
943		cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1);
944	cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec;
945	memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int));
946	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec),
947		cs->hw.njet.base + NETJET_DMA_WRITE_START);
948	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE/2 - 1),
949		cs->hw.njet.base + NETJET_DMA_WRITE_IRQ);
950	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1),
951		cs->hw.njet.base + NETJET_DMA_WRITE_END);
952	debugl1(cs, "tiger: dmacfg  %x/%x  pulse=%d",
953		inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
954		inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
955		bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
956	cs->hw.njet.last_is0 = 0;
957	cs->bcs[0].BC_SetStack = setstack_tiger;
958	cs->bcs[1].BC_SetStack = setstack_tiger;
959	cs->bcs[0].BC_Close = close_tigerstate;
960	cs->bcs[1].BC_Close = close_tigerstate;
961}
962
963static void
964releasetiger(struct IsdnCardState *cs)
965{
966	kfree(cs->bcs[0].hw.tiger.send);
967	cs->bcs[0].hw.tiger.send = NULL;
968	cs->bcs[1].hw.tiger.send = NULL;
969	kfree(cs->bcs[0].hw.tiger.rec);
970	cs->bcs[0].hw.tiger.rec = NULL;
971	cs->bcs[1].hw.tiger.rec = NULL;
972}
973
974void
975release_io_netjet(struct IsdnCardState *cs)
976{
977	byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
978	byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
979	releasetiger(cs);
980	release_region(cs->hw.njet.base, 256);
981}
982