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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [hisax/] [hscx.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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