OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [isdn/] [hisax/] [netjet.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.