1/* $Id: avm_pci.c,v 1.29.2.4 2004/02/11 13:21:32 keil Exp $ 2 * 3 * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards 4 * 5 * Author Karsten Keil 6 * Copyright by Karsten Keil <keil@isdn4linux.de> 7 * 8 * This software may be used and distributed according to the terms 9 * of the GNU General Public License, incorporated herein by reference. 10 * 11 * Thanks to AVM, Berlin for information 12 * 13 */ 14 15#include <linux/init.h> 16#include "hisax.h" 17#include "isac.h" 18#include "isdnl1.h" 19#include <linux/pci.h> 20#include <linux/slab.h> 21#include <linux/isapnp.h> 22#include <linux/interrupt.h> 23 24static const char *avm_pci_rev = "$Revision: 1.29.2.4 $"; 25 26#define AVM_FRITZ_PCI 1 27#define AVM_FRITZ_PNP 2 28 29#define HDLC_FIFO 0x0 30#define HDLC_STATUS 0x4 31 32#define AVM_HDLC_1 0x00 33#define AVM_HDLC_2 0x01 34#define AVM_ISAC_FIFO 0x02 35#define AVM_ISAC_REG_LOW 0x04 36#define AVM_ISAC_REG_HIGH 0x06 37 38#define AVM_STATUS0_IRQ_ISAC 0x01 39#define AVM_STATUS0_IRQ_HDLC 0x02 40#define AVM_STATUS0_IRQ_TIMER 0x04 41#define AVM_STATUS0_IRQ_MASK 0x07 42 43#define AVM_STATUS0_RESET 0x01 44#define AVM_STATUS0_DIS_TIMER 0x02 45#define AVM_STATUS0_RES_TIMER 0x04 46#define AVM_STATUS0_ENA_IRQ 0x08 47#define AVM_STATUS0_TESTBIT 0x10 48 49#define AVM_STATUS1_INT_SEL 0x0f 50#define AVM_STATUS1_ENA_IOM 0x80 51 52#define HDLC_MODE_ITF_FLG 0x01 53#define HDLC_MODE_TRANS 0x02 54#define HDLC_MODE_CCR_7 0x04 55#define HDLC_MODE_CCR_16 0x08 56#define HDLC_MODE_TESTLOOP 0x80 57 58#define HDLC_INT_XPR 0x80 59#define HDLC_INT_XDU 0x40 60#define HDLC_INT_RPR 0x20 61#define HDLC_INT_MASK 0xE0 62 63#define HDLC_STAT_RME 0x01 64#define HDLC_STAT_RDO 0x10 65#define HDLC_STAT_CRCVFRRAB 0x0E 66#define HDLC_STAT_CRCVFR 0x06 67#define HDLC_STAT_RML_MASK 0x3f00 68 69#define HDLC_CMD_XRS 0x80 70#define HDLC_CMD_XME 0x01 71#define HDLC_CMD_RRS 0x20 72#define HDLC_CMD_XML_MASK 0x3f00 73 74 75/* Interface functions */ 76 77static u_char 78ReadISAC(struct IsdnCardState *cs, u_char offset) 79{ 80 register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; 81 register u_char val; 82 83 outb(idx, cs->hw.avm.cfg_reg + 4); 84 val = inb(cs->hw.avm.isac + (offset & 0xf)); 85 return (val); 86} 87 88static void 89WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) 90{ 91 register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; 92 93 outb(idx, cs->hw.avm.cfg_reg + 4); 94 outb(value, cs->hw.avm.isac + (offset & 0xf)); 95} 96 97static void 98ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) 99{ 100 outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4); 101 insb(cs->hw.avm.isac, data, size); 102} 103 104static void 105WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) 106{ 107 outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4); 108 outsb(cs->hw.avm.isac, data, size); 109} 110 111static inline u_int 112ReadHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset) 113{ 114 register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; 115 register u_int val; 116 117 outl(idx, cs->hw.avm.cfg_reg + 4); 118 val = inl(cs->hw.avm.isac + offset); 119 return (val); 120} 121 122static inline void 123WriteHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset, u_int value) 124{ 125 register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; 126 127 outl(idx, cs->hw.avm.cfg_reg + 4); 128 outl(value, cs->hw.avm.isac + offset); 129} 130 131static inline u_char 132ReadHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset) 133{ 134 register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; 135 register u_char val; 136 137 outb(idx, cs->hw.avm.cfg_reg + 4); 138 val = inb(cs->hw.avm.isac + offset); 139 return (val); 140} 141 142static inline void 143WriteHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset, u_char value) 144{ 145 register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; 146 147 outb(idx, cs->hw.avm.cfg_reg + 4); 148 outb(value, cs->hw.avm.isac + offset); 149} 150 151static u_char 152ReadHDLC_s(struct IsdnCardState *cs, int chan, u_char offset) 153{ 154 return (0xff & ReadHDLCPCI(cs, chan, offset)); 155} 156 157static void 158WriteHDLC_s(struct IsdnCardState *cs, int chan, u_char offset, u_char value) 159{ 160 WriteHDLCPCI(cs, chan, offset, value); 161} 162 163static inline 164struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel) 165{ 166 if (cs->bcs[0].mode && (cs->bcs[0].channel == channel)) 167 return (&cs->bcs[0]); 168 else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel)) 169 return (&cs->bcs[1]); 170 else 171 return (NULL); 172} 173 174static void 175write_ctrl(struct BCState *bcs, int which) { 176 177 if (bcs->cs->debug & L1_DEB_HSCX) 178 debugl1(bcs->cs, "hdlc %c wr%x ctrl %x", 179 'A' + bcs->channel, which, bcs->hw.hdlc.ctrl.ctrl); 180 if (bcs->cs->subtyp == AVM_FRITZ_PCI) { 181 WriteHDLCPCI(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl.ctrl); 182 } else { 183 if (which & 4) 184 WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 2, 185 bcs->hw.hdlc.ctrl.sr.mode); 186 if (which & 2) 187 WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 1, 188 bcs->hw.hdlc.ctrl.sr.xml); 189 if (which & 1) 190 WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS, 191 bcs->hw.hdlc.ctrl.sr.cmd); 192 } 193} 194 195static void 196modehdlc(struct BCState *bcs, int mode, int bc) 197{ 198 struct IsdnCardState *cs = bcs->cs; 199 int hdlc = bcs->channel; 200 201 if (cs->debug & L1_DEB_HSCX) 202 debugl1(cs, "hdlc %c mode %d --> %d ichan %d --> %d", 203 'A' + hdlc, bcs->mode, mode, hdlc, bc); 204 bcs->hw.hdlc.ctrl.ctrl = 0; 205 switch (mode) { 206 case (-1): /* used for init */ 207 bcs->mode = 1; 208 bcs->channel = bc; 209 bc = 0; 210 case (L1_MODE_NULL): 211 if (bcs->mode == L1_MODE_NULL) 212 return; 213 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; 214 bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS; 215 write_ctrl(bcs, 5); 216 bcs->mode = L1_MODE_NULL; 217 bcs->channel = bc; 218 break; 219 case (L1_MODE_TRANS): 220 bcs->mode = mode; 221 bcs->channel = bc; 222 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; 223 bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS; 224 write_ctrl(bcs, 5); 225 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS; 226 write_ctrl(bcs, 1); 227 bcs->hw.hdlc.ctrl.sr.cmd = 0; 228 schedule_event(bcs, B_XMTBUFREADY); 229 break; 230 case (L1_MODE_HDLC): 231 bcs->mode = mode; 232 bcs->channel = bc; 233 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; 234 bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG; 235 write_ctrl(bcs, 5); 236 bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS; 237 write_ctrl(bcs, 1); 238 bcs->hw.hdlc.ctrl.sr.cmd = 0; 239 schedule_event(bcs, B_XMTBUFREADY); 240 break; 241 } 242} 243 244static inline void 245hdlc_empty_fifo(struct BCState *bcs, int count) 246{ 247 register u_int *ptr; 248 u_char *p; 249 u_char idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1; 250 int cnt = 0; 251 struct IsdnCardState *cs = bcs->cs; 252 253 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 254 debugl1(cs, "hdlc_empty_fifo %d", count); 255 if (bcs->hw.hdlc.rcvidx + count > HSCX_BUFMAX) { 256 if (cs->debug & L1_DEB_WARN) 257 debugl1(cs, "hdlc_empty_fifo: incoming packet too large"); 258 return; 259 } 260 p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx; 261 ptr = (u_int *)p; 262 bcs->hw.hdlc.rcvidx += count; 263 if (cs->subtyp == AVM_FRITZ_PCI) { 264 outl(idx, cs->hw.avm.cfg_reg + 4); 265 while (cnt < count) { 266#ifdef __powerpc__ 267 *ptr++ = in_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE)); 268#else 269 *ptr++ = inl(cs->hw.avm.isac); 270#endif /* __powerpc__ */ 271 cnt += 4; 272 } 273 } else { 274 outb(idx, cs->hw.avm.cfg_reg + 4); 275 while (cnt < count) { 276 *p++ = inb(cs->hw.avm.isac); 277 cnt++; 278 } 279 } 280 if (cs->debug & L1_DEB_HSCX_FIFO) { 281 char *t = bcs->blog; 282 283 if (cs->subtyp == AVM_FRITZ_PNP) 284 p = (u_char *) ptr; 285 t += sprintf(t, "hdlc_empty_fifo %c cnt %d", 286 bcs->channel ? 'B' : 'A', count); 287 QuickHex(t, p, count); 288 debugl1(cs, "%s", bcs->blog); 289 } 290} 291 292static inline void 293hdlc_fill_fifo(struct BCState *bcs) 294{ 295 struct IsdnCardState *cs = bcs->cs; 296 int count, cnt = 0; 297 int fifo_size = 32; 298 u_char *p; 299 u_int *ptr; 300 301 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 302 debugl1(cs, "hdlc_fill_fifo"); 303 if (!bcs->tx_skb) 304 return; 305 if (bcs->tx_skb->len <= 0) 306 return; 307 308 bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XME; 309 if (bcs->tx_skb->len > fifo_size) { 310 count = fifo_size; 311 } else { 312 count = bcs->tx_skb->len; 313 if (bcs->mode != L1_MODE_TRANS) 314 bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME; 315 } 316 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 317 debugl1(cs, "hdlc_fill_fifo %d/%u", count, bcs->tx_skb->len); 318 p = bcs->tx_skb->data; 319 ptr = (u_int *)p; 320 skb_pull(bcs->tx_skb, count); 321 bcs->tx_cnt -= count; 322 bcs->hw.hdlc.count += count; 323 bcs->hw.hdlc.ctrl.sr.xml = ((count == fifo_size) ? 0 : count); 324 write_ctrl(bcs, 3); /* sets the correct index too */ 325 if (cs->subtyp == AVM_FRITZ_PCI) { 326 while (cnt < count) { 327#ifdef __powerpc__ 328 out_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE), *ptr++); 329#else 330 outl(*ptr++, cs->hw.avm.isac); 331#endif /* __powerpc__ */ 332 cnt += 4; 333 } 334 } else { 335 while (cnt < count) { 336 outb(*p++, cs->hw.avm.isac); 337 cnt++; 338 } 339 } 340 if (cs->debug & L1_DEB_HSCX_FIFO) { 341 char *t = bcs->blog; 342 343 if (cs->subtyp == AVM_FRITZ_PNP) 344 p = (u_char *) ptr; 345 t += sprintf(t, "hdlc_fill_fifo %c cnt %d", 346 bcs->channel ? 'B' : 'A', count); 347 QuickHex(t, p, count); 348 debugl1(cs, "%s", bcs->blog); 349 } 350} 351 352static void 353HDLC_irq(struct BCState *bcs, u_int stat) { 354 int len; 355 struct sk_buff *skb; 356 357 if (bcs->cs->debug & L1_DEB_HSCX) 358 debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat); 359 if (stat & HDLC_INT_RPR) { 360 if (stat & HDLC_STAT_RDO) { 361 if (bcs->cs->debug & L1_DEB_HSCX) 362 debugl1(bcs->cs, "RDO"); 363 else 364 debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat); 365 bcs->hw.hdlc.ctrl.sr.xml = 0; 366 bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_RRS; 367 write_ctrl(bcs, 1); 368 bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS; 369 write_ctrl(bcs, 1); 370 bcs->hw.hdlc.rcvidx = 0; 371 } else { 372 if (!(len = (stat & HDLC_STAT_RML_MASK) >> 8)) 373 len = 32; 374 hdlc_empty_fifo(bcs, len); 375 if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) { 376 if (((stat & HDLC_STAT_CRCVFRRAB) == HDLC_STAT_CRCVFR) || 377 (bcs->mode == L1_MODE_TRANS)) { 378 if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx))) 379 printk(KERN_WARNING "HDLC: receive out of memory\n"); 380 else { 381 memcpy(skb_put(skb, bcs->hw.hdlc.rcvidx), 382 bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx); 383 skb_queue_tail(&bcs->rqueue, skb); 384 } 385 bcs->hw.hdlc.rcvidx = 0; 386 schedule_event(bcs, B_RCVBUFREADY); 387 } else { 388 if (bcs->cs->debug & L1_DEB_HSCX) 389 debugl1(bcs->cs, "invalid frame"); 390 else 391 debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat); 392 bcs->hw.hdlc.rcvidx = 0; 393 } 394 } 395 } 396 } 397 if (stat & HDLC_INT_XDU) { 398 /* Here we lost an TX interrupt, so 399 * restart transmitting the whole frame. 400 */ 401 if (bcs->tx_skb) { 402 skb_push(bcs->tx_skb, bcs->hw.hdlc.count); 403 bcs->tx_cnt += bcs->hw.hdlc.count; 404 bcs->hw.hdlc.count = 0; 405 if (bcs->cs->debug & L1_DEB_WARN) 406 debugl1(bcs->cs, "ch%d XDU", bcs->channel); 407 } else if (bcs->cs->debug & L1_DEB_WARN) 408 debugl1(bcs->cs, "ch%d XDU without skb", bcs->channel); 409 bcs->hw.hdlc.ctrl.sr.xml = 0; 410 bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XRS; 411 write_ctrl(bcs, 1); 412 bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XRS; 413 write_ctrl(bcs, 1); 414 hdlc_fill_fifo(bcs); 415 } else if (stat & HDLC_INT_XPR) { 416 if (bcs->tx_skb) { 417 if (bcs->tx_skb->len) { 418 hdlc_fill_fifo(bcs); 419 return; 420 } else { 421 if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && 422 (PACKET_NOACK != bcs->tx_skb->pkt_type)) { 423 u_long flags; 424 spin_lock_irqsave(&bcs->aclock, flags); 425 bcs->ackcnt += bcs->hw.hdlc.count; 426 spin_unlock_irqrestore(&bcs->aclock, flags); 427 schedule_event(bcs, B_ACKPENDING); 428 } 429 dev_kfree_skb_irq(bcs->tx_skb); 430 bcs->hw.hdlc.count = 0; 431 bcs->tx_skb = NULL; 432 } 433 } 434 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { 435 bcs->hw.hdlc.count = 0; 436 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 437 hdlc_fill_fifo(bcs); 438 } else { 439 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 440 schedule_event(bcs, B_XMTBUFREADY); 441 } 442 } 443} 444 445static inline void 446HDLC_irq_main(struct IsdnCardState *cs) 447{ 448 u_int stat; 449 struct BCState *bcs; 450 451 if (cs->subtyp == AVM_FRITZ_PCI) { 452 stat = ReadHDLCPCI(cs, 0, HDLC_STATUS); 453 } else { 454 stat = ReadHDLCPnP(cs, 0, HDLC_STATUS); 455 if (stat & HDLC_INT_RPR) 456 stat |= (ReadHDLCPnP(cs, 0, HDLC_STATUS + 1)) << 8; 457 } 458 if (stat & HDLC_INT_MASK) { 459 if (!(bcs = Sel_BCS(cs, 0))) { 460 if (cs->debug) 461 debugl1(cs, "hdlc spurious channel 0 IRQ"); 462 } else 463 HDLC_irq(bcs, stat); 464 } 465 if (cs->subtyp == AVM_FRITZ_PCI) { 466 stat = ReadHDLCPCI(cs, 1, HDLC_STATUS); 467 } else { 468 stat = ReadHDLCPnP(cs, 1, HDLC_STATUS); 469 if (stat & HDLC_INT_RPR) 470 stat |= (ReadHDLCPnP(cs, 1, HDLC_STATUS + 1)) << 8; 471 } 472 if (stat & HDLC_INT_MASK) { 473 if (!(bcs = Sel_BCS(cs, 1))) { 474 if (cs->debug) 475 debugl1(cs, "hdlc spurious channel 1 IRQ"); 476 } else 477 HDLC_irq(bcs, stat); 478 } 479} 480 481static void 482hdlc_l2l1(struct PStack *st, int pr, void *arg) 483{ 484 struct BCState *bcs = st->l1.bcs; 485 struct sk_buff *skb = arg; 486 u_long flags; 487 488 switch (pr) { 489 case (PH_DATA | REQUEST): 490 spin_lock_irqsave(&bcs->cs->lock, flags); 491 if (bcs->tx_skb) { 492 skb_queue_tail(&bcs->squeue, skb); 493 } else { 494 bcs->tx_skb = skb; 495 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 496 bcs->hw.hdlc.count = 0; 497 bcs->cs->BC_Send_Data(bcs); 498 } 499 spin_unlock_irqrestore(&bcs->cs->lock, flags); 500 break; 501 case (PH_PULL | INDICATION): 502 spin_lock_irqsave(&bcs->cs->lock, flags); 503 if (bcs->tx_skb) { 504 printk(KERN_WARNING "hdlc_l2l1: this shouldn't happen\n"); 505 } else { 506 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 507 bcs->tx_skb = skb; 508 bcs->hw.hdlc.count = 0; 509 bcs->cs->BC_Send_Data(bcs); 510 } 511 spin_unlock_irqrestore(&bcs->cs->lock, flags); 512 break; 513 case (PH_PULL | REQUEST): 514 if (!bcs->tx_skb) { 515 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 516 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); 517 } else 518 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 519 break; 520 case (PH_ACTIVATE | REQUEST): 521 spin_lock_irqsave(&bcs->cs->lock, flags); 522 test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); 523 modehdlc(bcs, st->l1.mode, st->l1.bc); 524 spin_unlock_irqrestore(&bcs->cs->lock, flags); 525 l1_msg_b(st, pr, arg); 526 break; 527 case (PH_DEACTIVATE | REQUEST): 528 l1_msg_b(st, pr, arg); 529 break; 530 case (PH_DEACTIVATE | CONFIRM): 531 spin_lock_irqsave(&bcs->cs->lock, flags); 532 test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); 533 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 534 modehdlc(bcs, 0, st->l1.bc); 535 spin_unlock_irqrestore(&bcs->cs->lock, flags); 536 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); 537 break; 538 } 539} 540 541static void 542close_hdlcstate(struct BCState *bcs) 543{ 544 modehdlc(bcs, 0, 0); 545 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 546 kfree(bcs->hw.hdlc.rcvbuf); 547 bcs->hw.hdlc.rcvbuf = NULL; 548 kfree(bcs->blog); 549 bcs->blog = NULL; 550 skb_queue_purge(&bcs->rqueue); 551 skb_queue_purge(&bcs->squeue); 552 if (bcs->tx_skb) { 553 dev_kfree_skb_any(bcs->tx_skb); 554 bcs->tx_skb = NULL; 555 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 556 } 557 } 558} 559 560static int 561open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs) 562{ 563 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { 564 if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { 565 printk(KERN_WARNING 566 "HiSax: No memory for hdlc.rcvbuf\n"); 567 return (1); 568 } 569 if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { 570 printk(KERN_WARNING 571 "HiSax: No memory for bcs->blog\n"); 572 test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); 573 kfree(bcs->hw.hdlc.rcvbuf); 574 bcs->hw.hdlc.rcvbuf = NULL; 575 return (2); 576 } 577 skb_queue_head_init(&bcs->rqueue); 578 skb_queue_head_init(&bcs->squeue); 579 } 580 bcs->tx_skb = NULL; 581 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 582 bcs->event = 0; 583 bcs->hw.hdlc.rcvidx = 0; 584 bcs->tx_cnt = 0; 585 return (0); 586} 587 588static int 589setstack_hdlc(struct PStack *st, struct BCState *bcs) 590{ 591 bcs->channel = st->l1.bc; 592 if (open_hdlcstate(st->l1.hardware, bcs)) 593 return (-1); 594 st->l1.bcs = bcs; 595 st->l2.l2l1 = hdlc_l2l1; 596 setstack_manager(st); 597 bcs->st = st; 598 setstack_l1_B(st); 599 return (0); 600} 601 602#if 0 603void __init 604clear_pending_hdlc_ints(struct IsdnCardState *cs) 605{ 606 u_int val; 607 608 if (cs->subtyp == AVM_FRITZ_PCI) { 609 val = ReadHDLCPCI(cs, 0, HDLC_STATUS); 610 debugl1(cs, "HDLC 1 STA %x", val); 611 val = ReadHDLCPCI(cs, 1, HDLC_STATUS); 612 debugl1(cs, "HDLC 2 STA %x", val); 613 } else { 614 val = ReadHDLCPnP(cs, 0, HDLC_STATUS); 615 debugl1(cs, "HDLC 1 STA %x", val); 616 val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 1); 617 debugl1(cs, "HDLC 1 RML %x", val); 618 val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 2); 619 debugl1(cs, "HDLC 1 MODE %x", val); 620 val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 3); 621 debugl1(cs, "HDLC 1 VIN %x", val); 622 val = ReadHDLCPnP(cs, 1, HDLC_STATUS); 623 debugl1(cs, "HDLC 2 STA %x", val); 624 val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 1); 625 debugl1(cs, "HDLC 2 RML %x", val); 626 val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 2); 627 debugl1(cs, "HDLC 2 MODE %x", val); 628 val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 3); 629 debugl1(cs, "HDLC 2 VIN %x", val); 630 } 631} 632#endif /* 0 */ 633 634static void 635inithdlc(struct IsdnCardState *cs) 636{ 637 cs->bcs[0].BC_SetStack = setstack_hdlc; 638 cs->bcs[1].BC_SetStack = setstack_hdlc; 639 cs->bcs[0].BC_Close = close_hdlcstate; 640 cs->bcs[1].BC_Close = close_hdlcstate; 641 modehdlc(cs->bcs, -1, 0); 642 modehdlc(cs->bcs + 1, -1, 1); 643} 644 645static irqreturn_t 646avm_pcipnp_interrupt(int intno, void *dev_id) 647{ 648 struct IsdnCardState *cs = dev_id; 649 u_long flags; 650 u_char val; 651 u_char sval; 652 653 spin_lock_irqsave(&cs->lock, flags); 654 sval = inb(cs->hw.avm.cfg_reg + 2); 655 if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) { 656 /* possible a shared IRQ reqest */ 657 spin_unlock_irqrestore(&cs->lock, flags); 658 return IRQ_NONE; 659 } 660 if (!(sval & AVM_STATUS0_IRQ_ISAC)) { 661 val = ReadISAC(cs, ISAC_ISTA); 662 isac_interrupt(cs, val); 663 } 664 if (!(sval & AVM_STATUS0_IRQ_HDLC)) { 665 HDLC_irq_main(cs); 666 } 667 WriteISAC(cs, ISAC_MASK, 0xFF); 668 WriteISAC(cs, ISAC_MASK, 0x0); 669 spin_unlock_irqrestore(&cs->lock, flags); 670 return IRQ_HANDLED; 671} 672 673static void 674reset_avmpcipnp(struct IsdnCardState *cs) 675{ 676 printk(KERN_INFO "AVM PCI/PnP: reset\n"); 677 outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2); 678 mdelay(10); 679 outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2); 680 outb(AVM_STATUS1_ENA_IOM | cs->irq, cs->hw.avm.cfg_reg + 3); 681 mdelay(10); 682 printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3)); 683} 684 685static int 686AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) 687{ 688 u_long flags; 689 690 switch (mt) { 691 case CARD_RESET: 692 spin_lock_irqsave(&cs->lock, flags); 693 reset_avmpcipnp(cs); 694 spin_unlock_irqrestore(&cs->lock, flags); 695 return (0); 696 case CARD_RELEASE: 697 outb(0, cs->hw.avm.cfg_reg + 2); 698 release_region(cs->hw.avm.cfg_reg, 32); 699 return (0); 700 case CARD_INIT: 701 spin_lock_irqsave(&cs->lock, flags); 702 reset_avmpcipnp(cs); 703 clear_pending_isac_ints(cs); 704 initisac(cs); 705 inithdlc(cs); 706 outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER, 707 cs->hw.avm.cfg_reg + 2); 708 WriteISAC(cs, ISAC_MASK, 0); 709 outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | 710 AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2); 711 /* RESET Receiver and Transmitter */ 712 WriteISAC(cs, ISAC_CMDR, 0x41); 713 spin_unlock_irqrestore(&cs->lock, flags); 714 return (0); 715 case CARD_TEST: 716 return (0); 717 } 718 return (0); 719} 720 721static int avm_setup_rest(struct IsdnCardState *cs) 722{ 723 u_int val, ver; 724 725 cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; 726 if (!request_region(cs->hw.avm.cfg_reg, 32, 727 (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) { 728 printk(KERN_WARNING 729 "HiSax: Fritz!PCI/PNP config port %x-%x already in use\n", 730 cs->hw.avm.cfg_reg, 731 cs->hw.avm.cfg_reg + 31); 732 return (0); 733 } 734 switch (cs->subtyp) { 735 case AVM_FRITZ_PCI: 736 val = inl(cs->hw.avm.cfg_reg); 737 printk(KERN_INFO "AVM PCI: stat %#x\n", val); 738 printk(KERN_INFO "AVM PCI: Class %X Rev %d\n", 739 val & 0xff, (val >> 8) & 0xff); 740 cs->BC_Read_Reg = &ReadHDLC_s; 741 cs->BC_Write_Reg = &WriteHDLC_s; 742 break; 743 case AVM_FRITZ_PNP: 744 val = inb(cs->hw.avm.cfg_reg); 745 ver = inb(cs->hw.avm.cfg_reg + 1); 746 printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver); 747 cs->BC_Read_Reg = &ReadHDLCPnP; 748 cs->BC_Write_Reg = &WriteHDLCPnP; 749 break; 750 default: 751 printk(KERN_WARNING "AVM unknown subtype %d\n", cs->subtyp); 752 return (0); 753 } 754 printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n", 755 (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP", 756 cs->irq, cs->hw.avm.cfg_reg); 757 758 setup_isac(cs); 759 cs->readisac = &ReadISAC; 760 cs->writeisac = &WriteISAC; 761 cs->readisacfifo = &ReadISACfifo; 762 cs->writeisacfifo = &WriteISACfifo; 763 cs->BC_Send_Data = &hdlc_fill_fifo; 764 cs->cardmsg = &AVM_card_msg; 765 cs->irq_func = &avm_pcipnp_interrupt; 766 cs->writeisac(cs, ISAC_MASK, 0xFF); 767 ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); 768 return (1); 769} 770 771#ifndef __ISAPNP__ 772 773static int avm_pnp_setup(struct IsdnCardState *cs) 774{ 775 return (1); /* no-op: success */ 776} 777 778#else 779 780static struct pnp_card *pnp_avm_c = NULL; 781 782static int avm_pnp_setup(struct IsdnCardState *cs) 783{ 784 struct pnp_dev *pnp_avm_d = NULL; 785 786 if (!isapnp_present()) 787 return (1); /* no-op: success */ 788 789 if ((pnp_avm_c = pnp_find_card( 790 ISAPNP_VENDOR('A', 'V', 'M'), 791 ISAPNP_FUNCTION(0x0900), pnp_avm_c))) { 792 if ((pnp_avm_d = pnp_find_dev(pnp_avm_c, 793 ISAPNP_VENDOR('A', 'V', 'M'), 794 ISAPNP_FUNCTION(0x0900), pnp_avm_d))) { 795 int err; 796 797 pnp_disable_dev(pnp_avm_d); 798 err = pnp_activate_dev(pnp_avm_d); 799 if (err < 0) { 800 printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", 801 __func__, err); 802 return (0); 803 } 804 cs->hw.avm.cfg_reg = 805 pnp_port_start(pnp_avm_d, 0); 806 cs->irq = pnp_irq(pnp_avm_d, 0); 807 if (!cs->irq) { 808 printk(KERN_ERR "FritzPnP:No IRQ\n"); 809 return (0); 810 } 811 if (!cs->hw.avm.cfg_reg) { 812 printk(KERN_ERR "FritzPnP:No IO address\n"); 813 return (0); 814 } 815 cs->subtyp = AVM_FRITZ_PNP; 816 817 return (2); /* goto 'ready' label */ 818 } 819 } 820 821 return (1); 822} 823 824#endif /* __ISAPNP__ */ 825 826#ifndef CONFIG_PCI 827 828static int avm_pci_setup(struct IsdnCardState *cs) 829{ 830 return (1); /* no-op: success */ 831} 832 833#else 834 835static struct pci_dev *dev_avm = NULL; 836 837static int avm_pci_setup(struct IsdnCardState *cs) 838{ 839 if ((dev_avm = hisax_find_pci_device(PCI_VENDOR_ID_AVM, 840 PCI_DEVICE_ID_AVM_A1, dev_avm))) { 841 842 if (pci_enable_device(dev_avm)) 843 return (0); 844 845 cs->irq = dev_avm->irq; 846 if (!cs->irq) { 847 printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); 848 return (0); 849 } 850 851 cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); 852 if (!cs->hw.avm.cfg_reg) { 853 printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); 854 return (0); 855 } 856 857 cs->subtyp = AVM_FRITZ_PCI; 858 } else { 859 printk(KERN_WARNING "FritzPCI: No PCI card found\n"); 860 return (0); 861 } 862 863 cs->irq_flags |= IRQF_SHARED; 864 865 return (1); 866} 867 868#endif /* CONFIG_PCI */ 869 870int setup_avm_pcipnp(struct IsdnCard *card) 871{ 872 struct IsdnCardState *cs = card->cs; 873 char tmp[64]; 874 int rc; 875 876 strcpy(tmp, avm_pci_rev); 877 printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); 878 879 if (cs->typ != ISDN_CTYPE_FRITZPCI) 880 return (0); 881 882 if (card->para[1]) { 883 /* old manual method */ 884 cs->hw.avm.cfg_reg = card->para[1]; 885 cs->irq = card->para[0]; 886 cs->subtyp = AVM_FRITZ_PNP; 887 goto ready; 888 } 889 890 rc = avm_pnp_setup(cs); 891 if (rc < 1) 892 return (0); 893 if (rc == 2) 894 goto ready; 895 896 rc = avm_pci_setup(cs); 897 if (rc < 1) 898 return (0); 899 900ready: 901 return avm_setup_rest(cs); 902} 903