OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [hisax/] [hscx.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* $Id: hscx.c,v 1.1 2005-12-20 10:17:01 jcastillo Exp $
2
 
3
 * hscx.c   HSCX specific routines
4
 *
5
 * Author       Karsten Keil (keil@isdn4linux.de)
6
 *
7
 *
8
 * $Log: not supported by cvs2svn $
9
 * Revision 1.1.1.1  2001/09/10 07:44:18  simons
10
 * Initial import
11
 *
12
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
13
 * Initial revision
14
 *
15
 * Revision 1.3.2.11  1998/11/05 21:14:01  keil
16
 * minor fixes
17
 *
18
 * Revision 1.3.2.10  1998/11/03 00:06:37  keil
19
 * certification related changes
20
 * fixed logging for smaller stack use
21
 *
22
 * Revision 1.3.2.9  1998/09/27 13:06:14  keil
23
 * Apply most changes from 2.1.X (HiSax 3.1)
24
 *
25
 * Revision 1.3.2.8  1998/09/15 15:25:04  keil
26
 * Repair HSCX init
27
 *
28
 * Revision 1.3.2.7  1998/06/26 22:02:55  keil
29
 * send flags between hdlc frames
30
 *
31
 * Revision 1.3.2.6  1998/06/09 18:26:32  keil
32
 * PH_DEACTIVATE B-channel every time signaled to higher layer
33
 *
34
 * Revision 1.3.2.5  1998/05/27 18:05:34  keil
35
 * HiSax 3.0
36
 *
37
 * Revision 1.3.2.4  1998/04/08 21:57:04  keil
38
 * Fix "lltrans ..." message
39
 * New init code to fix problems during init if S0 is allready activ
40
 *
41
 * Revision 1.3.2.3  1997/11/27 12:30:55  keil
42
 * cosmetic changes
43
 *
44
 * Revision 1.3.2.2  1997/11/15 18:54:25  keil
45
 * cosmetics
46
 *
47
 * Revision 1.3.2.1  1997/10/17 22:10:44  keil
48
 * new files on 2.0
49
 *
50
 * Revision 1.3  1997/07/27 21:38:34  keil
51
 * new B-channel interface
52
 *
53
 * Revision 1.2  1997/06/26 11:16:17  keil
54
 * first version
55
 *
56
 *
57
 */
58
 
59
#define __NO_VERSION__
60
#include "hisax.h"
61
#include "hscx.h"
62
#include "isac.h"
63
#include "isdnl1.h"
64
#include <linux/interrupt.h>
65
 
66
static char *HSCXVer[] HISAX_INITDATA =
67
{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
68
 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
69
 
70
HISAX_INITFUNC(int
71
HscxVersion(struct IsdnCardState *cs, char *s))
72
{
73
        int verA, verB;
74
 
75
        verA = cs->BC_Read_Reg(cs, 0, HSCX_VSTR) & 0xf;
76
        verB = cs->BC_Read_Reg(cs, 1, HSCX_VSTR) & 0xf;
77
        printk(KERN_INFO "%s HSCX version A: %s  B: %s\n", s,
78
               HSCXVer[verA], HSCXVer[verB]);
79
        if ((verA == 0) | (verA == 0xf) | (verB == 0) | (verB == 0xf))
80
                return (1);
81
        else
82
                return (0);
83
}
84
 
85
void
86
modehscx(struct BCState *bcs, int mode, int bc)
87
{
88
        struct IsdnCardState *cs = bcs->cs;
89
        int hscx = bcs->hw.hscx.hscx;
90
 
91
        if (cs->debug & L1_DEB_HSCX)
92
                debugl1(cs, "hscx %c mode %d ichan %d",
93
                        'A' + hscx, mode, bc);
94
        bcs->mode = mode;
95
        bcs->channel = bc;
96
        cs->BC_Write_Reg(cs, hscx, HSCX_XAD1, 0xFF);
97
        cs->BC_Write_Reg(cs, hscx, HSCX_XAD2, 0xFF);
98
        cs->BC_Write_Reg(cs, hscx, HSCX_RAH2, 0xFF);
99
        cs->BC_Write_Reg(cs, hscx, HSCX_XBCH, 0x0);
100
        cs->BC_Write_Reg(cs, hscx, HSCX_RLCR, 0x0);
101
        cs->BC_Write_Reg(cs, hscx, HSCX_CCR1,
102
                test_bit(HW_IPAC, &cs->HW_Flags) ? 0x82 : 0x85);
103
        cs->BC_Write_Reg(cs, hscx, HSCX_CCR2, 0x30);
104
        cs->BC_Write_Reg(cs, hscx, HSCX_XCCR, 7);
105
        cs->BC_Write_Reg(cs, hscx, HSCX_RCCR, 7);
106
 
107
        /* Switch IOM 1 SSI */
108
        if (test_bit(HW_IOM1, &cs->HW_Flags) && (hscx == 0))
109
                bc = 1 - bc;
110
 
111
        if (bc == 0) {
112
                cs->BC_Write_Reg(cs, hscx, HSCX_TSAX,
113
                              test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : 0x2f);
114
                cs->BC_Write_Reg(cs, hscx, HSCX_TSAR,
115
                              test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : 0x2f);
116
        } else {
117
                cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0x3);
118
                cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0x3);
119
        }
120
        switch (mode) {
121
                case (L1_MODE_NULL):
122
                        cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0x1f);
123
                        cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0x1f);
