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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 1626 jcastillo
/* $Id: hfc_2bs0.c,v 1.1 2005-12-20 10:17:01 jcastillo Exp $
2
 
3
 *  specific routines for CCD's HFC 2BS0
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.8  1998/11/03 00:06:29  keil
16
 * certification related changes
17
 * fixed logging for smaller stack use
18
 *
19
 * Revision 1.1.2.7  1998/09/30 22:23:59  keil
20
 * Fix missing line in setstack*
21
 *
22
 * Revision 1.1.2.6  1998/09/27 13:06:05  keil
23
 * Apply most changes from 2.1.X (HiSax 3.1)
24
 *
25
 * Revision 1.1.2.5  1998/05/27 18:05:27  keil
26
 * HiSax 3.0
27
 *
28
 * Revision 1.1.2.4  1998/04/08 21:54:38  keil
29
 * Fix "ll_trans ..." message
30
 *
31
 * Revision 1.1.2.3  1998/04/04 21:59:23  keil
32
 * Fixed B-channel access
33
 *
34
 * Revision 1.1.2.2  1997/11/15 18:54:27  keil
35
 * cosmetics
36
 *
37
 * Revision 1.1.2.1  1997/10/17 22:10:41  keil
38
 * new files on 2.0
39
 *
40
 * Revision 1.1  1997/09/11 17:31:33  keil
41
 * Common part for HFC 2BS0 based cards
42
 *
43
 *
44
 */
45
 
46
#define __NO_VERSION__
47
#include "hisax.h"
48
#include "hfc_2bs0.h"
49
#include "isac.h"
50
#include "isdnl1.h"
51
#include <linux/interrupt.h>
52
 
53
static inline int
54
WaitForBusy(struct IsdnCardState *cs)
55
{
56
        int to = 130;
57
        long flags;
58
        u_char val;
59
 
60
        save_flags(flags);
61
        cli();
62
        while (!(cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) {
63
                val = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2 |
64
                                      (cs->hw.hfc.cip & 3));
65
                udelay(1);
66
                to--;
67
        }
68
        restore_flags(flags);
69
        if (!to) {
70
                printk(KERN_WARNING "HiSax: waitforBusy timeout\n");
71
                return (0);
72
        } else
73
                return (to);
74
}
75
 
76
static inline int
77
WaitNoBusy(struct IsdnCardState *cs)
78
{
79
        int to = 125;
80
 
81
        while ((cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) {
82
                udelay(1);
83
                to--;
84
        }
85
        if (!to) {
86
                printk(KERN_WARNING "HiSax: waitforBusy timeout\n");
87
                return (0);
88
        } else
89
                return (to);
90
}
91
 
92
int
93
GetFreeFifoBytes(struct BCState *bcs)
94
{
95
        int s;
96
 
97
        if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2)
98
                return (bcs->cs->hw.hfc.fifosize);
99
        s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2];
100
        if (s <= 0)
101
                s += bcs->cs->hw.hfc.fifosize;
102
        s = bcs->cs->hw.hfc.fifosize - s;
103
        return (s);
104
}
105
 
106
int
107
ReadZReg(struct BCState *bcs, u_char reg)
108
{
109
        int val;
110
 
111
        WaitNoBusy(bcs->cs);
112
        val = 256 * bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_HIGH);
113
        WaitNoBusy(bcs->cs);
114
        val += bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_LOW);
115
        return (val);
116
}
117
 
118
void
119
hfc_sched_event(struct BCState *bcs, int event)
120
{
121
        bcs->event |= 1 << event;
122
        queue_task(&bcs->tqueue, &tq_immediate);
123
        mark_bh(IMMEDIATE_BH);
124
}
125
 
126
static void
127
hfc_clear_fifo(struct BCState *bcs)
128
{
129
        struct IsdnCardState *cs = bcs->cs;
130
        long flags;
131
        int idx, cnt;
132
        int rcnt, z1, z2;
133
        u_char cip, f1, f2;
134
 
135
        if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
136
                debugl1(cs, "hfc_clear_fifo");
137
        save_flags(flags);
138
        cli();
139
        cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
140
        if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
141
                cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
142
                WaitForBusy(cs);
143
        }
144
        WaitNoBusy(cs);
145
        f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
146
        cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
