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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [avmb1/] [b1lli.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 * $Id: b1lli.c,v 1.1 2005-12-20 10:16:58 jcastillo Exp $
3
 *
4
 * ISDN lowlevel-module for AVM B1-card.
5
 *
6
 * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
7
 *
8
 * $Log: not supported by cvs2svn $
9
 * Revision 1.1.1.1  2001/09/10 07:44:18  simons
10
 * Initial import
11
 *
12
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
13
 * Initial revision
14
 *
15
 * Revision 1.1.2.11  1998/10/25 14:36:18  fritz
16
 * Backported from MIPS (Cobalt).
17
 *
18
 * Revision 1.1.2.10  1998/03/20 20:34:41  calle
19
 * port valid check now only for T1, because of the PCI and PCMCIA cards.
20
 *
21
 * Revision 1.1.2.9  1998/03/20 14:38:20  calle
22
 * capidrv: prepared state machines for suspend/resume/hold
23
 * capidrv: fix bug in state machine if B1/T1 is out of nccis
24
 * b1capi: changed some errno returns.
25
 * b1capi: detect if you try to add same T1 to different io address.
26
 * b1capi: change number of nccis depending on number of channels.
27
 * b1lli: cosmetics
28
 *
29
 * Revision 1.1.2.8  1998/03/18 17:43:29  calle
30
 * T1 with fastlink, bugfix for multicontroller support in capidrv.c
31
 *
32
 * Revision 1.1.2.7  1998/03/04 17:33:50  calle
33
 * Changes for T1.
34
 *
35
 * Revision 1.1.2.6  1998/02/27 15:40:44  calle
36
 * T1 running with slow link. bugfix in capi_release.
37
 *
38
 * Revision 1.1.2.5  1998/02/13 16:28:28  calle
39
 * first step for T1
40
 *
41
 * Revision 1.1.2.4  1998/01/27 16:12:51  calle
42
 * Support for PCMCIA B1/M1/M2 ready.
43
 *
44
 * Revision 1.1.2.3  1998/01/15 15:33:37  calle
45
 * print cardtype, d2 protocol and linetype after load.
46
 *
47
 * Revision 1.1.2.2  1997/11/26 10:46:55  calle
48
 * prepared for M1 (Mobile) and T1 (PMX) cards.
49
 * prepared to set configuration after load to support other D-channel
50
 * protocols, point-to-point and leased lines.
51
 *
52
 * Revision 1.1.2.1  1997/07/13 12:16:46  calle
53
 * bug fix for more than one controller in connect_req.
54
 *
55
 * Revision 1.1  1997/03/04 21:50:28  calle
56
 * Frirst version in isdn4linux
57
 *
58
 * Revision 2.2  1997/02/12 09:31:39  calle
59
 * new version
60
 *
61
 * Revision 1.1  1997/01/31 10:32:20  calle
62
 * Initial revision
63
 *
64
 *
65
 */
66
/* #define FASTLINK_DEBUG */
67
 
68
#include <linux/kernel.h>
69
#include <linux/skbuff.h>
70
#include <linux/delay.h>
71
#include <linux/mm.h>
72
#include <asm/segment.h>
73
#include <asm/io.h>
74
#include <linux/capi.h>
75
#include <linux/b1lli.h>
76
 
77
#include "compat.h"
78
#include "capicmd.h"
79
#include "capiutil.h"
80
 
81
extern int showcapimsgs;
82
 
83
/*
84
 * LLI Messages to the ISDN-ControllerISDN Controller
85
 */
86
 
87
#define SEND_POLL               0x72    /*
88
                                           * after load <- RECEIVE_POLL
89
                                         */
90
#define SEND_INIT               0x11    /*
91
                                           * first message <- RECEIVE_INIT
92
                                           * int32 NumApplications  int32
93
                                           * NumNCCIs int32 BoardNumber
94
                                         */
95
#define SEND_REGISTER           0x12    /*
96
                                           * register an application int32
97
                                           * ApplIDId int32 NumMessages
98
                                           * int32 NumB3Connections int32
99
                                           * NumB3Blocks int32 B3Size
100
                                           *
101
                                           * AnzB3Connection != 0 &&
102
                                           * AnzB3Blocks >= 1 && B3Size >= 1
103
                                         */
104
#define SEND_RELEASE            0x14    /*
105
                                           * deregister an application int32
106
                                           * ApplID
107
                                         */
108
#define SEND_MESSAGE            0x15    /*
109
                                           * send capi-message int32 length
110
                                           * capi-data ...
111
                                         */
112
#define SEND_DATA_B3_REQ        0x13    /*
113
                                           * send capi-data-message int32
114
                                           * MsgLength capi-data ... int32
115
                                           * B3Length data ....
116
                                         */
117
 
118
#define SEND_CONFIG             0x21    /*
119
                                         */
120
 
121
#define SEND_POLLACK            0x73    /* T1 Watchdog */
122
 
123
/*
124
 * LLI Messages from the ISDN-ControllerISDN Controller
125
 */
126
 
127
#define RECEIVE_POLL            0x32    /*
128
                                           * <- after SEND_POLL
129
                                         */
130
#define RECEIVE_INIT            0x27    /*
131
                                           * <- after SEND_INIT int32 length
132
                                           * byte total length b1struct board
133
                                           * driver revision b1struct card
134
                                           * type b1struct reserved b1struct
135
                                           * serial number b1struct driver
136
                                           * capability b1struct d-channel
137
                                           * protocol b1struct CAPI-2.0
138
                                           * profile b1struct capi version
139
                                         */
140
#define RECEIVE_MESSAGE         0x21    /*
141
                                           * <- after SEND_MESSAGE int32
142
                                           * AppllID int32 Length capi-data
143
                                           * ....
144
                                         */
145
#define RECEIVE_DATA_B3_IND     0x22    /*
146
                                           * received data int32 AppllID
147
                                           * int32 Length capi-data ...
148
                                           * int32 B3Length data ...
149
                                         */
150
#define RECEIVE_START           0x23    /*
151
                                           * Handshake
152
                                         */
153
#define RECEIVE_STOP            0x24    /*
154
                                           * Handshake
155
                                         */
156
#define RECEIVE_NEW_NCCI        0x25    /*
157
                                           * int32 AppllID int32 NCCI int32
158
                                           * WindowSize
159
                                         */
160
#define RECEIVE_FREE_NCCI       0x26    /*
161
                                           * int32 AppllID int32 NCCI
162
                                         */
163
#define RECEIVE_RELEASE         0x26    /*
164
                                           * int32 AppllID int32 0xffffffff
165
                                         */
166
#define RECEIVE_TASK_READY      0x31    /*
167
                                           * int32 tasknr
168
                                           * int32 Length Taskname ...
169
                                         */
170
 
171
#define WRITE_REGISTER          0x00
172
#define READ_REGISTER           0x01
173
 
174
/*
175
 * port offsets
176
 */
177
 
178
#define B1_READ                 0x00
179
#define B1_WRITE                0x01
180
#define B1_INSTAT               0x02
181
#define B1_OUTSTAT              0x03
182
#define B1_RESET                0x10
183
#define B1_ANALYSE              0x04
184
 
185
/* Hema card T1 */
186
 
187
#define T1_FASTLINK             0x00
188
#define T1_SLOWLINK             0x08
189
 
190
#define T1_READ                 B1_READ
191
#define T1_WRITE                B1_WRITE
192
#define T1_INSTAT               B1_INSTAT
193
#define T1_OUTSTAT              B1_OUTSTAT
194
#define T1_IRQENABLE            0x05
195
#define T1_FIFOSTAT             0x06
196
#define T1_RESETLINK            0x10
197
#define T1_ANALYSE              0x11
198
#define T1_IRQMASTER            0x12
199
#define T1_IDENT                0x17
200
#define T1_RESETBOARD           0x1f
201
 
202
#define T1F_IREADY              0x01
203
#define T1F_IHALF               0x02
204
#define T1F_IFULL               0x04
205
#define T1F_IEMPTY              0x08
206
#define T1F_IFLAGS              0xF0
207
 
208
#define T1F_OREADY              0x10
209
#define T1F_OHALF               0x20
210
#define T1F_OEMPTY              0x40
211
#define T1F_OFULL               0x80
212
#define T1F_OFLAGS              0xF0
213
 
214
/* there are HEMA cards with 1k and 4k FIFO out */
215
#define FIFO_OUTBSIZE           256
216
#define FIFO_INPBSIZE           512
217
 
218
#define HEMA_VERSION_ID         0
219
#define HEMA_PAL_ID             0
220
 
221
#define B1_STAT0(cardtype)  ((cardtype) == AVM_CARDTYPE_M1 ? 0x81200000l : 0x80A00000l)
222
#define B1_STAT1(cardtype)  (0x80E00000l)
223
 
224
 
225
static inline unsigned char b1outp(unsigned int base,
226
                                   unsigned short offset,
227
                                   unsigned char value)
228
{
229
        outb(value, base + offset);
230
        return inb(base + B1_ANALYSE);
231
}
232
 
233
static inline void t1outp(unsigned int base,
234
                          unsigned short offset,
235
                          unsigned char value)
236
{
237
        outb(value, base + offset);
238
}
239
 
240
static inline unsigned char t1inp(unsigned int base,
241
                                  unsigned short offset)
242
{
243
        return inb(base + offset);
244
}
245
 
246
static inline int B1_isfastlink(unsigned int base)
247
{
248
        return (inb(base + T1_IDENT) & ~0x82) == 1;
249
}
250
static inline unsigned char B1_fifostatus(unsigned int base)
251
{
252
        return inb(base + T1_FIFOSTAT);
253
}
254
 
255
static inline int B1_rx_full(unsigned int base)
256
{
257
        return inb(base + B1_INSTAT) & 0x1;
258
}
259
 
260
static inline unsigned char B1_get_byte(unsigned int base)
261
{
262
        unsigned long i = jiffies + 1 * HZ;     /* maximum wait time 1 sec */
263
        while (!B1_rx_full(base) && i > jiffies);
264
        if (B1_rx_full(base))
265
                return inb(base + B1_READ);
266
        printk(KERN_CRIT "b1lli(0x%x): rx not full after 1 second\n", base);
267
        return 0;
268
}
269
 
270
static inline unsigned int B1_get_word(unsigned int base)
271
{
272
        unsigned int val = 0;
273
        val |= B1_get_byte(base);
274
        val |= (B1_get_byte(base) << 8);
275
        val |= (B1_get_byte(base) << 16);
276
        val |= (B1_get_byte(base) << 24);
277
        return val;
278
}
279
 
280
static inline int B1_tx_empty(unsigned int base)
281
{
282
        return inb(base + B1_OUTSTAT) & 0x1;
283
}
284
 
285
static inline void B1_put_byte(unsigned int base, unsigned char val)
286
{
287
        while (!B1_tx_empty(base));
288
        b1outp(base, B1_WRITE, val);
289
}
290
 
291
static inline void B1_put_word(unsigned int base, unsigned int val)
292
{
293
        B1_put_byte(base, val & 0xff);
294
        B1_put_byte(base, (val >> 8) & 0xff);
295
        B1_put_byte(base, (val >> 16) & 0xff);
296
        B1_put_byte(base, (val >> 24) & 0xff);
297
}
298
 
299
static inline unsigned int B1_get_slice(unsigned int base,
300
                                        unsigned char *dp)
301
{
302
        unsigned int len, i;
303
#ifdef FASTLINK_DEBUG
304
        unsigned wcnt = 0, bcnt = 0;
305
#endif
306
 
307
        len = i = B1_get_word(base);
308
        if (B1_isfastlink(base)) {
309
                int status;
310
                while (i > 0) {
311
                        status = B1_fifostatus(base) & (T1F_IREADY|T1F_IHALF);
312
                        if (i >= FIFO_INPBSIZE) status |= T1F_IFULL;
313
 
314
                        switch (status) {
315
                                case T1F_IREADY|T1F_IHALF|T1F_IFULL:
316
                                        insb(base+B1_READ, dp, FIFO_INPBSIZE);
317
                                        dp += FIFO_INPBSIZE;
318
                                        i -= FIFO_INPBSIZE;
319
#ifdef FASTLINK_DEBUG
320
                                        wcnt += FIFO_INPBSIZE;
321
#endif
322
                                        break;
323
                                case T1F_IREADY|T1F_IHALF:
324
                                        insb(base+B1_READ,dp, i);
325
#ifdef FASTLINK_DEBUG
326
                                        wcnt += i;
327
#endif
328
                                        dp += i;
329
                                        i = 0;
330
                                        if (i == 0)
331
                                                break;
332
                                        /* fall through */
333
                                default:
334
                                        *dp++ = B1_get_byte(base);
335
                                        i--;
336
#ifdef FASTLINK_DEBUG
337
                                        bcnt++;
338
#endif
339
                                        break;
340
                        }
341
            }
342
#ifdef FASTLINK_DEBUG
343
            if (wcnt)
344
            printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n",
345
                                base, len, wcnt, bcnt);
346
#endif
347
        } else {
348
                while (i-- > 0)
349
                        *dp++ = B1_get_byte(base);
350
        }
351
        return len;
352
}
353
 
