Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/isdn/hisax/hfc_2bds0.c
15115 views
1
/* $Id: hfc_2bds0.c,v 1.18.2.6 2004/02/11 13:21:33 keil Exp $
2
*
3
* specific routines for CCD's HFC 2BDS0
4
*
5
* Author Karsten Keil
6
* Copyright by Karsten Keil <[email protected]>
7
*
8
* This software may be used and distributed according to the terms
9
* of the GNU General Public License, incorporated herein by reference.
10
*
11
*/
12
13
#include <linux/init.h>
14
#include <linux/sched.h>
15
#include <linux/slab.h>
16
#include "hisax.h"
17
#include "hfc_2bds0.h"
18
#include "isdnl1.h"
19
#include <linux/interrupt.h>
20
/*
21
#define KDEBUG_DEF
22
#include "kdebug.h"
23
*/
24
25
#define byteout(addr,val) outb(val,addr)
26
#define bytein(addr) inb(addr)
27
28
static void
29
dummyf(struct IsdnCardState *cs, u_char * data, int size)
30
{
31
printk(KERN_WARNING "HiSax: hfcd dummy fifo called\n");
32
}
33
34
static inline u_char
35
ReadReg(struct IsdnCardState *cs, int data, u_char reg)
36
{
37
register u_char ret;
38
39
if (data) {
40
if (cs->hw.hfcD.cip != reg) {
41
cs->hw.hfcD.cip = reg;
42
byteout(cs->hw.hfcD.addr | 1, reg);
43
}
44
ret = bytein(cs->hw.hfcD.addr);
45
#ifdef HFC_REG_DEBUG
46
if (cs->debug & L1_DEB_HSCX_FIFO && (data != 2))
47
debugl1(cs, "t3c RD %02x %02x", reg, ret);
48
#endif
49
} else
50
ret = bytein(cs->hw.hfcD.addr | 1);
51
return (ret);
52
}
53
54
static inline void
55
WriteReg(struct IsdnCardState *cs, int data, u_char reg, u_char value)
56
{
57
if (cs->hw.hfcD.cip != reg) {
58
cs->hw.hfcD.cip = reg;
59
byteout(cs->hw.hfcD.addr | 1, reg);
60
}
61
if (data)
62
byteout(cs->hw.hfcD.addr, value);
63
#ifdef HFC_REG_DEBUG
64
if (cs->debug & L1_DEB_HSCX_FIFO && (data != HFCD_DATA_NODEB))
65
debugl1(cs, "t3c W%c %02x %02x", data ? 'D' : 'C', reg, value);
66
#endif
67
}
68
69
/* Interface functions */
70
71
static u_char
72
readreghfcd(struct IsdnCardState *cs, u_char offset)
73
{
74
return(ReadReg(cs, HFCD_DATA, offset));
75
}
76
77
static void
78
writereghfcd(struct IsdnCardState *cs, u_char offset, u_char value)
79
{
80
WriteReg(cs, HFCD_DATA, offset, value);
81
}
82
83
static inline int
84
WaitForBusy(struct IsdnCardState *cs)
85
{
86
int to = 130;
87
88
while (!(ReadReg(cs, HFCD_DATA, HFCD_STAT) & HFCD_BUSY) && to) {
89
udelay(1);
90
to--;
91
}
92
if (!to)
93
printk(KERN_WARNING "HiSax: WaitForBusy timeout\n");
94
return (to);
95
}
96
97
static inline int
98
WaitNoBusy(struct IsdnCardState *cs)
99
{
100
int to = 130;
101
102
while ((ReadReg(cs, HFCD_STATUS, HFCD_STATUS) & HFCD_BUSY) && to) {
103
udelay(1);
104
to--;
105
}
106
if (!to)
107
printk(KERN_WARNING "HiSax: WaitNoBusy timeout\n");
108
return (to);
109
}
110
111
static int
112
SelFiFo(struct IsdnCardState *cs, u_char FiFo)
113
{
114
u_char cip;
115
116
if (cs->hw.hfcD.fifo == FiFo)
117
return(1);
118
switch(FiFo) {
119
case 0: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B1;
120
break;
121
case 1: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B1;
122
break;
123
case 2: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B2;
124
break;
125
case 3: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B2;
126
break;
127
case 4: cip = HFCD_FIFO | HFCD_Z1 | HFCD_SEND;
128
break;
129
case 5: cip = HFCD_FIFO | HFCD_Z1 | HFCD_REC;
130
break;
131
default:
132
debugl1(cs, "SelFiFo Error");
133
return(0);
134
}
135
cs->hw.hfcD.fifo = FiFo;
136
WaitNoBusy(cs);
137
cs->BC_Write_Reg(cs, HFCD_DATA, cip, 0);
138
WaitForBusy(cs);
139
return(2);
140
}
141
142
static int
143
GetFreeFifoBytes_B(struct BCState *bcs)
144
{
145
int s;
146
147
if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2)
148
return (bcs->cs->hw.hfcD.bfifosize);
149
s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2];
150
if (s <= 0)
151
s += bcs->cs->hw.hfcD.bfifosize;
152
s = bcs->cs->hw.hfcD.bfifosize - s;
153
return (s);
154
}
155
156
static int
157
GetFreeFifoBytes_D(struct IsdnCardState *cs)
158
{
159
int s;
160
161
if (cs->hw.hfcD.f1 == cs->hw.hfcD.f2)
162
return (cs->hw.hfcD.dfifosize);
163
s = cs->hw.hfcD.send[cs->hw.hfcD.f1] - cs->hw.hfcD.send[cs->hw.hfcD.f2];
164
if (s <= 0)
165
s += cs->hw.hfcD.dfifosize;
166
s = cs->hw.hfcD.dfifosize - s;
167
return (s);
168
}
169
170
static int
171
ReadZReg(struct IsdnCardState *cs, u_char reg)
172
{
173
int val;
174
175
WaitNoBusy(cs);
176
val = 256 * ReadReg(cs, HFCD_DATA, reg | HFCB_Z_HIGH);
177
WaitNoBusy(cs);
178
val += ReadReg(cs, HFCD_DATA, reg | HFCB_Z_LOW);
179
return (val);
180
}
181
182
static struct sk_buff
183
*hfc_empty_fifo(struct BCState *bcs, int count)
184
{
185
u_char *ptr;
186
struct sk_buff *skb;
187
struct IsdnCardState *cs = bcs->cs;
188
int idx;
189
int chksum;
190
u_char stat, cip;
191
192
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
193
debugl1(cs, "hfc_empty_fifo");
194
idx = 0;
195
if (count > HSCX_BUFMAX + 3) {
196
if (cs->debug & L1_DEB_WARN)
197
debugl1(cs, "hfc_empty_fifo: incoming packet too large");
198
cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
199
while (idx++ < count) {
200
WaitNoBusy(cs);
201
ReadReg(cs, HFCD_DATA_NODEB, cip);
202
}
203
skb = NULL;
204
} else if (count < 4) {
205
if (cs->debug & L1_DEB_WARN)
206
debugl1(cs, "hfc_empty_fifo: incoming packet too small");
207
cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
208
#ifdef ERROR_STATISTIC
209
bcs->err_inv++;
210
#endif
211
while ((idx++ < count) && WaitNoBusy(cs))
212
ReadReg(cs, HFCD_DATA_NODEB, cip);
213
skb = NULL;
214
} else if (!(skb = dev_alloc_skb(count - 3)))
215
printk(KERN_WARNING "HFC: receive out of memory\n");
216
else {
217
ptr = skb_put(skb, count - 3);
218
idx = 0;
219
cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
220
while (idx < (count - 3)) {
221
if (!WaitNoBusy(cs))
222
break;
223
*ptr = ReadReg(cs, HFCD_DATA_NODEB, cip);
224
ptr++;
225
idx++;
226
}
227
if (idx != count - 3) {
228
debugl1(cs, "RFIFO BUSY error");
229
printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
230
dev_kfree_skb_irq(skb);
231
skb = NULL;
232
} else {
233
WaitNoBusy(cs);
234
chksum = (ReadReg(cs, HFCD_DATA, cip) << 8);
235
WaitNoBusy(cs);
236
chksum += ReadReg(cs, HFCD_DATA, cip);
237
WaitNoBusy(cs);
238
stat = ReadReg(cs, HFCD_DATA, cip);
239
if (cs->debug & L1_DEB_HSCX)
240
debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
241
bcs->channel, chksum, stat);
242
if (stat) {
243
debugl1(cs, "FIFO CRC error");
244
dev_kfree_skb_irq(skb);
245
skb = NULL;
246
#ifdef ERROR_STATISTIC
247
bcs->err_crc++;
248
#endif
249
}
250
}
251
}
252
WaitForBusy(cs);
253
WaitNoBusy(cs);
254
stat = ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F2_INC |
255
HFCB_REC | HFCB_CHANNEL(bcs->channel));
256
WaitForBusy(cs);
257
return (skb);
258
}
259
260
static void
261
hfc_fill_fifo(struct BCState *bcs)
262
{
263
struct IsdnCardState *cs = bcs->cs;
264
int idx, fcnt;
265
int count;
266
u_char cip;
267
268
if (!bcs->tx_skb)
269
return;
270
if (bcs->tx_skb->len <= 0)
271
return;
272
SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel));
273
cip = HFCB_FIFO | HFCB_F1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
274
WaitNoBusy(cs);
275
bcs->hw.hfc.f1 = ReadReg(cs, HFCD_DATA, cip);
276
WaitNoBusy(cs);
277
cip = HFCB_FIFO | HFCB_F2 | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
278
WaitNoBusy(cs);
279
bcs->hw.hfc.f2 = ReadReg(cs, HFCD_DATA, cip);
280
bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel));
281
if (cs->debug & L1_DEB_HSCX)
282
debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
283
bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
284
bcs->hw.hfc.send[bcs->hw.hfc.f1]);
285
fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
286
if (fcnt < 0)
287
fcnt += 32;
288
if (fcnt > 30) {
289
if (cs->debug & L1_DEB_HSCX)
290
debugl1(cs, "hfc_fill_fifo more as 30 frames");
291
return;
292
}
293
count = GetFreeFifoBytes_B(bcs);
294
if (cs->debug & L1_DEB_HSCX)
295
debugl1(cs, "hfc_fill_fifo %d count(%u/%d),%lx",
296
bcs->channel, bcs->tx_skb->len,
297
count, current->state);
298
if (count < bcs->tx_skb->len) {
299
if (cs->debug & L1_DEB_HSCX)
300
debugl1(cs, "hfc_fill_fifo no fifo mem");
301
return;
302
}
303
cip = HFCB_FIFO | HFCB_FIFO_IN | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
304
idx = 0;
305
WaitForBusy(cs);
306
WaitNoBusy(cs);
307
WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
308
while (idx < bcs->tx_skb->len) {
309
if (!WaitNoBusy(cs))
310
break;
311
WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx]);
312
idx++;
313
}
314
if (idx != bcs->tx_skb->len) {
315
debugl1(cs, "FIFO Send BUSY error");
316
printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
317
} else {
318
bcs->tx_cnt -= bcs->tx_skb->len;
319
if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
320
(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
321
u_long flags;
322
spin_lock_irqsave(&bcs->aclock, flags);
323
bcs->ackcnt += bcs->tx_skb->len;
324
spin_unlock_irqrestore(&bcs->aclock, flags);
325
schedule_event(bcs, B_ACKPENDING);
326
}
327
dev_kfree_skb_any(bcs->tx_skb);
328
bcs->tx_skb = NULL;
329
}
330
WaitForBusy(cs);
331
WaitNoBusy(cs);
332
ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F1_INC | HFCB_SEND | HFCB_CHANNEL(bcs->channel));
333
WaitForBusy(cs);
334
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
335
return;
336
}
337
338
static void
339
hfc_send_data(struct BCState *bcs)
340
{
341
struct IsdnCardState *cs = bcs->cs;
342
343
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
344
hfc_fill_fifo(bcs);
345
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
346
} else
347
debugl1(cs,"send_data %d blocked", bcs->channel);
348
}
349
350
static void
351
main_rec_2bds0(struct BCState *bcs)
352
{
353
struct IsdnCardState *cs = bcs->cs;
354
int z1, z2, rcnt;
355
u_char f1, f2, cip;
356
int receive, count = 5;
357
struct sk_buff *skb;
358
359
Begin:
360
count--;
361
if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
362
debugl1(cs,"rec_data %d blocked", bcs->channel);
363
return;
364
}
365
SelFiFo(cs, HFCB_REC | HFCB_CHANNEL(bcs->channel));
366
cip = HFCB_FIFO | HFCB_F1 | HFCB_REC | HFCB_CHANNEL(bcs->channel);
367
WaitNoBusy(cs);
368
f1 = ReadReg(cs, HFCD_DATA, cip);
369
cip = HFCB_FIFO | HFCB_F2 | HFCB_REC | HFCB_CHANNEL(bcs->channel);
370
WaitNoBusy(cs);
371
f2 = ReadReg(cs, HFCD_DATA, cip);
372
if (f1 != f2) {
373
if (cs->debug & L1_DEB_HSCX)
374
debugl1(cs, "hfc rec %d f1(%d) f2(%d)",
375
bcs->channel, f1, f2);
376
z1 = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_CHANNEL(bcs->channel));
377
z2 = ReadZReg(cs, HFCB_FIFO | HFCB_Z2 | HFCB_REC | HFCB_CHANNEL(bcs->channel));
378
rcnt = z1 - z2;
379
if (rcnt < 0)
380
rcnt += cs->hw.hfcD.bfifosize;
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
if ((skb = hfc_empty_fifo(bcs, rcnt))) {
386
skb_queue_tail(&bcs->rqueue, skb);
387
schedule_event(bcs, B_RCVBUFREADY);
388
}
389
rcnt = f1 -f2;
390
if (rcnt<0)
391
rcnt += 32;
392
if (rcnt>1)
393
receive = 1;
394
else
395
receive = 0;
396
} else
397
receive = 0;
398
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
399
if (count && receive)
400
goto Begin;
401
return;
402
}
403
404
static void
405
mode_2bs0(struct BCState *bcs, int mode, int bc)
406
{
407
struct IsdnCardState *cs = bcs->cs;
408
409
if (cs->debug & L1_DEB_HSCX)
410
debugl1(cs, "HFCD bchannel mode %d bchan %d/%d",
411
mode, bc, bcs->channel);
412
bcs->mode = mode;
413
bcs->channel = bc;
414
switch (mode) {
415
case (L1_MODE_NULL):
416
if (bc) {
417
cs->hw.hfcD.conn |= 0x18;
418
cs->hw.hfcD.sctrl &= ~SCTRL_B2_ENA;
419
} else {
420
cs->hw.hfcD.conn |= 0x3;
421
cs->hw.hfcD.sctrl &= ~SCTRL_B1_ENA;
422
}
423
break;
424
case (L1_MODE_TRANS):
425
if (bc) {
426
cs->hw.hfcD.ctmt |= 2;
427
cs->hw.hfcD.conn &= ~0x18;
428
cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
429
} else {
430
cs->hw.hfcD.ctmt |= 1;
431
cs->hw.hfcD.conn &= ~0x3;
432
cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
433
}
434
break;
435
case (L1_MODE_HDLC):
436
if (bc) {
437
cs->hw.hfcD.ctmt &= ~2;
438
cs->hw.hfcD.conn &= ~0x18;
439
cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
440
} else {
441
cs->hw.hfcD.ctmt &= ~1;
442
cs->hw.hfcD.conn &= ~0x3;
443
cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
444
}
445
break;
446
}
447
WriteReg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl);
448
WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt);
449
WriteReg(cs, HFCD_DATA, HFCD_CONN, cs->hw.hfcD.conn);
450
}
451
452
static void
453
hfc_l2l1(struct PStack *st, int pr, void *arg)
454
{
455
struct BCState *bcs = st->l1.bcs;
456
struct sk_buff *skb = arg;
457
u_long flags;
458
459
switch (pr) {
460
case (PH_DATA | REQUEST):
461
spin_lock_irqsave(&bcs->cs->lock, flags);
462
if (bcs->tx_skb) {
463
skb_queue_tail(&bcs->squeue, skb);
464
} else {
465
bcs->tx_skb = skb;
466
// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
467
bcs->cs->BC_Send_Data(bcs);
468
}
469
spin_unlock_irqrestore(&bcs->cs->lock, flags);
470
break;
471
case (PH_PULL | INDICATION):
472
spin_lock_irqsave(&bcs->cs->lock, flags);
473
if (bcs->tx_skb) {
474
printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
475
} else {
476
// test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
477
bcs->tx_skb = skb;
478
bcs->cs->BC_Send_Data(bcs);
479
}
480
spin_unlock_irqrestore(&bcs->cs->lock, flags);
481
break;
482
case (PH_PULL | REQUEST):
483
if (!bcs->tx_skb) {
484
test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
485
st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
486
} else
487
test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
488
break;
489
case (PH_ACTIVATE | REQUEST):
490
spin_lock_irqsave(&bcs->cs->lock, flags);
491
test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
492
mode_2bs0(bcs, st->l1.mode, st->l1.bc);
493
spin_unlock_irqrestore(&bcs->cs->lock, flags);
494
l1_msg_b(st, pr, arg);
495
break;
496
case (PH_DEACTIVATE | REQUEST):
497
l1_msg_b(st, pr, arg);
498
break;
499
case (PH_DEACTIVATE | CONFIRM):
500
spin_lock_irqsave(&bcs->cs->lock, flags);
501
test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
502
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
503
mode_2bs0(bcs, 0, st->l1.bc);
504
spin_unlock_irqrestore(&bcs->cs->lock, flags);
505
st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
506
break;
507
}
508
}
509
510
static void
511
close_2bs0(struct BCState *bcs)
512
{
513
mode_2bs0(bcs, 0, bcs->channel);
514
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
515
skb_queue_purge(&bcs->rqueue);
516
skb_queue_purge(&bcs->squeue);
517
if (bcs->tx_skb) {
518
dev_kfree_skb_any(bcs->tx_skb);
519
bcs->tx_skb = NULL;
520
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
521
}
522
}
523
}
524
525
static int
526
open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
527
{
528
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
529
skb_queue_head_init(&bcs->rqueue);
530
skb_queue_head_init(&bcs->squeue);
531
}
532
bcs->tx_skb = NULL;
533
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
534
bcs->event = 0;
535
bcs->tx_cnt = 0;
536
return (0);
537
}
538
539
static int
540
setstack_2b(struct PStack *st, struct BCState *bcs)
541
{
542
bcs->channel = st->l1.bc;
543
if (open_hfcstate(st->l1.hardware, bcs))
544
return (-1);
545
st->l1.bcs = bcs;
546
st->l2.l2l1 = hfc_l2l1;
547
setstack_manager(st);
548
bcs->st = st;
549
setstack_l1_B(st);
550
return (0);
551
}
552
553
static void
554
hfcd_bh(struct work_struct *work)
555
{
556
struct IsdnCardState *cs =
557
container_of(work, struct IsdnCardState, tqueue);
558
559
if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
560
switch (cs->dc.hfcd.ph_state) {
561
case (0):
562
l1_msg(cs, HW_RESET | INDICATION, NULL);
563
break;
564
case (3):
565
l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
566
break;
567
case (8):
568
l1_msg(cs, HW_RSYNC | INDICATION, NULL);
569
break;
570
case (6):
571
l1_msg(cs, HW_INFO2 | INDICATION, NULL);
572
break;
573
case (7):
574
l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
575
break;
576
default:
577
break;
578
}
579
}
580
if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
581
DChannel_proc_rcv(cs);
582
if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
583
DChannel_proc_xmt(cs);
584
}
585
586
static
587
int receive_dmsg(struct IsdnCardState *cs)
588
{
589
struct sk_buff *skb;
590
int idx;
591
int rcnt, z1, z2;
592
u_char stat, cip, f1, f2;
593
int chksum;
594
int count=5;
595
u_char *ptr;
596
597
if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
598
debugl1(cs, "rec_dmsg blocked");
599
return(1);
600
}
601
SelFiFo(cs, 4 | HFCD_REC);
602
cip = HFCD_FIFO | HFCD_F1 | HFCD_REC;
603
WaitNoBusy(cs);
604
f1 = cs->readisac(cs, cip) & 0xf;
605
cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
606
WaitNoBusy(cs);
607
f2 = cs->readisac(cs, cip) & 0xf;
608
while ((f1 != f2) && count--) {
609
z1 = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_REC);
610
z2 = ReadZReg(cs, HFCD_FIFO | HFCD_Z2 | HFCD_REC);
611
rcnt = z1 - z2;
612
if (rcnt < 0)
613
rcnt += cs->hw.hfcD.dfifosize;
614
rcnt++;
615
if (cs->debug & L1_DEB_ISAC)
616
debugl1(cs, "hfcd recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)",
617
f1, f2, z1, z2, rcnt);
618
idx = 0;
619
cip = HFCD_FIFO | HFCD_FIFO_OUT | HFCD_REC;
620
if (rcnt > MAX_DFRAME_LEN + 3) {
621
if (cs->debug & L1_DEB_WARN)
622
debugl1(cs, "empty_fifo d: incoming packet too large");
623
while (idx < rcnt) {
624
if (!(WaitNoBusy(cs)))
625
break;
626
ReadReg(cs, HFCD_DATA_NODEB, cip);
627
idx++;
628
}
629
} else if (rcnt < 4) {
630
if (cs->debug & L1_DEB_WARN)
631
debugl1(cs, "empty_fifo d: incoming packet too small");
632
while ((idx++ < rcnt) && WaitNoBusy(cs))
633
ReadReg(cs, HFCD_DATA_NODEB, cip);
634
} else if ((skb = dev_alloc_skb(rcnt - 3))) {
635
ptr = skb_put(skb, rcnt - 3);
636
while (idx < (rcnt - 3)) {
637
if (!(WaitNoBusy(cs)))
638
break;
639
*ptr = ReadReg(cs, HFCD_DATA_NODEB, cip);
640
idx++;
641
ptr++;
642
}
643
if (idx != (rcnt - 3)) {
644
debugl1(cs, "RFIFO D BUSY error");
645
printk(KERN_WARNING "HFC DFIFO channel BUSY Error\n");
646
dev_kfree_skb_irq(skb);
647
skb = NULL;
648
#ifdef ERROR_STATISTIC
649
cs->err_rx++;
650
#endif
651
} else {
652
WaitNoBusy(cs);
653
chksum = (ReadReg(cs, HFCD_DATA, cip) << 8);
654
WaitNoBusy(cs);
655
chksum += ReadReg(cs, HFCD_DATA, cip);
656
WaitNoBusy(cs);
657
stat = ReadReg(cs, HFCD_DATA, cip);
658
if (cs->debug & L1_DEB_ISAC)
659
debugl1(cs, "empty_dfifo chksum %x stat %x",
660
chksum, stat);
661
if (stat) {
662
debugl1(cs, "FIFO CRC error");
663
dev_kfree_skb_irq(skb);
664
skb = NULL;
665
#ifdef ERROR_STATISTIC
666
cs->err_crc++;
667
#endif
668
} else {
669
skb_queue_tail(&cs->rq, skb);
670
schedule_event(cs, D_RCVBUFREADY);
671
}
672
}
673
} else
674
printk(KERN_WARNING "HFC: D receive out of memory\n");
675
WaitForBusy(cs);
676
cip = HFCD_FIFO | HFCD_F2_INC | HFCD_REC;
677
WaitNoBusy(cs);
678
stat = ReadReg(cs, HFCD_DATA, cip);
679
WaitForBusy(cs);
680
cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
681
WaitNoBusy(cs);
682
f2 = cs->readisac(cs, cip) & 0xf;
683
}
684
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
685
return(1);
686
}
687
688
static void
689
hfc_fill_dfifo(struct IsdnCardState *cs)
690
{
691
int idx, fcnt;
692
int count;
693
u_char cip;
694
695
if (!cs->tx_skb)
696
return;
697
if (cs->tx_skb->len <= 0)
698
return;
699
700
SelFiFo(cs, 4 | HFCD_SEND);
701
cip = HFCD_FIFO | HFCD_F1 | HFCD_SEND;
702
WaitNoBusy(cs);
703
cs->hw.hfcD.f1 = ReadReg(cs, HFCD_DATA, cip) & 0xf;
704
WaitNoBusy(cs);
705
cip = HFCD_FIFO | HFCD_F2 | HFCD_SEND;
706
cs->hw.hfcD.f2 = ReadReg(cs, HFCD_DATA, cip) & 0xf;
707
cs->hw.hfcD.send[cs->hw.hfcD.f1] = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_SEND);
708
if (cs->debug & L1_DEB_ISAC)
709
debugl1(cs, "hfc_fill_Dfifo f1(%d) f2(%d) z1(%x)",
710
cs->hw.hfcD.f1, cs->hw.hfcD.f2,
711
cs->hw.hfcD.send[cs->hw.hfcD.f1]);
712
fcnt = cs->hw.hfcD.f1 - cs->hw.hfcD.f2;
713
if (fcnt < 0)
714
fcnt += 16;
715
if (fcnt > 14) {
716
if (cs->debug & L1_DEB_HSCX)
717
debugl1(cs, "hfc_fill_Dfifo more as 14 frames");
718
return;
719
}
720
count = GetFreeFifoBytes_D(cs);
721
if (cs->debug & L1_DEB_ISAC)
722
debugl1(cs, "hfc_fill_Dfifo count(%u/%d)",
723
cs->tx_skb->len, count);
724
if (count < cs->tx_skb->len) {
725
if (cs->debug & L1_DEB_ISAC)
726
debugl1(cs, "hfc_fill_Dfifo no fifo mem");
727
return;
728
}
729
cip = HFCD_FIFO | HFCD_FIFO_IN | HFCD_SEND;
730
idx = 0;
731
WaitForBusy(cs);
732
WaitNoBusy(cs);
733
WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx++]);
734
while (idx < cs->tx_skb->len) {
735
if (!(WaitNoBusy(cs)))
736
break;
737
WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx]);
738
idx++;
739
}
740
if (idx != cs->tx_skb->len) {
741
debugl1(cs, "DFIFO Send BUSY error");
742
printk(KERN_WARNING "HFC S DFIFO channel BUSY Error\n");
743
}
744
WaitForBusy(cs);
745
WaitNoBusy(cs);
746
ReadReg(cs, HFCD_DATA, HFCD_FIFO | HFCD_F1_INC | HFCD_SEND);
747
dev_kfree_skb_any(cs->tx_skb);
748
cs->tx_skb = NULL;
749
WaitForBusy(cs);
750
return;
751
}
752
753
static
754
struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
755
{
756
if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
757
return(&cs->bcs[0]);
758
else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
759
return(&cs->bcs[1]);
760
else
761
return(NULL);
762
}
763
764
void
765
hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
766
{
767
u_char exval;
768
struct BCState *bcs;
769
int count=15;
770
771
if (cs->debug & L1_DEB_ISAC)
772
debugl1(cs, "HFCD irq %x %s", val,
773
test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ?
774
"locked" : "unlocked");
775
val &= cs->hw.hfcD.int_m1;
776
if (val & 0x40) { /* TE state machine irq */
777
exval = cs->readisac(cs, HFCD_STATES) & 0xf;
778
if (cs->debug & L1_DEB_ISAC)
779
debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcd.ph_state,
780
exval);
781
cs->dc.hfcd.ph_state = exval;
782
schedule_event(cs, D_L1STATECHANGE);
783
val &= ~0x40;
784
}
785
while (val) {
786
if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
787
cs->hw.hfcD.int_s1 |= val;
788
return;
789
}
790
if (cs->hw.hfcD.int_s1 & 0x18) {
791
exval = val;
792
val = cs->hw.hfcD.int_s1;
793
cs->hw.hfcD.int_s1 = exval;
794
}
795
if (val & 0x08) {
796
if (!(bcs=Sel_BCS(cs, 0))) {
797
if (cs->debug)
798
debugl1(cs, "hfcd spurious 0x08 IRQ");
799
} else
800
main_rec_2bds0(bcs);
801
}
802
if (val & 0x10) {
803
if (!(bcs=Sel_BCS(cs, 1))) {
804
if (cs->debug)
805
debugl1(cs, "hfcd spurious 0x10 IRQ");
806
} else
807
main_rec_2bds0(bcs);
808
}
809
if (val & 0x01) {
810
if (!(bcs=Sel_BCS(cs, 0))) {
811
if (cs->debug)
812
debugl1(cs, "hfcd spurious 0x01 IRQ");
813
} else {
814
if (bcs->tx_skb) {
815
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
816
hfc_fill_fifo(bcs);
817
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
818
} else
819
debugl1(cs,"fill_data %d blocked", bcs->channel);
820
} else {
821
if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
822
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
823
hfc_fill_fifo(bcs);
824
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
825
} else
826
debugl1(cs,"fill_data %d blocked", bcs->channel);
827
} else {
828
schedule_event(bcs, B_XMTBUFREADY);
829
}
830
}
831
}
832
}
833
if (val & 0x02) {
834
if (!(bcs=Sel_BCS(cs, 1))) {
835
if (cs->debug)
836
debugl1(cs, "hfcd spurious 0x02 IRQ");
837
} else {
838
if (bcs->tx_skb) {
839
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
840
hfc_fill_fifo(bcs);
841
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
842
} else
843
debugl1(cs,"fill_data %d blocked", bcs->channel);
844
} else {
845
if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
846
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
847
hfc_fill_fifo(bcs);
848
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
849
} else
850
debugl1(cs,"fill_data %d blocked", bcs->channel);
851
} else {
852
schedule_event(bcs, B_XMTBUFREADY);
853
}
854
}
855
}
856
}
857
if (val & 0x20) { /* receive dframe */
858
receive_dmsg(cs);
859
}
860
if (val & 0x04) { /* dframe transmitted */
861
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
862
del_timer(&cs->dbusytimer);
863
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
864
schedule_event(cs, D_CLEARBUSY);
865
if (cs->tx_skb) {
866
if (cs->tx_skb->len) {
867
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
868
hfc_fill_dfifo(cs);
869
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
870
} else {
871
debugl1(cs, "hfc_fill_dfifo irq blocked");
872
}
873
goto afterXPR;
874
} else {
875
dev_kfree_skb_irq(cs->tx_skb);
876
cs->tx_cnt = 0;
877
cs->tx_skb = NULL;
878
}
879
}
880
if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
881
cs->tx_cnt = 0;
882
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
883
hfc_fill_dfifo(cs);
884
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
885
} else {
886
debugl1(cs, "hfc_fill_dfifo irq blocked");
887
}
888
} else
889
schedule_event(cs, D_XMTBUFREADY);
890
}
891
afterXPR:
892
if (cs->hw.hfcD.int_s1 && count--) {
893
val = cs->hw.hfcD.int_s1;
894
cs->hw.hfcD.int_s1 = 0;
895
if (cs->debug & L1_DEB_ISAC)
896
debugl1(cs, "HFCD irq %x loop %d", val, 15-count);
897
} else
898
val = 0;
899
}
900
}
901
902
static void
903
HFCD_l1hw(struct PStack *st, int pr, void *arg)
904
{
905
struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
906
struct sk_buff *skb = arg;
907
u_long flags;
908
909
switch (pr) {
910
case (PH_DATA | REQUEST):
911
if (cs->debug & DEB_DLOG_HEX)
912
LogFrame(cs, skb->data, skb->len);
913
if (cs->debug & DEB_DLOG_VERBOSE)
914
dlogframe(cs, skb, 0);
915
spin_lock_irqsave(&cs->lock, flags);
916
if (cs->tx_skb) {
917
skb_queue_tail(&cs->sq, skb);
918
#ifdef L2FRAME_DEBUG /* psa */
919
if (cs->debug & L1_DEB_LAPD)
920
Logl2Frame(cs, skb, "PH_DATA Queued", 0);
921
#endif
922
} else {
923
cs->tx_skb = skb;
924
cs->tx_cnt = 0;
925
#ifdef L2FRAME_DEBUG /* psa */
926
if (cs->debug & L1_DEB_LAPD)
927
Logl2Frame(cs, skb, "PH_DATA", 0);
928
#endif
929
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
930
hfc_fill_dfifo(cs);
931
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
932
} else
933
debugl1(cs, "hfc_fill_dfifo blocked");
934
935
}
936
spin_unlock_irqrestore(&cs->lock, flags);
937
break;
938
case (PH_PULL | INDICATION):
939
spin_lock_irqsave(&cs->lock, flags);
940
if (cs->tx_skb) {
941
if (cs->debug & L1_DEB_WARN)
942
debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
943
skb_queue_tail(&cs->sq, skb);
944
spin_unlock_irqrestore(&cs->lock, flags);
945
break;
946
}
947
if (cs->debug & DEB_DLOG_HEX)
948
LogFrame(cs, skb->data, skb->len);
949
if (cs->debug & DEB_DLOG_VERBOSE)
950
dlogframe(cs, skb, 0);
951
cs->tx_skb = skb;
952
cs->tx_cnt = 0;
953
#ifdef L2FRAME_DEBUG /* psa */
954
if (cs->debug & L1_DEB_LAPD)
955
Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
956
#endif
957
if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
958
hfc_fill_dfifo(cs);
959
test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
960
} else
961
debugl1(cs, "hfc_fill_dfifo blocked");
962
spin_unlock_irqrestore(&cs->lock, flags);
963
break;
964
case (PH_PULL | REQUEST):
965
#ifdef L2FRAME_DEBUG /* psa */
966
if (cs->debug & L1_DEB_LAPD)
967
debugl1(cs, "-> PH_REQUEST_PULL");
968
#endif
969
if (!cs->tx_skb) {
970
test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
971
st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
972
} else
973
test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
974
break;
975
case (HW_RESET | REQUEST):
976
spin_lock_irqsave(&cs->lock, flags);
977
cs->writeisac(cs, HFCD_STATES, HFCD_LOAD_STATE | 3); /* HFC ST 3 */
978
udelay(6);
979
cs->writeisac(cs, HFCD_STATES, 3); /* HFC ST 2 */
980
cs->hw.hfcD.mst_m |= HFCD_MASTER;
981
cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
982
cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
983
spin_unlock_irqrestore(&cs->lock, flags);
984
l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
985
break;
986
case (HW_ENABLE | REQUEST):
987
spin_lock_irqsave(&cs->lock, flags);
988
cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
989
spin_unlock_irqrestore(&cs->lock, flags);
990
break;
991
case (HW_DEACTIVATE | REQUEST):
992
spin_lock_irqsave(&cs->lock, flags);
993
cs->hw.hfcD.mst_m &= ~HFCD_MASTER;
994
cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
995
spin_unlock_irqrestore(&cs->lock, flags);
996
break;
997
case (HW_INFO3 | REQUEST):
998
spin_lock_irqsave(&cs->lock, flags);
999
cs->hw.hfcD.mst_m |= HFCD_MASTER;
1000
cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
1001
spin_unlock_irqrestore(&cs->lock, flags);
1002
break;
1003
default:
1004
if (cs->debug & L1_DEB_WARN)
1005
debugl1(cs, "hfcd_l1hw unknown pr %4x", pr);
1006
break;
1007
}
1008
}
1009
1010
static void
1011
setstack_hfcd(struct PStack *st, struct IsdnCardState *cs)
1012
{
1013
st->l1.l1hw = HFCD_l1hw;
1014
}
1015
1016
static void
1017
hfc_dbusy_timer(struct IsdnCardState *cs)
1018
{
1019
}
1020
1021
static unsigned int
1022
*init_send_hfcd(int cnt)
1023
{
1024
int i;
1025
unsigned *send;
1026
1027
if (!(send = kmalloc(cnt * sizeof(unsigned int), GFP_ATOMIC))) {
1028
printk(KERN_WARNING
1029
"HiSax: No memory for hfcd.send\n");
1030
return(NULL);
1031
}
1032
for (i = 0; i < cnt; i++)
1033
send[i] = 0x1fff;
1034
return(send);
1035
}
1036
1037
void
1038
init2bds0(struct IsdnCardState *cs)
1039
{
1040
cs->setstack_d = setstack_hfcd;
1041
if (!cs->hw.hfcD.send)
1042
cs->hw.hfcD.send = init_send_hfcd(16);
1043
if (!cs->bcs[0].hw.hfc.send)
1044
cs->bcs[0].hw.hfc.send = init_send_hfcd(32);
1045
if (!cs->bcs[1].hw.hfc.send)
1046
cs->bcs[1].hw.hfc.send = init_send_hfcd(32);
1047
cs->BC_Send_Data = &hfc_send_data;
1048
cs->bcs[0].BC_SetStack = setstack_2b;
1049
cs->bcs[1].BC_SetStack = setstack_2b;
1050
cs->bcs[0].BC_Close = close_2bs0;
1051
cs->bcs[1].BC_Close = close_2bs0;
1052
mode_2bs0(cs->bcs, 0, 0);
1053
mode_2bs0(cs->bcs + 1, 0, 1);
1054
}
1055
1056
void
1057
release2bds0(struct IsdnCardState *cs)
1058
{
1059
kfree(cs->bcs[0].hw.hfc.send);
1060
cs->bcs[0].hw.hfc.send = NULL;
1061
kfree(cs->bcs[1].hw.hfc.send);
1062
cs->bcs[1].hw.hfc.send = NULL;
1063
kfree(cs->hw.hfcD.send);
1064
cs->hw.hfcD.send = NULL;
1065
}
1066
1067
void
1068
set_cs_func(struct IsdnCardState *cs)
1069
{
1070
cs->readisac = &readreghfcd;
1071
cs->writeisac = &writereghfcd;
1072
cs->readisacfifo = &dummyf;
1073
cs->writeisacfifo = &dummyf;
1074
cs->BC_Read_Reg = &ReadReg;
1075
cs->BC_Write_Reg = &WriteReg;
1076
cs->dbusytimer.function = (void *) hfc_dbusy_timer;
1077
cs->dbusytimer.data = (long) cs;
1078
init_timer(&cs->dbusytimer);
1079
INIT_WORK(&cs->tqueue, hfcd_bh);
1080
}
1081
1082