147
        WaitNoBusy(cs);
148
        f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
149
        z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
150
        z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
151
        cnt = 32;
152
        while (((f1 != f2) || (z1 != z2)) && cnt--) {
153
                if (cs->debug & L1_DEB_HSCX)
154
                        debugl1(cs, "hfc clear %d f1(%d) f2(%d)",
155
                                bcs->channel, f1, f2);
156
                rcnt = z1 - z2;
157
                if (rcnt < 0)
158
                        rcnt += cs->hw.hfc.fifosize;
159
                if (rcnt)
160
                        rcnt++;
161
                if (cs->debug & L1_DEB_HSCX)
162
                        debugl1(cs, "hfc clear %d z1(%x) z2(%x) cnt(%d)",
163
                                bcs->channel, z1, z2, rcnt);
164
                cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
165
                idx = 0;
166
                while ((idx < rcnt) && WaitNoBusy(cs)) {
167
                        cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
168
                        idx++;
169
                }
170
                if (f1 != f2) {
171
                        WaitNoBusy(cs);
172
                        cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
173
                                        HFC_CHANNEL(bcs->channel));
174
                        WaitForBusy(cs);
175
                }
176
                cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
177
                WaitNoBusy(cs);
178
                f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
179
                cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
180
                WaitNoBusy(cs);
181
                f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
182
                z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
183
                z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
184
        }
185
        restore_flags(flags);
186
        return;
187
}
188
 
189
 
190
static struct sk_buff
191
*
192
hfc_empty_fifo(struct BCState *bcs, int count)
193
{
194
        u_char *ptr;
195
        struct sk_buff *skb;
196
        struct IsdnCardState *cs = bcs->cs;
197
        int idx;
198
        int chksum;
199
        u_char stat, cip;
200
 
201
        if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
202
                debugl1(cs, "hfc_empty_fifo");
203
        idx = 0;
204
        if (count > HSCX_BUFMAX + 3) {
205
                if (cs->debug & L1_DEB_WARN)
206
                        debugl1(cs, "hfc_empty_fifo: incoming packet too large");
207
                cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
208
                while ((idx++ < count) && WaitNoBusy(cs))
209
                        cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
210
                WaitNoBusy(cs);
211
                stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
212
                                       HFC_CHANNEL(bcs->channel));
213
                WaitForBusy(cs);
214
                return (NULL);
215
        }
216
        if (count < 4) {
217
                if (cs->debug & L1_DEB_WARN)
218
                        debugl1(cs, "hfc_empty_fifo: incoming packet too small");
219
                cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
220
                while ((idx++ < count) && WaitNoBusy(cs))
221
                        cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
222
                WaitNoBusy(cs);
223
                stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
224
                                       HFC_CHANNEL(bcs->channel));
225
                WaitForBusy(cs);
226
                return (NULL);
227
        }
228
        if (!(skb = dev_alloc_skb(count - 3)))
229
                printk(KERN_WARNING "HFC: receive out of memory\n");
230
        else {
231
                SET_SKB_FREE(skb);
232
                ptr = skb_put(skb, count - 3);
233
                idx = 0;
234
                cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
235
                while ((idx < count - 3) && WaitNoBusy(cs)) {
236
                        *ptr++ = cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
237
                        idx++;
238
                }
239
                if (idx != count - 3) {
240
                        debugl1(cs, "RFIFO BUSY error");
241
                        printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
242
                        dev_kfree_skb(skb, FREE_READ);
243
                        WaitNoBusy(cs);
244
                        stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
245
                                               HFC_CHANNEL(bcs->channel));
246
                        WaitForBusy(cs);
247
                        return (NULL);
248
                }
249
                WaitNoBusy(cs);
250
                chksum = (cs->BC_Read_Reg(cs, HFC_DATA, cip) << 8);
251
                WaitNoBusy(cs);
252
                chksum += cs->BC_Read_Reg(cs, HFC_DATA, cip);
253
                WaitNoBusy(cs);
254
                stat = cs->BC_Read_Reg(cs, HFC_DATA, cip);
255
                if (cs->debug & L1_DEB_HSCX)
256
                        debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
257
                                bcs->channel, chksum, stat);