354
static inline void B1_put_slice(unsigned int base,
355
                                unsigned char *dp, unsigned int len)
356
{
357
        unsigned i = len;
358
        B1_put_word(base, i);
359
        if (B1_isfastlink(base)) {
360
                int status;
361
                while (i > 0) {
362
                        status = B1_fifostatus(base) & (T1F_OREADY|T1F_OHALF);
363
                        if (i >= FIFO_OUTBSIZE) status |= T1F_OEMPTY;
364
                        switch (status) {
365
                                case T1F_OREADY|T1F_OHALF|T1F_OEMPTY:
366
                                        outsb(base+B1_WRITE, dp, FIFO_OUTBSIZE);
367
                                        dp += FIFO_OUTBSIZE;
368
                                        i -= FIFO_OUTBSIZE;
369
                                        break;
370
                                case T1F_OREADY|T1F_OHALF:
371
                                        outsb(base+B1_WRITE, dp, i);
372
                                        dp += i;
373
                                        i = 0;
374
                                        break;
375
                                default:
376
                                        B1_put_byte(base, *dp++);
377
                                        i--;
378
                                        break;
379
                        }
380
                }
381
        } else {
382
                while (i-- > 0)
383
                        B1_put_byte(base, *dp++);
384
        }
385
}
386
 
