1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * isac.c ISAC specific routines 4 * 5 * Author Karsten Keil <keil@isdn4linux.de> 6 * 7 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> 8 */ 9 10 #include <linux/irqreturn.h> 11 #include <linux/slab.h> 12 #include <linux/module.h> 13 #include <linux/mISDNhw.h> 14 #include "ipac.h" 15 16 17 #define DBUSY_TIMER_VALUE 80 18 #define ARCOFI_USE 1 19 20 #define ISAC_REV "2.0" 21 22 MODULE_AUTHOR("Karsten Keil"); 23 MODULE_VERSION(ISAC_REV); 24 MODULE_DESCRIPTION("mISDN driver for ISAC specific functions"); 25 MODULE_LICENSE("GPL v2"); 26 27 #define ReadISAC(is, o) (is->read_reg(is->dch.hw, o + is->off)) 28 #define WriteISAC(is, o, v) (is->write_reg(is->dch.hw, o + is->off, v)) 29 #define ReadHSCX(h, o) (h->ip->read_reg(h->ip->hw, h->off + o)) 30 #define WriteHSCX(h, o, v) (h->ip->write_reg(h->ip->hw, h->off + o, v)) 31 #define ReadIPAC(ip, o) (ip->read_reg(ip->hw, o)) 32 #define WriteIPAC(ip, o, v) (ip->write_reg(ip->hw, o, v)) 33 34 static inline void 35 ph_command(struct isac_hw *isac, u8 command) 36 { 37 pr_debug("%s: ph_command %x\n", isac->name, command); 38 if (isac->type & IPAC_TYPE_ISACX) 39 WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE); 40 else 41 WriteISAC(isac, ISAC_CIX0, (command << 2) | 3); 42 } 43 44 static void 45 isac_ph_state_change(struct isac_hw *isac) 46 { 47 switch (isac->state) { 48 case (ISAC_IND_RS): 49 case (ISAC_IND_EI): 50 ph_command(isac, ISAC_CMD_DUI); 51 } 52 schedule_event(&isac->dch, FLG_PHCHANGE); 53 } 54 55 static void 56 isac_ph_state_bh(struct dchannel *dch) 57 { 58 struct isac_hw *isac = container_of(dch, struct isac_hw, dch); 59 60 switch (isac->state) { 61 case ISAC_IND_RS: 62 case ISAC_IND_EI: 63 dch->state = 0; 64 l1_event(dch->l1, HW_RESET_IND); 65 break; 66 case ISAC_IND_DID: 67 dch->state = 3; 68 l1_event(dch->l1, HW_DEACT_CNF); 69 break; 70 case ISAC_IND_DR: 71 case ISAC_IND_DR6: 72 dch->state = 3; 73 l1_event(dch->l1, HW_DEACT_IND); 74 break; 75 case ISAC_IND_PU: 76 dch->state = 4; 77 l1_event(dch->l1, HW_POWERUP_IND); 78 break; 79 case ISAC_IND_RSY: 80 if (dch->state <= 5) { 81 dch->state = 5; 82 l1_event(dch->l1, ANYSIGNAL); 83 } else { 84 dch->state = 8; 85 l1_event(dch->l1, LOSTFRAMING); 86 } 87 break; 88 case ISAC_IND_ARD: 89 dch->state = 6; 90 l1_event(dch->l1, INFO2); 91 break; 92 case ISAC_IND_AI8: 93 dch->state = 7; 94 l1_event(dch->l1, INFO4_P8); 95 break; 96 case ISAC_IND_AI10: 97 dch->state = 7; 98 l1_event(dch->l1, INFO4_P10); 99 break; 100 } 101 pr_debug("%s: TE newstate %x\n", isac->name, dch->state); 102 } 103 104 static void 105 isac_empty_fifo(struct isac_hw *isac, int count) 106 { 107 u8 *ptr; 108 109 pr_debug("%s: %s %d\n", isac->name, __func__, count); 110 111 if (!isac->dch.rx_skb) { 112 isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC); 113 if (!isac->dch.rx_skb) { 114 pr_info("%s: D receive out of memory\n", isac->name); 115 WriteISAC(isac, ISAC_CMDR, 0x80); 116 return; 117 } 118 } 119 if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) { 120 pr_debug("%s: %s overrun %d\n", isac->name, __func__, 121 isac->dch.rx_skb->len + count); 122 WriteISAC(isac, ISAC_CMDR, 0x80); 123 return; 124 } 125 ptr = skb_put(isac->dch.rx_skb, count); 126 isac->read_fifo(isac->dch.hw, isac->off, ptr, count); 127 WriteISAC(isac, ISAC_CMDR, 0x80); 128 if (isac->dch.debug & DEBUG_HW_DFIFO) { 129 char pfx[MISDN_MAX_IDLEN + 16]; 130 131 snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ", 132 isac->name, count); 133 print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count); 134 } 135 } 136 137 static void 138 isac_fill_fifo(struct isac_hw *isac) 139 { 140 int count, more; 141 u8 *ptr; 142 143 if (!isac->dch.tx_skb) 144 return; 145 count = isac->dch.tx_skb->len - isac->dch.tx_idx; 146 if (count <= 0) 147 return; 148 149 more = 0; 150 if (count > 32) { 151 more = !0; 152 count = 32; 153 } 154 pr_debug("%s: %s %d\n", isac->name, __func__, count); 155 ptr = isac->dch.tx_skb->data + isac->dch.tx_idx; 156 isac->dch.tx_idx += count; 157 isac->write_fifo(isac->dch.hw, isac->off, ptr, count); 158 WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa); 159 if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) { 160 pr_debug("%s: %s dbusytimer running\n", isac->name, __func__); 161 del_timer(&isac->dch.timer); 162 } 163 isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); 164 add_timer(&isac->dch.timer); 165 if (isac->dch.debug & DEBUG_HW_DFIFO) { 166 char pfx[MISDN_MAX_IDLEN + 16]; 167 168 snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ", 169 isac->name, count); 170 print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count); 171 } 172 } 173 174 static void 175 isac_rme_irq(struct isac_hw *isac) 176 { 177 u8 val, count; 178 179 val = ReadISAC(isac, ISAC_RSTA); 180 if ((val & 0x70) != 0x20) { 181 if (val & 0x40) { 182 pr_debug("%s: ISAC RDO\n", isac->name); 183 #ifdef ERROR_STATISTIC 184 isac->dch.err_rx++; 185 #endif 186 } 187 if (!(val & 0x20)) { 188 pr_debug("%s: ISAC CRC error\n", isac->name); 189 #ifdef ERROR_STATISTIC 190 isac->dch.err_crc++; 191 #endif 192 } 193 WriteISAC(isac, ISAC_CMDR, 0x80); 194 dev_kfree_skb(isac->dch.rx_skb); 195 isac->dch.rx_skb = NULL; 196 } else { 197 count = ReadISAC(isac, ISAC_RBCL) & 0x1f; 198 if (count == 0) 199 count = 32; 200 isac_empty_fifo(isac, count); 201 recv_Dchannel(&isac->dch); 202 } 203 } 204 205 static void 206 isac_xpr_irq(struct isac_hw *isac) 207 { 208 if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) 209 del_timer(&isac->dch.timer); 210 if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) { 211 isac_fill_fifo(isac); 212 } else { 213 dev_kfree_skb(isac->dch.tx_skb); 214 if (get_next_dframe(&isac->dch)) 215 isac_fill_fifo(isac); 216 } 217 } 218 219 static void 220 isac_retransmit(struct isac_hw *isac) 221 { 222 if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) 223 del_timer(&isac->dch.timer); 224 if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) { 225 /* Restart frame */ 226 isac->dch.tx_idx = 0; 227 isac_fill_fifo(isac); 228 } else if (isac->dch.tx_skb) { /* should not happen */ 229 pr_info("%s: tx_skb exist but not busy\n", isac->name); 230 test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags); 231 isac->dch.tx_idx = 0; 232 isac_fill_fifo(isac); 233 } else { 234 pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name); 235 if (get_next_dframe(&isac->dch)) 236 isac_fill_fifo(isac); 237 } 238 } 239 240 static void 241 isac_mos_irq(struct isac_hw *isac) 242 { 243 u8 val; 244 int ret; 245 246 val = ReadISAC(isac, ISAC_MOSR); 247 pr_debug("%s: ISAC MOSR %02x\n", isac->name, val); 248 #if ARCOFI_USE 249 if (val & 0x08) { 250 if (!isac->mon_rx) { 251 isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC); 252 if (!isac->mon_rx) { 253 pr_info("%s: ISAC MON RX out of memory!\n", 254 isac->name); 255 isac->mocr &= 0xf0; 256 isac->mocr |= 0x0a; 257 WriteISAC(isac, ISAC_MOCR, isac->mocr); 258 goto afterMONR0; 259 } else 260 isac->mon_rxp = 0; 261 } 262 if (isac->mon_rxp >= MAX_MON_FRAME) { 263 isac->mocr &= 0xf0; 264 isac->mocr |= 0x0a; 265 WriteISAC(isac, ISAC_MOCR, isac->mocr); 266 isac->mon_rxp = 0; 267 pr_debug("%s: ISAC MON RX overflow!\n", isac->name); 268 goto afterMONR0; 269 } 270 isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0); 271 pr_debug("%s: ISAC MOR0 %02x\n", isac->name, 272 isac->mon_rx[isac->mon_rxp - 1]); 273 if (isac->mon_rxp == 1) { 274 isac->mocr |= 0x04; 275 WriteISAC(isac, ISAC_MOCR, isac->mocr); 276 } 277 } 278 afterMONR0: 279 if (val & 0x80) { 280 if (!isac->mon_rx) { 281 isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC); 282 if (!isac->mon_rx) { 283 pr_info("%s: ISAC MON RX out of memory!\n", 284 isac->name); 285 isac->mocr &= 0x0f; 286 isac->mocr |= 0xa0; 287 WriteISAC(isac, ISAC_MOCR, isac->mocr); 288 goto afterMONR1; 289 } else 290 isac->mon_rxp = 0; 291 } 292 if (isac->mon_rxp >= MAX_MON_FRAME) { 293 isac->mocr &= 0x0f; 294 isac->mocr |= 0xa0; 295 WriteISAC(isac, ISAC_MOCR, isac->mocr); 296 isac->mon_rxp = 0; 297 pr_debug("%s: ISAC MON RX overflow!\n", isac->name); 298 goto afterMONR1; 299 } 300 isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1); 301 pr_debug("%s: ISAC MOR1 %02x\n", isac->name, 302 isac->mon_rx[isac->mon_rxp - 1]); 303 isac->mocr |= 0x40; 304 WriteISAC(isac, ISAC_MOCR, isac->mocr); 305 } 306 afterMONR1: 307 if (val & 0x04) { 308 isac->mocr &= 0xf0; 309 WriteISAC(isac, ISAC_MOCR, isac->mocr); 310 isac->mocr |= 0x0a; 311 WriteISAC(isac, ISAC_MOCR, isac->mocr); 312 if (isac->monitor) { 313 ret = isac->monitor(isac->dch.hw, MONITOR_RX_0, 314 isac->mon_rx, isac->mon_rxp); 315 if (ret) 316 kfree(isac->mon_rx); 317 } else { 318 pr_info("%s: MONITOR 0 received %d but no user\n", 319 isac->name, isac->mon_rxp); 320 kfree(isac->mon_rx); 321 } 322 isac->mon_rx = NULL; 323 isac->mon_rxp = 0; 324 } 325 if (val & 0x40) { 326 isac->mocr &= 0x0f; 327 WriteISAC(isac, ISAC_MOCR, isac->mocr); 328 isac->mocr |= 0xa0; 329 WriteISAC(isac, ISAC_MOCR, isac->mocr); 330 if (isac->monitor) { 331 ret = isac->monitor(isac->dch.hw, MONITOR_RX_1, 332 isac->mon_rx, isac->mon_rxp); 333 if (ret) 334 kfree(isac->mon_rx); 335 } else { 336 pr_info("%s: MONITOR 1 received %d but no user\n", 337 isac->name, isac->mon_rxp); 338 kfree(isac->mon_rx); 339 } 340 isac->mon_rx = NULL; 341 isac->mon_rxp = 0; 342 } 343 if (val & 0x02) { 344 if ((!isac->mon_tx) || (isac->mon_txc && 345 (isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) { 346 isac->mocr &= 0xf0; 347 WriteISAC(isac, ISAC_MOCR, isac->mocr); 348 isac->mocr |= 0x0a; 349 WriteISAC(isac, ISAC_MOCR, isac->mocr); 350 if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { 351 if (isac->monitor) 352 isac->monitor(isac->dch.hw, 353 MONITOR_TX_0, NULL, 0); 354 } 355 kfree(isac->mon_tx); 356 isac->mon_tx = NULL; 357 isac->mon_txc = 0; 358 isac->mon_txp = 0; 359 goto AfterMOX0; 360 } 361 if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { 362 if (isac->monitor) 363 isac->monitor(isac->dch.hw, 364 MONITOR_TX_0, NULL, 0); 365 kfree(isac->mon_tx); 366 isac->mon_tx = NULL; 367 isac->mon_txc = 0; 368 isac->mon_txp = 0; 369 goto AfterMOX0; 370 } 371 WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]); 372 pr_debug("%s: ISAC %02x -> MOX0\n", isac->name, 373 isac->mon_tx[isac->mon_txp - 1]); 374 } 375 AfterMOX0: 376 if (val & 0x20) { 377 if ((!isac->mon_tx) || (isac->mon_txc && 378 (isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) { 379 isac->mocr &= 0x0f; 380 WriteISAC(isac, ISAC_MOCR, isac->mocr); 381 isac->mocr |= 0xa0; 382 WriteISAC(isac, ISAC_MOCR, isac->mocr); 383 if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { 384 if (isac->monitor) 385 isac->monitor(isac->dch.hw, 386 MONITOR_TX_1, NULL, 0); 387 } 388 kfree(isac->mon_tx); 389 isac->mon_tx = NULL; 390 isac->mon_txc = 0; 391 isac->mon_txp = 0; 392 goto AfterMOX1; 393 } 394 if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { 395 if (isac->monitor) 396 isac->monitor(isac->dch.hw, 397 MONITOR_TX_1, NULL, 0); 398 kfree(isac->mon_tx); 399 isac->mon_tx = NULL; 400 isac->mon_txc = 0; 401 isac->mon_txp = 0; 402 goto AfterMOX1; 403 } 404 WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]); 405 pr_debug("%s: ISAC %02x -> MOX1\n", isac->name, 406 isac->mon_tx[isac->mon_txp - 1]); 407 } 408 AfterMOX1: 409 val = 0; /* dummy to avoid warning */ 410 #endif 411 } 412 413 static void 414 isac_cisq_irq(struct isac_hw *isac) { 415 u8 val; 416 417 val = ReadISAC(isac, ISAC_CIR0); 418 pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val); 419 if (val & 2) { 420 pr_debug("%s: ph_state change %x->%x\n", isac->name, 421 isac->state, (val >> 2) & 0xf); 422 isac->state = (val >> 2) & 0xf; 423 isac_ph_state_change(isac); 424 } 425 if (val & 1) { 426 val = ReadISAC(isac, ISAC_CIR1); 427 pr_debug("%s: ISAC CIR1 %02X\n", isac->name, val); 428 } 429 } 430 431 static void 432 isacsx_cic_irq(struct isac_hw *isac) 433 { 434 u8 val; 435 436 val = ReadISAC(isac, ISACX_CIR0); 437 pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val); 438 if (val & ISACX_CIR0_CIC0) { 439 pr_debug("%s: ph_state change %x->%x\n", isac->name, 440 isac->state, val >> 4); 441 isac->state = val >> 4; 442 isac_ph_state_change(isac); 443 } 444 } 445 446 static void 447 isacsx_rme_irq(struct isac_hw *isac) 448 { 449 int count; 450 u8 val; 451 452 val = ReadISAC(isac, ISACX_RSTAD); 453 if ((val & (ISACX_RSTAD_VFR | 454 ISACX_RSTAD_RDO | 455 ISACX_RSTAD_CRC | 456 ISACX_RSTAD_RAB)) 457 != (ISACX_RSTAD_VFR | ISACX_RSTAD_CRC)) { 458 pr_debug("%s: RSTAD %#x, dropped\n", isac->name, val); 459 #ifdef ERROR_STATISTIC 460 if (val & ISACX_RSTAD_CRC) 461 isac->dch.err_rx++; 462 else 463 isac->dch.err_crc++; 464 #endif 465 WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC); 466 dev_kfree_skb(isac->dch.rx_skb); 467 isac->dch.rx_skb = NULL; 468 } else { 469 count = ReadISAC(isac, ISACX_RBCLD) & 0x1f; 470 if (count == 0) 471 count = 32; 472 isac_empty_fifo(isac, count); 473 if (isac->dch.rx_skb) { 474 skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1); 475 pr_debug("%s: dchannel received %d\n", isac->name, 476 isac->dch.rx_skb->len); 477 recv_Dchannel(&isac->dch); 478 } 479 } 480 } 481 482 irqreturn_t 483 mISDNisac_irq(struct isac_hw *isac, u8 val) 484 { 485 if (unlikely(!val)) 486 return IRQ_NONE; 487 pr_debug("%s: ISAC interrupt %02x\n", isac->name, val); 488 if (isac->type & IPAC_TYPE_ISACX) { 489 if (val & ISACX__CIC) 490 isacsx_cic_irq(isac); 491 if (val & ISACX__ICD) { 492 val = ReadISAC(isac, ISACX_ISTAD); 493 pr_debug("%s: ISTAD %02x\n", isac->name, val); 494 if (val & ISACX_D_XDU) { 495 pr_debug("%s: ISAC XDU\n", isac->name); 496 #ifdef ERROR_STATISTIC 497 isac->dch.err_tx++; 498 #endif 499 isac_retransmit(isac); 500 } 501 if (val & ISACX_D_XMR) { 502 pr_debug("%s: ISAC XMR\n", isac->name); 503 #ifdef ERROR_STATISTIC 504 isac->dch.err_tx++; 505 #endif 506 isac_retransmit(isac); 507 } 508 if (val & ISACX_D_XPR) 509 isac_xpr_irq(isac); 510 if (val & ISACX_D_RFO) { 511 pr_debug("%s: ISAC RFO\n", isac->name); 512 WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC); 513 } 514 if (val & ISACX_D_RME) 515 isacsx_rme_irq(isac); 516 if (val & ISACX_D_RPF) 517 isac_empty_fifo(isac, 0x20); 518 } 519 } else { 520 if (val & 0x80) /* RME */ 521 isac_rme_irq(isac); 522 if (val & 0x40) /* RPF */ 523 isac_empty_fifo(isac, 32); 524 if (val & 0x10) /* XPR */ 525 isac_xpr_irq(isac); 526 if (val & 0x04) /* CISQ */ 527 isac_cisq_irq(isac); 528 if (val & 0x20) /* RSC - never */ 529 pr_debug("%s: ISAC RSC interrupt\n", isac->name); 530 if (val & 0x02) /* SIN - never */ 531 pr_debug("%s: ISAC SIN interrupt\n", isac->name); 532 if (val & 0x01) { /* EXI */ 533 val = ReadISAC(isac, ISAC_EXIR); 534 pr_debug("%s: ISAC EXIR %02x\n", isac->name, val); 535 if (val & 0x80) /* XMR */ 536 pr_debug("%s: ISAC XMR\n", isac->name); 537 if (val & 0x40) { /* XDU */ 538 pr_debug("%s: ISAC XDU\n", isac->name); 539 #ifdef ERROR_STATISTIC 540 isac->dch.err_tx++; 541 #endif 542 isac_retransmit(isac); 543 } 544 if (val & 0x04) /* MOS */ 545 isac_mos_irq(isac); 546 } 547 } 548 return IRQ_HANDLED; 549 } 550 EXPORT_SYMBOL(mISDNisac_irq); 551 552 static int 553 isac_l1hw(struct mISDNchannel *ch, struct sk_buff *skb) 554 { 555 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); 556 struct dchannel *dch = container_of(dev, struct dchannel, dev); 557 struct isac_hw *isac = container_of(dch, struct isac_hw, dch); 558 int ret = -EINVAL; 559 struct mISDNhead *hh = mISDN_HEAD_P(skb); 560 u32 id; 561 u_long flags; 562 563 switch (hh->prim) { 564 case PH_DATA_REQ: 565 spin_lock_irqsave(isac->hwlock, flags); 566 ret = dchannel_senddata(dch, skb); 567 if (ret > 0) { /* direct TX */ 568 id = hh->id; /* skb can be freed */ 569 isac_fill_fifo(isac); 570 ret = 0; 571 spin_unlock_irqrestore(isac->hwlock, flags); 572 queue_ch_frame(ch, PH_DATA_CNF, id, NULL); 573 } else 574 spin_unlock_irqrestore(isac->hwlock, flags); 575 return ret; 576 case PH_ACTIVATE_REQ: 577 ret = l1_event(dch->l1, hh->prim); 578 break; 579 case PH_DEACTIVATE_REQ: 580 test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); 581 ret = l1_event(dch->l1, hh->prim); 582 break; 583 } 584 585 if (!ret) 586 dev_kfree_skb(skb); 587 return ret; 588 } 589 590 static int 591 isac_ctrl(struct isac_hw *isac, u32 cmd, unsigned long para) 592 { 593 u8 tl = 0; 594 unsigned long flags; 595 int ret = 0; 596 597 switch (cmd) { 598 case HW_TESTLOOP: 599 spin_lock_irqsave(isac->hwlock, flags); 600 if (!(isac->type & IPAC_TYPE_ISACX)) { 601 /* TODO: implement for IPAC_TYPE_ISACX */ 602 if (para & 1) /* B1 */ 603 tl |= 0x0c; 604 else if (para & 2) /* B2 */ 605 tl |= 0x3; 606 /* we only support IOM2 mode */ 607 WriteISAC(isac, ISAC_SPCR, tl); 608 if (tl) 609 WriteISAC(isac, ISAC_ADF1, 0x8); 610 else 611 WriteISAC(isac, ISAC_ADF1, 0x0); 612 } 613 spin_unlock_irqrestore(isac->hwlock, flags); 614 break; 615 case HW_TIMER3_VALUE: 616 ret = l1_event(isac->dch.l1, HW_TIMER3_VALUE | (para & 0xff)); 617 break; 618 default: 619 pr_debug("%s: %s unknown command %x %lx\n", isac->name, 620 __func__, cmd, para); 621 ret = -1; 622 } 623 return ret; 624 } 625 626 static int 627 isac_l1cmd(struct dchannel *dch, u32 cmd) 628 { 629 struct isac_hw *isac = container_of(dch, struct isac_hw, dch); 630 u_long flags; 631 632 pr_debug("%s: cmd(%x) state(%02x)\n", isac->name, cmd, isac->state); 633 switch (cmd) { 634 case INFO3_P8: 635 spin_lock_irqsave(isac->hwlock, flags); 636 ph_command(isac, ISAC_CMD_AR8); 637 spin_unlock_irqrestore(isac->hwlock, flags); 638 break; 639 case INFO3_P10: 640 spin_lock_irqsave(isac->hwlock, flags); 641 ph_command(isac, ISAC_CMD_AR10); 642 spin_unlock_irqrestore(isac->hwlock, flags); 643 break; 644 case HW_RESET_REQ: 645 spin_lock_irqsave(isac->hwlock, flags); 646 if ((isac->state == ISAC_IND_EI) || 647 (isac->state == ISAC_IND_DR) || 648 (isac->state == ISAC_IND_DR6) || 649 (isac->state == ISAC_IND_RS)) 650 ph_command(isac, ISAC_CMD_TIM); 651 else 652 ph_command(isac, ISAC_CMD_RS); 653 spin_unlock_irqrestore(isac->hwlock, flags); 654 break; 655 case HW_DEACT_REQ: 656 skb_queue_purge(&dch->squeue); 657 if (dch->tx_skb) { 658 dev_kfree_skb(dch->tx_skb); 659 dch->tx_skb = NULL; 660 } 661 dch->tx_idx = 0; 662 if (dch->rx_skb) { 663 dev_kfree_skb(dch->rx_skb); 664 dch->rx_skb = NULL; 665 } 666 test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); 667 if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) 668 del_timer(&dch->timer); 669 break; 670 case HW_POWERUP_REQ: 671 spin_lock_irqsave(isac->hwlock, flags); 672 ph_command(isac, ISAC_CMD_TIM); 673 spin_unlock_irqrestore(isac->hwlock, flags); 674 break; 675 case PH_ACTIVATE_IND: 676 test_and_set_bit(FLG_ACTIVE, &dch->Flags); 677 _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, 678 GFP_ATOMIC); 679 break; 680 case PH_DEACTIVATE_IND: 681 test_and_clear_bit(FLG_ACTIVE, &dch->Flags); 682 _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, 683 GFP_ATOMIC); 684 break; 685 default: 686 pr_debug("%s: %s unknown command %x\n", isac->name, 687 __func__, cmd); 688 return -1; 689 } 690 return 0; 691 } 692 693 static void 694 isac_release(struct isac_hw *isac) 695 { 696 if (isac->type & IPAC_TYPE_ISACX) 697 WriteISAC(isac, ISACX_MASK, 0xff); 698 else if (isac->type != 0) 699 WriteISAC(isac, ISAC_MASK, 0xff); 700 if (isac->dch.timer.function != NULL) { 701 del_timer(&isac->dch.timer); 702 isac->dch.timer.function = NULL; 703 } 704 kfree(isac->mon_rx); 705 isac->mon_rx = NULL; 706 kfree(isac->mon_tx); 707 isac->mon_tx = NULL; 708 if (isac->dch.l1) 709 l1_event(isac->dch.l1, CLOSE_CHANNEL); 710 mISDN_freedchannel(&isac->dch); 711 } 712 713 static void 714 dbusy_timer_handler(struct timer_list *t) 715 { 716 struct isac_hw *isac = from_timer(isac, t, dch.timer); 717 int rbch, star; 718 u_long flags; 719 720 if (test_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) { 721 spin_lock_irqsave(isac->hwlock, flags); 722 rbch = ReadISAC(isac, ISAC_RBCH); 723 star = ReadISAC(isac, ISAC_STAR); 724 pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n", 725 isac->name, rbch, star); 726 if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */ 727 test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags); 728 else { 729 /* discard frame; reset transceiver */ 730 test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags); 731 if (isac->dch.tx_idx) 732 isac->dch.tx_idx = 0; 733 else 734 pr_info("%s: ISAC D-Channel Busy no tx_idx\n", 735 isac->name); 736 /* Transmitter reset */ 737 WriteISAC(isac, ISAC_CMDR, 0x01); 738 } 739 spin_unlock_irqrestore(isac->hwlock, flags); 740 } 741 } 742 743 static int 744 open_dchannel_caller(struct isac_hw *isac, struct channel_req *rq, void *caller) 745 { 746 pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__, 747 isac->dch.dev.id, caller); 748 if (rq->protocol != ISDN_P_TE_S0) 749 return -EINVAL; 750 if (rq->adr.channel == 1) 751 /* E-Channel not supported */ 752 return -EINVAL; 753 rq->ch = &isac->dch.dev.D; 754 rq->ch->protocol = rq->protocol; 755 if (isac->dch.state == 7) 756 _queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 757 0, NULL, GFP_KERNEL); 758 return 0; 759 } 760 761 static int 762 open_dchannel(struct isac_hw *isac, struct channel_req *rq) 763 { 764 return open_dchannel_caller(isac, rq, __builtin_return_address(0)); 765 } 766 767 static const char *ISACVer[] = 768 {"2086/2186 V1.1", "2085 B1", "2085 B2", 769 "2085 V2.3"}; 770 771 static int 772 isac_init(struct isac_hw *isac) 773 { 774 u8 val; 775 int err = 0; 776 777 if (!isac->dch.l1) { 778 err = create_l1(&isac->dch, isac_l1cmd); 779 if (err) 780 return err; 781 } 782 isac->mon_tx = NULL; 783 isac->mon_rx = NULL; 784 timer_setup(&isac->dch.timer, dbusy_timer_handler, 0); 785 isac->mocr = 0xaa; 786 if (isac->type & IPAC_TYPE_ISACX) { 787 /* Disable all IRQ */ 788 WriteISAC(isac, ISACX_MASK, 0xff); 789 val = ReadISAC(isac, ISACX_STARD); 790 pr_debug("%s: ISACX STARD %x\n", isac->name, val); 791 val = ReadISAC(isac, ISACX_ISTAD); 792 pr_debug("%s: ISACX ISTAD %x\n", isac->name, val); 793 val = ReadISAC(isac, ISACX_ISTA); 794 pr_debug("%s: ISACX ISTA %x\n", isac->name, val); 795 /* clear LDD */ 796 WriteISAC(isac, ISACX_TR_CONF0, 0x00); 797 /* enable transmitter */ 798 WriteISAC(isac, ISACX_TR_CONF2, 0x00); 799 /* transparent mode 0, RAC, stop/go */ 800 WriteISAC(isac, ISACX_MODED, 0xc9); 801 /* all HDLC IRQ unmasked */ 802 val = ReadISAC(isac, ISACX_ID); 803 if (isac->dch.debug & DEBUG_HW) 804 pr_notice("%s: ISACX Design ID %x\n", 805 isac->name, val & 0x3f); 806 val = ReadISAC(isac, ISACX_CIR0); 807 pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val); 808 isac->state = val >> 4; 809 isac_ph_state_change(isac); 810 ph_command(isac, ISAC_CMD_RS); 811 WriteISAC(isac, ISACX_MASK, IPACX__ON); 812 WriteISAC(isac, ISACX_MASKD, 0x00); 813 } else { /* old isac */ 814 WriteISAC(isac, ISAC_MASK, 0xff); 815 val = ReadISAC(isac, ISAC_STAR); 816 pr_debug("%s: ISAC STAR %x\n", isac->name, val); 817 val = ReadISAC(isac, ISAC_MODE); 818 pr_debug("%s: ISAC MODE %x\n", isac->name, val); 819 val = ReadISAC(isac, ISAC_ADF2); 820 pr_debug("%s: ISAC ADF2 %x\n", isac->name, val); 821 val = ReadISAC(isac, ISAC_ISTA); 822 pr_debug("%s: ISAC ISTA %x\n", isac->name, val); 823 if (val & 0x01) { 824 val = ReadISAC(isac, ISAC_EXIR); 825 pr_debug("%s: ISAC EXIR %x\n", isac->name, val); 826 } 827 val = ReadISAC(isac, ISAC_RBCH); 828 if (isac->dch.debug & DEBUG_HW) 829 pr_notice("%s: ISAC version (%x): %s\n", isac->name, 830 val, ISACVer[(val >> 5) & 3]); 831 isac->type |= ((val >> 5) & 3); 832 if (!isac->adf2) 833 isac->adf2 = 0x80; 834 if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */ 835 pr_info("%s: only support IOM2 mode but adf2=%02x\n", 836 isac->name, isac->adf2); 837 isac_release(isac); 838 return -EINVAL; 839 } 840 WriteISAC(isac, ISAC_ADF2, isac->adf2); 841 WriteISAC(isac, ISAC_SQXR, 0x2f); 842 WriteISAC(isac, ISAC_SPCR, 0x00); 843 WriteISAC(isac, ISAC_STCR, 0x70); 844 WriteISAC(isac, ISAC_MODE, 0xc9); 845 WriteISAC(isac, ISAC_TIMR, 0x00); 846 WriteISAC(isac, ISAC_ADF1, 0x00); 847 val = ReadISAC(isac, ISAC_CIR0); 848 pr_debug("%s: ISAC CIR0 %x\n", isac->name, val); 849 isac->state = (val >> 2) & 0xf; 850 isac_ph_state_change(isac); 851 ph_command(isac, ISAC_CMD_RS); 852 WriteISAC(isac, ISAC_MASK, 0); 853 } 854 return err; 855 } 856 857 int 858 mISDNisac_init(struct isac_hw *isac, void *hw) 859 { 860 mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh); 861 isac->dch.hw = hw; 862 isac->dch.dev.D.send = isac_l1hw; 863 isac->init = isac_init; 864 isac->release = isac_release; 865 isac->ctrl = isac_ctrl; 866 isac->open = open_dchannel; 867 isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0); 868 isac->dch.dev.nrbchan = 2; 869 return 0; 870 } 871 EXPORT_SYMBOL(mISDNisac_init); 872 873 static void 874 waitforCEC(struct hscx_hw *hx) 875 { 876 u8 starb, to = 50; 877 878 while (to) { 879 starb = ReadHSCX(hx, IPAC_STARB); 880 if (!(starb & 0x04)) 881 break; 882 udelay(1); 883 to--; 884 } 885 if (to < 50) 886 pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr, 887 50 - to); 888 if (!to) 889 pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr); 890 } 891 892 893 static void 894 waitforXFW(struct hscx_hw *hx) 895 { 896 u8 starb, to = 50; 897 898 while (to) { 899 starb = ReadHSCX(hx, IPAC_STARB); 900 if ((starb & 0x44) == 0x40) 901 break; 902 udelay(1); 903 to--; 904 } 905 if (to < 50) 906 pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr, 907 50 - to); 908 if (!to) 909 pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr); 910 } 911 912 static void 913 hscx_cmdr(struct hscx_hw *hx, u8 cmd) 914 { 915 if (hx->ip->type & IPAC_TYPE_IPACX) 916 WriteHSCX(hx, IPACX_CMDRB, cmd); 917 else { 918 waitforCEC(hx); 919 WriteHSCX(hx, IPAC_CMDRB, cmd); 920 } 921 } 922 923 static void 924 hscx_empty_fifo(struct hscx_hw *hscx, u8 count) 925 { 926 u8 *p; 927 int maxlen; 928 929 pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count); 930 if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) { 931 hscx->bch.dropcnt += count; 932 hscx_cmdr(hscx, 0x80); /* RMC */ 933 return; 934 } 935 maxlen = bchannel_get_rxbuf(&hscx->bch, count); 936 if (maxlen < 0) { 937 hscx_cmdr(hscx, 0x80); /* RMC */ 938 if (hscx->bch.rx_skb) 939 skb_trim(hscx->bch.rx_skb, 0); 940 pr_warn("%s.B%d: No bufferspace for %d bytes\n", 941 hscx->ip->name, hscx->bch.nr, count); 942 return; 943 } 944 p = skb_put(hscx->bch.rx_skb, count); 945 946 if (hscx->ip->type & IPAC_TYPE_IPACX) 947 hscx->ip->read_fifo(hscx->ip->hw, 948 hscx->off + IPACX_RFIFOB, p, count); 949 else 950 hscx->ip->read_fifo(hscx->ip->hw, 951 hscx->off, p, count); 952 953 hscx_cmdr(hscx, 0x80); /* RMC */ 954 955 if (hscx->bch.debug & DEBUG_HW_BFIFO) { 956 snprintf(hscx->log, 64, "B%1d-recv %s %d ", 957 hscx->bch.nr, hscx->ip->name, count); 958 print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count); 959 } 960 } 961 962 static void 963 hscx_fill_fifo(struct hscx_hw *hscx) 964 { 965 int count, more; 966 u8 *p; 967 968 if (!hscx->bch.tx_skb) { 969 if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags)) 970 return; 971 count = hscx->fifo_size; 972 more = 1; 973 p = hscx->log; 974 memset(p, hscx->bch.fill[0], count); 975 } else { 976 count = hscx->bch.tx_skb->len - hscx->bch.tx_idx; 977 if (count <= 0) 978 return; 979 p = hscx->bch.tx_skb->data + hscx->bch.tx_idx; 980 981 more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0; 982 if (count > hscx->fifo_size) { 983 count = hscx->fifo_size; 984 more = 1; 985 } 986 pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, 987 count, hscx->bch.tx_idx, hscx->bch.tx_skb->len); 988 hscx->bch.tx_idx += count; 989 } 990 if (hscx->ip->type & IPAC_TYPE_IPACX) 991 hscx->ip->write_fifo(hscx->ip->hw, 992 hscx->off + IPACX_XFIFOB, p, count); 993 else { 994 waitforXFW(hscx); 995 hscx->ip->write_fifo(hscx->ip->hw, 996 hscx->off, p, count); 997 } 998 hscx_cmdr(hscx, more ? 0x08 : 0x0a); 999 1000 if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) { 1001 snprintf(hscx->log, 64, "B%1d-send %s %d ", 1002 hscx->bch.nr, hscx->ip->name, count); 1003 print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count); 1004 } 1005 } 1006 1007 static void 1008 hscx_xpr(struct hscx_hw *hx) 1009 { 1010 if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) { 1011 hscx_fill_fifo(hx); 1012 } else { 1013 dev_kfree_skb(hx->bch.tx_skb); 1014 if (get_next_bframe(&hx->bch)) { 1015 hscx_fill_fifo(hx); 1016 test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags); 1017 } else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) { 1018 hscx_fill_fifo(hx); 1019 } 1020 } 1021 } 1022 1023 static void 1024 ipac_rme(struct hscx_hw *hx) 1025 { 1026 int count; 1027 u8 rstab; 1028 1029 if (hx->ip->type & IPAC_TYPE_IPACX) 1030 rstab = ReadHSCX(hx, IPACX_RSTAB); 1031 else 1032 rstab = ReadHSCX(hx, IPAC_RSTAB); 1033 pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab); 1034 if ((rstab & 0xf0) != 0xa0) { 1035 /* !(VFR && !RDO && CRC && !RAB) */ 1036 if (!(rstab & 0x80)) { 1037 if (hx->bch.debug & DEBUG_HW_BCHANNEL) 1038 pr_notice("%s: B%1d invalid frame\n", 1039 hx->ip->name, hx->bch.nr); 1040 } 1041 if (rstab & 0x40) { 1042 if (hx->bch.debug & DEBUG_HW_BCHANNEL) 1043 pr_notice("%s: B%1d RDO proto=%x\n", 1044 hx->ip->name, hx->bch.nr, 1045 hx->bch.state); 1046 } 1047 if (!(rstab & 0x20)) { 1048 if (hx->bch.debug & DEBUG_HW_BCHANNEL) 1049 pr_notice("%s: B%1d CRC error\n", 1050 hx->ip->name, hx->bch.nr); 1051 } 1052 hscx_cmdr(hx, 0x80); /* Do RMC */ 1053 return; 1054 } 1055 if (hx->ip->type & IPAC_TYPE_IPACX) 1056 count = ReadHSCX(hx, IPACX_RBCLB); 1057 else 1058 count = ReadHSCX(hx, IPAC_RBCLB); 1059 count &= (hx->fifo_size - 1); 1060 if (count == 0) 1061 count = hx->fifo_size; 1062 hscx_empty_fifo(hx, count); 1063 if (!hx->bch.rx_skb) 1064 return; 1065 if (hx->bch.rx_skb->len < 2) { 1066 pr_debug("%s: B%1d frame too short %d\n", 1067 hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len); 1068 skb_trim(hx->bch.rx_skb, 0); 1069 } else { 1070 skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1); 1071 recv_Bchannel(&hx->bch, 0, false); 1072 } 1073 } 1074 1075 static void 1076 ipac_irq(struct hscx_hw *hx, u8 ista) 1077 { 1078 u8 istab, m, exirb = 0; 1079 1080 if (hx->ip->type & IPAC_TYPE_IPACX) 1081 istab = ReadHSCX(hx, IPACX_ISTAB); 1082 else if (hx->ip->type & IPAC_TYPE_IPAC) { 1083 istab = ReadHSCX(hx, IPAC_ISTAB); 1084 m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB; 1085 if (m & ista) { 1086 exirb = ReadHSCX(hx, IPAC_EXIRB); 1087 pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name, 1088 hx->bch.nr, exirb); 1089 } 1090 } else if (hx->bch.nr & 2) { /* HSCX B */ 1091 if (ista & (HSCX__EXA | HSCX__ICA)) 1092 ipac_irq(&hx->ip->hscx[0], ista); 1093 if (ista & HSCX__EXB) { 1094 exirb = ReadHSCX(hx, IPAC_EXIRB); 1095 pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name, 1096 hx->bch.nr, exirb); 1097 } 1098 istab = ista & 0xF8; 1099 } else { /* HSCX A */ 1100 istab = ReadHSCX(hx, IPAC_ISTAB); 1101 if (ista & HSCX__EXA) { 1102 exirb = ReadHSCX(hx, IPAC_EXIRB); 1103 pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name, 1104 hx->bch.nr, exirb); 1105 } 1106 istab = istab & 0xF8; 1107 } 1108 if (exirb & IPAC_B_XDU) 1109 istab |= IPACX_B_XDU; 1110 if (exirb & IPAC_B_RFO) 1111 istab |= IPACX_B_RFO; 1112 pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab); 1113 1114 if (!test_bit(FLG_ACTIVE, &hx->bch.Flags)) 1115 return; 1116 1117 if (istab & IPACX_B_RME) 1118 ipac_rme(hx); 1119 1120 if (istab & IPACX_B_RPF) { 1121 hscx_empty_fifo(hx, hx->fifo_size); 1122 if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) 1123 recv_Bchannel(&hx->bch, 0, false); 1124 } 1125 1126 if (istab & IPACX_B_RFO) { 1127 pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr); 1128 hscx_cmdr(hx, 0x40); /* RRES */ 1129 } 1130 1131 if (istab & IPACX_B_XPR) 1132 hscx_xpr(hx); 1133 1134 if (istab & IPACX_B_XDU) { 1135 if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { 1136 if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags)) 1137 test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags); 1138 hscx_xpr(hx); 1139 return; 1140 } 1141 pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name, 1142 hx->bch.nr, hx->bch.tx_idx); 1143 hx->bch.tx_idx = 0; 1144 hscx_cmdr(hx, 0x01); /* XRES */ 1145 } 1146 } 1147 1148 irqreturn_t 1149 mISDNipac_irq(struct ipac_hw *ipac, int maxloop) 1150 { 1151 int cnt = maxloop + 1; 1152 u8 ista, istad; 1153 struct isac_hw *isac = &ipac->isac; 1154 1155 if (ipac->type & IPAC_TYPE_IPACX) { 1156 ista = ReadIPAC(ipac, ISACX_ISTA); 1157 while (ista && --cnt) { 1158 pr_debug("%s: ISTA %02x\n", ipac->name, ista); 1159 if (ista & IPACX__ICA) 1160 ipac_irq(&ipac->hscx[0], ista); 1161 if (ista & IPACX__ICB) 1162 ipac_irq(&ipac->hscx[1], ista); 1163 if (ista & (ISACX__ICD | ISACX__CIC)) 1164 mISDNisac_irq(&ipac->isac, ista); 1165 ista = ReadIPAC(ipac, ISACX_ISTA); 1166 } 1167 } else if (ipac->type & IPAC_TYPE_IPAC) { 1168 ista = ReadIPAC(ipac, IPAC_ISTA); 1169 while (ista && --cnt) { 1170 pr_debug("%s: ISTA %02x\n", ipac->name, ista); 1171 if (ista & (IPAC__ICD | IPAC__EXD)) { 1172 istad = ReadISAC(isac, ISAC_ISTA); 1173 pr_debug("%s: ISTAD %02x\n", ipac->name, istad); 1174 if (istad & IPAC_D_TIN2) 1175 pr_debug("%s TIN2 irq\n", ipac->name); 1176 if (ista & IPAC__EXD) 1177 istad |= 1; /* ISAC EXI */ 1178 mISDNisac_irq(isac, istad); 1179 } 1180 if (ista & (IPAC__ICA | IPAC__EXA)) 1181 ipac_irq(&ipac->hscx[0], ista); 1182 if (ista & (IPAC__ICB | IPAC__EXB)) 1183 ipac_irq(&ipac->hscx[1], ista); 1184 ista = ReadIPAC(ipac, IPAC_ISTA); 1185 } 1186 } else if (ipac->type & IPAC_TYPE_HSCX) { 1187 while (--cnt) { 1188 ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off); 1189 pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista); 1190 if (ista) 1191 ipac_irq(&ipac->hscx[1], ista); 1192 istad = ReadISAC(isac, ISAC_ISTA); 1193 pr_debug("%s: ISTAD %02x\n", ipac->name, istad); 1194 if (istad) 1195 mISDNisac_irq(isac, istad); 1196 if (0 == (ista | istad)) 1197 break; 1198 } 1199 } 1200 if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */ 1201 return IRQ_NONE; 1202 if (cnt < maxloop) 1203 pr_debug("%s: %d irqloops cpu%d\n", ipac->name, 1204 maxloop - cnt, smp_processor_id()); 1205 if (maxloop && !cnt) 1206 pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name, 1207 maxloop, smp_processor_id()); 1208 return IRQ_HANDLED; 1209 } 1210 EXPORT_SYMBOL(mISDNipac_irq); 1211 1212 static int 1213 hscx_mode(struct hscx_hw *hscx, u32 bprotocol) 1214 { 1215 pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name, 1216 '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr); 1217 if (hscx->ip->type & IPAC_TYPE_IPACX) { 1218 if (hscx->bch.nr & 1) { /* B1 and ICA */ 1219 WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80); 1220 WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88); 1221 } else { /* B2 and ICB */ 1222 WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81); 1223 WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88); 1224 } 1225 switch (bprotocol) { 1226 case ISDN_P_NONE: /* init */ 1227 WriteHSCX(hscx, IPACX_MODEB, 0xC0); /* rec off */ 1228 WriteHSCX(hscx, IPACX_EXMB, 0x30); /* std adj. */ 1229 WriteHSCX(hscx, IPACX_MASKB, 0xFF); /* ints off */ 1230 hscx_cmdr(hscx, 0x41); 1231 test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags); 1232 test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags); 1233 break; 1234 case ISDN_P_B_RAW: 1235 WriteHSCX(hscx, IPACX_MODEB, 0x88); /* ex trans */ 1236 WriteHSCX(hscx, IPACX_EXMB, 0x00); /* trans */ 1237 hscx_cmdr(hscx, 0x41); 1238 WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON); 1239 test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags); 1240 break; 1241 case ISDN_P_B_HDLC: 1242 WriteHSCX(hscx, IPACX_MODEB, 0xC0); /* trans */ 1243 WriteHSCX(hscx, IPACX_EXMB, 0x00); /* hdlc,crc */ 1244 hscx_cmdr(hscx, 0x41); 1245 WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON); 1246 test_and_set_bit(FLG_HDLC, &hscx->bch.Flags); 1247 break; 1248 default: 1249 pr_info("%s: protocol not known %x\n", hscx->ip->name, 1250 bprotocol); 1251 return -ENOPROTOOPT; 1252 } 1253 } else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */ 1254 WriteHSCX(hscx, IPAC_CCR1, 0x82); 1255 WriteHSCX(hscx, IPAC_CCR2, 0x30); 1256 WriteHSCX(hscx, IPAC_XCCR, 0x07); 1257 WriteHSCX(hscx, IPAC_RCCR, 0x07); 1258 WriteHSCX(hscx, IPAC_TSAX, hscx->slot); 1259 WriteHSCX(hscx, IPAC_TSAR, hscx->slot); 1260 switch (bprotocol) { 1261 case ISDN_P_NONE: 1262 WriteHSCX(hscx, IPAC_TSAX, 0x1F); 1263 WriteHSCX(hscx, IPAC_TSAR, 0x1F); 1264 WriteHSCX(hscx, IPAC_MODEB, 0x84); 1265 WriteHSCX(hscx, IPAC_CCR1, 0x82); 1266 WriteHSCX(hscx, IPAC_MASKB, 0xFF); /* ints off */ 1267 test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags); 1268 test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags); 1269 break; 1270 case ISDN_P_B_RAW: 1271 WriteHSCX(hscx, IPAC_MODEB, 0xe4); /* ex trans */ 1272 WriteHSCX(hscx, IPAC_CCR1, 0x82); 1273 hscx_cmdr(hscx, 0x41); 1274 WriteHSCX(hscx, IPAC_MASKB, 0); 1275 test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags); 1276 break; 1277 case ISDN_P_B_HDLC: 1278 WriteHSCX(hscx, IPAC_MODEB, 0x8c); 1279 WriteHSCX(hscx, IPAC_CCR1, 0x8a); 1280 hscx_cmdr(hscx, 0x41); 1281 WriteHSCX(hscx, IPAC_MASKB, 0); 1282 test_and_set_bit(FLG_HDLC, &hscx->bch.Flags); 1283 break; 1284 default: 1285 pr_info("%s: protocol not known %x\n", hscx->ip->name, 1286 bprotocol); 1287 return -ENOPROTOOPT; 1288 } 1289 } else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */ 1290 WriteHSCX(hscx, IPAC_CCR1, 0x85); 1291 WriteHSCX(hscx, IPAC_CCR2, 0x30); 1292 WriteHSCX(hscx, IPAC_XCCR, 0x07); 1293 WriteHSCX(hscx, IPAC_RCCR, 0x07); 1294 WriteHSCX(hscx, IPAC_TSAX, hscx->slot); 1295 WriteHSCX(hscx, IPAC_TSAR, hscx->slot); 1296 switch (bprotocol) { 1297 case ISDN_P_NONE: 1298 WriteHSCX(hscx, IPAC_TSAX, 0x1F); 1299 WriteHSCX(hscx, IPAC_TSAR, 0x1F); 1300 WriteHSCX(hscx, IPAC_MODEB, 0x84); 1301 WriteHSCX(hscx, IPAC_CCR1, 0x85); 1302 WriteHSCX(hscx, IPAC_MASKB, 0xFF); /* ints off */ 1303 test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags); 1304 test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags); 1305 break; 1306 case ISDN_P_B_RAW: 1307 WriteHSCX(hscx, IPAC_MODEB, 0xe4); /* ex trans */ 1308 WriteHSCX(hscx, IPAC_CCR1, 0x85); 1309 hscx_cmdr(hscx, 0x41); 1310 WriteHSCX(hscx, IPAC_MASKB, 0); 1311 test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags); 1312 break; 1313 case ISDN_P_B_HDLC: 1314 WriteHSCX(hscx, IPAC_MODEB, 0x8c); 1315 WriteHSCX(hscx, IPAC_CCR1, 0x8d); 1316 hscx_cmdr(hscx, 0x41); 1317 WriteHSCX(hscx, IPAC_MASKB, 0); 1318 test_and_set_bit(FLG_HDLC, &hscx->bch.Flags); 1319 break; 1320 default: 1321 pr_info("%s: protocol not known %x\n", hscx->ip->name, 1322 bprotocol); 1323 return -ENOPROTOOPT; 1324 } 1325 } else 1326 return -EINVAL; 1327 hscx->bch.state = bprotocol; 1328 return 0; 1329 } 1330 1331 static int 1332 hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb) 1333 { 1334 struct bchannel *bch = container_of(ch, struct bchannel, ch); 1335 struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch); 1336 int ret = -EINVAL; 1337 struct mISDNhead *hh = mISDN_HEAD_P(skb); 1338 unsigned long flags; 1339 1340 switch (hh->prim) { 1341 case PH_DATA_REQ: 1342 spin_lock_irqsave(hx->ip->hwlock, flags); 1343 ret = bchannel_senddata(bch, skb); 1344 if (ret > 0) { /* direct TX */ 1345 ret = 0; 1346 hscx_fill_fifo(hx); 1347 } 1348 spin_unlock_irqrestore(hx->ip->hwlock, flags); 1349 return ret; 1350 case PH_ACTIVATE_REQ: 1351 spin_lock_irqsave(hx->ip->hwlock, flags); 1352 if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) 1353 ret = hscx_mode(hx, ch->protocol); 1354 else 1355 ret = 0; 1356 spin_unlock_irqrestore(hx->ip->hwlock, flags); 1357 if (!ret) 1358 _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, 1359 NULL, GFP_KERNEL); 1360 break; 1361 case PH_DEACTIVATE_REQ: 1362 spin_lock_irqsave(hx->ip->hwlock, flags); 1363 mISDN_clear_bchannel(bch); 1364 hscx_mode(hx, ISDN_P_NONE); 1365 spin_unlock_irqrestore(hx->ip->hwlock, flags); 1366 _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, 1367 NULL, GFP_KERNEL); 1368 ret = 0; 1369 break; 1370 default: 1371 pr_info("%s: %s unknown prim(%x,%x)\n", 1372 hx->ip->name, __func__, hh->prim, hh->id); 1373 ret = -EINVAL; 1374 } 1375 if (!ret) 1376 dev_kfree_skb(skb); 1377 return ret; 1378 } 1379 1380 static int 1381 channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) 1382 { 1383 return mISDN_ctrl_bchannel(bch, cq); 1384 } 1385 1386 static int 1387 hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) 1388 { 1389 struct bchannel *bch = container_of(ch, struct bchannel, ch); 1390 struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch); 1391 int ret = -EINVAL; 1392 u_long flags; 1393 1394 pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg); 1395 switch (cmd) { 1396 case CLOSE_CHANNEL: 1397 test_and_clear_bit(FLG_OPEN, &bch->Flags); 1398 cancel_work_sync(&bch->workq); 1399 spin_lock_irqsave(hx->ip->hwlock, flags); 1400 mISDN_clear_bchannel(bch); 1401 hscx_mode(hx, ISDN_P_NONE); 1402 spin_unlock_irqrestore(hx->ip->hwlock, flags); 1403 ch->protocol = ISDN_P_NONE; 1404 ch->peer = NULL; 1405 module_put(hx->ip->owner); 1406 ret = 0; 1407 break; 1408 case CONTROL_CHANNEL: 1409 ret = channel_bctrl(bch, arg); 1410 break; 1411 default: 1412 pr_info("%s: %s unknown prim(%x)\n", 1413 hx->ip->name, __func__, cmd); 1414 } 1415 return ret; 1416 } 1417 1418 static void 1419 free_ipac(struct ipac_hw *ipac) 1420 { 1421 isac_release(&ipac->isac); 1422 } 1423 1424 static const char *HSCXVer[] = 1425 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7", 1426 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"}; 1427 1428 1429 1430 static void 1431 hscx_init(struct hscx_hw *hx) 1432 { 1433 u8 val; 1434 1435 WriteHSCX(hx, IPAC_RAH2, 0xFF); 1436 WriteHSCX(hx, IPAC_XBCH, 0x00); 1437 WriteHSCX(hx, IPAC_RLCR, 0x00); 1438 1439 if (hx->ip->type & IPAC_TYPE_HSCX) { 1440 WriteHSCX(hx, IPAC_CCR1, 0x85); 1441 val = ReadHSCX(hx, HSCX_VSTR); 1442 pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val); 1443 if (hx->bch.debug & DEBUG_HW) 1444 pr_notice("%s: HSCX version %s\n", hx->ip->name, 1445 HSCXVer[val & 0x0f]); 1446 } else 1447 WriteHSCX(hx, IPAC_CCR1, 0x82); 1448 WriteHSCX(hx, IPAC_CCR2, 0x30); 1449 WriteHSCX(hx, IPAC_XCCR, 0x07); 1450 WriteHSCX(hx, IPAC_RCCR, 0x07); 1451 } 1452 1453 static int 1454 ipac_init(struct ipac_hw *ipac) 1455 { 1456 u8 val; 1457 1458 if (ipac->type & IPAC_TYPE_HSCX) { 1459 hscx_init(&ipac->hscx[0]); 1460 hscx_init(&ipac->hscx[1]); 1461 val = ReadIPAC(ipac, IPAC_ID); 1462 } else if (ipac->type & IPAC_TYPE_IPAC) { 1463 hscx_init(&ipac->hscx[0]); 1464 hscx_init(&ipac->hscx[1]); 1465 WriteIPAC(ipac, IPAC_MASK, IPAC__ON); 1466 val = ReadIPAC(ipac, IPAC_CONF); 1467 /* conf is default 0, but can be overwritten by card setup */ 1468 pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name, 1469 val, ipac->conf); 1470 WriteIPAC(ipac, IPAC_CONF, ipac->conf); 1471 val = ReadIPAC(ipac, IPAC_ID); 1472 if (ipac->hscx[0].bch.debug & DEBUG_HW) 1473 pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val); 1474 } 1475 /* nothing special for IPACX to do here */ 1476 return isac_init(&ipac->isac); 1477 } 1478 1479 static int 1480 open_bchannel(struct ipac_hw *ipac, struct channel_req *rq) 1481 { 1482 struct bchannel *bch; 1483 1484 if (rq->adr.channel == 0 || rq->adr.channel > 2) 1485 return -EINVAL; 1486 if (rq->protocol == ISDN_P_NONE) 1487 return -EINVAL; 1488 bch = &ipac->hscx[rq->adr.channel - 1].bch; 1489 if (test_and_set_bit(FLG_OPEN, &bch->Flags)) 1490 return -EBUSY; /* b-channel can be only open once */ 1491 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); 1492 bch->ch.protocol = rq->protocol; 1493 rq->ch = &bch->ch; 1494 return 0; 1495 } 1496 1497 static int 1498 channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq) 1499 { 1500 int ret = 0; 1501 1502 switch (cq->op) { 1503 case MISDN_CTRL_GETOP: 1504 cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3; 1505 break; 1506 case MISDN_CTRL_LOOP: 1507 /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */ 1508 if (cq->channel < 0 || cq->channel > 3) { 1509 ret = -EINVAL; 1510 break; 1511 } 1512 ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel); 1513 break; 1514 case MISDN_CTRL_L1_TIMER3: 1515 ret = ipac->isac.ctrl(&ipac->isac, HW_TIMER3_VALUE, cq->p1); 1516 break; 1517 default: 1518 pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op); 1519 ret = -EINVAL; 1520 break; 1521 } 1522 return ret; 1523 } 1524 1525 static int 1526 ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg) 1527 { 1528 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); 1529 struct dchannel *dch = container_of(dev, struct dchannel, dev); 1530 struct isac_hw *isac = container_of(dch, struct isac_hw, dch); 1531 struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac); 1532 struct channel_req *rq; 1533 int err = 0; 1534 1535 pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg); 1536 switch (cmd) { 1537 case OPEN_CHANNEL: 1538 rq = arg; 1539 if (rq->protocol == ISDN_P_TE_S0) 1540 err = open_dchannel_caller(isac, rq, __builtin_return_address(0)); 1541 else 1542 err = open_bchannel(ipac, rq); 1543 if (err) 1544 break; 1545 if (!try_module_get(ipac->owner)) 1546 pr_info("%s: cannot get module\n", ipac->name); 1547 break; 1548 case CLOSE_CHANNEL: 1549 pr_debug("%s: dev(%d) close from %p\n", ipac->name, 1550 dch->dev.id, __builtin_return_address(0)); 1551 module_put(ipac->owner); 1552 break; 1553 case CONTROL_CHANNEL: 1554 err = channel_ctrl(ipac, arg); 1555 break; 1556 default: 1557 pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd); 1558 return -EINVAL; 1559 } 1560 return err; 1561 } 1562 1563 u32 1564 mISDNipac_init(struct ipac_hw *ipac, void *hw) 1565 { 1566 u32 ret; 1567 u8 i; 1568 1569 ipac->hw = hw; 1570 if (ipac->isac.dch.debug & DEBUG_HW) 1571 pr_notice("%s: ipac type %x\n", ipac->name, ipac->type); 1572 if (ipac->type & IPAC_TYPE_HSCX) { 1573 ipac->isac.type = IPAC_TYPE_ISAC; 1574 ipac->hscx[0].off = 0; 1575 ipac->hscx[1].off = 0x40; 1576 ipac->hscx[0].fifo_size = 32; 1577 ipac->hscx[1].fifo_size = 32; 1578 } else if (ipac->type & IPAC_TYPE_IPAC) { 1579 ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC; 1580 ipac->hscx[0].off = 0; 1581 ipac->hscx[1].off = 0x40; 1582 ipac->hscx[0].fifo_size = 64; 1583 ipac->hscx[1].fifo_size = 64; 1584 } else if (ipac->type & IPAC_TYPE_IPACX) { 1585 ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX; 1586 ipac->hscx[0].off = IPACX_OFF_ICA; 1587 ipac->hscx[1].off = IPACX_OFF_ICB; 1588 ipac->hscx[0].fifo_size = 64; 1589 ipac->hscx[1].fifo_size = 64; 1590 } else 1591 return 0; 1592 1593 mISDNisac_init(&ipac->isac, hw); 1594 1595 ipac->isac.dch.dev.D.ctrl = ipac_dctrl; 1596 1597 for (i = 0; i < 2; i++) { 1598 ipac->hscx[i].bch.nr = i + 1; 1599 set_channelmap(i + 1, ipac->isac.dch.dev.channelmap); 1600 list_add(&ipac->hscx[i].bch.ch.list, 1601 &ipac->isac.dch.dev.bchannels); 1602 mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM, 1603 ipac->hscx[i].fifo_size); 1604 ipac->hscx[i].bch.ch.nr = i + 1; 1605 ipac->hscx[i].bch.ch.send = &hscx_l2l1; 1606 ipac->hscx[i].bch.ch.ctrl = hscx_bctrl; 1607 ipac->hscx[i].bch.hw = hw; 1608 ipac->hscx[i].ip = ipac; 1609 /* default values for IOM time slots 1610 * can be overwritten by card */ 1611 ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03; 1612 } 1613 1614 ipac->init = ipac_init; 1615 ipac->release = free_ipac; 1616 1617 ret = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | 1618 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); 1619 return ret; 1620 } 1621 EXPORT_SYMBOL(mISDNipac_init); 1622 1623 static int __init 1624 isac_mod_init(void) 1625 { 1626 pr_notice("mISDNipac module version %s\n", ISAC_REV); 1627 return 0; 1628 } 1629 1630 static void __exit 1631 isac_mod_cleanup(void) 1632 { 1633 pr_notice("mISDNipac module unloaded\n"); 1634 } 1635 module_init(isac_mod_init); 1636 module_exit(isac_mod_cleanup); 1637