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 46static int debug = 0; 47/* static int hdlcfifosize = 32; */ 48module_param(debug, int, 0); 49/* module_param(hdlcfifosize, int, 0); */ 50#endif 51 52MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>"); 53MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver"); 54 55static 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 70MODULE_DEVICE_TABLE(pci, fcpci_ids); 71 72#ifdef CONFIG_PNP 73static struct pnp_device_id fcpnp_ids[] = { 74 { 75 .id = "AVM0900", 76 .driver_data = (unsigned long) "Fritz!Card PnP", 77 }, 78 { .id = "" } 79}; 80 81MODULE_DEVICE_TABLE(pnp, fcpnp_ids); 82#endif 83 84static int protocol = 2; /* EURO-ISDN Default */ 85module_param(protocol, int, 0); 86MODULE_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 153static 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 170static 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 186static 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 198static 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 210static 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 223static 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 235static 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 248static 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 264static 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 278static 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 292static 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 306static 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 313static 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 327static 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 342static 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 362static 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 374static 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 382static 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 433static 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 468static 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 512static 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 537static 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 555static 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 574static 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 587static 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 624static 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 655static irqreturn_t 656fcpci2_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 675static irqreturn_t 676fcpci_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 696static 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 703static 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 715static 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 822err_region: 823 release_region(adapter->io, 32); 824err: 825 return retval; 826} 827 828static 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 839static 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 872static void delete_adapter(struct fritz_adapter *adapter) 873{ 874 hisax_unregister(&adapter->isac.hisax_d_if); 875 kfree(adapter); 876} 877 878static 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 911err_free: 912 delete_adapter(adapter); 913err: 914 return retval; 915} 916 917#ifdef CONFIG_PNP 918static 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 954err_free: 955 delete_adapter(adapter); 956err: 957 return retval; 958} 959 960static 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 971static 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 979static 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 988static struct pci_driver fcpci_driver = { 989 .name = "fcpci", 990 .probe = fcpci_probe, 991 .remove = fcpci_remove, 992 .id_table = fcpci_ids, 993}; 994 995static 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 1014static 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 1022module_init(hisax_fcpcipnp_init); 1023module_exit(hisax_fcpcipnp_exit); 1024