Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/isdn/hisax/hisax_fcpcipnp.c
15115 views
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 <[email protected]>
6
* 2001 by Karsten Keil <[email protected]>
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 <[email protected]>/Karsten Keil <[email protected]>");
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 CONFIG_PNP
72
static struct pnp_device_id fcpnp_ids[] __devinitdata = {
73
{
74
.id = "AVM0900",
75
.driver_data = (unsigned long) "Fritz!Card PnP",
76
},
77
{ .id = "" }
78
};
79
80
MODULE_DEVICE_TABLE(pnp, fcpnp_ids);
81
#endif
82
83
static int protocol = 2; /* EURO-ISDN Default */
84
module_param(protocol, int, 0);
85
MODULE_LICENSE("GPL");
86
87
// ----------------------------------------------------------------------
88
89
#define AVM_INDEX 0x04
90
#define AVM_DATA 0x10
91
92
#define AVM_IDX_HDLC_1 0x00
93
#define AVM_IDX_HDLC_2 0x01
94
#define AVM_IDX_ISAC_FIFO 0x02
95
#define AVM_IDX_ISAC_REG_LOW 0x04
96
#define AVM_IDX_ISAC_REG_HIGH 0x06
97
98
#define AVM_STATUS0 0x02
99
100
#define AVM_STATUS0_IRQ_ISAC 0x01
101
#define AVM_STATUS0_IRQ_HDLC 0x02
102
#define AVM_STATUS0_IRQ_TIMER 0x04
103
#define AVM_STATUS0_IRQ_MASK 0x07
104
105
#define AVM_STATUS0_RESET 0x01
106
#define AVM_STATUS0_DIS_TIMER 0x02
107
#define AVM_STATUS0_RES_TIMER 0x04
108
#define AVM_STATUS0_ENA_IRQ 0x08
109
#define AVM_STATUS0_TESTBIT 0x10
110
111
#define AVM_STATUS1 0x03
112
#define AVM_STATUS1_ENA_IOM 0x80
113
114
#define HDLC_FIFO 0x0
115
#define HDLC_STATUS 0x4
116
#define HDLC_CTRL 0x4
117
118
#define HDLC_MODE_ITF_FLG 0x01
119
#define HDLC_MODE_TRANS 0x02
120
#define HDLC_MODE_CCR_7 0x04
121
#define HDLC_MODE_CCR_16 0x08
122
#define HDLC_MODE_TESTLOOP 0x80
123
124
#define HDLC_INT_XPR 0x80
125
#define HDLC_INT_XDU 0x40
126
#define HDLC_INT_RPR 0x20
127
#define HDLC_INT_MASK 0xE0
128
129
#define HDLC_STAT_RME 0x01
130
#define HDLC_STAT_RDO 0x10
131
#define HDLC_STAT_CRCVFRRAB 0x0E
132
#define HDLC_STAT_CRCVFR 0x06
133
#define HDLC_STAT_RML_MASK 0xff00
134
135
#define HDLC_CMD_XRS 0x80
136
#define HDLC_CMD_XME 0x01
137
#define HDLC_CMD_RRS 0x20
138
#define HDLC_CMD_XML_MASK 0xff00
139
140
#define AVM_HDLC_FIFO_1 0x10
141
#define AVM_HDLC_FIFO_2 0x18
142
143
#define AVM_HDLC_STATUS_1 0x14
144
#define AVM_HDLC_STATUS_2 0x1c
145
146
#define AVM_ISACSX_INDEX 0x04
147
#define AVM_ISACSX_DATA 0x08
148
149
// ----------------------------------------------------------------------
150
// Fritz!PCI
151
152
static unsigned char fcpci_read_isac(struct isac *isac, unsigned char offset)
153
{
154
struct fritz_adapter *adapter = isac->priv;
155
unsigned char idx = (offset > 0x2f) ?
156
AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
157
unsigned char val;
158
unsigned long flags;
159
160
spin_lock_irqsave(&adapter->hw_lock, flags);
161
outb(idx, adapter->io + AVM_INDEX);
162
val = inb(adapter->io + AVM_DATA + (offset & 0xf));
163
spin_unlock_irqrestore(&adapter->hw_lock, flags);
164
DBG(0x1000, " port %#x, value %#x",
165
offset, val);
166
return val;
167
}
168
169
static void fcpci_write_isac(struct isac *isac, unsigned char offset,
170
unsigned char value)
171
{
172
struct fritz_adapter *adapter = isac->priv;
173
unsigned char idx = (offset > 0x2f) ?
174
AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
175
unsigned long flags;
176
177
DBG(0x1000, " port %#x, value %#x",
178
offset, value);
179
spin_lock_irqsave(&adapter->hw_lock, flags);
180
outb(idx, adapter->io + AVM_INDEX);
181
outb(value, adapter->io + AVM_DATA + (offset & 0xf));
182
spin_unlock_irqrestore(&adapter->hw_lock, flags);
183
}
184
185
static void fcpci_read_isac_fifo(struct isac *isac, unsigned char * data,
186
int size)
187
{
188
struct fritz_adapter *adapter = isac->priv;
189
unsigned long flags;
190
191
spin_lock_irqsave(&adapter->hw_lock, flags);
192
outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
193
insb(adapter->io + AVM_DATA, data, size);
194
spin_unlock_irqrestore(&adapter->hw_lock, flags);
195
}
196
197
static void fcpci_write_isac_fifo(struct isac *isac, unsigned char * data,
198
int size)
199
{
200
struct fritz_adapter *adapter = isac->priv;
201
unsigned long flags;
202
203
spin_lock_irqsave(&adapter->hw_lock, flags);
204
outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
205
outsb(adapter->io + AVM_DATA, data, size);
206
spin_unlock_irqrestore(&adapter->hw_lock, flags);
207
}
208
209
static u32 fcpci_read_hdlc_status(struct fritz_adapter *adapter, int nr)
210
{
211
u32 val;
212
int idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
213
unsigned long flags;
214
215
spin_lock_irqsave(&adapter->hw_lock, flags);
216
outl(idx, adapter->io + AVM_INDEX);
217
val = inl(adapter->io + AVM_DATA + HDLC_STATUS);
218
spin_unlock_irqrestore(&adapter->hw_lock, flags);
219
return val;
220
}
221
222
static void __fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
223
{
224
struct fritz_adapter *adapter = bcs->adapter;
225
int idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
226
227
DBG(0x40, "hdlc %c wr%x ctrl %x",
228
'A' + bcs->channel, which, bcs->ctrl.ctrl);
229
230
outl(idx, adapter->io + AVM_INDEX);
231
outl(bcs->ctrl.ctrl, adapter->io + AVM_DATA + HDLC_CTRL);
232
}
233
234
static void fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
235
{
236
struct fritz_adapter *adapter = bcs->adapter;
237
unsigned long flags;
238
239
spin_lock_irqsave(&adapter->hw_lock, flags);
240
__fcpci_write_ctrl(bcs, which);
241
spin_unlock_irqrestore(&adapter->hw_lock, flags);
242
}
243
244
// ----------------------------------------------------------------------
245
// Fritz!PCI v2
246
247
static unsigned char fcpci2_read_isac(struct isac *isac, unsigned char offset)
248
{
249
struct fritz_adapter *adapter = isac->priv;
250
unsigned char val;
251
unsigned long flags;
252
253
spin_lock_irqsave(&adapter->hw_lock, flags);
254
outl(offset, adapter->io + AVM_ISACSX_INDEX);
255
val = inl(adapter->io + AVM_ISACSX_DATA);
256
spin_unlock_irqrestore(&adapter->hw_lock, flags);
257
DBG(0x1000, " port %#x, value %#x",
258
offset, val);
259
260
return val;
261
}
262
263
static void fcpci2_write_isac(struct isac *isac, unsigned char offset,
264
unsigned char value)
265
{
266
struct fritz_adapter *adapter = isac->priv;
267
unsigned long flags;
268
269
DBG(0x1000, " port %#x, value %#x",
270
offset, value);
271
spin_lock_irqsave(&adapter->hw_lock, flags);
272
outl(offset, adapter->io + AVM_ISACSX_INDEX);
273
outl(value, adapter->io + AVM_ISACSX_DATA);
274
spin_unlock_irqrestore(&adapter->hw_lock, flags);
275
}
276
277
static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char * data,
278
int size)
279
{
280
struct fritz_adapter *adapter = isac->priv;
281
int i;
282
unsigned long flags;
283
284
spin_lock_irqsave(&adapter->hw_lock, flags);
285
outl(0, adapter->io + AVM_ISACSX_INDEX);
286
for (i = 0; i < size; i++)
287
data[i] = inl(adapter->io + AVM_ISACSX_DATA);
288
spin_unlock_irqrestore(&adapter->hw_lock, flags);
289
}
290
291
static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char * data,
292
int size)
293
{
294
struct fritz_adapter *adapter = isac->priv;
295
int i;
296
unsigned long flags;
297
298
spin_lock_irqsave(&adapter->hw_lock, flags);
299
outl(0, adapter->io + AVM_ISACSX_INDEX);
300
for (i = 0; i < size; i++)
301
outl(data[i], adapter->io + AVM_ISACSX_DATA);
302
spin_unlock_irqrestore(&adapter->hw_lock, flags);
303
}
304
305
static u32 fcpci2_read_hdlc_status(struct fritz_adapter *adapter, int nr)
306
{
307
int offset = nr ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
308
309
return inl(adapter->io + offset);
310
}
311
312
static void fcpci2_write_ctrl(struct fritz_bcs *bcs, int which)
313
{
314
struct fritz_adapter *adapter = bcs->adapter;
315
int offset = bcs->channel ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
316
317
DBG(0x40, "hdlc %c wr%x ctrl %x",
318
'A' + bcs->channel, which, bcs->ctrl.ctrl);
319
320
outl(bcs->ctrl.ctrl, adapter->io + offset);
321
}
322
323
// ----------------------------------------------------------------------
324
// Fritz!PnP (ISAC access as for Fritz!PCI)
325
326
static u32 fcpnp_read_hdlc_status(struct fritz_adapter *adapter, int nr)
327
{
328
unsigned char idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
329
u32 val;
330
unsigned long flags;
331
332
spin_lock_irqsave(&adapter->hw_lock, flags);
333
outb(idx, adapter->io + AVM_INDEX);
334
val = inb(adapter->io + AVM_DATA + HDLC_STATUS);
335
if (val & HDLC_INT_RPR)
336
val |= inb(adapter->io + AVM_DATA + HDLC_STATUS + 1) << 8;
337
spin_unlock_irqrestore(&adapter->hw_lock, flags);
338
return val;
339
}
340
341
static void __fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
342
{
343
struct fritz_adapter *adapter = bcs->adapter;
344
unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
345
346
DBG(0x40, "hdlc %c wr%x ctrl %x",
347
'A' + bcs->channel, which, bcs->ctrl.ctrl);
348
349
outb(idx, adapter->io + AVM_INDEX);
350
if (which & 4)
351
outb(bcs->ctrl.sr.mode,
352
adapter->io + AVM_DATA + HDLC_STATUS + 2);
353
if (which & 2)
354
outb(bcs->ctrl.sr.xml,
355
adapter->io + AVM_DATA + HDLC_STATUS + 1);
356
if (which & 1)
357
outb(bcs->ctrl.sr.cmd,
358
adapter->io + AVM_DATA + HDLC_STATUS + 0);
359
}
360
361
static void fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
362
{
363
struct fritz_adapter *adapter = bcs->adapter;
364
unsigned long flags;
365
366
spin_lock_irqsave(&adapter->hw_lock, flags);
367
__fcpnp_write_ctrl(bcs, which);
368
spin_unlock_irqrestore(&adapter->hw_lock, flags);
369
}
370
371
// ----------------------------------------------------------------------
372
373
static inline void B_L1L2(struct fritz_bcs *bcs, int pr, void *arg)
374
{
375
struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if;
376
377
DBG(2, "pr %#x", pr);
378
ifc->l1l2(ifc, pr, arg);
379
}
380
381
static void hdlc_fill_fifo(struct fritz_bcs *bcs)
382
{
383
struct fritz_adapter *adapter = bcs->adapter;
384
struct sk_buff *skb = bcs->tx_skb;
385
int count;
386
unsigned long flags;
387
unsigned char *p;
388
389
DBG(0x40, "hdlc_fill_fifo");
390
391
BUG_ON(skb->len == 0);
392
393
bcs->ctrl.sr.cmd &= ~HDLC_CMD_XME;
394
if (bcs->tx_skb->len > bcs->fifo_size) {
395
count = bcs->fifo_size;
396
} else {
397
count = bcs->tx_skb->len;
398
if (bcs->mode != L1_MODE_TRANS)
399
bcs->ctrl.sr.cmd |= HDLC_CMD_XME;
400
}
401
DBG(0x40, "hdlc_fill_fifo %d/%d", count, bcs->tx_skb->len);
402
p = bcs->tx_skb->data;
403
skb_pull(bcs->tx_skb, count);
404
bcs->tx_cnt += count;
405
bcs->ctrl.sr.xml = ((count == bcs->fifo_size) ? 0 : count);
406
407
switch (adapter->type) {
408
case AVM_FRITZ_PCI:
409
spin_lock_irqsave(&adapter->hw_lock, flags);
410
// sets the correct AVM_INDEX, too
411
__fcpci_write_ctrl(bcs, 3);
412
outsl(adapter->io + AVM_DATA + HDLC_FIFO,
413
p, (count + 3) / 4);
414
spin_unlock_irqrestore(&adapter->hw_lock, flags);
415
break;
416
case AVM_FRITZ_PCIV2:
417
fcpci2_write_ctrl(bcs, 3);
418
outsl(adapter->io +
419
(bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
420
p, (count + 3) / 4);
421
break;
422
case AVM_FRITZ_PNP:
423
spin_lock_irqsave(&adapter->hw_lock, flags);
424
// sets the correct AVM_INDEX, too
425
__fcpnp_write_ctrl(bcs, 3);
426
outsb(adapter->io + AVM_DATA, p, count);
427
spin_unlock_irqrestore(&adapter->hw_lock, flags);
428
break;
429
}
430
}
431
432
static inline void hdlc_empty_fifo(struct fritz_bcs *bcs, int count)
433
{
434
struct fritz_adapter *adapter = bcs->adapter;
435
unsigned char *p;
436
unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
437
438
DBG(0x10, "hdlc_empty_fifo %d", count);
439
if (bcs->rcvidx + count > HSCX_BUFMAX) {
440
DBG(0x10, "hdlc_empty_fifo: incoming packet too large");
441
return;
442
}
443
p = bcs->rcvbuf + bcs->rcvidx;
444
bcs->rcvidx += count;
445
switch (adapter->type) {
446
case AVM_FRITZ_PCI:
447
spin_lock(&adapter->hw_lock);
448
outl(idx, adapter->io + AVM_INDEX);
449
insl(adapter->io + AVM_DATA + HDLC_FIFO,
450
p, (count + 3) / 4);
451
spin_unlock(&adapter->hw_lock);
452
break;
453
case AVM_FRITZ_PCIV2:
454
insl(adapter->io +
455
(bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
456
p, (count + 3) / 4);
457
break;
458
case AVM_FRITZ_PNP:
459
spin_lock(&adapter->hw_lock);
460
outb(idx, adapter->io + AVM_INDEX);
461
insb(adapter->io + AVM_DATA, p, count);
462
spin_unlock(&adapter->hw_lock);
463
break;
464
}
465
}
466
467
static inline void hdlc_rpr_irq(struct fritz_bcs *bcs, u32 stat)
468
{
469
struct fritz_adapter *adapter = bcs->adapter;
470
struct sk_buff *skb;
471
int len;
472
473
if (stat & HDLC_STAT_RDO) {
474
DBG(0x10, "RDO");
475
bcs->ctrl.sr.xml = 0;
476
bcs->ctrl.sr.cmd |= HDLC_CMD_RRS;
477
adapter->write_ctrl(bcs, 1);
478
bcs->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
479
adapter->write_ctrl(bcs, 1);
480
bcs->rcvidx = 0;
481
return;
482
}
483
484
len = (stat & HDLC_STAT_RML_MASK) >> 8;
485
if (len == 0)
486
len = bcs->fifo_size;
487
488
hdlc_empty_fifo(bcs, len);
489
490
if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
491
if (((stat & HDLC_STAT_CRCVFRRAB)== HDLC_STAT_CRCVFR) ||
492
(bcs->mode == L1_MODE_TRANS)) {
493
skb = dev_alloc_skb(bcs->rcvidx);
494
if (!skb) {
495
printk(KERN_WARNING "HDLC: receive out of memory\n");
496
} else {
497
memcpy(skb_put(skb, bcs->rcvidx), bcs->rcvbuf,
498
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
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
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
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
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
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
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
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
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
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
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
714
static int __devinit 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
827
static void __devexit 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
838
static struct fritz_adapter * __devinit
839
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
872
static void delete_adapter(struct fritz_adapter *adapter)
873
{
874
hisax_unregister(&adapter->isac.hisax_d_if);
875
kfree(adapter);
876
}
877
878
static int __devinit fcpci_probe(struct pci_dev *pdev,
879
const struct pci_device_id *ent)
880
{
881
struct fritz_adapter *adapter;
882
int retval;
883
884
retval = -ENOMEM;
885
adapter = new_adapter();
886
if (!adapter)
887
goto err;
888
889
pci_set_drvdata(pdev, adapter);
890
891
if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2)
892
adapter->type = AVM_FRITZ_PCIV2;
893
else
894
adapter->type = AVM_FRITZ_PCI;
895
896
retval = pci_enable_device(pdev);
897
if (retval)
898
goto err_free;
899
900
adapter->io = pci_resource_start(pdev, 1);
901
adapter->irq = pdev->irq;
902
903
printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %s\n",
904
(char *) ent->driver_data, pci_name(pdev));
905
906
retval = fcpcipnp_setup(adapter);
907
if (retval)
908
goto err_free;
909
910
return 0;
911
912
err_free:
913
delete_adapter(adapter);
914
err:
915
return retval;
916
}
917
918
#ifdef CONFIG_PNP
919
static int __devinit fcpnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
920
{
921
struct fritz_adapter *adapter;
922
int retval;
923
924
if (!pdev)
925
return(-ENODEV);
926
927
retval = -ENOMEM;
928
adapter = new_adapter();
929
if (!adapter)
930
goto err;
931
932
pnp_set_drvdata(pdev, adapter);
933
934
adapter->type = AVM_FRITZ_PNP;
935
936
pnp_disable_dev(pdev);
937
retval = pnp_activate_dev(pdev);
938
if (retval < 0) {
939
printk(KERN_WARNING "%s: pnp_activate_dev(%s) ret(%d)\n", __func__,
940
(char *)dev_id->driver_data, retval);
941
goto err_free;
942
}
943
adapter->io = pnp_port_start(pdev, 0);
944
adapter->irq = pnp_irq(pdev, 0);
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
961
static void __devexit 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 = __devexit_p(fcpnp_remove),
976
.id_table = fcpnp_ids,
977
};
978
#endif
979
980
static void __devexit 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 = __devexit_p(fcpci_remove),
993
.id_table = fcpci_ids,
994
};
995
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
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
1026