1 /* $Id: hscx.c,v 1.24.2.4 2004/01/24 20:47:23 keil Exp $
3 * HSCX specific routines
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
13 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/slab.h>
21 static char *HSCXVer
[] =
22 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
23 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
26 HscxVersion(struct IsdnCardState
*cs
, char *s
)
30 verA
= cs
->BC_Read_Reg(cs
, 0, HSCX_VSTR
) & 0xf;
31 verB
= cs
->BC_Read_Reg(cs
, 1, HSCX_VSTR
) & 0xf;
32 printk(KERN_INFO
"%s HSCX version A: %s B: %s\n", s
,
33 HSCXVer
[verA
], HSCXVer
[verB
]);
34 if ((verA
== 0) | (verA
== 0xf) | (verB
== 0) | (verB
== 0xf))
41 modehscx(struct BCState
*bcs
, int mode
, int bc
)
43 struct IsdnCardState
*cs
= bcs
->cs
;
44 int hscx
= bcs
->hw
.hscx
.hscx
;
46 if (cs
->debug
& L1_DEB_HSCX
)
47 debugl1(cs
, "hscx %c mode %d ichan %d",
48 'A' + hscx
, mode
, bc
);
51 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XAD1
, 0xFF);
52 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XAD2
, 0xFF);
53 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RAH2
, 0xFF);
54 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XBCH
, 0x0);
55 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RLCR
, 0x0);
56 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR1
,
57 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x82 : 0x85);
58 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR2
, 0x30);
59 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XCCR
, 7);
60 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RCCR
, 7);
62 /* Switch IOM 1 SSI */
63 if (test_bit(HW_IOM1
, &cs
->HW_Flags
) && (hscx
== 0))
67 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
,
68 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : bcs
->hw
.hscx
.tsaxr0
);
69 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
,
70 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : bcs
->hw
.hscx
.tsaxr0
);
72 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
, bcs
->hw
.hscx
.tsaxr1
);
73 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
, bcs
->hw
.hscx
.tsaxr1
);
77 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
, 0x1f);
78 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
, 0x1f);
79 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0x84);
82 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0xe4);
85 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR1
,
86 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x8a : 0x8d);
87 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0x8c);
91 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CMDR
, 0x41);
92 cs
->BC_Write_Reg(cs
, hscx
, HSCX_ISTA
, 0x00);
96 hscx_l2l1(struct PStack
*st
, int pr
, void *arg
)
98 struct BCState
*bcs
= st
->l1
.bcs
;
100 struct sk_buff
*skb
= arg
;
103 case (PH_DATA
| REQUEST
):
104 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
106 skb_queue_tail(&bcs
->squeue
, skb
);
109 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
110 bcs
->hw
.hscx
.count
= 0;
111 bcs
->cs
->BC_Send_Data(bcs
);
113 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
115 case (PH_PULL
| INDICATION
):
116 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
118 printk(KERN_WARNING
"hscx_l2l1: this shouldn't happen\n");
120 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
122 bcs
->hw
.hscx
.count
= 0;
123 bcs
->cs
->BC_Send_Data(bcs
);
125 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
127 case (PH_PULL
| REQUEST
):
129 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
130 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
132 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
134 case (PH_ACTIVATE
| REQUEST
):
135 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
136 test_and_set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
137 modehscx(bcs
, st
->l1
.mode
, st
->l1
.bc
);
138 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
139 l1_msg_b(st
, pr
, arg
);
141 case (PH_DEACTIVATE
| REQUEST
):
142 l1_msg_b(st
, pr
, arg
);
144 case (PH_DEACTIVATE
| CONFIRM
):
145 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
146 test_and_clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
147 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
148 modehscx(bcs
, 0, st
->l1
.bc
);
149 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
150 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
156 close_hscxstate(struct BCState
*bcs
)
158 modehscx(bcs
, 0, bcs
->channel
);
159 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
160 kfree(bcs
->hw
.hscx
.rcvbuf
);
161 bcs
->hw
.hscx
.rcvbuf
= NULL
;
164 skb_queue_purge(&bcs
->rqueue
);
165 skb_queue_purge(&bcs
->squeue
);
167 dev_kfree_skb_any(bcs
->tx_skb
);
169 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
175 open_hscxstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
177 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
178 if (!(bcs
->hw
.hscx
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
180 "HiSax: No memory for hscx.rcvbuf\n");
181 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
184 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
186 "HiSax: No memory for bcs->blog\n");
187 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
188 kfree(bcs
->hw
.hscx
.rcvbuf
);
189 bcs
->hw
.hscx
.rcvbuf
= NULL
;
192 skb_queue_head_init(&bcs
->rqueue
);
193 skb_queue_head_init(&bcs
->squeue
);
196 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
198 bcs
->hw
.hscx
.rcvidx
= 0;
204 setstack_hscx(struct PStack
*st
, struct BCState
*bcs
)
206 bcs
->channel
= st
->l1
.bc
;
207 if (open_hscxstate(st
->l1
.hardware
, bcs
))
210 st
->l2
.l2l1
= hscx_l2l1
;
211 setstack_manager(st
);
218 clear_pending_hscx_ints(struct IsdnCardState
*cs
)
222 val
= cs
->BC_Read_Reg(cs
, 1, HSCX_ISTA
);
223 debugl1(cs
, "HSCX B ISTA %x", val
);
225 eval
= cs
->BC_Read_Reg(cs
, 1, HSCX_EXIR
);
226 debugl1(cs
, "HSCX B EXIR %x", eval
);
229 eval
= cs
->BC_Read_Reg(cs
, 0, HSCX_EXIR
);
230 debugl1(cs
, "HSCX A EXIR %x", eval
);
232 val
= cs
->BC_Read_Reg(cs
, 0, HSCX_ISTA
);
233 debugl1(cs
, "HSCX A ISTA %x", val
);
234 val
= cs
->BC_Read_Reg(cs
, 1, HSCX_STAR
);
235 debugl1(cs
, "HSCX B STAR %x", val
);
236 val
= cs
->BC_Read_Reg(cs
, 0, HSCX_STAR
);
237 debugl1(cs
, "HSCX A STAR %x", val
);
238 /* disable all IRQ */
239 cs
->BC_Write_Reg(cs
, 0, HSCX_MASK
, 0xFF);
240 cs
->BC_Write_Reg(cs
, 1, HSCX_MASK
, 0xFF);
244 inithscx(struct IsdnCardState
*cs
)
246 cs
->bcs
[0].BC_SetStack
= setstack_hscx
;
247 cs
->bcs
[1].BC_SetStack
= setstack_hscx
;
248 cs
->bcs
[0].BC_Close
= close_hscxstate
;
249 cs
->bcs
[1].BC_Close
= close_hscxstate
;
250 cs
->bcs
[0].hw
.hscx
.hscx
= 0;
251 cs
->bcs
[1].hw
.hscx
.hscx
= 1;
252 cs
->bcs
[0].hw
.hscx
.tsaxr0
= 0x2f;
253 cs
->bcs
[0].hw
.hscx
.tsaxr1
= 3;
254 cs
->bcs
[1].hw
.hscx
.tsaxr0
= 0x2f;
255 cs
->bcs
[1].hw
.hscx
.tsaxr1
= 3;
256 modehscx(cs
->bcs
, 0, 0);
257 modehscx(cs
->bcs
+ 1, 0, 0);
261 inithscxisac(struct IsdnCardState
*cs
, int part
)
264 clear_pending_isac_ints(cs
);
265 clear_pending_hscx_ints(cs
);
270 /* Reenable all IRQ */
271 cs
->writeisac(cs
, ISAC_MASK
, 0);
272 cs
->BC_Write_Reg(cs
, 0, HSCX_MASK
, 0);
273 cs
->BC_Write_Reg(cs
, 1, HSCX_MASK
, 0);
274 /* RESET Receiver and Transmitter */
275 cs
->writeisac(cs
, ISAC_CMDR
, 0x41);