387
static void b1_wr_reg(unsigned int base,
388
                      unsigned int reg,
389
                      unsigned int value)
390
{
391
        B1_put_byte(base, WRITE_REGISTER);
392
        B1_put_word(base, reg);
393
        B1_put_word(base, value);
394
}
395
 
396
static inline unsigned int b1_rd_reg(unsigned int base,
397
                                     unsigned int reg)
398
{
399
        B1_put_byte(base, READ_REGISTER);
400
        B1_put_word(base, reg);
401
        return B1_get_word(base);
402
 
403
}
404
 
405
static inline void b1_set_test_bit(unsigned int base,
406
                                   int cardtype,
407
                                   int onoff)
408
{
409
    b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20);
410
}
411
 
412
static inline int b1_get_test_bit(unsigned int base,
413
                                  int cardtype)
414
{
415
    return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0;
416
}
417
 
418
static int irq_table[16] =
419
{0,
420
 0,
421
 0,
422
 192,                           /* irq 3 */
423
 32,                            /* irq 4 */
424
 160,                           /* irq 5 */
425
 96,                            /* irq 6 */
426
 224,                           /* irq 7 */
427
 0,
428
 64,                            /* irq 9 */
429
 80,                            /* irq 10 */
430
 208,                           /* irq 11 */
431
 48,                            /* irq 12 */
432
 0,
433
 0,
434
 112,                           /* irq 15 */
435
};
436
 
