linux/drivers/isdn/hisax/netjet.c
<<
>>
Prefs
   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, "%s", 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                skb_put_data(skb, 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        cs->bcs[0].hw.tiger.send = kmalloc_array(NETJET_DMA_TXSIZE,
 916                                                 sizeof(unsigned int),
 917                                                 GFP_KERNEL | GFP_DMA);
 918        if (!cs->bcs[0].hw.tiger.send) {
 919                printk(KERN_WARNING
 920                       "HiSax: No memory for tiger.send\n");
 921                return;
 922        }
 923        cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE / 2 - 1;
 924        cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
 925        cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send;
 926        cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq;
 927        cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end;
 928
 929        memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int));
 930        debugl1(cs, "tiger: send buf %p - %p", cs->bcs[0].hw.tiger.send,
 931                cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1);
 932        outl(virt_to_bus(cs->bcs[0].hw.tiger.send),
 933             cs->hw.njet.base + NETJET_DMA_READ_START);
 934        outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq),
 935             cs->hw.njet.base + NETJET_DMA_READ_IRQ);
 936        outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end),
 937             cs->hw.njet.base + NETJET_DMA_READ_END);
 938        cs->bcs[0].hw.tiger.rec = kmalloc_array(NETJET_DMA_RXSIZE,
 939                                                sizeof(unsigned int),
 940                                                GFP_KERNEL | GFP_DMA);
 941        if (!cs->bcs[0].hw.tiger.rec) {
 942                printk(KERN_WARNING
 943                       "HiSax: No memory for tiger.rec\n");
 944                return;
 945        }
 946        debugl1(cs, "tiger: rec buf %p - %p", cs->bcs[0].hw.tiger.rec,
 947                cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1);
 948        cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec;
 949        memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int));
 950        outl(virt_to_bus(cs->bcs[0].hw.tiger.rec),
 951             cs->hw.njet.base + NETJET_DMA_WRITE_START);
 952        outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE / 2 - 1),
 953             cs->hw.njet.base + NETJET_DMA_WRITE_IRQ);
 954        outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1),
 955             cs->hw.njet.base + NETJET_DMA_WRITE_END);
 956        debugl1(cs, "tiger: dmacfg  %x/%x  pulse=%d",
 957                inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
 958                inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
 959                bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
 960        cs->hw.njet.last_is0 = 0;
 961        cs->bcs[0].BC_SetStack = setstack_tiger;
 962        cs->bcs[1].BC_SetStack = setstack_tiger;
 963        cs->bcs[0].BC_Close = close_tigerstate;
 964        cs->bcs[1].BC_Close = close_tigerstate;
 965}
 966
 967static void
 968releasetiger(struct IsdnCardState *cs)
 969{
 970        kfree(cs->bcs[0].hw.tiger.send);
 971        cs->bcs[0].hw.tiger.send = NULL;
 972        cs->bcs[1].hw.tiger.send = NULL;
 973        kfree(cs->bcs[0].hw.tiger.rec);
 974        cs->bcs[0].hw.tiger.rec = NULL;
 975        cs->bcs[1].hw.tiger.rec = NULL;
 976}
 977
 978void
 979release_io_netjet(struct IsdnCardState *cs)
 980{
 981        byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
 982        byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
 983        releasetiger(cs);
 984        release_region(cs->hw.njet.base, 256);
 985}
 986