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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [isdn/] [avmb1/] [b1dma.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: b1dma.c,v 1.1.1.1 2004-04-15 02:04:06 phoenix Exp $
2
 *
3
 * Common module for AVM B1 cards that support dma with AMCC
4
 *
5
 * Copyright 2000 by Carsten Paeth <calle@calle.de>
6
 *
7
 * This software may be used and distributed according to the terms
8
 * of the GNU General Public License, incorporated herein by reference.
9
 *
10
 */
11
 
12
#include <linux/config.h>
13
#include <linux/module.h>
14
#include <linux/kernel.h>
15
#include <linux/skbuff.h>
16
#include <linux/delay.h>
17
#include <linux/mm.h>
18
#include <linux/interrupt.h>
19
#include <linux/ioport.h>
20
#include <linux/capi.h>
21
#include <linux/kernelcapi.h>
22
#include <asm/io.h>
23
#include <linux/init.h>
24
#include <asm/uaccess.h>
25
#include <linux/netdevice.h>
26
#include "capilli.h"
27
#include "avmcard.h"
28
#include "capicmd.h"
29
#include "capiutil.h"
30
 
31
static char *revision = "$Revision: 1.1.1.1 $";
32
 
33
/* ------------------------------------------------------------- */
34
 
35
MODULE_DESCRIPTION("CAPI4Linux: DMA support for active AVM cards");
36
MODULE_AUTHOR("Carsten Paeth");
37
MODULE_LICENSE("GPL");
38
 
39
static int suppress_pollack = 0;
40
MODULE_PARM(suppress_pollack, "0-1i");
41
 
42
/* ------------------------------------------------------------- */
43
 
44
static void b1dma_dispatch_tx(avmcard *card);
45
 
46
/* ------------------------------------------------------------- */
47
 
48
/* S5933 */
49
 
50
#define AMCC_RXPTR      0x24
51
#define AMCC_RXLEN      0x28
52
#define AMCC_TXPTR      0x2c
53
#define AMCC_TXLEN      0x30
54
 
55
#define AMCC_INTCSR     0x38
56
#       define EN_READ_TC_INT           0x00008000L
57
#       define EN_WRITE_TC_INT          0x00004000L
58
#       define EN_TX_TC_INT             EN_READ_TC_INT
59
#       define EN_RX_TC_INT             EN_WRITE_TC_INT
60
#       define AVM_FLAG                 0x30000000L
61
 
62
#       define ANY_S5933_INT            0x00800000L
63
#       define  READ_TC_INT             0x00080000L
64
#       define WRITE_TC_INT             0x00040000L
65
#       define  TX_TC_INT               READ_TC_INT
66
#       define  RX_TC_INT               WRITE_TC_INT
67
#       define MASTER_ABORT_INT         0x00100000L
68
#       define TARGET_ABORT_INT         0x00200000L
69
#       define BUS_MASTER_INT           0x00200000L
70
#       define ALL_INT                  0x000C0000L
71
 
72
#define AMCC_MCSR       0x3c
73
#       define A2P_HI_PRIORITY          0x00000100L
74
#       define EN_A2P_TRANSFERS         0x00000400L
75
#       define P2A_HI_PRIORITY          0x00001000L
76
#       define EN_P2A_TRANSFERS         0x00004000L
77
#       define RESET_A2P_FLAGS          0x04000000L
78
#       define RESET_P2A_FLAGS          0x02000000L
79
 
80
/* ------------------------------------------------------------- */
81
 
82
#define b1dmaoutmeml(addr, value)       writel(value, addr)
83
#define b1dmainmeml(addr)       readl(addr)
84
#define b1dmaoutmemw(addr, value)       writew(value, addr)
85
#define b1dmainmemw(addr)       readw(addr)
86
#define b1dmaoutmemb(addr, value)       writeb(value, addr)
87
#define b1dmainmemb(addr)       readb(addr)
88
 
89
/* ------------------------------------------------------------- */
90
 
91
static inline int b1dma_tx_empty(unsigned int port)
92
{
93
        return inb(port + 0x03) & 0x1;
94
}
95
 
96
static inline int b1dma_rx_full(unsigned int port)
97
{
98
        return inb(port + 0x02) & 0x1;
99
}
100
 
101
static int b1dma_tolink(avmcard *card, void *buf, unsigned int len)
102
{
103
        unsigned long stop = jiffies + 1 * HZ;  /* maximum wait time 1 sec */
104
        unsigned char *s = (unsigned char *)buf;
105
        while (len--) {
106
                while (   !b1dma_tx_empty(card->port)
107
                       && time_before(jiffies, stop));
108
                if (!b1dma_tx_empty(card->port))
109
                        return -1;
110
                t1outp(card->port, 0x01, *s++);
111
        }
112
        return 0;
113
}
114
 
115
static int b1dma_fromlink(avmcard *card, void *buf, unsigned int len)
116
{
117
        unsigned long stop = jiffies + 1 * HZ;  /* maximum wait time 1 sec */
118
        unsigned char *s = (unsigned char *)buf;
119
        while (len--) {
120
                while (   !b1dma_rx_full(card->port)
121
                       && time_before(jiffies, stop));
122
                if (!b1dma_rx_full(card->port))
123
                        return -1;
124
                *s++ = t1inp(card->port, 0x00);
125
        }
126
        return 0;
127
}
128
 
129
static int WriteReg(avmcard *card, __u32 reg, __u8 val)
130
{
131
        __u8 cmd = 0x00;
132
        if (   b1dma_tolink(card, &cmd, 1) == 0
133
            && b1dma_tolink(card, &reg, 4) == 0) {
134
                __u32 tmp = val;
135
                return b1dma_tolink(card, &tmp, 4);
136
        }
137
        return -1;
138
}
139
 
140
static __u8 ReadReg(avmcard *card, __u32 reg)
141
{
142
        __u8 cmd = 0x01;
143
        if (   b1dma_tolink(card, &cmd, 1) == 0
144
            && b1dma_tolink(card, &reg, 4) == 0) {
145
                __u32 tmp;
146
                if (b1dma_fromlink(card, &tmp, 4) == 0)
147
                        return (__u8)tmp;
148
        }
149
        return 0xff;
150
}
151
 
152
/* ------------------------------------------------------------- */
153
 
154
static inline void _put_byte(void **pp, __u8 val)
155
{
156
        __u8 *s = *pp;
157
        *s++ = val;
158
        *pp = s;
159
}
160
 
161
static inline void _put_word(void **pp, __u32 val)
162
{
163
        __u8 *s = *pp;
164
        *s++ = val & 0xff;
165
        *s++ = (val >> 8) & 0xff;
166
        *s++ = (val >> 16) & 0xff;
167
        *s++ = (val >> 24) & 0xff;
168
        *pp = s;
169
}
170
 
171
static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len)
172
{
173
        unsigned i = len;
174
        _put_word(pp, i);
175
        while (i-- > 0)
176
                _put_byte(pp, *dp++);
177
}
178
 