437
static int hema_irq_table[16] =
438
{0,
439
 0,
440
 0,
441
 0x80,                          /* irq 3 */
442
 0,
443
 0x90,                          /* irq 5 */
444
 0,
445
 0xA0,                          /* irq 7 */
446
 0,
447
 0xB0,                          /* irq 9 */
448
 0xC0,                          /* irq 10 */
449
 0xD0,                          /* irq 11 */
450
 0xE0,                          /* irq 12 */
451
 0,
452
 0,
453
 0xF0,                          /* irq 15 */
454
};
455
 
456
 
457
int B1_valid_irq(unsigned irq, int cardtype)
458
{
459
        switch (cardtype) {
460
           default:
461
           case AVM_CARDTYPE_M1:
462
           case AVM_CARDTYPE_M2:
463
           case AVM_CARDTYPE_B1:
464
                return irq_table[irq & 0xf] != 0;
465
           case AVM_CARDTYPE_T1:
466
                return hema_irq_table[irq & 0xf] != 0;
467
        }
468
}
469
 
470
int B1_valid_port(unsigned port, int cardtype)
471
{
472
   switch (cardtype) {
473
           default:
474
           case AVM_CARDTYPE_M1:
475
           case AVM_CARDTYPE_M2:
476
           case AVM_CARDTYPE_B1:
477
#if 0   /* problem with PCMCIA and PCI cards */
478
                switch (port) {
479
                        case 0x150:
480
                        case 0x250:
481
                        case 0x300:
482
                        case 0x340:
483
                                return 1;
484
                }
485
                return 0;
486
#else
487
                return 1;
488
#endif
489
           case AVM_CARDTYPE_T1:
490
                return ((port & 0x7) == 0) && ((port & 0x30) != 0x30);
491
   }
492
}
493
 
494
void B1_setinterrupt(unsigned int base,
495
                                 unsigned irq, int cardtype)
496
{
497
        switch (cardtype) {
498
           case AVM_CARDTYPE_T1:
499
              t1outp(base, B1_INSTAT, 0x00);
500
              t1outp(base, B1_INSTAT, 0x02);
501
              t1outp(base, T1_IRQMASTER, 0x08);
502
           default:
503
           case AVM_CARDTYPE_M1:
504
           case AVM_CARDTYPE_M2:
505
           case AVM_CARDTYPE_B1:
506
              b1outp(base, B1_INSTAT, 0x00);
507
              b1outp(base, B1_RESET, irq_table[irq]);
508
              b1outp(base, B1_INSTAT, 0x02);
509
         }
510
}
511
 
512
unsigned char B1_disable_irq(unsigned int base)
513
{
514
        return b1outp(base, B1_INSTAT, 0x00);
515
}
516
 
517
void T1_disable_irq(unsigned int base)
518
{
519
      t1outp(base, T1_IRQMASTER, 0x00);
520
}
521
 
522
void B1_reset(unsigned int base)
523
{
524
        b1outp(base, B1_RESET, 0);
525
        udelay(55 * 2 * 1000);  /* 2 TIC's */
526
 
527
        b1outp(base, B1_RESET, 1);
528
        udelay(55 * 2 * 1000);  /* 2 TIC's */
529
 
530
        b1outp(base, B1_RESET, 0);
531
        udelay(55 * 2 * 1000);  /* 2 TIC's */
532
}
533
 
534
void T1_reset(unsigned int base)
535
{
536
        /* reset T1 Controller */
537
        B1_reset(base);
538
        /* disable irq on HEMA */
539
        t1outp(base, B1_INSTAT, 0x00);
540
        t1outp(base, B1_OUTSTAT, 0x00);
541
        t1outp(base, T1_IRQMASTER, 0x00);
542
        /* reset HEMA board configuration */
543
        t1outp(base, T1_RESETBOARD, 0xf);
544
}
545
 
