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