Import 2.3.46pre3
[davej-history.git] / drivers / isdn / hisax / hfc_sx.c
blob462de9d91ec5ff8a5cd1d48e929a13beb73b2453
1 /* $Id: hfc_sx.c,v 1.3 2000/01/20 19:49:36 keil Exp $
3 * hfc_sx.c low level driver for CCD´s hfc-s+/sp based cards
5 * Author Werner Cornelius (werner@isdn4linux.de)
6 * based on existing driver for CCD HFC PCI cards
8 * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de)
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * $Log: hfc_sx.c,v $
25 * Revision 1.3 2000/01/20 19:49:36 keil
26 * Support teles 13.3c vendor version 2.1
28 * Revision 1.2 1999/12/19 13:09:42 keil
29 * changed TASK_INTERRUPTIBLE into TASK_UNINTERRUPTIBLE for
30 * signal proof delays
32 * Revision 1.1 1999/11/18 00:09:18 werner
34 * Initial release of files for HFC-S+ and HFC-SP cards with 32K-RAM.
35 * Audio and Echo are supported.
41 #define __NO_VERSION__
42 #include "hisax.h"
43 #include "hfc_sx.h"
44 #include "isdnl1.h"
45 #include <linux/interrupt.h>
47 extern const char *CardType[];
49 static const char *hfcsx_revision = "$Revision: 1.3 $";
51 /***************************************/
52 /* IRQ-table for CCDs demo board */
53 /* IRQs 6,5,10,11,12,15 are supported */
54 /***************************************/
56 /* Teles 16.3c Vendor Id TAG2620, Version 1.0, Vendor version 2.1
58 * Thanks to Uwe Wisniewski
60 * ISA-SLOT Signal PIN
61 * B25 IRQ3 92 IRQ_G
62 * B23 IRQ5 94 IRQ_A
63 * B4 IRQ2/9 95 IRQ_B
64 * D3 IRQ10 96 IRQ_C
65 * D4 IRQ11 97 IRQ_D
66 * D5 IRQ12 98 IRQ_E
67 * D6 IRQ15 99 IRQ_F
70 #undef CCD_DEMO_BOARD
71 #ifdef CCD_DEMO_BOARD
72 static u_char ccd_sp_irqtab[16] = {
73 0,0,0,0,0,2,1,0,0,0,3,4,5,0,0,6
75 #else /* Teles 16.3c */
76 static u_char ccd_sp_irqtab[16] = {
77 0,0,0,7,0,1,0,0,0,2,3,4,5,0,0,6
79 #endif
80 #define NT_T1_COUNT 20 /* number of 3.125ms interrupts for G2 timeout */
82 #define byteout(addr,val) outb(val,addr)
83 #define bytein(addr) inb(addr)
85 /******************************/
86 /* In/Out access to registers */
87 /******************************/
88 static inline void
89 Write_hfc(struct IsdnCardState *cs, u_char regnum, u_char val)
90 { register int flags;
92 save_flags(flags);
93 cli();
94 byteout(cs->hw.hfcsx.base+1, regnum);
95 byteout(cs->hw.hfcsx.base, val);
96 restore_flags(flags);
99 static inline u_char
100 Read_hfc(struct IsdnCardState *cs, u_char regnum)
101 { register int flags;
102 register u_char ret;
104 save_flags(flags);
105 cli();
106 byteout(cs->hw.hfcsx.base+1, regnum);
107 ret = bytein(cs->hw.hfcsx.base);
108 restore_flags(flags);
109 return(ret);
113 /**************************************************/
114 /* select a fifo and remember which one for reuse */
115 /**************************************************/
116 static void
117 fifo_select(struct IsdnCardState *cs, u_char fifo)
118 { int flags;
120 if (fifo == cs->hw.hfcsx.last_fifo)
121 return; /* still valid */
123 save_flags(flags);
124 cli();
125 byteout(cs->hw.hfcsx.base+1, HFCSX_FIF_SEL);
126 byteout(cs->hw.hfcsx.base, fifo);
127 while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
128 udelay(4);
129 byteout(cs->hw.hfcsx.base, fifo);
130 while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
131 restore_flags(flags);
134 /******************************************/
135 /* reset the specified fifo to defaults. */
136 /* If its a send fifo init needed markers */
137 /******************************************/
138 static void
139 reset_fifo(struct IsdnCardState *cs, u_char fifo)
140 { int flags;
142 save_flags(flags);
143 cli();
144 fifo_select(cs, fifo); /* first select the fifo */
145 byteout(cs->hw.hfcsx.base+1, HFCSX_CIRM);
146 byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.cirm | 0x80); /* reset cmd */
147 udelay(1);
148 while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
149 restore_flags(flags);
153 /*************************************************************/
154 /* write_fifo writes the skb contents to the desired fifo */
155 /* if no space is available or an error occurs 0 is returned */
156 /* the skb is not released in any way. */
157 /*************************************************************/
158 static int
159 write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u_char fifo, int trans_max)
160 { unsigned short *msp;
161 int fifo_size, count, z1, z2;
162 u_char f_msk, f1, f2, *src;
164 if (skb->len <= 0) return(0);
165 if (fifo & 1) return(0); /* no write fifo */
167 fifo_select(cs, fifo);
168 if (fifo & 4) {
169 fifo_size = D_FIFO_SIZE; /* D-channel */
170 f_msk = MAX_D_FRAMES;
171 if (trans_max) return(0); /* only HDLC */
173 else {
174 fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */
175 f_msk = MAX_B_FRAMES;
178 z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
179 z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
181 /* Check for transparent mode */
182 if (trans_max) {
183 z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
184 z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
185 count = z2 - z1;
186 if (count <= 0)
187 count += fifo_size; /* free bytes */
188 if (count < skb->len+1) return(0); /* no room */
189 count = fifo_size - count; /* bytes still not send */
190 if (count > 2 * trans_max) return(0); /* delay to long */
191 count = skb->len;
192 src = skb->data;
193 while (count--)
194 Write_hfc(cs, HFCSX_FIF_DWR, *src++);
195 return(1); /* success */
198 msp = ((struct hfcsx_extra *)(cs->hw.hfcsx.extra))->marker;
199 msp += (((fifo >> 1) & 3) * (MAX_B_FRAMES+1));
200 f1 = Read_hfc(cs, HFCSX_FIF_F1) & f_msk;
201 f2 = Read_hfc(cs, HFCSX_FIF_F2) & f_msk;
203 count = f1 - f2; /* frame count actually buffered */
204 if (count < 0)
205 count += (f_msk + 1); /* if wrap around */
206 if (count > f_msk-1) {
207 if (cs->debug & L1_DEB_ISAC_FIFO)
208 debugl1(cs, "hfcsx_write_fifo %d more as %d frames",fifo,f_msk-1);
209 return(0);
212 *(msp + f1) = z1; /* remember marker */
214 if (cs->debug & L1_DEB_ISAC_FIFO)
215 debugl1(cs, "hfcsx_write_fifo %d f1(%x) f2(%x) z1(f1)(%x)",
216 fifo, f1, f2, z1);
217 /* now determine free bytes in FIFO buffer */
218 count = *(msp + f2) - z1;
219 if (count <= 0)
220 count += fifo_size; /* count now contains available bytes */
222 if (cs->debug & L1_DEB_ISAC_FIFO)
223 debugl1(cs, "hfcsx_write_fifo %d count(%ld/%d)",
224 fifo, skb->len, count);
225 if (count < skb->len) {
226 if (cs->debug & L1_DEB_ISAC_FIFO)
227 debugl1(cs, "hfcsx_write_fifo %d no fifo mem", fifo);
228 return(0);
231 count = skb->len; /* get frame len */
232 src = skb->data; /* source pointer */
233 while (count--)
234 Write_hfc(cs, HFCSX_FIF_DWR, *src++);
236 Read_hfc(cs, HFCSX_FIF_INCF1); /* increment F1 */
237 udelay(1);
238 while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
239 return(1);
242 /***************************************************************/
243 /* read_fifo reads data to an skb from the desired fifo */
244 /* if no data is available or an error occurs NULL is returned */
245 /* the skb is not released in any way. */
246 /***************************************************************/
247 static struct sk_buff *
248 read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max)
249 { int fifo_size, count, z1, z2;
250 u_char f_msk, f1, f2, *dst;
251 struct sk_buff *skb;
253 if (!(fifo & 1)) return(NULL); /* no read fifo */
254 fifo_select(cs, fifo);
255 if (fifo & 4) {
256 fifo_size = D_FIFO_SIZE; /* D-channel */
257 f_msk = MAX_D_FRAMES;
258 if (trans_max) return(NULL); /* only hdlc */
260 else {
261 fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */
262 f_msk = MAX_B_FRAMES;
265 /* transparent mode */
266 if (trans_max) {
267 z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
268 z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
269 z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
270 z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
271 /* now determine bytes in actual FIFO buffer */
272 count = z1 - z2;
273 if (count <= 0)
274 count += fifo_size; /* count now contains buffered bytes */
275 count++;
276 if (count > trans_max)
277 count = trans_max; /* limit length */
278 if ((skb = dev_alloc_skb(count))) {
279 dst = skb_put(skb, count);
280 while (count--)
281 *dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
282 return(skb);
284 else return(NULL); /* no memory */
287 do {
288 f1 = Read_hfc(cs, HFCSX_FIF_F1) & f_msk;
289 f2 = Read_hfc(cs, HFCSX_FIF_F2) & f_msk;
291 if (f1 == f2) return(NULL); /* no frame available */
293 z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
294 z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
295 z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
296 z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
298 if (cs->debug & L1_DEB_ISAC_FIFO)
299 debugl1(cs, "hfcsx_read_fifo %d f1(%x) f2(%x) z1(f2)(%x) z2(f2)(%x)",
300 fifo, f1, f2, z1, z2);
301 /* now determine bytes in actual FIFO buffer */
302 count = z1 - z2;
303 if (count <= 0)
304 count += fifo_size; /* count now contains buffered bytes */
305 count++;
307 if (cs->debug & L1_DEB_ISAC_FIFO)
308 debugl1(cs, "hfcsx_read_fifo %d count %ld)",
309 fifo, count);
311 if ((count > fifo_size) || (count < 4)) {
312 if (cs->debug & L1_DEB_WARN)
313 debugl1(cs, "hfcsx_read_fifo %d paket inv. len %d ", fifo , count);
314 while (count) {
315 count--; /* empty fifo */
316 Read_hfc(cs, HFCSX_FIF_DRD);
318 skb = NULL;
319 } else
320 if ((skb = dev_alloc_skb(count - 3))) {
321 count -= 3;
322 dst = skb_put(skb, count);
324 while (count--)
325 *dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
327 Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 1 */
328 Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 2 */
329 if (Read_hfc(cs, HFCSX_FIF_DRD)) {
330 dev_kfree_skb(skb);
331 if (cs->debug & L1_DEB_ISAC_FIFO)
332 debugl1(cs, "hfcsx_read_fifo %d crc error", fifo);
333 skb = NULL;
335 } else {
336 printk(KERN_WARNING "HFC-SX: receive out of memory\n");
337 return(NULL);
340 Read_hfc(cs, HFCSX_FIF_INCF2); /* increment F2 */
341 udelay(1);
342 while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
343 udelay(1);
344 } while (!skb); /* retry in case of crc error */
345 return(skb);
348 /******************************************/
349 /* free hardware resources used by driver */
350 /******************************************/
351 void
352 release_io_hfcsx(struct IsdnCardState *cs)
354 int flags;
356 save_flags(flags);
357 cli();
358 cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */
359 Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
360 restore_flags(flags);
361 Write_hfc(cs, HFCSX_CIRM, HFCSX_RESET); /* Reset On */
362 sti();
363 set_current_state(TASK_UNINTERRUPTIBLE);
364 schedule_timeout((30 * HZ) / 1000); /* Timeout 30ms */
365 Write_hfc(cs, HFCSX_CIRM, 0); /* Reset Off */
366 del_timer(&cs->hw.hfcsx.timer);
367 release_region(cs->hw.hfcsx.base, 2); /* release IO-Block */
368 kfree(cs->hw.hfcsx.extra);
369 cs->hw.hfcsx.extra = NULL;
372 /**********************************************************/
373 /* set_fifo_size determines the size of the RAM and FIFOs */
374 /* returning 0 -> need to reset the chip again. */
375 /**********************************************************/
376 static int set_fifo_size(struct IsdnCardState *cs)
379 if (cs->hw.hfcsx.b_fifo_size) return(1); /* already determined */
381 if ((cs->hw.hfcsx.chip >> 4) == 9) {
382 cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_32K;
383 return(1);
386 cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_8K;
387 cs->hw.hfcsx.cirm |= 0x10; /* only 8K of ram */
388 return(0);
392 /********************************************************************************/
393 /* function called to reset the HFC SX chip. A complete software reset of chip */
394 /* and fifos is done. */
395 /********************************************************************************/
396 static void
397 reset_hfcsx(struct IsdnCardState *cs)
399 long flags;
401 save_flags(flags);
402 cli();
403 cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */
404 Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
406 printk(KERN_INFO "HFC_SX: resetting card\n");
407 while (1) {
408 Write_hfc(cs, HFCSX_CIRM, HFCSX_RESET | cs->hw.hfcsx.cirm ); /* Reset */
409 sti();
410 set_current_state(TASK_UNINTERRUPTIBLE);
411 schedule_timeout((30 * HZ) / 1000); /* Timeout 30ms */
412 Write_hfc(cs, HFCSX_CIRM, cs->hw.hfcsx.cirm); /* Reset Off */
413 set_current_state(TASK_UNINTERRUPTIBLE);
414 schedule_timeout((20 * HZ) / 1000); /* Timeout 20ms */
415 if (Read_hfc(cs, HFCSX_STATUS) & 2)
416 printk(KERN_WARNING "HFC-SX init bit busy\n");
417 cs->hw.hfcsx.last_fifo = 0xff; /* invalidate */
418 if (!set_fifo_size(cs)) continue;
419 break;
422 cs->hw.hfcsx.trm = 0 + HFCSX_BTRANS_THRESMASK; /* no echo connect , threshold */
423 Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm);
425 Write_hfc(cs, HFCSX_CLKDEL, 0x0e); /* ST-Bit delay for TE-Mode */
426 cs->hw.hfcsx.sctrl_e = HFCSX_AUTO_AWAKE;
427 Write_hfc(cs, HFCSX_SCTRL_E, cs->hw.hfcsx.sctrl_e); /* S/T Auto awake */
428 cs->hw.hfcsx.bswapped = 0; /* no exchange */
429 cs->hw.hfcsx.nt_mode = 0; /* we are in TE mode */
430 cs->hw.hfcsx.ctmt = HFCSX_TIM3_125 | HFCSX_AUTO_TIMER;
431 Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt);
433 cs->hw.hfcsx.int_m1 = HFCSX_INTS_DTRANS | HFCSX_INTS_DREC |
434 HFCSX_INTS_L1STATE | HFCSX_INTS_TIMER;
435 Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
437 /* Clear already pending ints */
438 if (Read_hfc(cs, HFCSX_INT_S1));
440 Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 2); /* HFC ST 2 */
441 udelay(10);
442 Write_hfc(cs, HFCSX_STATES, 2); /* HFC ST 2 */
443 cs->hw.hfcsx.mst_m = HFCSX_MASTER; /* HFC Master Mode */
445 Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
446 cs->hw.hfcsx.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */
447 Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl);
448 cs->hw.hfcsx.sctrl_r = 0;
449 Write_hfc(cs, HFCSX_SCTRL_R, cs->hw.hfcsx.sctrl_r);
451 /* Init GCI/IOM2 in master mode */
452 /* Slots 0 and 1 are set for B-chan 1 and 2 */
453 /* D- and monitor/CI channel are not enabled */
454 /* STIO1 is used as output for data, B1+B2 from ST->IOM+HFC */
455 /* STIO2 is used as data input, B1+B2 from IOM->ST */
456 /* ST B-channel send disabled -> continous 1s */
457 /* The IOM slots are always enabled */
458 cs->hw.hfcsx.conn = 0x36; /* set data flow directions */
459 Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
460 Write_hfc(cs, HFCSX_B1_SSL, 0x80); /* B1-Slot 0 STIO1 out enabled */
461 Write_hfc(cs, HFCSX_B2_SSL, 0x81); /* B2-Slot 1 STIO1 out enabled */
462 Write_hfc(cs, HFCSX_B1_RSL, 0x80); /* B1-Slot 0 STIO2 in enabled */
463 Write_hfc(cs, HFCSX_B2_RSL, 0x81); /* B2-Slot 1 STIO2 in enabled */
465 /* Finally enable IRQ output */
466 cs->hw.hfcsx.int_m2 = HFCSX_IRQ_ENABLE;
467 Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
468 if (Read_hfc(cs, HFCSX_INT_S2));
469 restore_flags(flags);
472 /***************************************************/
473 /* Timer function called when kernel timer expires */
474 /***************************************************/
475 static void
476 hfcsx_Timer(struct IsdnCardState *cs)
478 cs->hw.hfcsx.timer.expires = jiffies + 75;
479 /* WD RESET */
480 /* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcsx.ctmt | 0x80);
481 add_timer(&cs->hw.hfcsx.timer);
486 /*********************************/
487 /* schedule a new D-channel task */
488 /*********************************/
489 static void
490 sched_event_D_sx(struct IsdnCardState *cs, int event)
492 test_and_set_bit(event, &cs->event);
493 queue_task(&cs->tqueue, &tq_immediate);
494 mark_bh(IMMEDIATE_BH);
497 /*********************************/
498 /* schedule a new b_channel task */
499 /*********************************/
500 static void
501 hfcsx_sched_event(struct BCState *bcs, int event)
503 bcs->event |= 1 << event;
504 queue_task(&bcs->tqueue, &tq_immediate);
505 mark_bh(IMMEDIATE_BH);
508 /************************************************/
509 /* select a b-channel entry matching and active */
510 /************************************************/
511 static
512 struct BCState *
513 Sel_BCS(struct IsdnCardState *cs, int channel)
515 if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
516 return (&cs->bcs[0]);
517 else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
518 return (&cs->bcs[1]);
519 else
520 return (NULL);
523 /*******************************/
524 /* D-channel receive procedure */
525 /*******************************/
526 static
528 receive_dmsg(struct IsdnCardState *cs)
530 struct sk_buff *skb;
531 int count = 5;
533 if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
534 debugl1(cs, "rec_dmsg blocked");
535 return (1);
538 do {
539 skb = read_fifo(cs, HFCSX_SEL_D_RX, 0);
540 if (skb) {
541 skb_queue_tail(&cs->rq, skb);
542 sched_event_D_sx(cs, D_RCVBUFREADY);
544 } while (--count && skb);
546 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
547 return (1);
550 /**********************************/
551 /* B-channel main receive routine */
552 /**********************************/
553 void
554 main_rec_hfcsx(struct BCState *bcs)
556 long flags;
557 struct IsdnCardState *cs = bcs->cs;
558 int count = 5;
559 struct sk_buff *skb;
561 save_flags(flags);
563 Begin:
564 count--;
565 cli();
566 if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
567 debugl1(cs, "rec_data %d blocked", bcs->channel);
568 restore_flags(flags);
569 return;
571 sti();
572 skb = read_fifo(cs, ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ?
573 HFCSX_SEL_B2_RX : HFCSX_SEL_B1_RX,
574 (bcs->mode == L1_MODE_TRANS) ?
575 HFCSX_BTRANS_THRESHOLD : 0);
577 if (skb) {
578 cli();
579 skb_queue_tail(&bcs->rqueue, skb);
580 sti();
581 hfcsx_sched_event(bcs, B_RCVBUFREADY);
584 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
585 if (count && skb)
586 goto Begin;
587 restore_flags(flags);
588 return;
591 /**************************/
592 /* D-channel send routine */
593 /**************************/
594 static void
595 hfcsx_fill_dfifo(struct IsdnCardState *cs)
597 if (!cs->tx_skb)
598 return;
599 if (cs->tx_skb->len <= 0)
600 return;
602 if (write_fifo(cs, cs->tx_skb, HFCSX_SEL_D_TX, 0)) {
603 dev_kfree_skb(cs->tx_skb);
604 cs->tx_skb = NULL;
606 return;
609 /**************************/
610 /* B-channel send routine */
611 /**************************/
612 static void
613 hfcsx_fill_fifo(struct BCState *bcs)
615 struct IsdnCardState *cs = bcs->cs;
616 int flags;
618 if (!bcs->tx_skb)
619 return;
620 if (bcs->tx_skb->len <= 0)
621 return;
623 save_flags(flags);
624 sti();
626 if (write_fifo(cs, bcs->tx_skb,
627 ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ?
628 HFCSX_SEL_B2_TX : HFCSX_SEL_B1_TX,
629 (bcs->mode == L1_MODE_TRANS) ?
630 HFCSX_BTRANS_THRESHOLD : 0)) {
632 bcs->tx_cnt -= bcs->tx_skb->len;
633 if (bcs->st->lli.l1writewakeup &&
634 (PACKET_NOACK != bcs->tx_skb->pkt_type))
635 bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
636 dev_kfree_skb(bcs->tx_skb);
637 bcs->tx_skb = NULL;
638 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
641 cli();
642 restore_flags(flags);
643 return;
646 /**********************************************/
647 /* D-channel l1 state call for leased NT-mode */
648 /**********************************************/
649 static void
650 dch_nt_l2l1(struct PStack *st, int pr, void *arg)
652 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
654 switch (pr) {
655 case (PH_DATA | REQUEST):
656 case (PH_PULL | REQUEST):
657 case (PH_PULL | INDICATION):
658 st->l1.l1hw(st, pr, arg);
659 break;
660 case (PH_ACTIVATE | REQUEST):
661 st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
662 break;
663 case (PH_TESTLOOP | REQUEST):
664 if (1 & (long) arg)
665 debugl1(cs, "PH_TEST_LOOP B1");
666 if (2 & (long) arg)
667 debugl1(cs, "PH_TEST_LOOP B2");
668 if (!(3 & (long) arg))
669 debugl1(cs, "PH_TEST_LOOP DISABLED");
670 st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
671 break;
672 default:
673 if (cs->debug)
674 debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr);
675 break;
681 /***********************/
682 /* set/reset echo mode */
683 /***********************/
684 static int
685 hfcsx_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic)
687 int flags;
688 int i = *(unsigned int *) ic->parm.num;
690 if ((ic->arg == 98) &&
691 (!(cs->hw.hfcsx.int_m1 & (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC + HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC)))) {
692 save_flags(flags);
693 cli();
694 Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 0); /* HFC ST G0 */
695 udelay(10);
696 cs->hw.hfcsx.sctrl |= SCTRL_MODE_NT;
697 Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl); /* set NT-mode */
698 udelay(10);
699 Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 1); /* HFC ST G1 */
700 udelay(10);
701 Write_hfc(cs, HFCSX_STATES, 1 | HFCSX_ACTIVATE | HFCSX_DO_ACTION);
702 cs->dc.hfcsx.ph_state = 1;
703 cs->hw.hfcsx.nt_mode = 1;
704 cs->hw.hfcsx.nt_timer = 0;
705 cs->stlist->l2.l2l1 = dch_nt_l2l1;
706 restore_flags(flags);
707 debugl1(cs, "NT mode activated");
708 return (0);
710 if ((cs->chanlimit > 1) || (cs->hw.hfcsx.bswapped) ||
711 (cs->hw.hfcsx.nt_mode) || (ic->arg != 12))
712 return (-EINVAL);
714 save_flags(flags);
715 cli();
716 if (i) {
717 cs->logecho = 1;
718 cs->hw.hfcsx.trm |= 0x20; /* enable echo chan */
719 cs->hw.hfcsx.int_m1 |= HFCSX_INTS_B2REC;
720 /* reset Channel !!!!! */
721 } else {
722 cs->logecho = 0;
723 cs->hw.hfcsx.trm &= ~0x20; /* disable echo chan */
724 cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_B2REC;
726 cs->hw.hfcsx.sctrl_r &= ~SCTRL_B2_ENA;
727 cs->hw.hfcsx.sctrl &= ~SCTRL_B2_ENA;
728 cs->hw.hfcsx.conn |= 0x10; /* B2-IOM -> B2-ST */
729 cs->hw.hfcsx.ctmt &= ~2;
730 Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt);
731 Write_hfc(cs, HFCSX_SCTRL_R, cs->hw.hfcsx.sctrl_r);
732 Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl);
733 Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
734 Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm);
735 Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
736 restore_flags(flags);
737 return (0);
738 } /* hfcsx_auxcmd */
740 /*****************************/
741 /* E-channel receive routine */
742 /*****************************/
743 static void
744 receive_emsg(struct IsdnCardState *cs)
746 int flags;
747 int count = 5;
748 u_char *ptr;
749 struct sk_buff *skb;
752 save_flags(flags);
753 cli();
754 if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
755 debugl1(cs, "echo_rec_data blocked");
756 restore_flags(flags);
757 return;
759 sti();
761 do {
762 skb = read_fifo(cs, HFCSX_SEL_B2_RX, 0);
763 if (skb) {
764 if (cs->debug & DEB_DLOG_HEX) {
765 ptr = cs->dlog;
766 if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) {
767 *ptr++ = 'E';
768 *ptr++ = 'C';
769 *ptr++ = 'H';
770 *ptr++ = 'O';
771 *ptr++ = ':';
772 ptr += QuickHex(ptr, skb->data, skb->len);
773 ptr--;
774 *ptr++ = '\n';
775 *ptr = 0;
776 HiSax_putstatus(cs, NULL, cs->dlog);
777 } else
778 HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len);
780 dev_kfree_skb(skb);
782 } while (--count && skb);
784 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
785 restore_flags(flags);
786 return;
787 } /* receive_emsg */
790 /*********************/
791 /* Interrupt handler */
792 /*********************/
793 static void
794 hfcsx_interrupt(int intno, void *dev_id, struct pt_regs *regs)
796 struct IsdnCardState *cs = dev_id;
797 u_char exval;
798 struct BCState *bcs;
799 int count = 15;
800 long flags;
801 u_char val, stat;
803 if (!cs) {
804 printk(KERN_WARNING "HFC-SX: Spurious interrupt!\n");
805 return;
807 if (!(cs->hw.hfcsx.int_m2 & 0x08))
808 return; /* not initialised */
810 if (HFCSX_ANYINT & (stat = Read_hfc(cs, HFCSX_STATUS))) {
811 val = Read_hfc(cs, HFCSX_INT_S1);
812 if (cs->debug & L1_DEB_ISAC)
813 debugl1(cs, "HFC-SX: stat(%02x) s1(%02x)", stat, val);
814 } else
815 return;
817 if (cs->debug & L1_DEB_ISAC)
818 debugl1(cs, "HFC-SX irq %x %s", val,
819 test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ?
820 "locked" : "unlocked");
821 val &= cs->hw.hfcsx.int_m1;
822 if (val & 0x40) { /* state machine irq */
823 exval = Read_hfc(cs, HFCSX_STATES) & 0xf;
824 if (cs->debug & L1_DEB_ISAC)
825 debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcsx.ph_state,
826 exval);
827 cs->dc.hfcsx.ph_state = exval;
828 sched_event_D_sx(cs, D_L1STATECHANGE);
829 val &= ~0x40;
831 if (val & 0x80) { /* timer irq */
832 if (cs->hw.hfcsx.nt_mode) {
833 if ((--cs->hw.hfcsx.nt_timer) < 0)
834 sched_event_D_sx(cs, D_L1STATECHANGE);
836 val &= ~0x80;
837 Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
839 while (val) {
840 save_flags(flags);
841 cli();
842 if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
843 cs->hw.hfcsx.int_s1 |= val;
844 restore_flags(flags);
845 return;
847 if (cs->hw.hfcsx.int_s1 & 0x18) {
848 exval = val;
849 val = cs->hw.hfcsx.int_s1;
850 cs->hw.hfcsx.int_s1 = exval;
852 if (val & 0x08) {
853 if (!(bcs = Sel_BCS(cs, cs->hw.hfcsx.bswapped ? 1 : 0))) {
854 if (cs->debug)
855 debugl1(cs, "hfcsx spurious 0x08 IRQ");
856 } else
857 main_rec_hfcsx(bcs);
859 if (val & 0x10) {
860 if (cs->logecho)
861 receive_emsg(cs);
862 else if (!(bcs = Sel_BCS(cs, 1))) {
863 if (cs->debug)
864 debugl1(cs, "hfcsx spurious 0x10 IRQ");
865 } else
866 main_rec_hfcsx(bcs);
868 if (val & 0x01) {
869 if (!(bcs = Sel_BCS(cs, cs->hw.hfcsx.bswapped ? 1 : 0))) {
870 if (cs->debug)
871 debugl1(cs, "hfcsx spurious 0x01 IRQ");
872 } else {
873 if (bcs->tx_skb) {
874 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
875 hfcsx_fill_fifo(bcs);
876 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
877 } else
878 debugl1(cs, "fill_data %d blocked", bcs->channel);
879 } else {
880 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
881 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
882 hfcsx_fill_fifo(bcs);
883 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
884 } else
885 debugl1(cs, "fill_data %d blocked", bcs->channel);
886 } else {
887 hfcsx_sched_event(bcs, B_XMTBUFREADY);
892 if (val & 0x02) {
893 if (!(bcs = Sel_BCS(cs, 1))) {
894 if (cs->debug)
895 debugl1(cs, "hfcsx spurious 0x02 IRQ");
896 } else {
897 if (bcs->tx_skb) {
898 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
899 hfcsx_fill_fifo(bcs);
900 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
901 } else
902 debugl1(cs, "fill_data %d blocked", bcs->channel);
903 } else {
904 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
905 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
906 hfcsx_fill_fifo(bcs);
907 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
908 } else
909 debugl1(cs, "fill_data %d blocked", bcs->channel);
910 } else {
911 hfcsx_sched_event(bcs, B_XMTBUFREADY);
916 if (val & 0x20) { /* receive dframe */
917 receive_dmsg(cs);
919 if (val & 0x04) { /* dframe transmitted */
920 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
921 del_timer(&cs->dbusytimer);
922 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
923 sched_event_D_sx(cs, D_CLEARBUSY);
924 if (cs->tx_skb) {
925 if (cs->tx_skb->len) {
926 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
927 hfcsx_fill_dfifo(cs);
928 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
929 } else {
930 debugl1(cs, "hfcsx_fill_dfifo irq blocked");
932 goto afterXPR;
933 } else {
934 dev_kfree_skb(cs->tx_skb);
935 cs->tx_cnt = 0;
936 cs->tx_skb = NULL;
939 if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
940 cs->tx_cnt = 0;
941 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
942 hfcsx_fill_dfifo(cs);
943 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
944 } else {
945 debugl1(cs, "hfcsx_fill_dfifo irq blocked");
947 } else
948 sched_event_D_sx(cs, D_XMTBUFREADY);
950 afterXPR:
951 if (cs->hw.hfcsx.int_s1 && count--) {
952 val = cs->hw.hfcsx.int_s1;
953 cs->hw.hfcsx.int_s1 = 0;
954 if (cs->debug & L1_DEB_ISAC)
955 debugl1(cs, "HFC-SX irq %x loop %d", val, 15 - count);
956 } else
957 val = 0;
958 restore_flags(flags);
962 /********************************************************************/
963 /* timer callback for D-chan busy resolution. Currently no function */
964 /********************************************************************/
965 static void
966 hfcsx_dbusy_timer(struct IsdnCardState *cs)
970 /*************************************/
971 /* Layer 1 D-channel hardware access */
972 /*************************************/
973 static void
974 HFCSX_l1hw(struct PStack *st, int pr, void *arg)
976 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
977 struct sk_buff *skb = arg;
978 int flags;
980 switch (pr) {
981 case (PH_DATA | REQUEST):
982 if (cs->debug & DEB_DLOG_HEX)
983 LogFrame(cs, skb->data, skb->len);
984 if (cs->debug & DEB_DLOG_VERBOSE)
985 dlogframe(cs, skb, 0);
986 if (cs->tx_skb) {
987 skb_queue_tail(&cs->sq, skb);
988 #ifdef L2FRAME_DEBUG /* psa */
989 if (cs->debug & L1_DEB_LAPD)
990 Logl2Frame(cs, skb, "PH_DATA Queued", 0);
991 #endif
992 } else {
993 cs->tx_skb = skb;
994 cs->tx_cnt = 0;
995 #ifdef L2FRAME_DEBUG /* psa */
996 if (cs->debug & L1_DEB_LAPD)
997 Logl2Frame(cs, skb, "PH_DATA", 0);
998 #endif
999 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
1000 hfcsx_fill_dfifo(cs);
1001 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
1002 } else
1003 debugl1(cs, "hfcsx_fill_dfifo blocked");
1006 break;
1007 case (PH_PULL | INDICATION):
1008 if (cs->tx_skb) {
1009 if (cs->debug & L1_DEB_WARN)
1010 debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
1011 skb_queue_tail(&cs->sq, skb);
1012 break;
1014 if (cs->debug & DEB_DLOG_HEX)
1015 LogFrame(cs, skb->data, skb->len);
1016 if (cs->debug & DEB_DLOG_VERBOSE)
1017 dlogframe(cs, skb, 0);
1018 cs->tx_skb = skb;
1019 cs->tx_cnt = 0;
1020 #ifdef L2FRAME_DEBUG /* psa */
1021 if (cs->debug & L1_DEB_LAPD)
1022 Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
1023 #endif
1024 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
1025 hfcsx_fill_dfifo(cs);
1026 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
1027 } else
1028 debugl1(cs, "hfcsx_fill_dfifo blocked");
1029 break;
1030 case (PH_PULL | REQUEST):
1031 #ifdef L2FRAME_DEBUG /* psa */
1032 if (cs->debug & L1_DEB_LAPD)
1033 debugl1(cs, "-> PH_REQUEST_PULL");
1034 #endif
1035 if (!cs->tx_skb) {
1036 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1037 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
1038 } else
1039 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1040 break;
1041 case (HW_RESET | REQUEST):
1042 Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 3); /* HFC ST 3 */
1043 udelay(6);
1044 Write_hfc(cs, HFCSX_STATES, 3); /* HFC ST 2 */
1045 cs->hw.hfcsx.mst_m |= HFCSX_MASTER;
1046 Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
1047 Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION);
1048 l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
1049 break;
1050 case (HW_ENABLE | REQUEST):
1051 Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION);
1052 break;
1053 case (HW_DEACTIVATE | REQUEST):
1054 cs->hw.hfcsx.mst_m &= ~HFCSX_MASTER;
1055 Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
1056 break;
1057 case (HW_INFO3 | REQUEST):
1058 cs->hw.hfcsx.mst_m |= HFCSX_MASTER;
1059 Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
1060 break;
1061 case (HW_TESTLOOP | REQUEST):
1062 switch ((int) arg) {
1063 case (1):
1064 Write_hfc(cs, HFCSX_B1_SSL, 0x80); /* tx slot */
1065 Write_hfc(cs, HFCSX_B1_RSL, 0x80); /* rx slot */
1066 save_flags(flags);
1067 cli();
1068 cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~7) | 1;
1069 Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
1070 restore_flags(flags);
1071 break;
1073 case (2):
1074 Write_hfc(cs, HFCSX_B2_SSL, 0x81); /* tx slot */
1075 Write_hfc(cs, HFCSX_B2_RSL, 0x81); /* rx slot */
1076 save_flags(flags);
1077 cli();
1078 cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~0x38) | 0x08;
1079 Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
1080 restore_flags(flags);
1081 break;
1083 default:
1084 if (cs->debug & L1_DEB_WARN)
1085 debugl1(cs, "hfcsx_l1hw loop invalid %4x", (int) arg);
1086 return;
1088 save_flags(flags);
1089 cli();
1090 cs->hw.hfcsx.trm |= 0x80; /* enable IOM-loop */
1091 Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm);
1092 restore_flags(flags);
1093 break;
1094 default:
1095 if (cs->debug & L1_DEB_WARN)
1096 debugl1(cs, "hfcsx_l1hw unknown pr %4x", pr);
1097 break;
1101 /***********************************************/
1102 /* called during init setting l1 stack pointer */
1103 /***********************************************/
1104 void
1105 setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs)
1107 st->l1.l1hw = HFCSX_l1hw;
1110 /**************************************/
1111 /* send B-channel data if not blocked */
1112 /**************************************/
1113 static void
1114 hfcsx_send_data(struct BCState *bcs)
1116 struct IsdnCardState *cs = bcs->cs;
1118 if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
1119 hfcsx_fill_fifo(bcs);
1120 test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
1121 } else
1122 debugl1(cs, "send_data %d blocked", bcs->channel);
1125 /***************************************************************/
1126 /* activate/deactivate hardware for selected channels and mode */
1127 /***************************************************************/
1128 void
1129 mode_hfcsx(struct BCState *bcs, int mode, int bc)
1131 struct IsdnCardState *cs = bcs->cs;
1132 int flags, fifo2;
1134 if (cs->debug & L1_DEB_HSCX)
1135 debugl1(cs, "HFCSX bchannel mode %d bchan %d/%d",
1136 mode, bc, bcs->channel);
1137 bcs->mode = mode;
1138 bcs->channel = bc;
1139 fifo2 = bc;
1140 save_flags(flags);
1141 cli();
1142 if (cs->chanlimit > 1) {
1143 cs->hw.hfcsx.bswapped = 0; /* B1 and B2 normal mode */
1144 cs->hw.hfcsx.sctrl_e &= ~0x80;
1145 } else {
1146 if (bc) {
1147 if (mode != L1_MODE_NULL) {
1148 cs->hw.hfcsx.bswapped = 1; /* B1 and B2 exchanged */
1149 cs->hw.hfcsx.sctrl_e |= 0x80;
1150 } else {
1151 cs->hw.hfcsx.bswapped = 0; /* B1 and B2 normal mode */
1152 cs->hw.hfcsx.sctrl_e &= ~0x80;
1154 fifo2 = 0;
1155 } else {
1156 cs->hw.hfcsx.bswapped = 0; /* B1 and B2 normal mode */
1157 cs->hw.hfcsx.sctrl_e &= ~0x80;
1160 switch (mode) {
1161 case (L1_MODE_NULL):
1162 if (bc) {
1163 cs->hw.hfcsx.sctrl &= ~SCTRL_B2_ENA;
1164 cs->hw.hfcsx.sctrl_r &= ~SCTRL_B2_ENA;
1165 } else {
1166 cs->hw.hfcsx.sctrl &= ~SCTRL_B1_ENA;
1167 cs->hw.hfcsx.sctrl_r &= ~SCTRL_B1_ENA;
1169 if (fifo2) {
1170 cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
1171 } else {
1172 cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
1174 break;
1175 case (L1_MODE_TRANS):
1176 if (bc) {
1177 cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
1178 cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
1179 } else {
1180 cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
1181 cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
1183 if (fifo2) {
1184 cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
1185 cs->hw.hfcsx.ctmt |= 2;
1186 cs->hw.hfcsx.conn &= ~0x18;
1187 } else {
1188 cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
1189 cs->hw.hfcsx.ctmt |= 1;
1190 cs->hw.hfcsx.conn &= ~0x03;
1192 break;
1193 case (L1_MODE_HDLC):
1194 if (bc) {
1195 cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
1196 cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
1197 } else {
1198 cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
1199 cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
1201 if (fifo2) {
1202 cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
1203 cs->hw.hfcsx.ctmt &= ~2;
1204 cs->hw.hfcsx.conn &= ~0x18;
1205 } else {
1206 cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
1207 cs->hw.hfcsx.ctmt &= ~1;
1208 cs->hw.hfcsx.conn &= ~0x03;
1210 break;
1211 case (L1_MODE_EXTRN):
1212 if (bc) {
1213 cs->hw.hfcsx.conn |= 0x10;
1214 cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
1215 cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
1216 cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
1217 } else {
1218 cs->hw.hfcsx.conn |= 0x02;
1219 cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
1220 cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
1221 cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
1223 break;
1225 Write_hfc(cs, HFCSX_SCTRL_E, cs->hw.hfcsx.sctrl_e);
1226 Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1227 Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl);
1228 Write_hfc(cs, HFCSX_SCTRL_R, cs->hw.hfcsx.sctrl_r);
1229 Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt);
1230 Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
1231 if (mode != L1_MODE_EXTRN) {
1232 reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_RX : HFCSX_SEL_B1_RX);
1233 reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_TX : HFCSX_SEL_B1_TX);
1235 restore_flags(flags);
1238 /******************************/
1239 /* Layer2 -> Layer 1 Transfer */
1240 /******************************/
1241 static void
1242 hfcsx_l2l1(struct PStack *st, int pr, void *arg)
1244 struct sk_buff *skb = arg;
1245 long flags;
1247 switch (pr) {
1248 case (PH_DATA | REQUEST):
1249 save_flags(flags);
1250 cli();
1251 if (st->l1.bcs->tx_skb) {
1252 skb_queue_tail(&st->l1.bcs->squeue, skb);
1253 restore_flags(flags);
1254 } else {
1255 st->l1.bcs->tx_skb = skb;
1256 /* test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
1257 */ st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
1258 restore_flags(flags);
1260 break;
1261 case (PH_PULL | INDICATION):
1262 if (st->l1.bcs->tx_skb) {
1263 printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
1264 break;
1266 save_flags(flags);
1267 cli();
1268 /* test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
1269 */ st->l1.bcs->tx_skb = skb;
1270 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
1271 restore_flags(flags);
1272 break;
1273 case (PH_PULL | REQUEST):
1274 if (!st->l1.bcs->tx_skb) {
1275 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1276 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
1277 } else
1278 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1279 break;
1280 case (PH_ACTIVATE | REQUEST):
1281 test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
1282 mode_hfcsx(st->l1.bcs, st->l1.mode, st->l1.bc);
1283 l1_msg_b(st, pr, arg);
1284 break;
1285 case (PH_DEACTIVATE | REQUEST):
1286 l1_msg_b(st, pr, arg);
1287 break;
1288 case (PH_DEACTIVATE | CONFIRM):
1289 test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
1290 test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
1291 mode_hfcsx(st->l1.bcs, 0, st->l1.bc);
1292 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
1293 break;
1297 /******************************************/
1298 /* deactivate B-channel access and queues */
1299 /******************************************/
1300 static void
1301 close_hfcsx(struct BCState *bcs)
1303 mode_hfcsx(bcs, 0, bcs->channel);
1304 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
1305 discard_queue(&bcs->rqueue);
1306 discard_queue(&bcs->squeue);
1307 if (bcs->tx_skb) {
1308 dev_kfree_skb(bcs->tx_skb);
1309 bcs->tx_skb = NULL;
1310 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
1315 /*************************************/
1316 /* init B-channel queues and control */
1317 /*************************************/
1318 static int
1319 open_hfcsxstate(struct IsdnCardState *cs, struct BCState *bcs)
1321 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
1322 skb_queue_head_init(&bcs->rqueue);
1323 skb_queue_head_init(&bcs->squeue);
1325 bcs->tx_skb = NULL;
1326 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
1327 bcs->event = 0;
1328 bcs->tx_cnt = 0;
1329 return (0);
1332 /*********************************/
1333 /* inits the stack for B-channel */
1334 /*********************************/
1335 static int
1336 setstack_2b(struct PStack *st, struct BCState *bcs)
1338 bcs->channel = st->l1.bc;
1339 if (open_hfcsxstate(st->l1.hardware, bcs))
1340 return (-1);
1341 st->l1.bcs = bcs;
1342 st->l2.l2l1 = hfcsx_l2l1;
1343 setstack_manager(st);
1344 bcs->st = st;
1345 setstack_l1_B(st);
1346 return (0);
1349 /***************************/
1350 /* handle L1 state changes */
1351 /***************************/
1352 static void
1353 hfcsx_bh(struct IsdnCardState *cs)
1355 int flags;
1356 /* struct PStack *stptr;
1358 if (!cs)
1359 return;
1360 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
1361 if (!cs->hw.hfcsx.nt_mode)
1362 switch (cs->dc.hfcsx.ph_state) {
1363 case (0):
1364 l1_msg(cs, HW_RESET | INDICATION, NULL);
1365 break;
1366 case (3):
1367 l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
1368 break;
1369 case (8):
1370 l1_msg(cs, HW_RSYNC | INDICATION, NULL);
1371 break;
1372 case (6):
1373 l1_msg(cs, HW_INFO2 | INDICATION, NULL);
1374 break;
1375 case (7):
1376 l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
1377 break;
1378 default:
1379 break;
1380 } else {
1381 switch (cs->dc.hfcsx.ph_state) {
1382 case (2):
1383 save_flags(flags);
1384 cli();
1385 if (cs->hw.hfcsx.nt_timer < 0) {
1386 cs->hw.hfcsx.nt_timer = 0;
1387 cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
1388 Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1389 /* Clear already pending ints */
1390 if (Read_hfc(cs, HFCSX_INT_S1));
1392 Write_hfc(cs, HFCSX_STATES, 4 | HFCSX_LOAD_STATE);
1393 udelay(10);
1394 Write_hfc(cs, HFCSX_STATES, 4);
1395 cs->dc.hfcsx.ph_state = 4;
1396 } else {
1397 cs->hw.hfcsx.int_m1 |= HFCSX_INTS_TIMER;
1398 Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1399 cs->hw.hfcsx.ctmt &= ~HFCSX_AUTO_TIMER;
1400 cs->hw.hfcsx.ctmt |= HFCSX_TIM3_125;
1401 Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
1402 Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
1403 cs->hw.hfcsx.nt_timer = NT_T1_COUNT;
1404 Write_hfc(cs, HFCSX_STATES, 2 | HFCSX_NT_G2_G3); /* allow G2 -> G3 transition */
1406 restore_flags(flags);
1407 break;
1408 case (1):
1409 case (3):
1410 case (4):
1411 save_flags(flags);
1412 cli();
1413 cs->hw.hfcsx.nt_timer = 0;
1414 cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
1415 Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1416 restore_flags(flags);
1417 break;
1418 default:
1419 break;
1423 if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
1424 DChannel_proc_rcv(cs);
1425 if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
1426 DChannel_proc_xmt(cs);
1430 /********************************/
1431 /* called for card init message */
1432 /********************************/
1433 __initfunc(void
1434 inithfcsx(struct IsdnCardState *cs))
1436 cs->setstack_d = setstack_hfcsx;
1437 cs->dbusytimer.function = (void *) hfcsx_dbusy_timer;
1438 cs->dbusytimer.data = (long) cs;
1439 init_timer(&cs->dbusytimer);
1440 cs->tqueue.routine = (void *) (void *) hfcsx_bh;
1441 cs->BC_Send_Data = &hfcsx_send_data;
1442 cs->bcs[0].BC_SetStack = setstack_2b;
1443 cs->bcs[1].BC_SetStack = setstack_2b;
1444 cs->bcs[0].BC_Close = close_hfcsx;
1445 cs->bcs[1].BC_Close = close_hfcsx;
1446 mode_hfcsx(cs->bcs, 0, 0);
1447 mode_hfcsx(cs->bcs + 1, 0, 1);
1452 /*******************************************/
1453 /* handle card messages from control layer */
1454 /*******************************************/
1455 static int
1456 hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg)
1458 long flags;
1460 if (cs->debug & L1_DEB_ISAC)
1461 debugl1(cs, "HFCSX: card_msg %x", mt);
1462 switch (mt) {
1463 case CARD_RESET:
1464 reset_hfcsx(cs);
1465 return (0);
1466 case CARD_RELEASE:
1467 release_io_hfcsx(cs);
1468 return (0);
1469 case CARD_INIT:
1470 inithfcsx(cs);
1471 save_flags(flags);
1472 sti();
1473 set_current_state(TASK_UNINTERRUPTIBLE);
1474 schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */
1475 /* now switch timer interrupt off */
1476 cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
1477 Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1478 /* reinit mode reg */
1479 Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
1480 restore_flags(flags);
1481 return (0);
1482 case CARD_TEST:
1483 return (0);
1485 return (0);
1490 __initfunc(int
1491 setup_hfcsx(struct IsdnCard *card))
1493 struct IsdnCardState *cs = card->cs;
1494 char tmp[64];
1495 int flags;
1497 strcpy(tmp, hfcsx_revision);
1498 printk(KERN_INFO "HiSax: HFC-SX driver Rev. %s\n", HiSax_getrev(tmp));
1499 cs->hw.hfcsx.base = card->para[1] & 0xfffe;
1500 cs->irq = card->para[0];
1501 cs->hw.hfcsx.int_s1 = 0;
1502 cs->dc.hfcsx.ph_state = 0;
1503 cs->hw.hfcsx.fifo = 255;
1504 if (cs->typ == ISDN_CTYPE_HFC_SX) {
1505 if ((!cs->hw.hfcsx.base) ||
1506 check_region((cs->hw.hfcsx.base), 2)) {
1507 printk(KERN_WARNING
1508 "HiSax: HFC-SX io-base 0x%x already in use\n",
1509 cs->hw.hfcsx.base);
1510 return(0);
1511 } else {
1512 request_region(cs->hw.hfcsx.base, 2, "HFCSX isdn");
1514 byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF);
1515 byteout(cs->hw.hfcsx.base + 1,
1516 ((cs->hw.hfcsx.base >> 8) & 3) | 0x54);
1517 udelay(10);
1518 cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID);
1519 switch (cs->hw.hfcsx.chip >> 4) {
1520 case 1:
1521 tmp[0] ='+';
1522 break;
1523 case 9:
1524 tmp[0] ='P';
1525 break;
1526 default:
1527 printk(KERN_WARNING
1528 "HFC-SX: invalid chip id 0x%x\n",
1529 cs->hw.hfcsx.chip >> 4);
1530 release_region(cs->hw.hfcsx.base, 2);
1531 return(0);
1533 if (!ccd_sp_irqtab[cs->irq & 0xF]) {
1534 printk(KERN_WARNING
1535 "HFC_SX: invalid irq %d specified\n",cs->irq & 0xF);
1536 release_region(cs->hw.hfcsx.base, 2);
1537 return(0);
1539 save_flags(flags);
1540 cli();
1541 if (!(cs->hw.hfcsx.extra = (void *)
1542 kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC))) {
1543 restore_flags(flags);
1544 release_region(cs->hw.hfcsx.base, 2);
1545 printk(KERN_WARNING "HFC-SX: unable to allocate memory\n");
1546 return(0);
1548 restore_flags(flags);
1550 printk(KERN_INFO
1551 "HFC-S%c chip detected at base 0x%x IRQ %d HZ %d\n",
1552 tmp[0], (u_int) cs->hw.hfcsx.base,
1553 cs->irq, HZ);
1554 cs->hw.hfcsx.int_m2 = 0; /* disable alle interrupts */
1555 cs->hw.hfcsx.int_m1 = 0;
1556 Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1557 Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
1558 } else
1559 return (0); /* no valid card type */
1561 cs->readisac = NULL;
1562 cs->writeisac = NULL;
1563 cs->readisacfifo = NULL;
1564 cs->writeisacfifo = NULL;
1565 cs->BC_Read_Reg = NULL;
1566 cs->BC_Write_Reg = NULL;
1567 cs->irq_func = &hfcsx_interrupt;
1569 cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer;
1570 cs->hw.hfcsx.timer.data = (long) cs;
1571 cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */
1572 cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */
1573 init_timer(&cs->hw.hfcsx.timer);
1575 reset_hfcsx(cs);
1576 cs->cardmsg = &hfcsx_card_msg;
1577 cs->auxcmd = &hfcsx_auxcmd;
1578 return (1);