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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [hisax/] [isar.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* $Id: isar.c,v 1.1.1.1 2001-09-10 07:44:18 simons Exp $
2
 
3
 * isar.c   ISAR (Siemens PSB 7110) specific routines
4
 *
5
 * Author       Karsten Keil (keil@isdn4linux.de)
6
 *
7
 *
8
 * $Log: not supported by cvs2svn $
9
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
10
 * Initial revision
11
 *
12
 * Revision 1.1.2.4  1998/11/03 00:06:44  keil
13
 * certification related changes
14
 * fixed logging for smaller stack use
15
 *
16
 * Revision 1.1.2.3  1998/10/04 23:04:58  keil
17
 * ISAR works now
18
 *
19
 * Revision 1.1.2.2  1998/09/30 22:28:07  keil
20
 * more work for isar support
21
 *
22
 * Revision 1.1.2.1  1998/09/27 13:01:43  keil
23
 * Start support for ISAR based cards
24
 *
25
 * Revision 1.1  1998/08/13 23:33:47  keil
26
 * First version, only init
27
 *
28
 *
29
 */
30
 
31
#define __NO_VERSION__
32
#include "hisax.h"
33
#include "isar.h"
34
#include "isdnl1.h"
35
#include <linux/interrupt.h>
36
 
37
#define DBG_LOADFIRM    0
38
#define DUMP_MBOXFRAME  2
39
 
40
#define MIN(a,b) ((a<b)?a:b)
41
 
42
void isar_setup(struct IsdnCardState *cs);
43
 
44
static inline int
45
waitforHIA(struct IsdnCardState *cs, int timeout)
46
{
47
 
48
        while ((cs->BC_Read_Reg(cs, 0, ISAR_HIA) & 1) && timeout) {
49
                udelay(1);
50
                timeout--;
51
        }
52
        if (!timeout)
53
                printk(KERN_WARNING "HiSax: ISAR waitforHIA timeout\n");
54
        return(timeout);
55
}
56
 
57
 
58
int
59
sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
60
        u_char *msg)
61
{
62
        long flags;
63
        int i;
64
 
65
        if (!waitforHIA(cs, 4000))
66
                return(0);
67
#if DUMP_MBOXFRAME
68
        if (cs->debug & L1_DEB_HSCX)
69
                debugl1(cs, "sendmsg(%02x,%02x,%d)", his, creg, len);
70
#endif
71
        save_flags(flags);
72
        cli();
73
        cs->BC_Write_Reg(cs, 0, ISAR_CTRL_H, creg);
74
        cs->BC_Write_Reg(cs, 0, ISAR_CTRL_L, len);
75
        cs->BC_Write_Reg(cs, 0, ISAR_WADR, 0);
76
        if (msg && len) {
77
                cs->BC_Write_Reg(cs, 1, ISAR_MBOX, msg[0]);
78
                for (i=1; i<len; i++)
79
                        cs->BC_Write_Reg(cs, 2, ISAR_MBOX, msg[i]);
80
#if DUMP_MBOXFRAME>1
81
                if (cs->debug & L1_DEB_HSCX_FIFO) {
82
                        char tmp[256], *t;
83
 
84
                        i = len;
85
                        while (i>0) {
86
                                t = tmp;
87
                                t += sprintf(t, "sendmbox cnt %d", len);
88
                                QuickHex(t, &msg[len-i], (i>64) ? 64:i);
89
                                debugl1(cs, tmp);
90
                                i -= 64;
91
                        }
92
                }
93
#endif
94
        }
95
        cs->BC_Write_Reg(cs, 1, ISAR_HIS, his);
96
        restore_flags(flags);
97
        waitforHIA(cs, 10000);
98
        return(1);
99
}
100
 
101
/* Call only with IRQ disabled !!! */
102
inline void
103
rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg)
104
{
105
        int i;
106
 
107
        cs->BC_Write_Reg(cs, 1, ISAR_RADR, 0);
108
        if (msg && ireg->clsb) {
109
                msg[0] = cs->BC_Read_Reg(cs, 1, ISAR_MBOX);
110
                for (i=1; i < ireg->clsb; i++)
111
                         msg[i] = cs->BC_Read_Reg(cs, 2, ISAR_MBOX);
112
#if DUMP_MBOXFRAME>1
113
                if (cs->debug & L1_DEB_HSCX_FIFO) {
114
                        char tmp[256], *t;
115
 
116
                        i = ireg->clsb;
117
                        while (i>0) {
118
                                t = tmp;
119
                                t += sprintf(t, "rcv_mbox cnt %d", ireg->clsb);
120
                                QuickHex(t, &msg[ireg->clsb-i], (i>64) ? 64:i);
121
                                debugl1(cs, tmp);
122
                                i -= 64;
123
                        }
124
                }
125
#endif
126
        }
127
        cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
128
}
129
 
