root/drivers/net/sdla.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sdla_read
  2. sdla_write
  3. sdla_clear
  4. sdla_byte
  5. sdla_stop
  6. sdla_start
  7. sdla_z80_poll
  8. sdla_cpuspeed
  9. sdla_errors
  10. sdla_cmd
  11. sdla_activate
  12. sdla_deactivate
  13. sdla_assoc
  14. sdla_deassoc
  15. sdla_dlci_conf
  16. sdla_transmit
  17. sdla_receive
  18. sdla_isr
  19. sdla_poll
  20. sdla_close
  21. sdla_open
  22. sdla_config
  23. sdla_xfer
  24. sdla_reconfig
  25. sdla_ioctl
  26. sdla_change_mtu
  27. sdla_set_config
  28. sdla_stats
  29. sdla_init
  30. sdla_setup
  31. init_module
  32. cleanup_module

   1 /*
   2  * SDLA      An implementation of a driver for the Sangoma S502/S508 series
   3  *           multi-protocol PC interface card.  Initial offering is with 
   4  *           the DLCI driver, providing Frame Relay support for linux.
   5  *
   6  *           Global definitions for the Frame relay interface.
   7  *
   8  * Version:  @(#)sdla.c   0.10   23 Mar 1996
   9  *
  10  * Credits:  Sangoma Technologies, for the use of 2 cards for an extended
  11  *                                 period of time.
  12  *           David Mandelstam <dm@sangoma.com> for getting me started on 
  13  *                            this project, and incentive to complete it.
  14  *           Gene Kozen <74604.152@compuserve.com> for providing me with
  15  *                      important information about the cards.
  16  *
  17  * Author:   Mike McLagan <mike.mclagan@linux.org>
  18  *
  19  *           This program is free software; you can redistribute it and/or
  20  *           modify it under the terms of the GNU General Public License
  21  *           as published by the Free Software Foundation; either version
  22  *           2 of the License, or (at your option) any later version.
  23  */
  24 
  25 #include <linux/module.h>
  26 
  27 #include <linux/kernel.h>
  28 #include <linux/sched.h>
  29 #include <linux/types.h>
  30 #include <linux/fcntl.h>
  31 #include <linux/interrupt.h>
  32 #include <linux/ptrace.h>
  33 #include <linux/ioport.h>
  34 #include <linux/in.h>
  35 #include <linux/malloc.h>
  36 #include <linux/string.h>
  37 #include <linux/timer.h>
  38 #include <linux/errno.h>
  39 
  40 #include <asm/system.h>
  41 #include <asm/bitops.h>
  42 #include <asm/io.h>
  43 #include <asm/dma.h>
  44 
  45 #include <linux/netdevice.h>
  46 #include <linux/skbuff.h>
  47 #include <linux/if_arp.h>
  48 #include <linux/if_frad.h>
  49 
  50 #include <linux/sdla.h>
  51 
  52 static const char* version = "SDLA driver v0.10, 23 Mar 1996, mike.mclagan@linux.org";
  53 
  54 static const char* devname = "sdla";
  55 
  56 static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
  57 
  58 static unsigned int valid_mem[]  = {0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, 
  59                                     0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
  60                                     0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
  61                                     0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
  62                                     0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; 
  63 
  64 /*********************************************************
  65  *
  66  * these are the core routines that access the card itself 
  67  *
  68  *********************************************************/
  69 
  70 #define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
  71 
  72 static void sdla_read(struct device *dev, int addr, void *buf, short len)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74    unsigned long flags;
  75    char          *temp, *base;
  76    int           offset, bytes;
  77 
  78    temp = buf;
  79    while(len)
  80    {
  81       offset = addr & 0x1FFF;
  82       if (offset + len > 0x2000)
  83          bytes = 0x2000 - offset;
  84       else
  85          bytes = len;
  86 
  87       base = (void *) dev->mem_start;
  88       base += offset;
  89 
  90       save_flags(flags);
  91       cli();
  92       SDLA_WINDOW(dev, addr);
  93       memcpy(temp, base, bytes);
  94       restore_flags(flags);
  95 
  96       addr += bytes;
  97       temp += bytes;
  98       len  -= bytes;
  99    }  
 100 }
 101 
 102 static void sdla_write(struct device *dev, int addr, void *buf, short len)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104    unsigned long flags;
 105    char          *temp, *base;
 106    int           offset, bytes;
 107 
 108    temp = buf;
 109    while(len)
 110    {
 111       offset = addr & 0x1FFF;
 112       if (offset + len > 0x2000)
 113          bytes = 0x2000 - offset;
 114       else
 115          bytes = len;
 116 
 117       base = (void *) dev->mem_start;
 118       base += offset;
 119 
 120       save_flags(flags);
 121       cli();
 122       SDLA_WINDOW(dev, addr);
 123       memcpy(base, temp, bytes);
 124       restore_flags(flags);
 125 
 126       addr += bytes;
 127       temp += bytes;
 128       len  -= bytes;
 129    }
 130 }
 131 
 132 static void sdla_clear(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134    unsigned long flags;
 135    char          *base;
 136    int           offset, len, addr, bytes;
 137 
 138    len = 65536;
 139    addr = 0;
 140    while(len)
 141    {
 142       offset = addr & 0x1FFF;
 143       if (offset + len > 0x2000)
 144          bytes = offset + len - 0x2000;
 145       else
 146          bytes = len;
 147 
 148       base = (void *) dev->mem_start;
 149       base += offset;
 150 
 151       save_flags(flags);
 152       cli();
 153       SDLA_WINDOW(dev, addr);
 154       memset(base, 0, bytes);
 155       restore_flags(flags);
 156 
 157       addr += bytes;
 158       len  -= bytes;
 159    }
 160 }
 161 
 162 static char sdla_byte(struct device *dev, int addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 163 {
 164    unsigned long flags;
 165    char          byte, *temp;
 166 
 167    temp = (void *) dev->mem_start;
 168    temp += addr & 0x1FFF;
 169 
 170    save_flags(flags);
 171    cli();
 172    SDLA_WINDOW(dev, addr);
 173    byte = *temp;
 174    restore_flags(flags);
 175 
 176    return(byte);
 177 }
 178 
 179 void sdla_stop(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181    struct frad_local *flp;
 182 
 183    flp = dev->priv;
 184    switch(flp->type)
 185    {
 186       case SDLA_S502A:
 187          outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
 188          flp->state = SDLA_HALT;
 189          break;
 190       case SDLA_S502E:
 191          outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
 192          outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
 193          flp->state = SDLA_S502E_ENABLE;
 194          break;
 195       case SDLA_S507:
 196          flp->state &= ~SDLA_CPUEN;
 197          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 198          break;
 199       case SDLA_S508:
 200          flp->state &= ~SDLA_CPUEN;
 201          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 202          break;
 203    }
 204 }
 205 
 206 void sdla_start(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 207 {
 208    struct frad_local *flp;
 209 
 210    flp = dev->priv;
 211    switch(flp->type)
 212    {
 213       case SDLA_S502A:
 214          outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL);
 215          outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
 216          flp->state = SDLA_S502A_START;
 217          break;
 218       case SDLA_S502E:
 219          outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL);
 220          outb(0x00, dev->base_addr + SDLA_REG_CONTROL);
 221          flp->state = 0;
 222          break;
 223       case SDLA_S507:
 224          flp->state |= SDLA_CPUEN;
 225          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 226          break;
 227       case SDLA_S508:
 228          flp->state |= SDLA_CPUEN;
 229          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 230          break;
 231    }
 232 }
 233 
 234 /****************************************************
 235  *
 236  * this is used for the S502A/E cards to determine
 237  * the speed of the onboard CPU.  Calibration is
 238  * necessary for the Frame Relay code uploaded 
 239  * later.  Incorrect results cause timing problems
 240  * with link checks & status messages
 241  *
 242  ***************************************************/
 243 
 244 int sdla_z80_poll(struct device *dev, int z80_addr, int jiffs, char resp1, char resp2)
     /* [previous][next][first][last][top][bottom][index][help] */
 245 {
 246    unsigned long start, done, now;
 247    char          resp, *temp;
 248 
 249    start = now = jiffies;
 250    done = jiffies + jiffs;
 251 
 252    temp = (void *)dev->mem_start;
 253    temp += z80_addr & 0x1FFF;
 254 
 255    resp = ~resp1;
 256    while ((jiffies < done) && (resp != resp1) && (!resp2 || (resp != resp2)))
 257    {
 258       if (jiffies != now)
 259       {
 260          SDLA_WINDOW(dev, z80_addr);
 261          now = jiffies;
 262          resp = *temp;
 263       }
 264    }
 265    return(jiffies < done ? jiffies - start : -1);
 266 }
 267 
 268 /* constants for Z80 CPU speed */
 269 #define Z80_READY               '1'     /* Z80 is ready to begin */
 270 #define LOADER_READY            '2'     /* driver is ready to begin */
 271 #define Z80_SCC_OK              '3'     /* SCC is on board */
 272 #define Z80_SCC_BAD             '4'     /* SCC was not found */
 273 
 274 static int sdla_cpuspeed(struct device *dev, struct ifreq *ifr)
     /* [previous][next][first][last][top][bottom][index][help] */
 275 {
 276    int  jiffs;
 277    char data;
 278 
 279    sdla_start(dev);
 280    if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0)
 281       return(-EIO);
 282 
 283    data = LOADER_READY;
 284    sdla_write(dev, 0, &data, 1);
 285 
 286    if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0)
 287       return(-EIO);
 288 
 289    sdla_stop(dev);
 290    sdla_read(dev, 0, &data, 1);
 291 
 292    if (data == Z80_SCC_BAD)
 293       return(-EIO);
 294 
 295    if (data != Z80_SCC_OK)
 296       return(-EINVAL);
 297 
 298    if (jiffs < 165)
 299       ifr->ifr_mtu = SDLA_CPU_16M;
 300    else
 301       if (jiffs < 220)
 302          ifr->ifr_mtu = SDLA_CPU_10M;
 303       else
 304          if (jiffs < 258)
 305             ifr->ifr_mtu = SDLA_CPU_8M;
 306          else
 307             if (jiffs < 357)
 308                ifr->ifr_mtu = SDLA_CPU_7M;
 309             else
 310                if (jiffs < 467)
 311                   ifr->ifr_mtu = SDLA_CPU_5M;
 312                else
 313                   ifr->ifr_mtu = SDLA_CPU_3M;
 314  
 315    return(0);
 316 }
 317 
 318 /************************************************
 319  *
 320  *  Direct interaction with the Frame Relay code 
 321  *  starts here.
 322  *
 323  ************************************************/
 324 
 325 struct _dlci_stat {
 326    short dlci           __attribute__((packed));
 327    char  flags          __attribute__((packed));
 328 };
 329 
 330 struct _frad_stat {
 331    char    flags;
 332    struct _dlci_stat dlcis[SDLA_MAX_DLCI];
 333 };
 334 
 335 static void sdla_errors(struct device *dev, int cmd, int dlci, int ret, int len, void *data) 
     /* [previous][next][first][last][top][bottom][index][help] */
 336 {
 337    struct _dlci_stat *pstatus;
 338    short             *pdlci;
 339    int               i;
 340    char              *state;
 341 
 342    switch (ret)
 343    {
 344       case SDLA_RET_MODEM:
 345          state = data;
 346          if (*state & SDLA_MODEM_DCD_LOW)
 347             printk(KERN_INFO "%s: Modem DCD unexpectedly low!\n", dev->name);
 348          if (*state & SDLA_MODEM_CTS_LOW)
 349             printk(KERN_INFO "%s: Modem CTS unexpectedly low!\n", dev->name);
 350 /* I should probably do something about this! */
 351          break;
 352 
 353       case SDLA_RET_CHANNEL_OFF:
 354          printk(KERN_INFO "%s: Channel became inoperative!\n", dev->name);
 355 /* same here */
 356          break;
 357 
 358       case SDLA_RET_CHANNEL_ON:
 359          printk(KERN_INFO "%s: Channel became operative!\n", dev->name);
 360 /* same here */
 361          break;
 362 
 363       case SDLA_RET_DLCI_STATUS:
 364          printk(KERN_INFO "%s: Status change reported by Access Node.\n", dev->name);
 365          len /= sizeof(struct _dlci_stat);
 366          for(pstatus = data, i=0;i < len;i++,pstatus++)
 367          {
 368             if (pstatus->flags & SDLA_DLCI_NEW)
 369                state = "new";
 370             else
 371                if (pstatus->flags & SDLA_DLCI_DELETED)
 372                   state = "deleted";
 373                else
 374                   if (pstatus->flags & SDLA_DLCI_ACTIVE)
 375                      state = "active";
 376                   else
 377                      state = "unknown status";
 378  
 379             printk(KERN_INFO "%s: DLCI %i: %s.\n", dev->name, pstatus->dlci, state);
 380 /* same here */
 381          }
 382          break;
 383 
 384       case SDLA_RET_DLCI_UNKNOWN:
 385          printk(KERN_INFO "%s: Received unknown DLCIs:", dev->name);
 386          len /= sizeof(short);
 387          for(pdlci = data,i=0;i < len;i++,pdlci++)
 388             printk(" %i", *pdlci);
 389          printk("\n");
 390          break;
 391 
 392       case SDLA_RET_TIMEOUT:
 393          printk(KERN_ERR "%s: Command timed out!\n", dev->name);
 394          break;
 395 
 396       case SDLA_RET_CHANNEL_INACTIVE:
 397       case SDLA_RET_DLCI_INACTIVE:
 398       case SDLA_RET_NO_BUFF:
 399          if (cmd == SDLA_INFORMATION_WRITE)
 400             break;
 401 
 402       default: 
 403          /*
 404           * Further processing could be done here 
 405           * printk(KERN_DEBUG "%s: Unhandled return code 0x%2.2X\n", dev->name, ret);
 406           *
 407           */
 408    }
 409 }
 410 
 411 static int sdla_cmd(struct device *dev, int cmd, short dlci, short flags, 
     /* [previous][next][first][last][top][bottom][index][help] */
 412                         void *inbuf, short inlen, void *outbuf, short *outlen)
 413 {
 414    static struct _frad_stat status;
 415    struct frad_local        *flp;
 416    struct sdla_cmd          *cmd_buf;
 417    unsigned long            pflags;
 418    int                      jiffs, ret, waiting, len;
 419    long                     temp, window;
 420 
 421    flp = dev->priv;
 422 
 423    window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF;
 424    temp = (int) dev->mem_start;
 425    temp += window & 0x1FFF;
 426    cmd_buf = (struct sdla_cmd *)temp;
 427    ret = 0;
 428    jiffs = jiffies + HZ / 2;  /* 1/2 second timeout */
 429    save_flags(pflags);
 430    cli();
 431    SDLA_WINDOW(dev, window);
 432    cmd_buf->cmd = cmd;
 433    cmd_buf->dlci = dlci;
 434    cmd_buf->flags = flags;
 435 
 436    if (inbuf)
 437       memcpy(cmd_buf->data, inbuf, inlen);
 438 
 439    cmd_buf->length = inlen;
 440 
 441    cmd_buf->opp_flag = 1;
 442    restore_flags(pflags);
 443 
 444    waiting = 1;
 445    len = 0;
 446    while (waiting && (jiffies <= jiffs))
 447    {
 448       if (waiting++ % 4) 
 449       {
 450          save_flags(pflags);
 451          cli();
 452          SDLA_WINDOW(dev, window);
 453          waiting = ((volatile)(cmd_buf->opp_flag));
 454          restore_flags(pflags);
 455       }
 456    }
 457    
 458    if (!waiting)
 459    {
 460       save_flags(pflags);
 461       cli();
 462       SDLA_WINDOW(dev, window);
 463       ret = cmd_buf->retval;
 464       len = cmd_buf->length;
 465       if (outbuf && len)
 466       {
 467          *outlen = *outlen >= len ? len : *outlen;
 468          memcpy(outbuf, cmd_buf->data, *outlen);
 469       }
 470       if (ret)
 471          memcpy(&status, cmd_buf->data, len);
 472       restore_flags(pflags);
 473    }
 474    else
 475       ret = SDLA_RET_TIMEOUT;
 476 
 477    if (ret != SDLA_RET_OK)
 478       sdla_errors(dev, cmd, dlci, ret, len, &status);
 479 
 480    return(ret);
 481 }
 482 
 483 /***********************************************
 484  *
 485  * these functions are called by the DLCI driver 
 486  *
 487  ***********************************************/
 488 
 489 static int sdla_reconfig(struct device *dev);
 490 
 491 int sdla_activate(struct device *slave, struct device *master)
     /* [previous][next][first][last][top][bottom][index][help] */
 492 {
 493    struct frad_local *flp;
 494    int               i;
 495 
 496    flp = slave->priv;
 497 
 498    for(i=0;i<CONFIG_DLCI_MAX;i++)
 499       if (flp->master[i] == master)
 500          break;
 501 
 502    if (i == CONFIG_DLCI_MAX)
 503       return(-ENODEV);
 504 
 505    flp->dlci[i] = abs(flp->dlci[i]);
 506 
 507    if (slave->start && (flp->config.station == FRAD_STATION_NODE))
 508       sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
 509 
 510    return(0);
 511 }
 512 
 513 int sdla_deactivate(struct device *slave, struct device *master)
     /* [previous][next][first][last][top][bottom][index][help] */
 514 {
 515    struct frad_local *flp;
 516    int               i;
 517 
 518    flp = slave->priv;
 519 
 520    for(i=0;i<CONFIG_DLCI_MAX;i++)
 521       if (flp->master[i] == master)
 522          break;
 523 
 524    flp->dlci[i] = -abs(flp->dlci[i]);
 525 
 526    if (slave->start && (flp->config.station == FRAD_STATION_NODE))
 527       sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
 528 
 529    return(0);
 530 }
 531 
 532 int sdla_assoc(struct device *slave, struct device *master)
     /* [previous][next][first][last][top][bottom][index][help] */
 533 {
 534    struct frad_local *flp;
 535    int               i;
 536 
 537    if (master->type != ARPHRD_DLCI)
 538       return(-EINVAL);
 539 
 540    flp = slave->priv;
 541 
 542    for(i=0;i<CONFIG_DLCI_MAX;i++)
 543    {
 544       if (!flp->master[i])
 545          break;
 546       if (abs(flp->dlci[i]) == *(short *)(master->dev_addr))
 547          return(-EADDRINUSE);
 548    } 
 549 
 550    if (i == CONFIG_DLCI_MAX)
 551       return(-EMLINK);  /* #### Alan: Comments on this ?? */
 552 
 553    MOD_INC_USE_COUNT;
 554 
 555    flp->master[i] = master;
 556    flp->dlci[i] = -*(short *)(master->dev_addr);
 557    master->mtu = slave->mtu;
 558 
 559    if (slave->start)
 560       if (flp->config.station == FRAD_STATION_CPE)
 561          sdla_reconfig(slave);
 562       else
 563          sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
 564 
 565    return(0);
 566 }
 567 
 568 int sdla_deassoc(struct device *slave, struct device *master)
     /* [previous][next][first][last][top][bottom][index][help] */
 569 {
 570    struct frad_local *flp;
 571    int               i;
 572 
 573    flp = slave->priv;
 574 
 575    for(i=0;i<CONFIG_DLCI_MAX;i++)
 576       if (flp->master[i] == master)
 577          break;
 578 
 579    if (i == CONFIG_DLCI_MAX)
 580       return(-ENODEV);
 581 
 582    flp->master[i] = NULL;
 583    flp->dlci[i] = 0;
 584 
 585    MOD_DEC_USE_COUNT;
 586 
 587    if (slave->start)
 588       if (flp->config.station == FRAD_STATION_CPE)
 589          sdla_reconfig(slave);
 590       else
 591          sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
 592 
 593    return(0);
 594 }
 595 
 596 int sdla_dlci_conf(struct device *slave, struct device *master, int get)
     /* [previous][next][first][last][top][bottom][index][help] */
 597 {
 598    struct frad_local *flp;
 599    struct frad_local *dlp;
 600    int               i;
 601 
 602    flp = slave->priv;
 603 
 604    for(i=0;i<CONFIG_DLCI_MAX;i++)
 605       if (flp->master[i] == master)
 606          break;
 607 
 608    if (i == CONFIG_DLCI_MAX)
 609       return(-ENODEV);
 610 
 611    dlp = master->priv;
 612    if (slave->start)
 613       sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, flp->dlci[i], 0,  
 614                   &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL);
 615 
 616    return(0);
 617 }
 618 
 619 /**************************
 620  *
 621  * now for the Linux driver 
 622  *
 623  **************************/
 624 
 625 static int sdla_transmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 626 {
 627    struct frad_local *flp;
 628    int               ret, addr;
 629    short             size;
 630    unsigned long     flags;
 631    struct buf_entry  *pbuf;
 632 
 633    flp = dev->priv;
 634    ret = 0;
 635 
 636    if (dev->tbusy) 
 637       return(1);
 638 
 639    if (skb == NULL) 
 640       return(0);
 641 
 642    if (set_bit(0, (void*)&dev->tbusy) != 0)
 643       printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
 644    else
 645    {
 646       switch (flp->type)
 647       {
 648          case SDLA_S502A:
 649          case SDLA_S502E:
 650             ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
 651             break;
 652 
 653          case SDLA_S508:
 654             size = sizeof(addr);
 655             ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
 656             if (ret == SDLA_RET_OK)
 657             {
 658                save_flags(flags); 
 659                cli();
 660                SDLA_WINDOW(dev, addr);
 661                pbuf = (void *)(((int) dev->mem_start) + (addr & 0x1FFF));
 662 
 663                sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
 664 
 665                SDLA_WINDOW(dev, addr);
 666                pbuf->opp_flag = 1;
 667                restore_flags(flags);
 668             }
 669             break;
 670       }
 671  
 672       switch (ret)
 673       {
 674          case SDLA_RET_OK:
 675             flp->stats.tx_packets++;
 676             ret = 0;
 677             break;
 678  
 679          default:
 680             flp->stats.tx_errors++;
 681             ret = 1;
 682       }
 683 
 684       /* per Alan Cox, we can drop the packet on the floor if it doesn't go */
 685       dev_kfree_skb(skb, FREE_WRITE);
 686 
 687       dev->tbusy = 0;
 688    }
 689    return(ret);
 690 }
 691 
 692 static void sdla_receive(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 693 {
 694    struct device     *master;
 695    struct frad_local *flp;
 696    struct dlci_local *dlp;
 697    struct sk_buff    *skb;
 698 
 699    struct sdla_cmd   *cmd;
 700    struct buf_info   *pbufi;
 701    struct buf_entry  *pbuf;
 702 
 703    unsigned long     flags;
 704    int               i, received, success, addr;
 705    short             dlci, len, split;
 706    char              bogus;
 707 
 708    flp = dev->priv;
 709    bogus = 0;
 710    success = 0;
 711    received = 0;
 712    addr = 0;
 713    skb = NULL;
 714    master = NULL;
 715 
 716    save_flags(flags);
 717    cli();
 718 
 719    switch (flp->type)
 720    {
 721       case SDLA_S502A:
 722       case SDLA_S502E:
 723          cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & 0x1FFF));
 724          SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
 725          if (!cmd->opp_flag)
 726             break;
 727 
 728          dlci = cmd->dlci;
 729          len = cmd->length;
 730 
 731          for (i=0;i<CONFIG_DLCI_MAX;i++)
 732             if (flp->dlci[i] == dlci)
 733                break;
 734 
 735          if (i == CONFIG_DLCI_MAX)
 736          {
 737             printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
 738             flp->stats.rx_errors++;
 739             cmd->opp_flag = 0;
 740             break;
 741          }
 742 
 743          master = flp->master[i];
 744          skb = dev_alloc_skb(len);
 745          if (skb == NULL) 
 746          {
 747             printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
 748             flp->stats.rx_dropped++;
 749             cmd->opp_flag = 0;
 750             break;
 751          }
 752 
 753          /* pick up the data */
 754          sdla_read(dev, dev->mem_start + ((SDLA_502_RCV_BUF + SDLA_502_DATA_OFS) & 0x1FFF), skb_put(skb,len), len);
 755          cmd->opp_flag = 0;
 756          success = 1;
 757          break;
 758 
 759       case SDLA_S508:
 760          pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & 0x1FFF));
 761          SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
 762          pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & 0x1FFF));
 763          if (!pbuf->opp_flag)
 764             break;
 765 
 766          dlci = pbuf->dlci;
 767          len = pbuf->length;
 768          addr = pbuf->buf_addr;
 769 
 770          for (i=0;i<CONFIG_DLCI_MAX;i++)
 771             if (flp->dlci[i] == dlci)
 772                break;
 773 
 774          if (i == CONFIG_DLCI_MAX)
 775          {
 776             printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
 777             flp->stats.rx_errors++;
 778             pbuf->opp_flag = 0;
 779             break;
 780          }
 781 
 782          master = flp->master[i];
 783          skb = dev_alloc_skb(len);
 784          if (skb == NULL) 
 785          {
 786             printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
 787             flp->stats.rx_dropped++;
 788             pbuf->opp_flag = 0;
 789             break;
 790          }
 791 
 792          /* is this buffer split off the end of the internal ring buffer */
 793          split = addr + len > pbufi->buf_top + 1 ? pbufi->buf_top - addr + 1 : 0;
 794          len -= split;
 795 
 796          /* lets get the data */
 797          sdla_read(dev, addr, skb_put(skb, len), len);
 798          if (split)
 799          {
 800             SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
 801             sdla_read(dev, pbufi->buf_base, skb_put(skb, split), split);
 802          }
 803 
 804          SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
 805          pbuf->opp_flag = 0;
 806          success = 1;
 807 
 808          /* increment the buffer we're looking at */
 809          flp->buffer = (flp->buffer + 1) % pbufi->rse_num;
 810          break;
 811    }
 812 
 813    if (success)
 814    {
 815       flp->stats.rx_packets++;
 816       dlp = master->priv;
 817       (*dlp->receive)(skb, master);
 818    }
 819 
 820    restore_flags(flags);
 821 }
 822 
 823 static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 824 {
 825    struct device     *dev;
 826    struct frad_local *flp;
 827    char              byte;
 828 
 829    dev = irq2dev_map[irq];
 830 
 831    if (dev == NULL)
 832    {
 833       printk(KERN_WARNING "sdla_isr(): irq %d for unknown device.\n", irq);
 834       return;
 835    }
 836 
 837    flp = dev->priv;
 838 
 839    if (!flp->initialized)
 840    {
 841       printk(KERN_WARNING "%s: irq %d for unintialiazed device.\n", dev->name, irq);
 842       return;
 843    }
 844 
 845    dev->interrupt = 1;
 846    byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
 847    switch (byte)
 848    {
 849       case SDLA_INTR_RX:
 850          sdla_receive(dev);
 851          break;
 852 
 853       /* the command will get an error return, which is processed above */
 854       case SDLA_INTR_MODEM:
 855       case SDLA_INTR_STATUS:
 856          sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
 857          break;
 858 
 859       case SDLA_INTR_TX:
 860       case SDLA_INTR_COMPLETE:
 861       case SDLA_INTR_TIMER:
 862          printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte);
 863          break;
 864    }
 865 
 866    /* the S502E requires a manual acknowledgement of the interrupt */ 
 867    if (flp->type == SDLA_S502E)
 868    {
 869       flp->state &= ~SDLA_S502E_INTACK;
 870       outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 871       flp->state |= SDLA_S502E_INTACK;
 872       outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 873    }
 874 
 875    dev->interrupt = 0;
 876    /* this clears the byte, informing the Z80 we're done */
 877    byte = 0;
 878    sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
 879 }
 880 
 881 static void sdla_poll(unsigned long device)
     /* [previous][next][first][last][top][bottom][index][help] */
 882 {
 883    struct device     *dev;
 884    struct frad_local *flp;
 885 
 886    dev = (struct device *) device;
 887    flp = dev->priv;
 888 
 889    if (sdla_byte(dev, SDLA_502_RCV_BUF))
 890       sdla_receive(dev);
 891 
 892    flp->timer.expires = 1;
 893    add_timer(&flp->timer);
 894 }
 895 
 896 static int sdla_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 897 {
 898    struct frad_local *flp;
 899    struct intr_info  intr;
 900    int               len, i;
 901    short             dlcis[CONFIG_DLCI_MAX];
 902 
 903    flp = dev->priv;
 904 
 905    len = 0;
 906    for(i=0;i<CONFIG_DLCI_MAX;i++)
 907       if (flp->dlci[i])
 908          dlcis[len++] = abs(flp->dlci[i]);
 909    len *= 2;
 910 
 911    if (flp->config.station == FRAD_STATION_NODE)
 912    {
 913       for(i=0;i<CONFIG_DLCI_MAX;i++)
 914          if (flp->dlci[i] > 0) 
 915             sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
 916       sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
 917    }
 918 
 919    memset(&intr, 0, sizeof(intr));
 920    /* lets start up the reception */
 921    switch(flp->type)
 922    {
 923       case SDLA_S502A:
 924          del_timer(&flp->timer); 
 925          break;
 926 
 927       case SDLA_S502E:
 928          sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
 929          flp->state &= ~SDLA_S502E_INTACK;
 930          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 931          break;
 932 
 933       case SDLA_S507:
 934          break;
 935 
 936       case SDLA_S508:
 937          sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
 938          flp->state &= ~SDLA_S508_INTEN;
 939          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 940          break;
 941    }
 942 
 943    sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
 944    sdla_stop(dev);
 945 
 946    dev->tbusy = 1;
 947    dev->start = 0;
 948 
 949    MOD_DEC_USE_COUNT;
 950 
 951    return(0);
 952 }
 953 
 954 struct conf_data {
 955    struct frad_conf config;
 956    short            dlci[CONFIG_DLCI_MAX];
 957 };
 958 
 959 static int sdla_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 960 {
 961    struct frad_local *flp;
 962    struct dlci_local *dlp;
 963    struct conf_data  data;
 964    struct intr_info  intr;
 965    int               len, i;
 966    char              byte;
 967 
 968    flp = dev->priv;
 969 
 970    if (!flp->initialized)
 971       return(-EPERM);
 972 
 973    if (!flp->configured)
 974       return(-EPERM);
 975 
 976    /* off to the races! */
 977    sdla_start(dev);
 978 
 979    /* time to send in the configuration */
 980    len = 0;
 981    for(i=0;i<CONFIG_DLCI_MAX;i++)
 982       if (flp->dlci[i])
 983          data.dlci[len++] = abs(flp->dlci[i]);
 984    len *= 2;
 985 
 986    memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
 987    len += sizeof(struct frad_conf);
 988 
 989    sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
 990    sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
 991 
 992    if (flp->type == SDLA_S508)
 993       flp->buffer = 0;
 994 
 995    sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
 996 
 997    /* lets start up the reception */
 998    memset(&intr, 0, sizeof(intr));
 999    switch(flp->type)
1000    {
1001       case SDLA_S502A:
1002          flp->timer.expires = 1;
1003          add_timer(&flp->timer);
1004          break;
1005 
1006       case SDLA_S502E:
1007          flp->state |= SDLA_S502E_ENABLE;
1008          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1009          flp->state |= SDLA_S502E_INTACK;
1010          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1011          byte = 0;
1012          sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
1013          intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1014          sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
1015          break;
1016 
1017       case SDLA_S507:
1018          break;
1019 
1020       case SDLA_S508:
1021          flp->state |= SDLA_S508_INTEN;
1022          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1023          byte = 0;
1024          sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
1025          intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1026          intr.irq = dev->irq;
1027          sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
1028          break;
1029    }
1030 
1031    if (flp->config.station == FRAD_STATION_CPE)
1032    {
1033       byte = SDLA_ICS_STATUS_ENQ;
1034       sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
1035    }
1036    else
1037    {
1038       sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
1039       for(i=0;i<CONFIG_DLCI_MAX;i++)
1040          if (flp->dlci[i] > 0)
1041             sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
1042    }
1043 
1044    /* configure any specific DLCI settings */
1045    for(i=0;i<CONFIG_DLCI_MAX;i++)
1046       if (flp->dlci[i])
1047       {
1048          dlp = flp->master[i]->priv;
1049          if (dlp->configured)
1050             sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
1051       }
1052 
1053    dev->tbusy = 0;
1054    dev->interrupt = 0;
1055    dev->start = 1;
1056 
1057    MOD_INC_USE_COUNT;
1058 
1059    return(0);
1060 }
1061 
1062 static int sdla_config(struct device *dev, struct frad_conf *conf, int get)
     /* [previous][next][first][last][top][bottom][index][help] */
