root/drivers/net/3c501.c

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

DEFINITIONS

This source file includes following definitions.
  1. el1_probe
  2. el_open
  3. el_start_xmit
  4. el_interrupt
  5. el_receive
  6. el_reset
  7. el1_close
  8. el1_get_stats
  9. set_multicast_list
  10. init_module
  11. cleanup_module

   1 /* 3c501.c: A 3Com 3c501 ethernet driver for linux. */
   2 /*
   3     Copyright (C) 1992,1993  Donald Becker
   4 
   5     Copyright 1993 United States Government as represented by the
   6     Director, National Security Agency.  This software may be used and
   7     distributed according to the terms of the GNU Public License,
   8     incorporated herein by reference.
   9 
  10     This is a device driver for the 3Com Etherlink 3c501.
  11     Do not purchase this card, even as a joke.  It's performance is horrible,
  12     and it breaks in many ways.  
  13 
  14     The Author may be reached as becker@super.org or
  15     C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
  16     I'll only accept bug fixes, not reports, for the 3c501 driver.
  17 */
  18 
  19 static char *version =
  20     "3c501.c: 3/3/94 Donald Becker (becker@super.org).\n";
  21 
  22 /*
  23   Braindamage remaining:
  24   The 3c501 board.
  25   */
  26 
  27 #include <linux/config.h>
  28 #include <linux/kernel.h>
  29 #include <linux/sched.h>
  30 #include <linux/ptrace.h>
  31 #include <linux/fcntl.h>
  32 #include <linux/ioport.h>
  33 #include <linux/interrupt.h>
  34 #include <linux/malloc.h>
  35 #include <linux/ioport.h>
  36 #include <asm/bitops.h>
  37 #include <asm/io.h>
  38 #include <errno.h>
  39 
  40 #include <linux/netdevice.h>
  41 #include <linux/etherdevice.h>
  42 #include <linux/skbuff.h>
  43 
  44 #ifdef MODULE
  45 #include <linux/module.h>
  46 #include "../../tools/version.h"
  47 #endif
  48 
  49 #ifndef HAVE_AUTOIRQ
  50 /* From auto_irq.c, should be in a *.h file. */
  51 extern void autoirq_setup(int waittime);
  52 extern int autoirq_report(int waittime);
  53 extern struct device *irq2dev_map[16];
  54 #endif
  55 
  56 
  57 /* Index to functions. */
  58 int el1_probe(struct device *dev);
  59 static int  el_open(struct device *dev);
  60 static int  el_start_xmit(struct sk_buff *skb, struct device *dev);
  61 static void el_interrupt(int reg_ptr);
  62 static void el_receive(struct device *dev);
  63 static void el_reset(struct device *dev);
  64 static int  el1_close(struct device *dev);
  65 static struct enet_statistics *el1_get_stats(struct device *dev);
  66 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
  67 
  68 #define EL_NAME "EtherLink 3c501"
  69 
  70 #ifndef EL_DEBUG
  71 #define EL_DEBUG  2     /* use 0 for production, 1 for devel., >2 for debug */
  72 #endif                  /* Anything above 5 is wordy death! */
  73 static int el_debug = EL_DEBUG;
  74 static int el_base;
  75 static struct device *eldev;    /* Only for consistency checking.  */
  76  
  77 /* We could easily have this struct kmalloc()ed per-board, but
  78    who would want more than one 3c501?. */
  79 static struct {
  80     struct enet_statistics stats;
  81     int tx_pkt_start;           /* The length of the current Tx packet. */
  82     int collisions;             /* Tx collisions this packet */
  83 } el_status;                    /* This should be stored per-board */
  84 
  85 
  86 #define RX_STATUS (el_base + 0x06)
  87 #define RX_CMD    RX_STATUS
  88 #define TX_STATUS (el_base + 0x07)
  89 #define TX_CMD    TX_STATUS
  90 #define GP_LOW    (el_base + 0x08)
  91 #define GP_HIGH   (el_base + 0x09)
  92 #define RX_BUF_CLR (el_base + 0x0A)
  93 #define RX_LOW    (el_base + 0x0A)
  94 #define RX_HIGH   (el_base + 0x0B)
  95 #define SAPROM    (el_base + 0x0C)
  96 #define AX_STATUS (el_base + 0x0E)
  97 #define AX_CMD    AX_STATUS
  98 #define DATAPORT  (el_base + 0x0F)
  99 #define TX_RDY 0x08             /* In TX_STATUS */
 100 
 101 #define EL1_DATAPTR     0x08
 102 #define EL1_RXPTR       0x0A
 103 #define EL1_SAPROM      0x0C
 104 #define EL1_DATAPORT    0x0f
 105 
 106 /* Writes to the ax command register. */
 107 #define AX_OFF  0x00                    /* Irq off, buffer access on */
 108 #define AX_SYS  0x40                    /* Load the buffer */
 109 #define AX_XMIT 0x44                    /* Transmit a packet */
 110 #define AX_RX   0x48                    /* Receive a packet */
 111 #define AX_LOOP 0x0C                    /* Loopback mode */
 112 #define AX_RESET 0x80
 113 
 114 /* Normal receive mode written to RX_STATUS.  We must intr on short packets
 115    to avoid bogus rx lockups. */
 116 #define RX_NORM 0xA8            /* 0x68 == all addrs, 0xA8 only to me. */
 117 #define RX_PROM 0x68            /* Senior Prom, uhmm promiscuous mode. */
 118 #define RX_MULT 0xE8            /* Accept multicast packets. */
 119 #define TX_NORM 0x0A    /* Interrupt on everything that might hang the chip */
 120 
 121 /* TX_STATUS register. */
 122 #define TX_COLLISION 0x02
 123 #define TX_16COLLISIONS 0x04
 124 #define TX_READY 0x08
 125 
 126 #define RX_RUNT 0x08
 127 #define RX_MISSED 0x01          /* Missed a packet due to 3c501 braindamage. */
 128 #define RX_GOOD 0x30            /* Good packet 0x20, or simple overflow 0x10. */
 129 
 130 
 131 int
 132 el1_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134     int i;
 135     int ioaddr;
 136     unsigned char station_addr[6];
 137     int autoirq = 0;
 138 
 139     eldev = dev;                /* Store for debugging. */
 140     el_base = dev->base_addr;
 141 
 142     if (el_base < 0x40)         /* Invalid?  Probe for it. */
 143         el_base = 0x280;
 144 
 145     ioaddr = el_base;
 146 
 147     /* Read the station address PROM data from the special port.  */
 148     for (i = 0; i < 6; i++) {
 149         outw(i, ioaddr + EL1_DATAPTR);
 150         station_addr[i] = inb(ioaddr + EL1_SAPROM);
 151     }
 152     /* Check the first three octets of the S.A. for 3Com's code. */ 
 153     if (station_addr[0] != 0x02  ||  station_addr[1] != 0x60
 154         || station_addr[2] != 0x8c) {
 155         return ENODEV;
 156     }
 157 
 158 #ifdef HAVE_PORTRESERVE
 159     /* Grab the region so we can find the another board if autoIRQ fails. */
 160     snarf_region(ioaddr, 16);
 161 #endif
 162 
 163     /* We auto-IRQ by shutting off the interrupt line and letting it float
 164        high. */
 165     if (dev->irq < 2) {
 166 
 167         autoirq_setup(2);
 168 
 169         inb(RX_STATUS);         /* Clear pending interrupts. */
 170         inb(TX_STATUS);
 171         outb(AX_LOOP + 1, AX_CMD);
 172 
 173         outb(0x00, AX_CMD);
 174 
 175         autoirq = autoirq_report(1);
 176 
 177         if (autoirq == 0) {
 178             printk("%s: 3c501 probe failed to detect IRQ line.\n", dev->name);
 179             return EAGAIN;
 180         }
 181         dev->irq = autoirq;
 182     }
 183 
 184     outb(AX_RESET+AX_LOOP, AX_CMD);                     /* Loopback mode. */
 185 
 186     dev->base_addr = el_base;
 187     memcpy(dev->dev_addr, station_addr, ETH_ALEN);
 188     if (dev->mem_start & 0xf)
 189         el_debug = dev->mem_start & 0x7;
 190 
 191     printk("%s: 3c501 EtherLink at %#x, using %sIRQ %d, melting ethernet.\n",
 192            dev->name, dev->base_addr, autoirq ? "auto":"assigned ", dev->irq);
 193 
 194     if (el_debug)
 195         printk("%s", version);
 196 
 197     /* The EL1-specific entries in the device structure. */
 198     dev->open = &el_open;
 199     dev->hard_start_xmit = &el_start_xmit;
 200     dev->stop = &el1_close;
 201     dev->get_stats = &el1_get_stats;
 202     dev->set_multicast_list = &set_multicast_list;
 203     /* Setup the generic properties */
 204     ether_setup(dev);
 205 
 206     return 0;
 207 }
 208 
 209 /* Open/initialize the board. */
 210 static int
 211 el_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 212 {
 213 
 214   if (el_debug > 2)
 215       printk("%s: Doing el_open()...", dev->name);
 216 
 217   if (request_irq(dev->irq, &el_interrupt, 0, "3c501")) {
 218       if (el_debug > 2)
 219           printk("interrupt busy, exiting el_open().\n");
 220       return -EAGAIN;
 221   }
 222   irq2dev_map[dev->irq] = dev;
 223 
 224   el_reset(dev);
 225 
 226   dev->start = 1;
 227 
 228   outb(AX_RX, AX_CMD);  /* Aux control, irq and receive enabled */
 229   if (el_debug > 2)
 230      printk("finished el_open().\n");
 231 #ifdef MODULE
 232   MOD_INC_USE_COUNT;
 233 #endif       
 234   return (0);
 235 }
 236 
 237 static int
 238 el_start_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 239 {
 240     unsigned long flags;
 241     
 242     save_flags(flags);
 243     if (dev->tbusy) {
 244         if (jiffies - dev->trans_start < 20) {
 245             if (el_debug > 2)
 246                 printk(" transmitter busy, deferred.\n");
 247             return 1;
 248         }
 249         if (el_debug)
 250             printk ("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
 251                     dev->name, inb(TX_STATUS), inb(AX_STATUS), inb(RX_STATUS));
 252         el_status.stats.tx_errors++;
 253 #ifdef oldway
 254         el_reset(dev);
 255 #else
 256         cli();
 257         outb(TX_NORM, TX_CMD);
 258         outb(RX_NORM, RX_CMD);
 259         outb(AX_OFF, AX_CMD);   /* Just trigger a false interrupt. */
 260 #endif
 261         outb(AX_RX, AX_CMD);    /* Aux control, irq and receive enabled */
 262         dev->tbusy = 0;
 263         restore_flags(flags);
 264         dev->trans_start = jiffies;
 265     }
 266 
 267     if (skb == NULL) {
 268         dev_tint(dev);
 269         return 0;
 270     }
 271 
 272     if (skb->len <= 0)
 273         return 0;
 274 
 275     /* Avoid timer-based retransmission conflicts. */
 276     cli();
 277     if (set_bit(0, (void*)&dev->tbusy) != 0)
 278     {
 279         printk("%s: Transmitter access conflict.\n", dev->name);
 280         restore_flags(flags);
 281     } else {
 282         int gp_start = 0x800 - (ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
 283         unsigned char *buf = skb->data;
 284 
 285         el_status.tx_pkt_start = gp_start;
 286         el_status.collisions = 0;
 287 
 288         outb(AX_SYS, AX_CMD);
 289         inb(RX_STATUS);
 290         inb(TX_STATUS);
 291         outb(0x00, RX_BUF_CLR); /* Set rx packet area to 0. */
 292         outw(gp_start, GP_LOW);
 293         restore_flags(flags);
 294         outsb(DATAPORT,buf,skb->len);
 295         outw(gp_start, GP_LOW);
 296         outb(AX_XMIT, AX_CMD);          /* Trigger xmit.  */
 297         dev->trans_start = jiffies;
 298     }
 299 
 300     if (el_debug > 2)
 301         printk(" queued xmit.\n");
 302     dev_kfree_skb (skb, FREE_WRITE);
 303     return 0;
 304 }
 305 
 306 
 307 /* The typical workload of the driver:
 308    Handle the ether interface interrupts. */
 309 static void
 310 el_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 311 {
 312     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 313     /*struct device *dev = (struct device *)(irq2dev_map[irq]);*/
 314     struct device *dev = eldev;
 315     int axsr;                   /* Aux. status reg. */
 316     short ioaddr;
 317 
 318     if (eldev->irq != irq) {
 319         printk (EL_NAME ": irq %d for unknown device\n", irq);
 320         return;
 321     }
 322 
 323     ioaddr = dev->base_addr;
 324 
 325     axsr = inb(AX_STATUS);
 326 
 327     if (el_debug > 3)
 328       printk("%s: el_interrupt() aux=%#02x", dev->name, axsr);
 329     if (dev->interrupt)
 330         printk("%s: Reentering the interrupt driver!\n", dev->name);
 331     dev->interrupt = 1;
 332 
 333     if (dev->tbusy) {
 334         int txsr = inb(TX_STATUS);
 335 
 336         if (el_debug > 6)
 337             printk(" txsr=%02x gp=%04x rp=%04x", txsr, inw(GP_LOW),
 338                    inw(RX_LOW));
 339 
 340         if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
 341             printk("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x"
 342                    " gp=%03x rp=%03x.\n", dev->name, txsr, axsr,
 343                    inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR));
 344             dev->tbusy = 0;
 345             mark_bh(NET_BH);
 346         } else if (txsr & TX_16COLLISIONS) {
 347             if (el_debug)
 348                 printk("%s: Transmit failed 16 times, ethernet jammed?\n",
 349                        dev->name);
 350             outb(AX_SYS, AX_CMD);
 351             el_status.stats.tx_aborted_errors++;
 352         } else if (txsr & TX_COLLISION) {       /* Retrigger xmit. */
 353             if (el_debug > 6)
 354                 printk(" retransmitting after a collision.\n");
 355             outb(AX_SYS, AX_CMD);
 356             outw(el_status.tx_pkt_start, GP_LOW);
 357             outb(AX_XMIT, AX_CMD);
 358             el_status.stats.collisions++;
 359             dev->interrupt = 0;
 360             return;
 361         } else {
 362             el_status.stats.tx_packets++;
 363             if (el_debug > 6)
 364                 printk(" Tx succeeded %s\n",
 365                        (txsr & TX_RDY) ? "." : "but tx is busy!");
 366             dev->tbusy = 0;
 367             mark_bh(NET_BH);
 368         }
 369     } else {
 370         int rxsr = inb(RX_STATUS);
 371         if (el_debug > 5)
 372             printk(" rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS),
 373                    inw(RX_LOW));
 374 
 375         /* Just reading rx_status fixes most errors. */
 376         if (rxsr & RX_MISSED)
 377             el_status.stats.rx_missed_errors++;
 378         if (rxsr & RX_RUNT) {   /* Handled to avoid board lock-up. */
 379             el_status.stats.rx_length_errors++;
 380             if (el_debug > 5) printk(" runt.\n");
 381         } else if (rxsr & RX_GOOD) {
 382             el_receive(eldev);
 383         } else {                        /* Nothing?  Something is broken! */
 384             if (el_debug > 2)
 385                 printk("%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
 386                        dev->name, rxsr);
 387             el_reset(eldev);
 388         }
 389         if (el_debug > 3)
 390             printk(".\n");
 391     }
 392 
 393     outb(AX_RX, AX_CMD);
 394     outb(0x00, RX_BUF_CLR);
 395     inb(RX_STATUS);             /* Be certain that interrupts are cleared. */
 396     inb(TX_STATUS);
 397     dev->interrupt = 0;
 398     return;
 399 }
 400 
 401 
 402 /* We have a good packet. Well, not really "good", just mostly not broken.
 403    We must check everything to see if it is good. */
 404 static void
 405 el_receive(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 406 {
 407     int pkt_len;
 408     struct sk_buff *skb;
 409 
 410     pkt_len = inw(RX_LOW);
 411 
 412     if (el_debug > 4)
 413       printk(" el_receive %d.\n", pkt_len);
 414 
 415     if ((pkt_len < 60)  ||  (pkt_len > 1536)) {
 416         if (el_debug)
 417           printk("%s: bogus packet, length=%d\n", dev->name, pkt_len);
 418         el_status.stats.rx_over_errors++;
 419         return;
 420     }
 421     outb(AX_SYS, AX_CMD);
 422 
 423     skb = alloc_skb(pkt_len, GFP_ATOMIC);
 424     outw(0x00, GP_LOW);
 425     if (skb == NULL) {
 426         printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 427         el_status.stats.rx_dropped++;
 428         return;
 429     } else {
 430         skb->len = pkt_len;
 431         skb->dev = dev;
 432 
 433         insb(DATAPORT, skb->data, pkt_len);
 434 
 435         netif_rx(skb);
 436         el_status.stats.rx_packets++;
 437     }
 438     return;
 439 }
 440 
 441 static void 
 442 el_reset(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 443 {
 444     if (el_debug> 2)
 445         printk("3c501 reset...");
 446     outb(AX_RESET, AX_CMD);     /* Reset the chip */
 447     outb(AX_LOOP, AX_CMD);      /* Aux control, irq and loopback enabled */
 448     {
 449         int i;
 450         for (i = 0; i < 6; i++) /* Set the station address. */
 451             outb(dev->dev_addr[i], el_base + i);
 452     }
 453     
 454     outb(0, RX_BUF_CLR);                /* Set rx packet area to 0. */
 455     cli();                      /* Avoid glitch on writes to CMD regs */
 456     outb(TX_NORM, TX_CMD);              /* tx irq on done, collision */
 457     outb(RX_NORM, RX_CMD);      /* Set Rx commands. */
 458     inb(RX_STATUS);             /* Clear status. */
 459     inb(TX_STATUS);
 460     dev->interrupt = 0;
 461     dev->tbusy = 0;
 462     sti();
 463 }
 464 
 465 static int
 466 el1_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 467 {
 468     int ioaddr = dev->base_addr;
 469 
 470     if (el_debug > 2)
 471         printk("%s: Shutting down ethercard at %#x.\n", dev->name, ioaddr);
 472 
 473     dev->tbusy = 1;
 474     dev->start = 0;
 475 
 476     /* Free and disable the IRQ. */
 477     free_irq(dev->irq);
 478     outb(AX_RESET, AX_CMD);     /* Reset the chip */
 479     irq2dev_map[dev->irq] = 0;
 480 
 481 #ifdef MODULE
 482     MOD_DEC_USE_COUNT;
 483 #endif    
 484     return 0;
 485 }
 486 
 487 static struct enet_statistics *
 488 el1_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 489 {
 490     return &el_status.stats;
 491 }
 492 
 493 /* Set or clear the multicast filter for this adaptor.
 494    num_addrs == -1      Promiscuous mode, receive all packets
 495    num_addrs == 0       Normal mode, clear multicast list
 496    num_addrs > 0        Multicast mode, receive normal and MC packets, and do
 497                         best-effort filtering.
 498  */
 499 static void
 500 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 501 {
 502     if (num_addrs > 0) {
 503         outb(RX_MULT, RX_CMD);
 504         inb(RX_STATUS);         /* Clear status. */
 505     } else if (num_addrs < 0) {
 506         outb(RX_PROM, RX_CMD);
 507         inb(RX_STATUS);
 508     } else {
 509         outb(RX_NORM, RX_CMD);
 510         inb(RX_STATUS);
 511     }
 512 }
 513 
 514 /*
 515  * Local variables:
 516  *  compile-command: "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer  -m486 -c -o 3c501.o 3c501.c"
 517  *  kept-new-versions: 5
 518  * End:
 519  */
 520 
 521 #ifdef MODULE
 522 char kernel_version[] = UTS_RELEASE;
 523 static struct device dev_3c501 = {
 524         "        " /*"3c501"*/, 
 525                 0, 0, 0, 0,
 526                 0x280, 5,
 527                 0, 0, 0, NULL, el1_probe };
 528         
 529 int
 530 init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 531 {
 532         if (register_netdev(&dev_3c501) != 0)
 533                 return -EIO;
 534         return 0;
 535 }
 536 
 537 void
 538 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 539 {
 540         if (MOD_IN_USE)
 541                 printk("3c501: device busy, remove delayed\n");
 542         else
 543         {
 544                 unregister_netdev(&dev_3c501);
 545         }
 546 }
 547 #endif /* MODULE */

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