130
/* Call only with IRQ disabled !!! */
131
inline void
132
get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg)
133
{
134
        ireg->iis = cs->BC_Read_Reg(cs, 1, ISAR_IIS);
135
        ireg->cmsb = cs->BC_Read_Reg(cs, 1, ISAR_CTRL_H);
136
        ireg->clsb = cs->BC_Read_Reg(cs, 1, ISAR_CTRL_L);
137
#if DUMP_MBOXFRAME
138
        if (cs->debug & L1_DEB_HSCX)
139
                debugl1(cs, "rcv_mbox(%02x,%02x,%d)", ireg->iis, ireg->cmsb,
140
                        ireg->clsb);
141
#endif
142
}
143
 
144
int
145
waitrecmsg(struct IsdnCardState *cs, u_char *len,
146
        u_char *msg, int maxdelay)
147
{
148
        int timeout = 0;
149
        long flags;
150
        struct isar_reg *ir = cs->bcs[0].hw.isar.reg;
151
 
152
 
153
        while((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) &&
154
                (timeout++ < maxdelay))
155
                udelay(1);
156
        if (timeout >= maxdelay) {
157
                printk(KERN_WARNING"isar recmsg IRQSTA timeout\n");
158
                return(0);
159
        }
160
        save_flags(flags);
161
        cli();
162
        get_irq_infos(cs, ir);
163
        rcv_mbox(cs, ir, msg);
164
        *len = ir->clsb;
165
        restore_flags(flags);
166
        return(1);
167
}
168
 
169
int
170
ISARVersion(struct IsdnCardState *cs, char *s)
171
{
172
        int ver;
173
        u_char msg[] = ISAR_MSG_HWVER;
174
        u_char tmp[64];
175
        u_char len;
176
        int debug;
177
 
178
        cs->cardmsg(cs, CARD_RESET,  NULL);
179
        /* disable ISAR IRQ */
180
        cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0);
181
        debug = cs->debug;
182
        cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO);
183
        if (!sendmsg(cs, ISAR_HIS_VNR, 0, 3, msg))
184
                return(-1);
185
        if (!waitrecmsg(cs, &len, tmp, 100000))
186
                 return(-2);
187
        cs->debug = debug;
188
        if (cs->bcs[0].hw.isar.reg->iis == ISAR_IIS_VNR) {
189
                if (len == 1) {
190
                        ver = tmp[0] & 0xf;
191
                        printk(KERN_INFO "%s ISAR version %d\n", s, ver);
192
                        return(ver);
193
                }
194
                return(-3);
195
        }
196
        return(-4);
197
}
198
 
199
int
200
isar_load_firmware(struct IsdnCardState *cs, u_char *buf)
201
{
202
        int ret, size, cnt, debug;
203
        u_char len, nom, noc;
204
        u_short sadr, left, *sp;
205
        u_char *p = buf;
206
        u_char *msg, *tmpmsg, *mp, tmp[64];
207
        long flags;
208
        struct isar_reg *ireg = cs->bcs[0].hw.isar.reg;
209
 
210
        struct {u_short sadr;
211
                u_short len;
212
                u_short d_key;
213
        } blk_head;
214
 
215
#define BLK_HEAD_SIZE 6
216
        if (1 != (ret = ISARVersion(cs, "Testing"))) {
217
                printk(KERN_ERR"isar_load_firmware wrong isar version %d\n", ret);
218
                return(1);
219
        }
220
        debug = cs->debug;
221
#if DBG_LOADFIRM<2
222
        cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO);
223
#endif
224
        printk(KERN_DEBUG"isar_load_firmware buf %#lx\n", (u_long)buf);
225
        if ((ret = verify_area(VERIFY_READ, (void *) p, sizeof(int)))) {
226
                printk(KERN_ERR"isar_load_firmware verify_area ret %d\n", ret);
227
                return ret;
228
        }
229
        if ((ret = copy_from_user(&size, p, sizeof(int)))) {
230
                printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret);
231
                return ret;
232
        }
233
        p += sizeof(int);
234
        printk(KERN_DEBUG"isar_load_firmware size: %d\n", size);
235
        if ((ret = verify_area(VERIFY_READ, (void *) p, size))) {
236
                printk(KERN_ERR"isar_load_firmware verify_area ret %d\n", ret);
237
                return ret;
238
        }
239
        cnt = 0;
240
        /* disable ISAR IRQ */
241
        cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0);
242
        if (!(msg = kmalloc(256, GFP_KERNEL))) {
243
                printk(KERN_ERR"isar_load_firmware no buffer\n");
244
                return (1);
245
        }
246
        if (!(tmpmsg = kmalloc(256, GFP_KERNEL))) {
247
                printk(KERN_ERR"isar_load_firmware no tmp buffer\n");
248
                kfree(msg);
249
                return (1);
250
        }
