added mtd driver
[linux-2.4.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 #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 
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 
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
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
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
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
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
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 
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 
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 
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
517 dch_setstack(struct PStack *st, struct IsdnCardState *cs)
518 {
519         st->l1.l1hw = dch_l2l1;
520 }
521
522 //----------------------------------------------------------
523 //----------------------------------------------------------
524 static void __devinit
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
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
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
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
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
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
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
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
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
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
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 
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
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
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