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