1 /* $Id: hscx.c,v 1.21 2000/11/24 17:05:37 kai Exp $
3 * hscx.c HSCX specific routines
5 * Author Karsten Keil (keil@isdn4linux.de)
7 * This file is (c) under GNU PUBLIC LICENSE
11 #define __NO_VERSION__
12 #include <linux/init.h>
17 #include <linux/interrupt.h>
19 static char *HSCXVer
[] __initdata
=
20 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
21 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
24 HscxVersion(struct IsdnCardState
*cs
, char *s
)
28 verA
= cs
->BC_Read_Reg(cs
, 0, HSCX_VSTR
) & 0xf;
29 verB
= cs
->BC_Read_Reg(cs
, 1, HSCX_VSTR
) & 0xf;
30 printk(KERN_INFO
"%s HSCX version A: %s B: %s\n", s
,
31 HSCXVer
[verA
], HSCXVer
[verB
]);
32 if ((verA
== 0) | (verA
== 0xf) | (verB
== 0) | (verB
== 0xf))
39 modehscx(struct BCState
*bcs
, int mode
, int bc
)
41 struct IsdnCardState
*cs
= bcs
->cs
;
42 int hscx
= bcs
->hw
.hscx
.hscx
;
44 if (cs
->debug
& L1_DEB_HSCX
)
45 debugl1(cs
, "hscx %c mode %d ichan %d",
46 'A' + hscx
, mode
, bc
);
49 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XAD1
, 0xFF);
50 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XAD2
, 0xFF);
51 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RAH2
, 0xFF);
52 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XBCH
, 0x0);
53 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RLCR
, 0x0);
54 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR1
,
55 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x82 : 0x85);
56 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR2
, 0x30);
57 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XCCR
, 7);
58 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RCCR
, 7);
60 /* Switch IOM 1 SSI */
61 if (test_bit(HW_IOM1
, &cs
->HW_Flags
) && (hscx
== 0))
65 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
,
66 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : bcs
->hw
.hscx
.tsaxr0
);
67 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
,
68 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : bcs
->hw
.hscx
.tsaxr0
);
70 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
, bcs
->hw
.hscx
.tsaxr1
);
71 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
, bcs
->hw
.hscx
.tsaxr1
);
75 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
, 0x1f);
76 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
, 0x1f);
77 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0x84);
80 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0xe4);
83 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR1
,
84 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x8a : 0x8d);
85 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0x8c);
89 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CMDR
, 0x41);
90 cs
->BC_Write_Reg(cs
, hscx
, HSCX_ISTA
, 0x00);
94 hscx_sched_event(struct BCState
*bcs
, int event
)
96 bcs
->event
|= 1 << event
;
97 queue_task(&bcs
->tqueue
, &tq_immediate
);
98 mark_bh(IMMEDIATE_BH
);
102 hscx_l2l1(struct PStack
*st
, int pr
, void *arg
)
104 struct sk_buff
*skb
= arg
;
108 case (PH_DATA
| REQUEST
):
111 if (st
->l1
.bcs
->tx_skb
) {
112 skb_queue_tail(&st
->l1
.bcs
->squeue
, skb
);
113 restore_flags(flags
);
115 st
->l1
.bcs
->tx_skb
= skb
;
116 test_and_set_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
117 st
->l1
.bcs
->hw
.hscx
.count
= 0;
118 restore_flags(flags
);
119 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
122 case (PH_PULL
| INDICATION
):
123 if (st
->l1
.bcs
->tx_skb
) {
124 printk(KERN_WARNING
"hscx_l2l1: this shouldn't happen\n");
127 test_and_set_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
128 st
->l1
.bcs
->tx_skb
= skb
;
129 st
->l1
.bcs
->hw
.hscx
.count
= 0;
130 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
132 case (PH_PULL
| REQUEST
):
133 if (!st
->l1
.bcs
->tx_skb
) {
134 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
135 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
137 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
139 case (PH_ACTIVATE
| REQUEST
):
140 test_and_set_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
141 modehscx(st
->l1
.bcs
, st
->l1
.mode
, st
->l1
.bc
);
142 l1_msg_b(st
, pr
, arg
);
144 case (PH_DEACTIVATE
| REQUEST
):
145 l1_msg_b(st
, pr
, arg
);
147 case (PH_DEACTIVATE
| CONFIRM
):
148 test_and_clear_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
149 test_and_clear_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
150 modehscx(st
->l1
.bcs
, 0, st
->l1
.bc
);
151 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
157 close_hscxstate(struct BCState
*bcs
)
159 modehscx(bcs
, 0, bcs
->channel
);
160 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
161 if (bcs
->hw
.hscx
.rcvbuf
) {
162 kfree(bcs
->hw
.hscx
.rcvbuf
);
163 bcs
->hw
.hscx
.rcvbuf
= NULL
;
169 discard_queue(&bcs
->rqueue
);
170 discard_queue(&bcs
->squeue
);
172 dev_kfree_skb_any(bcs
->tx_skb
);
174 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
180 open_hscxstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
182 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
183 if (!(bcs
->hw
.hscx
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
185 "HiSax: No memory for hscx.rcvbuf\n");
186 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
189 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
191 "HiSax: No memory for bcs->blog\n");
192 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
193 kfree(bcs
->hw
.hscx
.rcvbuf
);
194 bcs
->hw
.hscx
.rcvbuf
= NULL
;
197 skb_queue_head_init(&bcs
->rqueue
);
198 skb_queue_head_init(&bcs
->squeue
);
201 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
203 bcs
->hw
.hscx
.rcvidx
= 0;
209 setstack_hscx(struct PStack
*st
, struct BCState
*bcs
)
211 bcs
->channel
= st
->l1
.bc
;
212 if (open_hscxstate(st
->l1
.hardware
, bcs
))
215 st
->l2
.l2l1
= hscx_l2l1
;
216 setstack_manager(st
);
223 clear_pending_hscx_ints(struct IsdnCardState
*cs
)
227 val
= cs
->BC_Read_Reg(cs
, 1, HSCX_ISTA
);
228 debugl1(cs
, "HSCX B ISTA %x", val
);
230 eval
= cs
->BC_Read_Reg(cs
, 1, HSCX_EXIR
);
231 debugl1(cs
, "HSCX B EXIR %x", eval
);
234 eval
= cs
->BC_Read_Reg(cs
, 0, HSCX_EXIR
);
235 debugl1(cs
, "HSCX A EXIR %x", eval
);
237 val
= cs
->BC_Read_Reg(cs
, 0, HSCX_ISTA
);
238 debugl1(cs
, "HSCX A ISTA %x", val
);
239 val
= cs
->BC_Read_Reg(cs
, 1, HSCX_STAR
);
240 debugl1(cs
, "HSCX B STAR %x", val
);
241 val
= cs
->BC_Read_Reg(cs
, 0, HSCX_STAR
);
242 debugl1(cs
, "HSCX A STAR %x", val
);
243 /* disable all IRQ */
244 cs
->BC_Write_Reg(cs
, 0, HSCX_MASK
, 0xFF);
245 cs
->BC_Write_Reg(cs
, 1, HSCX_MASK
, 0xFF);
249 inithscx(struct IsdnCardState
*cs
)
251 cs
->bcs
[0].BC_SetStack
= setstack_hscx
;
252 cs
->bcs
[1].BC_SetStack
= setstack_hscx
;
253 cs
->bcs
[0].BC_Close
= close_hscxstate
;
254 cs
->bcs
[1].BC_Close
= close_hscxstate
;
255 cs
->bcs
[0].hw
.hscx
.hscx
= 0;
256 cs
->bcs
[1].hw
.hscx
.hscx
= 1;
257 cs
->bcs
[0].hw
.hscx
.tsaxr0
= 0x2f;
258 cs
->bcs
[0].hw
.hscx
.tsaxr1
= 3;
259 cs
->bcs
[1].hw
.hscx
.tsaxr0
= 0x2f;
260 cs
->bcs
[1].hw
.hscx
.tsaxr1
= 3;
261 modehscx(cs
->bcs
, 0, 0);
262 modehscx(cs
->bcs
+ 1, 0, 0);
266 inithscxisac(struct IsdnCardState
*cs
, int part
)
269 clear_pending_isac_ints(cs
);
270 clear_pending_hscx_ints(cs
);
275 /* Reenable all IRQ */
276 cs
->writeisac(cs
, ISAC_MASK
, 0);
277 cs
->BC_Write_Reg(cs
, 0, HSCX_MASK
, 0);
278 cs
->BC_Write_Reg(cs
, 1, HSCX_MASK
, 0);
279 /* RESET Receiver and Transmitter */
280 cs
->writeisac(cs
, ISAC_CMDR
, 0x41);