root/drivers/net/3c509.c

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

DEFINITIONS

This source file includes following definitions.
  1. el3_probe
  2. read_eeprom
  3. id_read_eeprom
  4. el3_open
  5. el3_start_xmit
  6. el3_interrupt
  7. el3_get_stats
  8. update_stats
  9. el3_rx
  10. set_multicast_list
  11. el3_close
  12. init_module
  13. cleanup_module

   1 /* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
   2 /*
   3         Written 1993-1995 by Donald Becker.
   4 
   5         Copyright 1994,1995 by Donald Becker.
   6         Copyright 1993 United States Government as represented by the
   7         Director, National Security Agency.      This software may be used and
   8         distributed according to the terms of the GNU Public License,
   9         incorporated herein by reference.
  10 
  11         This driver is for the 3Com EtherLinkIII series.
  12 
  13         The author may be reached as becker@cesdis.gsfc.nasa.gov or
  14         C/O Center of Excellence in Space Data and Information Sciences
  15                 Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
  16 
  17         Known limitations:
  18         Because of the way 3c509 ISA detection works it's difficult to predict
  19         a priori which of several ISA-mode cards will be detected first.
  20 
  21         This driver does not use predictive interrupt mode, resulting in higher
  22         packet latency but lower overhead.  If interrupts are disabled for an
  23         unusually long time it could also result in missed packets, but in
  24         practice this rarely happens.
  25 
  26 
  27         FIXES:
  28                 Alan Cox:       Removed the 'Unexpected interrupt' bug.
  29                 Michael Meskes: Upgraded to Donald Becker's version 1.07.
  30 */
  31 
  32 static char *version = "3c509.c:1.07 6/15/95 becker@cesdis.gsfc.nasa.gov\n";
  33 
  34 #include <linux/module.h>
  35 
  36 #include <linux/config.h>
  37 #include <linux/kernel.h>
  38 #include <linux/sched.h>
  39 #include <linux/string.h>
  40 #include <linux/interrupt.h>
  41 #include <linux/ptrace.h>
  42 #include <linux/errno.h>
  43 #include <linux/in.h>
  44 #include <linux/malloc.h>
  45 #include <linux/ioport.h>
  46 #include <linux/netdevice.h>
  47 #include <linux/etherdevice.h>
  48 #include <linux/skbuff.h>
  49 #include <linux/config.h>       /* for CONFIG_MCA */
  50 
  51 #include <asm/bitops.h>
  52 #include <asm/io.h>
  53 
  54 
  55 #ifdef EL3_DEBUG
  56 int el3_debug = EL3_DEBUG;
  57 #else
  58 int el3_debug = 2;
  59 #endif
  60 
  61 /* To minimize the size of the driver source I only define operating
  62    constants if they are used several times.  You'll need the manual
  63    if you want to understand driver details. */
  64 /* Offsets from base I/O address. */
  65 #define EL3_DATA 0x00
  66 #define EL3_CMD 0x0e
  67 #define EL3_STATUS 0x0e
  68 #define  EEPROM_READ 0x80
  69 
  70 #define EL3_IO_EXTENT   16
  71 
  72 #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
  73 
  74 
  75 /* The top five bits written to EL3_CMD are a command, the lower
  76    11 bits are the parameter, if applicable. */
  77 enum c509cmd {
  78         TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
  79         RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
  80         TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
  81         FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
  82         SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
  83         SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
  84         StatsDisable = 22<<11, StopCoax = 23<<11,};
  85 
  86 enum c509status {
  87         IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
  88         TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
  89         IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000, };
  90 
  91 /* The SetRxFilter command accepts the following classes: */
  92 enum RxFilter {
  93         RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
  94 
  95 /* Register window 1 offsets, the window used in normal operation. */
  96 #define TX_FIFO         0x00
  97 #define RX_FIFO         0x00
  98 #define RX_STATUS       0x08
  99 #define TX_STATUS       0x0B
 100 #define TX_FREE         0x0C            /* Remaining free bytes in Tx buffer. */
 101 
 102 #define WN0_IRQ         0x08            /* Window 0: Set IRQ line in bits 12-15. */
 103 #define WN4_MEDIA       0x0A            /* Window 4: Various transcvr/media bits. */
 104 #define  MEDIA_TP       0x00C0          /* Enable link beat and jabber for 10baseT. */
 105 
 106 /*
 107  * Must be a power of two (we use a binary and in the
 108  * circular queue)
 109  */
 110 #define SKB_QUEUE_SIZE  64
 111 
 112 struct el3_private {
 113         struct enet_statistics stats;
 114         /* skb send-queue */
 115         int head, size;
 116         struct sk_buff *queue[SKB_QUEUE_SIZE];
 117 };
 118 static int id_port = 0x100;
 119 
 120 static ushort id_read_eeprom(int index);
 121 static ushort read_eeprom(short ioaddr, int index);
 122 static int el3_open(struct device *dev);
 123 static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
 124 static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 125 static void update_stats(int addr, struct device *dev);
 126 static struct enet_statistics *el3_get_stats(struct device *dev);
 127 static int el3_rx(struct device *dev);
 128 static int el3_close(struct device *dev);
 129 #ifdef HAVE_MULTICAST
 130 static void set_multicast_list(struct device *dev);
 131 #endif
 132 
 133 
 134 
 135 int el3_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         short lrs_state = 0xff, i;
 138         ushort ioaddr, irq, if_port;
 139         short *phys_addr = (short *)dev->dev_addr;
 140         static int current_tag = 0;
 141 
 142         /* First check all slots of the EISA bus.  The next slot address to
 143            probe is kept in 'eisa_addr' to support multiple probe() calls. */
 144         if (EISA_bus) {
 145                 static int eisa_addr = 0x1000;
 146                 while (eisa_addr < 0x9000) {
 147                         ioaddr = eisa_addr;
 148                         eisa_addr += 0x1000;
 149 
 150                         /* Check the standard EISA ID register for an encoded '3Com'. */
 151                         if (inw(ioaddr + 0xC80) != 0x6d50)
 152                                 continue;
 153 
 154                         /* Change the register set to the configuration window 0. */
 155                         outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
 156 
 157                         irq = inw(ioaddr + WN0_IRQ) >> 12;
 158                         if_port = inw(ioaddr + 6)>>14;
 159                         for (i = 0; i < 3; i++)
 160                                 phys_addr[i] = htons(read_eeprom(ioaddr, i));
 161 
 162                         /* Restore the "Product ID" to the EEPROM read register. */
 163                         read_eeprom(ioaddr, 3);
 164 
 165                         /* Was the EISA code an add-on hack?  Nahhhhh... */
 166                         goto found;
 167                 }
 168         }
 169 
 170 #ifdef CONFIG_MCA
 171         if (MCA_bus) {
 172                 mca_adaptor_select_mode(1);
 173                 for (i = 0; i < 8; i++)
 174                         if ((mca_adaptor_id(i) | 1) == 0x627c) {
 175                                 ioaddr = mca_pos_base_addr(i);
 176                                 irq = inw(ioaddr + WN0_IRQ) >> 12;
 177                                 if_port = inw(ioaddr + 6)>>14;
 178                                 for (i = 0; i < 3; i++)
 179                                         phys_addr[i] = htons(read_eeprom(ioaddr, i));
 180 
 181                                 mca_adaptor_select_mode(0);
 182                                 goto found;
 183                         }
 184                 mca_adaptor_select_mode(0);
 185 
 186         }
 187 #endif
 188 
 189         /* Reset the ISA PnP mechanism on 3c509b. */
 190         outb(0x02, 0x279);           /* Select PnP config control register. */
 191         outb(0x02, 0xA79);           /* Return to WaitForKey state. */
 192         /* Select an open I/O location at 0x1*0 to do contention select. */
 193         for (id_port = 0x100; id_port < 0x200; id_port += 0x10) {
 194                 outb(0x00, id_port);
 195                 outb(0xff, id_port);
 196                 if (inb(id_port) & 0x01)
 197                         break;
 198         }
 199         if (id_port >= 0x200) {             /* GCC optimizes this test out. */
 200                 /* Rare -- do we really need a warning? */
 201                 printk(" WARNING: No I/O port available for 3c509 activation.\n");
 202                 return -ENODEV;
 203         }
 204         /* Next check for all ISA bus boards by sending the ID sequence to the
 205            ID_PORT.  We find cards past the first by setting the 'current_tag'
 206            on cards as they are found.  Cards with their tag set will not
 207            respond to subsequent ID sequences. */
 208 
 209         if (check_region(id_port,1)) {
 210           static int once = 1;
 211           if (once) printk("3c509: Somebody has reserved 0x%x, can't do ID_PORT lookup, nor card auto-probing\n",id_port);
 212           once = 0;
 213           return -ENODEV;
 214         }
 215 
 216         outb(0x00, id_port);
 217         outb(0x00, id_port);
 218         for(i = 0; i < 255; i++) {
 219                 outb(lrs_state, id_port);
 220                 lrs_state <<= 1;
 221                 lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
 222         }
 223 
 224         /* For the first probe, clear all board's tag registers. */
 225         if (current_tag == 0)
 226                 outb(0xd0, id_port);
 227         else                            /* Otherwise kill off already-found boards. */
 228                 outb(0xd8, id_port);
 229 
 230         if (id_read_eeprom(7) != 0x6d50) {
 231                 return -ENODEV;
 232         }
 233 
 234         /* Read in EEPROM data, which does contention-select.
 235            Only the lowest address board will stay "on-line".
 236            3Com got the byte order backwards. */
 237         for (i = 0; i < 3; i++) {
 238                 phys_addr[i] = htons(id_read_eeprom(i));
 239         }
 240 
 241         {
 242                 unsigned short iobase = id_read_eeprom(8);
 243                 if_port = iobase >> 14;
 244                 ioaddr = 0x200 + ((iobase & 0x1f) << 4);
 245         }
 246         if (dev->irq > 1  &&  dev->irq < 16)
 247                 irq = dev->irq;
 248         else
 249                 irq = id_read_eeprom(9) >> 12;
 250 
 251         if (dev->base_addr != 0
 252                 &&      dev->base_addr != (unsigned short)ioaddr) {
 253                 return -ENODEV;
 254         }
 255 
 256         /* Set the adaptor tag so that the next card can be found. */
 257         outb(0xd0 + ++current_tag, id_port);
 258 
 259         /* Activate the adaptor at the EEPROM location. */
 260         outb((ioaddr >> 4) | 0xe0, id_port);
 261 
 262         EL3WINDOW(0);
 263         if (inw(ioaddr) != 0x6d50)
 264                 return -ENODEV;
 265 
 266         /* Free the interrupt so that some other card can use it. */
 267         outw(0x0f00, ioaddr + WN0_IRQ);
 268  found:
 269         dev->base_addr = ioaddr;
 270         dev->irq = irq;
 271         dev->if_port = if_port;
 272         request_region(dev->base_addr, EL3_IO_EXTENT, "3c509");
 273 
 274         {
 275                 const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
 276                 printk("%s: 3c509 at %#3.3lx tag %d, %s port, address ",
 277                            dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
 278         }
 279 
 280         /* Read in the station address. */
 281         for (i = 0; i < 6; i++)
 282                 printk(" %2.2x", dev->dev_addr[i]);
 283         printk(", IRQ %d.\n", dev->irq);
 284 
 285         /* Make up a EL3-specific-data structure. */
 286         dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
 287         if (dev->priv == NULL)
 288                 return -ENOMEM;
 289         memset(dev->priv, 0, sizeof(struct el3_private));
 290 
 291         if (el3_debug > 0)
 292                 printk(version);
 293 
 294         /* The EL3-specific entries in the device structure. */
 295         dev->open = &el3_open;
 296         dev->hard_start_xmit = &el3_start_xmit;
 297         dev->stop = &el3_close;
 298         dev->get_stats = &el3_get_stats;
 299 #ifdef HAVE_MULTICAST
 300                 dev->set_multicast_list = &set_multicast_list;
 301 #endif
 302 
 303         /* Fill in the generic fields of the device structure. */
 304         ether_setup(dev);
 305         return 0;
 306 }
 307 
 308 /* Read a word from the EEPROM using the regular EEPROM access register.
 309    Assume that we are in register window zero.
 310  */
 311 static ushort read_eeprom(short ioaddr, int index)
     /* [previous][next][first][last][top][bottom][index][help] */
 312 {
 313         int timer;
 314 
 315         outw(EEPROM_READ + index, ioaddr + 10);
 316         /* Pause for at least 162 us. for the read to take place. */
 317         for (timer = 0; timer < 162*4 + 400; timer++)
 318                 SLOW_DOWN_IO;
 319         return inw(ioaddr + 12);
 320 }
 321 
 322 /* Read a word from the EEPROM when in the ISA ID probe state. */
 323 static ushort id_read_eeprom(int index)
     /* [previous][next][first][last][top][bottom][index][help] */
 324 {
 325         int timer, bit, word = 0;
 326 
 327         /* Issue read command, and pause for at least 162 us. for it to complete.
 328            Assume extra-fast 16Mhz bus. */
 329         outb(EEPROM_READ + index, id_port);
 330 
 331         /* This should really be done by looking at one of the timer channels. */
 332         for (timer = 0; timer < 162*4 + 400; timer++)
 333                 SLOW_DOWN_IO;
 334 
 335         for (bit = 15; bit >= 0; bit--)
 336                 word = (word << 1) + (inb(id_port) & 0x01);
 337 
 338         if (el3_debug > 3)
 339                 printk("  3c509 EEPROM word %d %#4.4x.\n", index, word);
 340 
 341         return word;
 342 }
 343 
 344 
 345 
 346 static int
 347 el3_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 348 {
 349         int ioaddr = dev->base_addr;
 350         int i;
 351 
 352         outw(TxReset, ioaddr + EL3_CMD);
 353         outw(RxReset, ioaddr + EL3_CMD);
 354         outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
 355 
 356         if (request_irq(dev->irq, &el3_interrupt, 0, "3c509", dev)) {
 357                 irq2dev_map[dev->irq] = NULL;
 358                 return -EAGAIN;
 359         }
 360 
 361         EL3WINDOW(0);
 362         if (el3_debug > 3)
 363                 printk("%s: Opening, IRQ %d      status@%x %4.4x.\n", dev->name,
 364                            dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
 365 
 366         /* Activate board: this is probably unnecessary. */
 367         outw(0x0001, ioaddr + 4);
 368 
 369         /* Set the IRQ line. */
 370         outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
 371 
 372         /* Set the station address in window 2 each time opened. */
 373         EL3WINDOW(2);
 374 
 375         for (i = 0; i < 6; i++)
 376                 outb(dev->dev_addr[i], ioaddr + i);
 377 
 378         if (dev->if_port == 3)
 379                 /* Start the thinnet transceiver. We should really wait 50ms...*/
 380                 outw(StartCoax, ioaddr + EL3_CMD);
 381         else if (dev->if_port == 0) {
 382                 /* 10baseT interface, enabled link beat and jabber check. */
 383                 EL3WINDOW(4);
 384                 outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
 385         }
 386 
 387         /* Switch to the stats window, and clear all stats by reading. */
 388         outw(StatsDisable, ioaddr + EL3_CMD);
 389         EL3WINDOW(6);
 390         for (i = 0; i < 9; i++)
 391                 inb(ioaddr + i);
 392         inw(ioaddr + 10);
 393         inw(ioaddr + 12);
 394 
 395         /* Switch to register set 1 for normal use. */
 396         EL3WINDOW(1);
 397 
 398         /* Accept b-case and phys addr only. */
 399         outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
 400         outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
 401 
 402         dev->interrupt = 0;
 403         dev->tbusy = 0;
 404         dev->start = 1;
 405 
 406         outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
 407         outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
 408         /* Allow status bits to be seen. */
 409         outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
 410         /* Ack all pending events, and set active indicator mask. */
 411         outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
 412                  ioaddr + EL3_CMD);
 413         outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull,
 414                  ioaddr + EL3_CMD);
 415 
 416         if (el3_debug > 3)
 417                 printk("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
 418                            dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
 419 
 420         MOD_INC_USE_COUNT;
 421         return 0;                                       /* Always succeed */
 422 }
 423 
 424 static int
 425 el3_start_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 426 {
 427         struct el3_private *lp = (struct el3_private *)dev->priv;
 428         int ioaddr = dev->base_addr;
 429 
 430         /* Transmitter timeout, serious problems. */
 431         if (dev->tbusy) {
 432                 int tickssofar = jiffies - dev->trans_start;
 433                 if (tickssofar < 40)
 434                         return 1;
 435                 printk("%s: transmit timed out, Tx_status %2.2x status %4.4x "
 436                            "Tx FIFO room %d.\n",
 437                            dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
 438                            inw(ioaddr + TX_FREE));
 439                 lp->stats.tx_errors++;
 440                 dev->trans_start = jiffies;
 441                 /* Issue TX_RESET and TX_START commands. */
 442                 outw(TxReset, ioaddr + EL3_CMD);
 443                 outw(TxEnable, ioaddr + EL3_CMD);
 444                 dev->tbusy = 0;
 445         }
 446 
 447         if (skb == NULL) {
 448                 dev_tint(dev);
 449                 return 0;
 450         }
 451 
 452         if (skb->len <= 0)
 453                 return 0;
 454 
 455         if (el3_debug > 4) {
 456                 printk("%s: el3_start_xmit(length = %ld) called, status %4.4x.\n",
 457                            dev->name, skb->len, inw(ioaddr + EL3_STATUS));
 458         }
 459 #if 0
 460 #ifndef final_version
 461         {       /* Error-checking code, delete someday. */
 462                 ushort status = inw(ioaddr + EL3_STATUS);
 463                 if (status & 0x0001             /* IRQ line active, missed one. */
 464                         && inw(ioaddr + EL3_STATUS) & 1) {                      /* Make sure. */
 465                         printk("%s: Missed interrupt, status then %04x now %04x"
 466                                    "  Tx %2.2x Rx %4.4x.\n", dev->name, status,
 467                                    inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
 468                                    inw(ioaddr + RX_STATUS));
 469                         /* Fake interrupt trigger by masking, acknowledge interrupts. */
 470                         outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
 471                         outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
 472                                  ioaddr + EL3_CMD);
 473                         outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
 474                 }
 475         }
 476 #endif
 477 #endif
 478         /* Avoid timer-based retransmission conflicts. */
 479         if (set_bit(0, (void*)&dev->tbusy) != 0)
 480                 printk("%s: Transmitter access conflict.\n", dev->name);
 481         else {
 482                 /* Put out the doubleword header... */
 483                 outw(skb->len, ioaddr + TX_FIFO);
 484                 outw(0x00, ioaddr + TX_FIFO);
 485                 /* ... and the packet rounded to a doubleword. */
 486                 outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 487 
 488                 dev->trans_start = jiffies;
 489                 if (inw(ioaddr + TX_FREE) > 1536) {
 490                         dev->tbusy = 0;
 491                 } else
 492                         /* Interrupt us when the FIFO has room for max-sized packet. */
 493                         outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
 494         }
 495 
 496         dev_kfree_skb (skb, FREE_WRITE);
 497 
 498         /* Clear the Tx status stack. */
 499         {
 500                 short tx_status;
 501                 int i = 4;
 502 
 503                 while (--i > 0  &&      (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
 504                         if (tx_status & 0x38) lp->stats.tx_aborted_errors++;
 505                         if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
 506                         if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
 507                         outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
 508                 }
 509         }
 510         return 0;
 511 }
 512 
 513 /* The EL3 interrupt handler. */
 514 static void
 515 el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 516 {
 517         struct device *dev = (struct device *)dev_id;
 518         int ioaddr, status;
 519         int i = 0;
 520 
 521         if (dev == NULL) {
 522                 printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
 523                 return;
 524         }
 525 
 526         if (dev->interrupt)
 527                 printk("%s: Re-entering the interrupt handler.\n", dev->name);
 528         dev->interrupt = 1;
 529 
 530         ioaddr = dev->base_addr;
 531         status = inw(ioaddr + EL3_STATUS);
 532 
 533         if (el3_debug > 4)
 534                 printk("%s: interrupt, status %4.4x.\n", dev->name, status);
 535 
 536         while ((status = inw(ioaddr + EL3_STATUS)) &
 537                    (IntLatch | RxComplete | StatsFull)) {
 538 
 539                 if (status & RxComplete)
 540                         el3_rx(dev);
 541 
 542                 if (status & TxAvailable) {
 543                         if (el3_debug > 5)
 544                                 printk("        TX room bit was handled.\n");
 545                         /* There's room in the FIFO for a full-sized packet. */
 546                         outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
 547                         dev->tbusy = 0;
 548                         mark_bh(NET_BH);
 549                 }
 550                 if (status & (AdapterFailure | RxEarly | StatsFull)) {
 551                         /* Handle all uncommon interrupts. */
 552                         if (status & StatsFull)                         /* Empty statistics. */
 553                                 update_stats(ioaddr, dev);
 554                         if (status & RxEarly) {                         /* Rx early is unused. */
 555                                 el3_rx(dev);
 556                                 outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
 557                         }
 558                         if (status & AdapterFailure) {
 559                                 /* Adapter failure requires Rx reset and reinit. */
 560                                 outw(RxReset, ioaddr + EL3_CMD);
 561                                 /* Set the Rx filter to the current state. */
 562                                 outw(SetRxFilter | RxStation | RxBroadcast
 563                                          | (dev->flags & IFF_ALLMULTI ? RxMulticast : 0)
 564                                          | (dev->flags & IFF_PROMISC ? RxProm : 0),
 565                                          ioaddr + EL3_CMD);
 566                                 outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
 567                                 outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);
 568                         }
 569                 }
 570 
 571                 if (++i > 10) {
 572                         printk("%s: Infinite loop in interrupt, status %4.4x.\n",
 573                                    dev->name, status);
 574                         /* Clear all interrupts. */
 575                         outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
 576                         break;
 577                 }
 578                 /* Acknowledge the IRQ. */
 579                 outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); /* Ack IRQ */
 580         }
 581 
 582         if (el3_debug > 4) {
 583                 printk("%s: exiting interrupt, status %4.4x.\n", dev->name,
 584                            inw(ioaddr + EL3_STATUS));
 585         }
 586 
 587         dev->interrupt = 0;
 588         return;
 589 }
 590 
 591 
 592 static struct enet_statistics *
 593 el3_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 594 {
 595         struct el3_private *lp = (struct el3_private *)dev->priv;
 596         unsigned long flags;
 597 
 598         save_flags(flags);
 599         cli();
 600         update_stats(dev->base_addr, dev);
 601         restore_flags(flags);
 602         return &lp->stats;
 603 }
 604 
 605 /*  Update statistics.  We change to register window 6, so this should be run
 606         single-threaded if the device is active. This is expected to be a rare
 607         operation, and it's simpler for the rest of the driver to assume that
 608         window 1 is always valid rather than use a special window-state variable.
 609         */
 610 static void update_stats(int ioaddr, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 611 {
 612         struct el3_private *lp = (struct el3_private *)dev->priv;
 613 
 614         if (el3_debug > 5)
 615                 printk("   Updating the statistics.\n");
 616         /* Turn off statistics updates while reading. */
 617         outw(StatsDisable, ioaddr + EL3_CMD);
 618         /* Switch to the stats window, and read everything. */
 619         EL3WINDOW(6);
 620         lp->stats.tx_carrier_errors     += inb(ioaddr + 0);
 621         lp->stats.tx_heartbeat_errors   += inb(ioaddr + 1);
 622         /* Multiple collisions. */              inb(ioaddr + 2);
 623         lp->stats.collisions                    += inb(ioaddr + 3);
 624         lp->stats.tx_window_errors              += inb(ioaddr + 4);
 625         lp->stats.rx_fifo_errors                += inb(ioaddr + 5);
 626         lp->stats.tx_packets                    += inb(ioaddr + 6);
 627         /* Rx packets   */                              inb(ioaddr + 7);
 628         /* Tx deferrals */                              inb(ioaddr + 8);
 629         inw(ioaddr + 10);       /* Total Rx and Tx octets. */
 630         inw(ioaddr + 12);
 631 
 632         /* Back to window 1, and turn statistics back on. */
 633         EL3WINDOW(1);
 634         outw(StatsEnable, ioaddr + EL3_CMD);
 635         return;
 636 }
 637 
 638 static int
 639 el3_rx(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 640 {
 641         struct el3_private *lp = (struct el3_private *)dev->priv;
 642         int ioaddr = dev->base_addr;
 643         short rx_status;
 644 
 645         if (el3_debug > 5)
 646                 printk("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
 647                            inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
 648         while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
 649                 if (rx_status & 0x4000) { /* Error, update stats. */
 650                         short error = rx_status & 0x3800;
 651                         lp->stats.rx_errors++;
 652                         switch (error) {
 653                         case 0x0000:            lp->stats.rx_over_errors++; break;
 654                         case 0x0800:            lp->stats.rx_length_errors++; break;
 655                         case 0x1000:            lp->stats.rx_frame_errors++; break;
 656                         case 0x1800:            lp->stats.rx_length_errors++; break;
 657                         case 0x2000:            lp->stats.rx_frame_errors++; break;
 658                         case 0x2800:            lp->stats.rx_crc_errors++; break;
 659                         }
 660                 } else {
 661                         short pkt_len = rx_status & 0x7ff;
 662                         struct sk_buff *skb;
 663 
 664                         skb = dev_alloc_skb(pkt_len+5);
 665                         if (el3_debug > 4)
 666                                 printk("Receiving packet size %d status %4.4x.\n",
 667                                            pkt_len, rx_status);
 668                         if (skb != NULL) {
 669                                 skb->dev = dev;
 670                                 skb_reserve(skb,2);     /* Align IP on 16 byte */
 671 
 672                                 /* 'skb->data' points to the start of sk_buff data area. */
 673                                 insl(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
 674                                                         (pkt_len + 3) >> 2);
 675 
 676                                 skb->protocol=eth_type_trans(skb,dev);
 677                                 netif_rx(skb);
 678                                 outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
 679                                 lp->stats.rx_packets++;
 680                                 continue;
 681                         } else if (el3_debug)
 682                                 printk("%s: Couldn't allocate a sk_buff of size %d.\n",
 683                                            dev->name, pkt_len);
 684                 }
 685                 lp->stats.rx_dropped++;
 686                 outw(RxDiscard, ioaddr + EL3_CMD);
 687                 while (inw(ioaddr + EL3_STATUS) & 0x1000)
 688                         printk("        Waiting for 3c509 to discard packet, status %x.\n",
 689                                    inw(ioaddr + EL3_STATUS) );
 690         }
 691 
 692         return 0;
 693 }
 694 
 695 #ifdef HAVE_MULTICAST
 696 /*
 697  *     Set or clear the multicast filter for this adaptor.
 698  */
 699 static void
 700 set_multicast_list(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 701 {
 702         short ioaddr = dev->base_addr;
 703         if (el3_debug > 1) {
 704                 static int old = 0;
 705                 if (old != dev->mc_count) {
 706                         old = dev->mc_count;
 707                         printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
 708                 }
 709         }
 710         if (dev->flags&IFF_PROMISC) {
 711                 outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
 712                          ioaddr + EL3_CMD);
 713         }
 714         else if (dev->mc_count || (dev->flags&IFF_ALLMULTI)) {
 715                 outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast, ioaddr + EL3_CMD);
 716         }
 717         else
 718                 outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
 719 }
 720 #endif
 721 
 722 static int
 723 el3_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 724 {
 725         int ioaddr = dev->base_addr;
 726 
 727         if (el3_debug > 2)
 728                 printk("%s: Shutting down ethercard.\n", dev->name);
 729 
 730         dev->tbusy = 1;
 731         dev->start = 0;
 732 
 733         /* Turn off statistics ASAP.  We update lp->stats below. */
 734         outw(StatsDisable, ioaddr + EL3_CMD);
 735 
 736         /* Disable the receiver and transmitter. */
 737         outw(RxDisable, ioaddr + EL3_CMD);
 738         outw(TxDisable, ioaddr + EL3_CMD);
 739 
 740         if (dev->if_port == 3)
 741                 /* Turn off thinnet power.  Green! */
 742                 outw(StopCoax, ioaddr + EL3_CMD);
 743         else if (dev->if_port == 0) {
 744                 /* Disable link beat and jabber, if_port may change ere next open(). */
 745                 EL3WINDOW(4);
 746                 outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
 747         }
 748 
 749         free_irq(dev->irq, dev);
 750         /* Switching back to window 0 disables the IRQ. */
 751         EL3WINDOW(0);
 752         /* But we explicitly zero the IRQ line select anyway. */
 753         outw(0x0f00, ioaddr + WN0_IRQ);
 754 
 755         update_stats(ioaddr, dev);
 756         MOD_DEC_USE_COUNT;
 757         return 0;
 758 }
 759 
 760 #ifdef MODULE
 761 static char devicename[9] = { 0, };
 762 static struct device dev_3c509 = {
 763         devicename, /* device name is inserted by linux/drivers/net/net_init.c */
 764         0, 0, 0, 0,
 765         0, 0,
 766         0, 0, 0, NULL, el3_probe };
 767 
 768 static int io  = 0;
 769 static int irq = 0;
 770 
 771 int
 772 init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 773 {
 774         dev_3c509.base_addr = io;
 775         dev_3c509.irq       = irq;
 776         if (!EISA_bus && !io) {
 777                 printk("3c509: WARNING! Module load-time probing works reliably only for EISA bus!!\n");
 778         }
 779         if (register_netdev(&dev_3c509) != 0)
 780                 return -EIO;
 781         return 0;
 782 }
 783 
 784 void
 785 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 786 {
 787         if (MOD_IN_USE)
 788                 printk("3c509: device busy, remove delayed\n");
 789         else
 790         {
 791                 unregister_netdev(&dev_3c509);
 792                 kfree_s(dev_3c509.priv,sizeof(struct el3_private));
 793                 dev_3c509.priv=NULL;
 794                 /* If we don't do this, we can't re-insmod it later. */
 795                 release_region(dev_3c509.base_addr, EL3_IO_EXTENT);
 796         }
 797 }
 798 #endif /* MODULE */
 799 
 800 /*
 801  * Local variables:
 802  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 3c509.c"
 803  *  version-control: t
 804  *  kept-new-versions: 5
 805  *  tab-width: 4
 806  * End:
 807  */

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