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