546
int B1_detect(unsigned int base, int cardtype)
547
{
548
        int onoff, i;
549
 
550
        if (cardtype == AVM_CARDTYPE_T1)
551
           return 0;
552
 
553
        /*
554
         * Statusregister 0000 00xx
555
         */
556
        if ((inb(base + B1_INSTAT) & 0xfc)
557
            || (inb(base + B1_OUTSTAT) & 0xfc))
558
                return 1;
559
        /*
560
         * Statusregister 0000 001x
561
         */
562
        b1outp(base, B1_INSTAT, 0x2);   /* enable irq */
563
        /* b1outp(base, B1_OUTSTAT, 0x2); */
564
        if ((inb(base + B1_INSTAT) & 0xfe) != 0x2
565
            /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */)
566
                return 2;
567
        /*
568
         * Statusregister 0000 000x
569
         */
570
        b1outp(base, B1_INSTAT, 0x0);   /* disable irq */
571
        b1outp(base, B1_OUTSTAT, 0x0);
572
        if ((inb(base + B1_INSTAT) & 0xfe)
573
            || (inb(base + B1_OUTSTAT) & 0xfe))
574
                return 3;
575
 
576
        for (onoff = !0, i= 0; i < 10 ; i++) {
577
                b1_set_test_bit(base, cardtype, onoff);
578
                if (b1_get_test_bit(base, cardtype) != onoff)
579
                   return 4;
580
                onoff = !onoff;
581
        }
582
 
583
        if (cardtype == AVM_CARDTYPE_M1)
584
           return 0;
585
 
586
        if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01)
587
           return 5;
588
 
589
        return 0;
590
}
591
 
592
int T1_detectandinit(unsigned int base, unsigned irq, int cardnr)
593
{
594
        unsigned char cregs[8];
595
        unsigned char reverse_cardnr;
596
        unsigned long flags;
597
        unsigned char dummy;
598
        int i;
599
 
600
        reverse_cardnr =   ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1)
601
                         | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3);
602
        cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf);
603
        cregs[1] = 0x00; /* fast & slow link connected to CON1 */
604
        cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */
605
        cregs[3] = 0;
606
        cregs[4] = 0x11; /* zero wait state */
607
        cregs[5] = hema_irq_table[irq & 0xf];
608
        cregs[6] = 0;
609
        cregs[7] = 0;
610
 
611
        save_flags(flags);
612
        cli();
613
        /* board reset */
614
        t1outp(base, T1_RESETBOARD, 0xf);
615
        udelay(100 * 1000);
616
        dummy = t1inp(base, T1_FASTLINK+T1_OUTSTAT); /* first read */
617
 
618
        /* write config */
619
        dummy = (base >> 4) & 0xff;
620
        for (i=1;i<=0xf;i++) t1outp(base, i, dummy);
621
        t1outp(base, HEMA_PAL_ID & 0xf, dummy);
622
        t1outp(base, HEMA_PAL_ID >> 4, cregs[0]);
623
        for(i=1;i<7;i++) t1outp(base, 0, cregs[i]);
624
        t1outp(base, ((base >> 4)) & 0x3, cregs[7]);
625
        restore_flags(flags);
626
 
627
        udelay(100 * 1000);
628
        t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);
629
        t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);
630
        udelay(10 * 1000);
631
        t1outp(base, T1_FASTLINK+T1_RESETLINK, 1);
632
        t1outp(base, T1_SLOWLINK+T1_RESETLINK, 1);
633
        udelay(100 * 1000);
634
        t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);
635
        t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);
636
        udelay(10 * 1000);
637
        t1outp(base, T1_FASTLINK+T1_ANALYSE, 0);
638
        udelay(5 * 1000);
639
        t1outp(base, T1_SLOWLINK+T1_ANALYSE, 0);
640
 
641
        if (t1inp(base, T1_FASTLINK+T1_OUTSTAT) != 0x1) /* tx empty */
642
                return 1;
643
        if (t1inp(base, T1_FASTLINK+T1_INSTAT) != 0x0) /* rx empty */
644
                return 2;
645
        if (t1inp(base, T1_FASTLINK+T1_IRQENABLE) != 0x0)
646
                return 3;
647
        if ((t1inp(base, T1_FASTLINK+T1_FIFOSTAT) & 0xf0) != 0x70)
648
                return 4;
649
        if ((t1inp(base, T1_FASTLINK+T1_IRQMASTER) & 0x0e) != 0)
650
                return 5;
651
        if ((t1inp(base, T1_FASTLINK+T1_IDENT) & 0x7d) != 1)
652
                return 6;
653
        if (t1inp(base, T1_SLOWLINK+T1_OUTSTAT) != 0x1) /* tx empty */
654
                return 7;
655
        if ((t1inp(base, T1_SLOWLINK+T1_IRQMASTER) & 0x0e) != 0)
656
                return 8;
657
        if ((t1inp(base, T1_SLOWLINK+T1_IDENT) & 0x7d) != 0)
658
                return 9;
659
        return 0;
660
}
661
 
662
extern int loaddebug;
663
 