179
static inline __u8 _get_byte(void **pp)
180
{
181
        __u8 *s = *pp;
182
        __u8 val;
183
        val = *s++;
184
        *pp = s;
185
        return val;
186
}
187
 
188
static inline __u32 _get_word(void **pp)
189
{
190
        __u8 *s = *pp;
191
        __u32 val;
192
        val = *s++;
193
        val |= (*s++ << 8);
194
        val |= (*s++ << 16);
195
        val |= (*s++ << 24);
196
        *pp = s;
197
        return val;
198
}
199
 
200
static inline __u32 _get_slice(void **pp, unsigned char *dp)
201
{
202
        unsigned int len, i;
203
 
204
        len = i = _get_word(pp);
205
        while (i-- > 0) *dp++ = _get_byte(pp);
206
        return len;
207
}
208
 
209
/* ------------------------------------------------------------- */
210
 
211
void b1dma_reset(avmcard *card)
212
{
213
        unsigned long flags;
214
 
215
        save_flags(flags);
216
        cli();
217
        card->csr = 0x0;
218
        b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
219
        b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
220
        b1dmaoutmeml(card->mbase+AMCC_RXLEN, 0);
221
        b1dmaoutmeml(card->mbase+AMCC_TXLEN, 0);
222
 
223
        t1outp(card->port, 0x10, 0x00);
224
        t1outp(card->port, 0x07, 0x00);
225
 
226
        restore_flags(flags);
227
 
228
        b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
229
        mdelay(10);
230
        b1dmaoutmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */
231
        mdelay(10);
232
        b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
233
        if (card->cardtype == avm_t1pci)
234
                mdelay(42);
235
        else
236
                mdelay(10);
237
}
238
 
239
/* ------------------------------------------------------------- */
240
 