258
                if (stat) {
259
                        debugl1(cs, "FIFO CRC error");
260
                        dev_kfree_skb(skb, FREE_READ);
261
                        skb = NULL;
262
                }
263
                WaitNoBusy(cs);
264
                stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
265
                                       HFC_CHANNEL(bcs->channel));
266
                WaitForBusy(cs);
267
        }
268
        return (skb);
269
}
270
 
271
static void
272
hfc_fill_fifo(struct BCState *bcs)
273
{
274
        struct IsdnCardState *cs = bcs->cs;
275
        long flags;
276
        int idx, fcnt;
277
        int count;
278
        u_char cip;
279
 
280
        if (!bcs->tx_skb)
281
                return;
282
        if (bcs->tx_skb->len <= 0)
283
                return;
284
 
285
        save_flags(flags);
286
        cli();
287
        cip = HFC_CIP | HFC_F1 | HFC_SEND | HFC_CHANNEL(bcs->channel);
288
        if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
289
                cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
290
                WaitForBusy(cs);
291
        }
292
        WaitNoBusy(cs);
293
        bcs->hw.hfc.f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
294
        cip = HFC_CIP | HFC_F2 | HFC_SEND | HFC_CHANNEL(bcs->channel);
295
        WaitNoBusy(cs);
296
        bcs->hw.hfc.f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
297
        bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(bcs, HFC_Z1 | HFC_SEND | HFC_CHANNEL(bcs->channel));
298
        if (cs->debug & L1_DEB_HSCX)
299
                debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
300
                        bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
301
                        bcs->hw.hfc.send[bcs->hw.hfc.f1]);
302
        fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
303
        if (fcnt < 0)
304
                fcnt += 32;
305
        if (fcnt > 30) {
306
                if (cs->debug & L1_DEB_HSCX)
307
                        debugl1(cs, "hfc_fill_fifo more as 30 frames");
308
                restore_flags(flags);
309
                return;
310
        }
311
        count = GetFreeFifoBytes(bcs);
312
        if (cs->debug & L1_DEB_HSCX)
313
                debugl1(cs, "hfc_fill_fifo %d count(%ld/%d)",
314
                        bcs->channel, bcs->tx_skb->len,
315
                        count);
316
        if (count < bcs->tx_skb->len) {
317
                if (cs->debug & L1_DEB_HSCX)
318
                        debugl1(cs, "hfc_fill_fifo no fifo mem");
319
                restore_flags(flags);
320
                return;
321
        }
322
        cip = HFC_CIP | HFC_FIFO_IN | HFC_SEND | HFC_CHANNEL(bcs->channel);
323
        idx = 0;
324
        while ((idx < bcs->tx_skb->len) && WaitNoBusy(cs))
325
                cs->BC_Write_Reg(cs, HFC_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
326
        if (idx != bcs->tx_skb->len) {
327
                debugl1(cs, "FIFO Send BUSY error");
328
                printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
329
        } else {
330
                count =  bcs->tx_skb->len;
331
                bcs->tx_cnt -= count;
332
                if (PACKET_NOACK == bcs->tx_skb->pkt_type)
333
                        count = -1;
334
                dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
335
                bcs->tx_skb = NULL;
336
                WaitForBusy(cs);
337
                WaitNoBusy(cs);
338
                cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel));
339
                if (bcs->st->lli.l1writewakeup && (count >= 0))
340
                        bcs->st->lli.l1writewakeup(bcs->st, count);
341
                test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
342
        }
343
        restore_flags(flags);
344
        return;
345
}
346
 
347
void
348
main_irq_hfc(struct BCState *bcs)
349
{
350
        long flags;
351
        struct IsdnCardState *cs = bcs->cs;
352
        int z1, z2, rcnt;
353
        u_char f1, f2, cip;
354
        int receive, transmit, count = 5;
355
        struct sk_buff *skb;
356
 
357
        save_flags(flags);
358
      Begin:
359
        cli();
360
        count--;
361
        cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
362
        if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
363
                cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
364
                WaitForBusy(cs);
365
        }
366
        WaitNoBusy(cs);
367
        f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
368
        cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
369
        WaitNoBusy(cs);
370
        f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
