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)
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.
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
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__
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
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
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 /******************************/
89 Write_hfc(struct IsdnCardState
*cs
, u_char regnum
, u_char val
)
94 byteout(cs
->hw
.hfcsx
.base
+1, regnum
);
95 byteout(cs
->hw
.hfcsx
.base
, val
);
100 Read_hfc(struct IsdnCardState
*cs
, u_char regnum
)
101 { register int flags
;
106 byteout(cs
->hw
.hfcsx
.base
+1, regnum
);
107 ret
= bytein(cs
->hw
.hfcsx
.base
);
108 restore_flags(flags
);
113 /**************************************************/
114 /* select a fifo and remember which one for reuse */
115 /**************************************************/
117 fifo_select(struct IsdnCardState
*cs
, u_char fifo
)
120 if (fifo
== cs
->hw
.hfcsx
.last_fifo
)
121 return; /* still valid */
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 */
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 /******************************************/
139 reset_fifo(struct IsdnCardState
*cs
, u_char fifo
)
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 */
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 /*************************************************************/
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
);
169 fifo_size
= D_FIFO_SIZE
; /* D-channel */
170 f_msk
= MAX_D_FRAMES
;
171 if (trans_max
) return(0); /* only HDLC */
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 */
183 z2
= Read_hfc(cs
, HFCSX_FIF_Z2H
);
184 z2
= ((z2
<< 8) | Read_hfc(cs
, HFCSX_FIF_Z2L
));
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 */
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 */
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);
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)",
217 /* now determine free bytes in FIFO buffer */
218 count
= *(msp
+ f2
) - z1
;
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
);
231 count
= skb
->len
; /* get frame len */
232 src
= skb
->data
; /* source pointer */
234 Write_hfc(cs
, HFCSX_FIF_DWR
, *src
++);
236 Read_hfc(cs
, HFCSX_FIF_INCF1
); /* increment F1 */
238 while (bytein(cs
->hw
.hfcsx
.base
+1) & 1); /* wait for busy */
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
;
253 if (!(fifo
& 1)) return(NULL
); /* no read fifo */
254 fifo_select(cs
, fifo
);
256 fifo_size
= D_FIFO_SIZE
; /* D-channel */
257 f_msk
= MAX_D_FRAMES
;
258 if (trans_max
) return(NULL
); /* only hdlc */
261 fifo_size
= cs
->hw
.hfcsx
.b_fifo_size
; /* B-channel */
262 f_msk
= MAX_B_FRAMES
;
265 /* transparent mode */
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 */
274 count
+= fifo_size
; /* count now contains buffered bytes */
276 if (count
> trans_max
)
277 count
= trans_max
; /* limit length */
278 if ((skb
= dev_alloc_skb(count
))) {
279 dst
= skb_put(skb
, count
);
281 *dst
++ = Read_hfc(cs
, HFCSX_FIF_DRD
);
284 else return(NULL
); /* no memory */
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 */
304 count
+= fifo_size
; /* count now contains buffered bytes */
307 if (cs
->debug
& L1_DEB_ISAC_FIFO
)
308 debugl1(cs
, "hfcsx_read_fifo %d count %ld)",
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
);
315 count
--; /* empty fifo */
316 Read_hfc(cs
, HFCSX_FIF_DRD
);
320 if ((skb
= dev_alloc_skb(count
- 3))) {
322 dst
= skb_put(skb
, 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
)) {
331 if (cs
->debug
& L1_DEB_ISAC_FIFO
)
332 debugl1(cs
, "hfcsx_read_fifo %d crc error", fifo
);
336 printk(KERN_WARNING
"HFC-SX: receive out of memory\n");
340 Read_hfc(cs
, HFCSX_FIF_INCF2
); /* increment F2 */
342 while (bytein(cs
->hw
.hfcsx
.base
+1) & 1); /* wait for busy */
344 } while (!skb
); /* retry in case of crc error */
348 /******************************************/
349 /* free hardware resources used by driver */
350 /******************************************/
352 release_io_hfcsx(struct IsdnCardState
*cs
)
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 */
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
;
386 cs
->hw
.hfcsx
.b_fifo_size
= B_FIFO_SIZE_8K
;
387 cs
->hw
.hfcsx
.cirm
|= 0x10; /* only 8K of ram */
392 /********************************************************************************/
393 /* function called to reset the HFC SX chip. A complete software reset of chip */
394 /* and fifos is done. */
395 /********************************************************************************/
397 reset_hfcsx(struct IsdnCardState
*cs
)
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");
408 Write_hfc(cs
, HFCSX_CIRM
, HFCSX_RESET
| cs
->hw
.hfcsx
.cirm
); /* Reset */
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;
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 */
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 /***************************************************/
476 hfcsx_Timer(struct IsdnCardState
*cs
)
478 cs
->hw
.hfcsx
.timer
.expires
= jiffies
+ 75;
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 /*********************************/
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 /*********************************/
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 /************************************************/
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]);
523 /*******************************/
524 /* D-channel receive procedure */
525 /*******************************/
528 receive_dmsg(struct IsdnCardState
*cs
)
533 if (test_and_set_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
)) {
534 debugl1(cs
, "rec_dmsg blocked");
539 skb
= read_fifo(cs
, HFCSX_SEL_D_RX
, 0);
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
);
550 /**********************************/
551 /* B-channel main receive routine */
552 /**********************************/
554 main_rec_hfcsx(struct BCState
*bcs
)
557 struct IsdnCardState
*cs
= bcs
->cs
;
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
);
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);
579 skb_queue_tail(&bcs
->rqueue
, skb
);
581 hfcsx_sched_event(bcs
, B_RCVBUFREADY
);
584 test_and_clear_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
);
587 restore_flags(flags
);
591 /**************************/
592 /* D-channel send routine */
593 /**************************/
595 hfcsx_fill_dfifo(struct IsdnCardState
*cs
)
599 if (cs
->tx_skb
->len
<= 0)
602 if (write_fifo(cs
, cs
->tx_skb
, HFCSX_SEL_D_TX
, 0)) {
603 dev_kfree_skb(cs
->tx_skb
);
609 /**************************/
610 /* B-channel send routine */
611 /**************************/
613 hfcsx_fill_fifo(struct BCState
*bcs
)
615 struct IsdnCardState
*cs
= bcs
->cs
;
620 if (bcs
->tx_skb
->len
<= 0)
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
);
638 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
642 restore_flags(flags
);
646 /**********************************************/
647 /* D-channel l1 state call for leased NT-mode */
648 /**********************************************/
650 dch_nt_l2l1(struct PStack
*st
, int pr
, void *arg
)
652 struct IsdnCardState
*cs
= (struct IsdnCardState
*) st
->l1
.hardware
;
655 case (PH_DATA
| REQUEST
):
656 case (PH_PULL
| REQUEST
):
657 case (PH_PULL
| INDICATION
):
658 st
->l1
.l1hw(st
, pr
, arg
);
660 case (PH_ACTIVATE
| REQUEST
):
661 st
->l1
.l1l2(st
, PH_ACTIVATE
| CONFIRM
, NULL
);
663 case (PH_TESTLOOP
| REQUEST
):
665 debugl1(cs
, "PH_TEST_LOOP B1");
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
);
674 debugl1(cs
, "dch_nt_l2l1 msg %04X unhandled", pr
);
681 /***********************/
682 /* set/reset echo mode */
683 /***********************/
685 hfcsx_auxcmd(struct IsdnCardState
*cs
, isdn_ctrl
* ic
)
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
)))) {
694 Write_hfc(cs
, HFCSX_STATES
, HFCSX_LOAD_STATE
| 0); /* HFC ST G0 */
696 cs
->hw
.hfcsx
.sctrl
|= SCTRL_MODE_NT
;
697 Write_hfc(cs
, HFCSX_SCTRL
, cs
->hw
.hfcsx
.sctrl
); /* set NT-mode */
699 Write_hfc(cs
, HFCSX_STATES
, HFCSX_LOAD_STATE
| 1); /* HFC ST G1 */
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");
710 if ((cs
->chanlimit
> 1) || (cs
->hw
.hfcsx
.bswapped
) ||
711 (cs
->hw
.hfcsx
.nt_mode
) || (ic
->arg
!= 12))
718 cs
->hw
.hfcsx
.trm
|= 0x20; /* enable echo chan */
719 cs
->hw
.hfcsx
.int_m1
|= HFCSX_INTS_B2REC
;
720 /* reset Channel !!!!! */
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
);
740 /*****************************/
741 /* E-channel receive routine */
742 /*****************************/
744 receive_emsg(struct IsdnCardState
*cs
)
754 if (test_and_set_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
)) {
755 debugl1(cs
, "echo_rec_data blocked");
756 restore_flags(flags
);
762 skb
= read_fifo(cs
, HFCSX_SEL_B2_RX
, 0);
764 if (cs
->debug
& DEB_DLOG_HEX
) {
766 if ((skb
->len
) < MAX_DLOG_SPACE
/ 3 - 10) {
772 ptr
+= QuickHex(ptr
, skb
->data
, skb
->len
);
776 HiSax_putstatus(cs
, NULL
, cs
->dlog
);
778 HiSax_putstatus(cs
, "LogEcho: ", "warning Frame too big (%d)", skb
->len
);
782 } while (--count
&& skb
);
784 test_and_clear_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
);
785 restore_flags(flags
);
790 /*********************/
791 /* Interrupt handler */
792 /*********************/
794 hfcsx_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
796 struct IsdnCardState
*cs
= dev_id
;
804 printk(KERN_WARNING
"HFC-SX: Spurious interrupt!\n");
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
);
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
,
827 cs
->dc
.hfcsx
.ph_state
= exval
;
828 sched_event_D_sx(cs
, D_L1STATECHANGE
);
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
);
837 Write_hfc(cs
, HFCSX_CTMT
, cs
->hw
.hfcsx
.ctmt
| HFCSX_CLTIMER
);
842 if (test_bit(FLG_LOCK_ATOMIC
, &cs
->HW_Flags
)) {
843 cs
->hw
.hfcsx
.int_s1
|= val
;
844 restore_flags(flags
);
847 if (cs
->hw
.hfcsx
.int_s1
& 0x18) {
849 val
= cs
->hw
.hfcsx
.int_s1
;
850 cs
->hw
.hfcsx
.int_s1
= exval
;
853 if (!(bcs
= Sel_BCS(cs
, cs
->hw
.hfcsx
.bswapped
? 1 : 0))) {
855 debugl1(cs
, "hfcsx spurious 0x08 IRQ");
862 else if (!(bcs
= Sel_BCS(cs
, 1))) {
864 debugl1(cs
, "hfcsx spurious 0x10 IRQ");
869 if (!(bcs
= Sel_BCS(cs
, cs
->hw
.hfcsx
.bswapped
? 1 : 0))) {
871 debugl1(cs
, "hfcsx spurious 0x01 IRQ");
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
);
878 debugl1(cs
, "fill_data %d blocked", bcs
->channel
);
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
);
885 debugl1(cs
, "fill_data %d blocked", bcs
->channel
);
887 hfcsx_sched_event(bcs
, B_XMTBUFREADY
);
893 if (!(bcs
= Sel_BCS(cs
, 1))) {
895 debugl1(cs
, "hfcsx spurious 0x02 IRQ");
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
);
902 debugl1(cs
, "fill_data %d blocked", bcs
->channel
);
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
);
909 debugl1(cs
, "fill_data %d blocked", bcs
->channel
);
911 hfcsx_sched_event(bcs
, B_XMTBUFREADY
);
916 if (val
& 0x20) { /* receive dframe */
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
);
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
);
930 debugl1(cs
, "hfcsx_fill_dfifo irq blocked");
934 dev_kfree_skb(cs
->tx_skb
);
939 if ((cs
->tx_skb
= skb_dequeue(&cs
->sq
))) {
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
);
945 debugl1(cs
, "hfcsx_fill_dfifo irq blocked");
948 sched_event_D_sx(cs
, D_XMTBUFREADY
);
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
);
958 restore_flags(flags
);
962 /********************************************************************/
963 /* timer callback for D-chan busy resolution. Currently no function */
964 /********************************************************************/
966 hfcsx_dbusy_timer(struct IsdnCardState
*cs
)
970 /*************************************/
971 /* Layer 1 D-channel hardware access */
972 /*************************************/
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
;
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);
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);
995 #ifdef L2FRAME_DEBUG /* psa */
996 if (cs
->debug
& L1_DEB_LAPD
)
997 Logl2Frame(cs
, skb
, "PH_DATA", 0);
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
);
1003 debugl1(cs
, "hfcsx_fill_dfifo blocked");
1007 case (PH_PULL
| INDICATION
):
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
);
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);
1020 #ifdef L2FRAME_DEBUG /* psa */
1021 if (cs
->debug
& L1_DEB_LAPD
)
1022 Logl2Frame(cs
, skb
, "PH_DATA_PULLED", 0);
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
);
1028 debugl1(cs
, "hfcsx_fill_dfifo blocked");
1030 case (PH_PULL
| REQUEST
):
1031 #ifdef L2FRAME_DEBUG /* psa */
1032 if (cs
->debug
& L1_DEB_LAPD
)
1033 debugl1(cs
, "-> PH_REQUEST_PULL");
1036 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
1037 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
1039 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
1041 case (HW_RESET
| REQUEST
):
1042 Write_hfc(cs
, HFCSX_STATES
, HFCSX_LOAD_STATE
| 3); /* HFC ST 3 */
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
);
1050 case (HW_ENABLE
| REQUEST
):
1051 Write_hfc(cs
, HFCSX_STATES
, HFCSX_ACTIVATE
| HFCSX_DO_ACTION
);
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
);
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
);
1061 case (HW_TESTLOOP
| REQUEST
):
1062 switch ((int) arg
) {
1064 Write_hfc(cs
, HFCSX_B1_SSL
, 0x80); /* tx slot */
1065 Write_hfc(cs
, HFCSX_B1_RSL
, 0x80); /* rx slot */
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
);
1074 Write_hfc(cs
, HFCSX_B2_SSL
, 0x81); /* tx slot */
1075 Write_hfc(cs
, HFCSX_B2_RSL
, 0x81); /* rx slot */
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
);
1084 if (cs
->debug
& L1_DEB_WARN
)
1085 debugl1(cs
, "hfcsx_l1hw loop invalid %4x", (int) arg
);
1090 cs
->hw
.hfcsx
.trm
|= 0x80; /* enable IOM-loop */
1091 Write_hfc(cs
, HFCSX_TRM
, cs
->hw
.hfcsx
.trm
);
1092 restore_flags(flags
);
1095 if (cs
->debug
& L1_DEB_WARN
)
1096 debugl1(cs
, "hfcsx_l1hw unknown pr %4x", pr
);
1101 /***********************************************/
1102 /* called during init setting l1 stack pointer */
1103 /***********************************************/
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 /**************************************/
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
);
1122 debugl1(cs
, "send_data %d blocked", bcs
->channel
);
1125 /***************************************************************/
1126 /* activate/deactivate hardware for selected channels and mode */
1127 /***************************************************************/
1129 mode_hfcsx(struct BCState
*bcs
, int mode
, int bc
)
1131 struct IsdnCardState
*cs
= bcs
->cs
;
1134 if (cs
->debug
& L1_DEB_HSCX
)
1135 debugl1(cs
, "HFCSX bchannel mode %d bchan %d/%d",
1136 mode
, bc
, bcs
->channel
);
1142 if (cs
->chanlimit
> 1) {
1143 cs
->hw
.hfcsx
.bswapped
= 0; /* B1 and B2 normal mode */
1144 cs
->hw
.hfcsx
.sctrl_e
&= ~0x80;
1147 if (mode
!= L1_MODE_NULL
) {
1148 cs
->hw
.hfcsx
.bswapped
= 1; /* B1 and B2 exchanged */
1149 cs
->hw
.hfcsx
.sctrl_e
|= 0x80;
1151 cs
->hw
.hfcsx
.bswapped
= 0; /* B1 and B2 normal mode */
1152 cs
->hw
.hfcsx
.sctrl_e
&= ~0x80;
1156 cs
->hw
.hfcsx
.bswapped
= 0; /* B1 and B2 normal mode */
1157 cs
->hw
.hfcsx
.sctrl_e
&= ~0x80;
1161 case (L1_MODE_NULL
):
1163 cs
->hw
.hfcsx
.sctrl
&= ~SCTRL_B2_ENA
;
1164 cs
->hw
.hfcsx
.sctrl_r
&= ~SCTRL_B2_ENA
;
1166 cs
->hw
.hfcsx
.sctrl
&= ~SCTRL_B1_ENA
;
1167 cs
->hw
.hfcsx
.sctrl_r
&= ~SCTRL_B1_ENA
;
1170 cs
->hw
.hfcsx
.int_m1
&= ~(HFCSX_INTS_B2TRANS
+ HFCSX_INTS_B2REC
);
1172 cs
->hw
.hfcsx
.int_m1
&= ~(HFCSX_INTS_B1TRANS
+ HFCSX_INTS_B1REC
);
1175 case (L1_MODE_TRANS
):
1177 cs
->hw
.hfcsx
.sctrl
|= SCTRL_B2_ENA
;
1178 cs
->hw
.hfcsx
.sctrl_r
|= SCTRL_B2_ENA
;
1180 cs
->hw
.hfcsx
.sctrl
|= SCTRL_B1_ENA
;
1181 cs
->hw
.hfcsx
.sctrl_r
|= SCTRL_B1_ENA
;
1184 cs
->hw
.hfcsx
.int_m1
|= (HFCSX_INTS_B2TRANS
+ HFCSX_INTS_B2REC
);
1185 cs
->hw
.hfcsx
.ctmt
|= 2;
1186 cs
->hw
.hfcsx
.conn
&= ~0x18;
1188 cs
->hw
.hfcsx
.int_m1
|= (HFCSX_INTS_B1TRANS
+ HFCSX_INTS_B1REC
);
1189 cs
->hw
.hfcsx
.ctmt
|= 1;
1190 cs
->hw
.hfcsx
.conn
&= ~0x03;
1193 case (L1_MODE_HDLC
):
1195 cs
->hw
.hfcsx
.sctrl
|= SCTRL_B2_ENA
;
1196 cs
->hw
.hfcsx
.sctrl_r
|= SCTRL_B2_ENA
;
1198 cs
->hw
.hfcsx
.sctrl
|= SCTRL_B1_ENA
;
1199 cs
->hw
.hfcsx
.sctrl_r
|= SCTRL_B1_ENA
;
1202 cs
->hw
.hfcsx
.int_m1
|= (HFCSX_INTS_B2TRANS
+ HFCSX_INTS_B2REC
);
1203 cs
->hw
.hfcsx
.ctmt
&= ~2;
1204 cs
->hw
.hfcsx
.conn
&= ~0x18;
1206 cs
->hw
.hfcsx
.int_m1
|= (HFCSX_INTS_B1TRANS
+ HFCSX_INTS_B1REC
);
1207 cs
->hw
.hfcsx
.ctmt
&= ~1;
1208 cs
->hw
.hfcsx
.conn
&= ~0x03;
1211 case (L1_MODE_EXTRN
):
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
);
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
);
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 /******************************/
1242 hfcsx_l2l1(struct PStack
*st
, int pr
, void *arg
)
1244 struct sk_buff
*skb
= arg
;
1248 case (PH_DATA
| REQUEST
):
1251 if (st
->l1
.bcs
->tx_skb
) {
1252 skb_queue_tail(&st
->l1
.bcs
->squeue
, skb
);
1253 restore_flags(flags
);
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
);
1261 case (PH_PULL
| INDICATION
):
1262 if (st
->l1
.bcs
->tx_skb
) {
1263 printk(KERN_WARNING
"hfc_l2l1: this shouldn't happen\n");
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
);
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
);
1278 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
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
);
1285 case (PH_DEACTIVATE
| REQUEST
):
1286 l1_msg_b(st
, pr
, arg
);
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
);
1297 /******************************************/
1298 /* deactivate B-channel access and queues */
1299 /******************************************/
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
);
1308 dev_kfree_skb(bcs
->tx_skb
);
1310 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
1315 /*************************************/
1316 /* init B-channel queues and control */
1317 /*************************************/
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
);
1326 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
1332 /*********************************/
1333 /* inits the stack for B-channel */
1334 /*********************************/
1336 setstack_2b(struct PStack
*st
, struct BCState
*bcs
)
1338 bcs
->channel
= st
->l1
.bc
;
1339 if (open_hfcsxstate(st
->l1
.hardware
, bcs
))
1342 st
->l2
.l2l1
= hfcsx_l2l1
;
1343 setstack_manager(st
);
1349 /***************************/
1350 /* handle L1 state changes */
1351 /***************************/
1353 hfcsx_bh(struct IsdnCardState
*cs
)
1356 /* struct PStack *stptr;
1360 if (test_and_clear_bit(D_L1STATECHANGE
, &cs
->event
)) {
1361 if (!cs
->hw
.hfcsx
.nt_mode
)
1362 switch (cs
->dc
.hfcsx
.ph_state
) {
1364 l1_msg(cs
, HW_RESET
| INDICATION
, NULL
);
1367 l1_msg(cs
, HW_DEACTIVATE
| INDICATION
, NULL
);
1370 l1_msg(cs
, HW_RSYNC
| INDICATION
, NULL
);
1373 l1_msg(cs
, HW_INFO2
| INDICATION
, NULL
);
1376 l1_msg(cs
, HW_INFO4_P8
| INDICATION
, NULL
);
1381 switch (cs
->dc
.hfcsx
.ph_state
) {
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
);
1394 Write_hfc(cs
, HFCSX_STATES
, 4);
1395 cs
->dc
.hfcsx
.ph_state
= 4;
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
);
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
);
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 /********************************/
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 /*******************************************/
1456 hfcsx_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
1460 if (cs
->debug
& L1_DEB_ISAC
)
1461 debugl1(cs
, "HFCSX: card_msg %x", mt
);
1467 release_io_hfcsx(cs
);
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
);
1491 setup_hfcsx(struct IsdnCard
*card
))
1493 struct IsdnCardState
*cs
= card
->cs
;
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)) {
1508 "HiSax: HFC-SX io-base 0x%x already in use\n",
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);
1518 cs
->hw
.hfcsx
.chip
= Read_hfc(cs
,HFCSX_CHIP_ID
);
1519 switch (cs
->hw
.hfcsx
.chip
>> 4) {
1528 "HFC-SX: invalid chip id 0x%x\n",
1529 cs
->hw
.hfcsx
.chip
>> 4);
1530 release_region(cs
->hw
.hfcsx
.base
, 2);
1533 if (!ccd_sp_irqtab
[cs
->irq
& 0xF]) {
1535 "HFC_SX: invalid irq %d specified\n",cs
->irq
& 0xF);
1536 release_region(cs
->hw
.hfcsx
.base
, 2);
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");
1548 restore_flags(flags
);
1551 "HFC-S%c chip detected at base 0x%x IRQ %d HZ %d\n",
1552 tmp
[0], (u_int
) cs
->hw
.hfcsx
.base
,
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
);
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
);
1576 cs
->cardmsg
= &hfcsx_card_msg
;
1577 cs
->auxcmd
= &hfcsx_auxcmd
;