241
int b1dma_detect(avmcard *card)
242
{
243
        b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
244
        mdelay(10);
245
        b1dmaoutmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */
246
        mdelay(10);
247
        b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
248
        mdelay(42);
249
 
250
        b1dmaoutmeml(card->mbase+AMCC_RXLEN, 0);
251
        b1dmaoutmeml(card->mbase+AMCC_TXLEN, 0);
252
        card->csr = 0x0;
253
        b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
254
 
255
        if (b1dmainmeml(card->mbase+AMCC_MCSR) != 0x000000E6)
256
                return 1;
257
 
258
        b1dmaoutmeml(card->mbase+AMCC_RXPTR, 0xffffffff);
259
        b1dmaoutmeml(card->mbase+AMCC_TXPTR, 0xffffffff);
260
        if (   b1dmainmeml(card->mbase+AMCC_RXPTR) != 0xfffffffc
261
            || b1dmainmeml(card->mbase+AMCC_TXPTR) != 0xfffffffc)
262
                return 2;
263
 
264
        b1dmaoutmeml(card->mbase+AMCC_RXPTR, 0x0);
265
        b1dmaoutmeml(card->mbase+AMCC_TXPTR, 0x0);
266
        if (   b1dmainmeml(card->mbase+AMCC_RXPTR) != 0x0
267
            || b1dmainmeml(card->mbase+AMCC_TXPTR) != 0x0)
268
                return 3;
269
 
270
        t1outp(card->port, 0x10, 0x00);
271
        t1outp(card->port, 0x07, 0x00);
272
 
273
        t1outp(card->port, 0x02, 0x02);
274
        t1outp(card->port, 0x03, 0x02);
275
 
276
        if (   (t1inp(card->port, 0x02) & 0xFE) != 0x02
277
            || t1inp(card->port, 0x3) != 0x03)
278
                return 4;
279
 
280
        t1outp(card->port, 0x02, 0x00);
281
        t1outp(card->port, 0x03, 0x00);
282
 
283
        if (   (t1inp(card->port, 0x02) & 0xFE) != 0x00
284
            || t1inp(card->port, 0x3) != 0x01)
285
                return 5;
286
 
287
        return 0;
288
}
289
 
290
int t1pci_detect(avmcard *card)
291
{
292
        int ret;
293
 
294
        if ((ret = b1dma_detect(card)) != 0)
295
                return ret;
296
 
297
        /* Transputer test */
298
 
299
        if (   WriteReg(card, 0x80001000, 0x11) != 0
300
            || WriteReg(card, 0x80101000, 0x22) != 0
301
            || WriteReg(card, 0x80201000, 0x33) != 0
302
            || WriteReg(card, 0x80301000, 0x44) != 0)
303
                return 6;
304
 
305
        if (   ReadReg(card, 0x80001000) != 0x11
306
            || ReadReg(card, 0x80101000) != 0x22
307
            || ReadReg(card, 0x80201000) != 0x33
308
            || ReadReg(card, 0x80301000) != 0x44)
309
                return 7;
310
 
311
        if (   WriteReg(card, 0x80001000, 0x55) != 0
312
            || WriteReg(card, 0x80101000, 0x66) != 0
313
            || WriteReg(card, 0x80201000, 0x77) != 0
314
            || WriteReg(card, 0x80301000, 0x88) != 0)
315
                return 8;
316
 
317
        if (   ReadReg(card, 0x80001000) != 0x55
318
            || ReadReg(card, 0x80101000) != 0x66
319
            || ReadReg(card, 0x80201000) != 0x77
320
            || ReadReg(card, 0x80301000) != 0x88)
321
                return 9;
322
 
323
        return 0;
324
}
325
 
326
int b1pciv4_detect(avmcard *card)
327
{
328
        int ret, i;
329
 
330
        if ((ret = b1dma_detect(card)) != 0)
331
                return ret;
332
 
333
        for (i=0; i < 5 ; i++) {
334
                if (WriteReg(card, 0x80A00000, 0x21) != 0)
335
                        return 6;
336
                if ((ReadReg(card, 0x80A00000) & 0x01) != 0x01)
337
                        return 7;
338
        }
339
        for (i=0; i < 5 ; i++) {
340
                if (WriteReg(card, 0x80A00000, 0x20) != 0)
341
                        return 8;
342
                if ((ReadReg(card, 0x80A00000) & 0x01) != 0x00)
343
                        return 9;
344
        }
345
 
346
        return 0;
347
}
348
 
349
/* ------------------------------------------------------------- */
350
 
