Import 2.3.10pre5
[davej-history.git] / drivers / isdn / hisax / hfc_2bds0.c
blob4e734b2c6fa12f3a9f24f83b07c16000986f6ddc
1 /* $Id: hfc_2bds0.c,v 1.8 1998/11/15 23:54:40 keil Exp $
3 * specific routines for CCD's HFC 2BDS0
5 * Author Karsten Keil (keil@temic-ech.spacenet.de)
8 * $Log: hfc_2bds0.c,v $
9 * Revision 1.8 1998/11/15 23:54:40 keil
10 * changes from 2.0
12 * Revision 1.7 1998/09/30 22:24:45 keil
13 * Fix missing line in setstack*
15 * Revision 1.6 1998/08/13 23:36:26 keil
16 * HiSax 3.1 - don't work stable with current LinkLevel
18 * Revision 1.5 1998/06/27 22:52:58 keil
19 * make 16.3c working with 3.0
21 * Revision 1.4 1998/05/25 12:57:52 keil
22 * HiSax golden code from certification, Don't use !!!
23 * No leased lines, no X75, but many changes.
25 * Revision 1.3 1998/02/12 23:07:22 keil
26 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
28 * Revision 1.2 1998/02/02 13:26:13 keil
29 * New
34 #define __NO_VERSION__
35 #include "hisax.h"
36 #include "hfc_2bds0.h"
37 #include "isdnl1.h"
38 #include <linux/interrupt.h>
40 #define KDEBUG_DEF
41 #include "kdebug.h"
44 #define byteout(addr,val) outb(val,addr)
45 #define bytein(addr) inb(addr)
47 static void
48 dummyf(struct IsdnCardState *cs, u_char * data, int size)
50 printk(KERN_WARNING "HiSax: hfcd dummy fifo called\n");
53 static inline u_char
54 ReadReg(struct IsdnCardState *cs, int data, u_char reg)
56 register u_char ret;
58 if (data) {
59 if (cs->hw.hfcD.cip != reg) {
60 cs->hw.hfcD.cip = reg;
61 byteout(cs->hw.hfcD.addr | 1, reg);
63 ret = bytein(cs->hw.hfcD.addr);
64 #if HFC_REG_DEBUG
65 if (cs->debug & L1_DEB_HSCX_FIFO && (data != 2))
66 debugl1(cs, "t3c RD %02x %02x", reg, ret);
67 #endif
68 } else
69 ret = bytein(cs->hw.hfcD.addr | 1);
70 return (ret);
73 static inline void
74 WriteReg(struct IsdnCardState *cs, int data, u_char reg, u_char value)
76 if (cs->hw.hfcD.cip != reg) {
77 cs->hw.hfcD.cip = reg;
78 byteout(cs->hw.hfcD.addr | 1, reg);
80 if (data)
81 byteout(cs->hw.hfcD.addr, value);
82 #if HFC_REG_DEBUG
83 if (cs->debug & L1_DEB_HSCX_FIFO && (data != HFCD_DATA_NODEB))
84 debugl1(cs, "t3c W%c %02x %02x", data ? 'D' : 'C', reg, value);
85 #endif
88 /* Interface functions */
90 static u_char
91 readreghfcd(struct IsdnCardState *cs, u_char offset)
93 return(ReadReg(cs, HFCD_DATA, offset));
96 static void
97 writereghfcd(struct IsdnCardState *cs, u_char offset, u_char value)
99 WriteReg(cs, HFCD_DATA, offset, value);
102 void
103 set_cs_func(struct IsdnCardState *cs)
105 cs->readisac = &readreghfcd;
106 cs->writeisac = &writereghfcd;
107 cs->readisacfifo = &dummyf;
108 cs->writeisacfifo = &dummyf;
109 cs->BC_Read_Reg = &ReadReg;
110 cs->BC_Write_Reg = &WriteReg;
113 static inline int
114 WaitForBusy(struct IsdnCardState *cs)
116 int to = 130;
118 while (!(ReadReg(cs, HFCD_DATA, HFCD_STAT) & HFCD_BUSY) && to) {
119 udelay(1);
120 to--;
122 if (!to)
123 printk(KERN_WARNING "HiSax: WaitForBusy timeout\n");
124 return (to);
127 static inline int
128 WaitNoBusy(struct IsdnCardState *cs)
130 long flags;
131 int to = 130;
133 while ((ReadReg(cs, HFCD_STATUS, HFCD_STATUS) & HFCD_BUSY) && to) {
134 save_flags(flags);
135 sti();
136 udelay(1);
137 to--;
138 restore_flags(flags);
140 if (!to)
141 printk(KERN_WARNING "HiSax: WaitNoBusy timeout\n");
142 return (to);
145 static int
146 SelFiFo(struct IsdnCardState *cs, u_char FiFo)
148 u_char cip;
149 long flags;
152 if (cs->hw.hfcD.fifo == FiFo)
153 return(1);
154 save_flags(flags);
155 cli();
156 switch(FiFo) {
157 case 0: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B1;
158 break;
159 case 1: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B1;
160 break;
161 case 2: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B2;
162 break;
163 case 3: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B2;
164 break;
165 case 4: cip = HFCD_FIFO | HFCD_Z1 | HFCD_SEND;
166 break;
167 case 5: cip = HFCD_FIFO | HFCD_Z1 | HFCD_REC;
168 break;
169 default:
170 restore_flags(flags);
171 debugl1(cs, "SelFiFo Error");
172 return(0);
174 cs->hw.hfcD.fifo = FiFo;
175 WaitNoBusy(cs);
176 cs->BC_Write_Reg(cs, HFCD_DATA, cip, 0);
177 sti();
178 WaitForBusy(cs);
179 restore_flags(flags);
180 return(2);
182 static int
183 GetFreeFifoBytes_B(struct BCState *bcs)
185 int s;
187 if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2)
188 return (bcs->cs->hw.hfcD.bfifosize);
189 s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2];
190 if (s <= 0)
191 s += bcs->cs->hw.hfcD.bfifosize;
192 s = bcs->cs->hw.hfcD.bfifosize - s;
193 return (s);
196 static int
197 GetFreeFifoBytes_D(struct IsdnCardState *cs)
199 int s;
201 if (cs->hw.hfcD.f1 == cs->hw.hfcD.f2)
202 return (cs->hw.hfcD.dfifosize);
203 s = cs->hw.hfcD.send[cs->hw.hfcD.f1] - cs->hw.hfcD.send[cs->hw.hfcD.f2];
204 if (s <= 0)
205 s += cs->hw.hfcD.dfifosize;
206 s = cs->hw.hfcD.dfifosize - s;
207 return (s);
210 static int
211 ReadZReg(struct IsdnCardState *cs, u_char reg)
213 int val;
215 WaitNoBusy(cs);
216 val = 256 * ReadReg(cs, HFCD_DATA, reg | HFCB_Z_HIGH);
217 WaitNoBusy(cs);
218 val += ReadReg(cs, HFCD_DATA, reg | HFCB_Z_LOW);
219 return (val);
222 static void
223 hfc_sched_event(struct BCState *bcs, int event)
225 bcs->event |= 1 << event;
226 queue_task(&bcs->tqueue, &tq_immediate);
227 mark_bh(IMMEDIATE_BH);
230 static struct sk_buff
231 *hfc_empty_fifo(struct BCState *bcs, int count)
233 u_char *ptr;
234 struct sk_buff *skb;
235 struct IsdnCardState *cs = bcs->cs;
236 int idx;
237 int chksum;
238 long flags;
239 u_char stat, cip;
241 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
242 debugl1(cs, "hfc_empty_fifo");
243 idx = 0;
244 save_flags(flags);
245 if (count > HSCX_BUFMAX + 3) {
246 if (cs->debug & L1_DEB_WARN)
247 debugl1(cs, "hfc_empty_fifo: incoming packet too large");
248 cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
249 while (idx++ < count) {
250 cli();
251 WaitNoBusy(cs);
252 ReadReg(cs, HFCD_DATA_NODEB, cip);
253 sti();
255 skb = NULL;
256 } else if (count < 4) {
257 if (cs->debug & L1_DEB_WARN)
258 debugl1(cs, "hfc_empty_fifo: incoming packet too small");
259 cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
260 cli();
261 while ((idx++ < count) && WaitNoBusy(cs))
262 ReadReg(cs, HFCD_DATA_NODEB, cip);
263 skb = NULL;
264 } else if (!(skb = dev_alloc_skb(count - 3)))
265 printk(KERN_WARNING "HFC: receive out of memory\n");
266 else {
267 ptr = skb_put(skb, count - 3);
268 idx = 0;
269 cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
270 cli();
271 while (idx < (count - 3)) {
272 cli();
273 if (!WaitNoBusy(cs))
274 break;
275 *ptr = ReadReg(cs, HFCD_DATA_NODEB, cip);
276 sti();
277 ptr++;
278 idx++;
280 if (idx != count - 3) {
281 sti();
282 debugl1(cs, "RFIFO BUSY error");
283 printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
284 dev_kfree_skb(skb);
285 skb = NULL;
286 } else {
287 cli();
288 WaitNoBusy(cs);
289 chksum = (ReadReg(cs, HFCD_DATA, cip) << 8);
290 WaitNoBusy(cs);
291 chksum += ReadReg(cs, HFCD_DATA, cip);
292 WaitNoBusy(cs);
293 stat = ReadReg(cs, HFCD_DATA, cip);
294 sti();
295 if (cs->debug & L1_DEB_HSCX)
296 debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
297 bcs->channel, chksum, stat);
298 if (stat) {
299 debugl1(cs, "FIFO CRC error");
300 dev_kfree_skb(skb);
301 skb = NULL;
305 sti();
306 WaitForBusy(cs);
307 cli();
308 WaitNoBusy(cs);
309 stat = ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F2_INC |
310 HFCB_REC | HFCB_CHANNEL(bcs->channel));
311 sti();
312 WaitForBusy(cs);
313 restore_flags(flags);
314 return (skb);
317 static void
318 hfc_fill_fifo(struct BCState *bcs)
320 struct IsdnCardState *cs = bcs->cs;
321 long flags;
322 int idx, fcnt;
323 int count;
324 u_char cip;
326 if (!bcs->tx_skb)
327 return;
328 if (bcs->tx_skb->len <= 0)
329 return;
330 save_flags(flags);
331 cli();
332 SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel));
333 cip = HFCB_FIFO | HFCB_F1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
334 WaitNoBusy(cs);
335 bcs->hw.hfc.f1 = ReadReg(cs, HFCD_DATA, cip);
336 WaitNoBusy(cs);
337 cip = HFCB_FIFO | HFCB_F2 | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
338 WaitNoBusy(cs);
339 bcs->hw.hfc.f2 = ReadReg(cs, HFCD_DATA, cip);
340 bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel));
341 sti();
342 if (cs->debug & L1_DEB_HSCX)
343 debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
344 bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
345 bcs->hw.hfc.send[bcs->hw.hfc.f1]);
346 fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
347 if (fcnt < 0)
348 fcnt += 32;
349 if (fcnt > 30) {
350 if (cs->debug & L1_DEB_HSCX)
351 debugl1(cs, "hfc_fill_fifo more as 30 frames");
352 restore_flags(flags);
353 return;
355 count = GetFreeFifoBytes_B(bcs);
356 if (cs->debug & L1_DEB_HSCX)
357 debugl1(cs, "hfc_fill_fifo %d count(%ld/%d),%lx",
358 bcs->channel, bcs->tx_skb->len,
359 count, current->state);
360 if (count < bcs->tx_skb->len) {
361 if (cs->debug & L1_DEB_HSCX)
362 debugl1(cs, "hfc_fill_fifo no fifo mem");
363 restore_flags(flags);
364 return;
366 cip = HFCB_FIFO | HFCB_FIFO_IN | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
367 idx = 0;
368 cli();
369 WaitForBusy(cs);
370 WaitNoBusy(cs);
371 WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
372 while (idx < bcs->tx_skb->len) {
373 cli();
374 if (!WaitNoBusy(cs))
375 break;
376 WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx]);
377 sti();
378 idx++;
380 if (idx != bcs->tx_skb->len) {
381 sti();
382 debugl1(cs, "FIFO Send BUSY error");
383 printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
384 } else {
385 bcs->tx_cnt -= bcs->tx_skb->len;
386 if (bcs->st->lli.l1writewakeup &&
387 (PACKET_NOACK != bcs->tx_skb->pkt_type))
388 bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
389 dev_kfree_skb(bcs->tx_skb);
390 bcs->tx_skb = NULL;
392 WaitForBusy(cs);
393 cli();
394 WaitNoBusy(cs);
395 ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F1_INC | HFCB_SEND | HFCB_CHANNEL(bcs->channel));
396 sti();
397 WaitForBusy(cs);
398 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
399 restore_flags(flags);
400 return;
403 static void
404 hfc_send_data(struct BCState *bcs)
406 struct IsdnCardState *cs = bcs->cs;
408 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
409 hfc_fill_fifo(bcs);
410 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
411 } else
412 debugl1(cs,"send_data %d blocked", bcs->channel);
415 void
416 main_rec_2bds0(struct BCState *bcs)
418 long flags;
419 struct IsdnCardState *cs = bcs->cs;
420 int z1, z2, rcnt;
421 u_char f1, f2, cip;
422 int receive, count = 5;
423 struct sk_buff *skb;
425 save_flags(flags);
426 Begin:
427 count--;
428 cli();
429 if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
430 debugl1(cs,"rec_data %d blocked", bcs->channel);
431 restore_flags(flags);
432 return;
434 SelFiFo(cs, HFCB_REC | HFCB_CHANNEL(bcs->channel));
435 cip = HFCB_FIFO | HFCB_F1 | HFCB_REC | HFCB_CHANNEL(bcs->channel);
436 WaitNoBusy(cs);
437 f1 = ReadReg(cs, HFCD_DATA, cip);
438 cip = HFCB_FIFO | HFCB_F2 | HFCB_REC | HFCB_CHANNEL(bcs->channel);
439 WaitNoBusy(cs);
440 f2 = ReadReg(cs, HFCD_DATA, cip);
441 sti();
442 if (f1 != f2) {
443 if (cs->debug & L1_DEB_HSCX)
444 debugl1(cs, "hfc rec %d f1(%d) f2(%d)",
445 bcs->channel, f1, f2);
446 cli();
447 z1 = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_CHANNEL(bcs->channel));
448 z2 = ReadZReg(cs, HFCB_FIFO | HFCB_Z2 | HFCB_REC | HFCB_CHANNEL(bcs->channel));
449 sti();
450 rcnt = z1 - z2;
451 if (rcnt < 0)
452 rcnt += cs->hw.hfcD.bfifosize;
453 rcnt++;
454 if (cs->debug & L1_DEB_HSCX)
455 debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)",
456 bcs->channel, z1, z2, rcnt);
457 if ((skb = hfc_empty_fifo(bcs, rcnt))) {
458 cli();
459 skb_queue_tail(&bcs->rqueue, skb);
460 sti();
461 hfc_sched_event(bcs, B_RCVBUFREADY);
463 rcnt = f1 -f2;
464 if (rcnt<0)
465 rcnt += 32;
466 if (rcnt>1)
467 receive = 1;
468 else
469 receive = 0;
470 } else
471 receive = 0;
472 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
473 if (count && receive)
474 goto Begin;
475 restore_flags(flags);
476 return;
479 void
480 mode_2bs0(struct BCState *bcs, int mode, int bc)
482 struct IsdnCardState *cs = bcs->cs;
484 if (cs->debug & L1_DEB_HSCX)
485 debugl1(cs, "HFCD bchannel mode %d bchan %d/%d",
486 mode, bc, bcs->channel);
487 bcs->mode = mode;
488 bcs->channel = bc;
489 switch (mode) {
490 case (L1_MODE_NULL):
491 if (bc) {
492 cs->hw.hfcD.conn |= 0x18;
493 cs->hw.hfcD.sctrl &= ~SCTRL_B2_ENA;
494 } else {
495 cs->hw.hfcD.conn |= 0x3;
496 cs->hw.hfcD.sctrl &= ~SCTRL_B1_ENA;
498 break;
499 case (L1_MODE_TRANS):
500 if (bc) {
501 cs->hw.hfcD.ctmt |= 2;
502 cs->hw.hfcD.conn &= ~0x18;
503 cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
504 } else {
505 cs->hw.hfcD.ctmt |= 1;
506 cs->hw.hfcD.conn &= ~0x3;
507 cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
509 break;
510 case (L1_MODE_HDLC):
511 if (bc) {
512 cs->hw.hfcD.ctmt &= ~2;
513 cs->hw.hfcD.conn &= ~0x18;
514 cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
515 } else {
516 cs->hw.hfcD.ctmt &= ~1;
517 cs->hw.hfcD.conn &= ~0x3;
518 cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
520 break;
522 WriteReg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl);
523 WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt);
524 WriteReg(cs, HFCD_DATA, HFCD_CONN, cs->hw.hfcD.conn);
527 static void
528 hfc_l2l1(struct PStack *st, int pr, void *arg)
530 struct sk_buff *skb = arg;
531 long flags;
533 switch (pr) {
534 case (PH_DATA | REQUEST):
535 save_flags(flags);
536 cli();
537 if (st->l1.bcs->tx_skb) {
538 skb_queue_tail(&st->l1.bcs->squeue, skb);
539 restore_flags(flags);
540 } else {
541 st->l1.bcs->tx_skb = skb;
542 /* test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
543 */ st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
544 restore_flags(flags);
546 break;
547 case (PH_PULL | INDICATION):
548 if (st->l1.bcs->tx_skb) {
549 printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
550 break;
552 save_flags(flags);
553 cli();
554 /* test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
555 */ st->l1.bcs->tx_skb = skb;
556 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
557 restore_flags(flags);
558 break;
559 case (PH_PULL | REQUEST):
560 if (!st->l1.bcs->tx_skb) {
561 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
562 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
563 } else
564 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
565 break;
566 case (PH_ACTIVATE | REQUEST):
567 test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
568 mode_2bs0(st->l1.bcs, st->l1.mode, st->l1.bc);
569 l1_msg_b(st, pr, arg);
570 break;
571 case (PH_DEACTIVATE | REQUEST):
572 l1_msg_b(st, pr, arg);
573 break;
574 case (PH_DEACTIVATE | CONFIRM):
575 test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
576 test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
577 mode_2bs0(st->l1.bcs, 0, st->l1.bc);
578 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
579 break;
583 void
584 close_2bs0(struct BCState *bcs)
586 mode_2bs0(bcs, 0, bcs->channel);
587 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
588 discard_queue(&bcs->rqueue);
589 discard_queue(&bcs->squeue);
590 if (bcs->tx_skb) {
591 dev_kfree_skb(bcs->tx_skb);
592 bcs->tx_skb = NULL;
593 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
598 static int
599 open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
601 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
602 skb_queue_head_init(&bcs->rqueue);
603 skb_queue_head_init(&bcs->squeue);
605 bcs->tx_skb = NULL;
606 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
607 bcs->event = 0;
608 bcs->tx_cnt = 0;
609 return (0);
613 setstack_2b(struct PStack *st, struct BCState *bcs)
615 bcs->channel = st->l1.bc;
616 if (open_hfcstate(st->l1.hardware, bcs))
617 return (-1);
618 st->l1.bcs = bcs;
619 st->l2.l2l1 = hfc_l2l1;
620 setstack_manager(st);
621 bcs->st = st;
622 setstack_l1_B(st);
623 return (0);
626 static void
627 hfcd_bh(struct IsdnCardState *cs)
629 /* struct PStack *stptr;
631 if (!cs)
632 return;
633 #if 0
634 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
635 if (cs->debug)
636 debugl1(cs, "D-Channel Busy cleared");
637 stptr = cs->stlist;
638 while (stptr != NULL) {
639 stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
640 stptr = stptr->next;
643 #endif
644 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
645 switch (cs->ph_state) {
646 case (0):
647 l1_msg(cs, HW_RESET | INDICATION, NULL);
648 break;
649 case (3):
650 l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
651 break;
652 case (8):
653 l1_msg(cs, HW_RSYNC | INDICATION, NULL);
654 break;
655 case (6):
656 l1_msg(cs, HW_INFO2 | INDICATION, NULL);
657 break;
658 case (7):
659 l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
660 break;
661 default:
662 break;
665 if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
666 DChannel_proc_rcv(cs);
667 if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
668 DChannel_proc_xmt(cs);
671 void
672 sched_event_D(struct IsdnCardState *cs, int event)
674 test_and_set_bit(event, &cs->event);
675 queue_task(&cs->tqueue, &tq_immediate);
676 mark_bh(IMMEDIATE_BH);
679 static
680 int receive_dmsg(struct IsdnCardState *cs)
682 struct sk_buff *skb;
683 long flags;
684 int idx;
685 int rcnt, z1, z2;
686 u_char stat, cip, f1, f2;
687 int chksum;
688 int count=5;
689 u_char *ptr;
691 save_flags(flags);
692 cli();
693 if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
694 debugl1(cs, "rec_dmsg blocked");
695 restore_flags(flags);
696 return(1);
698 SelFiFo(cs, 4 | HFCD_REC);
699 cip = HFCD_FIFO | HFCD_F1 | HFCD_REC;
700 WaitNoBusy(cs);
701 f1 = cs->readisac(cs, cip) & 0xf;
702 cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
703 WaitNoBusy(cs);
704 f2 = cs->readisac(cs, cip) & 0xf;
705 while ((f1 != f2) && count--) {
706 z1 = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_REC);
707 z2 = ReadZReg(cs, HFCD_FIFO | HFCD_Z2 | HFCD_REC);
708 rcnt = z1 - z2;
709 if (rcnt < 0)
710 rcnt += cs->hw.hfcD.dfifosize;
711 rcnt++;
712 if (cs->debug & L1_DEB_ISAC)
713 debugl1(cs, "hfcd recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)",
714 f1, f2, z1, z2, rcnt);
715 sti();
716 idx = 0;
717 cip = HFCD_FIFO | HFCD_FIFO_OUT | HFCD_REC;
718 if (rcnt > MAX_DFRAME_LEN + 3) {
719 if (cs->debug & L1_DEB_WARN)
720 debugl1(cs, "empty_fifo d: incoming packet too large");
721 while (idx < rcnt) {
722 cli();
723 if (!(WaitNoBusy(cs)))
724 break;
725 ReadReg(cs, HFCD_DATA_NODEB, cip);
726 sti();
727 idx++;
729 } else if (rcnt < 4) {
730 if (cs->debug & L1_DEB_WARN)
731 debugl1(cs, "empty_fifo d: incoming packet too small");
732 cli();
733 while ((idx++ < rcnt) && WaitNoBusy(cs))
734 ReadReg(cs, HFCD_DATA_NODEB, cip);
735 } else if ((skb = dev_alloc_skb(rcnt - 3))) {
736 ptr = skb_put(skb, rcnt - 3);
737 while (idx < (rcnt - 3)) {
738 cli();
739 if (!(WaitNoBusy(cs)))
740 break;
741 *ptr = ReadReg(cs, HFCD_DATA_NODEB, cip);
742 sti();
743 idx++;
744 ptr++;
746 if (idx != (rcnt - 3)) {
747 sti();
748 debugl1(cs, "RFIFO D BUSY error");
749 printk(KERN_WARNING "HFC DFIFO channel BUSY Error\n");
750 dev_kfree_skb(skb);
751 skb = NULL;
752 } else {
753 cli();
754 WaitNoBusy(cs);
755 chksum = (ReadReg(cs, HFCD_DATA, cip) << 8);
756 WaitNoBusy(cs);
757 chksum += ReadReg(cs, HFCD_DATA, cip);
758 WaitNoBusy(cs);
759 stat = ReadReg(cs, HFCD_DATA, cip);
760 sti();
761 if (cs->debug & L1_DEB_ISAC)
762 debugl1(cs, "empty_dfifo chksum %x stat %x",
763 chksum, stat);
764 if (stat) {
765 debugl1(cs, "FIFO CRC error");
766 dev_kfree_skb(skb);
767 skb = NULL;
768 } else {
769 skb_queue_tail(&cs->rq, skb);
770 sched_event_D(cs, D_RCVBUFREADY);
773 } else
774 printk(KERN_WARNING "HFC: D receive out of memory\n");
775 sti();
776 WaitForBusy(cs);
777 cip = HFCD_FIFO | HFCD_F2_INC | HFCD_REC;
778 cli();
779 WaitNoBusy(cs);
780 stat = ReadReg(cs, HFCD_DATA, cip);
781 sti();
782 WaitForBusy(cs);
783 cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
784 cli();
785 WaitNoBusy(cs);
786 f2 = cs->readisac(cs, cip) & 0xf;
788 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
789 restore_flags(flags);
790 return(1);
793 static void
794 hfc_fill_dfifo(struct IsdnCardState *cs)
796 long flags;
797 int idx, fcnt;
798 int count;
799 u_char cip;
801 if (!cs->tx_skb)
802 return;
803 if (cs->tx_skb->len <= 0)
804 return;
806 save_flags(flags);
807 cli();
808 SelFiFo(cs, 4 | HFCD_SEND);
809 cip = HFCD_FIFO | HFCD_F1 | HFCD_SEND;
810 WaitNoBusy(cs);
811 cs->hw.hfcD.f1 = ReadReg(cs, HFCD_DATA, cip) & 0xf;
812 WaitNoBusy(cs);
813 cip = HFCD_FIFO | HFCD_F2 | HFCD_SEND;
814 cs->hw.hfcD.f2 = ReadReg(cs, HFCD_DATA, cip) & 0xf;
815 cs->hw.hfcD.send[cs->hw.hfcD.f1] = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_SEND);
816 sti();
817 if (cs->debug & L1_DEB_ISAC)
818 debugl1(cs, "hfc_fill_Dfifo f1(%d) f2(%d) z1(%x)",
819 cs->hw.hfcD.f1, cs->hw.hfcD.f2,
820 cs->hw.hfcD.send[cs->hw.hfcD.f1]);
821 fcnt = cs->hw.hfcD.f1 - cs->hw.hfcD.f2;
822 if (fcnt < 0)
823 fcnt += 16;
824 if (fcnt > 14) {
825 if (cs->debug & L1_DEB_HSCX)
826 debugl1(cs, "hfc_fill_Dfifo more as 14 frames");
827 restore_flags(flags);
828 return;
830 count = GetFreeFifoBytes_D(cs);
831 if (cs->debug & L1_DEB_ISAC)
832 debugl1(cs, "hfc_fill_Dfifo count(%ld/%d)",
833 cs->tx_skb->len, count);
834 if (count < cs->tx_skb->len) {
835 if (cs->debug & L1_DEB_ISAC)
836 debugl1(cs, "hfc_fill_Dfifo no fifo mem");
837 restore_flags(flags);
838 return;
840 cip = HFCD_FIFO | HFCD_FIFO_IN | HFCD_SEND;
841 idx = 0;
842 cli();
843 WaitForBusy(cs);
844 WaitNoBusy(cs);
845 WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx++]);
846 while (idx < cs->tx_skb->len) {
847 cli();
848 if (!(WaitNoBusy(cs)))
849 break;
850 WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx]);
851 sti();
852 idx++;
854 if (idx != cs->tx_skb->len) {
855 sti();
856 debugl1(cs, "DFIFO Send BUSY error");
857 printk(KERN_WARNING "HFC S DFIFO channel BUSY Error\n");
859 WaitForBusy(cs);
860 cli();
861 WaitNoBusy(cs);
862 ReadReg(cs, HFCD_DATA, HFCD_FIFO | HFCD_F1_INC | HFCD_SEND);
863 dev_kfree_skb(cs->tx_skb);
864 cs->tx_skb = NULL;
865 sti();
866 WaitForBusy(cs);
867 restore_flags(flags);
868 return;
871 static
872 struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
874 if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
875 return(&cs->bcs[0]);
876 else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
877 return(&cs->bcs[1]);
878 else
879 return(NULL);
882 void
883 hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
885 u_char exval;
886 struct BCState *bcs;
887 int count=15;
888 long flags;
890 if (cs->debug & L1_DEB_ISAC)
891 debugl1(cs, "HFCD irq %x %s", val,
892 test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ?
893 "locked" : "unlocked");
894 val &= cs->hw.hfcD.int_m1;
895 if (val & 0x40) { /* TE state machine irq */
896 exval = cs->readisac(cs, HFCD_STATES) & 0xf;
897 if (cs->debug & L1_DEB_ISAC)
898 debugl1(cs, "ph_state chg %d->%d", cs->ph_state,
899 exval);
900 cs->ph_state = exval;
901 sched_event_D(cs, D_L1STATECHANGE);
902 val &= ~0x40;
904 while (val) {
905 save_flags(flags);
906 cli();
907 if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
908 cs->hw.hfcD.int_s1 |= val;
909 restore_flags(flags);
910 return;
912 if (cs->hw.hfcD.int_s1 & 0x18) {
913 exval = val;
914 val = cs->hw.hfcD.int_s1;
915 cs->hw.hfcD.int_s1 = exval;
917 if (val & 0x08) {
918 if (!(bcs=Sel_BCS(cs, 0))) {
919 if (cs->debug)
920 debugl1(cs, "hfcd spurious 0x08 IRQ");
921 } else
922 main_rec_2bds0(bcs);
924 if (val & 0x10) {
925 if (!(bcs=Sel_BCS(cs, 1))) {
926 if (cs->debug)
927 debugl1(cs, "hfcd spurious 0x10 IRQ");
928 } else
929 main_rec_2bds0(bcs);
931 if (val & 0x01) {
932 if (!(bcs=Sel_BCS(cs, 0))) {
933 if (cs->debug)
934 debugl1(cs, "hfcd spurious 0x01 IRQ");
935 } else {
936 if (bcs->tx_skb) {
937 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
938 hfc_fill_fifo(bcs);
939 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
940 } else
941 debugl1(cs,"fill_data %d blocked", bcs->channel);
942 } else {
943 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
944 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
945 hfc_fill_fifo(bcs);
946 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
947 } else
948 debugl1(cs,"fill_data %d blocked", bcs->channel);
949 } else {
950 hfc_sched_event(bcs, B_XMTBUFREADY);
955 if (val & 0x02) {
956 if (!(bcs=Sel_BCS(cs, 1))) {
957 if (cs->debug)
958 debugl1(cs, "hfcd spurious 0x02 IRQ");
959 } else {
960 if (bcs->tx_skb) {
961 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
962 hfc_fill_fifo(bcs);
963 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
964 } else
965 debugl1(cs,"fill_data %d blocked", bcs->channel);
966 } else {
967 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
968 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
969 hfc_fill_fifo(bcs);
970 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
971 } else
972 debugl1(cs,"fill_data %d blocked", bcs->channel);
973 } else {
974 hfc_sched_event(bcs, B_XMTBUFREADY);
979 if (val & 0x20) { /* receive dframe */
980 receive_dmsg(cs);
982 if (val & 0x04) { /* dframe transmitted */
983 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
984 del_timer(&cs->dbusytimer);
985 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
986 sched_event_D(cs, D_CLEARBUSY);
987 if (cs->tx_skb)
988 if (cs->tx_skb->len) {
989 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
990 hfc_fill_dfifo(cs);
991 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
992 } else {
993 debugl1(cs, "hfc_fill_dfifo irq blocked");
995 goto afterXPR;
996 } else {
997 dev_kfree_skb(cs->tx_skb);
998 cs->tx_cnt = 0;
999 cs->tx_skb = NULL;
1001 if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
1002 cs->tx_cnt = 0;
1003 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
1004 hfc_fill_dfifo(cs);
1005 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
1006 } else {
1007 debugl1(cs, "hfc_fill_dfifo irq blocked");
1009 } else
1010 sched_event_D(cs, D_XMTBUFREADY);
1012 afterXPR:
1013 if (cs->hw.hfcD.int_s1 && count--) {
1014 val = cs->hw.hfcD.int_s1;
1015 cs->hw.hfcD.int_s1 = 0;
1016 if (cs->debug & L1_DEB_ISAC)
1017 debugl1(cs, "HFCD irq %x loop %d", val, 15-count);
1018 } else
1019 val = 0;
1020 restore_flags(flags);
1024 static void
1025 HFCD_l1hw(struct PStack *st, int pr, void *arg)
1027 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
1028 struct sk_buff *skb = arg;
1030 switch (pr) {
1031 case (PH_DATA | REQUEST):
1032 if (cs->debug & DEB_DLOG_HEX)
1033 LogFrame(cs, skb->data, skb->len);
1034 if (cs->debug & DEB_DLOG_VERBOSE)
1035 dlogframe(cs, skb, 0);
1036 if (cs->tx_skb) {
1037 skb_queue_tail(&cs->sq, skb);
1038 #ifdef L2FRAME_DEBUG /* psa */
1039 if (cs->debug & L1_DEB_LAPD)
1040 Logl2Frame(cs, skb, "PH_DATA Queued", 0);
1041 #endif
1042 } else {
1043 cs->tx_skb = skb;
1044 cs->tx_cnt = 0;
1045 #ifdef L2FRAME_DEBUG /* psa */
1046 if (cs->debug & L1_DEB_LAPD)
1047 Logl2Frame(cs, skb, "PH_DATA", 0);
1048 #endif
1049 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
1050 hfc_fill_dfifo(cs);
1051 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
1052 } else
1053 debugl1(cs, "hfc_fill_dfifo blocked");
1056 break;
1057 case (PH_PULL | INDICATION):
1058 if (cs->tx_skb) {
1059 if (cs->debug & L1_DEB_WARN)
1060 debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
1061 skb_queue_tail(&cs->sq, skb);
1062 break;
1064 if (cs->debug & DEB_DLOG_HEX)
1065 LogFrame(cs, skb->data, skb->len);
1066 if (cs->debug & DEB_DLOG_VERBOSE)
1067 dlogframe(cs, skb, 0);
1068 cs->tx_skb = skb;
1069 cs->tx_cnt = 0;
1070 #ifdef L2FRAME_DEBUG /* psa */
1071 if (cs->debug & L1_DEB_LAPD)
1072 Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
1073 #endif
1074 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
1075 hfc_fill_dfifo(cs);
1076 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
1077 } else
1078 debugl1(cs, "hfc_fill_dfifo blocked");
1079 break;
1080 case (PH_PULL | REQUEST):
1081 #ifdef L2FRAME_DEBUG /* psa */
1082 if (cs->debug & L1_DEB_LAPD)
1083 debugl1(cs, "-> PH_REQUEST_PULL");
1084 #endif
1085 if (!cs->tx_skb) {
1086 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1087 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
1088 } else
1089 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1090 break;
1091 case (HW_RESET | REQUEST):
1092 cs->writeisac(cs, HFCD_STATES, HFCD_LOAD_STATE | 3); /* HFC ST 3 */
1093 udelay(6);
1094 cs->writeisac(cs, HFCD_STATES, 3); /* HFC ST 2 */
1095 cs->hw.hfcD.mst_m |= HFCD_MASTER;
1096 cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
1097 cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
1098 l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
1099 break;
1100 case (HW_ENABLE | REQUEST):
1101 cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
1102 break;
1103 case (HW_DEACTIVATE | REQUEST):
1104 cs->hw.hfcD.mst_m &= ~HFCD_MASTER;
1105 cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
1106 break;
1107 case (HW_INFO3 | REQUEST):
1108 cs->hw.hfcD.mst_m |= HFCD_MASTER;
1109 cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
1110 break;
1111 #if 0
1112 case (HW_TESTLOOP | REQUEST):
1113 u_char val = 0;
1114 if (1 & (int) arg)
1115 val |= 0x0c;
1116 if (2 & (int) arg)
1117 val |= 0x3;
1118 if (test_bit(HW_IOM1, &cs->HW_Flags)) {
1119 /* IOM 1 Mode */
1120 if (!val) {
1121 cs->writeisac(cs, ISAC_SPCR, 0xa);
1122 cs->writeisac(cs, ISAC_ADF1, 0x2);
1123 } else {
1124 cs->writeisac(cs, ISAC_SPCR, val);
1125 cs->writeisac(cs, ISAC_ADF1, 0xa);
1127 } else {
1128 /* IOM 2 Mode */
1129 cs->writeisac(cs, ISAC_SPCR, val);
1130 if (val)
1131 cs->writeisac(cs, ISAC_ADF1, 0x8);
1132 else
1133 cs->writeisac(cs, ISAC_ADF1, 0x0);
1135 break;
1136 #endif
1137 default:
1138 if (cs->debug & L1_DEB_WARN)
1139 debugl1(cs, "hfcd_l1hw unknown pr %4x", pr);
1140 break;
1144 void
1145 setstack_hfcd(struct PStack *st, struct IsdnCardState *cs)
1147 st->l1.l1hw = HFCD_l1hw;
1150 static void
1151 hfc_dbusy_timer(struct IsdnCardState *cs)
1153 #if 0
1154 struct PStack *stptr;
1155 if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
1156 if (cs->debug)
1157 debugl1(cs, "D-Channel Busy");
1158 test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
1159 stptr = cs->stlist;
1161 while (stptr != NULL) {
1162 stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
1163 stptr = stptr->next;
1166 #endif
1169 unsigned int __init
1170 *init_send_hfcd(int cnt)
1172 int i, *send;
1174 if (!(send = kmalloc(cnt * sizeof(unsigned int), GFP_ATOMIC))) {
1175 printk(KERN_WARNING
1176 "HiSax: No memory for hfcd.send\n");
1177 return(NULL);
1179 for (i = 0; i < cnt; i++)
1180 send[i] = 0x1fff;
1181 return(send);
1184 void __init
1185 init2bds0(struct IsdnCardState *cs)
1187 cs->setstack_d = setstack_hfcd;
1188 cs->dbusytimer.function = (void *) hfc_dbusy_timer;
1189 cs->dbusytimer.data = (long) cs;
1190 init_timer(&cs->dbusytimer);
1191 cs->tqueue.routine = (void *) (void *) hfcd_bh;
1192 if (!cs->hw.hfcD.send)
1193 cs->hw.hfcD.send = init_send_hfcd(16);
1194 if (!cs->bcs[0].hw.hfc.send)
1195 cs->bcs[0].hw.hfc.send = init_send_hfcd(32);
1196 if (!cs->bcs[1].hw.hfc.send)
1197 cs->bcs[1].hw.hfc.send = init_send_hfcd(32);
1198 cs->BC_Send_Data = &hfc_send_data;
1199 cs->bcs[0].BC_SetStack = setstack_2b;
1200 cs->bcs[1].BC_SetStack = setstack_2b;
1201 cs->bcs[0].BC_Close = close_2bs0;
1202 cs->bcs[1].BC_Close = close_2bs0;
1203 mode_2bs0(cs->bcs, 0, 0);
1204 mode_2bs0(cs->bcs + 1, 0, 1);
1207 void
1208 release2bds0(struct IsdnCardState *cs)
1210 if (cs->bcs[0].hw.hfc.send) {
1211 kfree(cs->bcs[0].hw.hfc.send);
1212 cs->bcs[0].hw.hfc.send = NULL;
1214 if (cs->bcs[1].hw.hfc.send) {
1215 kfree(cs->bcs[1].hw.hfc.send);
1216 cs->bcs[1].hw.hfc.send = NULL;
1218 if (cs->hw.hfcD.send) {
1219 kfree(cs->hw.hfcD.send);
1220 cs->hw.hfcD.send = NULL;