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