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
45static int debug = 0;
46/* static int hdlcfifosize = 32; */
47module_param(debug, int, 0);
48/* module_param(hdlcfifosize, int, 0); */
49#endif
50
51MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
52MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver");
53
54static 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
69MODULE_DEVICE_TABLE(pci, fcpci_ids);
70
71#ifdef __ISAPNP__
72static struct pnp_device_id fcpnp_ids[] __devinitdata = {
73	{
74		.id		= "AVM0900",
75		.driver_data	= (unsigned long) "Fritz!Card PnP",
76	},
77};
78
79MODULE_DEVICE_TABLE(isapnp, fcpnp_ids);
80#endif
81
82static int protocol = 2;       /* EURO-ISDN Default */
83module_param(protocol, int, 0);
84MODULE_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
151static 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
168static 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
184static 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
196static 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
208static 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
221static 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
233static 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
246static 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
262static 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
276static 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
290static 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
304static 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
311static 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
325static 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
340static 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
360static 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
372static 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
380static 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
431static 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
466static 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
510static 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
535static 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
553static 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
572static 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
585static 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
622static 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
653static irqreturn_t
654fcpci2_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
673static irqreturn_t
674fcpci_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
694static 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
701static 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
713static 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);
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		retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED,
729				     "fcpcipnp", adapter);
730		break;
731	case AVM_FRITZ_PCI:
732		retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED,
733				     "fcpcipnp", adapter);
734		break;
735	case AVM_FRITZ_PNP:
736		retval = request_irq(adapter->irq, fcpci_irq, 0,
737				     "fcpcipnp", adapter);
738		break;
739	}
740	if (retval)
741		goto err_region;
742
743	switch (adapter->type) {
744	case AVM_FRITZ_PCIV2:
745	case AVM_FRITZ_PCI:
746		val = inl(adapter->io);
747		break;
748	case AVM_FRITZ_PNP:
749		val = inb(adapter->io);
750		val |= inb(adapter->io + 1) << 8;
751		break;
752	}
753
754	DBG(1, "stat %#x Class %X Rev %d",
755	    val, val & 0xff, (val>>8) & 0xff);
756
757	spin_lock_init(&adapter->hw_lock);
758	adapter->isac.priv = adapter;
759	switch (adapter->type) {
760	case AVM_FRITZ_PCIV2:
761		adapter->isac.read_isac       = &fcpci2_read_isac;
762		adapter->isac.write_isac      = &fcpci2_write_isac;
763		adapter->isac.read_isac_fifo  = &fcpci2_read_isac_fifo;
764		adapter->isac.write_isac_fifo = &fcpci2_write_isac_fifo;
765
766		adapter->read_hdlc_status     = &fcpci2_read_hdlc_status;
767		adapter->write_ctrl           = &fcpci2_write_ctrl;
768		break;
769	case AVM_FRITZ_PCI:
770		adapter->isac.read_isac       = &fcpci_read_isac;
771		adapter->isac.write_isac      = &fcpci_write_isac;
772		adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
773		adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
774
775		adapter->read_hdlc_status     = &fcpci_read_hdlc_status;
776		adapter->write_ctrl           = &fcpci_write_ctrl;
777		break;
778	case AVM_FRITZ_PNP:
779		adapter->isac.read_isac       = &fcpci_read_isac;
780		adapter->isac.write_isac      = &fcpci_write_isac;
781		adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
782		adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
783
784		adapter->read_hdlc_status     = &fcpnp_read_hdlc_status;
785		adapter->write_ctrl           = &fcpnp_write_ctrl;
786		break;
787	}
788
789	// Reset
790	outb(0, adapter->io + AVM_STATUS0);
791	mdelay(10);
792	outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0);
793	mdelay(10);
794	outb(0, adapter->io + AVM_STATUS0);
795	mdelay(10);
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
826static 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
837static struct fritz_adapter * __devinit
838new_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
871static void delete_adapter(struct fritz_adapter *adapter)
872{
873	hisax_unregister(&adapter->isac.hisax_d_if);
874	kfree(adapter);
875}
876
877static 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__
918static 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
960static 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
971static 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
979static 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
988static 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
995static 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
1014static 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
1022module_init(hisax_fcpcipnp_init);
1023module_exit(hisax_fcpcipnp_exit);
1024