351
static void b1dma_dispatch_tx(avmcard *card)
352
{
353
        avmcard_dmainfo *dma = card->dma;
354
        unsigned long flags;
355
        struct sk_buff *skb;
356
        __u8 cmd, subcmd;
357
        __u16 len;
358
        __u32 txlen;
359
        int inint;
360
        void *p;
361
 
362
        save_flags(flags);
363
        cli();
364
 
365
        inint = card->interrupt;
366
 
367
        if (card->csr & EN_TX_TC_INT) { /* tx busy */
368
                restore_flags(flags);
369
                return;
370
        }
371
 
372
        skb = skb_dequeue(&dma->send_queue);
373
        if (!skb) {
374
#ifdef CONFIG_B1DMA_DEBUG
375
                printk(KERN_DEBUG "tx(%d): underrun\n", inint);
376
#endif
377
                restore_flags(flags);
378
                return;
379
        }
380
 
381
        len = CAPIMSG_LEN(skb->data);
382
 
383
        if (len) {
384
                cmd = CAPIMSG_COMMAND(skb->data);
385
                subcmd = CAPIMSG_SUBCOMMAND(skb->data);
386
 
387
                p = dma->sendbuf;
388
 
389
                if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
390
                        __u16 dlen = CAPIMSG_DATALEN(skb->data);
391
                        _put_byte(&p, SEND_DATA_B3_REQ);
392
                        _put_slice(&p, skb->data, len);
393
                        _put_slice(&p, skb->data + len, dlen);
394
                } else {
395
                        _put_byte(&p, SEND_MESSAGE);
396
                        _put_slice(&p, skb->data, len);
397
                }
398
                txlen = (__u8 *)p - (__u8 *)dma->sendbuf;
399
#ifdef CONFIG_B1DMA_DEBUG
400
                printk(KERN_DEBUG "tx(%d): put msg len=%d\n",
401
                                inint, txlen);
402
#endif
403
        } else {
404
                txlen = skb->len-2;
405
#ifdef CONFIG_B1DMA_POLLDEBUG
406
                if (skb->data[2] == SEND_POLLACK)
407
                        printk(KERN_INFO "%s: send ack\n", card->name);
408
#endif
409
#ifdef CONFIG_B1DMA_DEBUG
410
                printk(KERN_DEBUG "tx(%d): put 0x%x len=%d\n",
411
                                inint, skb->data[2], txlen);
412
#endif
413
                memcpy(dma->sendbuf, skb->data+2, skb->len-2);
414
        }
415
        txlen = (txlen + 3) & ~3;
416
 
417
        b1dmaoutmeml(card->mbase+AMCC_TXPTR, virt_to_phys(dma->sendbuf));
418
        b1dmaoutmeml(card->mbase+AMCC_TXLEN, txlen);
419
 
420
        card->csr |= EN_TX_TC_INT;
421
 
422
        if (!inint)
423
                b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
424
 
425
        restore_flags(flags);
426
        dev_kfree_skb_any(skb);
427
}
428
 
429
/* ------------------------------------------------------------- */
430
 
431
static void queue_pollack(avmcard *card)
432
{
433
        struct sk_buff *skb;
434
        void *p;
435
 
436
        skb = alloc_skb(3, GFP_ATOMIC);
437
        if (!skb) {
438
                printk(KERN_CRIT "%s: no memory, lost poll ack\n",
439
                                        card->name);
440
                return;
441
        }
442
        p = skb->data;
443
        _put_byte(&p, 0);
444
        _put_byte(&p, 0);
445
        _put_byte(&p, SEND_POLLACK);
446
        skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
447
 
448
        skb_queue_tail(&card->dma->send_queue, skb);
449
        b1dma_dispatch_tx(card);
450
}
451
 
452
/* ------------------------------------------------------------- */
453
 
454
static void b1dma_handle_rx(avmcard *card)
455
{
456
        avmctrl_info *cinfo = &card->ctrlinfo[0];
457
        avmcard_dmainfo *dma = card->dma;
458
        struct capi_ctr *ctrl = cinfo->capi_ctrl;
459
        struct sk_buff *skb;
460
        void *p = dma->recvbuf+4;
461
        __u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
462
        __u8 b1cmd =  _get_byte(&p);
463
 
464
#ifdef CONFIG_B1DMA_DEBUG
465
        printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen);
466
#endif
467
 
468
        switch (b1cmd) {
469
        case RECEIVE_DATA_B3_IND:
470
 
471
                ApplId = (unsigned) _get_word(&p);
472
                MsgLen = _get_slice(&p, card->msgbuf);
473
                DataB3Len = _get_slice(&p, card->databuf);
474
 
475
                if (MsgLen < 30) { /* not CAPI 64Bit */
476
                        memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
477
                        MsgLen = 30;
478
                        CAPIMSG_SETLEN(card->msgbuf, 30);
479
                }
480
                if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
481
                        printk(KERN_ERR "%s: incoming packet dropped\n",
482
                                        card->name);
483
                } else {
484
                        memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
485
                        memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
486
                        ctrl->handle_capimsg(ctrl, ApplId, skb);
487
                }
488
                break;
489
 
490
        case RECEIVE_MESSAGE:
