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>
20 static char *HSCXVer
[] =
21 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
22 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
25 HscxVersion(struct IsdnCardState
*cs
, char *s
)
29 verA
= cs
->BC_Read_Reg(cs
, 0, HSCX_VSTR
) & 0xf;
30 verB
= cs
->BC_Read_Reg(cs
, 1, HSCX_VSTR
) & 0xf;
31 printk(KERN_INFO
"%s HSCX version A: %s B: %s\n", s
,
32 HSCXVer
[verA
], HSCXVer
[verB
]);
33 if ((verA
== 0) | (verA
== 0xf) | (verB
== 0) | (verB
== 0xf))
40 modehscx(struct BCState
*bcs
, int mode
, int bc
)
42 struct IsdnCardState
*cs
= bcs
->cs
;
43 int hscx
= bcs
->hw
.hscx
.hscx
;
45 if (cs
->debug
& L1_DEB_HSCX
)
46 debugl1(cs
, "hscx %c mode %d ichan %d",
47 'A' + hscx
, mode
, bc
);
50 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XAD1
, 0xFF);
51 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XAD2
, 0xFF);
52 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RAH2
, 0xFF);
53 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XBCH
, 0x0);
54 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RLCR
, 0x0);
55 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR1
,
56 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x82 : 0x85);
57 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR2
, 0x30);
58 cs
->BC_Write_Reg(cs
, hscx
, HSCX_XCCR
, 7);
59 cs
->BC_Write_Reg(cs
, hscx
, HSCX_RCCR
, 7);
61 /* Switch IOM 1 SSI */
62 if (test_bit(HW_IOM1
, &cs
->HW_Flags
) && (hscx
== 0))
66 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
,
67 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : bcs
->hw
.hscx
.tsaxr0
);
68 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
,
69 test_bit(HW_IOM1
, &cs
->HW_Flags
) ? 0x7 : bcs
->hw
.hscx
.tsaxr0
);
71 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
, bcs
->hw
.hscx
.tsaxr1
);
72 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
, bcs
->hw
.hscx
.tsaxr1
);
76 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAX
, 0x1f);
77 cs
->BC_Write_Reg(cs
, hscx
, HSCX_TSAR
, 0x1f);
78 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0x84);
81 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0xe4);
84 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CCR1
,
85 test_bit(HW_IPAC
, &cs
->HW_Flags
) ? 0x8a : 0x8d);
86 cs
->BC_Write_Reg(cs
, hscx
, HSCX_MODE
, 0x8c);
90 cs
->BC_Write_Reg(cs
, hscx
, HSCX_CMDR
, 0x41);
91 cs
->BC_Write_Reg(cs
, hscx
, HSCX_ISTA
, 0x00);
95 hscx_l2l1(struct PStack
*st
, int pr
, void *arg
)
97 struct BCState
*bcs
= st
->l1
.bcs
;
99 struct sk_buff
*skb
= arg
;
102 case (PH_DATA
| REQUEST
):
103 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
105 skb_queue_tail(&bcs
->squeue
, skb
);
108 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
109 bcs
->hw
.hscx
.count
= 0;
110 bcs
->cs
->BC_Send_Data(bcs
);
112 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
114 case (PH_PULL
| INDICATION
):
115 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
117 printk(KERN_WARNING
"hscx_l2l1: this shouldn't happen\n");
119 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
121 bcs
->hw
.hscx
.count
= 0;
122 bcs
->cs
->BC_Send_Data(bcs
);
124 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
126 case (PH_PULL
| REQUEST
):
128 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
129 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
131 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
133 case (PH_ACTIVATE
| REQUEST
):
134 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
135 test_and_set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
136 modehscx(bcs
, st
->l1
.mode
, st
->l1
.bc
);
137 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
138 l1_msg_b(st
, pr
, arg
);
140 case (PH_DEACTIVATE
| REQUEST
):
141 l1_msg_b(st
, pr
, arg
);
143 case (PH_DEACTIVATE
| CONFIRM
):
144 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
145 test_and_clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
146 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
147 modehscx(bcs
, 0, st
->l1
.bc
);
148 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
149 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
155 close_hscxstate(struct BCState
*bcs
)
157 modehscx(bcs
, 0, bcs
->channel
);
158 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
159 if (bcs
->hw
.hscx
.rcvbuf
) {
160 kfree(bcs
->hw
.hscx
.rcvbuf
);
161 bcs
->hw
.hscx
.rcvbuf
= NULL
;
167 skb_queue_purge(&bcs
->rqueue
);
168 skb_queue_purge(&bcs
->squeue
);
170 dev_kfree_skb_any(bcs
->tx_skb
);
172 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
178 open_hscxstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
180 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
181 if (!(bcs
->hw
.hscx
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
183 "HiSax: No memory for hscx.rcvbuf\n");
184 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
187 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
189 "HiSax: No memory for bcs->blog\n");
190 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
191 kfree(bcs
->hw
.hscx
.rcvbuf
);
192 bcs
->hw
.hscx
.rcvbuf
= NULL
;
195 skb_queue_head_init(&bcs
->rqueue
);
196 skb_queue_head_init(&bcs
->squeue
);
199 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
201 bcs
->hw
.hscx
.rcvidx
= 0;
207 setstack_hscx(struct PStack
*st
, struct BCState
*bcs
)
209 bcs
->channel
= st
->l1
.bc
;
210 if (open_hscxstate(st
->l1
.hardware
, bcs
))
213 st
->l2
.l2l1
= hscx_l2l1
;
214 setstack_manager(st
);
221 clear_pending_hscx_ints(struct IsdnCardState
*cs
)
225 val
= cs
->BC_Read_Reg(cs
, 1, HSCX_ISTA
);
226 debugl1(cs
, "HSCX B ISTA %x", val
);
228 eval
= cs
->BC_Read_Reg(cs
, 1, HSCX_EXIR
);
229 debugl1(cs
, "HSCX B EXIR %x", eval
);
232 eval
= cs
->BC_Read_Reg(cs
, 0, HSCX_EXIR
);
233 debugl1(cs
, "HSCX A EXIR %x", eval
);
235 val
= cs
->BC_Read_Reg(cs
, 0, HSCX_ISTA
);
236 debugl1(cs
, "HSCX A ISTA %x", val
);
237 val
= cs
->BC_Read_Reg(cs
, 1, HSCX_STAR
);
238 debugl1(cs
, "HSCX B STAR %x", val
);
239 val
= cs
->BC_Read_Reg(cs
, 0, HSCX_STAR
);
240 debugl1(cs
, "HSCX A STAR %x", val
);
241 /* disable all IRQ */
242 cs
->BC_Write_Reg(cs
, 0, HSCX_MASK
, 0xFF);
243 cs
->BC_Write_Reg(cs
, 1, HSCX_MASK
, 0xFF);
247 inithscx(struct IsdnCardState
*cs
)
249 cs
->bcs
[0].BC_SetStack
= setstack_hscx
;
250 cs
->bcs
[1].BC_SetStack
= setstack_hscx
;
251 cs
->bcs
[0].BC_Close
= close_hscxstate
;
252 cs
->bcs
[1].BC_Close
= close_hscxstate
;
253 cs
->bcs
[0].hw
.hscx
.hscx
= 0;
254 cs
->bcs
[1].hw
.hscx
.hscx
= 1;
255 cs
->bcs
[0].hw
.hscx
.tsaxr0
= 0x2f;
256 cs
->bcs
[0].hw
.hscx
.tsaxr1
= 3;
257 cs
->bcs
[1].hw
.hscx
.tsaxr0
= 0x2f;
258 cs
->bcs
[1].hw
.hscx
.tsaxr1
= 3;
259 modehscx(cs
->bcs
, 0, 0);
260 modehscx(cs
->bcs
+ 1, 0, 0);
264 inithscxisac(struct IsdnCardState
*cs
, int part
)
267 clear_pending_isac_ints(cs
);
268 clear_pending_hscx_ints(cs
);
273 /* Reenable all IRQ */
274 cs
->writeisac(cs
, ISAC_MASK
, 0);
275 cs
->BC_Write_Reg(cs
, 0, HSCX_MASK
, 0);
276 cs
->BC_Write_Reg(cs
, 1, HSCX_MASK
, 0);
277 /* RESET Receiver and Transmitter */
278 cs
->writeisac(cs
, ISAC_CMDR
, 0x41);