1/* $Id: netjet.c,v 1.29.2.4 2004/02/11 13:21:34 keil Exp $ 2 * 3 * low level stuff for Traverse Technologie NETJet ISDN cards 4 * 5 * Author Karsten Keil 6 * Copyright by Karsten Keil <keil@isdn4linux.de> 7 * 8 * This software may be used and distributed according to the terms 9 * of the GNU General Public License, incorporated herein by reference. 10 * 11 * Thanks to Traverse Technologies Australia for documents and information 12 * 13 * 16-Apr-2002 - led code added - Guy Ellis (guy@traverse.com.au) 14 * 15 */ 16 17#include <linux/init.h> 18#include "hisax.h" 19#include "isac.h" 20#include "hscx.h" 21#include "isdnl1.h" 22#include <linux/interrupt.h> 23#include <linux/ppp_defs.h> 24#include <linux/slab.h> 25#include <asm/io.h> 26#include "netjet.h" 27 28/* Interface functions */ 29 30u_char 31NETjet_ReadIC(struct IsdnCardState *cs, u_char offset) 32{ 33 u_char ret; 34 35 cs->hw.njet.auxd &= 0xfc; 36 cs->hw.njet.auxd |= (offset >> 4) & 3; 37 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 38 ret = bytein(cs->hw.njet.isac + ((offset & 0xf) << 2)); 39 return (ret); 40} 41 42void 43NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value) 44{ 45 cs->hw.njet.auxd &= 0xfc; 46 cs->hw.njet.auxd |= (offset >> 4) & 3; 47 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 48 byteout(cs->hw.njet.isac + ((offset & 0xf) << 2), value); 49} 50 51void 52NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size) 53{ 54 cs->hw.njet.auxd &= 0xfc; 55 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 56 insb(cs->hw.njet.isac, data, size); 57} 58 59void 60NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size) 61{ 62 cs->hw.njet.auxd &= 0xfc; 63 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 64 outsb(cs->hw.njet.isac, data, size); 65} 66 67static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill) 68{ 69 u_int mask = 0x000000ff, val = 0, *p = pos; 70 u_int i; 71 72 val |= fill; 73 if (chan) { 74 val <<= 8; 75 mask <<= 8; 76 } 77 mask ^= 0xffffffff; 78 for (i = 0; i < cnt; i++) { 79 *p &= mask; 80 *p++ |= val; 81 if (p > bcs->hw.tiger.s_end) 82 p = bcs->hw.tiger.send; 83 } 84} 85 86static void 87mode_tiger(struct BCState *bcs, int mode, int bc) 88{ 89 struct IsdnCardState *cs = bcs->cs; 90 u_char led; 91 92 if (cs->debug & L1_DEB_HSCX) 93 debugl1(cs, "Tiger mode %d bchan %d/%d", 94 mode, bc, bcs->channel); 95 bcs->mode = mode; 96 bcs->channel = bc; 97 switch (mode) { 98 case (L1_MODE_NULL): 99 fill_mem(bcs, bcs->hw.tiger.send, 100 NETJET_DMA_TXSIZE, bc, 0xff); 101 if (cs->debug & L1_DEB_HSCX) 102 debugl1(cs, "Tiger stat rec %d/%d send %d", 103 bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err, 104 bcs->hw.tiger.s_tot); 105 if ((cs->bcs[0].mode == L1_MODE_NULL) && 106 (cs->bcs[1].mode == L1_MODE_NULL)) { 107 cs->hw.njet.dmactrl = 0; 108 byteout(cs->hw.njet.base + NETJET_DMACTRL, 109 cs->hw.njet.dmactrl); 110 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); 111 } 112 if (cs->typ == ISDN_CTYPE_NETJET_S) 113 { 114 // led off 115 led = bc & 0x01; 116 led = 0x01 << (6 + led); // convert to mask 117 led = ~led; 118 cs->hw.njet.auxd &= led; 119 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 120 } 121 break; 122 case (L1_MODE_TRANS): 123 break; 124 case (L1_MODE_HDLC_56K): 125 case (L1_MODE_HDLC): 126 fill_mem(bcs, bcs->hw.tiger.send, 127 NETJET_DMA_TXSIZE, bc, 0xff); 128 bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH; 129 bcs->hw.tiger.r_tot = 0; 130 bcs->hw.tiger.r_bitcnt = 0; 131 bcs->hw.tiger.r_one = 0; 132 bcs->hw.tiger.r_err = 0; 133 bcs->hw.tiger.s_tot = 0; 134 if (!cs->hw.njet.dmactrl) { 135 fill_mem(bcs, bcs->hw.tiger.send, 136 NETJET_DMA_TXSIZE, !bc, 0xff); 137 cs->hw.njet.dmactrl = 1; 138 byteout(cs->hw.njet.base + NETJET_DMACTRL, 139 cs->hw.njet.dmactrl); 140 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x0f); 141 /* was 0x3f now 0x0f for TJ300 and TJ320 GE 13/07/00 */ 142 } 143 bcs->hw.tiger.sendp = bcs->hw.tiger.send; 144 bcs->hw.tiger.free = NETJET_DMA_TXSIZE; 145 test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag); 146 if (cs->typ == ISDN_CTYPE_NETJET_S) 147 { 148 // led on 149 led = bc & 0x01; 150 led = 0x01 << (6 + led); // convert to mask 151 cs->hw.njet.auxd |= led; 152 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 153 } 154 break; 155 } 156 if (cs->debug & L1_DEB_HSCX) 157 debugl1(cs, "tiger: set %x %x %x %x/%x pulse=%d", 158 bytein(cs->hw.njet.base + NETJET_DMACTRL), 159 bytein(cs->hw.njet.base + NETJET_IRQMASK0), 160 bytein(cs->hw.njet.base + NETJET_IRQSTAT0), 161 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR), 162 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR), 163 bytein(cs->hw.njet.base + NETJET_PULSE_CNT)); 164} 165 166static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s) { 167 char tmp[128]; 168 char *t = tmp; 169 int i = count, j; 170 u_char *p = buf; 171 172 t += sprintf(t, "tiger %s(%4d)", s, count); 173 while (i > 0) { 174 if (i > 16) 175 j = 16; 176 else 177 j = i; 178 QuickHex(t, p, j); 179 debugl1(cs, tmp); 180 p += j; 181 i -= j; 182 t = tmp; 183 t += sprintf(t, "tiger %s ", s); 184 } 185} 186 187// macro for 64k 188 189#define MAKE_RAW_BYTE for (j = 0; j < 8; j++) { \ 190 bitcnt++; \ 191 s_val >>= 1; \ 192 if (val & 1) { \ 193 s_one++; \ 194 s_val |= 0x80; \ 195 } else { \ 196 s_one = 0; \ 197 s_val &= 0x7f; \ 198 } \ 199 if (bitcnt == 8) { \ 200 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; \ 201 bitcnt = 0; \ 202 } \ 203 if (s_one == 5) { \ 204 s_val >>= 1; \ 205 s_val &= 0x7f; \ 206 bitcnt++; \ 207 s_one = 0; \ 208 } \ 209 if (bitcnt == 8) { \ 210 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; \ 211 bitcnt = 0; \ 212 } \ 213 val >>= 1; \ 214 } 215 216static int make_raw_data(struct BCState *bcs) { 217// this make_raw is for 64k 218 register u_int i, s_cnt = 0; 219 register u_char j; 220 register u_char val; 221 register u_char s_one = 0; 222 register u_char s_val = 0; 223 register u_char bitcnt = 0; 224 u_int fcs; 225 226 if (!bcs->tx_skb) { 227 debugl1(bcs->cs, "tiger make_raw: NULL skb"); 228 return (1); 229 } 230 bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE; 231 fcs = PPP_INITFCS; 232 for (i = 0; i < bcs->tx_skb->len; i++) { 233 val = bcs->tx_skb->data[i]; 234 fcs = PPP_FCS(fcs, val); 235 MAKE_RAW_BYTE; 236 } 237 fcs ^= 0xffff; 238 val = fcs & 0xff; 239 MAKE_RAW_BYTE; 240 val = (fcs >> 8) & 0xff; 241 MAKE_RAW_BYTE; 242 val = HDLC_FLAG_VALUE; 243 for (j = 0; j < 8; j++) { 244 bitcnt++; 245 s_val >>= 1; 246 if (val & 1) 247 s_val |= 0x80; 248 else 249 s_val &= 0x7f; 250 if (bitcnt == 8) { 251 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 252 bitcnt = 0; 253 } 254 val >>= 1; 255 } 256 if (bcs->cs->debug & L1_DEB_HSCX) 257 debugl1(bcs->cs, "tiger make_raw: in %u out %d.%d", 258 bcs->tx_skb->len, s_cnt, bitcnt); 259 if (bitcnt) { 260 while (8 > bitcnt++) { 261 s_val >>= 1; 262 s_val |= 0x80; 263 } 264 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 265 bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix 266 } 267 bcs->hw.tiger.sendcnt = s_cnt; 268 bcs->tx_cnt -= bcs->tx_skb->len; 269 bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf; 270 return (0); 271} 272 273// macro for 56k 274 275#define MAKE_RAW_BYTE_56K for (j = 0; j < 8; j++) { \ 276 bitcnt++; \ 277 s_val >>= 1; \ 278 if (val & 1) { \ 279 s_one++; \ 280 s_val |= 0x80; \ 281 } else { \ 282 s_one = 0; \ 283 s_val &= 0x7f; \ 284 } \ 285 if (bitcnt == 7) { \ 286 s_val >>= 1; \ 287 s_val |= 0x80; \ 288 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; \ 289 bitcnt = 0; \ 290 } \ 291 if (s_one == 5) { \ 292 s_val >>= 1; \ 293 s_val &= 0x7f; \ 294 bitcnt++; \ 295 s_one = 0; \ 296 } \ 297 if (bitcnt == 7) { \ 298 s_val >>= 1; \ 299 s_val |= 0x80; \ 300 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; \ 301 bitcnt = 0; \ 302 } \ 303 val >>= 1; \ 304 } 305 306static int make_raw_data_56k(struct BCState *bcs) { 307// this make_raw is for 56k 308 register u_int i, s_cnt = 0; 309 register u_char j; 310 register u_char val; 311 register u_char s_one = 0; 312 register u_char s_val = 0; 313 register u_char bitcnt = 0; 314 u_int fcs; 315 316 if (!bcs->tx_skb) { 317 debugl1(bcs->cs, "tiger make_raw_56k: NULL skb"); 318 return (1); 319 } 320 val = HDLC_FLAG_VALUE; 321 for (j = 0; j < 8; j++) { 322 bitcnt++; 323 s_val >>= 1; 324 if (val & 1) 325 s_val |= 0x80; 326 else 327 s_val &= 0x7f; 328 if (bitcnt == 7) { 329 s_val >>= 1; 330 s_val |= 0x80; 331 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 332 bitcnt = 0; 333 } 334 val >>= 1; 335 }; 336 fcs = PPP_INITFCS; 337 for (i = 0; i < bcs->tx_skb->len; i++) { 338 val = bcs->tx_skb->data[i]; 339 fcs = PPP_FCS(fcs, val); 340 MAKE_RAW_BYTE_56K; 341 } 342 fcs ^= 0xffff; 343 val = fcs & 0xff; 344 MAKE_RAW_BYTE_56K; 345 val = (fcs >> 8) & 0xff; 346 MAKE_RAW_BYTE_56K; 347 val = HDLC_FLAG_VALUE; 348 for (j = 0; j < 8; j++) { 349 bitcnt++; 350 s_val >>= 1; 351 if (val & 1) 352 s_val |= 0x80; 353 else 354 s_val &= 0x7f; 355 if (bitcnt == 7) { 356 s_val >>= 1; 357 s_val |= 0x80; 358 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 359 bitcnt = 0; 360 } 361 val >>= 1; 362 } 363 if (bcs->cs->debug & L1_DEB_HSCX) 364 debugl1(bcs->cs, "tiger make_raw_56k: in %u out %d.%d", 365 bcs->tx_skb->len, s_cnt, bitcnt); 366 if (bitcnt) { 367 while (8 > bitcnt++) { 368 s_val >>= 1; 369 s_val |= 0x80; 370 } 371 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 372 bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix 373 } 374 bcs->hw.tiger.sendcnt = s_cnt; 375 bcs->tx_cnt -= bcs->tx_skb->len; 376 bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf; 377 return (0); 378} 379 380static void got_frame(struct BCState *bcs, int count) { 381 struct sk_buff *skb; 382 383 if (!(skb = dev_alloc_skb(count))) 384 printk(KERN_WARNING "TIGER: receive out of memory\n"); 385 else { 386 memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count); 387 skb_queue_tail(&bcs->rqueue, skb); 388 } 389 test_and_set_bit(B_RCVBUFREADY, &bcs->event); 390 schedule_work(&bcs->tqueue); 391 392 if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME) 393 printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec"); 394} 395 396 397 398static void read_raw(struct BCState *bcs, u_int *buf, int cnt) { 399 int i; 400 register u_char j; 401 register u_char val; 402 u_int *pend = bcs->hw.tiger.rec + NETJET_DMA_RXSIZE - 1; 403 register u_char state = bcs->hw.tiger.r_state; 404 register u_char r_one = bcs->hw.tiger.r_one; 405 register u_char r_val = bcs->hw.tiger.r_val; 406 register u_int bitcnt = bcs->hw.tiger.r_bitcnt; 407 u_int *p = buf; 408 int bits; 409 u_char mask; 410 411 if (bcs->mode == L1_MODE_HDLC) { // it's 64k 412 mask = 0xff; 413 bits = 8; 414 } 415 else { // it's 56K 416 mask = 0x7f; 417 bits = 7; 418 }; 419 for (i = 0; i < cnt; i++) { 420 val = bcs->channel ? ((*p >> 8) & 0xff) : (*p & 0xff); 421 p++; 422 if (p > pend) 423 p = bcs->hw.tiger.rec; 424 if ((val & mask) == mask) { 425 state = HDLC_ZERO_SEARCH; 426 bcs->hw.tiger.r_tot++; 427 bitcnt = 0; 428 r_one = 0; 429 continue; 430 } 431 for (j = 0; j < bits; j++) { 432 if (state == HDLC_ZERO_SEARCH) { 433 if (val & 1) { 434 r_one++; 435 } else { 436 r_one = 0; 437 state = HDLC_FLAG_SEARCH; 438 if (bcs->cs->debug & L1_DEB_HSCX) 439 debugl1(bcs->cs, "tiger read_raw: zBit(%d,%d,%d) %x", 440 bcs->hw.tiger.r_tot, i, j, val); 441 } 442 } else if (state == HDLC_FLAG_SEARCH) { 443 if (val & 1) { 444 r_one++; 445 if (r_one > 6) { 446 state = HDLC_ZERO_SEARCH; 447 } 448 } else { 449 if (r_one == 6) { 450 bitcnt = 0; 451 r_val = 0; 452 state = HDLC_FLAG_FOUND; 453 if (bcs->cs->debug & L1_DEB_HSCX) 454 debugl1(bcs->cs, "tiger read_raw: flag(%d,%d,%d) %x", 455 bcs->hw.tiger.r_tot, i, j, val); 456 } 457 r_one = 0; 458 } 459 } else if (state == HDLC_FLAG_FOUND) { 460 if (val & 1) { 461 r_one++; 462 if (r_one > 6) { 463 state = HDLC_ZERO_SEARCH; 464 } else { 465 r_val >>= 1; 466 r_val |= 0x80; 467 bitcnt++; 468 } 469 } else { 470 if (r_one == 6) { 471 bitcnt = 0; 472 r_val = 0; 473 r_one = 0; 474 val >>= 1; 475 continue; 476 } else if (r_one != 5) { 477 r_val >>= 1; 478 r_val &= 0x7f; 479 bitcnt++; 480 } 481 r_one = 0; 482 } 483 if ((state != HDLC_ZERO_SEARCH) && 484 !(bitcnt & 7)) { 485 state = HDLC_FRAME_FOUND; 486 bcs->hw.tiger.r_fcs = PPP_INITFCS; 487 bcs->hw.tiger.rcvbuf[0] = r_val; 488 bcs->hw.tiger.r_fcs = PPP_FCS(bcs->hw.tiger.r_fcs, r_val); 489 if (bcs->cs->debug & L1_DEB_HSCX) 490 debugl1(bcs->cs, "tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x", 491 bcs->hw.tiger.r_tot, i, j, r_val, val, 492 bcs->cs->hw.njet.irqstat0); 493 } 494 } else if (state == HDLC_FRAME_FOUND) { 495 if (val & 1) { 496 r_one++; 497 if (r_one > 6) { 498 state = HDLC_ZERO_SEARCH; 499 bitcnt = 0; 500 } else { 501 r_val >>= 1; 502 r_val |= 0x80; 503 bitcnt++; 504 } 505 } else { 506 if (r_one == 6) { 507 r_val = 0; 508 r_one = 0; 509 bitcnt++; 510 if (bitcnt & 7) { 511 debugl1(bcs->cs, "tiger: frame not byte aligned"); 512 state = HDLC_FLAG_SEARCH; 513 bcs->hw.tiger.r_err++; 514#ifdef ERROR_STATISTIC 515 bcs->err_inv++; 516#endif 517 } else { 518 if (bcs->cs->debug & L1_DEB_HSCX) 519 debugl1(bcs->cs, "tiger frame end(%d,%d): fcs(%x) i %x", 520 i, j, bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0); 521 if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) { 522 got_frame(bcs, (bitcnt >> 3) - 3); 523 } else { 524 if (bcs->cs->debug) { 525 debugl1(bcs->cs, "tiger FCS error"); 526 printframe(bcs->cs, bcs->hw.tiger.rcvbuf, 527 (bitcnt >> 3) - 1, "rec"); 528 bcs->hw.tiger.r_err++; 529 } 530#ifdef ERROR_STATISTIC 531 bcs->err_crc++; 532#endif 533 } 534 state = HDLC_FLAG_FOUND; 535 } 536 bitcnt = 0; 537 } else if (r_one == 5) { 538 val >>= 1; 539 r_one = 0; 540 continue; 541 } else { 542 r_val >>= 1; 543 r_val &= 0x7f; 544 bitcnt++; 545 } 546 r_one = 0; 547 } 548 if ((state == HDLC_FRAME_FOUND) && 549 !(bitcnt & 7)) { 550 if ((bitcnt >> 3) >= HSCX_BUFMAX) { 551 debugl1(bcs->cs, "tiger: frame too big"); 552 r_val = 0; 553 state = HDLC_FLAG_SEARCH; 554 bcs->hw.tiger.r_err++; 555#ifdef ERROR_STATISTIC 556 bcs->err_inv++; 557#endif 558 } else { 559 bcs->hw.tiger.rcvbuf[(bitcnt >> 3) - 1] = r_val; 560 bcs->hw.tiger.r_fcs = 561 PPP_FCS(bcs->hw.tiger.r_fcs, r_val); 562 } 563 } 564 } 565 val >>= 1; 566 } 567 bcs->hw.tiger.r_tot++; 568 } 569 bcs->hw.tiger.r_state = state; 570 bcs->hw.tiger.r_one = r_one; 571 bcs->hw.tiger.r_val = r_val; 572 bcs->hw.tiger.r_bitcnt = bitcnt; 573} 574 575void read_tiger(struct IsdnCardState *cs) { 576 u_int *p; 577 int cnt = NETJET_DMA_RXSIZE / 2; 578 579 if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) { 580 debugl1(cs, "tiger warn read double dma %x/%x", 581 cs->hw.njet.irqstat0, cs->hw.njet.last_is0); 582#ifdef ERROR_STATISTIC 583 if (cs->bcs[0].mode) 584 cs->bcs[0].err_rdo++; 585 if (cs->bcs[1].mode) 586 cs->bcs[1].err_rdo++; 587#endif 588 return; 589 } else { 590 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ; 591 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ); 592 } 593 if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1) 594 p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1; 595 else 596 p = cs->bcs[0].hw.tiger.rec + cnt - 1; 597 if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K)) 598 read_raw(cs->bcs, p, cnt); 599 600 if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K)) 601 read_raw(cs->bcs + 1, p, cnt); 602 cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ; 603} 604 605static void write_raw(struct BCState *bcs, u_int *buf, int cnt); 606 607void netjet_fill_dma(struct BCState *bcs) 608{ 609 register u_int *p, *sp; 610 register int cnt; 611 612 if (!bcs->tx_skb) 613 return; 614 if (bcs->cs->debug & L1_DEB_HSCX) 615 debugl1(bcs->cs, "tiger fill_dma1: c%d %4lx", bcs->channel, 616 bcs->Flag); 617 if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag)) 618 return; 619 if (bcs->mode == L1_MODE_HDLC) { // it's 64k 620 if (make_raw_data(bcs)) 621 return; 622 } 623 else { // it's 56k 624 if (make_raw_data_56k(bcs)) 625 return; 626 }; 627 if (bcs->cs->debug & L1_DEB_HSCX) 628 debugl1(bcs->cs, "tiger fill_dma2: c%d %4lx", bcs->channel, 629 bcs->Flag); 630 if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { 631 write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); 632 } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) { 633 p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR)); 634 sp = bcs->hw.tiger.sendp; 635 if (p == bcs->hw.tiger.s_end) 636 p = bcs->hw.tiger.send - 1; 637 if (sp == bcs->hw.tiger.s_end) 638 sp = bcs->hw.tiger.send - 1; 639 cnt = p - sp; 640 if (cnt < 0) { 641 write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); 642 } else { 643 p++; 644 cnt++; 645 if (p > bcs->hw.tiger.s_end) 646 p = bcs->hw.tiger.send; 647 p++; 648 cnt++; 649 if (p > bcs->hw.tiger.s_end) 650 p = bcs->hw.tiger.send; 651 write_raw(bcs, p, bcs->hw.tiger.free - cnt); 652 } 653 } else if (test_and_clear_bit(BC_FLG_EMPTY, &bcs->Flag)) { 654 p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR)); 655 cnt = bcs->hw.tiger.s_end - p; 656 if (cnt < 2) { 657 p = bcs->hw.tiger.send + 1; 658 cnt = NETJET_DMA_TXSIZE / 2 - 2; 659 } else { 660 p++; 661 p++; 662 if (cnt <= (NETJET_DMA_TXSIZE / 2)) 663 cnt += NETJET_DMA_TXSIZE / 2; 664 cnt--; 665 cnt--; 666 } 667 write_raw(bcs, p, cnt); 668 } 669 if (bcs->cs->debug & L1_DEB_HSCX) 670 debugl1(bcs->cs, "tiger fill_dma3: c%d %4lx", bcs->channel, 671 bcs->Flag); 672} 673 674static void write_raw(struct BCState *bcs, u_int *buf, int cnt) { 675 u_int mask, val, *p = buf; 676 u_int i, s_cnt; 677 678 if (cnt <= 0) 679 return; 680 if (test_bit(BC_FLG_BUSY, &bcs->Flag)) { 681 if (bcs->hw.tiger.sendcnt > cnt) { 682 s_cnt = cnt; 683 bcs->hw.tiger.sendcnt -= cnt; 684 } else { 685 s_cnt = bcs->hw.tiger.sendcnt; 686 bcs->hw.tiger.sendcnt = 0; 687 } 688 if (bcs->channel) 689 mask = 0xffff00ff; 690 else 691 mask = 0xffffff00; 692 for (i = 0; i < s_cnt; i++) { 693 val = bcs->channel ? ((bcs->hw.tiger.sp[i] << 8) & 0xff00) : 694 (bcs->hw.tiger.sp[i]); 695 *p &= mask; 696 *p++ |= val; 697 if (p > bcs->hw.tiger.s_end) 698 p = bcs->hw.tiger.send; 699 } 700 bcs->hw.tiger.s_tot += s_cnt; 701 if (bcs->cs->debug & L1_DEB_HSCX) 702 debugl1(bcs->cs, "tiger write_raw: c%d %p-%p %d/%d %d %x", bcs->channel, 703 buf, p, s_cnt, cnt, 704 bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0); 705 if (bcs->cs->debug & L1_DEB_HSCX_FIFO) 706 printframe(bcs->cs, bcs->hw.tiger.sp, s_cnt, "snd"); 707 bcs->hw.tiger.sp += s_cnt; 708 bcs->hw.tiger.sendp = p; 709 if (!bcs->hw.tiger.sendcnt) { 710 if (!bcs->tx_skb) { 711 debugl1(bcs->cs, "tiger write_raw: NULL skb s_cnt %d", s_cnt); 712 } else { 713 if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && 714 (PACKET_NOACK != bcs->tx_skb->pkt_type)) { 715 u_long flags; 716 spin_lock_irqsave(&bcs->aclock, flags); 717 bcs->ackcnt += bcs->tx_skb->len; 718 spin_unlock_irqrestore(&bcs->aclock, flags); 719 schedule_event(bcs, B_ACKPENDING); 720 } 721 dev_kfree_skb_any(bcs->tx_skb); 722 bcs->tx_skb = NULL; 723 } 724 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 725 bcs->hw.tiger.free = cnt - s_cnt; 726 if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE / 2)) 727 test_and_set_bit(BC_FLG_HALF, &bcs->Flag); 728 else { 729 test_and_clear_bit(BC_FLG_HALF, &bcs->Flag); 730 test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag); 731 } 732 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { 733 netjet_fill_dma(bcs); 734 } else { 735 mask ^= 0xffffffff; 736 if (s_cnt < cnt) { 737 for (i = s_cnt; i < cnt; i++) { 738 *p++ |= mask; 739 if (p > bcs->hw.tiger.s_end) 740 p = bcs->hw.tiger.send; 741 } 742 if (bcs->cs->debug & L1_DEB_HSCX) 743 debugl1(bcs->cs, "tiger write_raw: fill rest %d", 744 cnt - s_cnt); 745 } 746 test_and_set_bit(B_XMTBUFREADY, &bcs->event); 747 schedule_work(&bcs->tqueue); 748 } 749 } 750 } else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { 751 test_and_set_bit(BC_FLG_HALF, &bcs->Flag); 752 fill_mem(bcs, buf, cnt, bcs->channel, 0xff); 753 bcs->hw.tiger.free += cnt; 754 if (bcs->cs->debug & L1_DEB_HSCX) 755 debugl1(bcs->cs, "tiger write_raw: fill half"); 756 } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) { 757 test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag); 758 fill_mem(bcs, buf, cnt, bcs->channel, 0xff); 759 if (bcs->cs->debug & L1_DEB_HSCX) 760 debugl1(bcs->cs, "tiger write_raw: fill full"); 761 } 762} 763 764void write_tiger(struct IsdnCardState *cs) { 765 u_int *p, cnt = NETJET_DMA_TXSIZE / 2; 766 767 if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) { 768 debugl1(cs, "tiger warn write double dma %x/%x", 769 cs->hw.njet.irqstat0, cs->hw.njet.last_is0); 770#ifdef ERROR_STATISTIC 771 if (cs->bcs[0].mode) 772 cs->bcs[0].err_tx++; 773 if (cs->bcs[1].mode) 774 cs->bcs[1].err_tx++; 775#endif 776 return; 777 } else { 778 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE; 779 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE); 780 } 781 if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE_1) 782 p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1; 783 else 784 p = cs->bcs[0].hw.tiger.send + cnt - 1; 785 if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K)) 786 write_raw(cs->bcs, p, cnt); 787 if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K)) 788 write_raw(cs->bcs + 1, p, cnt); 789 cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE; 790} 791 792static void 793tiger_l2l1(struct PStack *st, int pr, void *arg) 794{ 795 struct BCState *bcs = st->l1.bcs; 796 struct sk_buff *skb = arg; 797 u_long flags; 798 799 switch (pr) { 800 case (PH_DATA | REQUEST): 801 spin_lock_irqsave(&bcs->cs->lock, flags); 802 if (bcs->tx_skb) { 803 skb_queue_tail(&bcs->squeue, skb); 804 } else { 805 bcs->tx_skb = skb; 806 bcs->cs->BC_Send_Data(bcs); 807 } 808 spin_unlock_irqrestore(&bcs->cs->lock, flags); 809 break; 810 case (PH_PULL | INDICATION): 811 spin_lock_irqsave(&bcs->cs->lock, flags); 812 if (bcs->tx_skb) { 813 printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n"); 814 } else { 815 bcs->tx_skb = skb; 816 bcs->cs->BC_Send_Data(bcs); 817 } 818 spin_unlock_irqrestore(&bcs->cs->lock, flags); 819 break; 820 case (PH_PULL | REQUEST): 821 if (!bcs->tx_skb) { 822 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 823 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); 824 } else 825 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 826 break; 827 case (PH_ACTIVATE | REQUEST): 828 spin_lock_irqsave(&bcs->cs->lock, flags); 829 test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); 830 mode_tiger(bcs, st->l1.mode, st->l1.bc); 831 /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */ 832 spin_unlock_irqrestore(&bcs->cs->lock, flags); 833 bcs->cs->cardmsg(bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc)); 834 l1_msg_b(st, pr, arg); 835 break; 836 case (PH_DEACTIVATE | REQUEST): 837 /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */ 838 bcs->cs->cardmsg(bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc)); 839 l1_msg_b(st, pr, arg); 840 break; 841 case (PH_DEACTIVATE | CONFIRM): 842 spin_lock_irqsave(&bcs->cs->lock, flags); 843 test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); 844 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 845 mode_tiger(bcs, 0, st->l1.bc); 846 spin_unlock_irqrestore(&bcs->cs->lock, flags); 847 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); 848 break; 849 } 850} 851 852 853static void 854close_tigerstate(struct BCState *bcs) 855{ 856 mode_tiger(bcs, 0, bcs->channel); 857 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 858 kfree(bcs->hw.tiger.rcvbuf); 859 bcs->hw.tiger.rcvbuf = NULL; 860 kfree(bcs->hw.tiger.sendbuf); 861 bcs->hw.tiger.sendbuf = NULL; 862 skb_queue_purge(&bcs->rqueue); 863 skb_queue_purge(&bcs->squeue); 864 if (bcs->tx_skb) { 865 dev_kfree_skb_any(bcs->tx_skb); 866 bcs->tx_skb = NULL; 867 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 868 } 869 } 870} 871 872static int 873open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs) 874{ 875 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { 876 if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { 877 printk(KERN_WARNING 878 "HiSax: No memory for tiger.rcvbuf\n"); 879 return (1); 880 } 881 if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) { 882 printk(KERN_WARNING 883 "HiSax: No memory for tiger.sendbuf\n"); 884 return (1); 885 } 886 skb_queue_head_init(&bcs->rqueue); 887 skb_queue_head_init(&bcs->squeue); 888 } 889 bcs->tx_skb = NULL; 890 bcs->hw.tiger.sendcnt = 0; 891 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 892 bcs->event = 0; 893 bcs->tx_cnt = 0; 894 return (0); 895} 896 897static int 898setstack_tiger(struct PStack *st, struct BCState *bcs) 899{ 900 bcs->channel = st->l1.bc; 901 if (open_tigerstate(st->l1.hardware, bcs)) 902 return (-1); 903 st->l1.bcs = bcs; 904 st->l2.l2l1 = tiger_l2l1; 905 setstack_manager(st); 906 bcs->st = st; 907 setstack_l1_B(st); 908 return (0); 909} 910 911 912void 913inittiger(struct IsdnCardState *cs) 914{ 915 if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int), 916 GFP_KERNEL | GFP_DMA))) { 917 printk(KERN_WARNING 918 "HiSax: No memory for tiger.send\n"); 919 return; 920 } 921 cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE / 2 - 1; 922 cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1; 923 cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send; 924 cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq; 925 cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end; 926 927 memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int)); 928 debugl1(cs, "tiger: send buf %p - %p", cs->bcs[0].hw.tiger.send, 929 cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1); 930 outl(virt_to_bus(cs->bcs[0].hw.tiger.send), 931 cs->hw.njet.base + NETJET_DMA_READ_START); 932 outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq), 933 cs->hw.njet.base + NETJET_DMA_READ_IRQ); 934 outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end), 935 cs->hw.njet.base + NETJET_DMA_READ_END); 936 if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_RXSIZE * sizeof(unsigned int), 937 GFP_KERNEL | GFP_DMA))) { 938 printk(KERN_WARNING 939 "HiSax: No memory for tiger.rec\n"); 940 return; 941 } 942 debugl1(cs, "tiger: rec buf %p - %p", cs->bcs[0].hw.tiger.rec, 943 cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1); 944 cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec; 945 memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int)); 946 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec), 947 cs->hw.njet.base + NETJET_DMA_WRITE_START); 948 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE / 2 - 1), 949 cs->hw.njet.base + NETJET_DMA_WRITE_IRQ); 950 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1), 951 cs->hw.njet.base + NETJET_DMA_WRITE_END); 952 debugl1(cs, "tiger: dmacfg %x/%x pulse=%d", 953 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR), 954 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR), 955 bytein(cs->hw.njet.base + NETJET_PULSE_CNT)); 956 cs->hw.njet.last_is0 = 0; 957 cs->bcs[0].BC_SetStack = setstack_tiger; 958 cs->bcs[1].BC_SetStack = setstack_tiger; 959 cs->bcs[0].BC_Close = close_tigerstate; 960 cs->bcs[1].BC_Close = close_tigerstate; 961} 962 963static void 964releasetiger(struct IsdnCardState *cs) 965{ 966 kfree(cs->bcs[0].hw.tiger.send); 967 cs->bcs[0].hw.tiger.send = NULL; 968 cs->bcs[1].hw.tiger.send = NULL; 969 kfree(cs->bcs[0].hw.tiger.rec); 970 cs->bcs[0].hw.tiger.rec = NULL; 971 cs->bcs[1].hw.tiger.rec = NULL; 972} 973 974void 975release_io_netjet(struct IsdnCardState *cs) 976{ 977 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); 978 byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0); 979 releasetiger(cs); 980 release_region(cs->hw.njet.base, 256); 981} 982