251
        while (cnt < size) {
252
                if ((ret = copy_from_user(&blk_head, p, BLK_HEAD_SIZE))) {
253
                        printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret);
254
                        goto reterror;
255
                }
256
                cnt += BLK_HEAD_SIZE;
257
                p += BLK_HEAD_SIZE;
258
                printk(KERN_DEBUG"isar firmware block (%#x,%5d,%#x)\n",
259
                        blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
260
                sadr = blk_head.sadr;
261
                left = blk_head.len;
262
                if (!sendmsg(cs, ISAR_HIS_DKEY, blk_head.d_key & 0xff, 0, NULL)) {
263
                        printk(KERN_ERR"isar sendmsg dkey failed\n");
264
                        ret = 1;goto reterror;
265
                }
266
                if (!waitrecmsg(cs, &len, tmp, 100000)) {
267
                        printk(KERN_ERR"isar waitrecmsg dkey failed\n");
268
                        ret = 1;goto reterror;
269
                }
270
                if ((ireg->iis != ISAR_IIS_DKEY) || ireg->cmsb || len) {
271
                        printk(KERN_ERR"isar wrong dkey response (%x,%x,%x)\n",
272
                                ireg->iis, ireg->cmsb, len);
273
                        ret = 1;goto reterror;
274
                }
275
                while (left>0) {
276
                        noc = MIN(126, left);
277
                        nom = 2*noc;
278
                        mp  = msg;
279
                        *mp++ = sadr / 256;
280
                        *mp++ = sadr % 256;
281
                        left -= noc;
282
                        *mp++ = noc;
283
                        if ((ret = copy_from_user(tmpmsg, p, nom))) {
284
                                printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", ret);
285
                                goto reterror;
286
                        }
287
                        p += nom;
288
                        cnt += nom;
289
                        nom += 3;
290
                        sp = (u_short *)tmpmsg;
291
#if DBG_LOADFIRM
292
                        printk(KERN_DEBUG"isar: load %3d words at %04x\n",
293
                                 noc, sadr);
294
#endif
295
                        sadr += noc;
296
                        while(noc) {
297
                                *mp++ = *sp / 256;
298
                                *mp++ = *sp % 256;
299
                                sp++;
300
                                noc--;
301
                        }
302
                        if (!sendmsg(cs, ISAR_HIS_FIRM, 0, nom, msg)) {
303
                                printk(KERN_ERR"isar sendmsg prog failed\n");
304
                                ret = 1;goto reterror;
305
                        }
306
                        if (!waitrecmsg(cs, &len, tmp, 100000)) {
307
                                printk(KERN_ERR"isar waitrecmsg prog failed\n");
308
                                ret = 1;goto reterror;
309
                        }
310
                        if ((ireg->iis != ISAR_IIS_FIRM) || ireg->cmsb || len) {
311
                                printk(KERN_ERR"isar wrong prog response (%x,%x,%x)\n",
312
                                        ireg->iis, ireg->cmsb, len);
313
                                ret = 1;goto reterror;
314
                        }
315
                }
316
                printk(KERN_DEBUG"isar firmware block %5d words loaded\n",
317
                        blk_head.len);
318
        }
319
        msg[0] = 0xff;
320
        msg[1] = 0xfe;
321
        ireg->bstat = 0;
322
        if (!sendmsg(cs, ISAR_HIS_STDSP, 0, 2, msg)) {
323
                printk(KERN_ERR"isar sendmsg start dsp failed\n");
324
                ret = 1;goto reterror;
325
        }
326
        if (!waitrecmsg(cs, &len, tmp, 100000)) {
327
                printk(KERN_ERR"isar waitrecmsg start dsp failed\n");
328
                ret = 1;goto reterror;
329
        }
330
        if ((ireg->iis != ISAR_IIS_STDSP) || ireg->cmsb || len) {
331
                printk(KERN_ERR"isar wrong start dsp response (%x,%x,%x)\n",
332
                        ireg->iis, ireg->cmsb, len);
333
                ret = 1;goto reterror;
334
        } else
335
                printk(KERN_DEBUG"isar start dsp success\n");
336
        /* NORMAL mode entered */
337
        /* Enable IRQs of ISAR */
338
        cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, ISAR_IRQSTA);
339
        save_flags(flags);
340
        sti();
341
        cnt = 1000; /* max 1s */
342
        while ((!ireg->bstat) && cnt) {
343
                udelay(1000);
344
                cnt--;
345
        }
346
        if (!cnt) {
347
                printk(KERN_ERR"isar no general status event received\n");
348
                ret = 1;goto reterrflg;
349
        } else {
350
                printk(KERN_DEBUG"isar general status event %x\n",
351
                        ireg->bstat);
352
        }
353
        ireg->iis = 0;