664
int B1_load_t4file(unsigned int base, avmb1_t4file * t4file)
665
{
666
        /*
667
         * Data is in user space !!!
668
         */
669
        unsigned char buf[256];
670
        unsigned char *dp;
671
        int i, left, retval;
672
 
673
 
674
        dp = t4file->data;
675
        left = t4file->len;
676
        while (left > sizeof(buf)) {
677
                retval = copy_from_user(buf, dp, sizeof(buf));
678
                if (retval)
679
                        return -EFAULT;
680
                if (loaddebug)
681
                        printk(KERN_DEBUG "b1capi: loading: %d bytes ..", sizeof(buf));
682
                for (i = 0; i < sizeof(buf); i++)
683
                        B1_put_byte(base, buf[i]);
684
                if (loaddebug)
685
                   printk("ok\n");
686
                left -= sizeof(buf);
687
                dp += sizeof(buf);
688
        }
689
        if (left) {
690
                retval = copy_from_user(buf, dp, left);
691
                if (retval)
692
                        return -EFAULT;
693
                if (loaddebug)
694
                        printk(KERN_DEBUG "b1capi: loading: %d bytes ..", left);
695
                for (i = 0; i < left; i++)
696
                        B1_put_byte(base, buf[i]);
697
                if (loaddebug)
698
                   printk("ok\n");
699
        }
700
        return 0;
701
}
702
 
703
int B1_load_config(unsigned int base, avmb1_t4file * config)
704
{
705
        /*
706
         * Data is in user space !!!
707
         */
708
        unsigned char buf[256];
709
        unsigned char *dp;
710
        int i, j, left, retval;
711
 
712
 
713
        dp = config->data;
714
        left = config->len;
715
        if (left) {
716
                B1_put_byte(base, SEND_CONFIG);
717
                B1_put_word(base, 1);
718
                B1_put_byte(base, SEND_CONFIG);
719
                B1_put_word(base, left);
720
        }
721
        while (left > sizeof(buf)) {
722
                retval = copy_from_user(buf, dp, sizeof(buf));
723
                if (retval)
724
                        return -EFAULT;
725
                if (loaddebug)
726
                        printk(KERN_DEBUG "b1capi: conf load: %d bytes ..", sizeof(buf));
727
                for (i = 0; i < sizeof(buf); ) {
728
                        B1_put_byte(base, SEND_CONFIG);
729
                        for (j=0; j < 4; j++) {
730
                                B1_put_byte(base, buf[i++]);
731
                        }
732
                }
733
                if (loaddebug)
734
                   printk("ok\n");
735
                left -= sizeof(buf);
736
                dp += sizeof(buf);
737
        }
738
        if (left) {
739
                retval = copy_from_user(buf, dp, left);
740
                if (retval)
741
                        return -EFAULT;
742
                if (loaddebug)
743
                        printk(KERN_DEBUG "b1capi: conf load: %d bytes ..", left);
744
                for (i = 0; i < left; ) {
745
                        B1_put_byte(base, SEND_CONFIG);
746
                        for (j=0; j < 4; j++) {
747
                                if (i < left)
748
                                        B1_put_byte(base, buf[i++]);
749
                                else
750
                                        B1_put_byte(base, 0);
751
                        }
752
                }
753
                if (loaddebug)
754
                   printk("ok\n");
755
        }
756
        return 0;
757
}
758
 
759
int B1_loaded(unsigned int base)
760
{
761
        int i;
762
        unsigned char ans;
763
 
764
        if (loaddebug)
765
                printk(KERN_DEBUG "b1capi: loaded: wait 1 ..\n");
766
        for (i = jiffies + 10 * HZ; i > jiffies;) {
767
                if (B1_tx_empty(base))
768
                        break;
769
        }
770
        if (!B1_tx_empty(base)) {
771
                printk(KERN_ERR "b1lli(0x%x): B1_loaded: timeout tx\n", base);
772
                return 0;
773
        }
774
        B1_put_byte(base, SEND_POLL);
775
        printk(KERN_DEBUG "b1capi: loaded: wait 2 ..\n");
776
        for (i = jiffies + 10 * HZ; i > jiffies;) {
777
                if (B1_rx_full(base)) {
778
                        if ((ans = B1_get_byte(base)) == RECEIVE_POLL) {
779
                                if (loaddebug)
780
                                        printk(KERN_DEBUG "b1capi: loaded: ok\n");
781
                                return 1;
782
                        }
783
                        printk(KERN_ERR "b1lli(0x%x): B1_loaded: got 0x%x ???\n",
784
                                base, ans);
785
                        return 0;
786
                }
787
        }
788
        printk(KERN_ERR "b1lli(0x%x): B1_loaded: timeout rx\n", base);
789
        return 0;
790
}
791
 
792
/*
793
 * -------------------------------------------------------------------
794
 */
795
static inline void parse_version(avmb1_card * card)
796
{
797
        int i, j;
798
        for (j = 0; j < AVM_MAXVERSION; j++)
799
                card->version[j] = "\0\0" + 1;
800
        for (i = 0, j = 0;
801
             j < AVM_MAXVERSION && i < card->versionlen;
802
             j++, i += card->versionbuf[i] + 1)
803
                card->version[j] = &card->versionbuf[i + 1];
804
}
805
/*
806
 * -------------------------------------------------------------------
807
 */
808
 
809
void B1_send_init(unsigned int port,
810
             unsigned int napps, unsigned int nncci, unsigned int cardnr)
811
{
812
        unsigned long flags;
813
 
814
        save_flags(flags);
815
        cli();
816
        B1_put_byte(port, SEND_INIT);
817
        B1_put_word(port, napps);
818
        B1_put_word(port, nncci);
819
        B1_put_word(port, cardnr);
820
        restore_flags(flags);
821
}
822
 