124
                        cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x84);
125
                        break;
126
                case (L1_MODE_TRANS):
127
                        cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0xe4);
128
                        break;
129
                case (L1_MODE_HDLC):
130
                        cs->BC_Write_Reg(cs, hscx, HSCX_CCR1,
131
                                test_bit(HW_IPAC, &cs->HW_Flags) ? 0x8a : 0x8d);
132
                        cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x8c);
133
                        break;
134
        }
135
        if (mode)
136
                cs->BC_Write_Reg(cs, hscx, HSCX_CMDR, 0x41);
137
        cs->BC_Write_Reg(cs, hscx, HSCX_ISTA, 0x00);
138
}
139
 
140
void
141
hscx_sched_event(struct BCState *bcs, int event)
142
{
143
        bcs->event |= 1 << event;
144
        queue_task(&bcs->tqueue, &tq_immediate);
145
        mark_bh(IMMEDIATE_BH);
146
}
147
 
148
void
149
hscx_l2l1(struct PStack *st, int pr, void *arg)
150
{
151
        struct sk_buff *skb = arg;
152
        long flags;
153
 
154
        switch (pr) {
155
                case (PH_DATA | REQUEST):
156
                        save_flags(flags);
157
                        cli();
158
                        if (st->l1.bcs->tx_skb) {
159
                                skb_queue_tail(&st->l1.bcs->squeue, skb);
160
                                restore_flags(flags);
161
                        } else {
162
                                st->l1.bcs->tx_skb = skb;
163
                                test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
164
                                st->l1.bcs->hw.hscx.count = 0;
165
                                restore_flags(flags);
166
                                st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
167
                        }
168
                        break;
169
                case (PH_PULL | INDICATION):
170
                        if (st->l1.bcs->tx_skb) {
171
                                printk(KERN_WARNING "hscx_l2l1: this shouldn't happen\n");
172
                                break;
173
                        }
174
                        test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
175
                        st->l1.bcs->tx_skb = skb;
176
                        st->l1.bcs->hw.hscx.count = 0;
177
                        st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
178
                        break;
179
                case (PH_PULL | REQUEST):
180
                        if (!st->l1.bcs->tx_skb) {
181
                                test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
182
                                st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
183
                        } else
184
                                test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
185
                        break;
186
                case (PH_ACTIVATE | REQUEST):
187
                        test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
188
                        modehscx(st->l1.bcs, st->l1.mode, st->l1.bc);
189
                        l1_msg_b(st, pr, arg);
190
                        break;
191
                case (PH_DEACTIVATE | REQUEST):
192
                        l1_msg_b(st, pr, arg);
193
                        break;
194
                case (PH_DEACTIVATE | CONFIRM):
195
                        test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
196
                        test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
197
                        modehscx(st->l1.bcs, 0, st->l1.bc);
198
                        st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
199
                        break;
200
        }
201
}
202
 
203
void
204
close_hscxstate(struct BCState *bcs)
205
{
206
        modehscx(bcs, 0, bcs->channel);
207
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
208
                if (bcs->hw.hscx.rcvbuf) {
209
                        kfree(bcs->hw.hscx.rcvbuf);
210
                        bcs->hw.hscx.rcvbuf = NULL;
211
                }
212
                if (bcs->blog) {
213
                        kfree(bcs->blog);
214
                        bcs->blog = NULL;
215
                }
216
                discard_queue(&bcs->rqueue);
217
                discard_queue(&bcs->squeue);
218
                if (bcs->tx_skb) {
219
                        dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
220
                        bcs->tx_skb = NULL;
221
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
222
                }
223
        }
