1 /*
2 *
3 * IPACX specific routines
4 *
5 * Author Joerg Petersohn
6 * Derived from hisax_isac.c, isac.c, hscx.c and others
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 #define __NO_VERSION__
13 #include <linux/kernel.h>
14 #include <linux/config.h>
15 #include <linux/init.h>
16 #include "hisax_if.h"
17 #include "hisax.h"
18 #include "isdnl1.h"
19 #include "ipacx.h"
20
21 #define DBUSY_TIMER_VALUE 80
22 #define TIMER3_VALUE 7000
23 #define MAX_DFRAME_LEN_L1 300
24 #define B_FIFO_SIZE 64
25 #define D_FIFO_SIZE 32
26
27
28 // ipacx interrupt mask values
29 #define _MASK_IMASK 0x2E // global mask
30 #define _MASKB_IMASK 0x0B
31 #define _MASKD_IMASK 0x03 // all on
32
33 //----------------------------------------------------------
34 // local function declarations
35 //----------------------------------------------------------
36 static void ph_command(struct IsdnCardState *cs, unsigned int command);
37 static inline void cic_int(struct IsdnCardState *cs);
38 static void dch_l2l1(struct PStack *st, int pr, void *arg);
39 static void dbusy_timer_handler(struct IsdnCardState *cs);
40 static void ipacx_new_ph(struct IsdnCardState *cs);
41 static void dch_bh(struct IsdnCardState *cs);
42 static void dch_sched_event(struct IsdnCardState *cs, int event);
43 static void dch_empty_fifo(struct IsdnCardState *cs, int count);
44 static void dch_fill_fifo(struct IsdnCardState *cs);
45 static inline void dch_int(struct IsdnCardState *cs);
46 static void __devinit dch_setstack(struct PStack *st, struct IsdnCardState *cs);
47 static void __devinit dch_init(struct IsdnCardState *cs);
48 static void bch_l2l1(struct PStack *st, int pr, void *arg);
49 static void bch_sched_event(struct BCState *bcs, int event);
50 static void bch_empty_fifo(struct BCState *bcs, int count);
51 static void bch_fill_fifo(struct BCState *bcs);
52 static void bch_int(struct IsdnCardState *cs, u_char hscx);
53 static void bch_mode(struct BCState *bcs, int mode, int bc);
54 static void bch_close_state(struct BCState *bcs);
55 static int bch_open_state(struct IsdnCardState *cs, struct BCState *bcs);
56 static int bch_setstack(struct PStack *st, struct BCState *bcs);
57 static void __devinit bch_init(struct IsdnCardState *cs, int hscx);
58 static void __init clear_pending_ints(struct IsdnCardState *cs);
59
60 //----------------------------------------------------------
61 // Issue Layer 1 command to chip
62 //----------------------------------------------------------
63 static void
ph_command(struct IsdnCardState * cs,unsigned int command)64 ph_command(struct IsdnCardState *cs, unsigned int command)
65 {
66 if (cs->debug &L1_DEB_ISAC)
67 debugl1(cs, "ph_command (%#x) in (%#x)", command,
68 cs->dc.isac.ph_state);
69 //###################################
70 // printk(KERN_INFO "ph_command (%#x)\n", command);
71 //###################################
72 cs->writeisac(cs, IPACX_CIX0, (command << 4) | 0x0E);
73 }
74
75 //----------------------------------------------------------
76 // Transceiver interrupt handler
77 //----------------------------------------------------------
78 static inline void
cic_int(struct IsdnCardState * cs)79 cic_int(struct IsdnCardState *cs)
80 {
81 u_char event;
82
83 event = cs->readisac(cs, IPACX_CIR0) >> 4;
84 if (cs->debug &L1_DEB_ISAC) debugl1(cs, "cic_int(event=%#x)", event);
85 //#########################################
86 // printk(KERN_INFO "cic_int(%x)\n", event);
87 //#########################################
88 cs->dc.isac.ph_state = event;
89 dch_sched_event(cs, D_L1STATECHANGE);
90 }
91
92 //==========================================================
93 // D channel functions
94 //==========================================================
95
96 //----------------------------------------------------------
97 // Command entry point
98 //----------------------------------------------------------
99 static void
dch_l2l1(struct PStack * st,int pr,void * arg)100 dch_l2l1(struct PStack *st, int pr, void *arg)
101 {
102 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
103 struct sk_buff *skb = arg;
104 u_char cda1_cr, cda2_cr;
105
106 switch (pr) {
107 case (PH_DATA |REQUEST):
108 if (cs->debug &DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len);
109 if (cs->debug &DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
110 if (cs->tx_skb) {
111 skb_queue_tail(&cs->sq, skb);
112 #ifdef L2FRAME_DEBUG
113 if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0);
114 #endif
115 } else {
116 cs->tx_skb = skb;
117 cs->tx_cnt = 0;
118 #ifdef L2FRAME_DEBUG
119 if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0);
120 #endif
121 dch_fill_fifo(cs);
122 }
123 break;
124
125 case (PH_PULL |INDICATION):
126 if (cs->tx_skb) {
127 if (cs->debug & L1_DEB_WARN)
128 debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
129 skb_queue_tail(&cs->sq, skb);
130 break;
131 }
132 if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len);
133 if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
134 cs->tx_skb = skb;
135 cs->tx_cnt = 0;
136 #ifdef L2FRAME_DEBUG
137 if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
138 #endif
139 dch_fill_fifo(cs);
140 break;
141
142 case (PH_PULL | REQUEST):
143 #ifdef L2FRAME_DEBUG
144 if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL");
145 #endif
146 if (!cs->tx_skb) {
147 clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
148 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
149 } else
150 set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
151 break;
152
153 case (HW_RESET | REQUEST):
154 case (HW_ENABLE | REQUEST):
155 if ((cs->dc.isac.ph_state == IPACX_IND_RES) ||
156 (cs->dc.isac.ph_state == IPACX_IND_DR) ||
157 (cs->dc.isac.ph_state == IPACX_IND_DC))
158 ph_command(cs, IPACX_CMD_TIM);
159 else
160 ph_command(cs, IPACX_CMD_RES);
161
162 break;
163
164 case (HW_INFO3 | REQUEST):
165 ph_command(cs, IPACX_CMD_AR8);
166 break;
167
168 case (HW_TESTLOOP | REQUEST):
169 cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1
170 cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1
171 cda1_cr = cs->readisac(cs, IPACX_CDA1_CR);
172 cda2_cr = cs->readisac(cs, IPACX_CDA2_CR);
173 if ((long)arg &1) { // loop B1
174 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a);
175 }
176 else { // B1 off
177 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x0a);
178 }
179 if ((long)arg &2) { // loop B2
180 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x14);
181 }
182 else { // B2 off
183 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x14);
184 }
185 break;
186
187 case (HW_DEACTIVATE | RESPONSE):
188 skb_queue_purge(&cs->rq);
189 skb_queue_purge(&cs->sq);
190 if (cs->tx_skb) {
191 dev_kfree_skb_any(cs->tx_skb);
192 cs->tx_skb = NULL;
193 }
194 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
195 del_timer(&cs->dbusytimer);
196 break;
197
198 default:
199 if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_l2l1 unknown %04x", pr);
200 break;
201 }
202 }
203
204 //----------------------------------------------------------
205 //----------------------------------------------------------
206 static void
dbusy_timer_handler(struct IsdnCardState * cs)207 dbusy_timer_handler(struct IsdnCardState *cs)
208 {
209 struct PStack *st;
210 int rbchd, stard;
211
212 if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
213 rbchd = cs->readisac(cs, IPACX_RBCHD);
214 stard = cs->readisac(cs, IPACX_STARD);
215 if (cs->debug)
216 debugl1(cs, "D-Channel Busy RBCHD %02x STARD %02x", rbchd, stard);
217 if (!(stard &0x40)) { // D-Channel Busy
218 set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
219 for (st = cs->stlist; st; st = st->next) {
220 st->l1.l1l2(st, PH_PAUSE | INDICATION, NULL); // flow control on
221 }
222 } else {
223 // seems we lost an interrupt; reset transceiver */
224 clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
225 if (cs->tx_skb) {
226 dev_kfree_skb_any(cs->tx_skb);
227 cs->tx_cnt = 0;
228 cs->tx_skb = NULL;
229 } else {
230 printk(KERN_WARNING "HiSax: ISAC D-Channel Busy no skb\n");
231 debugl1(cs, "D-Channel Busy no skb");
232 }
233 cs->writeisac(cs, IPACX_CMDRD, 0x01); // Tx reset, generates XPR
234 }
235 }
236 }
237
238 //----------------------------------------------------------
239 // L1 state machine intermediate layer to isdnl1 module
240 //----------------------------------------------------------
241 static void
ipacx_new_ph(struct IsdnCardState * cs)242 ipacx_new_ph(struct IsdnCardState *cs)
243 {
244 switch (cs->dc.isac.ph_state) {
245 case (IPACX_IND_RES):
246 ph_command(cs, IPACX_CMD_DI);
247 l1_msg(cs, HW_RESET | INDICATION, NULL);
248 break;
249
250 case (IPACX_IND_DC):
251 l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
252 break;
253
254 case (IPACX_IND_DR):
255 l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
256 break;
257
258 case (IPACX_IND_PU):
259 l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
260 break;
261
262 case (IPACX_IND_RSY):
263 l1_msg(cs, HW_RSYNC | INDICATION, NULL);
264 break;
265
266 case (IPACX_IND_AR):
267 l1_msg(cs, HW_INFO2 | INDICATION, NULL);
268 break;
269
270 case (IPACX_IND_AI8):
271 l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
272 break;
273
274 case (IPACX_IND_AI10):
275 l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
276 break;
277
278 default:
279 break;
280 }
281 }
282
283 //----------------------------------------------------------
284 // bottom half handler for D channel
285 //----------------------------------------------------------
286 static void
dch_bh(struct IsdnCardState * cs)287 dch_bh(struct IsdnCardState *cs)
288 {
289 struct PStack *st;
290
291 if (!cs) return;
292
293 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
294 if (cs->debug) debugl1(cs, "D-Channel Busy cleared");
295 for (st = cs->stlist; st; st = st->next) {
296 st->l1.l1l2(st, PH_PAUSE | CONFIRM, NULL);
297 }
298 }
299
300 if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
301 DChannel_proc_rcv(cs);
302 }
303
304 if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
305 DChannel_proc_xmt(cs);
306 }
307
308 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
309 ipacx_new_ph(cs);
310 }
311 }
312
313 //----------------------------------------------------------
314 // proceed with bottom half handler dch_bh()
315 //----------------------------------------------------------
316 static void
dch_sched_event(struct IsdnCardState * cs,int event)317 dch_sched_event(struct IsdnCardState *cs, int event)
318 {
319 set_bit(event, &cs->event);
320 queue_task(&cs->tqueue, &tq_immediate);
321 mark_bh(IMMEDIATE_BH);
322 }
323
324 //----------------------------------------------------------
325 // Fill buffer from receive FIFO
326 //----------------------------------------------------------
327 static void
dch_empty_fifo(struct IsdnCardState * cs,int count)328 dch_empty_fifo(struct IsdnCardState *cs, int count)
329 {
330 long flags;
331 u_char *ptr;
332
333 if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO))
334 debugl1(cs, "dch_empty_fifo()");
335
336 // message too large, remove
337 if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
338 if (cs->debug &L1_DEB_WARN)
339 debugl1(cs, "dch_empty_fifo() incoming message too large");
340 cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
341 cs->rcvidx = 0;
342 return;
343 }
344
345 ptr = cs->rcvbuf + cs->rcvidx;
346 cs->rcvidx += count;
347
348 save_flags(flags);
349 cli();
350 cs->readisacfifo(cs, ptr, count);
351 cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
352 restore_flags(flags);
353
354 if (cs->debug &L1_DEB_ISAC_FIFO) {
355 char *t = cs->dlog;
356
357 t += sprintf(t, "dch_empty_fifo() cnt %d", count);
358 QuickHex(t, ptr, count);
359 debugl1(cs, cs->dlog);
360 }
361 }
362
363 //----------------------------------------------------------
364 // Fill transmit FIFO
365 //----------------------------------------------------------
366 static void
dch_fill_fifo(struct IsdnCardState * cs)367 dch_fill_fifo(struct IsdnCardState *cs)
368 {
369 long flags;
370 int count;
371 u_char cmd, *ptr;
372
373 if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO))
374 debugl1(cs, "dch_fill_fifo()");
375
376 if (!cs->tx_skb) return;
377 count = cs->tx_skb->len;
378 if (count <= 0) return;
379
380 if (count > D_FIFO_SIZE) {
381 count = D_FIFO_SIZE;
382 cmd = 0x08; // XTF
383 } else {
384 cmd = 0x0A; // XTF | XME
385 }
386
387 save_flags(flags);
388 cli();
389 ptr = cs->tx_skb->data;
390 skb_pull(cs->tx_skb, count);
391 cs->tx_cnt += count;
392 cs->writeisacfifo(cs, ptr, count);
393 cs->writeisac(cs, IPACX_CMDRD, cmd);
394
395 // set timeout for transmission contol
396 if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
397 debugl1(cs, "dch_fill_fifo dbusytimer running");
398 del_timer(&cs->dbusytimer);
399 }
400 init_timer(&cs->dbusytimer);
401 cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
402 add_timer(&cs->dbusytimer);
403 restore_flags(flags);
404
405 if (cs->debug &L1_DEB_ISAC_FIFO) {
406 char *t = cs->dlog;
407
408 t += sprintf(t, "dch_fill_fifo() cnt %d", count);
409 QuickHex(t, ptr, count);
410 debugl1(cs, cs->dlog);
411 }
412 }
413
414 //----------------------------------------------------------
415 // D channel interrupt handler
416 //----------------------------------------------------------
417 static inline void
dch_int(struct IsdnCardState * cs)418 dch_int(struct IsdnCardState *cs)
419 {
420 struct sk_buff *skb;
421 u_char istad, rstad;
422 long flags;
423 int count;
424
425 istad = cs->readisac(cs, IPACX_ISTAD);
426 //##############################################
427 // printk(KERN_WARNING "dch_int(istad=%02x)\n", istad);
428 //##############################################
429
430 if (istad &0x80) { // RME
431 rstad = cs->readisac(cs, IPACX_RSTAD);
432 if ((rstad &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
433 if (!(rstad &0x80))
434 if (cs->debug &L1_DEB_WARN)
435 debugl1(cs, "dch_int(): invalid frame");
436 if ((rstad &0x40))
437 if (cs->debug &L1_DEB_WARN)
438 debugl1(cs, "dch_int(): RDO");
439 if (!(rstad &0x20))
440 if (cs->debug &L1_DEB_WARN)
441 debugl1(cs, "dch_int(): CRC error");
442 cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
443 } else { // received frame ok
444 count = cs->readisac(cs, IPACX_RBCLD);
445 if (count) count--; // RSTAB is last byte
446 count &= D_FIFO_SIZE-1;
447 if (count == 0) count = D_FIFO_SIZE;
448 dch_empty_fifo(cs, count);
449 save_flags(flags);
450 cli();
451 if ((count = cs->rcvidx) > 0) {
452 cs->rcvidx = 0;
453 if (!(skb = dev_alloc_skb(count)))
454 printk(KERN_WARNING "HiSax dch_int(): receive out of memory\n");
455 else {
456 memcpy(skb_put(skb, count), cs->rcvbuf, count);
457 skb_queue_tail(&cs->rq, skb);
458 }
459 }
460 restore_flags(flags);
461 }
462 cs->rcvidx = 0;
463 dch_sched_event(cs, D_RCVBUFREADY);
464 }
465
466 if (istad &0x40) { // RPF
467 dch_empty_fifo(cs, D_FIFO_SIZE);
468 }
469
470 if (istad &0x20) { // RFO
471 if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): RFO");
472 cs->writeisac(cs, IPACX_CMDRD, 0x40); //RRES
473 }
474
475 if (istad &0x10) { // XPR
476 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
477 del_timer(&cs->dbusytimer);
478 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
479 dch_sched_event(cs, D_CLEARBUSY);
480 if (cs->tx_skb) {
481 if (cs->tx_skb->len) {
482 dch_fill_fifo(cs);
483 goto afterXPR;
484 }
485 else {
486 dev_kfree_skb_irq(cs->tx_skb);
487 cs->tx_skb = NULL;
488 cs->tx_cnt = 0;
489 }
490 }
491 if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
492 cs->tx_cnt = 0;
493 dch_fill_fifo(cs);
494 }
495 else {
496 dch_sched_event(cs, D_XMTBUFREADY);
497 }
498 }
499 afterXPR:
500
501 if (istad &0x0C) { // XDU or XMR
502 if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): XDU");
503 if (cs->tx_skb) {
504 skb_push(cs->tx_skb, cs->tx_cnt); // retransmit
505 cs->tx_cnt = 0;
506 dch_fill_fifo(cs);
507 } else {
508 printk(KERN_WARNING "HiSax: ISAC XDU no skb\n");
509 debugl1(cs, "ISAC XDU no skb");
510 }
511 }
512 }
513
514 //----------------------------------------------------------
515 //----------------------------------------------------------
516 static void __devinit
dch_setstack(struct PStack * st,struct IsdnCardState * cs)517 dch_setstack(struct PStack *st, struct IsdnCardState *cs)
518 {
519 st->l1.l1hw = dch_l2l1;
520 }
521
522 //----------------------------------------------------------
523 //----------------------------------------------------------
524 static void __devinit
dch_init(struct IsdnCardState * cs)525 dch_init(struct IsdnCardState *cs)
526 {
527 printk(KERN_INFO "HiSax: IPACX ISDN driver v0.1.0\n");
528
529 cs->tqueue.routine = (void *)(void *) dch_bh;
530 cs->setstack_d = dch_setstack;
531
532 cs->dbusytimer.function = (void *) dbusy_timer_handler;
533 cs->dbusytimer.data = (long) cs;
534 init_timer(&cs->dbusytimer);
535
536 cs->writeisac(cs, IPACX_TR_CONF0, 0x00); // clear LDD
537 cs->writeisac(cs, IPACX_TR_CONF2, 0x00); // enable transmitter
538 cs->writeisac(cs, IPACX_MODED, 0xC9); // transparent mode 0, RAC, stop/go
539 cs->writeisac(cs, IPACX_MON_CR, 0x00); // disable monitor channel
540 }
541
542
543 //==========================================================
544 // B channel functions
545 //==========================================================
546
547 //----------------------------------------------------------
548 // Entry point for commands
549 //----------------------------------------------------------
550 static void
bch_l2l1(struct PStack * st,int pr,void * arg)551 bch_l2l1(struct PStack *st, int pr, void *arg)
552 {
553 struct sk_buff *skb = arg;
554 long flags;
555
556 switch (pr) {
557 case (PH_DATA | REQUEST):
558 save_flags(flags);
559 cli();
560 if (st->l1.bcs->tx_skb) {
561 skb_queue_tail(&st->l1.bcs->squeue, skb);
562 restore_flags(flags);
563 } else {
564 st->l1.bcs->tx_skb = skb;
565 set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
566 st->l1.bcs->hw.hscx.count = 0;
567 restore_flags(flags);
568 bch_fill_fifo(st->l1.bcs);
569 }
570 break;
571 case (PH_PULL | INDICATION):
572 if (st->l1.bcs->tx_skb) {
573 printk(KERN_WARNING "HiSax bch_l2l1(): this shouldn't happen\n");
574 break;
575 }
576 set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
577 st->l1.bcs->tx_skb = skb;
578 st->l1.bcs->hw.hscx.count = 0;
579 bch_fill_fifo(st->l1.bcs);
580 break;
581 case (PH_PULL | REQUEST):
582 if (!st->l1.bcs->tx_skb) {
583 clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
584 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
585 } else
586 set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
587 break;
588 case (PH_ACTIVATE | REQUEST):
589 set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
590 bch_mode(st->l1.bcs, st->l1.mode, st->l1.bc);
591 l1_msg_b(st, pr, arg);
592 break;
593 case (PH_DEACTIVATE | REQUEST):
594 l1_msg_b(st, pr, arg);
595 break;
596 case (PH_DEACTIVATE | CONFIRM):
597 clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
598 clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
599 bch_mode(st->l1.bcs, 0, st->l1.bc);
600 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
601 break;
602 }
603 }
604
605 //----------------------------------------------------------
606 // proceed with bottom half handler BChannel_bh()
607 //----------------------------------------------------------
608 static void
bch_sched_event(struct BCState * bcs,int event)609 bch_sched_event(struct BCState *bcs, int event)
610 {
611 bcs->event |= 1 << event;
612 queue_task(&bcs->tqueue, &tq_immediate);
613 mark_bh(IMMEDIATE_BH);
614 }
615
616 //----------------------------------------------------------
617 // Read B channel fifo to receive buffer
618 //----------------------------------------------------------
619 static void
bch_empty_fifo(struct BCState * bcs,int count)620 bch_empty_fifo(struct BCState *bcs, int count)
621 {
622 u_char *ptr, hscx;
623 struct IsdnCardState *cs;
624 long flags;
625 int cnt;
626
627 cs = bcs->cs;
628 hscx = bcs->hw.hscx.hscx;
629 if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO))
630 debugl1(cs, "bch_empty_fifo()");
631
632 // message too large, remove
633 if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
634 if (cs->debug &L1_DEB_WARN)
635 debugl1(cs, "bch_empty_fifo() incoming packet too large");
636 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC
637 bcs->hw.hscx.rcvidx = 0;
638 return;
639 }
640
641 // Read data uninterruptible
642 save_flags(flags);
643 cli();
644 ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
645 cnt = count;
646 while (cnt--) *ptr++ = cs->BC_Read_Reg(cs, hscx, IPACX_RFIFOB);
647 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC
648
649 ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
650 bcs->hw.hscx.rcvidx += count;
651 restore_flags(flags);
652
653 if (cs->debug &L1_DEB_HSCX_FIFO) {
654 char *t = bcs->blog;
655
656 t += sprintf(t, "bch_empty_fifo() B-%d cnt %d", hscx, count);
657 QuickHex(t, ptr, count);
658 debugl1(cs, bcs->blog);
659 }
660 }
661
662 //----------------------------------------------------------
663 // Fill buffer to transmit FIFO
664 //----------------------------------------------------------
665 static void
bch_fill_fifo(struct BCState * bcs)666 bch_fill_fifo(struct BCState *bcs)
667 {
668 struct IsdnCardState *cs;
669 int more, count, cnt;
670 u_char *ptr, *p, hscx;
671 long flags;
672
673 cs = bcs->cs;
674 if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO))
675 debugl1(cs, "bch_fill_fifo()");
676
677 if (!bcs->tx_skb) return;
678 if (bcs->tx_skb->len <= 0) return;
679
680 hscx = bcs->hw.hscx.hscx;
681 more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
682 if (bcs->tx_skb->len > B_FIFO_SIZE) {
683 more = 1;
684 count = B_FIFO_SIZE;
685 } else {
686 count = bcs->tx_skb->len;
687 }
688 cnt = count;
689
690 save_flags(flags);
691 cli();
692 p = ptr = bcs->tx_skb->data;
693 skb_pull(bcs->tx_skb, count);
694 bcs->tx_cnt -= count;
695 bcs->hw.hscx.count += count;
696 while (cnt--) cs->BC_Write_Reg(cs, hscx, IPACX_XFIFOB, *p++);
697 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, (more ? 0x08 : 0x0a));
698 restore_flags(flags);
699
700 if (cs->debug &L1_DEB_HSCX_FIFO) {
701 char *t = bcs->blog;
702
703 t += sprintf(t, "chb_fill_fifo() B-%d cnt %d", hscx, count);
704 QuickHex(t, ptr, count);
705 debugl1(cs, bcs->blog);
706 }
707 }
708
709 //----------------------------------------------------------
710 // B channel interrupt handler
711 //----------------------------------------------------------
712 static void
bch_int(struct IsdnCardState * cs,u_char hscx)713 bch_int(struct IsdnCardState *cs, u_char hscx)
714 {
715 u_char istab;
716 struct BCState *bcs;
717 struct sk_buff *skb;
718 int count;
719 u_char rstab;
720
721 bcs = cs->bcs + hscx;
722 istab = cs->BC_Read_Reg(cs, hscx, IPACX_ISTAB);
723 //##############################################
724 // printk(KERN_WARNING "bch_int(istab=%02x)\n", istab);
725 //##############################################
726 if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return;
727
728 if (istab &0x80) { // RME
729 rstab = cs->BC_Read_Reg(cs, hscx, IPACX_RSTAB);
730 if ((rstab &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
731 if (!(rstab &0x80))
732 if (cs->debug &L1_DEB_WARN)
733 debugl1(cs, "bch_int() B-%d: invalid frame", hscx);
734 if ((rstab &0x40) && (bcs->mode != L1_MODE_NULL))
735 if (cs->debug &L1_DEB_WARN)
736 debugl1(cs, "bch_int() B-%d: RDO mode=%d", hscx, bcs->mode);
737 if (!(rstab &0x20))
738 if (cs->debug &L1_DEB_WARN)
739 debugl1(cs, "bch_int() B-%d: CRC error", hscx);
740 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC
741 }
742 else { // received frame ok
743 count = cs->BC_Read_Reg(cs, hscx, IPACX_RBCLB) &(B_FIFO_SIZE-1);
744 if (count == 0) count = B_FIFO_SIZE;
745 bch_empty_fifo(bcs, count);
746 if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
747 if (cs->debug &L1_DEB_HSCX_FIFO)
748 debugl1(cs, "bch_int Frame %d", count);
749 if (!(skb = dev_alloc_skb(count)))
750 printk(KERN_WARNING "HiSax bch_int(): receive frame out of memory\n");
751 else {
752 memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count);
753 skb_queue_tail(&bcs->rqueue, skb);
754 }
755 }
756 }
757 bcs->hw.hscx.rcvidx = 0;
758 bch_sched_event(bcs, B_RCVBUFREADY);
759 }
760
761 if (istab &0x40) { // RPF
762 bch_empty_fifo(bcs, B_FIFO_SIZE);
763
764 if (bcs->mode == L1_MODE_TRANS) { // queue every chunk
765 // receive transparent audio data
766 if (!(skb = dev_alloc_skb(B_FIFO_SIZE)))
767 printk(KERN_WARNING "HiSax bch_int(): receive transparent out of memory\n");
768 else {
769 memcpy(skb_put(skb, B_FIFO_SIZE), bcs->hw.hscx.rcvbuf, B_FIFO_SIZE);
770 skb_queue_tail(&bcs->rqueue, skb);
771 }
772 bcs->hw.hscx.rcvidx = 0;
773 bch_sched_event(bcs, B_RCVBUFREADY);
774 }
775 }
776
777 if (istab &0x20) { // RFO
778 if (cs->debug &L1_DEB_WARN)
779 debugl1(cs, "bch_int() B-%d: RFO error", hscx);
780 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x40); // RRES
781 }
782
783 if (istab &0x10) { // XPR
784 if (bcs->tx_skb) {
785 if (bcs->tx_skb->len) {
786 bch_fill_fifo(bcs);
787 goto afterXPR;
788 }
789 else {
790 if (bcs->st->lli.l1writewakeup &&
791 (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
792 bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count);
793 }
794 dev_kfree_skb_irq(bcs->tx_skb);
795 bcs->hw.hscx.count = 0;
796 bcs->tx_skb = NULL;
797 }
798 }
799 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
800 bcs->hw.hscx.count = 0;
801 set_bit(BC_FLG_BUSY, &bcs->Flag);
802 bch_fill_fifo(bcs);
803 } else {
804 clear_bit(BC_FLG_BUSY, &bcs->Flag);
805 bch_sched_event(bcs, B_XMTBUFREADY);
806 }
807 }
808 afterXPR:
809
810 if (istab &0x04) { // XDU
811 if (bcs->mode == L1_MODE_TRANS) {
812 bch_fill_fifo(bcs);
813 }
814 else {
815 if (bcs->tx_skb) { // restart transmitting the whole frame
816 skb_push(bcs->tx_skb, bcs->hw.hscx.count);
817 bcs->tx_cnt += bcs->hw.hscx.count;
818 bcs->hw.hscx.count = 0;
819 }
820 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x01); // XRES
821 if (cs->debug &L1_DEB_WARN)
822 debugl1(cs, "bch_int() B-%d XDU error", hscx);
823 }
824 }
825 }
826
827 //----------------------------------------------------------
828 //----------------------------------------------------------
829 static void
bch_mode(struct BCState * bcs,int mode,int bc)830 bch_mode(struct BCState *bcs, int mode, int bc)
831 {
832 struct IsdnCardState *cs = bcs->cs;
833 int hscx = bcs->hw.hscx.hscx;
834
835 bc = bc ? 1 : 0; // in case bc is greater than 1
836 if (cs->debug & L1_DEB_HSCX)
837 debugl1(cs, "mode_bch() switch B-% mode %d chan %d", hscx, mode, bc);
838 bcs->mode = mode;
839 bcs->channel = bc;
840
841 // map controller to according timeslot
842 if (!hscx)
843 {
844 cs->writeisac(cs, IPACX_BCHA_TSDP_BC1, 0x80 | bc);
845 cs->writeisac(cs, IPACX_BCHA_CR, 0x88);
846 }
847 else
848 {
849 cs->writeisac(cs, IPACX_BCHB_TSDP_BC1, 0x80 | bc);
850 cs->writeisac(cs, IPACX_BCHB_CR, 0x88);
851 }
852
853 switch (mode) {
854 case (L1_MODE_NULL):
855 cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC0); // rec off
856 cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x30); // std adj.
857 cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, 0xFF); // ints off
858 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments
859 break;
860 case (L1_MODE_TRANS):
861 cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0x88); // ext transp mode
862 cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x00); // xxx00000
863 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments
864 cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
865 break;
866 case (L1_MODE_HDLC):
867 cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC8); // transp mode 0
868 cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x01); // idle=hdlc flags crc enabled
869 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments
870 cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
871 break;
872 }
873 }
874
875 //----------------------------------------------------------
876 //----------------------------------------------------------
877 static void
bch_close_state(struct BCState * bcs)878 bch_close_state(struct BCState *bcs)
879 {
880 bch_mode(bcs, 0, bcs->channel);
881 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
882 if (bcs->hw.hscx.rcvbuf) {
883 kfree(bcs->hw.hscx.rcvbuf);
884 bcs->hw.hscx.rcvbuf = NULL;
885 }
886 if (bcs->blog) {
887 kfree(bcs->blog);
888 bcs->blog = NULL;
889 }
890 skb_queue_purge(&bcs->rqueue);
891 skb_queue_purge(&bcs->squeue);
892 if (bcs->tx_skb) {
893 dev_kfree_skb_any(bcs->tx_skb);
894 bcs->tx_skb = NULL;
895 clear_bit(BC_FLG_BUSY, &bcs->Flag);
896 }
897 }
898 }
899
900 //----------------------------------------------------------
901 //----------------------------------------------------------
902 static int
bch_open_state(struct IsdnCardState * cs,struct BCState * bcs)903 bch_open_state(struct IsdnCardState *cs, struct BCState *bcs)
904 {
905 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
906 if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
907 printk(KERN_WARNING
908 "HiSax open_bchstate(): No memory for hscx.rcvbuf\n");
909 clear_bit(BC_FLG_INIT, &bcs->Flag);
910 return (1);
911 }
912 if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
913 printk(KERN_WARNING
914 "HiSax open_bchstate: No memory for bcs->blog\n");
915 clear_bit(BC_FLG_INIT, &bcs->Flag);
916 kfree(bcs->hw.hscx.rcvbuf);
917 bcs->hw.hscx.rcvbuf = NULL;
918 return (2);
919 }
920 skb_queue_head_init(&bcs->rqueue);
921 skb_queue_head_init(&bcs->squeue);
922 }
923 bcs->tx_skb = NULL;
924 clear_bit(BC_FLG_BUSY, &bcs->Flag);
925 bcs->event = 0;
926 bcs->hw.hscx.rcvidx = 0;
927 bcs->tx_cnt = 0;
928 return (0);
929 }
930
931 //----------------------------------------------------------
932 //----------------------------------------------------------
933 static int
bch_setstack(struct PStack * st,struct BCState * bcs)934 bch_setstack(struct PStack *st, struct BCState *bcs)
935 {
936 bcs->channel = st->l1.bc;
937 if (bch_open_state(st->l1.hardware, bcs)) return (-1);
938 st->l1.bcs = bcs;
939 st->l2.l2l1 = bch_l2l1;
940 setstack_manager(st);
941 bcs->st = st;
942 setstack_l1_B(st);
943 return (0);
944 }
945
946 //----------------------------------------------------------
947 //----------------------------------------------------------
948 static void __devinit
bch_init(struct IsdnCardState * cs,int hscx)949 bch_init(struct IsdnCardState *cs, int hscx)
950 {
951 cs->bcs[hscx].BC_SetStack = bch_setstack;
952 cs->bcs[hscx].BC_Close = bch_close_state;
953 cs->bcs[hscx].hw.hscx.hscx = hscx;
954 cs->bcs[hscx].cs = cs;
955 bch_mode(cs->bcs + hscx, 0, hscx);
956 }
957
958
959 //==========================================================
960 // Shared functions
961 //==========================================================
962
963 //----------------------------------------------------------
964 // Main interrupt handler
965 //----------------------------------------------------------
966 void
interrupt_ipacx(struct IsdnCardState * cs)967 interrupt_ipacx(struct IsdnCardState *cs)
968 {
969 u_char ista;
970
971 while ((ista = cs->readisac(cs, IPACX_ISTA))) {
972 //#################################################
973 // printk(KERN_WARNING "interrupt_ipacx(ista=%02x)\n", ista);
974 //#################################################
975 if (ista &0x80) bch_int(cs, 0); // B channel interrupts
976 if (ista &0x40) bch_int(cs, 1);
977
978 if (ista &0x01) dch_int(cs); // D channel
979 if (ista &0x10) cic_int(cs); // Layer 1 state
980 }
981 }
982
983 //----------------------------------------------------------
984 // Clears chip interrupt status
985 //----------------------------------------------------------
986 static void __init
clear_pending_ints(struct IsdnCardState * cs)987 clear_pending_ints(struct IsdnCardState *cs)
988 {
989 int ista;
990
991 // all interrupts off
992 cs->writeisac(cs, IPACX_MASK, 0xff);
993 cs->writeisac(cs, IPACX_MASKD, 0xff);
994 cs->BC_Write_Reg(cs, 0, IPACX_MASKB, 0xff);
995 cs->BC_Write_Reg(cs, 1, IPACX_MASKB, 0xff);
996
997 ista = cs->readisac(cs, IPACX_ISTA);
998 if (ista &0x80) cs->BC_Read_Reg(cs, 0, IPACX_ISTAB);
999 if (ista &0x40) cs->BC_Read_Reg(cs, 1, IPACX_ISTAB);
1000 if (ista &0x10) cs->readisac(cs, IPACX_CIR0);
1001 if (ista &0x01) cs->readisac(cs, IPACX_ISTAD);
1002 }
1003
1004 //----------------------------------------------------------
1005 // Does chip configuration work
1006 // Work to do depends on bit mask in part
1007 //----------------------------------------------------------
1008 void __init
init_ipacx(struct IsdnCardState * cs,int part)1009 init_ipacx(struct IsdnCardState *cs, int part)
1010 {
1011 if (part &1) { // initialise chip
1012 //##################################################
1013 // printk(KERN_INFO "init_ipacx(%x)\n", part);
1014 //##################################################
1015 clear_pending_ints(cs);
1016 bch_init(cs, 0);
1017 bch_init(cs, 1);
1018 dch_init(cs);
1019 }
1020 if (part &2) { // reenable all interrupts and start chip
1021 cs->BC_Write_Reg(cs, 0, IPACX_MASKB, _MASKB_IMASK);
1022 cs->BC_Write_Reg(cs, 1, IPACX_MASKB, _MASKB_IMASK);
1023 cs->writeisac(cs, IPACX_MASKD, _MASKD_IMASK);
1024 cs->writeisac(cs, IPACX_MASK, _MASK_IMASK); // global mask register
1025
1026 // reset HDLC Transmitters/receivers
1027 cs->writeisac(cs, IPACX_CMDRD, 0x41);
1028 cs->BC_Write_Reg(cs, 0, IPACX_CMDRB, 0x41);
1029 cs->BC_Write_Reg(cs, 1, IPACX_CMDRB, 0x41);
1030 ph_command(cs, IPACX_CMD_RES);
1031 }
1032 }
1033
1034 //----------------- end of file -----------------------
1035
1036