823
void B1_send_register(unsigned int port,
824
                      __u16 appid, __u32 nmsg,
825
                      __u32 nb3conn, __u32 nb3blocks, __u32 b3bsize)
826
{
827
        unsigned long flags;
828
 
829
        save_flags(flags);
830
        cli();
831
        B1_put_byte(port, SEND_REGISTER);
832
        B1_put_word(port, appid);
833
        B1_put_word(port, nmsg);
834
        B1_put_word(port, nb3conn);
835
        B1_put_word(port, nb3blocks);
836
        B1_put_word(port, b3bsize);
837
        restore_flags(flags);
838
}
839
 
840
void B1_send_release(unsigned int port,
841
                     __u16 appid)
842
{
843
        unsigned long flags;
844
 
845
        save_flags(flags);
846
        cli();
847
        B1_put_byte(port, SEND_RELEASE);
848
        B1_put_word(port, appid);
849
        restore_flags(flags);
850
}
851
 
852
void B1_send_message(unsigned int port, struct sk_buff *skb)
853
{
854
        unsigned long flags;
855
        __u16 len = CAPIMSG_LEN(skb->data);
856
        __u8 cmd = CAPIMSG_COMMAND(skb->data);
857
        __u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
858
        __u32 contr = CAPIMSG_CONTROL(skb->data);
859
 
860
        if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
861
                __u16 dlen = CAPIMSG_DATALEN(skb->data);
862
 
863
                if (showcapimsgs > 2) {
864
                        if (showcapimsgs & 1) {
865
                                printk(KERN_DEBUG "b1lli: Put [0x%lx] id#%d %s len=%u\n",
866
                                       (unsigned long) contr,
867
                                       CAPIMSG_APPID(skb->data),
868
                                       capi_cmd2str(cmd, subcmd), len);
869
                        } else {
870
                                printk(KERN_DEBUG "b1lli: Put [0x%lx] %s\n",
871
                                                (unsigned long) contr,
872
                                                capi_message2str(skb->data));
873
                        }
874
 
875
                }
876
                save_flags(flags);
877
                cli();
878
                B1_put_byte(port, SEND_DATA_B3_REQ);
879
                B1_put_slice(port, skb->data, len);
880
                B1_put_slice(port, skb->data + len, dlen);
881
                restore_flags(flags);
882
        } else {
883
                if (showcapimsgs) {
884
 
885
                        if (showcapimsgs & 1) {
886
                                printk(KERN_DEBUG "b1lli: Put [0x%lx] id#%d %s len=%u\n",
887
                                       (unsigned long) contr,
888
                                       CAPIMSG_APPID(skb->data),
889
                                       capi_cmd2str(cmd, subcmd), len);
890
                        } else {
891
                                printk(KERN_DEBUG "b1lli: Put [0x%lx] %s\n", (unsigned long)contr, capi_message2str(skb->data));
892
                        }
893
                }
894
                save_flags(flags);
895
                cli();
896
                B1_put_byte(port, SEND_MESSAGE);
897
                B1_put_slice(port, skb->data, len);
898
                restore_flags(flags);
899
        }
900
        dev_kfree_skb(skb, FREE_WRITE);
901
}
902
 
903
/*
904
 * -------------------------------------------------------------------
905
 */
906
 
