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 memcpy(skb_put(skb, cs->rcvidx), cs->rcvbuf, cs->rcvidx);
321 skb_queue_tail(&cs->rq, skb);
322 }
323 }
324
325 }
326
327 ptr = cs->rcvbuf;
328 cs->rcvidx = 0;
329 schedule_event(cs, D_RCVBUFREADY);
330 }
331 }
332
333 if (cs->rcvidx >= MAX_DFRAME_LEN_L1) {
334 if (cs->debug & L1_DEB_WARN)
335 debugl1(cs, "AMD7930: empty_Dfifo L2-Framelength overrun");
336 cs->rcvidx = 0;
337 return;
338 }
339
340 AmdIrqOn(cs);
341}
342
343
344static void
345Amd7930_fill_Dfifo(struct IsdnCardState *cs)
346{
347
348 WORD dtcrr, dtcrw, len, count;
349 BYTE txstat, dmr3;
350 BYTE *ptr, *deb_ptr;
351
352 if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
353 debugl1(cs, "Amd7930: fill_Dfifo");
354
355 if ((!cs->tx_skb) || (cs->tx_skb->len <= 0))
356 return;
357
358 dtcrw = 0;
359 if (!cs->dc.amd7930.tx_xmtlen)
360
361 len = dtcrw = cs->tx_skb->len;
362
363 else len = cs->dc.amd7930.tx_xmtlen;
364
365
366
367 AmdIrqOff(cs);
368
369 deb_ptr = ptr = cs->tx_skb->data;
370
371
372 txstat = 0x10;
373 while ((txstat & 0x10) && (cs->tx_cnt < len)) {
374 wByteAMD(cs, 0x04, *ptr);
375 ptr++;
376 cs->tx_cnt++;
377 txstat = rByteAMD(cs, 0x07);
378 }
379 count = ptr - cs->tx_skb->data;
380 skb_pull(cs->tx_skb, count);
381
382
383 dtcrr = rWordAMD(cs, 0x85);
384 dmr3 = rByteAMD(cs, 0x8E);
385
386 if (cs->debug & L1_DEB_ISAC) {
387 debugl1(cs, "Amd7930: fill_Dfifo, DMR3: 0x%02X, DTCR read: 0x%04X write: 0x%02X 0x%02X", dmr3, dtcrr, LOBYTE(dtcrw), HIBYTE(dtcrw));
388 }
389
390
391 if (!cs->dc.amd7930.tx_xmtlen) {
392 wWordAMD(cs, 0x85, dtcrw);
393 cs->dc.amd7930.tx_xmtlen = dtcrw;
394 }
395
396 if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
397 debugl1(cs, "Amd7930: fill_Dfifo dbusytimer running");
398 del_timer(&cs->dbusytimer);
399 }
400 init_timer(&cs->dbusytimer);
401 cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
402 add_timer(&cs->dbusytimer);
403
404 if (cs->debug & L1_DEB_ISAC_FIFO) {
405 char *t = cs->dlog;
406
407 t += sprintf(t, "Amd7930: fill_Dfifo cnt: %d |", count);
408 QuickHex(t, deb_ptr, count);
409 debugl1(cs, "%s", cs->dlog);
410 }
411
412 AmdIrqOn(cs);
413}
414
415
416void Amd7930_interrupt(struct IsdnCardState *cs, BYTE irflags)
417{
418 BYTE dsr1, dsr2, lsr;
419 WORD der;
420
421 while (irflags)
422 {
423
424 dsr1 = rByteAMD(cs, 0x02);
425 der = rWordAMD(cs, 0x03);
426 dsr2 = rByteAMD(cs, 0x07);
427 lsr = rByteAMD(cs, 0xA1);
428
429 if (cs->debug & L1_DEB_ISAC)
430 debugl1(cs, "Amd7930: interrupt: flags: 0x%02X, DSR1: 0x%02X, DSR2: 0x%02X, LSR: 0x%02X, DER=0x%04X", irflags, dsr1, dsr2, lsr, der);
431
432
433 if (der || (dsr2 & 4)) {
434
435 if (cs->debug & L1_DEB_WARN)
436 debugl1(cs, "Amd7930: interrupt: D error DER=0x%04X", der);
437
438
439 if (der & 2) {
440 wByteAMD(cs, 0x21, 0xC2);
441 wByteAMD(cs, 0x21, 0x02);
442 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
443 del_timer(&cs->dbusytimer);
444 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
445 schedule_event(cs, D_CLEARBUSY);
446
447 if (cs->tx_skb) {
448 skb_push(cs->tx_skb, cs->tx_cnt);
449 cs->tx_cnt = 0;
450 cs->dc.amd7930.tx_xmtlen = 0;
451 Amd7930_fill_Dfifo(cs);
452 } else {
453 printk(KERN_WARNING "HiSax: Amd7930 D-Collision, no skb\n");
454 debugl1(cs, "Amd7930: interrupt: D-Collision, no skb");
455 }
456 }
457
458 Amd7930_empty_Dfifo(cs, 1);
459
460 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
461 del_timer(&cs->dbusytimer);
462 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
463 schedule_event(cs, D_CLEARBUSY);
464
465 if (cs->tx_skb) {
466 skb_push(cs->tx_skb, cs->tx_cnt);
467 cs->tx_cnt = 0;
468 cs->dc.amd7930.tx_xmtlen = 0;
469 Amd7930_fill_Dfifo(cs);
470 }
471 }
472
473
474 if (irflags & 1) {
475 if (cs->debug & L1_DEB_ISAC)
476 debugl1(cs, "Amd7930: interrupt: clear Timer and fill D-TX-FIFO if data");
477
478
479 AmdIrqOff(cs);
480
481 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
482 del_timer(&cs->dbusytimer);
483 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
484 schedule_event(cs, D_CLEARBUSY);
485 if (cs->tx_skb) {
486 if (cs->tx_skb->len)
487 Amd7930_fill_Dfifo(cs);
488 }
489
490 AmdIrqOn(cs);
491 }
492
493
494
495 if ((irflags & 2) || (dsr1 & 2)) {
496 if (cs->debug & L1_DEB_ISAC)
497 debugl1(cs, "Amd7930: interrupt: empty D-FIFO");
498 Amd7930_empty_Dfifo(cs, 0);
499 }
500
501
502
503 if (dsr1 & 64) {
504 if (cs->debug & L1_DEB_ISAC) {
505 debugl1(cs, "Amd7930: interrupt: transmit packet ready");
506 }
507
508 AmdIrqOff(cs);
509
510 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
511 del_timer(&cs->dbusytimer);
512 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
513 schedule_event(cs, D_CLEARBUSY);
514
515 if (cs->tx_skb) {
516 if (cs->debug & L1_DEB_ISAC)
517 debugl1(cs, "Amd7930: interrupt: TX-Packet ready, freeing skb");
518 dev_kfree_skb_irq(cs->tx_skb);
519 cs->tx_cnt = 0;
520 cs->dc.amd7930.tx_xmtlen = 0;
521 cs->tx_skb = NULL;
522 }
523 if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
524 if (cs->debug & L1_DEB_ISAC)
525 debugl1(cs, "Amd7930: interrupt: TX-Packet ready, next packet dequeued");
526 cs->tx_cnt = 0;
527 cs->dc.amd7930.tx_xmtlen = 0;
528 Amd7930_fill_Dfifo(cs);
529 }
530 else
531 schedule_event(cs, D_XMTBUFREADY);
532
533 AmdIrqOn(cs);
534 }
535
536
537 if (lsr & 0x38) {
538
539 AmdIrqOff(cs);
540
541 if (cs->debug & L1_DEB_ISAC)
542 debugl1(cs, "Amd: interrupt: LSR=0x%02X, LIU is in state %d", lsr, ((lsr & 0x7) + 2));
543
544 cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
545
546 schedule_event(cs, D_L1STATECHANGE);
547
548 AmdIrqOn(cs);
549 }
550
551
552 irflags = rByteAMD(cs, 0x00);
553 }
554
555}
556
557static void
558Amd7930_l1hw(struct PStack *st, int pr, void *arg)
559{
560 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
561 struct sk_buff *skb = arg;
562 u_long flags;
563
564 if (cs->debug & L1_DEB_ISAC)
565 debugl1(cs, "Amd7930: l1hw called, pr: 0x%04X", pr);
566
567 switch (pr) {
568 case (PH_DATA | REQUEST):
569 if (cs->debug & DEB_DLOG_HEX)
570 LogFrame(cs, skb->data, skb->len);
571 if (cs->debug & DEB_DLOG_VERBOSE)
572 dlogframe(cs, skb, 0);
573 spin_lock_irqsave(&cs->lock, flags);
574 if (cs->tx_skb) {
575 skb_queue_tail(&cs->sq, skb);
576#ifdef L2FRAME_DEBUG
577 if (cs->debug & L1_DEB_LAPD)
578 Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA Queued", 0);
579#endif
580 } else {
581 cs->tx_skb = skb;
582 cs->tx_cnt = 0;
583 cs->dc.amd7930.tx_xmtlen = 0;
584#ifdef L2FRAME_DEBUG
585 if (cs->debug & L1_DEB_LAPD)
586 Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA", 0);
587#endif
588 Amd7930_fill_Dfifo(cs);
589 }
590 spin_unlock_irqrestore(&cs->lock, flags);
591 break;
592 case (PH_PULL | INDICATION):
593 spin_lock_irqsave(&cs->lock, flags);
594 if (cs->tx_skb) {
595 if (cs->debug & L1_DEB_WARN)
596 debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen");
597 skb_queue_tail(&cs->sq, skb);
598 spin_unlock_irqrestore(&cs->lock, flags);
599 break;
600 }
601 if (cs->debug & DEB_DLOG_HEX)
602 LogFrame(cs, skb->data, skb->len);
603 if (cs->debug & DEB_DLOG_VERBOSE)
604 dlogframe(cs, skb, 0);
605 cs->tx_skb = skb;
606 cs->tx_cnt = 0;
607 cs->dc.amd7930.tx_xmtlen = 0;
608#ifdef L2FRAME_DEBUG
609 if (cs->debug & L1_DEB_LAPD)
610 Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA_PULLED", 0);
611#endif
612 Amd7930_fill_Dfifo(cs);
613 spin_unlock_irqrestore(&cs->lock, flags);
614 break;
615 case (PH_PULL | REQUEST):
616#ifdef L2FRAME_DEBUG
617 if (cs->debug & L1_DEB_LAPD)
618 debugl1(cs, "Amd7930: l1hw: -> PH_REQUEST_PULL, skb: %s", (cs->tx_skb) ? "yes" : "no");
619#endif
620 if (!cs->tx_skb) {
621 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
622 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
623 } else
624 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
625 break;
626 case (HW_RESET | REQUEST):
627 spin_lock_irqsave(&cs->lock, flags);
628 if ((cs->dc.amd7930.ph_state == 8)) {
629
630
631 Amd7930_ph_command(cs, 0x20, "HW_RESET REQUEST");
632 spin_unlock_irqrestore(&cs->lock, flags);
633 } else {
634 Amd7930_ph_command(cs, 0x40, "HW_RESET REQUEST");
635 cs->dc.amd7930.ph_state = 2;
636 spin_unlock_irqrestore(&cs->lock, flags);
637 Amd7930_new_ph(cs);
638 }
639 break;
640 case (HW_ENABLE | REQUEST):
641 cs->dc.amd7930.ph_state = 9;
642 Amd7930_new_ph(cs);
643 break;
644 case (HW_INFO3 | REQUEST):
645
646 break;
647 case (HW_TESTLOOP | REQUEST):
648
649 break;
650 case (HW_DEACTIVATE | RESPONSE):
651 skb_queue_purge(&cs->rq);
652 skb_queue_purge(&cs->sq);
653 if (cs->tx_skb) {
654 dev_kfree_skb(cs->tx_skb);
655 cs->tx_skb = NULL;
656 }
657 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
658 del_timer(&cs->dbusytimer);
659 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
660 schedule_event(cs, D_CLEARBUSY);
661 break;
662 default:
663 if (cs->debug & L1_DEB_WARN)
664 debugl1(cs, "Amd7930: l1hw: unknown %04x", pr);
665 break;
666 }
667}
668
669static void
670setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
671{
672
673 if (cs->debug & L1_DEB_ISAC)
674 debugl1(cs, "Amd7930: setstack called");
675
676 st->l1.l1hw = Amd7930_l1hw;
677}
678
679
680static void
681DC_Close_Amd7930(struct IsdnCardState *cs) {
682 if (cs->debug & L1_DEB_ISAC)
683 debugl1(cs, "Amd7930: DC_Close called");
684}
685
686
687static void
688dbusy_timer_handler(struct IsdnCardState *cs)
689{
690 u_long flags;
691 struct PStack *stptr;
692 WORD dtcr, der;
693 BYTE dsr1, dsr2;
694
695
696 if (cs->debug & L1_DEB_ISAC)
697 debugl1(cs, "Amd7930: dbusy_timer expired!");
698
699 if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
700 spin_lock_irqsave(&cs->lock, flags);
701
702
703 dtcr = rWordAMD(cs, 0x85);
704 dsr1 = rByteAMD(cs, 0x02);
705 dsr2 = rByteAMD(cs, 0x07);
706 der = rWordAMD(cs, 0x03);
707
708 if (cs->debug & L1_DEB_ISAC)
709 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);
710
711 if ((cs->dc.amd7930.tx_xmtlen - dtcr) < cs->tx_cnt) {
712 test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
713 stptr = cs->stlist;
714 spin_unlock_irqrestore(&cs->lock, flags);
715 while (stptr != NULL) {
716 stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
717 stptr = stptr->next;
718 }
719
720 } else {
721
722 test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
723 if (cs->tx_skb) {
724 dev_kfree_skb_any(cs->tx_skb);
725 cs->tx_cnt = 0;
726 cs->tx_skb = NULL;
727 cs->dc.amd7930.tx_xmtlen = 0;
728 } else {
729 printk(KERN_WARNING "HiSax: Amd7930: D-Channel Busy no skb\n");
730 debugl1(cs, "Amd7930: D-Channel Busy no skb");
731
732 }
733
734 wByteAMD(cs, 0x21, 0x82);
735 wByteAMD(cs, 0x21, 0x02);
736 spin_unlock_irqrestore(&cs->lock, flags);
737 cs->irq_func(cs->irq, cs);
738
739 if (cs->debug & L1_DEB_ISAC)
740 debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset");
741 }
742 }
743}
744
745
746
747void Amd7930_init(struct IsdnCardState *cs)
748{
749 WORD *ptr;
750 BYTE cmd, cnt;
751
752 if (cs->debug & L1_DEB_ISAC)
753 debugl1(cs, "Amd7930: initamd called");
754
755 cs->dc.amd7930.tx_xmtlen = 0;
756 cs->dc.amd7930.old_state = 0;
757 cs->dc.amd7930.lmr1 = 0x40;
758 cs->dc.amd7930.ph_command = Amd7930_ph_command;
759 cs->setstack_d = setstack_Amd7930;
760 cs->DC_Close = DC_Close_Amd7930;
761
762
763 for (ptr = initAMD; *ptr != 0xFFFF; ) {
764 cmd = LOBYTE(*ptr);
765
766
767 if (*ptr++ >= 0x100) {
768 if (cmd < 8)
769
770 rByteAMD(cs, cmd);
771 else {
772 wByteAMD(cs, 0x00, cmd);
773 for (cnt = *ptr++; cnt > 0; cnt--)
774 rByteAMD(cs, 0x01);
775 }
776 }
777
778 else if (cmd < 8)
779 wByteAMD(cs, cmd, LOBYTE(*ptr++));
780
781 else {
782 wByteAMD(cs, 0x00, cmd);
783 for (cnt = *ptr++; cnt > 0; cnt--)
784 wByteAMD(cs, 0x01, LOBYTE(*ptr++));
785 }
786 }
787}
788
789void setup_Amd7930(struct IsdnCardState *cs)
790{
791 INIT_WORK(&cs->tqueue, Amd7930_bh);
792 cs->dbusytimer.function = (void *) dbusy_timer_handler;
793 cs->dbusytimer.data = (long) cs;
794 init_timer(&cs->dbusytimer);
795}
796