File: /usr/src/linux/drivers/isdn/hisax/jade.c

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