1 /* $Id: jade.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
2  *
3  * JADE stuff (derived from original hscx.c)
4  *
5  * Author       Roland Klabunde
6  * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
7  *
8  * This software may be used and distributed according to the terms
9  * of the GNU General Public License, incorporated herein by reference.
10  *
11  */
12 
13 
14 #define __NO_VERSION__
15 #include <linux/init.h>
16 #include "hisax.h"
17 #include "hscx.h"
18 #include "jade.h"
19 #include "isdnl1.h"
20 #include <linux/interrupt.h>
21 
22 
23 int __init
JadeVersion(struct IsdnCardState * cs,char * s)24 JadeVersion(struct IsdnCardState *cs, char *s)
25 {
26     int ver,i;
27     int to = 50;
28     cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
29     i=0;
30     while (to) {
31     	udelay(1);
32 	ver = cs->BC_Read_Reg(cs, -1, 0x60);
33 	to--;
34 	if (ver)
35     	    break;
36 	if (!to) {
37 	    printk(KERN_INFO "%s JADE version not obtainable\n", s);
38     	    return (0);
39         }
40     }
41     /* Wait for the JADE */
42     udelay(10);
43     /* Read version */
44     ver = cs->BC_Read_Reg(cs, -1, 0x60);
45     printk(KERN_INFO "%s JADE version: %d\n", s, ver);
46     return (1);
47 }
48 
49 /* Write to indirect accessible jade register set */
50 static void
jade_write_indirect(struct IsdnCardState * cs,u_char reg,u_char value)51 jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value)
52 {
53     int to = 50;
54     long flags;
55     u_char ret;
56     save_flags(flags);
57     cli();
58     /* Write the data */
59     cs->BC_Write_Reg(cs, -1, COMM_JADE+1, value);
60     /* Say JADE we wanna write indirect reg 'reg' */
61     cs->BC_Write_Reg(cs, -1, COMM_JADE, reg);
62     to = 50;
63     /* Wait for RDY goes high */
64     while (to) {
65     	udelay(1);
66 	ret = cs->BC_Read_Reg(cs, -1, COMM_JADE);
67 	to--;
68 	if (ret & 1)
69 	    /* Got acknowledge */
70 	    break;
71 	if (!to) {
72 	    restore_flags(flags);
73     	    printk(KERN_INFO "Can not see ready bit from JADE DSP (reg=0x%X, value=0x%X)\n", reg, value);
74 	    return;
75 	}
76     }
77     restore_flags(flags);
78 }
79 
80 
81 
82 void
modejade(struct BCState * bcs,int mode,int bc)83 modejade(struct BCState *bcs, int mode, int bc)
84 {
85     struct IsdnCardState *cs = bcs->cs;
86     int jade = bcs->hw.hscx.hscx;
87 
88     if (cs->debug & L1_DEB_HSCX) {
89 	char tmp[40];
90 	sprintf(tmp, "jade %c mode %d ichan %d",
91 		'A' + jade, mode, bc);
92 	debugl1(cs, tmp);
93     }
94     bcs->mode = mode;
95     bcs->channel = bc;
96 
97     cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (mode == L1_MODE_TRANS ? jadeMODE_TMO:0x00));
98     cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR0, (jadeCCR0_PU|jadeCCR0_ITF));
99     cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR1, 0x00);
100 
101     jade_write_indirect(cs, jade_HDLC1SERRXPATH, 0x08);
102     jade_write_indirect(cs, jade_HDLC2SERRXPATH, 0x08);
103     jade_write_indirect(cs, jade_HDLC1SERTXPATH, 0x00);
104     jade_write_indirect(cs, jade_HDLC2SERTXPATH, 0x00);
105 
106     cs->BC_Write_Reg(cs, jade, jade_HDLC_XCCR, 0x07);
107     cs->BC_Write_Reg(cs, jade, jade_HDLC_RCCR, 0x07);
108 
109     if (bc == 0) {
110 	cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x00);
111 	cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x00);
112     } else {
113 	cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x04);
114 	cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x04);
115     }
116     switch (mode) {
117 	case (L1_MODE_NULL):
118 		cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, jadeMODE_TMO);
119 		break;
120 	case (L1_MODE_TRANS):
121 		cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_TMO|jadeMODE_RAC|jadeMODE_XAC));
122 		break;
123 	case (L1_MODE_HDLC):
124 		cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_RAC|jadeMODE_XAC));
125 		break;
126     }
127     if (mode) {
128 	cs->BC_Write_Reg(cs, jade, jade_HDLC_RCMD, (jadeRCMD_RRES|jadeRCMD_RMC));
129 	cs->BC_Write_Reg(cs, jade, jade_HDLC_XCMD, jadeXCMD_XRES);
130 	/* Unmask ints */
131 	cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0xF8);
132     }
133     else
134 	/* Mask ints */
135 	cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0x00);
136 }
137 
138 void
jade_sched_event(struct BCState * bcs,int event)139 jade_sched_event(struct BCState *bcs, int event)
140 {
141     bcs->event |= 1 << event;
142     queue_task(&bcs->tqueue, &tq_immediate);
143     mark_bh(IMMEDIATE_BH);
144 }
145 
146 static void
jade_l2l1(struct PStack * st,int pr,void * arg)147 jade_l2l1(struct PStack *st, int pr, void *arg)
148 {
149     struct sk_buff *skb = arg;
150     long flags;
151 
152     switch (pr) {
153 	case (PH_DATA | REQUEST):
154 		save_flags(flags);
155 		cli();
156 		if (st->l1.bcs->tx_skb) {
157 			skb_queue_tail(&st->l1.bcs->squeue, skb);
158 			restore_flags(flags);
159 		} else {
160 			st->l1.bcs->tx_skb = skb;
161 			test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
162 			st->l1.bcs->hw.hscx.count = 0;
163 			restore_flags(flags);
164 			st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
165 		}
166 		break;
167 	case (PH_PULL | INDICATION):
168 		if (st->l1.bcs->tx_skb) {
169 			printk(KERN_WARNING "jade_l2l1: this shouldn't happen\n");
170 			break;
171 		}
172 		test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
173 		st->l1.bcs->tx_skb = skb;
174 		st->l1.bcs->hw.hscx.count = 0;
175 		st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
176 		break;
177 	case (PH_PULL | REQUEST):
178 		if (!st->l1.bcs->tx_skb) {
179 		    test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
180 		    st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
181 		} else
182 		    test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
183 		break;
184 	case (PH_ACTIVATE | REQUEST):
185 		test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
186 		modejade(st->l1.bcs, st->l1.mode, st->l1.bc);
187 		l1_msg_b(st, pr, arg);
188 		break;
189 	case (PH_DEACTIVATE | REQUEST):
190 		l1_msg_b(st, pr, arg);
191 		break;
192 	case (PH_DEACTIVATE | CONFIRM):
193 		test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
194 		test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
195 		modejade(st->l1.bcs, 0, st->l1.bc);
196 		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
197 		break;
198     }
199 }
200 
201 void
close_jadestate(struct BCState * bcs)202 close_jadestate(struct BCState *bcs)
203 {
204     modejade(bcs, 0, bcs->channel);
205     if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
206 	if (bcs->hw.hscx.rcvbuf) {
207 		kfree(bcs->hw.hscx.rcvbuf);
208 		bcs->hw.hscx.rcvbuf = NULL;
209 	}
210 	if (bcs->blog) {
211 		kfree(bcs->blog);
212 		bcs->blog = NULL;
213 	}
214 	skb_queue_purge(&bcs->rqueue);
215 	skb_queue_purge(&bcs->squeue);
216 	if (bcs->tx_skb) {
217 		dev_kfree_skb_any(bcs->tx_skb);
218 		bcs->tx_skb = NULL;
219 		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
220 	}
221     }
222 }
223 
224 static int
open_jadestate(struct IsdnCardState * cs,struct BCState * bcs)225 open_jadestate(struct IsdnCardState *cs, struct BCState *bcs)
226 {
227 	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
228 		if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
229 			printk(KERN_WARNING
230 			       "HiSax: No memory for hscx.rcvbuf\n");
231 			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
232 			return (1);
233 		}
234 		if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
235 			printk(KERN_WARNING
236 				"HiSax: No memory for bcs->blog\n");
237 			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
238 			kfree(bcs->hw.hscx.rcvbuf);
239 			bcs->hw.hscx.rcvbuf = NULL;
240 			return (2);
241 		}
242 		skb_queue_head_init(&bcs->rqueue);
243 		skb_queue_head_init(&bcs->squeue);
244 	}
245 	bcs->tx_skb = NULL;
246 	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
247 	bcs->event = 0;
248 	bcs->hw.hscx.rcvidx = 0;
249 	bcs->tx_cnt = 0;
250 	return (0);
251 }
252 
253 
254 int
setstack_jade(struct PStack * st,struct BCState * bcs)255 setstack_jade(struct PStack *st, struct BCState *bcs)
256 {
257 	bcs->channel = st->l1.bc;
258 	if (open_jadestate(st->l1.hardware, bcs))
259 		return (-1);
260 	st->l1.bcs = bcs;
261 	st->l2.l2l1 = jade_l2l1;
262 	setstack_manager(st);
263 	bcs->st = st;
264 	setstack_l1_B(st);
265 	return (0);
266 }
267 
268 void __init
clear_pending_jade_ints(struct IsdnCardState * cs)269 clear_pending_jade_ints(struct IsdnCardState *cs)
270 {
271 	int val;
272 	char tmp[64];
273 
274 	cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00);
275 	cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00);
276 
277 	val = cs->BC_Read_Reg(cs, 1, jade_HDLC_ISR);
278 	sprintf(tmp, "jade B ISTA %x", val);
279 	debugl1(cs, tmp);
280 	val = cs->BC_Read_Reg(cs, 0, jade_HDLC_ISR);
281 	sprintf(tmp, "jade A ISTA %x", val);
282 	debugl1(cs, tmp);
283 	val = cs->BC_Read_Reg(cs, 1, jade_HDLC_STAR);
284 	sprintf(tmp, "jade B STAR %x", val);
285 	debugl1(cs, tmp);
286 	val = cs->BC_Read_Reg(cs, 0, jade_HDLC_STAR);
287 	sprintf(tmp, "jade A STAR %x", val);
288 	debugl1(cs, tmp);
289 	/* Unmask ints */
290 	cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0xF8);
291 	cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0xF8);
292 }
293 
294 void __init
initjade(struct IsdnCardState * cs)295 initjade(struct IsdnCardState *cs)
296 {
297 	cs->bcs[0].BC_SetStack = setstack_jade;
298 	cs->bcs[1].BC_SetStack = setstack_jade;
299 	cs->bcs[0].BC_Close = close_jadestate;
300 	cs->bcs[1].BC_Close = close_jadestate;
301 	cs->bcs[0].hw.hscx.hscx = 0;
302 	cs->bcs[1].hw.hscx.hscx = 1;
303 
304 	/* Stop DSP audio tx/rx */
305 	jade_write_indirect(cs, 0x11, 0x0f);
306 	jade_write_indirect(cs, 0x17, 0x2f);
307 
308 	/* Transparent Mode, RxTx inactive, No Test, No RFS/TFS */
309 	cs->BC_Write_Reg(cs, 0, jade_HDLC_MODE, jadeMODE_TMO);
310 	cs->BC_Write_Reg(cs, 1, jade_HDLC_MODE, jadeMODE_TMO);
311 	/* Power down, 1-Idle, RxTx least significant bit first */
312 	cs->BC_Write_Reg(cs, 0, jade_HDLC_CCR0, 0x00);
313 	cs->BC_Write_Reg(cs, 1, jade_HDLC_CCR0, 0x00);
314 	/* Mask all interrupts */
315 	cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR,  0x00);
316 	cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR,  0x00);
317 	/* Setup host access to hdlc controller */
318 	jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1|jadeINDIRECT_HAH2));
319 	/* Unmask HDLC int (don�t forget DSP int later on)*/
320 	cs->BC_Write_Reg(cs, -1,jade_INT, (jadeINT_HDLC1|jadeINT_HDLC2));
321 
322 	/* once again TRANSPARENT */
323 	modejade(cs->bcs, 0, 0);
324 	modejade(cs->bcs + 1, 0, 0);
325 }
326 
327