354
        if (!sendmsg(cs, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) {
355
                printk(KERN_ERR"isar sendmsg self tst failed\n");
356
                ret = 1;goto reterrflg;
357
        }
358
        cnt = 1000; /* max 10 ms */
359
        while ((ireg->iis != ISAR_IIS_DIAG) && cnt) {
360
                udelay(10);
361
                cnt--;
362
        }
363
        if (!cnt) {
364
                printk(KERN_ERR"isar no self tst response\n");
365
                ret = 1;goto reterrflg;
366
        } else if ((ireg->cmsb == ISAR_CTRL_STST) && (ireg->clsb == 1)
367
                && (ireg->par[0] == 0)) {
368
                printk(KERN_DEBUG"isar selftest OK\n");
369
        } else {
370
                printk(KERN_DEBUG"isar selftest not OK %x/%x/%x\n",
371
                        ireg->cmsb, ireg->clsb, ireg->par[0]);
372
                ret = 1;goto reterror;
373
        }
374
        ireg->iis = 0;
375
        if (!sendmsg(cs, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) {
376
                printk(KERN_ERR"isar RQST SVN failed\n");
377
                ret = 1;goto reterror;
378
        }
379
        cnt = 10000; /* max 100 ms */
380
        while ((ireg->iis != ISAR_IIS_DIAG) && cnt) {
381
                udelay(10);
382
                cnt--;
383
        }
384
        if (!cnt) {
385
                printk(KERN_ERR"isar no SVN response\n");
386
                ret = 1;goto reterrflg;
387
        } else {
388
                if ((ireg->cmsb == ISAR_CTRL_SWVER) && (ireg->clsb == 1))
389
                        printk(KERN_DEBUG"isar software version %#x\n",
390
                                ireg->par[0]);
391
                else {
392
                        printk(KERN_ERR"isar wrong swver response (%x,%x) cnt(%d)\n",
393
                                ireg->cmsb, ireg->clsb, cnt);
394
                        ret = 1;goto reterrflg;
395
                }
396
        }
397
        cs->debug = debug;
398
        isar_setup(cs);
399
        ret = 0;
400
reterrflg:
401
        restore_flags(flags);
402
reterror:
403
        cs->debug = debug;
404
        if (ret)
405
                /* disable ISAR IRQ */
406
                cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0);
407
        kfree(msg);
408
        kfree(tmpmsg);
409
        return(ret);
410
}
411
 
412
void
413
isar_sched_event(struct BCState *bcs, int event)
414
{
415
        bcs->event |= 1 << event;
416
        queue_task(&bcs->tqueue, &tq_immediate);
417
        mark_bh(IMMEDIATE_BH);
418
}
419
 
420
static inline void
421
isar_rcv_frame(struct IsdnCardState *cs, struct BCState *bcs)
422
{
423
        u_char *ptr;
424
        struct sk_buff *skb;
425
        struct isar_reg *ireg = bcs->hw.isar.reg;
426
 
427
        if (!ireg->clsb) {
428
                debugl1(cs, "isar zero len frame");
429
                cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
430
                return;
431
        }
432
        switch (bcs->mode) {
433
        case L1_MODE_NULL:
434
                debugl1(cs, "isar mode 0 spurious IIS_RDATA %x/%x/%x",
435
                        ireg->iis, ireg->cmsb, ireg->clsb);
436
                printk(KERN_WARNING"isar mode 0 spurious IIS_RDATA %x/%x/%x\n",
437
                        ireg->iis, ireg->cmsb, ireg->clsb);
438
                cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
439
                break;
440
        case L1_MODE_TRANS:
441
                if ((skb = dev_alloc_skb(ireg->clsb))) {
442
                        SET_SKB_FREE(skb);
443
                        rcv_mbox(cs, ireg, (u_char *)skb_put(skb, ireg->clsb));
444
                        skb_queue_tail(&bcs->rqueue, skb);
445
                        isar_sched_event(bcs, B_RCVBUFREADY);
446
                } else {
447
                        printk(KERN_WARNING "HiSax: skb out of memory\n");
448
                        cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
449
                }
450
                break;
451
        case L1_MODE_HDLC:
452
                if ((bcs->hw.isar.rcvidx + ireg->clsb) > HSCX_BUFMAX) {
453
                        if (cs->debug & L1_DEB_WARN)
454
                                debugl1(cs, "isar_rcv_frame: incoming packet too large");
455
                        cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
456
                        bcs->hw.isar.rcvidx = 0;
457
                } else if (ireg->cmsb & HDLC_ERROR) {
458
                        if (cs->debug & L1_DEB_WARN)
459
                                debugl1(cs, "isar frame error %x len %d",
460
                                        ireg->cmsb, ireg->clsb);
461
                        bcs->hw.isar.rcvidx = 0;
462
                        cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
463
                } else {
464
                        if (ireg->cmsb & HDLC_FSD)
465
                                bcs->hw.isar.rcvidx = 0;
466
                        ptr = bcs->hw.isar.rcvbuf + bcs->hw.isar.rcvidx;
467
                        bcs->hw.isar.rcvidx += ireg->clsb;
468
                        rcv_mbox(cs, ireg, ptr);
469
                        if (ireg->cmsb & HDLC_FED) {
470
                                if (bcs->hw.isar.rcvidx < 3) { /* last 2 bytes are the FCS */
471
                                        printk(KERN_WARNING "ISAR: HDLC frame too short(%d)\n",
472
                                                bcs->hw.isar.rcvidx);
473
                                } else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx-2)))
474
                                        printk(KERN_WARNING "ISAR: receive out of memory\n");
475
                                else {
476
                                        SET_SKB_FREE(skb);
477
                                        memcpy(skb_put(skb, bcs->hw.isar.rcvidx-2),
478
                                                bcs->hw.isar.rcvbuf, bcs->hw.isar.rcvidx-2);
479
                                        skb_queue_tail(&bcs->rqueue, skb);
480
                                        isar_sched_event(bcs, B_RCVBUFREADY);
481
                                }
482
                        }