907
void B1_handle_interrupt(avmb1_card * card)
908
{
909
        unsigned char b1cmd;
910
        struct sk_buff *skb;
911
 
912
        unsigned ApplId;
913
        unsigned MsgLen;
914
        unsigned DataB3Len;
915
        unsigned NCCI;
916
        unsigned WindowSize;
917
 
918
t1retry:
919
        if (!B1_rx_full(card->port))
920
                return;
921
 
922
        b1cmd = B1_get_byte(card->port);
923
 
924
        switch (b1cmd) {
925
 
926
        case RECEIVE_DATA_B3_IND:
927
 
928
                ApplId = (unsigned) B1_get_word(card->port);
929
                MsgLen = B1_get_slice(card->port, card->msgbuf);
930
                DataB3Len = B1_get_slice(card->port, card->databuf);
931
 
932
                if (showcapimsgs > 2) {
933
                        __u8 cmd = CAPIMSG_COMMAND(card->msgbuf);
934
                        __u8 subcmd = CAPIMSG_SUBCOMMAND(card->msgbuf);
935
                        __u32 contr = CAPIMSG_CONTROL(card->msgbuf);
936
                        CAPIMSG_SETDATA(card->msgbuf, card->databuf);
937
                        if (showcapimsgs & 1) {
938
                                printk(KERN_DEBUG "b1lli: Got [0x%lx] id#%d %s len=%u/%u\n",
939
                                       (unsigned long) contr,
940
                                       CAPIMSG_APPID(card->msgbuf),
941
                                       capi_cmd2str(cmd, subcmd),
942
                                       MsgLen, DataB3Len);
943
                        } else {
944
                                printk(KERN_DEBUG "b1lli: Got [0x%lx] %s\n", (unsigned long)contr, capi_message2str(card->msgbuf));
945
                        }
946
                }
947
                if (!(skb = dev_alloc_skb(DataB3Len + MsgLen))) {
948
                        printk(KERN_ERR "b1lli: incoming packet dropped\n");
949
                } else {
950
                        SET_SKB_FREE(skb);
951
                        memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
952
                        memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
953
                        CAPIMSG_SETDATA(skb->data, skb->data + MsgLen);
954
                        avmb1_handle_capimsg(card, ApplId, skb);
955
                }
956
                break;
957
 
958
        case RECEIVE_MESSAGE:
959
 
960
                ApplId = (unsigned) B1_get_word(card->port);
961
                MsgLen = B1_get_slice(card->port, card->msgbuf);
962
                if (showcapimsgs) {
963
                        __u8 cmd = CAPIMSG_COMMAND(card->msgbuf);
964
                        __u8 subcmd = CAPIMSG_SUBCOMMAND(card->msgbuf);
965
                        __u32 contr = CAPIMSG_CONTROL(card->msgbuf);
966
                        if (showcapimsgs & 1) {
967
                                printk(KERN_DEBUG "b1lli: Got [0x%lx] id#%d %s len=%u\n",
968
                                       (unsigned long) contr,
969
                                       CAPIMSG_APPID(card->msgbuf),
970
                                       capi_cmd2str(cmd, subcmd),
971
                                       MsgLen);
972
                        } else {
973
                                printk(KERN_DEBUG "b1lli: Got [0x%lx] %s\n",
974
                                                (unsigned long) contr,
975
                                                capi_message2str(card->msgbuf));
976
                        }
977
 
978
                }
979
                if (!(skb = dev_alloc_skb(MsgLen))) {
980
                        printk(KERN_ERR "b1lli: incoming packet dropped\n");
981
                } else {
982
                        SET_SKB_FREE(skb);
983
                        memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
984
                        avmb1_handle_capimsg(card, ApplId, skb);
985
                }
986
                break;
987
 
988
        case RECEIVE_NEW_NCCI:
989
 
990
                ApplId = B1_get_word(card->port);
991
                NCCI = B1_get_word(card->port);
992
                WindowSize = B1_get_word(card->port);
993
 
994
                if (showcapimsgs)
995
                        printk(KERN_DEBUG "b1lli(0x%x): NEW_NCCI app %u ncci 0x%x\n", card->port, ApplId, NCCI);
996
 
997
                avmb1_handle_new_ncci(card, ApplId, NCCI, WindowSize);
998
 
999
                break;
1000
 
1001
        case RECEIVE_FREE_NCCI:
1002
 
1003
                ApplId = B1_get_word(card->port);
1004
                NCCI = B1_get_word(card->port);
1005
 
1006
                if (showcapimsgs)
1007
                        printk(KERN_DEBUG "b1lli(0x%x): FREE_NCCI app %u ncci 0x%x\n", card->port, ApplId, NCCI);
1008
 
1009
                avmb1_handle_free_ncci(card, ApplId, NCCI);
1010
                break;
1011
 
1012
        case RECEIVE_START:
1013
                if (card->cardtype == AVM_CARDTYPE_T1) {
1014
                   B1_put_byte(card->port, SEND_POLLACK);
1015
                   /* printk(KERN_DEBUG "b1lli: T1 watchdog\n"); */
1016
                }
1017
                if (card->blocked)
1018
                        printk(KERN_DEBUG "b1lli(0x%x): RESTART\n", card->port);
1019
                card->blocked = 0;
1020
                break;
1021
 
1022
        case RECEIVE_STOP:
1023
                printk(KERN_DEBUG "b1lli(0x%x): STOP\n", card->port);
1024
                card->blocked = 1;
1025
                break;
1026
 
1027
        case RECEIVE_INIT:
1028
 
1029
                card->versionlen = B1_get_slice(card->port, card->versionbuf);
1030
                card->cardstate = CARD_ACTIVE;
1031
                parse_version(card);
1032
                printk(KERN_INFO "b1lli(0x%x): %s-card (%s) now active\n",
1033
                       card->port,
1034
                       card->version[VER_CARDTYPE],
1035
                       card->version[VER_DRIVER]);
1036
                avmb1_card_ready(card);
1037
                break;
1038
        case RECEIVE_TASK_READY:
1039
                ApplId = (unsigned) B1_get_word(card->port);
1040
                MsgLen = B1_get_slice(card->port, card->msgbuf);
1041
                card->msgbuf[MsgLen] = 0;
1042
                printk(KERN_INFO "b1lli(0x%x): Task %d \"%s\" ready.\n",
1043
                                card->port, ApplId, card->msgbuf);
1044
                break;
1045
        default:
1046
                printk(KERN_ERR "b1lli(0x%x): B1_handle_interrupt: 0x%x ???\n",
1047
                                card->port, b1cmd);
1048
                break;
1049
        }
1050
        if (card->cardtype == AVM_CARDTYPE_T1)
1051
                goto t1retry;
1052
}

powered by: WebSVN 2.1.0

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