1063 {
1064    struct frad_local *flp;
1065    struct conf_data  data;
1066    int               i, err;
1067    short             size;
1068 
1069    if (dev->type == 0xFFFF)
1070       return(-EUNATCH);
1071 
1072    flp = dev->priv;
1073 
1074    if (!get)
1075    {
1076       if (dev->start)
1077          return(-EBUSY);
1078 
1079       err = verify_area(VERIFY_READ, conf, sizeof(struct frad_conf));
1080       if (err)
1081          return(err);
1082 
1083       memcpy_fromfs(&data.config, conf, sizeof(struct frad_conf));
1084 
1085       if (data.config.station & ~FRAD_STATION_NODE)
1086          return(-EINVAL);
1087 
1088       if (data.config.flags & ~FRAD_VALID_FLAGS)
1089          return(-EINVAL);
1090 
1091       if ((data.config.kbaud < 0) || 
1092           ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
1093          return(-EINVAL);
1094 
1095       if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
1096          return(-EINVAL);
1097 
1098       if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
1099          return(-EINVAL);
1100 
1101       if ((data.config.T391 < 5) || (data.config.T391 > 30))
1102          return(-EINVAL);
1103 
1104       if ((data.config.T392 < 5) || (data.config.T392 > 30))
1105          return(-EINVAL);
1106 
1107       if ((data.config.N391 < 1) || (data.config.N391 > 255))
1108          return(-EINVAL);
1109 
1110       if ((data.config.N392 < 1) || (data.config.N392 > 10))
1111          return(-EINVAL);
1112 
1113       if ((data.config.N393 < 1) || (data.config.N393 > 10))
1114          return(-EINVAL);
1115 
1116       memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1117       flp->config.flags |= SDLA_DIRECT_RECV;
1118 
1119       if (dev->mtu != flp->config.mtu)
1120       {
1121          /* this is required to change the MTU */
1122          dev->mtu = flp->config.mtu;
1123          for(i=0;i<CONFIG_DLCI_MAX;i++)
1124             if (flp->master[i])
1125                flp->master[i]->mtu = flp->config.mtu;
1126       }
1127 
1128       flp->config.mtu += sizeof(struct fradhdr);
1129       flp->configured = 1;
1130    }
1131    else
1132    {
1133       err = verify_area(VERIFY_WRITE, conf, sizeof(struct frad_conf));
1134       if (err)
1135          return(err);
1136 
1137       /* no sense reading if the CPU isnt' started */
1138       if (dev->start)
1139       {
1140          size = sizeof(data);
1141          if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK)
1142             return(-EIO);
1143       }
1144       else
1145          if (flp->configured)
1146             memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
1147          else
1148             memset(&data.config, 0, sizeof(struct frad_conf));
1149 
1150       memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1151       data.config.flags &= ~SDLA_DIRECT_RECV;
1152       data.config.mtu -= data.config.mtu > sizeof(struct fradhdr) ? sizeof(struct fradhdr) : data.config.mtu;
1153       memcpy_tofs(conf, &data.config, sizeof(struct frad_conf));
1154    }
1155 
1156    return(0);
1157 }
1158 
1159 static int sdla_xfer(struct device *dev, struct sdla_mem *info, int read)
     /* [previous][next][first][last][top][bottom][index][help] */
