• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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 				memcpy(skb_put(skb, bcs->rcvidx), bcs->rcvbuf,
499 				       bcs->rcvidx);
500 				DBG_SKB(1, skb);
501 				B_L1L2(bcs, PH_DATA | INDICATION, skb);
502 			}
503 			bcs->rcvidx = 0;
504 		} else {
505 			DBG(0x10, "ch%d invalid frame %#x",
506 			    bcs->channel, stat);
507 			bcs->rcvidx = 0;
508 		}
509 	}
510 }
511 
hdlc_xdu_irq(struct fritz_bcs * bcs)512 static inline void hdlc_xdu_irq(struct fritz_bcs *bcs)
513 {
514 	struct fritz_adapter *adapter = bcs->adapter;
515 
516 
517 	/* Here we lost an TX interrupt, so
518 	 * restart transmitting the whole frame.
519 	 */
520 	bcs->ctrl.sr.xml = 0;
521 	bcs->ctrl.sr.cmd |= HDLC_CMD_XRS;
522 	adapter->write_ctrl(bcs, 1);
523 	bcs->ctrl.sr.cmd &= ~HDLC_CMD_XRS;
524 
525 	if (!bcs->tx_skb) {
526 		DBG(0x10, "XDU without skb");
527 		adapter->write_ctrl(bcs, 1);
528 		return;
529 	}
530 	/* only hdlc restarts the frame, transparent mode must continue */
531 	if (bcs->mode == L1_MODE_HDLC) {
532 		skb_push(bcs->tx_skb, bcs->tx_cnt);
533 		bcs->tx_cnt = 0;
534 	}
535 }
536 
hdlc_xpr_irq(struct fritz_bcs * bcs)537 static inline void hdlc_xpr_irq(struct fritz_bcs *bcs)
538 {
539 	struct sk_buff *skb;
540 
541 	skb = bcs->tx_skb;
542 	if (!skb)
543 		return;
544 
545 	if (skb->len) {
546 		hdlc_fill_fifo(bcs);
547 		return;
548 	}
549 	bcs->tx_cnt = 0;
550 	bcs->tx_skb = NULL;
551 	B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long)skb->truesize);
552 	dev_kfree_skb_irq(skb);
553 }
554 
hdlc_irq_one(struct fritz_bcs * bcs,u32 stat)555 static void hdlc_irq_one(struct fritz_bcs *bcs, u32 stat)
556 {
557 	DBG(0x10, "ch%d stat %#x", bcs->channel, stat);
558 	if (stat & HDLC_INT_RPR) {
559 		DBG(0x10, "RPR");
560 		hdlc_rpr_irq(bcs, stat);
561 	}
562 	if (stat & HDLC_INT_XDU) {
563 		DBG(0x10, "XDU");
564 		hdlc_xdu_irq(bcs);
565 		hdlc_xpr_irq(bcs);
566 		return;
567 	}
568 	if (stat & HDLC_INT_XPR) {
569 		DBG(0x10, "XPR");
570 		hdlc_xpr_irq(bcs);
571 	}
572 }
573 
hdlc_irq(struct fritz_adapter * adapter)574 static inline void hdlc_irq(struct fritz_adapter *adapter)
575 {
576 	int nr;
577 	u32 stat;
578 
579 	for (nr = 0; nr < 2; nr++) {
580 		stat = adapter->read_hdlc_status(adapter, nr);
581 		DBG(0x10, "HDLC %c stat %#x", 'A' + nr, stat);
582 		if (stat & HDLC_INT_MASK)
583 			hdlc_irq_one(&adapter->bcs[nr], stat);
584 	}
585 }
586 
modehdlc(struct fritz_bcs * bcs,int mode)587 static void modehdlc(struct fritz_bcs *bcs, int mode)
588 {
589 	struct fritz_adapter *adapter = bcs->adapter;
590 
591 	DBG(0x40, "hdlc %c mode %d --> %d",
592 	    'A' + bcs->channel, bcs->mode, mode);
593 
594 	if (bcs->mode == mode)
595 		return;
596 
597 	bcs->fifo_size = 32;
598 	bcs->ctrl.ctrl = 0;
599 	bcs->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
600 	switch (mode) {
601 	case L1_MODE_NULL:
602 		bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
603 		adapter->write_ctrl(bcs, 5);
604 		break;
605 	case L1_MODE_TRANS:
606 	case L1_MODE_HDLC:
607 		bcs->rcvidx = 0;
608 		bcs->tx_cnt = 0;
609 		bcs->tx_skb = NULL;
610 		if (mode == L1_MODE_TRANS) {
611 			bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
612 		} else {
613 			bcs->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
614 		}
615 		adapter->write_ctrl(bcs, 5);
616 		bcs->ctrl.sr.cmd = HDLC_CMD_XRS;
617 		adapter->write_ctrl(bcs, 1);
618 		bcs->ctrl.sr.cmd = 0;
619 		break;
620 	}
621 	bcs->mode = mode;
622 }
623 
fritz_b_l2l1(struct hisax_if * ifc,int pr,void * arg)624 static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
625 {
626 	struct fritz_bcs *bcs = ifc->priv;
627 	struct sk_buff *skb = arg;
628 	int mode;
629 
630 	DBG(0x10, "pr %#x", pr);
631 
632 	switch (pr) {
633 	case PH_DATA | REQUEST:
634 		BUG_ON(bcs->tx_skb);
635 		bcs->tx_skb = skb;
636 		DBG_SKB(1, skb);
637 		hdlc_fill_fifo(bcs);
638 		break;
639 	case PH_ACTIVATE | REQUEST:
640 		mode = (long) arg;
641 		DBG(4, "B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
642 		modehdlc(bcs, mode);
643 		B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
644 		break;
645 	case PH_DEACTIVATE | REQUEST:
646 		DBG(4, "B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
647 		modehdlc(bcs, L1_MODE_NULL);
648 		B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL);
649 		break;
650 	}
651 }
652 
653 // ----------------------------------------------------------------------
654 
655 static irqreturn_t
fcpci2_irq(int intno,void * dev)656 fcpci2_irq(int intno, void *dev)
657 {
658 	struct fritz_adapter *adapter = dev;
659 	unsigned char val;
660 
661 	val = inb(adapter->io + AVM_STATUS0);
662 	if (!(val & AVM_STATUS0_IRQ_MASK))
663 		/* hopefully a shared  IRQ reqest */
664 		return IRQ_NONE;
665 	DBG(2, "STATUS0 %#x", val);
666 	if (val & AVM_STATUS0_IRQ_ISAC)
667 		isacsx_irq(&adapter->isac);
668 	if (val & AVM_STATUS0_IRQ_HDLC)
669 		hdlc_irq(adapter);
670 	if (val & AVM_STATUS0_IRQ_ISAC)
671 		isacsx_irq(&adapter->isac);
672 	return IRQ_HANDLED;
673 }
674 
675 static irqreturn_t
fcpci_irq(int intno,void * dev)676 fcpci_irq(int intno, void *dev)
677 {
678 	struct fritz_adapter *adapter = dev;
679 	unsigned char sval;
680 
681 	sval = inb(adapter->io + 2);
682 	if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK)
683 		/* possibly a shared  IRQ reqest */
684 		return IRQ_NONE;
685 	DBG(2, "sval %#x", sval);
686 	if (!(sval & AVM_STATUS0_IRQ_ISAC))
687 		isac_irq(&adapter->isac);
688 
689 	if (!(sval & AVM_STATUS0_IRQ_HDLC))
690 		hdlc_irq(adapter);
691 	return IRQ_HANDLED;
692 }
693 
694 // ----------------------------------------------------------------------
695 
fcpci2_init(struct fritz_adapter * adapter)696 static inline void fcpci2_init(struct fritz_adapter *adapter)
697 {
698 	outb(AVM_STATUS0_RES_TIMER, adapter->io + AVM_STATUS0);
699 	outb(AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
700 
701 }
702 
fcpci_init(struct fritz_adapter * adapter)703 static inline void fcpci_init(struct fritz_adapter *adapter)
704 {
705 	outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
706 	     AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
707 
708 	outb(AVM_STATUS1_ENA_IOM | adapter->irq,
709 	     adapter->io + AVM_STATUS1);
710 	mdelay(10);
711 }
712 
713 // ----------------------------------------------------------------------
714 
fcpcipnp_setup(struct fritz_adapter * adapter)715 static int fcpcipnp_setup(struct fritz_adapter *adapter)
716 {
717 	u32 val = 0;
718 	int retval;
719 
720 	DBG(1, "");
721 
722 	isac_init(&adapter->isac); // FIXME is this okay now
723 
724 	retval = -EBUSY;
725 	if (!request_region(adapter->io, 32, "fcpcipnp"))
726 		goto err;
727 
728 	switch (adapter->type) {
729 	case AVM_FRITZ_PCIV2:
730 	case AVM_FRITZ_PCI:
731 		val = inl(adapter->io);
732 		break;
733 	case AVM_FRITZ_PNP:
734 		val = inb(adapter->io);
735 		val |= inb(adapter->io + 1) << 8;
736 		break;
737 	}
738 
739 	DBG(1, "stat %#x Class %X Rev %d",
740 	    val, val & 0xff, (val >> 8) & 0xff);
741 
742 	spin_lock_init(&adapter->hw_lock);
743 	adapter->isac.priv = adapter;
744 	switch (adapter->type) {
745 	case AVM_FRITZ_PCIV2:
746 		adapter->isac.read_isac       = &fcpci2_read_isac;
747 		adapter->isac.write_isac      = &fcpci2_write_isac;
748 		adapter->isac.read_isac_fifo  = &fcpci2_read_isac_fifo;
749 		adapter->isac.write_isac_fifo = &fcpci2_write_isac_fifo;
750 
751 		adapter->read_hdlc_status     = &fcpci2_read_hdlc_status;
752 		adapter->write_ctrl           = &fcpci2_write_ctrl;
753 		break;
754 	case AVM_FRITZ_PCI:
755 		adapter->isac.read_isac       = &fcpci_read_isac;
756 		adapter->isac.write_isac      = &fcpci_write_isac;
757 		adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
758 		adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
759 
760 		adapter->read_hdlc_status     = &fcpci_read_hdlc_status;
761 		adapter->write_ctrl           = &fcpci_write_ctrl;
762 		break;
763 	case AVM_FRITZ_PNP:
764 		adapter->isac.read_isac       = &fcpci_read_isac;
765 		adapter->isac.write_isac      = &fcpci_write_isac;
766 		adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
767 		adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
768 
769 		adapter->read_hdlc_status     = &fcpnp_read_hdlc_status;
770 		adapter->write_ctrl           = &fcpnp_write_ctrl;
771 		break;
772 	}
773 
774 	// Reset
775 	outb(0, adapter->io + AVM_STATUS0);
776 	mdelay(10);
777 	outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0);
778 	mdelay(10);
779 	outb(0, adapter->io + AVM_STATUS0);
780 	mdelay(10);
781 
782 	switch (adapter->type) {
783 	case AVM_FRITZ_PCIV2:
784 		retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED,
785 				     "fcpcipnp", adapter);
786 		break;
787 	case AVM_FRITZ_PCI:
788 		retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED,
789 				     "fcpcipnp", adapter);
790 		break;
791 	case AVM_FRITZ_PNP:
792 		retval = request_irq(adapter->irq, fcpci_irq, 0,
793 				     "fcpcipnp", adapter);
794 		break;
795 	}
796 	if (retval)
797 		goto err_region;
798 
799 	switch (adapter->type) {
800 	case AVM_FRITZ_PCIV2:
801 		fcpci2_init(adapter);
802 		isacsx_setup(&adapter->isac);
803 		break;
804 	case AVM_FRITZ_PCI:
805 	case AVM_FRITZ_PNP:
806 		fcpci_init(adapter);
807 		isac_setup(&adapter->isac);
808 		break;
809 	}
810 	val = adapter->read_hdlc_status(adapter, 0);
811 	DBG(0x20, "HDLC A STA %x", val);
812 	val = adapter->read_hdlc_status(adapter, 1);
813 	DBG(0x20, "HDLC B STA %x", val);
814 
815 	adapter->bcs[0].mode = -1;
816 	adapter->bcs[1].mode = -1;
817 	modehdlc(&adapter->bcs[0], L1_MODE_NULL);
818 	modehdlc(&adapter->bcs[1], L1_MODE_NULL);
819 
820 	return 0;
821 
822 err_region:
823 	release_region(adapter->io, 32);
824 err:
825 	return retval;
826 }
827 
fcpcipnp_release(struct fritz_adapter * adapter)828 static void fcpcipnp_release(struct fritz_adapter *adapter)
829 {
830 	DBG(1, "");
831 
832 	outb(0, adapter->io + AVM_STATUS0);
833 	free_irq(adapter->irq, adapter);
834 	release_region(adapter->io, 32);
835 }
836 
837 // ----------------------------------------------------------------------
838 
new_adapter(void)839 static struct fritz_adapter *new_adapter(void)
840 {
841 	struct fritz_adapter *adapter;
842 	struct hisax_b_if *b_if[2];
843 	int i;
844 
845 	adapter = kzalloc(sizeof(struct fritz_adapter), GFP_KERNEL);
846 	if (!adapter)
847 		return NULL;
848 
849 	adapter->isac.hisax_d_if.owner = THIS_MODULE;
850 	adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;
851 	adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;
852 
853 	for (i = 0; i < 2; i++) {
854 		adapter->bcs[i].adapter = adapter;
855 		adapter->bcs[i].channel = i;
856 		adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
857 		adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1;
858 	}
859 
860 	for (i = 0; i < 2; i++)
861 		b_if[i] = &adapter->bcs[i].b_if;
862 
863 	if (hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp",
864 			   protocol) != 0) {
865 		kfree(adapter);
866 		adapter = NULL;
867 	}
868 
869 	return adapter;
870 }
871 
delete_adapter(struct fritz_adapter * adapter)872 static void delete_adapter(struct fritz_adapter *adapter)
873 {
874 	hisax_unregister(&adapter->isac.hisax_d_if);
875 	kfree(adapter);
876 }
877 
fcpci_probe(struct pci_dev * pdev,const struct pci_device_id * ent)878 static int fcpci_probe(struct pci_dev *pdev, 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 CONFIG_PNP
fcpnp_probe(struct pnp_dev * pdev,const struct pnp_device_id * dev_id)918 static int 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", __func__,
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 
fcpnp_remove(struct pnp_dev * pdev)960 static void 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		= fcpnp_remove,
975 	.id_table	= fcpnp_ids,
976 };
977 #endif
978 
fcpci_remove(struct pci_dev * pdev)979 static void 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		= fcpci_remove,
992 	.id_table	= fcpci_ids,
993 };
994 
hisax_fcpcipnp_init(void)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 CONFIG_PNP
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 
hisax_fcpcipnp_exit(void)1014 static void __exit hisax_fcpcipnp_exit(void)
1015 {
1016 #ifdef CONFIG_PNP
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);
1024