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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [hisax/] [isar.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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