483
                }
484
                break;
485
        default:
486
                printk(KERN_ERR"isar_rcv_frame mode (%x)error\n", bcs->mode);
487
                cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
488
                break;
489
        }
490
}
491
 
492
void
493
isar_fill_fifo(struct BCState *bcs)
494
{
495
        struct IsdnCardState *cs = bcs->cs;
496
        int count;
497
        u_char msb;
498
        u_char *ptr;
499
        long flags;
500
 
501
        if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
502
                debugl1(cs, "isar_fill_fifo");
503
        if (!bcs->tx_skb)
504
                return;
505
        if (bcs->tx_skb->len <= 0)
506
                return;
507
        if (!(bcs->hw.isar.reg->bstat &
508
                (bcs->hw.isar.dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
509
                return;
510
        if (bcs->tx_skb->len > bcs->hw.isar.mml) {
511
                msb = 0;
512
                count = bcs->hw.isar.mml;
513
        } else {
514
                count = bcs->tx_skb->len;
515
                msb = HDLC_FED;
516
        }
517
        if (!bcs->hw.isar.txcnt)
518
                msb |= HDLC_FST;
519
        save_flags(flags);
520
        cli();
521
        ptr = bcs->tx_skb->data;
522
        skb_pull(bcs->tx_skb, count);
523
        bcs->tx_cnt -= count;
524
        bcs->hw.isar.txcnt += count;
525
        switch (bcs->mode) {
526
        case L1_MODE_NULL:
527
                printk(KERN_ERR"isar_fill_fifo wrong mode 0\n");
528
                break;
529
        case L1_MODE_TRANS:
530
                if (!sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
531
                        0, count, ptr)) {
532
                        if (cs->debug)
533
                                debugl1(cs, "isar bin data send dp%d failed",
534
                                        bcs->hw.isar.dpath);
535
                }
536
                break;
537
        case L1_MODE_HDLC:
538
                if (!sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
539
                        msb, count, ptr)) {
540
                        if (cs->debug)
541
                                debugl1(cs, "isar hdlc data send dp%d failed",
542
                                        bcs->hw.isar.dpath);
543
                }
544
                break;
545
        default:
546
                printk(KERN_ERR"isar_fill_fifo mode (%x)error\n", bcs->mode);
547
                break;
548
        }
549
        restore_flags(flags);
550
}
551
 
552
inline
553
struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath)
554
{
555
        if ((!dpath) || (dpath == 3))
556
                return(NULL);
557
        if (cs->bcs[0].hw.isar.dpath == dpath)
558
                return(&cs->bcs[0]);
559
        if (cs->bcs[1].hw.isar.dpath == dpath)
560
                return(&cs->bcs[1]);
561
        return(NULL);
562
}
563
 
564
inline void
565
send_frames(struct BCState *bcs)
566
{
567
        if (bcs->tx_skb) {
568
                if (bcs->tx_skb->len) {
569
                        isar_fill_fifo(bcs);
570
                        return;
571
                } else {
572
                        if (bcs->st->lli.l1writewakeup &&
573
                                (PACKET_NOACK != bcs->tx_skb->pkt_type))
574
                                        bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.isar.txcnt);
575
                        dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
576
                        bcs->hw.isar.txcnt = 0;
577
                        bcs->tx_skb = NULL;
578
                }
579
        }
580
        if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
581
                bcs->hw.isar.txcnt = 0;
582
                test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
583
                isar_fill_fifo(bcs);
584
        } else {
585
                test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
586
                isar_sched_event(bcs, B_XMTBUFREADY);
587
        }
588
}
589
 