371
        if (f1 != f2) {
372
                if (cs->debug & L1_DEB_HSCX)
373
                        debugl1(cs, "hfc rec %d f1(%d) f2(%d)",
374
                                bcs->channel, f1, f2);
375
                WaitForBusy(cs);
376
                z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
377
                z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
378
                rcnt = z1 - z2;
379
                if (rcnt < 0)
380
                        rcnt += cs->hw.hfc.fifosize;
381
                rcnt++;
382
                if (cs->debug & L1_DEB_HSCX)
383
                        debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)",
384
                                bcs->channel, z1, z2, rcnt);
385
/*              sti(); */
386
                if ((skb = hfc_empty_fifo(bcs, rcnt))) {
387
                        skb_queue_tail(&bcs->rqueue, skb);
388
                        hfc_sched_event(bcs, B_RCVBUFREADY);
389
                }
390
                receive = 1;
391
        } else
392
                receive = 0;
393
        restore_flags(flags);
394
        udelay(1);
395
        cli();
396
        if (bcs->tx_skb) {
397
                transmit = 1;
398
                test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
399
                hfc_fill_fifo(bcs);
400
                if (test_bit(BC_FLG_BUSY, &bcs->Flag))
401
                        transmit = 0;
402
        } else {
403
                if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
404
                        transmit = 1;
405
                        test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
406
                        hfc_fill_fifo(bcs);
407
                        if (test_bit(BC_FLG_BUSY, &bcs->Flag))
408
                                transmit = 0;
409
                } else {
410
                        transmit = 0;
411
                        hfc_sched_event(bcs, B_XMTBUFREADY);
412
                }
413
        }
414
        restore_flags(flags);
415
        if ((receive || transmit) && count)
416
                goto Begin;
417
        return;
418
}
419
 
420
void
421
mode_hfc(struct BCState *bcs, int mode, int bc)
422
{
423
        struct IsdnCardState *cs = bcs->cs;
424
 
425
        if (cs->debug & L1_DEB_HSCX)
426
                debugl1(cs, "HFC 2BS0 mode %d bchan %d/%d",
427
                        mode, bc, bcs->channel);
428
        bcs->mode = mode;
429
        bcs->channel = bc;
430
 
431
        switch (mode) {
432
                case (L1_MODE_NULL):
433
                        if (bc)
434
                                cs->hw.hfc.isac_spcr &= ~0x03;
435
                        else
436
                                cs->hw.hfc.isac_spcr &= ~0x0c;
437
                        break;
438
                case (L1_MODE_TRANS):
439
                        if (bc) {
440
                                cs->hw.hfc.ctmt |= 1;
441
                                cs->hw.hfc.isac_spcr &= ~0x03;
442
                                cs->hw.hfc.isac_spcr |= 0x02;
443
                        } else {
444
                                cs->hw.hfc.ctmt |= 2;
445
                                cs->hw.hfc.isac_spcr &= ~0x0c;
446
                                cs->hw.hfc.isac_spcr |= 0x08;
447
                        }
448
                        break;
449
                case (L1_MODE_HDLC):
450
                        if (bc) {
451
                                cs->hw.hfc.ctmt &= ~1;
452
                                cs->hw.hfc.isac_spcr &= ~0x03;
453
                                cs->hw.hfc.isac_spcr |= 0x02;
454
                        } else {
455
                                cs->hw.hfc.ctmt &= ~2;
456
                                cs->hw.hfc.isac_spcr &= ~0x0c;
457
                                cs->hw.hfc.isac_spcr |= 0x08;
458
                        }
459
                        break;
460
        }
461
        cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);
462
        cs->writeisac(cs, ISAC_SPCR, cs->hw.hfc.isac_spcr);
463
        if (mode)
464
                hfc_clear_fifo(bcs);
465
}
466
 