224
}
225
 
226
int
227
open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs)
228
{
229
        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
230
                if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
231
                        printk(KERN_WARNING
232
                                "HiSax: No memory for hscx.rcvbuf\n");
233
                        test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
234
                        return (1);
235
                }
236
                if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
237
                        printk(KERN_WARNING
238
                                "HiSax: No memory for bcs->blog\n");
239
                        test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
240
                        kfree(bcs->hw.hscx.rcvbuf);
241
                        bcs->hw.hscx.rcvbuf = NULL;
242
                        return (2);
243
                }
244
                skb_queue_head_init(&bcs->rqueue);
245
                skb_queue_head_init(&bcs->squeue);
246
        }
247
        bcs->tx_skb = NULL;
248
        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
249
        bcs->event = 0;
250
        bcs->hw.hscx.rcvidx = 0;
251
        bcs->tx_cnt = 0;
252
        return (0);
253
}
254
 
255
int
256
setstack_hscx(struct PStack *st, struct BCState *bcs)
257
{
258
        bcs->channel = st->l1.bc;
259
        if (open_hscxstate(st->l1.hardware, bcs))
260
                return (-1);
261
        st->l1.bcs = bcs;
262
        st->l2.l2l1 = hscx_l2l1;
263
        setstack_manager(st);
264
        bcs->st = st;
265
        setstack_l1_B(st);
266
        return (0);
267
}
268
 
269
HISAX_INITFUNC(void
270
clear_pending_hscx_ints(struct IsdnCardState *cs))
271
{
272
        int val, eval;
273
 
274
        val = cs->BC_Read_Reg(cs, 1, HSCX_ISTA);
275
        debugl1(cs, "HSCX B ISTA %x", val);
276
        if (val & 0x01) {
277
                eval = cs->BC_Read_Reg(cs, 1, HSCX_EXIR);
278
                debugl1(cs, "HSCX B EXIR %x", eval);
279
        }
280
        if (val & 0x02) {
281
                eval = cs->BC_Read_Reg(cs, 0, HSCX_EXIR);
282
                debugl1(cs, "HSCX A EXIR %x", eval);
283
        }
284
        val = cs->BC_Read_Reg(cs, 0, HSCX_ISTA);
285
        debugl1(cs, "HSCX A ISTA %x", val);
286
        val = cs->BC_Read_Reg(cs, 1, HSCX_STAR);
287
        debugl1(cs, "HSCX B STAR %x", val);
288
        val = cs->BC_Read_Reg(cs, 0, HSCX_STAR);
289
        debugl1(cs, "HSCX A STAR %x", val);
290
        /* disable all IRQ */
291
        cs->BC_Write_Reg(cs, 0, HSCX_MASK, 0xFF);
292
        cs->BC_Write_Reg(cs, 1, HSCX_MASK, 0xFF);
293
}
294
 
295
HISAX_INITFUNC(void
296
inithscx(struct IsdnCardState *cs))
297
{
298
        cs->bcs[0].BC_SetStack = setstack_hscx;
299
        cs->bcs[1].BC_SetStack = setstack_hscx;
300
        cs->bcs[0].BC_Close = close_hscxstate;
301
        cs->bcs[1].BC_Close = close_hscxstate;
302
        cs->bcs[0].hw.hscx.hscx = 0;
303
        cs->bcs[1].hw.hscx.hscx = 1;
304
        modehscx(cs->bcs, 0, 0);
305
        modehscx(cs->bcs + 1, 0, 0);
306
}
307
 
308
HISAX_INITFUNC(void
309
inithscxisac(struct IsdnCardState *cs, int part))
310
{
311
        if (part & 1) {
312
                clear_pending_isac_ints(cs);
313
                clear_pending_hscx_ints(cs);
314
                initisac(cs);
315
                inithscx(cs);
316
        }
317
        if (part & 2) {
318
                /* Reenable all IRQ */
319
                cs->writeisac(cs, ISAC_MASK, 0);
320
                cs->BC_Write_Reg(cs, 0, HSCX_MASK, 0);
321
                cs->BC_Write_Reg(cs, 1, HSCX_MASK, 0);
322
                /* RESET Receiver and Transmitter */
323
                cs->writeisac(cs, ISAC_CMDR, 0x41);
324
        }
325
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.