590
inline void
591
check_send(struct IsdnCardState *cs, u_char rdm)
592
{
593
        struct BCState *bcs;
594
 
595
        if (rdm & BSTAT_RDM1) {
596
                if ((bcs = sel_bcs_isar(cs, 1))) {
597
                        if (bcs->mode) {
598
                                send_frames(bcs);
599
                        }
600
                }
601
        }
602
        if (rdm & BSTAT_RDM2) {
603
                if ((bcs = sel_bcs_isar(cs, 2))) {
604
                        if (bcs->mode) {
605
                                send_frames(bcs);
606
                        }
607
                }
608
        }
609
 
610
}
611
 
612
static char debbuf[64];
613
 
614
void
615
isar_int_main(struct IsdnCardState *cs)
616
{
617
        long flags;
618
        struct isar_reg *ireg = cs->bcs[0].hw.isar.reg;
619
        struct BCState *bcs;
620
 
621
        save_flags(flags);
622
        cli();
623
        get_irq_infos(cs, ireg);
624
        switch (ireg->iis & ISAR_IIS_MSCMSD) {
625
                case ISAR_IIS_RDATA:
626
                        if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
627
                                isar_rcv_frame(cs, bcs);
628
                        } else {
629
                                debugl1(cs, "isar spurious IIS_RDATA %x/%x/%x",
630
                                        ireg->iis, ireg->cmsb, ireg->clsb);
631
                                printk(KERN_WARNING"isar spurious IIS_RDATA %x/%x/%x\n",
632
                                        ireg->iis, ireg->cmsb, ireg->clsb);
633
                                cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
634
                        }
635
                        break;
636
                case ISAR_IIS_GSTEV:
637
                        cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
638
                        ireg->bstat |= ireg->cmsb;
639
                        check_send(cs, ireg->cmsb);
640
                        break;
641
                case ISAR_IIS_BSTEV:
642
                        cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
643
                        if (cs->debug & L1_DEB_WARN)
644
                                debugl1(cs, "Buffer STEV dpath%d msb(%x)",
645
                                        ireg->iis>>6, ireg->cmsb);
646
                        break;
647
                case ISAR_IIS_DIAG:
648
                case ISAR_IIS_PSTRSP:
649
                case ISAR_IIS_PSTEV:
650
                case ISAR_IIS_BSTRSP:
651
                case ISAR_IIS_IOM2RSP:
652
                        rcv_mbox(cs, ireg, (u_char *)ireg->par);
653
                        if ((cs->debug & (L1_DEB_HSCX | L1_DEB_HSCX_FIFO))
654
                                == L1_DEB_HSCX) {
655
                                u_char *tp=debbuf;
656
 
657
                                tp += sprintf(debbuf, "msg iis(%x) msb(%x)",
658
                                        ireg->iis, ireg->cmsb);
659
                                QuickHex(tp, (u_char *)ireg->par, ireg->clsb);
660
                                debugl1(cs, debbuf);
661
                        }
662
                        break;
663
                default:
664
                        rcv_mbox(cs, ireg, debbuf);
665
                        if (cs->debug & L1_DEB_WARN)
666
                                debugl1(cs, "unhandled msg iis(%x) ctrl(%x/%x)",
667
                                        ireg->iis, ireg->cmsb, ireg->clsb);
668
                        break;
669
        }
670
        restore_flags(flags);
671
}
672
 
673
void
674
setup_pump(struct BCState *bcs) {
675
        struct IsdnCardState *cs = bcs->cs;
676
        u_char dps = SET_DPS(bcs->hw.isar.dpath);
677
 
678
        switch (bcs->mode) {
679
                case L1_MODE_NULL:
680
                case L1_MODE_TRANS:
681
                case L1_MODE_HDLC:
682
                        if (!sendmsg(cs, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL)) {
683
                                if (cs->debug)
684
                                        debugl1(cs, "isar pump bypass cfg dp%d failed",
685
                                                bcs->hw.isar.dpath);
686
                        }
687
                        break;
688
        }
689
        if (!sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL)) {
690
                if (cs->debug)
691
                        debugl1(cs, "isar pump status req dp%d failed",
692
                                bcs->hw.isar.dpath);
693
        }
694
}
695
 
696
void
697
setup_sart(struct BCState *bcs) {
698
        struct IsdnCardState *cs = bcs->cs;
699
        u_char dps = SET_DPS(bcs->hw.isar.dpath);
700
 
701
        switch (bcs->mode) {
702
                case L1_MODE_NULL:
703
                        if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE, 0, NULL)) {
704
                                if (cs->debug)
705
                                        debugl1(cs, "isar sart disable dp%d failed",
706
                                                bcs->hw.isar.dpath);
707
                        }
708
                        break;
709
                case L1_MODE_TRANS:
710
                        if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_BINARY, 2, "\0\0")) {
711
                                if (cs->debug)
712
                                        debugl1(cs, "isar sart binary dp%d failed",
713
                                                bcs->hw.isar.dpath);
714
                        }
