1/* 2 * 3 * IPACX specific routines 4 * 5 * Author Joerg Petersohn 6 * Derived from hisax_isac.c, isac.c, hscx.c and others 7 * 8 * This software may be used and distributed according to the terms 9 * of the GNU General Public License, incorporated herein by reference. 10 * 11 */ 12#include <linux/kernel.h> 13#include <linux/init.h> 14#include "hisax_if.h" 15#include "hisax.h" 16#include "isdnl1.h" 17#include "ipacx.h" 18 19#define DBUSY_TIMER_VALUE 80 20#define TIMER3_VALUE 7000 21#define MAX_DFRAME_LEN_L1 300 22#define B_FIFO_SIZE 64 23#define D_FIFO_SIZE 32 24 25 26// ipacx interrupt mask values 27#define _MASK_IMASK 0x2E // global mask 28#define _MASKB_IMASK 0x0B 29#define _MASKD_IMASK 0x03 // all on 30 31//---------------------------------------------------------- 32// local function declarations 33//---------------------------------------------------------- 34static void ph_command(struct IsdnCardState *cs, unsigned int command); 35static inline void cic_int(struct IsdnCardState *cs); 36static void dch_l2l1(struct PStack *st, int pr, void *arg); 37static void dbusy_timer_handler(struct IsdnCardState *cs); 38static void dch_empty_fifo(struct IsdnCardState *cs, int count); 39static void dch_fill_fifo(struct IsdnCardState *cs); 40static inline void dch_int(struct IsdnCardState *cs); 41static void dch_setstack(struct PStack *st, struct IsdnCardState *cs); 42static void dch_init(struct IsdnCardState *cs); 43static void bch_l2l1(struct PStack *st, int pr, void *arg); 44static void bch_empty_fifo(struct BCState *bcs, int count); 45static void bch_fill_fifo(struct BCState *bcs); 46static void bch_int(struct IsdnCardState *cs, u_char hscx); 47static void bch_mode(struct BCState *bcs, int mode, int bc); 48static void bch_close_state(struct BCState *bcs); 49static int bch_open_state(struct IsdnCardState *cs, struct BCState *bcs); 50static int bch_setstack(struct PStack *st, struct BCState *bcs); 51static void bch_init(struct IsdnCardState *cs, int hscx); 52static void clear_pending_ints(struct IsdnCardState *cs); 53 54//---------------------------------------------------------- 55// Issue Layer 1 command to chip 56//---------------------------------------------------------- 57static void 58ph_command(struct IsdnCardState *cs, unsigned int command) 59{ 60 if (cs->debug &L1_DEB_ISAC) 61 debugl1(cs, "ph_command (%#x) in (%#x)", command, 62 cs->dc.isac.ph_state); 63//################################### 64// printk(KERN_INFO "ph_command (%#x)\n", command); 65//################################### 66 cs->writeisac(cs, IPACX_CIX0, (command << 4) | 0x0E); 67} 68 69//---------------------------------------------------------- 70// Transceiver interrupt handler 71//---------------------------------------------------------- 72static inline void 73cic_int(struct IsdnCardState *cs) 74{ 75 u_char event; 76 77 event = cs->readisac(cs, IPACX_CIR0) >> 4; 78 if (cs->debug &L1_DEB_ISAC) debugl1(cs, "cic_int(event=%#x)", event); 79//######################################### 80// printk(KERN_INFO "cic_int(%x)\n", event); 81//######################################### 82 cs->dc.isac.ph_state = event; 83 schedule_event(cs, D_L1STATECHANGE); 84} 85 86//========================================================== 87// D channel functions 88//========================================================== 89 90//---------------------------------------------------------- 91// Command entry point 92//---------------------------------------------------------- 93static void 94dch_l2l1(struct PStack *st, int pr, void *arg) 95{ 96 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; 97 struct sk_buff *skb = arg; 98 u_char cda1_cr, cda2_cr; 99 100 switch (pr) { 101 case (PH_DATA |REQUEST): 102 if (cs->debug &DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); 103 if (cs->debug &DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); 104 if (cs->tx_skb) { 105 skb_queue_tail(&cs->sq, skb); 106#ifdef L2FRAME_DEBUG 107 if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0); 108#endif 109 } else { 110 cs->tx_skb = skb; 111 cs->tx_cnt = 0; 112#ifdef L2FRAME_DEBUG 113 if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0); 114#endif 115 dch_fill_fifo(cs); 116 } 117 break; 118 119 case (PH_PULL |INDICATION): 120 if (cs->tx_skb) { 121 if (cs->debug & L1_DEB_WARN) 122 debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); 123 skb_queue_tail(&cs->sq, skb); 124 break; 125 } 126 if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); 127 if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0); 128 cs->tx_skb = skb; 129 cs->tx_cnt = 0; 130#ifdef L2FRAME_DEBUG 131 if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); 132#endif 133 dch_fill_fifo(cs); 134 break; 135 136 case (PH_PULL | REQUEST): 137#ifdef L2FRAME_DEBUG 138 if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL"); 139#endif 140 if (!cs->tx_skb) { 141 clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 142 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); 143 } else 144 set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 145 break; 146 147 case (HW_RESET | REQUEST): 148 case (HW_ENABLE | REQUEST): 149 if ((cs->dc.isac.ph_state == IPACX_IND_RES) || 150 (cs->dc.isac.ph_state == IPACX_IND_DR) || 151 (cs->dc.isac.ph_state == IPACX_IND_DC)) 152 ph_command(cs, IPACX_CMD_TIM); 153 else 154 ph_command(cs, IPACX_CMD_RES); 155 break; 156 157 case (HW_INFO3 | REQUEST): 158 ph_command(cs, IPACX_CMD_AR8); 159 break; 160 161 case (HW_TESTLOOP | REQUEST): 162 cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1 163 cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1 164 cda1_cr = cs->readisac(cs, IPACX_CDA1_CR); 165 cda2_cr = cs->readisac(cs, IPACX_CDA2_CR); 166 if ((long)arg &1) { // loop B1 167 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a); 168 } 169 else { // B1 off 170 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x0a); 171 } 172 if ((long)arg &2) { // loop B2 173 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x14); 174 } 175 else { // B2 off 176 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x14); 177 } 178 break; 179 180 case (HW_DEACTIVATE | RESPONSE): 181 skb_queue_purge(&cs->rq); 182 skb_queue_purge(&cs->sq); 183 if (cs->tx_skb) { 184 dev_kfree_skb_any(cs->tx_skb); 185 cs->tx_skb = NULL; 186 } 187 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) 188 del_timer(&cs->dbusytimer); 189 break; 190 191 default: 192 if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_l2l1 unknown %04x", pr); 193 break; 194 } 195} 196 197//---------------------------------------------------------- 198//---------------------------------------------------------- 199static void 200dbusy_timer_handler(struct IsdnCardState *cs) 201{ 202 struct PStack *st; 203 int rbchd, stard; 204 205 if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { 206 rbchd = cs->readisac(cs, IPACX_RBCHD); 207 stard = cs->readisac(cs, IPACX_STARD); 208 if (cs->debug) 209 debugl1(cs, "D-Channel Busy RBCHD %02x STARD %02x", rbchd, stard); 210 if (!(stard &0x40)) { // D-Channel Busy 211 set_bit(FLG_L1_DBUSY, &cs->HW_Flags); 212 for (st = cs->stlist; st; st = st->next) { 213 st->l1.l1l2(st, PH_PAUSE | INDICATION, NULL); // flow control on 214 } 215 } else { 216 // seems we lost an interrupt; reset transceiver */ 217 clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags); 218 if (cs->tx_skb) { 219 dev_kfree_skb_any(cs->tx_skb); 220 cs->tx_cnt = 0; 221 cs->tx_skb = NULL; 222 } else { 223 printk(KERN_WARNING "HiSax: ISAC D-Channel Busy no skb\n"); 224 debugl1(cs, "D-Channel Busy no skb"); 225 } 226 cs->writeisac(cs, IPACX_CMDRD, 0x01); // Tx reset, generates XPR 227 } 228 } 229} 230 231//---------------------------------------------------------- 232// Fill buffer from receive FIFO 233//---------------------------------------------------------- 234static void 235dch_empty_fifo(struct IsdnCardState *cs, int count) 236{ 237 u_char *ptr; 238 239 if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO)) 240 debugl1(cs, "dch_empty_fifo()"); 241 242 // message too large, remove 243 if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) { 244 if (cs->debug &L1_DEB_WARN) 245 debugl1(cs, "dch_empty_fifo() incoming message too large"); 246 cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC 247 cs->rcvidx = 0; 248 return; 249 } 250 251 ptr = cs->rcvbuf + cs->rcvidx; 252 cs->rcvidx += count; 253 254 cs->readisacfifo(cs, ptr, count); 255 cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC 256 257 if (cs->debug &L1_DEB_ISAC_FIFO) { 258 char *t = cs->dlog; 259 260 t += sprintf(t, "dch_empty_fifo() cnt %d", count); 261 QuickHex(t, ptr, count); 262 debugl1(cs, cs->dlog); 263 } 264} 265 266//---------------------------------------------------------- 267// Fill transmit FIFO 268//---------------------------------------------------------- 269static void 270dch_fill_fifo(struct IsdnCardState *cs) 271{ 272 int count; 273 u_char cmd, *ptr; 274 275 if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO)) 276 debugl1(cs, "dch_fill_fifo()"); 277 278 if (!cs->tx_skb) return; 279 count = cs->tx_skb->len; 280 if (count <= 0) return; 281 282 if (count > D_FIFO_SIZE) { 283 count = D_FIFO_SIZE; 284 cmd = 0x08; // XTF 285 } else { 286 cmd = 0x0A; // XTF | XME 287 } 288 289 ptr = cs->tx_skb->data; 290 skb_pull(cs->tx_skb, count); 291 cs->tx_cnt += count; 292 cs->writeisacfifo(cs, ptr, count); 293 cs->writeisac(cs, IPACX_CMDRD, cmd); 294 295 // set timeout for transmission contol 296 if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { 297 debugl1(cs, "dch_fill_fifo dbusytimer running"); 298 del_timer(&cs->dbusytimer); 299 } 300 init_timer(&cs->dbusytimer); 301 cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); 302 add_timer(&cs->dbusytimer); 303 304 if (cs->debug &L1_DEB_ISAC_FIFO) { 305 char *t = cs->dlog; 306 307 t += sprintf(t, "dch_fill_fifo() cnt %d", count); 308 QuickHex(t, ptr, count); 309 debugl1(cs, cs->dlog); 310 } 311} 312 313//---------------------------------------------------------- 314// D channel interrupt handler 315//---------------------------------------------------------- 316static inline void 317dch_int(struct IsdnCardState *cs) 318{ 319 struct sk_buff *skb; 320 u_char istad, rstad; 321 int count; 322 323 istad = cs->readisac(cs, IPACX_ISTAD); 324//############################################## 325// printk(KERN_WARNING "dch_int(istad=%02x)\n", istad); 326//############################################## 327 328 if (istad &0x80) { // RME 329 rstad = cs->readisac(cs, IPACX_RSTAD); 330 if ((rstad &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB) 331 if (!(rstad &0x80)) 332 if (cs->debug &L1_DEB_WARN) 333 debugl1(cs, "dch_int(): invalid frame"); 334 if ((rstad &0x40)) 335 if (cs->debug &L1_DEB_WARN) 336 debugl1(cs, "dch_int(): RDO"); 337 if (!(rstad &0x20)) 338 if (cs->debug &L1_DEB_WARN) 339 debugl1(cs, "dch_int(): CRC error"); 340 cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC 341 } else { // received frame ok 342 count = cs->readisac(cs, IPACX_RBCLD); 343 if (count) count--; // RSTAB is last byte 344 count &= D_FIFO_SIZE-1; 345 if (count == 0) count = D_FIFO_SIZE; 346 dch_empty_fifo(cs, count); 347 if ((count = cs->rcvidx) > 0) { 348 cs->rcvidx = 0; 349 if (!(skb = dev_alloc_skb(count))) 350 printk(KERN_WARNING "HiSax dch_int(): receive out of memory\n"); 351 else { 352 memcpy(skb_put(skb, count), cs->rcvbuf, count); 353 skb_queue_tail(&cs->rq, skb); 354 } 355 } 356 } 357 cs->rcvidx = 0; 358 schedule_event(cs, D_RCVBUFREADY); 359 } 360 361 if (istad &0x40) { // RPF 362 dch_empty_fifo(cs, D_FIFO_SIZE); 363 } 364 365 if (istad &0x20) { // RFO 366 if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): RFO"); 367 cs->writeisac(cs, IPACX_CMDRD, 0x40); //RRES 368 } 369 370 if (istad &0x10) { // XPR 371 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) 372 del_timer(&cs->dbusytimer); 373 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) 374 schedule_event(cs, D_CLEARBUSY); 375 if (cs->tx_skb) { 376 if (cs->tx_skb->len) { 377 dch_fill_fifo(cs); 378 goto afterXPR; 379 } 380 else { 381 dev_kfree_skb_irq(cs->tx_skb); 382 cs->tx_skb = NULL; 383 cs->tx_cnt = 0; 384 } 385 } 386 if ((cs->tx_skb = skb_dequeue(&cs->sq))) { 387 cs->tx_cnt = 0; 388 dch_fill_fifo(cs); 389 } 390 else { 391 schedule_event(cs, D_XMTBUFREADY); 392 } 393 } 394 afterXPR: 395 396 if (istad &0x0C) { // XDU or XMR 397 if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): XDU"); 398 if (cs->tx_skb) { 399 skb_push(cs->tx_skb, cs->tx_cnt); // retransmit 400 cs->tx_cnt = 0; 401 dch_fill_fifo(cs); 402 } else { 403 printk(KERN_WARNING "HiSax: ISAC XDU no skb\n"); 404 debugl1(cs, "ISAC XDU no skb"); 405 } 406 } 407} 408 409//---------------------------------------------------------- 410//---------------------------------------------------------- 411static void 412dch_setstack(struct PStack *st, struct IsdnCardState *cs) 413{ 414 st->l1.l1hw = dch_l2l1; 415} 416 417//---------------------------------------------------------- 418//---------------------------------------------------------- 419static void 420dch_init(struct IsdnCardState *cs) 421{ 422 printk(KERN_INFO "HiSax: IPACX ISDN driver v0.1.0\n"); 423 424 cs->setstack_d = dch_setstack; 425 426 cs->dbusytimer.function = (void *) dbusy_timer_handler; 427 cs->dbusytimer.data = (long) cs; 428 init_timer(&cs->dbusytimer); 429 430 cs->writeisac(cs, IPACX_TR_CONF0, 0x00); // clear LDD 431 cs->writeisac(cs, IPACX_TR_CONF2, 0x00); // enable transmitter 432 cs->writeisac(cs, IPACX_MODED, 0xC9); // transparent mode 0, RAC, stop/go 433 cs->writeisac(cs, IPACX_MON_CR, 0x00); // disable monitor channel 434} 435 436 437//========================================================== 438// B channel functions 439//========================================================== 440 441//---------------------------------------------------------- 442// Entry point for commands 443//---------------------------------------------------------- 444static void 445bch_l2l1(struct PStack *st, int pr, void *arg) 446{ 447 struct BCState *bcs = st->l1.bcs; 448 struct sk_buff *skb = arg; 449 u_long flags; 450 451 switch (pr) { 452 case (PH_DATA | REQUEST): 453 spin_lock_irqsave(&bcs->cs->lock, flags); 454 if (bcs->tx_skb) { 455 skb_queue_tail(&bcs->squeue, skb); 456 } else { 457 bcs->tx_skb = skb; 458 set_bit(BC_FLG_BUSY, &bcs->Flag); 459 bcs->hw.hscx.count = 0; 460 bch_fill_fifo(bcs); 461 } 462 spin_unlock_irqrestore(&bcs->cs->lock, flags); 463 break; 464 case (PH_PULL | INDICATION): 465 spin_lock_irqsave(&bcs->cs->lock, flags); 466 if (bcs->tx_skb) { 467 printk(KERN_WARNING "HiSax bch_l2l1(): this shouldn't happen\n"); 468 } else { 469 set_bit(BC_FLG_BUSY, &bcs->Flag); 470 bcs->tx_skb = skb; 471 bcs->hw.hscx.count = 0; 472 bch_fill_fifo(bcs); 473 } 474 spin_unlock_irqrestore(&bcs->cs->lock, flags); 475 break; 476 case (PH_PULL | REQUEST): 477 if (!bcs->tx_skb) { 478 clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 479 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); 480 } else 481 set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 482 break; 483 case (PH_ACTIVATE | REQUEST): 484 spin_lock_irqsave(&bcs->cs->lock, flags); 485 set_bit(BC_FLG_ACTIV, &bcs->Flag); 486 bch_mode(bcs, st->l1.mode, st->l1.bc); 487 spin_unlock_irqrestore(&bcs->cs->lock, flags); 488 l1_msg_b(st, pr, arg); 489 break; 490 case (PH_DEACTIVATE | REQUEST): 491 l1_msg_b(st, pr, arg); 492 break; 493 case (PH_DEACTIVATE | CONFIRM): 494 spin_lock_irqsave(&bcs->cs->lock, flags); 495 clear_bit(BC_FLG_ACTIV, &bcs->Flag); 496 clear_bit(BC_FLG_BUSY, &bcs->Flag); 497 bch_mode(bcs, 0, st->l1.bc); 498 spin_unlock_irqrestore(&bcs->cs->lock, flags); 499 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); 500 break; 501 } 502} 503 504//---------------------------------------------------------- 505// Read B channel fifo to receive buffer 506//---------------------------------------------------------- 507static void 508bch_empty_fifo(struct BCState *bcs, int count) 509{ 510 u_char *ptr, hscx; 511 struct IsdnCardState *cs; 512 int cnt; 513 514 cs = bcs->cs; 515 hscx = bcs->hw.hscx.hscx; 516 if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO)) 517 debugl1(cs, "bch_empty_fifo()"); 518 519 // message too large, remove 520 if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { 521 if (cs->debug &L1_DEB_WARN) 522 debugl1(cs, "bch_empty_fifo() incoming packet too large"); 523 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC 524 bcs->hw.hscx.rcvidx = 0; 525 return; 526 } 527 528 ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; 529 cnt = count; 530 while (cnt--) *ptr++ = cs->BC_Read_Reg(cs, hscx, IPACX_RFIFOB); 531 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC 532 533 ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; 534 bcs->hw.hscx.rcvidx += count; 535 536 if (cs->debug &L1_DEB_HSCX_FIFO) { 537 char *t = bcs->blog; 538 539 t += sprintf(t, "bch_empty_fifo() B-%d cnt %d", hscx, count); 540 QuickHex(t, ptr, count); 541 debugl1(cs, bcs->blog); 542 } 543} 544 545//---------------------------------------------------------- 546// Fill buffer to transmit FIFO 547//---------------------------------------------------------- 548static void 549bch_fill_fifo(struct BCState *bcs) 550{ 551 struct IsdnCardState *cs; 552 int more, count, cnt; 553 u_char *ptr, *p, hscx; 554 555 cs = bcs->cs; 556 if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO)) 557 debugl1(cs, "bch_fill_fifo()"); 558 559 if (!bcs->tx_skb) return; 560 if (bcs->tx_skb->len <= 0) return; 561 562 hscx = bcs->hw.hscx.hscx; 563 more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; 564 if (bcs->tx_skb->len > B_FIFO_SIZE) { 565 more = 1; 566 count = B_FIFO_SIZE; 567 } else { 568 count = bcs->tx_skb->len; 569 } 570 cnt = count; 571 572 p = ptr = bcs->tx_skb->data; 573 skb_pull(bcs->tx_skb, count); 574 bcs->tx_cnt -= count; 575 bcs->hw.hscx.count += count; 576 while (cnt--) cs->BC_Write_Reg(cs, hscx, IPACX_XFIFOB, *p++); 577 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, (more ? 0x08 : 0x0a)); 578 579 if (cs->debug &L1_DEB_HSCX_FIFO) { 580 char *t = bcs->blog; 581 582 t += sprintf(t, "chb_fill_fifo() B-%d cnt %d", hscx, count); 583 QuickHex(t, ptr, count); 584 debugl1(cs, bcs->blog); 585 } 586} 587 588//---------------------------------------------------------- 589// B channel interrupt handler 590//---------------------------------------------------------- 591static void 592bch_int(struct IsdnCardState *cs, u_char hscx) 593{ 594 u_char istab; 595 struct BCState *bcs; 596 struct sk_buff *skb; 597 int count; 598 u_char rstab; 599 600 bcs = cs->bcs + hscx; 601 istab = cs->BC_Read_Reg(cs, hscx, IPACX_ISTAB); 602//############################################## 603// printk(KERN_WARNING "bch_int(istab=%02x)\n", istab); 604//############################################## 605 if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return; 606 607 if (istab &0x80) { // RME 608 rstab = cs->BC_Read_Reg(cs, hscx, IPACX_RSTAB); 609 if ((rstab &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB) 610 if (!(rstab &0x80)) 611 if (cs->debug &L1_DEB_WARN) 612 debugl1(cs, "bch_int() B-%d: invalid frame", hscx); 613 if ((rstab &0x40) && (bcs->mode != L1_MODE_NULL)) 614 if (cs->debug &L1_DEB_WARN) 615 debugl1(cs, "bch_int() B-%d: RDO mode=%d", hscx, bcs->mode); 616 if (!(rstab &0x20)) 617 if (cs->debug &L1_DEB_WARN) 618 debugl1(cs, "bch_int() B-%d: CRC error", hscx); 619 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC 620 } 621 else { // received frame ok 622 count = cs->BC_Read_Reg(cs, hscx, IPACX_RBCLB) &(B_FIFO_SIZE-1); 623 if (count == 0) count = B_FIFO_SIZE; 624 bch_empty_fifo(bcs, count); 625 if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { 626 if (cs->debug &L1_DEB_HSCX_FIFO) 627 debugl1(cs, "bch_int Frame %d", count); 628 if (!(skb = dev_alloc_skb(count))) 629 printk(KERN_WARNING "HiSax bch_int(): receive frame out of memory\n"); 630 else { 631 memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); 632 skb_queue_tail(&bcs->rqueue, skb); 633 } 634 } 635 } 636 bcs->hw.hscx.rcvidx = 0; 637 schedule_event(bcs, B_RCVBUFREADY); 638 } 639 640 if (istab &0x40) { // RPF 641 bch_empty_fifo(bcs, B_FIFO_SIZE); 642 643 if (bcs->mode == L1_MODE_TRANS) { // queue every chunk 644 // receive transparent audio data 645 if (!(skb = dev_alloc_skb(B_FIFO_SIZE))) 646 printk(KERN_WARNING "HiSax bch_int(): receive transparent out of memory\n"); 647 else { 648 memcpy(skb_put(skb, B_FIFO_SIZE), bcs->hw.hscx.rcvbuf, B_FIFO_SIZE); 649 skb_queue_tail(&bcs->rqueue, skb); 650 } 651 bcs->hw.hscx.rcvidx = 0; 652 schedule_event(bcs, B_RCVBUFREADY); 653 } 654 } 655 656 if (istab &0x20) { // RFO 657 if (cs->debug &L1_DEB_WARN) 658 debugl1(cs, "bch_int() B-%d: RFO error", hscx); 659 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x40); // RRES 660 } 661 662 if (istab &0x10) { // XPR 663 if (bcs->tx_skb) { 664 if (bcs->tx_skb->len) { 665 bch_fill_fifo(bcs); 666 goto afterXPR; 667 } else { 668 if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) && 669 (PACKET_NOACK != bcs->tx_skb->pkt_type)) { 670 u_long flags; 671 spin_lock_irqsave(&bcs->aclock, flags); 672 bcs->ackcnt += bcs->hw.hscx.count; 673 spin_unlock_irqrestore(&bcs->aclock, flags); 674 schedule_event(bcs, B_ACKPENDING); 675 } 676 } 677 dev_kfree_skb_irq(bcs->tx_skb); 678 bcs->hw.hscx.count = 0; 679 bcs->tx_skb = NULL; 680 } 681 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { 682 bcs->hw.hscx.count = 0; 683 set_bit(BC_FLG_BUSY, &bcs->Flag); 684 bch_fill_fifo(bcs); 685 } else { 686 clear_bit(BC_FLG_BUSY, &bcs->Flag); 687 schedule_event(bcs, B_XMTBUFREADY); 688 } 689 } 690 afterXPR: 691 692 if (istab &0x04) { // XDU 693 if (bcs->mode == L1_MODE_TRANS) { 694 bch_fill_fifo(bcs); 695 } 696 else { 697 if (bcs->tx_skb) { // restart transmitting the whole frame 698 skb_push(bcs->tx_skb, bcs->hw.hscx.count); 699 bcs->tx_cnt += bcs->hw.hscx.count; 700 bcs->hw.hscx.count = 0; 701 } 702 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x01); // XRES 703 if (cs->debug &L1_DEB_WARN) 704 debugl1(cs, "bch_int() B-%d XDU error", hscx); 705 } 706 } 707} 708 709//---------------------------------------------------------- 710//---------------------------------------------------------- 711static void 712bch_mode(struct BCState *bcs, int mode, int bc) 713{ 714 struct IsdnCardState *cs = bcs->cs; 715 int hscx = bcs->hw.hscx.hscx; 716 717 bc = bc ? 1 : 0; // in case bc is greater than 1 718 if (cs->debug & L1_DEB_HSCX) 719 debugl1(cs, "mode_bch() switch B-% mode %d chan %d", hscx, mode, bc); 720 bcs->mode = mode; 721 bcs->channel = bc; 722 723 // map controller to according timeslot 724 if (!hscx) 725 { 726 cs->writeisac(cs, IPACX_BCHA_TSDP_BC1, 0x80 | bc); 727 cs->writeisac(cs, IPACX_BCHA_CR, 0x88); 728 } 729 else 730 { 731 cs->writeisac(cs, IPACX_BCHB_TSDP_BC1, 0x80 | bc); 732 cs->writeisac(cs, IPACX_BCHB_CR, 0x88); 733 } 734 735 switch (mode) { 736 case (L1_MODE_NULL): 737 cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC0); // rec off 738 cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x30); // std adj. 739 cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, 0xFF); // ints off 740 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments 741 break; 742 case (L1_MODE_TRANS): 743 cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0x88); // ext transp mode 744 cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x00); // xxx00000 745 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments 746 cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK); 747 break; 748 case (L1_MODE_HDLC): 749 cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC8); // transp mode 0 750 cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x01); // idle=hdlc flags crc enabled 751 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments 752 cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK); 753 break; 754 } 755} 756 757//---------------------------------------------------------- 758//---------------------------------------------------------- 759static void 760bch_close_state(struct BCState *bcs) 761{ 762 bch_mode(bcs, 0, bcs->channel); 763 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 764 kfree(bcs->hw.hscx.rcvbuf); 765 bcs->hw.hscx.rcvbuf = NULL; 766 kfree(bcs->blog); 767 bcs->blog = NULL; 768 skb_queue_purge(&bcs->rqueue); 769 skb_queue_purge(&bcs->squeue); 770 if (bcs->tx_skb) { 771 dev_kfree_skb_any(bcs->tx_skb); 772 bcs->tx_skb = NULL; 773 clear_bit(BC_FLG_BUSY, &bcs->Flag); 774 } 775 } 776} 777 778//---------------------------------------------------------- 779//---------------------------------------------------------- 780static int 781bch_open_state(struct IsdnCardState *cs, struct BCState *bcs) 782{ 783 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { 784 if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { 785 printk(KERN_WARNING 786 "HiSax open_bchstate(): No memory for hscx.rcvbuf\n"); 787 clear_bit(BC_FLG_INIT, &bcs->Flag); 788 return (1); 789 } 790 if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { 791 printk(KERN_WARNING 792 "HiSax open_bchstate: No memory for bcs->blog\n"); 793 clear_bit(BC_FLG_INIT, &bcs->Flag); 794 kfree(bcs->hw.hscx.rcvbuf); 795 bcs->hw.hscx.rcvbuf = NULL; 796 return (2); 797 } 798 skb_queue_head_init(&bcs->rqueue); 799 skb_queue_head_init(&bcs->squeue); 800 } 801 bcs->tx_skb = NULL; 802 clear_bit(BC_FLG_BUSY, &bcs->Flag); 803 bcs->event = 0; 804 bcs->hw.hscx.rcvidx = 0; 805 bcs->tx_cnt = 0; 806 return (0); 807} 808 809//---------------------------------------------------------- 810//---------------------------------------------------------- 811static int 812bch_setstack(struct PStack *st, struct BCState *bcs) 813{ 814 bcs->channel = st->l1.bc; 815 if (bch_open_state(st->l1.hardware, bcs)) return (-1); 816 st->l1.bcs = bcs; 817 st->l2.l2l1 = bch_l2l1; 818 setstack_manager(st); 819 bcs->st = st; 820 setstack_l1_B(st); 821 return (0); 822} 823 824//---------------------------------------------------------- 825//---------------------------------------------------------- 826static void 827bch_init(struct IsdnCardState *cs, int hscx) 828{ 829 cs->bcs[hscx].BC_SetStack = bch_setstack; 830 cs->bcs[hscx].BC_Close = bch_close_state; 831 cs->bcs[hscx].hw.hscx.hscx = hscx; 832 cs->bcs[hscx].cs = cs; 833 bch_mode(cs->bcs + hscx, 0, hscx); 834} 835 836 837//========================================================== 838// Shared functions 839//========================================================== 840 841//---------------------------------------------------------- 842// Main interrupt handler 843//---------------------------------------------------------- 844void 845interrupt_ipacx(struct IsdnCardState *cs) 846{ 847 u_char ista; 848 849 while ((ista = cs->readisac(cs, IPACX_ISTA))) { 850//################################################# 851// printk(KERN_WARNING "interrupt_ipacx(ista=%02x)\n", ista); 852//################################################# 853 if (ista &0x80) bch_int(cs, 0); // B channel interrupts 854 if (ista &0x40) bch_int(cs, 1); 855 856 if (ista &0x01) dch_int(cs); // D channel 857 if (ista &0x10) cic_int(cs); // Layer 1 state 858 } 859} 860 861//---------------------------------------------------------- 862// Clears chip interrupt status 863//---------------------------------------------------------- 864static void 865clear_pending_ints(struct IsdnCardState *cs) 866{ 867 int ista; 868 869 // all interrupts off 870 cs->writeisac(cs, IPACX_MASK, 0xff); 871 cs->writeisac(cs, IPACX_MASKD, 0xff); 872 cs->BC_Write_Reg(cs, 0, IPACX_MASKB, 0xff); 873 cs->BC_Write_Reg(cs, 1, IPACX_MASKB, 0xff); 874 875 ista = cs->readisac(cs, IPACX_ISTA); 876 if (ista &0x80) cs->BC_Read_Reg(cs, 0, IPACX_ISTAB); 877 if (ista &0x40) cs->BC_Read_Reg(cs, 1, IPACX_ISTAB); 878 if (ista &0x10) cs->readisac(cs, IPACX_CIR0); 879 if (ista &0x01) cs->readisac(cs, IPACX_ISTAD); 880} 881 882//---------------------------------------------------------- 883// Does chip configuration work 884// Work to do depends on bit mask in part 885//---------------------------------------------------------- 886void 887init_ipacx(struct IsdnCardState *cs, int part) 888{ 889 if (part &1) { // initialise chip 890//################################################## 891// printk(KERN_INFO "init_ipacx(%x)\n", part); 892//################################################## 893 clear_pending_ints(cs); 894 bch_init(cs, 0); 895 bch_init(cs, 1); 896 dch_init(cs); 897 } 898 if (part &2) { // reenable all interrupts and start chip 899 cs->BC_Write_Reg(cs, 0, IPACX_MASKB, _MASKB_IMASK); 900 cs->BC_Write_Reg(cs, 1, IPACX_MASKB, _MASKB_IMASK); 901 cs->writeisac(cs, IPACX_MASKD, _MASKD_IMASK); 902 cs->writeisac(cs, IPACX_MASK, _MASK_IMASK); // global mask register 903 904 // reset HDLC Transmitters/receivers 905 cs->writeisac(cs, IPACX_CMDRD, 0x41); 906 cs->BC_Write_Reg(cs, 0, IPACX_CMDRB, 0x41); 907 cs->BC_Write_Reg(cs, 1, IPACX_CMDRB, 0x41); 908 ph_command(cs, IPACX_CMD_RES); 909 } 910} 911 912//----------------- end of file ----------------------- 913