491
 
492
                ApplId = (unsigned) _get_word(&p);
493
                MsgLen = _get_slice(&p, card->msgbuf);
494
                if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
495
                        printk(KERN_ERR "%s: incoming packet dropped\n",
496
                                        card->name);
497
                } else {
498
                        memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
499
                        ctrl->handle_capimsg(ctrl, ApplId, skb);
500
                }
501
                break;
502
 
503
        case RECEIVE_NEW_NCCI:
504
 
505
                ApplId = _get_word(&p);
506
                NCCI = _get_word(&p);
507
                WindowSize = _get_word(&p);
508
 
509
                ctrl->new_ncci(ctrl, ApplId, NCCI, WindowSize);
510
 
511
                break;
512
 
513
        case RECEIVE_FREE_NCCI:
514
 
515
                ApplId = _get_word(&p);
516
                NCCI = _get_word(&p);
517
 
518
                if (NCCI != 0xffffffff)
519
                        ctrl->free_ncci(ctrl, ApplId, NCCI);
520
                else ctrl->appl_released(ctrl, ApplId);
521
                break;
522
 
523
        case RECEIVE_START:
524
#ifdef CONFIG_B1DMA_POLLDEBUG
525
                printk(KERN_INFO "%s: receive poll\n", card->name);
526
#endif
527
                if (!suppress_pollack)
528
                        queue_pollack(card);
529
                ctrl->resume_output(ctrl);
530
                break;
531
 
532
        case RECEIVE_STOP:
533
                ctrl->suspend_output(ctrl);
534
                break;
535
 
536
        case RECEIVE_INIT:
537
 
538
                cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);
539
                b1_parse_version(cinfo);
540
                printk(KERN_INFO "%s: %s-card (%s) now active\n",
541
                       card->name,
542
                       cinfo->version[VER_CARDTYPE],
543
                       cinfo->version[VER_DRIVER]);
544
                ctrl->ready(ctrl);
545
                break;
546
 
547
        case RECEIVE_TASK_READY:
548
                ApplId = (unsigned) _get_word(&p);
549
                MsgLen = _get_slice(&p, card->msgbuf);
550
                card->msgbuf[MsgLen] = 0;
551
                while (    MsgLen > 0
552
                       && (   card->msgbuf[MsgLen-1] == '\n'
553
                           || card->msgbuf[MsgLen-1] == '\r')) {
554
                        card->msgbuf[MsgLen-1] = 0;
555
                        MsgLen--;
556
                }
557
                printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
558
                                card->name, ApplId, card->msgbuf);
559
                break;
560
 
561
        case RECEIVE_DEBUGMSG:
562
                MsgLen = _get_slice(&p, card->msgbuf);
563
                card->msgbuf[MsgLen] = 0;
564
                while (    MsgLen > 0
565
                       && (   card->msgbuf[MsgLen-1] == '\n'
566
                           || card->msgbuf[MsgLen-1] == '\r')) {
567
                        card->msgbuf[MsgLen-1] = 0;
568
                        MsgLen--;
569
                }
570
                printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
571
                break;
572
 
573
        default:
574
                printk(KERN_ERR "%s: b1dma_interrupt: 0x%x ???\n",
575
                                card->name, b1cmd);
576
                return;
577
        }
578
}
579
 
580
/* ------------------------------------------------------------- */
581
 
582
static void b1dma_handle_interrupt(avmcard *card)
583
{
584
        __u32 status = b1dmainmeml(card->mbase+AMCC_INTCSR);
585
        __u32 newcsr;
586
 
587
        if ((status & ANY_S5933_INT) == 0)
588
                return;
589
 
590
        newcsr = card->csr | (status & ALL_INT);
591
        if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
592
        if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
593
        b1dmaoutmeml(card->mbase+AMCC_INTCSR, newcsr);
594
 
595
        if ((status & RX_TC_INT) != 0) {
596
                __u8 *recvbuf = card->dma->recvbuf;
597
                __u32 rxlen;
598
                if (card->dma->recvlen == 0) {
599
                        card->dma->recvlen = *((__u32 *)recvbuf);
600
                        rxlen = (card->dma->recvlen + 3) & ~3;
601
                        b1dmaoutmeml(card->mbase+AMCC_RXPTR,
602
                                        virt_to_phys(recvbuf+4));
603
                        b1dmaoutmeml(card->mbase+AMCC_RXLEN, rxlen);
604
                } else {
605
                        b1dma_handle_rx(card);
606
                        card->dma->recvlen = 0;
607
                        b1dmaoutmeml(card->mbase+AMCC_RXPTR, virt_to_phys(recvbuf));
608
                        b1dmaoutmeml(card->mbase+AMCC_RXLEN, 4);
609
                }
610
        }
611
 
612
        if ((status & TX_TC_INT) != 0) {
613
                card->csr &= ~EN_TX_TC_INT;
614
                b1dma_dispatch_tx(card);
615
        }
616
        b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
617
}
618
 