715
                        break;
716
                case L1_MODE_HDLC:
717
                        if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1, "\0")) {
718
                                if (cs->debug)
719
                                        debugl1(cs, "isar sart binary dp%d failed",
720
                                                bcs->hw.isar.dpath);
721
                        }
722
                        break;
723
        }
724
        if (!sendmsg(cs, dps | ISAR_HIS_BSTREQ, 0, 0, NULL)) {
725
                if (cs->debug)
726
                        debugl1(cs, "isar buf stat req dp%d failed",
727
                                bcs->hw.isar.dpath);
728
        }
729
}
730
 
731
void
732
setup_iom2(struct BCState *bcs) {
733
        struct IsdnCardState *cs = bcs->cs;
734
        u_char dps = SET_DPS(bcs->hw.isar.dpath);
735
        u_char cmsb = 0, msg[5] = {0x10,0,0,0,0};
736
 
737
        switch (bcs->mode) {
738
                case L1_MODE_NULL:
739
                        /* dummy slot */
740
                        msg[1] = msg[3] = bcs->hw.isar.dpath + 2;
741
                        break;
742
                case L1_MODE_TRANS:
743
                case L1_MODE_HDLC:
744
                        cmsb = 0x80;
745
                        if (bcs->channel)
746
                                msg[1] = msg[3] = 1;
747
                        break;
748
        }
749
        if (!sendmsg(cs, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg)) {
750
                if (cs->debug)
751
                        debugl1(cs, "isar iom2 dp%d failed", bcs->hw.isar.dpath);
752
        }
753
        if (!sendmsg(cs, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL)) {
754
                if (cs->debug)
755
                        debugl1(cs, "isar IOM2 cfg req dp%d failed",
756
                                bcs->hw.isar.dpath);
757
        }
758
}
759
 
760
int
761
modeisar(struct BCState *bcs, int mode, int bc)
762
{
763
        struct IsdnCardState *cs = bcs->cs;
764
 
765
        /* Here we are selecting the best datapath for requested mode */
766
        if(bcs->mode == L1_MODE_NULL) { /* New Setup */
767
                bcs->channel = bc;
768
                switch (mode) {
769
                        case L1_MODE_NULL: /* init */
770
                                break;
771
                        case L1_MODE_TRANS:
772
                        case L1_MODE_HDLC:
773
                                /* best is datapath 2 */
774
                                if (!test_and_set_bit(ISAR_DP2_USE,
775
                                        &bcs->hw.isar.reg->Flags))
776
                                        bcs->hw.isar.dpath = 2;
777
                                else if (!test_and_set_bit(ISAR_DP1_USE,
778
                                        &bcs->hw.isar.reg->Flags))
779
                                        bcs->hw.isar.dpath = 1;
780
                                else {
781
                                        printk(KERN_ERR"isar modeisar both pathes in use\n");
782
                                        return(1);
783
                                }
784
                                break;
785
                }
786
        }
787
        if (cs->debug & L1_DEB_HSCX)
788
                debugl1(cs, "isar dp%d mode %d->%d ichan %d",
789
                        bcs->hw.isar.dpath, bcs->mode, mode, bc);
790
        bcs->mode = mode;
791
        setup_pump(bcs);
792
        setup_sart(bcs);
793
        setup_iom2(bcs);
794
        if (bcs->mode == L1_MODE_NULL) {
795
                /* Clear resources */
796
                if (bcs->hw.isar.dpath == 1)
797
                        test_and_clear_bit(ISAR_DP1_USE, &bcs->hw.isar.reg->Flags);
798
                else if (bcs->hw.isar.dpath == 2)
799
                        test_and_clear_bit(ISAR_DP2_USE, &bcs->hw.isar.reg->Flags);
800
                bcs->hw.isar.dpath = 0;
801
        }
802
        return(0);
803
}
804
 
805
void
806
isar_setup(struct IsdnCardState *cs)
807
{
808
        u_char msg;
809
        int i;
810
 
811
        /* Dpath 1, 2 */
812
        msg = 61;
813
        for (i=0; i<2; i++) {
814
                /* Buffer Config */
815
                if (!sendmsg(cs, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
816
                        ISAR_HIS_P12CFG, 4, 1, &msg)) {
817
                        if (cs->debug)
818
                                debugl1(cs, "isar P%dCFG failed", i+1);
819
                }
820
                cs->bcs[i].hw.isar.mml = msg;
821
                cs->bcs[i].mode = 0;
822
                cs->bcs[i].hw.isar.dpath = i + 1;
823
                modeisar(&cs->bcs[i], 0, 0);
824
        }
825
}
826
 
