1/* 2 * Driver for AVM Fritz!PCI, Fritz!PCI v2, Fritz!PnP ISDN cards 3 * 4 * Author Kai Germaschewski 5 * Copyright 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> 6 * 2001 by Karsten Keil <keil@isdn4linux.de> 7 * 8 * based upon Karsten Keil's original avm_pci.c driver 9 * 10 * This software may be used and distributed according to the terms 11 * of the GNU General Public License, incorporated herein by reference. 12 * 13 * Thanks to Wizard Computersysteme GmbH, Bremervoerde and 14 * SoHaNet Technology GmbH, Berlin 15 * for supporting the development of this driver 16 */ 17 18 19/* TODO: 20 * 21 * o POWER PC 22 * o clean up debugging 23 * o tx_skb at PH_DEACTIVATE time 24 */ 25 26#include <linux/module.h> 27#include <linux/init.h> 28#include <linux/pci.h> 29#include <linux/isapnp.h> 30#include <linux/kmod.h> 31#include <linux/slab.h> 32#include <linux/skbuff.h> 33#include <linux/netdevice.h> 34#include <linux/delay.h> 35 36#include <asm/io.h> 37 38#include "hisax_fcpcipnp.h" 39 40// debugging cruft 41#define __debug_variable debug 42#include "hisax_debug.h" 43 44#ifdef CONFIG_HISAX_DEBUG 45static int debug = 0; 46/* static int hdlcfifosize = 32; */ 47module_param(debug, int, 0); 48/* module_param(hdlcfifosize, int, 0); */ 49#endif 50 51MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>"); 52MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver"); 53 54static struct pci_device_id fcpci_ids[] = { 55 { .vendor = PCI_VENDOR_ID_AVM, 56 .device = PCI_DEVICE_ID_AVM_A1, 57 .subvendor = PCI_ANY_ID, 58 .subdevice = PCI_ANY_ID, 59 .driver_data = (unsigned long) "Fritz!Card PCI", 60 }, 61 { .vendor = PCI_VENDOR_ID_AVM, 62 .device = PCI_DEVICE_ID_AVM_A1_V2, 63 .subvendor = PCI_ANY_ID, 64 .subdevice = PCI_ANY_ID, 65 .driver_data = (unsigned long) "Fritz!Card PCI v2" }, 66 {} 67}; 68 69MODULE_DEVICE_TABLE(pci, fcpci_ids); 70 71#ifdef CONFIG_PNP 72static struct pnp_device_id fcpnp_ids[] __devinitdata = { 73 { 74 .id = "AVM0900", 75 .driver_data = (unsigned long) "Fritz!Card PnP", 76 }, 77 { .id = "" } 78}; 79 80MODULE_DEVICE_TABLE(pnp, fcpnp_ids); 81#endif 82 83static int protocol = 2; /* EURO-ISDN Default */ 84module_param(protocol, int, 0); 85MODULE_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 152static 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 169static 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 185static 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 197static 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 209static 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 222static 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 234static 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 247static 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 263static 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 277static 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 291static 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 305static 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 312static 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 326static 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 341static 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 361static 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 373static 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 381static 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 432static 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 467static 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 511static 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 536static 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 554static 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 573static 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 586static 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 623static 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 654static irqreturn_t 655fcpci2_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 674static irqreturn_t 675fcpci_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 695static 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 702static 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 714static 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); 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 827static 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 838static struct fritz_adapter * __devinit 839new_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 872static void delete_adapter(struct fritz_adapter *adapter) 873{ 874 hisax_unregister(&adapter->isac.hisax_d_if); 875 kfree(adapter); 876} 877 878static 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 919static 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 961static 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 972static 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 980static 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 989static 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 996static 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 1015static 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 1023module_init(hisax_fcpcipnp_init); 1024module_exit(hisax_fcpcipnp_exit); 1025