1 /* $Id: hscx.c,v 1.16 1998/11/15 23:54:48 keil Exp $
3 * hscx.c HSCX specific routines
5 * Author Karsten Keil (keil@isdn4linux.de)
9 * Revision 1.16 1998/11/15 23:54:48 keil
12 * Revision 1.15 1998/08/20 13:50:42 keil
13 * More support for hybrid modem (not working yet)
15 * Revision 1.14 1998/08/13 23:36:33 keil
16 * HiSax 3.1 - don't work stable with current LinkLevel
18 * Revision 1.13 1998/06/26 22:03:28 keil
19 * send flags between hdlc frames
21 * Revision 1.12 1998/06/09 18:26:01 keil
22 * PH_DEACTIVATE B-channel every time signaled to higher layer
24 * Revision 1.11 1998/05/25 14:10:07 keil
26 * X.75 and leased are working again.
28 * Revision 1.10 1998/05/25 12:57:59 keil
29 * HiSax golden code from certification, Don't use !!!
30 * No leased lines, no X75, but many changes.
32 * Revision 1.9 1998/04/15 16:45:33 keil
35 * Revision 1.8 1998/03/19 13:16:24 keil
36 * fix the correct release of the hscx
38 * Revision 1.7 1998/02/12 23:07:36 keil
39 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
41 * Revision 1.6 1998/02/02 13:41:12 keil
44 * Revision 1.5 1997/11/06 17:09:34 keil
47 * Revision 1.4 1997/10/29 19:01:06 keil
50 * Revision 1.3 1997/07/27 21:38:34 keil
51 * new B-channel interface
53 * Revision 1.2 1997/06/26 11:16:17 keil
59 #define __NO_VERSION__
64 #include <linux/interrupt.h>
66 static char *HSCXVer
[] HISAX_INITDATA
=
67 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
68 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
71 HscxVersion(struct IsdnCardState
*cs
, char *s
))
75 verA
= cs
->BC_Read_Reg(cs
, 0, HSCX_VSTR
) & 0xf;
76 verB
= cs
->BC_Read_Reg(cs
, 1, HSCX_VSTR
) & 0xf;
77 printk(KERN_INFO
"%s HSCX version A: %s B: %s\n", s
,
78 HSCXVer
[verA
], HSCXVer
[verB
]);
79 if ((verA
== 0) | (verA
== 0xf) | (verB
== 0) | (verB
== 0xf))
86 modehscx(struct BCState
*bcs
, int mode
, int bc
)
88 struct IsdnCardState
*cs
= bcs
->cs
;
89 int hscx
= bcs
->hw
.hscx
.hscx
;
91 if (cs
->debug
& L1_DEB_HSCX
)
92 debugl1(cs
, "hscx %c mode %d ichan %d",
93 'A' + hscx
, mode
, bc
);
96 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XAD1
, 0xFF);
97 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XAD2
, 0xFF);
98 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RAH2
, 0xFF);
99 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XBCH
, 0x0);
100 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RLCR
, 0x0);
101 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR1
,
102 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x82 : 0x85);
103 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR2
, 0x30);
104 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XCCR
, 7);
105 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RCCR
, 7);
107 /* Switch IOM 1 SSI */
108 if (test_bit(HW_IOM1
, &cs
->HW_Flags
) && (hscx
== 0))
112 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
,
113 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : 0x2f);
114 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
,
115 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : 0x2f);
117 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
, 0x3);
118 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
, 0x3);
122 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
, 0x1f);
123 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
, 0x1f);
124 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0x84);
126 case (L1_MODE_TRANS
):
127 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0xe4);
130 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR1
,
131 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x8a : 0x8d);
132 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0x8c);
136 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CMDR
, 0x41);
137 cs
->BC_Write_Reg(cs
, hscx
, HSCX_ISTA
, 0x00);
141 hscx_sched_event(struct BCState
*bcs
, int event
)
143 bcs
->event
|= 1 << event
;
144 queue_task(&bcs
->tqueue
, &tq_immediate
);
145 mark_bh(IMMEDIATE_BH
);
149 hscx_l2l1(struct PStack
*st
, int pr
, void *arg
)
151 struct sk_buff
*skb
= arg
;
155 case (PH_DATA
| REQUEST
):
158 if (st
->l1
.bcs
->tx_skb
) {
159 skb_queue_tail(&st
->l1
.bcs
->squeue
, skb
);
160 restore_flags(flags
);
162 st
->l1
.bcs
->tx_skb
= skb
;
163 test_and_set_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
164 st
->l1
.bcs
->hw
.hscx
.count
= 0;
165 restore_flags(flags
);
166 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
169 case (PH_PULL
| INDICATION
):
170 if (st
->l1
.bcs
->tx_skb
) {
171 printk(KERN_WARNING
"hscx_l2l1: this shouldn't happen\n");
174 test_and_set_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
175 st
->l1
.bcs
->tx_skb
= skb
;
176 st
->l1
.bcs
->hw
.hscx
.count
= 0;
177 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
179 case (PH_PULL
| REQUEST
):
180 if (!st
->l1
.bcs
->tx_skb
) {
181 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
182 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
184 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
186 case (PH_ACTIVATE
| REQUEST
):
187 test_and_set_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
188 modehscx(st
->l1
.bcs
, st
->l1
.mode
, st
->l1
.bc
);
189 l1_msg_b(st
, pr
, arg
);
191 case (PH_DEACTIVATE
| REQUEST
):
192 l1_msg_b(st
, pr
, arg
);
194 case (PH_DEACTIVATE
| CONFIRM
):
195 test_and_clear_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
196 test_and_clear_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
197 modehscx(st
->l1
.bcs
, 0, st
->l1
.bc
);
198 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
204 close_hscxstate(struct BCState
*bcs
)
206 modehscx(bcs
, 0, bcs
->channel
);
207 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
208 if (bcs
->hw
.hscx
.rcvbuf
) {
209 kfree(bcs
->hw
.hscx
.rcvbuf
);
210 bcs
->hw
.hscx
.rcvbuf
= NULL
;
216 discard_queue(&bcs
->rqueue
);
217 discard_queue(&bcs
->squeue
);
219 dev_kfree_skb(bcs
->tx_skb
);
221 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
227 open_hscxstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
229 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
230 if (!(bcs
->hw
.hscx
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
232 "HiSax: No memory for hscx.rcvbuf\n");
233 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
236 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
238 "HiSax: No memory for bcs->blog\n");
239 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
240 kfree(bcs
->hw
.hscx
.rcvbuf
);
241 bcs
->hw
.hscx
.rcvbuf
= NULL
;
244 skb_queue_head_init(&bcs
->rqueue
);
245 skb_queue_head_init(&bcs
->squeue
);
248 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
250 bcs
->hw
.hscx
.rcvidx
= 0;
256 setstack_hscx(struct PStack
*st
, struct BCState
*bcs
)
258 bcs
->channel
= st
->l1
.bc
;
259 if (open_hscxstate(st
->l1
.hardware
, bcs
))
262 st
->l2
.l2l1
= hscx_l2l1
;
263 setstack_manager(st
);
270 clear_pending_hscx_ints(struct IsdnCardState
*cs
))
274 val
= cs
->BC_Read_Reg(cs
, 1, HSCX_ISTA
);
275 debugl1(cs
, "HSCX B ISTA %x", val
);
277 eval
= cs
->BC_Read_Reg(cs
, 1, HSCX_EXIR
);
278 debugl1(cs
, "HSCX B EXIR %x", eval
);
281 eval
= cs
->BC_Read_Reg(cs
, 0, HSCX_EXIR
);
282 debugl1(cs
, "HSCX A EXIR %x", eval
);
284 val
= cs
->BC_Read_Reg(cs
, 0, HSCX_ISTA
);
285 debugl1(cs
, "HSCX A ISTA %x", val
);
286 val
= cs
->BC_Read_Reg(cs
, 1, HSCX_STAR
);
287 debugl1(cs
, "HSCX B STAR %x", val
);
288 val
= cs
->BC_Read_Reg(cs
, 0, HSCX_STAR
);
289 debugl1(cs
, "HSCX A STAR %x", val
);
290 /* disable all IRQ */
291 cs
->BC_Write_Reg(cs
, 0, HSCX_MASK
, 0xFF);
292 cs
->BC_Write_Reg(cs
, 1, HSCX_MASK
, 0xFF);
296 inithscx(struct IsdnCardState
*cs
))
298 cs
->bcs
[0].BC_SetStack
= setstack_hscx
;
299 cs
->bcs
[1].BC_SetStack
= setstack_hscx
;
300 cs
->bcs
[0].BC_Close
= close_hscxstate
;
301 cs
->bcs
[1].BC_Close
= close_hscxstate
;
302 cs
->bcs
[0].hw
.hscx
.hscx
= 0;
303 cs
->bcs
[1].hw
.hscx
.hscx
= 1;
304 modehscx(cs
->bcs
, 0, 0);
305 modehscx(cs
->bcs
+ 1, 0, 0);
309 inithscxisac(struct IsdnCardState
*cs
, int part
))
312 clear_pending_isac_ints(cs
);
313 clear_pending_hscx_ints(cs
);
318 /* Reenable all IRQ */
319 cs
->writeisac(cs
, ISAC_MASK
, 0);
320 cs
->BC_Write_Reg(cs
, 0, HSCX_MASK
, 0);
321 cs
->BC_Write_Reg(cs
, 1, HSCX_MASK
, 0);
322 /* RESET Receiver and Transmitter */
323 cs
->writeisac(cs
, ISAC_CMDR
, 0x41);