827
void
828
isar_l2l1(struct PStack *st, int pr, void *arg)
829
{
830
        struct sk_buff *skb = arg;
831
        long flags;
832
 
833
        switch (pr) {
834
                case (PH_DATA | REQUEST):
835
                        save_flags(flags);
836
                        cli();
837
                        if (st->l1.bcs->tx_skb) {
838
                                skb_queue_tail(&st->l1.bcs->squeue, skb);
839
                                restore_flags(flags);
840
                        } else {
841
                                st->l1.bcs->tx_skb = skb;
842
                                test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
843
                                if (st->l1.bcs->cs->debug & L1_DEB_HSCX)
844
                                        debugl1(st->l1.bcs->cs, "DRQ set BC_FLG_BUSY");
845
                                st->l1.bcs->hw.isar.txcnt = 0;
846
                                restore_flags(flags);
847
                                st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
848
                        }
849
                        break;
850
                case (PH_PULL | INDICATION):
851
                        if (st->l1.bcs->tx_skb) {
852
                                printk(KERN_WARNING "isar_l2l1: this shouldn't happen\n");
853
                                break;
854
                        }
855
                        test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
856
                        if (st->l1.bcs->cs->debug & L1_DEB_HSCX)
857
                                debugl1(st->l1.bcs->cs, "PUI set BC_FLG_BUSY");
858
                        st->l1.bcs->tx_skb = skb;
859
                        st->l1.bcs->hw.isar.txcnt = 0;
860
                        st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
861
                        break;
862
                case (PH_PULL | REQUEST):
863
                        if (!st->l1.bcs->tx_skb) {
864
                                test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
865
                                st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
866
                        } else
867
                                test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
868
                        break;
869
                case (PH_ACTIVATE | REQUEST):
870
                        test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
871
                        modeisar(st->l1.bcs, st->l1.mode, st->l1.bc);
872
                        l1_msg_b(st, pr, arg);
873
                        break;
874
                case (PH_DEACTIVATE | REQUEST):
875
                        l1_msg_b(st, pr, arg);
876
                        break;
877
                case (PH_DEACTIVATE | CONFIRM):
878
                        test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
879
                        test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
880
                        if (st->l1.bcs->cs->debug & L1_DEB_HSCX)
881
                                debugl1(st->l1.bcs->cs, "PDAC clear BC_FLG_BUSY");
882
                        modeisar(st->l1.bcs, 0, st->l1.bc);
883
                        st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
884
                        break;
885
        }
886
}
887
 
888
void
889
close_isarstate(struct BCState *bcs)
890
{
891
        modeisar(bcs, 0, bcs->channel);
892
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
893
                if (bcs->hw.isar.rcvbuf) {
894
                        kfree(bcs->hw.isar.rcvbuf);
895
                        bcs->hw.isar.rcvbuf = NULL;
896
                }
897
                discard_queue(&bcs->rqueue);
898
                discard_queue(&bcs->squeue);
899
                if (bcs->tx_skb) {
900
                        dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
901
                        bcs->tx_skb = NULL;
902
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
903
                        if (bcs->cs->debug & L1_DEB_HSCX)
904
                                debugl1(bcs->cs, "closeisar clear BC_FLG_BUSY");
905
                }
906
        }
907
}
908
 
909
int
910
open_isarstate(struct IsdnCardState *cs, struct BCState *bcs)
911
{
912
        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
913
                if (!(bcs->hw.isar.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
914
                        printk(KERN_WARNING
915
                               "HiSax: No memory for isar.rcvbuf\n");
916
                        return (1);
917
                }
918
                skb_queue_head_init(&bcs->rqueue);
919
                skb_queue_head_init(&bcs->squeue);
920
        }
921
        bcs->tx_skb = NULL;
922
        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
923
        if (cs->debug & L1_DEB_HSCX)
924
                debugl1(cs, "openisar clear BC_FLG_BUSY");
925
        bcs->event = 0;
926
        bcs->hw.isar.rcvidx = 0;
927
        bcs->tx_cnt = 0;
928
        return (0);
929
}
930
 
931
int
932
setstack_isar(struct PStack *st, struct BCState *bcs)
933
{
934
        bcs->channel = st->l1.bc;
935
        if (open_isarstate(st->l1.hardware, bcs))
936
                return (-1);
937
        st->l1.bcs = bcs;
938
        st->l2.l2l1 = isar_l2l1;
939
        setstack_manager(st);
940
        bcs->st = st;
941
        setstack_l1_B(st);
942
        return (0);
943
}
944
 
945
HISAX_INITFUNC(void
946
initisar(struct IsdnCardState *cs))
947
{
948
        cs->bcs[0].BC_SetStack = setstack_isar;
949
        cs->bcs[1].BC_SetStack = setstack_isar;
950
        cs->bcs[0].BC_Close = close_isarstate;
951
        cs->bcs[1].BC_Close = close_isarstate;
952
}

powered by: WebSVN 2.1.0

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