1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56#include "hisax.h"
57#include "isdnl1.h"
58#include "isac.h"
59#include "amd7930_fn.h"
60#include <linux/interrupt.h>
61#include <linux/init.h>
62#include <linux/gfp.h>
63
64static void Amd7930_new_ph(struct IsdnCardState *cs);
65
66static WORD initAMD[] = {
67 0x0100,
68
69 0x00A5, 3, 0x01, 0x40, 0x58,
70 0x0086, 1, 0x0B,
71 0x0087, 1, 0xFF,
72 0x0092, 1, 0x03,
73 0x0090, 4, 0xFE, 0xFF, 0x02, 0x0F,
74 0x0084, 2, 0x80, 0x00,
75 0x00C0, 1, 0x47,
76 0x00C8, 1, 0x01,
77
78 0x0102,
79 0x0107,
80 0x01A1, 1,
81 0x0121, 1,
82 0x0189, 2,
83
84 0x0045, 4, 0x61, 0x72, 0x00, 0x00,
85 0x0063, 2, 0x08, 0x08,
86 0x0064, 2, 0x08, 0x08,
87 0x0065, 2, 0x99, 0x00,
88 0x0066, 2, 0x7C, 0x8B,
89 0x0067, 2, 0x00, 0x00,
90 0x0068, 2, 0x20, 0x20,
91 0x0069, 1, 0x4F,
92 0x006A, 1, 0x00,
93 0x006C, 1, 0x40,
94 0x0021, 1, 0x02,
95 0x00A3, 1, 0x40,
96
97 0xFFFF
98};
99
100
101static void
102WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val)
103{
104 wByteAMD(cs, 0x00, reg);
105 wByteAMD(cs, 0x01, LOBYTE(val));
106 wByteAMD(cs, 0x01, HIBYTE(val));
107}
108
109static WORD
110ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg)
111{
112 WORD res;
113
114 if (reg < 8) {
115 res = rByteAMD(cs, reg);
116 res += 256 * rByteAMD(cs, reg);
117 }
118
119 else {
120 wByteAMD(cs, 0x00, reg);
121 res = rByteAMD(cs, 0x01);
122 res += 256 * rByteAMD(cs, 0x01);
123 }
124 return (res);
125}
126
127
128static void
129Amd7930_ph_command(struct IsdnCardState *cs, u_char command, char *s)
130{
131 if (cs->debug & L1_DEB_ISAC)
132 debugl1(cs, "AMD7930: %s: ph_command 0x%02X", s, command);
133
134 cs->dc.amd7930.lmr1 = command;
135 wByteAMD(cs, 0xA3, command);
136}
137
138
139
140static BYTE i430States[] = {
141
142 0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,
143 0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,
144 0x01, 0x02, 0x00, 0x00, 0x00, 0x09, 0x05, 0x04,
145 0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
146 0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
147 0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00,
148 0x11, 0x13, 0x00, 0x00, 0x1B, 0x00, 0x15, 0x00,
149 0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
150 0x01, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x0A};
151
152
153
154static BYTE stateHelper[] = { 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
155
156
157
158
159static void
160Amd7930_get_state(struct IsdnCardState *cs) {
161 BYTE lsr = rByteAMD(cs, 0xA1);
162 cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
163 Amd7930_new_ph(cs);
164}
165
166
167
168static void
169Amd7930_new_ph(struct IsdnCardState *cs)
170{
171 u_char index = stateHelper[cs->dc.amd7930.old_state] * 8 + stateHelper[cs->dc.amd7930.ph_state] - 1;
172 u_char message = i430States[index];
173
174 if (cs->debug & L1_DEB_ISAC)
175 debugl1(cs, "AMD7930: new_ph %d, old_ph %d, message %d, index %d",
176 cs->dc.amd7930.ph_state, cs->dc.amd7930.old_state, message & 0x0f, index);
177
178 cs->dc.amd7930.old_state = cs->dc.amd7930.ph_state;
179
180
181 if ((message & 0xf0) && (cs->tx_skb)) {
182 wByteAMD(cs, 0x21, 0xC2);
183 wByteAMD(cs, 0x21, 0x02);
184 }
185
186 switch (message & 0x0f) {
187
188 case (1):
189 l1_msg(cs, HW_RESET | INDICATION, NULL);
190 Amd7930_get_state(cs);
191 break;
192 case (2):
193 l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
194 break;
195 case (3):
196 l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
197 break;
198 case (4):
199 l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
200 Amd7930_ph_command(cs, 0x50, "HW_ENABLE REQUEST");
201 break;
202 case (5):
203 l1_msg(cs, HW_RSYNC | INDICATION, NULL);
204 break;
205 case (6):
206 l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
207 break;
208 case (7):
209 l1_msg(cs, HW_RSYNC | INDICATION, NULL);
210 l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
211 break;
212 case (8):
213 l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
214
215 case (9):
216 Amd7930_ph_command(cs, 0x40, "HW_ENABLE REQ cleared if set");
217 l1_msg(cs, HW_RSYNC | INDICATION, NULL);
218 l1_msg(cs, HW_INFO2 | INDICATION, NULL);
219 l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
220 break;
221 case (10):
222 Amd7930_ph_command(cs, 0x40, "T3 expired, HW_ENABLE REQ cleared");
223 cs->dc.amd7930.old_state = 3;
224 break;
225 case (11):
226 l1_msg(cs, HW_INFO2 | INDICATION, NULL);
227 break;
228 default:
229 break;
230 }
231}
232
233
234
235static void
236Amd7930_bh(struct work_struct *work)
237{
238 struct IsdnCardState *cs =
239 container_of(work, struct IsdnCardState, tqueue);
240 struct PStack *stptr;
241
242 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
243 if (cs->debug)
244 debugl1(cs, "Amd7930: bh, D-Channel Busy cleared");
245 stptr = cs->stlist;
246 while (stptr != NULL) {
247 stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
248 stptr = stptr->next;
249 }
250 }
251 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
252 if (cs->debug & L1_DEB_ISAC)
253 debugl1(cs, "AMD7930: bh, D_L1STATECHANGE");
254 Amd7930_new_ph(cs);
255 }
256
257 if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
258 if (cs->debug & L1_DEB_ISAC)
259 debugl1(cs, "AMD7930: bh, D_RCVBUFREADY");
260 DChannel_proc_rcv(cs);
261 }
262
263 if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
264 if (cs->debug & L1_DEB_ISAC)
265 debugl1(cs, "AMD7930: bh, D_XMTBUFREADY");
266 DChannel_proc_xmt(cs);
267 }
268}
269
270static void
271Amd7930_empty_Dfifo(struct IsdnCardState *cs, int flag)
272{
273
274 BYTE stat, der;
275 BYTE *ptr;
276 struct sk_buff *skb;
277
278
279 if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
280 debugl1(cs, "Amd7930: empty_Dfifo");
281
282
283 ptr = cs->rcvbuf + cs->rcvidx;
284
285
286 AmdIrqOff(cs);
287
288
289 stat = rByteAMD(cs, 0x07);
290
291
292 while ((stat & 2) && ((ptr-cs->rcvbuf) < MAX_DFRAME_LEN_L1)) {
293 *ptr = rByteAMD(cs, 0x04);
294 ptr++;
295 stat = rByteAMD(cs, 0x07);
296 cs->rcvidx = ptr - cs->rcvbuf;
297
298
299 if (stat & 1) {
300
301 der = rWordAMD(cs, 0x03);
302
303
304 if (!der && !flag) {
305 rWordAMD(cs, 0x89);
306
307 if ((cs->rcvidx) > 0) {
308 if (!(skb = alloc_skb(cs->rcvidx, GFP_ATOMIC)))
309 printk(KERN_WARNING "HiSax: Amd7930: empty_Dfifo, D receive out of memory!\n");
310 else {
311
312 if (cs->debug & L1_DEB_ISAC_FIFO) {
313 char *t = cs->dlog;
314
315 t += sprintf(t, "Amd7930: empty_Dfifo cnt: %d |", cs->rcvidx);
316 QuickHex(t, cs->rcvbuf, cs->rcvidx);
317 debugl1(cs, "%s", cs->dlog);
318 }
319
320 skb_put_data(skb, cs->rcvbuf,
321 cs->rcvidx);
322 skb_queue_tail(&cs->rq, skb);
323 }
324 }
325
326 }
327
328 ptr = cs->rcvbuf;
329 cs->rcvidx = 0;
330 schedule_event(cs, D_RCVBUFREADY);
331 }
332 }
333
334 if (cs->rcvidx >= MAX_DFRAME_LEN_L1) {
335 if (cs->debug & L1_DEB_WARN)
336 debugl1(cs, "AMD7930: empty_Dfifo L2-Framelength overrun");
337 cs->rcvidx = 0;
338 return;
339 }
340
341 AmdIrqOn(cs);
342}
343
344
345static void
346Amd7930_fill_Dfifo(struct IsdnCardState *cs)
347{
348
349 WORD dtcrr, dtcrw, len, count;
350 BYTE txstat, dmr3;
351 BYTE *ptr, *deb_ptr;
352
353 if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
354 debugl1(cs, "Amd7930: fill_Dfifo");
355
356 if ((!cs->tx_skb) || (cs->tx_skb->len <= 0))
357 return;
358
359 dtcrw = 0;
360 if (!cs->dc.amd7930.tx_xmtlen)
361
362 len = dtcrw = cs->tx_skb->len;
363
364 else len = cs->dc.amd7930.tx_xmtlen;
365
366
367
368 AmdIrqOff(cs);
369
370 deb_ptr = ptr = cs->tx_skb->data;
371
372
373 txstat = 0x10;
374 while ((txstat & 0x10) && (cs->tx_cnt < len)) {
375 wByteAMD(cs, 0x04, *ptr);
376 ptr++;
377 cs->tx_cnt++;
378 txstat = rByteAMD(cs, 0x07);
379 }
380 count = ptr - cs->tx_skb->data;
381 skb_pull(cs->tx_skb, count);
382
383
384 dtcrr = rWordAMD(cs, 0x85);
385 dmr3 = rByteAMD(cs, 0x8E);
386
387 if (cs->debug & L1_DEB_ISAC) {
388 debugl1(cs, "Amd7930: fill_Dfifo, DMR3: 0x%02X, DTCR read: 0x%04X write: 0x%02X 0x%02X", dmr3, dtcrr, LOBYTE(dtcrw), HIBYTE(dtcrw));
389 }
390
391
392 if (!cs->dc.amd7930.tx_xmtlen) {
393 wWordAMD(cs, 0x85, dtcrw);
394 cs->dc.amd7930.tx_xmtlen = dtcrw;
395 }
396
397 if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
398 debugl1(cs, "Amd7930: fill_Dfifo dbusytimer running");
399 del_timer(&cs->dbusytimer);
400 }
401 init_timer(&cs->dbusytimer);
402 cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
403 add_timer(&cs->dbusytimer);
404
405 if (cs->debug & L1_DEB_ISAC_FIFO) {
406 char *t = cs->dlog;
407
408 t += sprintf(t, "Amd7930: fill_Dfifo cnt: %d |", count);
409 QuickHex(t, deb_ptr, count);
410 debugl1(cs, "%s", cs->dlog);
411 }
412
413 AmdIrqOn(cs);
414}
415
416
417void Amd7930_interrupt(struct IsdnCardState *cs, BYTE irflags)
418{
419 BYTE dsr1, dsr2, lsr;
420 WORD der;
421
422 while (irflags)
423 {
424
425 dsr1 = rByteAMD(cs, 0x02);
426 der = rWordAMD(cs, 0x03);
427 dsr2 = rByteAMD(cs, 0x07);
428 lsr = rByteAMD(cs, 0xA1);
429
430 if (cs->debug & L1_DEB_ISAC)
431 debugl1(cs, "Amd7930: interrupt: flags: 0x%02X, DSR1: 0x%02X, DSR2: 0x%02X, LSR: 0x%02X, DER=0x%04X", irflags, dsr1, dsr2, lsr, der);
432
433
434 if (der || (dsr2 & 4)) {
435
436 if (cs->debug & L1_DEB_WARN)
437 debugl1(cs, "Amd7930: interrupt: D error DER=0x%04X", der);
438
439
440 if (der & 2) {
441 wByteAMD(cs, 0x21, 0xC2);
442 wByteAMD(cs, 0x21, 0x02);
443 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
444 del_timer(&cs->dbusytimer);
445 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
446 schedule_event(cs, D_CLEARBUSY);
447
448 if (cs->tx_skb) {
449 skb_push(cs->tx_skb, cs->tx_cnt);
450 cs->tx_cnt = 0;
451 cs->dc.amd7930.tx_xmtlen = 0;
452 Amd7930_fill_Dfifo(cs);
453 } else {
454 printk(KERN_WARNING "HiSax: Amd7930 D-Collision, no skb\n");
455 debugl1(cs, "Amd7930: interrupt: D-Collision, no skb");
456 }
457 }
458
459 Amd7930_empty_Dfifo(cs, 1);
460
461 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
462 del_timer(&cs->dbusytimer);
463 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
464 schedule_event(cs, D_CLEARBUSY);
465
466 if (cs->tx_skb) {
467 skb_push(cs->tx_skb, cs->tx_cnt);
468 cs->tx_cnt = 0;
469 cs->dc.amd7930.tx_xmtlen = 0;
470 Amd7930_fill_Dfifo(cs);
471 }
472 }
473
474
475 if (irflags & 1) {
476 if (cs->debug & L1_DEB_ISAC)
477 debugl1(cs, "Amd7930: interrupt: clear Timer and fill D-TX-FIFO if data");
478
479
480 AmdIrqOff(cs);
481
482 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
483 del_timer(&cs->dbusytimer);
484 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
485 schedule_event(cs, D_CLEARBUSY);
486 if (cs->tx_skb) {
487 if (cs->tx_skb->len)
488 Amd7930_fill_Dfifo(cs);
489 }
490
491 AmdIrqOn(cs);
492 }
493
494
495
496 if ((irflags & 2) || (dsr1 & 2)) {
497 if (cs->debug & L1_DEB_ISAC)
498 debugl1(cs, "Amd7930: interrupt: empty D-FIFO");
499 Amd7930_empty_Dfifo(cs, 0);
500 }
501
502
503
504 if (dsr1 & 64) {
505 if (cs->debug & L1_DEB_ISAC) {
506 debugl1(cs, "Amd7930: interrupt: transmit packet ready");
507 }
508
509 AmdIrqOff(cs);
510
511 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
512 del_timer(&cs->dbusytimer);
513 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
514 schedule_event(cs, D_CLEARBUSY);
515
516 if (cs->tx_skb) {
517 if (cs->debug & L1_DEB_ISAC)
518 debugl1(cs, "Amd7930: interrupt: TX-Packet ready, freeing skb");
519 dev_kfree_skb_irq(cs->tx_skb);
520 cs->tx_cnt = 0;
521 cs->dc.amd7930.tx_xmtlen = 0;
522 cs->tx_skb = NULL;
523 }
524 if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
525 if (cs->debug & L1_DEB_ISAC)
526 debugl1(cs, "Amd7930: interrupt: TX-Packet ready, next packet dequeued");
527 cs->tx_cnt = 0;
528 cs->dc.amd7930.tx_xmtlen = 0;
529 Amd7930_fill_Dfifo(cs);
530 }
531 else
532 schedule_event(cs, D_XMTBUFREADY);
533
534 AmdIrqOn(cs);
535 }
536
537
538 if (lsr & 0x38) {
539
540 AmdIrqOff(cs);
541
542 if (cs->debug & L1_DEB_ISAC)
543 debugl1(cs, "Amd: interrupt: LSR=0x%02X, LIU is in state %d", lsr, ((lsr & 0x7) + 2));
544
545 cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
546
547 schedule_event(cs, D_L1STATECHANGE);
548
549 AmdIrqOn(cs);
550 }
551
552
553 irflags = rByteAMD(cs, 0x00);
554 }
555
556}
557
558static void
559Amd7930_l1hw(struct PStack *st, int pr, void *arg)
560{
561 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
562 struct sk_buff *skb = arg;
563 u_long flags;
564
565 if (cs->debug & L1_DEB_ISAC)
566 debugl1(cs, "Amd7930: l1hw called, pr: 0x%04X", pr);
567
568 switch (pr) {
569 case (PH_DATA | REQUEST):
570 if (cs->debug & DEB_DLOG_HEX)
571 LogFrame(cs, skb->data, skb->len);
572 if (cs->debug & DEB_DLOG_VERBOSE)
573 dlogframe(cs, skb, 0);
574 spin_lock_irqsave(&cs->lock, flags);
575 if (cs->tx_skb) {
576 skb_queue_tail(&cs->sq, skb);
577#ifdef L2FRAME_DEBUG
578 if (cs->debug & L1_DEB_LAPD)
579 Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA Queued", 0);
580#endif
581 } else {
582 cs->tx_skb = skb;
583 cs->tx_cnt = 0;
584 cs->dc.amd7930.tx_xmtlen = 0;
585#ifdef L2FRAME_DEBUG
586 if (cs->debug & L1_DEB_LAPD)
587 Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA", 0);
588#endif
589 Amd7930_fill_Dfifo(cs);
590 }
591 spin_unlock_irqrestore(&cs->lock, flags);
592 break;
593 case (PH_PULL | INDICATION):
594 spin_lock_irqsave(&cs->lock, flags);
595 if (cs->tx_skb) {
596 if (cs->debug & L1_DEB_WARN)
597 debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen");
598 skb_queue_tail(&cs->sq, skb);
599 spin_unlock_irqrestore(&cs->lock, flags);
600 break;
601 }
602 if (cs->debug & DEB_DLOG_HEX)
603 LogFrame(cs, skb->data, skb->len);
604 if (cs->debug & DEB_DLOG_VERBOSE)
605 dlogframe(cs, skb, 0);
606 cs->tx_skb = skb;
607 cs->tx_cnt = 0;
608 cs->dc.amd7930.tx_xmtlen = 0;
609#ifdef L2FRAME_DEBUG
610 if (cs->debug & L1_DEB_LAPD)
611 Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA_PULLED", 0);
612#endif
613 Amd7930_fill_Dfifo(cs);
614 spin_unlock_irqrestore(&cs->lock, flags);
615 break;
616 case (PH_PULL | REQUEST):
617#ifdef L2FRAME_DEBUG
618 if (cs->debug & L1_DEB_LAPD)
619 debugl1(cs, "Amd7930: l1hw: -> PH_REQUEST_PULL, skb: %s", (cs->tx_skb) ? "yes" : "no");
620#endif
621 if (!cs->tx_skb) {
622 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
623 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
624 } else
625 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
626 break;
627 case (HW_RESET | REQUEST):
628 spin_lock_irqsave(&cs->lock, flags);
629 if ((cs->dc.amd7930.ph_state == 8)) {
630
631
632 Amd7930_ph_command(cs, 0x20, "HW_RESET REQUEST");
633 spin_unlock_irqrestore(&cs->lock, flags);
634 } else {
635 Amd7930_ph_command(cs, 0x40, "HW_RESET REQUEST");
636 cs->dc.amd7930.ph_state = 2;
637 spin_unlock_irqrestore(&cs->lock, flags);
638 Amd7930_new_ph(cs);
639 }
640 break;
641 case (HW_ENABLE | REQUEST):
642 cs->dc.amd7930.ph_state = 9;
643 Amd7930_new_ph(cs);
644 break;
645 case (HW_INFO3 | REQUEST):
646
647 break;
648 case (HW_TESTLOOP | REQUEST):
649
650 break;
651 case (HW_DEACTIVATE | RESPONSE):
652 skb_queue_purge(&cs->rq);
653 skb_queue_purge(&cs->sq);
654 if (cs->tx_skb) {
655 dev_kfree_skb(cs->tx_skb);
656 cs->tx_skb = NULL;
657 }
658 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
659 del_timer(&cs->dbusytimer);
660 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
661 schedule_event(cs, D_CLEARBUSY);
662 break;
663 default:
664 if (cs->debug & L1_DEB_WARN)
665 debugl1(cs, "Amd7930: l1hw: unknown %04x", pr);
666 break;
667 }
668}
669
670static void
671setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
672{
673
674 if (cs->debug & L1_DEB_ISAC)
675 debugl1(cs, "Amd7930: setstack called");
676
677 st->l1.l1hw = Amd7930_l1hw;
678}
679
680
681static void
682DC_Close_Amd7930(struct IsdnCardState *cs) {
683 if (cs->debug & L1_DEB_ISAC)
684 debugl1(cs, "Amd7930: DC_Close called");
685}
686
687
688static void
689dbusy_timer_handler(struct IsdnCardState *cs)
690{
691 u_long flags;
692 struct PStack *stptr;
693 WORD dtcr, der;
694 BYTE dsr1, dsr2;
695
696
697 if (cs->debug & L1_DEB_ISAC)
698 debugl1(cs, "Amd7930: dbusy_timer expired!");
699
700 if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
701 spin_lock_irqsave(&cs->lock, flags);
702
703
704 dtcr = rWordAMD(cs, 0x85);
705 dsr1 = rByteAMD(cs, 0x02);
706 dsr2 = rByteAMD(cs, 0x07);
707 der = rWordAMD(cs, 0x03);
708
709 if (cs->debug & L1_DEB_ISAC)
710 debugl1(cs, "Amd7930: dbusy_timer_handler: DSR1=0x%02X, DSR2=0x%02X, DER=0x%04X, cs->tx_skb->len=%u, tx_stat=%u, dtcr=%u, cs->tx_cnt=%u", dsr1, dsr2, der, cs->tx_skb->len, cs->dc.amd7930.tx_xmtlen, dtcr, cs->tx_cnt);
711
712 if ((cs->dc.amd7930.tx_xmtlen - dtcr) < cs->tx_cnt) {
713 test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
714 stptr = cs->stlist;
715 spin_unlock_irqrestore(&cs->lock, flags);
716 while (stptr != NULL) {
717 stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
718 stptr = stptr->next;
719 }
720
721 } else {
722
723 test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
724 if (cs->tx_skb) {
725 dev_kfree_skb_any(cs->tx_skb);
726 cs->tx_cnt = 0;
727 cs->tx_skb = NULL;
728 cs->dc.amd7930.tx_xmtlen = 0;
729 } else {
730 printk(KERN_WARNING "HiSax: Amd7930: D-Channel Busy no skb\n");
731 debugl1(cs, "Amd7930: D-Channel Busy no skb");
732
733 }
734
735 wByteAMD(cs, 0x21, 0x82);
736 wByteAMD(cs, 0x21, 0x02);
737 spin_unlock_irqrestore(&cs->lock, flags);
738 cs->irq_func(cs->irq, cs);
739
740 if (cs->debug & L1_DEB_ISAC)
741 debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset");
742 }
743 }
744}
745
746
747
748void Amd7930_init(struct IsdnCardState *cs)
749{
750 WORD *ptr;
751 BYTE cmd, cnt;
752
753 if (cs->debug & L1_DEB_ISAC)
754 debugl1(cs, "Amd7930: initamd called");
755
756 cs->dc.amd7930.tx_xmtlen = 0;
757 cs->dc.amd7930.old_state = 0;
758 cs->dc.amd7930.lmr1 = 0x40;
759 cs->dc.amd7930.ph_command = Amd7930_ph_command;
760 cs->setstack_d = setstack_Amd7930;
761 cs->DC_Close = DC_Close_Amd7930;
762
763
764 for (ptr = initAMD; *ptr != 0xFFFF; ) {
765 cmd = LOBYTE(*ptr);
766
767
768 if (*ptr++ >= 0x100) {
769 if (cmd < 8)
770
771 rByteAMD(cs, cmd);
772 else {
773 wByteAMD(cs, 0x00, cmd);
774 for (cnt = *ptr++; cnt > 0; cnt--)
775 rByteAMD(cs, 0x01);
776 }
777 }
778
779 else if (cmd < 8)
780 wByteAMD(cs, cmd, LOBYTE(*ptr++));
781
782 else {
783 wByteAMD(cs, 0x00, cmd);
784 for (cnt = *ptr++; cnt > 0; cnt--)
785 wByteAMD(cs, 0x01, LOBYTE(*ptr++));
786 }
787 }
788}
789
790void setup_Amd7930(struct IsdnCardState *cs)
791{
792 INIT_WORK(&cs->tqueue, Amd7930_bh);
793 setup_timer(&cs->dbusytimer, (void *)dbusy_timer_handler, (long)cs);
794}
795