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