467
static void
468
hfc_l2l1(struct PStack *st, int pr, void *arg)
469
{
470
        struct sk_buff *skb = arg;
471
        long flags;
472
 
473
        switch (pr) {
474
                case (PH_DATA | REQUEST):
475
                        save_flags(flags);
476
                        cli();
477
                        if (st->l1.bcs->tx_skb) {
478
                                skb_queue_tail(&st->l1.bcs->squeue, skb);
479
                                restore_flags(flags);
480
                        } else {
481
                                st->l1.bcs->tx_skb = skb;
482
                                test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
483
                                st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
484
                                restore_flags(flags);
485
                        }
486
                        break;
487
                case (PH_PULL | INDICATION):
488
                        if (st->l1.bcs->tx_skb) {
489
                                printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
490
                                break;
491
                        }
492
                        save_flags(flags);
493
                        cli();
494
                        test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
495
                        st->l1.bcs->tx_skb = skb;
496
                        st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
497
                        restore_flags(flags);
498
                        break;
499
                case (PH_PULL | REQUEST):
500
                        if (!st->l1.bcs->tx_skb) {
501
                                test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
502
                                st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
503
                        } else
504
                                test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
505
                        break;
506
                case (PH_ACTIVATE | REQUEST):
507
                        test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
508
                        mode_hfc(st->l1.bcs, st->l1.mode, st->l1.bc);
509
                        l1_msg_b(st, pr, arg);
510
                        break;
511
                case (PH_DEACTIVATE | REQUEST):
512
                        l1_msg_b(st, pr, arg);
513
                        break;
514
                case (PH_DEACTIVATE | CONFIRM):
515
                        test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
516
                        test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
517
                        mode_hfc(st->l1.bcs, 0, st->l1.bc);
518
                        st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
519
                        break;
520
        }
521
}
522
 
523
 
524
void
525
close_hfcstate(struct BCState *bcs)
526
{
527
        mode_hfc(bcs, 0, bcs->channel);
528
        if (test_bit(BC_FLG_INIT, &bcs->Flag)) {
529
                discard_queue(&bcs->rqueue);
530
                discard_queue(&bcs->squeue);
531
                if (bcs->tx_skb) {
532
                        dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
533
                        bcs->tx_skb = NULL;
534
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
535
                }
536
        }
537
        test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
538
}
539
 
540
static int
541
open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
542
{
543
        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
544
                skb_queue_head_init(&bcs->rqueue);
545
                skb_queue_head_init(&bcs->squeue);
546
        }
547
        bcs->tx_skb = NULL;
548
        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
549
        bcs->event = 0;
550
        bcs->tx_cnt = 0;
551
        return (0);
552
}
553
 
554
int
555
setstack_hfc(struct PStack *st, struct BCState *bcs)
556
{
557
        bcs->channel = st->l1.bc;
558
        if (open_hfcstate(st->l1.hardware, bcs))
559
                return (-1);
560
        st->l1.bcs = bcs;
561
        st->l2.l2l1 = hfc_l2l1;
562
        setstack_manager(st);
563
        bcs->st = st;
564
        setstack_l1_B(st);
565
        return (0);
566
}
567
 
568
__initfunc(void
569
init_send(struct BCState *bcs))
570
{
571
        int i;
572
 
573
        if (!(bcs->hw.hfc.send = kmalloc(32 * sizeof(unsigned int), GFP_ATOMIC))) {
574
                printk(KERN_WARNING
575
                       "HiSax: No memory for hfc.send\n");
576
                return;
577
        }
578
        for (i = 0; i < 32; i++)
579
                bcs->hw.hfc.send[i] = 0x1fff;
580
}
581
 
582
__initfunc(void
583
inithfc(struct IsdnCardState *cs))
584
{
585
        init_send(&cs->bcs[0]);
586
        init_send(&cs->bcs[1]);
587
        cs->BC_Send_Data = &hfc_fill_fifo;
588
        cs->bcs[0].BC_SetStack = setstack_hfc;
589
        cs->bcs[1].BC_SetStack = setstack_hfc;
590
        cs->bcs[0].BC_Close = close_hfcstate;
591
        cs->bcs[1].BC_Close = close_hfcstate;
592
        mode_hfc(cs->bcs, 0, 0);
593
        mode_hfc(cs->bcs + 1, 0, 0);
594
}
595
 
596
void
597
releasehfc(struct IsdnCardState *cs)
598
{
599
        if (cs->bcs[0].hw.hfc.send) {
600
                kfree(cs->bcs[0].hw.hfc.send);
601
                cs->bcs[0].hw.hfc.send = NULL;
602
        }
603
        if (cs->bcs[1].hw.hfc.send) {
604
                kfree(cs->bcs[1].hw.hfc.send);
605
                cs->bcs[1].hw.hfc.send = NULL;
606
        }
607
}

powered by: WebSVN 2.1.0

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