619
void b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
620
{
621
        avmcard *card;
622
 
623
        card = (avmcard *) devptr;
624
 
625
        if (!card) {
626
                printk(KERN_WARNING "b1dma: interrupt: wrong device\n");
627
                return;
628
        }
629
        if (card->interrupt) {
630
                printk(KERN_ERR "%s: reentering interrupt hander\n", card->name);
631
                return;
632
        }
633
 
634
        card->interrupt = 1;
635
 
636
        b1dma_handle_interrupt(card);
637
 
638
        card->interrupt = 0;
639
}
640
 
641
/* ------------------------------------------------------------- */
642
 
643
static int b1dma_loaded(avmcard *card)
644
{
645
        unsigned long stop;
646
        unsigned char ans;
647
        unsigned long tout = 2;
648
        unsigned int base = card->port;
649
 
650
        for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
651
                if (b1_tx_empty(base))
652
                        break;
653
        }
654
        if (!b1_tx_empty(base)) {
655
                printk(KERN_ERR "%s: b1dma_loaded: tx err, corrupted t4 file ?\n",
656
                                card->name);
657
                return 0;
658
        }
659
        b1_put_byte(base, SEND_POLLACK);
660
        for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
661
                if (b1_rx_full(base)) {
662
                        if ((ans = b1_get_byte(base)) == RECEIVE_POLLDWORD) {
663
                                return 1;
664
                        }
665
                        printk(KERN_ERR "%s: b1dma_loaded: got 0x%x, firmware not running in dword mode\n", card->name, ans);
666
                        return 0;
667
                }
668
        }
669
        printk(KERN_ERR "%s: b1dma_loaded: firmware not running\n", card->name);
670
        return 0;
671
}
672
 
673
/* ------------------------------------------------------------- */
674
 
675
static void b1dma_send_init(avmcard *card)
676
{
677
        struct sk_buff *skb;
678
        void *p;
679
 
680
        skb = alloc_skb(15, GFP_ATOMIC);
681
        if (!skb) {
682
                printk(KERN_CRIT "%s: no memory, lost register appl.\n",
683
                                        card->name);
684
                return;
685
        }
686
        p = skb->data;
687
        _put_byte(&p, 0);
688
        _put_byte(&p, 0);
689
        _put_byte(&p, SEND_INIT);
690
        _put_word(&p, CAPI_MAXAPPL);
691
        _put_word(&p, AVM_NCCI_PER_CHANNEL*30);
692
        _put_word(&p, card->cardnr - 1);
693
        skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
694
 
695
        skb_queue_tail(&card->dma->send_queue, skb);
696
        b1dma_dispatch_tx(card);
697
}
698
 
699
int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
700
{
701
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
702
        avmcard *card = cinfo->card;
703
        unsigned long flags;
704
        int retval;
705
 
706
        b1dma_reset(card);
707
 
708
        if ((retval = b1_load_t4file(card, &data->firmware))) {
709
                b1dma_reset(card);
710
                printk(KERN_ERR "%s: failed to load t4file!!\n",
711
                                        card->name);
712
                return retval;
713
        }
714
 
715
        if (data->configuration.len > 0 && data->configuration.data) {
716
                if ((retval = b1_load_config(card, &data->configuration))) {
717
                        b1dma_reset(card);
718
                        printk(KERN_ERR "%s: failed to load config!!\n",
719
                                        card->name);
720
                        return retval;
721
                }
722
        }
723
 
724
        if (!b1dma_loaded(card)) {
725
                b1dma_reset(card);
726
                printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
727
                return -EIO;
728
        }
729
 
730
        save_flags(flags);
731
        cli();
732
 
733
        card->csr = AVM_FLAG;
734
        b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
735
        b1dmaoutmeml(card->mbase+AMCC_MCSR,
736
                EN_A2P_TRANSFERS|EN_P2A_TRANSFERS
737
                |A2P_HI_PRIORITY|P2A_HI_PRIORITY
738
                |RESET_A2P_FLAGS|RESET_P2A_FLAGS);
739
        t1outp(card->port, 0x07, 0x30);
740
        t1outp(card->port, 0x10, 0xF0);
741
 
742
        card->dma->recvlen = 0;
743
        b1dmaoutmeml(card->mbase+AMCC_RXPTR, virt_to_phys(card->dma->recvbuf));
744
        b1dmaoutmeml(card->mbase+AMCC_RXLEN, 4);
745
        card->csr |= EN_RX_TC_INT;
746
        b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
747
        restore_flags(flags);
748
 
749
        b1dma_send_init(card);
750
 
751
        return 0;
752
}
753
 
