]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/isdn/hisax/hisax_fcpcipnp.c
Merge branch 'linux-2.6'
[linux-2.6-omap-h63xx.git] / drivers / isdn / hisax / hisax_fcpcipnp.c
1 /*
2  * Driver for AVM Fritz!PCI, Fritz!PCI v2, Fritz!PnP ISDN cards
3  *
4  * Author       Kai Germaschewski
5  * Copyright    2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
6  *              2001 by Karsten Keil       <keil@isdn4linux.de>
7  * 
8  * based upon Karsten Keil's original avm_pci.c driver
9  *
10  * This software may be used and distributed according to the terms
11  * of the GNU General Public License, incorporated herein by reference.
12  *
13  * Thanks to Wizard Computersysteme GmbH, Bremervoerde and
14  *           SoHaNet Technology GmbH, Berlin
15  * for supporting the development of this driver
16  */
17
18
19 /* TODO:
20  *
21  * o POWER PC
22  * o clean up debugging
23  * o tx_skb at PH_DEACTIVATE time
24  */
25
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/pci.h>
29 #include <linux/isapnp.h>
30 #include <linux/kmod.h>
31 #include <linux/slab.h>
32 #include <linux/skbuff.h>
33 #include <linux/netdevice.h>
34 #include <linux/delay.h>
35
36 #include <asm/io.h>
37
38 #include "hisax_fcpcipnp.h"
39
40 // debugging cruft
41 #define __debug_variable debug
42 #include "hisax_debug.h"
43
44 #ifdef CONFIG_HISAX_DEBUG
45 static int debug = 0;
46 /* static int hdlcfifosize = 32; */
47 module_param(debug, int, 0);
48 /* module_param(hdlcfifosize, int, 0); */
49 #endif
50
51 MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
52 MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver");
53
54 static struct pci_device_id fcpci_ids[] = {
55         { .vendor      = PCI_VENDOR_ID_AVM,
56           .device      = PCI_DEVICE_ID_AVM_A1,
57           .subvendor   = PCI_ANY_ID,
58           .subdevice   = PCI_ANY_ID,
59           .driver_data = (unsigned long) "Fritz!Card PCI",
60         },
61         { .vendor      = PCI_VENDOR_ID_AVM,
62           .device      = PCI_DEVICE_ID_AVM_A1_V2,
63           .subvendor   = PCI_ANY_ID,
64           .subdevice   = PCI_ANY_ID,
65           .driver_data = (unsigned long) "Fritz!Card PCI v2" },
66         {}
67 };
68
69 MODULE_DEVICE_TABLE(pci, fcpci_ids);
70
71 #ifdef __ISAPNP__
72 static struct pnp_device_id fcpnp_ids[] __devinitdata = {
73         { 
74                 .id             = "AVM0900",
75                 .driver_data    = (unsigned long) "Fritz!Card PnP",
76         },
77 };
78
79 MODULE_DEVICE_TABLE(isapnp, fcpnp_ids);
80 #endif
81
82 static int protocol = 2;       /* EURO-ISDN Default */
83 module_param(protocol, int, 0);
84 MODULE_LICENSE("GPL");
85
86 // ----------------------------------------------------------------------
87
88 #define  AVM_INDEX              0x04
89 #define  AVM_DATA               0x10
90
91 #define  AVM_IDX_HDLC_1         0x00
92 #define  AVM_IDX_HDLC_2         0x01
93 #define  AVM_IDX_ISAC_FIFO      0x02
94 #define  AVM_IDX_ISAC_REG_LOW   0x04
95 #define  AVM_IDX_ISAC_REG_HIGH  0x06
96
97 #define  AVM_STATUS0            0x02
98
99 #define  AVM_STATUS0_IRQ_ISAC   0x01
100 #define  AVM_STATUS0_IRQ_HDLC   0x02
101 #define  AVM_STATUS0_IRQ_TIMER  0x04
102 #define  AVM_STATUS0_IRQ_MASK   0x07
103
104 #define  AVM_STATUS0_RESET      0x01
105 #define  AVM_STATUS0_DIS_TIMER  0x02
106 #define  AVM_STATUS0_RES_TIMER  0x04
107 #define  AVM_STATUS0_ENA_IRQ    0x08
108 #define  AVM_STATUS0_TESTBIT    0x10
109
110 #define  AVM_STATUS1            0x03
111 #define  AVM_STATUS1_ENA_IOM    0x80
112
113 #define  HDLC_FIFO              0x0
114 #define  HDLC_STATUS            0x4
115 #define  HDLC_CTRL              0x4
116
117 #define  HDLC_MODE_ITF_FLG      0x01
118 #define  HDLC_MODE_TRANS        0x02
119 #define  HDLC_MODE_CCR_7        0x04
120 #define  HDLC_MODE_CCR_16       0x08
121 #define  HDLC_MODE_TESTLOOP     0x80
122
123 #define  HDLC_INT_XPR           0x80
124 #define  HDLC_INT_XDU           0x40
125 #define  HDLC_INT_RPR           0x20
126 #define  HDLC_INT_MASK          0xE0
127
128 #define  HDLC_STAT_RME          0x01
129 #define  HDLC_STAT_RDO          0x10
130 #define  HDLC_STAT_CRCVFRRAB    0x0E
131 #define  HDLC_STAT_CRCVFR       0x06
132 #define  HDLC_STAT_RML_MASK     0xff00
133
134 #define  HDLC_CMD_XRS           0x80
135 #define  HDLC_CMD_XME           0x01
136 #define  HDLC_CMD_RRS           0x20
137 #define  HDLC_CMD_XML_MASK      0xff00
138
139 #define  AVM_HDLC_FIFO_1        0x10
140 #define  AVM_HDLC_FIFO_2        0x18
141
142 #define  AVM_HDLC_STATUS_1      0x14
143 #define  AVM_HDLC_STATUS_2      0x1c
144
145 #define  AVM_ISACSX_INDEX       0x04
146 #define  AVM_ISACSX_DATA        0x08
147
148 // ----------------------------------------------------------------------
149 // Fritz!PCI
150
151 static unsigned char fcpci_read_isac(struct isac *isac, unsigned char offset)
152 {
153         struct fritz_adapter *adapter = isac->priv;
154         unsigned char idx = (offset > 0x2f) ? 
155                 AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
156         unsigned char val;
157         unsigned long flags;
158
159         spin_lock_irqsave(&adapter->hw_lock, flags);
160         outb(idx, adapter->io + AVM_INDEX);
161         val = inb(adapter->io + AVM_DATA + (offset & 0xf));
162         spin_unlock_irqrestore(&adapter->hw_lock, flags);
163         DBG(0x1000, " port %#x, value %#x",
164             offset, val);
165         return val;
166 }
167
168 static void fcpci_write_isac(struct isac *isac, unsigned char offset,
169                              unsigned char value)
170 {
171         struct fritz_adapter *adapter = isac->priv;
172         unsigned char idx = (offset > 0x2f) ? 
173                 AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
174         unsigned long flags;
175
176         DBG(0x1000, " port %#x, value %#x",
177             offset, value);
178         spin_lock_irqsave(&adapter->hw_lock, flags);
179         outb(idx, adapter->io + AVM_INDEX);
180         outb(value, adapter->io + AVM_DATA + (offset & 0xf));
181         spin_unlock_irqrestore(&adapter->hw_lock, flags);
182 }
183
184 static void fcpci_read_isac_fifo(struct isac *isac, unsigned char * data, 
185                                  int size)
186 {
187         struct fritz_adapter *adapter = isac->priv;
188         unsigned long flags;
189
190         spin_lock_irqsave(&adapter->hw_lock, flags);
191         outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
192         insb(adapter->io + AVM_DATA, data, size);
193         spin_unlock_irqrestore(&adapter->hw_lock, flags);
194 }
195
196 static void fcpci_write_isac_fifo(struct isac *isac, unsigned char * data, 
197                                   int size)
198 {
199         struct fritz_adapter *adapter = isac->priv;
200         unsigned long flags;
201
202         spin_lock_irqsave(&adapter->hw_lock, flags);
203         outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
204         outsb(adapter->io + AVM_DATA, data, size);
205         spin_unlock_irqrestore(&adapter->hw_lock, flags);
206 }
207
208 static u32 fcpci_read_hdlc_status(struct fritz_adapter *adapter, int nr)
209 {
210         u32 val;
211         int idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
212         unsigned long flags;
213
214         spin_lock_irqsave(&adapter->hw_lock, flags);
215         outl(idx, adapter->io + AVM_INDEX);
216         val = inl(adapter->io + AVM_DATA + HDLC_STATUS);
217         spin_unlock_irqrestore(&adapter->hw_lock, flags);
218         return val;
219 }
220
221 static void __fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
222 {
223         struct fritz_adapter *adapter = bcs->adapter;
224         int idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
225
226         DBG(0x40, "hdlc %c wr%x ctrl %x",
227             'A' + bcs->channel, which, bcs->ctrl.ctrl);
228
229         outl(idx, adapter->io + AVM_INDEX);
230         outl(bcs->ctrl.ctrl, adapter->io + AVM_DATA + HDLC_CTRL);
231 }
232
233 static void fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
234 {
235         struct fritz_adapter *adapter = bcs->adapter;
236         unsigned long flags;
237
238         spin_lock_irqsave(&adapter->hw_lock, flags);
239         __fcpci_write_ctrl(bcs, which);
240         spin_unlock_irqrestore(&adapter->hw_lock, flags);
241 }
242
243 // ----------------------------------------------------------------------
244 // Fritz!PCI v2
245
246 static unsigned char fcpci2_read_isac(struct isac *isac, unsigned char offset)
247 {
248         struct fritz_adapter *adapter = isac->priv;
249         unsigned char val;
250         unsigned long flags;
251
252         spin_lock_irqsave(&adapter->hw_lock, flags);
253         outl(offset, adapter->io + AVM_ISACSX_INDEX);
254         val = inl(adapter->io + AVM_ISACSX_DATA);
255         spin_unlock_irqrestore(&adapter->hw_lock, flags);
256         DBG(0x1000, " port %#x, value %#x",
257             offset, val);
258
259         return val;
260 }
261
262 static void fcpci2_write_isac(struct isac *isac, unsigned char offset, 
263                               unsigned char value)
264 {
265         struct fritz_adapter *adapter = isac->priv;
266         unsigned long flags;
267
268         DBG(0x1000, " port %#x, value %#x",
269             offset, value);
270         spin_lock_irqsave(&adapter->hw_lock, flags);
271         outl(offset, adapter->io + AVM_ISACSX_INDEX);
272         outl(value, adapter->io + AVM_ISACSX_DATA);
273         spin_unlock_irqrestore(&adapter->hw_lock, flags);
274 }
275
276 static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char * data, 
277                                   int size)
278 {
279         struct fritz_adapter *adapter = isac->priv;
280         int i;
281         unsigned long flags;
282
283         spin_lock_irqsave(&adapter->hw_lock, flags);
284         outl(0, adapter->io + AVM_ISACSX_INDEX);
285         for (i = 0; i < size; i++)
286                 data[i] = inl(adapter->io + AVM_ISACSX_DATA);
287         spin_unlock_irqrestore(&adapter->hw_lock, flags);
288 }
289
290 static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char * data, 
291                                    int size)
292 {
293         struct fritz_adapter *adapter = isac->priv;
294         int i;
295         unsigned long flags;
296
297         spin_lock_irqsave(&adapter->hw_lock, flags);
298         outl(0, adapter->io + AVM_ISACSX_INDEX);
299         for (i = 0; i < size; i++)
300                 outl(data[i], adapter->io + AVM_ISACSX_DATA);
301         spin_unlock_irqrestore(&adapter->hw_lock, flags);
302 }
303
304 static u32 fcpci2_read_hdlc_status(struct fritz_adapter *adapter, int nr)
305 {
306         int offset = nr ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
307
308         return inl(adapter->io + offset);
309 }
310
311 static void fcpci2_write_ctrl(struct fritz_bcs *bcs, int which)
312 {
313         struct fritz_adapter *adapter = bcs->adapter;
314         int offset = bcs->channel ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
315
316         DBG(0x40, "hdlc %c wr%x ctrl %x",
317             'A' + bcs->channel, which, bcs->ctrl.ctrl);
318
319         outl(bcs->ctrl.ctrl, adapter->io + offset);
320 }
321
322 // ----------------------------------------------------------------------
323 // Fritz!PnP (ISAC access as for Fritz!PCI)
324
325 static u32 fcpnp_read_hdlc_status(struct fritz_adapter *adapter, int nr)
326 {
327         unsigned char idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
328         u32 val;
329         unsigned long flags;
330
331         spin_lock_irqsave(&adapter->hw_lock, flags);
332         outb(idx, adapter->io + AVM_INDEX);
333         val = inb(adapter->io + AVM_DATA + HDLC_STATUS);
334         if (val & HDLC_INT_RPR)
335                 val |= inb(adapter->io + AVM_DATA + HDLC_STATUS + 1) << 8;
336         spin_unlock_irqrestore(&adapter->hw_lock, flags);
337         return val;
338 }
339
340 static void __fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
341 {
342         struct fritz_adapter *adapter = bcs->adapter;
343         unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
344
345         DBG(0x40, "hdlc %c wr%x ctrl %x",
346             'A' + bcs->channel, which, bcs->ctrl.ctrl);
347
348         outb(idx, adapter->io + AVM_INDEX);
349         if (which & 4)
350                 outb(bcs->ctrl.sr.mode, 
351                      adapter->io + AVM_DATA + HDLC_STATUS + 2);
352         if (which & 2)
353                 outb(bcs->ctrl.sr.xml, 
354                      adapter->io + AVM_DATA + HDLC_STATUS + 1);
355         if (which & 1)
356                 outb(bcs->ctrl.sr.cmd,
357                      adapter->io + AVM_DATA + HDLC_STATUS + 0);
358 }
359
360 static void fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
361 {
362         struct fritz_adapter *adapter = bcs->adapter;
363         unsigned long flags;
364
365         spin_lock_irqsave(&adapter->hw_lock, flags);
366         __fcpnp_write_ctrl(bcs, which);
367         spin_unlock_irqrestore(&adapter->hw_lock, flags);
368 }
369
370 // ----------------------------------------------------------------------
371
372 static inline void B_L1L2(struct fritz_bcs *bcs, int pr, void *arg)
373 {
374         struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if;
375
376         DBG(2, "pr %#x", pr);
377         ifc->l1l2(ifc, pr, arg);
378 }
379
380 static void hdlc_fill_fifo(struct fritz_bcs *bcs)
381 {
382         struct fritz_adapter *adapter = bcs->adapter;
383         struct sk_buff *skb = bcs->tx_skb;
384         int count;
385         unsigned long flags;
386         unsigned char *p;
387
388         DBG(0x40, "hdlc_fill_fifo");
389
390         BUG_ON(skb->len == 0);
391
392         bcs->ctrl.sr.cmd &= ~HDLC_CMD_XME;
393         if (bcs->tx_skb->len > bcs->fifo_size) {
394                 count = bcs->fifo_size;
395         } else {
396                 count = bcs->tx_skb->len;
397                 if (bcs->mode != L1_MODE_TRANS)
398                         bcs->ctrl.sr.cmd |= HDLC_CMD_XME;
399         }
400         DBG(0x40, "hdlc_fill_fifo %d/%d", count, bcs->tx_skb->len);
401         p = bcs->tx_skb->data;
402         skb_pull(bcs->tx_skb, count);
403         bcs->tx_cnt += count;
404         bcs->ctrl.sr.xml = ((count == bcs->fifo_size) ? 0 : count);
405
406         switch (adapter->type) {
407         case AVM_FRITZ_PCI:
408                 spin_lock_irqsave(&adapter->hw_lock, flags);
409                 // sets the correct AVM_INDEX, too
410                 __fcpci_write_ctrl(bcs, 3);
411                 outsl(adapter->io + AVM_DATA + HDLC_FIFO,
412                       p, (count + 3) / 4);
413                 spin_unlock_irqrestore(&adapter->hw_lock, flags);
414                 break;
415         case AVM_FRITZ_PCIV2:
416                 fcpci2_write_ctrl(bcs, 3);
417                 outsl(adapter->io + 
418                       (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
419                       p, (count + 3) / 4);
420                 break;
421         case AVM_FRITZ_PNP:
422                 spin_lock_irqsave(&adapter->hw_lock, flags);
423                 // sets the correct AVM_INDEX, too
424                 __fcpnp_write_ctrl(bcs, 3);
425                 outsb(adapter->io + AVM_DATA, p, count);
426                 spin_unlock_irqrestore(&adapter->hw_lock, flags);
427                 break;
428         }
429 }
430
431 static inline void hdlc_empty_fifo(struct fritz_bcs *bcs, int count)
432 {
433         struct fritz_adapter *adapter = bcs->adapter;
434         unsigned char *p;
435         unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
436
437         DBG(0x10, "hdlc_empty_fifo %d", count);
438         if (bcs->rcvidx + count > HSCX_BUFMAX) {
439                 DBG(0x10, "hdlc_empty_fifo: incoming packet too large");
440                 return;
441         }
442         p = bcs->rcvbuf + bcs->rcvidx;
443         bcs->rcvidx += count;
444         switch (adapter->type) {
445         case AVM_FRITZ_PCI:
446                 spin_lock(&adapter->hw_lock);
447                 outl(idx, adapter->io + AVM_INDEX);
448                 insl(adapter->io + AVM_DATA + HDLC_FIFO, 
449                      p, (count + 3) / 4);
450                 spin_unlock(&adapter->hw_lock);
451                 break;
452         case AVM_FRITZ_PCIV2:
453                 insl(adapter->io + 
454                      (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
455                      p, (count + 3) / 4);
456                 break;
457         case AVM_FRITZ_PNP:
458                 spin_lock(&adapter->hw_lock);
459                 outb(idx, adapter->io + AVM_INDEX);
460                 insb(adapter->io + AVM_DATA, p, count);
461                 spin_unlock(&adapter->hw_lock);
462                 break;
463         }
464 }
465
466 static inline void hdlc_rpr_irq(struct fritz_bcs *bcs, u32 stat)
467 {
468         struct fritz_adapter *adapter = bcs->adapter;
469         struct sk_buff *skb;
470         int len;
471
472         if (stat & HDLC_STAT_RDO) {
473                 DBG(0x10, "RDO");
474                 bcs->ctrl.sr.xml = 0;
475                 bcs->ctrl.sr.cmd |= HDLC_CMD_RRS;
476                 adapter->write_ctrl(bcs, 1);
477                 bcs->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
478                 adapter->write_ctrl(bcs, 1);
479                 bcs->rcvidx = 0;
480                 return;
481         }
482
483         len = (stat & HDLC_STAT_RML_MASK) >> 8;
484         if (len == 0)
485                 len = bcs->fifo_size;
486
487         hdlc_empty_fifo(bcs, len);
488
489         if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
490                 if (((stat & HDLC_STAT_CRCVFRRAB)== HDLC_STAT_CRCVFR) ||
491                     (bcs->mode == L1_MODE_TRANS)) {
492                         skb = dev_alloc_skb(bcs->rcvidx);
493                         if (!skb) {
494                                 printk(KERN_WARNING "HDLC: receive out of memory\n");
495                         } else {
496                                 memcpy(skb_put(skb, bcs->rcvidx), bcs->rcvbuf,
497                                        bcs->rcvidx);
498                                 DBG_SKB(1, skb);
499                                 B_L1L2(bcs, PH_DATA | INDICATION, skb);
500                         }
501                         bcs->rcvidx = 0;
502                 } else {
503                         DBG(0x10, "ch%d invalid frame %#x",
504                             bcs->channel, stat);
505                         bcs->rcvidx = 0;
506                 }
507         }
508 }
509
510 static inline void hdlc_xdu_irq(struct fritz_bcs *bcs)
511 {
512         struct fritz_adapter *adapter = bcs->adapter;
513         
514
515         /* Here we lost an TX interrupt, so
516          * restart transmitting the whole frame.
517          */
518         bcs->ctrl.sr.xml = 0;
519         bcs->ctrl.sr.cmd |= HDLC_CMD_XRS;
520         adapter->write_ctrl(bcs, 1);
521         bcs->ctrl.sr.cmd &= ~HDLC_CMD_XRS;
522
523         if (!bcs->tx_skb) {
524                 DBG(0x10, "XDU without skb");
525                 adapter->write_ctrl(bcs, 1);
526                 return;
527         }
528         /* only hdlc restarts the frame, transparent mode must continue */
529         if (bcs->mode == L1_MODE_HDLC) {
530                 skb_push(bcs->tx_skb, bcs->tx_cnt);
531                 bcs->tx_cnt = 0;
532         }
533 }
534
535 static inline void hdlc_xpr_irq(struct fritz_bcs *bcs)
536 {
537         struct sk_buff *skb;
538
539         skb = bcs->tx_skb;
540         if (!skb)
541                 return;
542
543         if (skb->len) {
544                 hdlc_fill_fifo(bcs);
545                 return;
546         }
547         bcs->tx_cnt = 0;
548         bcs->tx_skb = NULL;
549         B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long)skb->truesize);
550         dev_kfree_skb_irq(skb);
551 }
552
553 static void hdlc_irq_one(struct fritz_bcs *bcs, u32 stat)
554 {
555         DBG(0x10, "ch%d stat %#x", bcs->channel, stat);
556         if (stat & HDLC_INT_RPR) {
557                 DBG(0x10, "RPR");
558                 hdlc_rpr_irq(bcs, stat);
559         }
560         if (stat & HDLC_INT_XDU) {
561                 DBG(0x10, "XDU");
562                 hdlc_xdu_irq(bcs);
563                 hdlc_xpr_irq(bcs);
564                 return;
565         }
566         if (stat & HDLC_INT_XPR) {
567                 DBG(0x10, "XPR");
568                 hdlc_xpr_irq(bcs);
569         }
570 }
571
572 static inline void hdlc_irq(struct fritz_adapter *adapter)
573 {
574         int nr;
575         u32 stat;
576
577         for (nr = 0; nr < 2; nr++) {
578                 stat = adapter->read_hdlc_status(adapter, nr);
579                 DBG(0x10, "HDLC %c stat %#x", 'A' + nr, stat);
580                 if (stat & HDLC_INT_MASK)
581                         hdlc_irq_one(&adapter->bcs[nr], stat);
582         }
583 }
584
585 static void modehdlc(struct fritz_bcs *bcs, int mode)
586 {
587         struct fritz_adapter *adapter = bcs->adapter;
588         
589         DBG(0x40, "hdlc %c mode %d --> %d",
590             'A' + bcs->channel, bcs->mode, mode);
591
592         if (bcs->mode == mode)
593                 return;
594
595         bcs->fifo_size = 32;
596         bcs->ctrl.ctrl = 0;
597         bcs->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
598         switch (mode) {
599         case L1_MODE_NULL:
600                 bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
601                 adapter->write_ctrl(bcs, 5);
602                 break;
603         case L1_MODE_TRANS:
604         case L1_MODE_HDLC:
605                 bcs->rcvidx = 0;
606                 bcs->tx_cnt = 0;
607                 bcs->tx_skb = NULL;
608                 if (mode == L1_MODE_TRANS) {
609                         bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
610                 } else {
611                         bcs->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
612                 }
613                 adapter->write_ctrl(bcs, 5);
614                 bcs->ctrl.sr.cmd = HDLC_CMD_XRS;
615                 adapter->write_ctrl(bcs, 1);
616                 bcs->ctrl.sr.cmd = 0;
617                 break;
618         }
619         bcs->mode = mode;
620 }
621
622 static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
623 {
624         struct fritz_bcs *bcs = ifc->priv;
625         struct sk_buff *skb = arg;
626         int mode;
627
628         DBG(0x10, "pr %#x", pr);
629
630         switch (pr) {
631         case PH_DATA | REQUEST:
632                 BUG_ON(bcs->tx_skb);
633                 bcs->tx_skb = skb;
634                 DBG_SKB(1, skb);
635                 hdlc_fill_fifo(bcs);
636                 break;
637         case PH_ACTIVATE | REQUEST:
638                 mode = (long) arg;
639                 DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
640                 modehdlc(bcs, mode);
641                 B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
642                 break;
643         case PH_DEACTIVATE | REQUEST:
644                 DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
645                 modehdlc(bcs, L1_MODE_NULL);
646                 B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL);
647                 break;
648         }
649 }
650
651 // ----------------------------------------------------------------------
652
653 static irqreturn_t
654 fcpci2_irq(int intno, void *dev)
655 {
656         struct fritz_adapter *adapter = dev;
657         unsigned char val;
658
659         val = inb(adapter->io + AVM_STATUS0);
660         if (!(val & AVM_STATUS0_IRQ_MASK))
661                 /* hopefully a shared  IRQ reqest */
662                 return IRQ_NONE;
663         DBG(2, "STATUS0 %#x", val);
664         if (val & AVM_STATUS0_IRQ_ISAC)
665                 isacsx_irq(&adapter->isac);
666         if (val & AVM_STATUS0_IRQ_HDLC)
667                 hdlc_irq(adapter);
668         if (val & AVM_STATUS0_IRQ_ISAC)
669                 isacsx_irq(&adapter->isac);
670         return IRQ_HANDLED;
671 }
672
673 static irqreturn_t
674 fcpci_irq(int intno, void *dev)
675 {
676         struct fritz_adapter *adapter = dev;
677         unsigned char sval;
678
679         sval = inb(adapter->io + 2);
680         if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK)
681                 /* possibly a shared  IRQ reqest */
682                 return IRQ_NONE;
683         DBG(2, "sval %#x", sval);
684         if (!(sval & AVM_STATUS0_IRQ_ISAC))
685                 isac_irq(&adapter->isac);
686
687         if (!(sval & AVM_STATUS0_IRQ_HDLC))
688                 hdlc_irq(adapter);
689         return IRQ_HANDLED;
690 }
691
692 // ----------------------------------------------------------------------
693
694 static inline void fcpci2_init(struct fritz_adapter *adapter)
695 {
696         outb(AVM_STATUS0_RES_TIMER, adapter->io + AVM_STATUS0);
697         outb(AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
698
699 }
700
701 static inline void fcpci_init(struct fritz_adapter *adapter)
702 {
703         outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | 
704              AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
705
706         outb(AVM_STATUS1_ENA_IOM | adapter->irq, 
707              adapter->io + AVM_STATUS1);
708         mdelay(10);
709 }
710
711 // ----------------------------------------------------------------------
712
713 static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
714 {
715         u32 val = 0;
716         int retval;
717
718         DBG(1,"");
719
720         isac_init(&adapter->isac); // FIXME is this okay now
721
722         retval = -EBUSY;
723         if (!request_region(adapter->io, 32, "fcpcipnp"))
724                 goto err;
725
726         switch (adapter->type) {
727         case AVM_FRITZ_PCIV2:
728         case AVM_FRITZ_PCI:
729                 val = inl(adapter->io);
730                 break;
731         case AVM_FRITZ_PNP:
732                 val = inb(adapter->io);
733                 val |= inb(adapter->io + 1) << 8;
734                 break;
735         }
736
737         DBG(1, "stat %#x Class %X Rev %d",
738             val, val & 0xff, (val>>8) & 0xff);
739
740         spin_lock_init(&adapter->hw_lock);
741         adapter->isac.priv = adapter;
742         switch (adapter->type) {
743         case AVM_FRITZ_PCIV2:
744                 adapter->isac.read_isac       = &fcpci2_read_isac;
745                 adapter->isac.write_isac      = &fcpci2_write_isac;
746                 adapter->isac.read_isac_fifo  = &fcpci2_read_isac_fifo;
747                 adapter->isac.write_isac_fifo = &fcpci2_write_isac_fifo;
748
749                 adapter->read_hdlc_status     = &fcpci2_read_hdlc_status;
750                 adapter->write_ctrl           = &fcpci2_write_ctrl;
751                 break;
752         case AVM_FRITZ_PCI:
753                 adapter->isac.read_isac       = &fcpci_read_isac;
754                 adapter->isac.write_isac      = &fcpci_write_isac;
755                 adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
756                 adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
757
758                 adapter->read_hdlc_status     = &fcpci_read_hdlc_status;
759                 adapter->write_ctrl           = &fcpci_write_ctrl;
760                 break;
761         case AVM_FRITZ_PNP:
762                 adapter->isac.read_isac       = &fcpci_read_isac;
763                 adapter->isac.write_isac      = &fcpci_write_isac;
764                 adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
765                 adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
766
767                 adapter->read_hdlc_status     = &fcpnp_read_hdlc_status;
768                 adapter->write_ctrl           = &fcpnp_write_ctrl;
769                 break;
770         }
771
772         // Reset
773         outb(0, adapter->io + AVM_STATUS0);
774         mdelay(10);
775         outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0);
776         mdelay(10);
777         outb(0, adapter->io + AVM_STATUS0);
778         mdelay(10);
779
780         switch (adapter->type) {
781         case AVM_FRITZ_PCIV2:
782                 retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED,
783                                      "fcpcipnp", adapter);
784                 break;
785         case AVM_FRITZ_PCI:
786                 retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED,
787                                      "fcpcipnp", adapter);
788                 break;
789         case AVM_FRITZ_PNP:
790                 retval = request_irq(adapter->irq, fcpci_irq, 0,
791                                      "fcpcipnp", adapter);
792                 break;
793         }
794         if (retval)
795                 goto err_region;
796
797         switch (adapter->type) {
798         case AVM_FRITZ_PCIV2:
799                 fcpci2_init(adapter);
800                 isacsx_setup(&adapter->isac);
801                 break;
802         case AVM_FRITZ_PCI:
803         case AVM_FRITZ_PNP:
804                 fcpci_init(adapter);
805                 isac_setup(&adapter->isac);
806                 break;
807         }
808         val = adapter->read_hdlc_status(adapter, 0);
809         DBG(0x20, "HDLC A STA %x", val);
810         val = adapter->read_hdlc_status(adapter, 1);
811         DBG(0x20, "HDLC B STA %x", val);
812
813         adapter->bcs[0].mode = -1;
814         adapter->bcs[1].mode = -1;
815         modehdlc(&adapter->bcs[0], L1_MODE_NULL);
816         modehdlc(&adapter->bcs[1], L1_MODE_NULL);
817
818         return 0;
819
820  err_region:
821         release_region(adapter->io, 32);
822  err:
823         return retval;
824 }
825
826 static void __devexit fcpcipnp_release(struct fritz_adapter *adapter)
827 {
828         DBG(1,"");
829
830         outb(0, adapter->io + AVM_STATUS0);
831         free_irq(adapter->irq, adapter);
832         release_region(adapter->io, 32);
833 }
834
835 // ----------------------------------------------------------------------
836
837 static struct fritz_adapter * __devinit 
838 new_adapter(void)
839 {
840         struct fritz_adapter *adapter;
841         struct hisax_b_if *b_if[2];
842         int i;
843
844         adapter = kzalloc(sizeof(struct fritz_adapter), GFP_KERNEL);
845         if (!adapter)
846                 return NULL;
847
848         adapter->isac.hisax_d_if.owner = THIS_MODULE;
849         adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;
850         adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;
851         
852         for (i = 0; i < 2; i++) {
853                 adapter->bcs[i].adapter = adapter;
854                 adapter->bcs[i].channel = i;
855                 adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
856                 adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1;
857         }
858
859         for (i = 0; i < 2; i++)
860                 b_if[i] = &adapter->bcs[i].b_if;
861
862         if (hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp",
863                         protocol) != 0) {
864                 kfree(adapter);
865                 adapter = NULL;
866         }
867
868         return adapter;
869 }
870
871 static void delete_adapter(struct fritz_adapter *adapter)
872 {
873         hisax_unregister(&adapter->isac.hisax_d_if);
874         kfree(adapter);
875 }
876
877 static int __devinit fcpci_probe(struct pci_dev *pdev,
878                                  const struct pci_device_id *ent)
879 {
880         struct fritz_adapter *adapter;
881         int retval;
882
883         retval = -ENOMEM;
884         adapter = new_adapter();
885         if (!adapter)
886                 goto err;
887
888         pci_set_drvdata(pdev, adapter);
889
890         if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2) 
891                 adapter->type = AVM_FRITZ_PCIV2;
892         else
893                 adapter->type = AVM_FRITZ_PCI;
894
895         retval = pci_enable_device(pdev);
896         if (retval)
897                 goto err_free;
898
899         adapter->io = pci_resource_start(pdev, 1);
900         adapter->irq = pdev->irq;
901
902         printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %s\n",
903                (char *) ent->driver_data, pci_name(pdev));
904
905         retval = fcpcipnp_setup(adapter);
906         if (retval)
907                 goto err_free;
908
909         return 0;
910         
911  err_free:
912         delete_adapter(adapter);
913  err:
914         return retval;
915 }
916
917 #ifdef __ISAPNP__
918 static int __devinit fcpnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
919 {
920         struct fritz_adapter *adapter;
921         int retval;
922
923         if (!pdev)
924                 return(-ENODEV);
925
926         retval = -ENOMEM;
927         adapter = new_adapter();
928         if (!adapter)
929                 goto err;
930
931         pnp_set_drvdata(pdev, adapter);
932
933         adapter->type = AVM_FRITZ_PNP;
934
935         pnp_disable_dev(pdev);
936         retval = pnp_activate_dev(pdev);
937         if (retval < 0) {
938                 printk(KERN_WARNING "%s: pnp_activate_dev(%s) ret(%d)\n", __FUNCTION__,
939                         (char *)dev_id->driver_data, retval);
940                 goto err_free;
941         }
942         adapter->io = pnp_port_start(pdev, 0);
943         adapter->irq = pnp_irq(pdev, 0);
944
945         printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %d\n",
946                (char *) dev_id->driver_data, adapter->io, adapter->irq);
947
948         retval = fcpcipnp_setup(adapter);
949         if (retval)
950                 goto err_free;
951
952         return 0;
953         
954  err_free:
955         delete_adapter(adapter);
956  err:
957         return retval;
958 }
959
960 static void __devexit fcpnp_remove(struct pnp_dev *pdev)
961 {
962         struct fritz_adapter *adapter = pnp_get_drvdata(pdev);
963
964         if (adapter) {
965                 fcpcipnp_release(adapter);
966                 delete_adapter(adapter);
967         }
968         pnp_disable_dev(pdev);
969 }
970
971 static struct pnp_driver fcpnp_driver = {
972         .name           = "fcpnp",
973         .probe          = fcpnp_probe,
974         .remove         = __devexit_p(fcpnp_remove),
975         .id_table       = fcpnp_ids,
976 };
977 #endif
978
979 static void __devexit fcpci_remove(struct pci_dev *pdev)
980 {
981         struct fritz_adapter *adapter = pci_get_drvdata(pdev);
982
983         fcpcipnp_release(adapter);
984         pci_disable_device(pdev);
985         delete_adapter(adapter);
986 }
987
988 static struct pci_driver fcpci_driver = {
989         .name           = "fcpci",
990         .probe          = fcpci_probe,
991         .remove         = __devexit_p(fcpci_remove),
992         .id_table       = fcpci_ids,
993 };
994
995 static int __init hisax_fcpcipnp_init(void)
996 {
997         int retval;
998
999         printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n");
1000
1001         retval = pci_register_driver(&fcpci_driver);
1002         if (retval)
1003                 return retval;
1004 #ifdef __ISAPNP__
1005         retval = pnp_register_driver(&fcpnp_driver);
1006         if (retval < 0) {
1007                 pci_unregister_driver(&fcpci_driver);
1008                 return retval;
1009         }
1010 #endif
1011         return 0;
1012 }
1013
1014 static void __exit hisax_fcpcipnp_exit(void)
1015 {
1016 #ifdef __ISAPNP__
1017         pnp_unregister_driver(&fcpnp_driver);
1018 #endif
1019         pci_unregister_driver(&fcpci_driver);
1020 }
1021
1022 module_init(hisax_fcpcipnp_init);
1023 module_exit(hisax_fcpcipnp_exit);