1160 {
1161    struct sdla_mem mem;
1162    int    err;
1163    char   *temp;
1164 
1165    err = verify_area(VERIFY_READ, info, sizeof(struct sdla_mem));
1166    if (err)
1167       return(err);
1168 
1169    memcpy_fromfs(&mem, info, sizeof(mem));
1170    if (read)
1171    {
1172       err = verify_area(VERIFY_WRITE, mem.data, mem.len);
1173       if (err)
1174          return(err);
1175 
1176       temp = kmalloc(mem.len, GFP_KERNEL);
1177       if (!temp)
1178          return(-ENOMEM);
1179       sdla_read(dev, mem.addr, temp, mem.len);
1180       memcpy_tofs(mem.data, temp, mem.len);
1181       kfree(temp);
1182    }
1183    else
1184    {
1185       err = verify_area(VERIFY_READ, mem.data, mem.len);
1186       if (err)
1187          return(err);
1188 
1189       temp = kmalloc(mem.len, GFP_KERNEL);
1190       if (!temp)
1191          return(-ENOMEM);
1192       memcpy_fromfs(temp, mem.data, mem.len);
1193       sdla_write(dev, mem.addr, temp, mem.len);
1194       kfree(temp);
1195    }
1196    return(0);
1197 }
1198 
1199 static int sdla_reconfig(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1200 {
1201    struct frad_local *flp;
1202    struct conf_data  data;
1203    int               i, len;
1204 
1205    flp = dev->priv;
1206 
1207    memcpy(&data, &flp->config, sizeof(struct frad_conf));
1208 
1209    len = 0;
1210    for(i=0;i<CONFIG_DLCI_MAX;i++)
1211       if (flp->dlci[i])
1212          data.dlci[len++] = flp->dlci[i];
1213    len *= 2;
1214    len += sizeof(struct frad_conf);
1215 
1216    sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1217    sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
1218    sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1219 
1220    return(0);
1221 }
1222 
1223 static int sdla_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
1224 {
1225    struct frad_local *flp;
1226 
1227    flp = dev->priv;
1228 
1229    if (!flp->initialized)
1230       return(-EPERM);
1231 
1232    switch (cmd)
1233    {
1234       case FRAD_GET_CONF:
1235       case FRAD_SET_CONF:
1236          return(sdla_config(dev, (struct frad_conf *)ifr->ifr_data, cmd == FRAD_GET_CONF));
1237 
1238       case SDLA_IDENTIFY:
1239          ifr->ifr_flags = flp->type;
1240          break;
1241 
1242       case SDLA_CPUSPEED:
1243          return(sdla_cpuspeed(dev, ifr)); 
1244 
1245 /* ==========================================================
1246 NOTE:  This is rather a useless action right now, as the
1247        driver does not support protocols other than FR right
1248        now.  However, Sangoma has modules for a number of
1249        other protocols.
1250 ============================================================*/
1251       case SDLA_PROTOCOL:
1252          if (flp->configured)
1253             return(-EALREADY);
1254 
1255          switch (ifr->ifr_flags)
1256          {
1257             case ARPHRD_FRAD:
1258                dev->type = ifr->ifr_flags;
1259                dev->family = AF_UNSPEC;
1260                break;
1261 
1262             default:
1263                return(-ENOPROTOOPT);
1264          }
1265          break;
1266 
1267       case SDLA_CLEARMEM:
1268          sdla_clear(dev);
1269          break;
1270 
1271       case SDLA_WRITEMEM:
1272       case SDLA_READMEM:
1273          return(sdla_xfer(dev, (struct sdla_mem *)ifr->ifr_data, cmd == SDLA_READMEM));
1274 
1275       case SDLA_START:
1276          sdla_start(dev);
1277          break;
1278 
1279       case SDLA_STOP:
1280          sdla_stop(dev);
1281          break;
1282 
1283       default:
1284          return(-EOPNOTSUPP);
1285    }
1286    return(0);
1287 }
1288 
1289 int sdla_change_mtu(struct device *dev, int new_mtu)
     /* [previous][next][first][last][top][bottom][index][help] */
1290 {
1291    struct frad_local *flp;
1292 
1293    flp = dev->priv;
1294 
1295    if (dev->start)
1296       return(-EBUSY);
1297 
1298    /* for now, you can't change the MTU! */
1299    return(-EACCES);
1300 }
1301 
1302 int sdla_set_config(struct device *dev, struct ifmap *map)
     /* [previous][next][first][last][top][bottom][index][help] */
1303 {
1304    struct frad_local *flp;
1305    int               i;
1306    char              byte;
1307 
1308    flp = dev->priv;
1309 
1310    if (flp->initialized)
1311       return(-EINVAL);
1312 
1313    for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
1314       if (valid_port[i] == map->base_addr)
1315          break;   
1316 
1317    if (i == sizeof(valid_port) / sizeof(int))
1318       return(-EINVAL);
1319 
1320    dev->base_addr = map->base_addr;
1321    request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name);
1322 
1323    /* test for card types, S502A, S502E, S507, S508                 */
1324    /* these tests shut down the card completely, so clear the state */
1325    flp->type = SDLA_UNKNOWN;
1326    flp->state = 0;
1327    
1328    for(i=1;i<SDLA_IO_EXTENTS;i++)
1329       if (inb(dev->base_addr + i) != 0xFF)
1330         break;
1331 
1332    if (i == SDLA_IO_EXTENTS)
1333    {   
1334       outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
1335       if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x08)
1336       {
1337          outb(SDLA_S502E_INTACK, dev->base_addr + SDLA_REG_CONTROL);
1338          if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x0C)
1339          {
1340             outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1341             flp->type = SDLA_S502E;
1342          }
1343       }
1344    }
1345 
1346    if (flp->type == SDLA_UNKNOWN)
1347    {
1348       for(byte=inb(dev->base_addr),i=0;i<SDLA_IO_EXTENTS;i++)
1349          if (inb(dev->base_addr + i) != byte)
1350             break;
1351 
1352       if (i == SDLA_IO_EXTENTS)
1353       {
1354          outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1355          if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x30)
1356          {
1357             outb(SDLA_S507_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
1358             if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x32)
1359             {
1360                outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1361                flp->type = SDLA_S507;
1362             }
1363          }
1364       }
1365    }
1366 
1367    if (flp->type == SDLA_UNKNOWN)
1368    {
1369       outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1370       if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x00)
1371       {
1372          outb(SDLA_S508_INTEN, dev->base_addr + SDLA_REG_CONTROL);
1373          if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x10)
1374          {
1375             outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1376             flp->type = SDLA_S508;
1377          }
1378       }
1379    }
1380 
1381    if (flp->type == SDLA_UNKNOWN)
1382    {
1383       outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
1384       if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
1385       {
1386          outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
1387          if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
1388          {
1389             outb(SDLA_S502A_INTEN, dev->base_addr + SDLA_REG_CONTROL);
1390             if (inb(dev->base_addr + SDLA_S502_STS) == 0x44)
1391             {
1392                outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
1393                flp->type = SDLA_S502A;
1394             }
1395          }
1396       }
1397    }
1398 
1399    if (flp->type == SDLA_UNKNOWN)
1400    {
1401       printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
1402       return(-ENODEV);
1403    }
1404 
1405    switch(dev->base_addr)
1406    {
1407       case 0x270:
1408       case 0x280:
1409       case 0x380: 
1410       case 0x390:
1411          if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
1412             return(-EINVAL);
1413    }
1414 
1415    switch (map->irq)
1416    {
1417       case 2:
1418          if (flp->type != SDLA_S502E)
1419             return(-EINVAL);
1420          break;
1421 
1422       case 10:
1423       case 11:
1424       case 12:
1425       case 15:
1426       case 4:
1427          if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
1428             return(-EINVAL);
1429 
1430       case 3:
1431       case 5:
1432       case 7:
1433          if (flp->type == SDLA_S502A)
1434             return(-EINVAL);
1435          break;
1436 
1437       default:
1438          return(-EINVAL);
1439    }
1440    dev->irq = map->irq;
1441 
1442    if (request_irq(dev->irq, &sdla_isr, 0, dev->name, NULL)) 
1443       return(-EADDRINUSE);
1444 
1445    irq2dev_map[dev->irq] = dev;
1446 
1447    if (flp->type == SDLA_S507)
1448    {
1449       switch(dev->irq)
1450       {
1451          case 3:
1452             flp->state = SDLA_S507_IRQ3;
1453             break;
1454          case 4:
1455             flp->state = SDLA_S507_IRQ4;
1456             break;
1457          case 5:
1458             flp->state = SDLA_S507_IRQ5;
1459             break;
1460          case 7:
1461             flp->state = SDLA_S507_IRQ7;
1462             break;
1463          case 10:
1464             flp->state = SDLA_S507_IRQ10;
1465             break;
1466          case 11:
1467             flp->state = SDLA_S507_IRQ11;
1468             break;
1469          case 12:
1470             flp->state = SDLA_S507_IRQ12;
1471             break;
1472          case 15:
1473             flp->state = SDLA_S507_IRQ15;
1474             break;
1475       }
1476    }
1477 
1478    for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
1479       if (valid_mem[i] == map->mem_start)
1480          break;   
1481 
1482    if (i == sizeof(valid_mem) / sizeof(int))
1483       return(-EINVAL);
1484 
1485    if ((flp->type == SDLA_S502A) && (((map->mem_start & 0xF000) >> 12) == 0x0E))
1486       return(-EINVAL);
1487 
1488    if ((flp->type != SDLA_S507) && ((map->mem_start >> 16) == 0x0B))
1489       return(-EINVAL);
1490 
1491    if ((flp->type == SDLA_S507) && ((map->mem_start >> 16) == 0x0D))
1492       return(-EINVAL);
1493 
1494    dev->mem_start = map->mem_start;
1495    dev->mem_end = dev->mem_start + 0x2000;
1496 
1497    byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
1498    byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
1499    switch(flp->type)
1500    {
1501       case SDLA_S502A:
1502       case SDLA_S502E:
1503          switch (map->mem_start >> 16)
1504          {
1505             case 0x0A:
1506                byte |= SDLA_S502_SEG_A;
1507                break;
1508             case 0x0C:
1509                byte |= SDLA_S502_SEG_C;
1510                break;
1511             case 0x0D:
1512                byte |= SDLA_S502_SEG_D;
1513                break;
1514             case 0x0E:
1515                byte |= SDLA_S502_SEG_E;
1516                break;
1517          }
1518          break;
1519       case SDLA_S507:
1520          switch (map->mem_start >> 16)
1521          {
1522             case 0x0A:
1523                byte |= SDLA_S507_SEG_A;
1524                break;
1525             case 0x0B:
1526                byte |= SDLA_S507_SEG_B;
1527                break;
1528             case 0x0C:
1529                byte |= SDLA_S507_SEG_C;
1530                break;
1531             case 0x0E:
1532                byte |= SDLA_S507_SEG_E;
1533                break;
1534          }
1535          break;
1536       case SDLA_S508:
1537          switch (map->mem_start >> 16)
1538          {
1539             case 0x0A:
1540                byte |= SDLA_S508_SEG_A;
1541                break;
1542             case 0x0C:
1543                byte |= SDLA_S508_SEG_C;
1544                break;
1545             case 0x0D:
1546                byte |= SDLA_S508_SEG_D;
1547                break;
1548             case 0x0E:
1549                byte |= SDLA_S508_SEG_E;
1550                break;
1551          }
1552          break;
1553    }
1554 
1555    /* set the memory bits, and enable access */
1556    outb(byte, dev->base_addr + SDLA_REG_PC_WINDOW);
1557    switch(flp->type)
1558    {
1559       case SDLA_S502E:
1560          flp->state = SDLA_S502E_ENABLE;
1561          break;
1562       case SDLA_S507:
1563          flp->state |= SDLA_MEMEN;
1564          break;
1565       case SDLA_S508:
1566          flp->state = SDLA_MEMEN;
1567          break;
1568    }
1569    outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1570 
1571    flp->initialized = 1;
1572    return(0);
1573 }
1574  
1575 static struct enet_statistics *sdla_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1576 {
1577    struct frad_local *flp;
1578 
1579    flp = dev->priv;
1580 
1581    return(&flp->stats);
1582 }
1583 
1584 int sdla_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1585 {
1586    struct frad_local *flp;
1587    int               i;
1588 
1589    /* allocate the private data structure */
1590    flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL);
1591    if (!flp)
1592       return(-ENOMEM);
1593 
1594    memset(flp, 0, sizeof(struct frad_local));
1595    dev->priv = flp;
1596 
1597    dev->flags           = 0;
1598    dev->open            = sdla_open;
1599    dev->stop            = sdla_close;
1600    dev->do_ioctl        = sdla_ioctl;
1601    dev->set_config      = sdla_set_config;
1602    dev->get_stats       = sdla_stats;
1603    dev->hard_start_xmit = sdla_transmit;
1604    dev->change_mtu      = sdla_change_mtu;
1605 
1606    dev->type            = 0xFFFF;
1607    dev->family          = AF_UNSPEC;
1608    dev->pa_alen         = sizeof(unsigned long);
1609    dev->hard_header_len = 0;
1610    dev->mtu             = SDLA_MAX_MTU;
1611 
1612    for (i = 0; i < DEV_NUMBUFFS; i++) 
1613       skb_queue_head_init(&dev->buffs[i]);
1614 
1615    flp->activate        = sdla_activate;
1616    flp->deactivate      = sdla_deactivate;
1617    flp->assoc           = sdla_assoc;
1618    flp->deassoc         = sdla_deassoc;
1619    flp->dlci_conf       = sdla_dlci_conf;
1620 
1621    init_timer(&flp->timer);
1622    flp->timer.expires   = 1;
1623    flp->timer.data      = (unsigned long) dev;
1624    flp->timer.function  = sdla_poll;
1625 
1626    return(0);
1627 }
1628 
1629 void sdla_setup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1630 {
1631    printk("%s.\n", version);
1632    register_frad(devname);
1633 }
1634 
1635 #ifdef MODULE
1636 static struct device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init};
1637 
1638 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1639 {
1640    int result;
1641 
1642    sdla_setup();
1643    if ((result = register_netdev(&sdla0)) != 0)
1644       return result;
1645 
1646    return 0;
1647 }
1648 
1649 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1650 {
1651    unregister_netdev(&sdla0);
1652    if (sdla0.priv)
1653       kfree(sdla0.priv);
1654    if (sdla0.irq)
1655       free_irq(sdla0.irq, NULL);
1656 }
1657 #endif /* MODULE */

/* [previous][next][first][last][top][bottom][index][help] */