754
void b1dma_reset_ctr(struct capi_ctr *ctrl)
755
{
756
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
757
        avmcard *card = cinfo->card;
758
 
759
        b1dma_reset(card);
760
 
761
        memset(cinfo->version, 0, sizeof(cinfo->version));
762
        ctrl->reseted(ctrl);
763
}
764
 
765
 
766
/* ------------------------------------------------------------- */
767
 
768
 
769
void b1dma_register_appl(struct capi_ctr *ctrl,
770
                                __u16 appl,
771
                                capi_register_params *rp)
772
{
773
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
774
        avmcard *card = cinfo->card;
775
        struct sk_buff *skb;
776
        int want = rp->level3cnt;
777
        int nconn;
778
        void *p;
779
 
780
        if (want > 0) nconn = want;
781
        else nconn = ctrl->profile.nbchannel * -want;
782
        if (nconn == 0) nconn = ctrl->profile.nbchannel;
783
 
784
        skb = alloc_skb(23, GFP_ATOMIC);
785
        if (!skb) {
786
                printk(KERN_CRIT "%s: no memory, lost register appl.\n",
787
                                        card->name);
788
                return;
789
        }
790
        p = skb->data;
791
        _put_byte(&p, 0);
792
        _put_byte(&p, 0);
793
        _put_byte(&p, SEND_REGISTER);
794
        _put_word(&p, appl);
795
        _put_word(&p, 1024 * (nconn+1));
796
        _put_word(&p, nconn);
797
        _put_word(&p, rp->datablkcnt);
798
        _put_word(&p, rp->datablklen);
799
        skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
800
 
801
        skb_queue_tail(&card->dma->send_queue, skb);
802
        b1dma_dispatch_tx(card);
803
 
804
        ctrl->appl_registered(ctrl, appl);
805
}
806
 
807
/* ------------------------------------------------------------- */
808
 
809
void b1dma_release_appl(struct capi_ctr *ctrl, __u16 appl)
810
{
811
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
812
        avmcard *card = cinfo->card;
813
        struct sk_buff *skb;
814
        void *p;
815
 
816
        skb = alloc_skb(7, GFP_ATOMIC);
817
        if (!skb) {
818
                printk(KERN_CRIT "%s: no memory, lost release appl.\n",
819
                                        card->name);
820
                return;
821
        }
822
        p = skb->data;
823
        _put_byte(&p, 0);
824
        _put_byte(&p, 0);
825
        _put_byte(&p, SEND_RELEASE);
826
        _put_word(&p, appl);
827
 
828
        skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
829
        skb_queue_tail(&card->dma->send_queue, skb);
830
        b1dma_dispatch_tx(card);
831
}
832
 
833
/* ------------------------------------------------------------- */
834
 
835
void b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
836
{
837
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
838
        avmcard *card = cinfo->card;
839
        skb_queue_tail(&card->dma->send_queue, skb);
840
        b1dma_dispatch_tx(card);
841
}
842
 
843
/* ------------------------------------------------------------- */
844
 
845
int b1dmactl_read_proc(char *page, char **start, off_t off,
846
                        int count, int *eof, struct capi_ctr *ctrl)
847
{
848
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
849
        avmcard *card = cinfo->card;
850
        unsigned long flags;
851
        __u8 flag;
852
        int len = 0;
853
        char *s;
854
        u_long txaddr, txlen, rxaddr, rxlen, csr;
855
 
856
        len += sprintf(page+len, "%-16s %s\n", "name", card->name);
857
        len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
858
        len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
859
        len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase);
860
        switch (card->cardtype) {
861
        case avm_b1isa: s = "B1 ISA"; break;
862
        case avm_b1pci: s = "B1 PCI"; break;
863
        case avm_b1pcmcia: s = "B1 PCMCIA"; break;
864
        case avm_m1: s = "M1"; break;
865
        case avm_m2: s = "M2"; break;
866
        case avm_t1isa: s = "T1 ISA (HEMA)"; break;
867
        case avm_t1pci: s = "T1 PCI"; break;
868
        case avm_c4: s = "C4"; break;
869
        case avm_c2: s = "C2"; break;
870
        default: s = "???"; break;
871
        }
872
        len += sprintf(page+len, "%-16s %s\n", "type", s);
873
        if ((s = cinfo->version[VER_DRIVER]) != 0)
874
           len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
875
        if ((s = cinfo->version[VER_CARDTYPE]) != 0)
876
           len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
877
        if ((s = cinfo->version[VER_SERIAL]) != 0)
878
           len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
879
 
880
        if (card->cardtype != avm_m1) {
881
                flag = ((__u8 *)(ctrl->profile.manu))[3];
882
                if (flag)
883
                        len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n",
884
                        "protocol",
885
                        (flag & 0x01) ? " DSS1" : "",
886
                        (flag & 0x02) ? " CT1" : "",
887
                        (flag & 0x04) ? " VN3" : "",
888
                        (flag & 0x08) ? " NI1" : "",
889
                        (flag & 0x10) ? " AUSTEL" : "",
890
                        (flag & 0x20) ? " ESS" : "",
891
                        (flag & 0x40) ? " 1TR6" : ""
892
                        );
893
        }
894
        if (card->cardtype != avm_m1) {
895
                flag = ((__u8 *)(ctrl->profile.manu))[5];
896
                if (flag)
897
                        len += sprintf(page+len, "%-16s%s%s%s%s\n",
898
                        "linetype",
899
                        (flag & 0x01) ? " point to point" : "",
900
                        (flag & 0x02) ? " point to multipoint" : "",
901
                        (flag & 0x08) ? " leased line without D-channel" : "",
902
                        (flag & 0x04) ? " leased line with D-channel" : ""
903
                        );
904
        }
905
        len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
906
 
907
        save_flags(flags);
908
        cli();
909
 
910
        txaddr = (u_long)phys_to_virt(b1dmainmeml(card->mbase+0x2c));
911
        txaddr -= (u_long)card->dma->sendbuf;
912
        txlen  = b1dmainmeml(card->mbase+0x30);
913
 
914
        rxaddr = (u_long)phys_to_virt(b1dmainmeml(card->mbase+0x24));
915
        rxaddr -= (u_long)card->dma->recvbuf;
916
        rxlen  = b1dmainmeml(card->mbase+0x28);
917
 
918
        csr  = b1dmainmeml(card->mbase+AMCC_INTCSR);
919
 
920
        restore_flags(flags);
921
 
922
        len += sprintf(page+len, "%-16s 0x%lx\n",
923
                                "csr (cached)", (unsigned long)card->csr);
924
        len += sprintf(page+len, "%-16s 0x%lx\n",
925
                                "csr", (unsigned long)csr);
926
        len += sprintf(page+len, "%-16s %lu\n",
927
                                "txoff", (unsigned long)txaddr);
928
        len += sprintf(page+len, "%-16s %lu\n",
929
                                "txlen", (unsigned long)txlen);
930
        len += sprintf(page+len, "%-16s %lu\n",
931
                                "rxoff", (unsigned long)rxaddr);
932
        len += sprintf(page+len, "%-16s %lu\n",
933
                                "rxlen", (unsigned long)rxlen);
934
 
935
        if (off+count >= len)
936
           *eof = 1;
937
        if (len < off)
938
           return 0;
939
        *start = page + off;
940
        return ((count < len-off) ? count : len-off);
941
}
942
 
943
/* ------------------------------------------------------------- */
944
 
945
EXPORT_SYMBOL(b1dma_reset);
946
EXPORT_SYMBOL(t1pci_detect);
947
EXPORT_SYMBOL(b1pciv4_detect);
948
EXPORT_SYMBOL(b1dma_interrupt);
949
 
950
EXPORT_SYMBOL(b1dma_load_firmware);
951
EXPORT_SYMBOL(b1dma_reset_ctr);
952
EXPORT_SYMBOL(b1dma_register_appl);
953
EXPORT_SYMBOL(b1dma_release_appl);
954
EXPORT_SYMBOL(b1dma_send_message);
955
EXPORT_SYMBOL(b1dmactl_read_proc);
956
 
957
int b1dma_init(void)
958
{
959
        char *p;
960
        char rev[32];
961
 
962
        if ((p = strchr(revision, ':')) != 0 && p[1]) {
963
                strncpy(rev, p + 2, sizeof(rev));
964
                rev[sizeof(rev)-1] = 0;
965
                if ((p = strchr(rev, '$')) != 0 && p > rev)
966
                   *(p-1) = 0;
967
        } else
968
                strcpy(rev, "1.0");
969
 
970
        printk(KERN_INFO "b1dma: revision %s\n", rev);
971
 
972
        return 0;
973
}
974
 
975
void b1dma_exit(void)
976
{
977
}
978
 
979
module_init(b1dma_init);
980
module_exit(b1dma_exit);

powered by: WebSVN 2.1.0

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