root/net/inet/3c509.c

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

DEFINITIONS

This source file includes following definitions.
  1. el3_probe
  2. read_eeprom
  3. el3_open
  4. el3_start_xmit
  5. el3_interrupt
  6. el3_get_stats
  7. update_stats
  8. el3_rx
  9. el3_close

   1 /* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
   2 /*
   3     Written 1993 by 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 driver is for the 3Com EtherLinkIII series.
  11 
  12     The author may be reached as becker@super.org or
  13     C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
  14 */
  15 
  16 static char *version = "3c509.c: v0.06 9/3/93 becker@super.org\n";
  17 
  18 #include <linux/config.h>
  19 #include <linux/kernel.h>
  20 #include <linux/sched.h>
  21 #include <linux/string.h>
  22 #include <linux/interrupt.h>
  23 #include <linux/ptrace.h>
  24 #include <linux/errno.h>
  25 #include <linux/in.h>
  26 
  27 #ifndef PRE_PL13
  28 #include <linux/ioport.h>
  29 #else
  30 #define snarf_region(base,extent) do {;}while(0)
  31 #define check_region(base,extent) (0)
  32 #endif
  33 
  34 /*#include <asm/system.h>*/
  35 #include <asm/io.h>
  36 #ifndef port_read
  37 #include "iow.h"
  38 #endif
  39 
  40 #include "dev.h"
  41 #include "eth.h"
  42 #include "skbuff.h"
  43 #include "arp.h"
  44 
  45 #ifndef HAVE_AUTOIRQ
  46 /* From auto_irq.c, should be in a *.h file. */
  47 extern void autoirq_setup(int waittime);
  48 extern int autoirq_report(int waittime);
  49 extern struct device *irq2dev_map[16];
  50 #endif
  51 
  52 /* These should be in <asm/io.h>. */
  53 #define port_read_l(port,buf,nr) \
  54 __asm__("cld;rep;insl": :"d" (port),"D" (buf),"c" (nr):"cx","di")
  55 #define port_write_l(port,buf,nr) \
  56 __asm__("cld;rep;outsl": :"d" (port),"S" (buf),"c" (nr):"cx","si")
  57 
  58 
  59 #ifdef EL3_DEBUG
  60 int el3_debug = EL3_DEBUG;
  61 #else
  62 int el3_debug = 2;
  63 #endif
  64 
  65 /* To minimize the size of the driver source I only define operating
  66    constants if they are used several times.  You'll need the manual
  67    if you want to understand driver details. */
  68 /* Offsets from base I/O address. */
  69 #define EL3_DATA 0x00
  70 #define EL3_CMD 0x0e
  71 #define EL3_STATUS 0x0e
  72 #define ID_PORT 0x100
  73 #define  EEPROM_READ 0x80
  74 
  75 #define EL3WINDOW(win_num) outw(0x0800+(win_num), ioaddr + EL3_CMD)
  76 
  77 
  78 /* Register window 1 offsets, used in normal operation. */
  79 #define TX_FREE 0x0C
  80 #define TX_STATUS 0x0B
  81 #define TX_FIFO 0x00
  82 #define RX_STATUS 0x08
  83 #define RX_FIFO 0x00
  84 
  85 #define WN4_MEDIA       0x0A
  86 
  87 struct el3_private {
  88     struct enet_statistics stats;
  89 };
  90 
  91 static int read_eeprom(int index);
  92 static int el3_open(struct device *dev);
  93 static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
  94 static void el3_interrupt(int reg_ptr);
  95 static void update_stats(int addr, struct device *dev);
  96 static struct enet_statistics *el3_get_stats(struct device *dev);
  97 static int el3_rx(struct device *dev);
  98 static int el3_close(struct device *dev);
  99 
 100 
 101 
 102 int el3_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104     short lrs_state = 0xff, i;
 105     short ioaddr, irq;
 106     short *phys_addr = (short *)dev->dev_addr;
 107     static int current_tag = 0;
 108 
 109     /* Send the ID sequence to the ID_PORT. */
 110     outb(0x00, ID_PORT);
 111     outb(0x00, ID_PORT);
 112     for(i = 0; i < 255; i++) {
 113         outb(lrs_state, ID_PORT);
 114         lrs_state <<= 1;
 115         lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
 116     }
 117 
 118     /* For the first probe, clear all board's tag registers. */
 119     if (current_tag == 0)
 120         outb(0xd0, ID_PORT);
 121     else                /* Otherwise kill off already-found boards. */
 122         outb(0xd8, ID_PORT);
 123 
 124     if (read_eeprom(7) != 0x6d50) {
 125         return -ENODEV;
 126     }
 127 
 128     /* Read in EEPROM data, which does contention-select.
 129        Only the lowest address board will stay "on-line".
 130        3Com got the byte order backwards. */
 131     for (i = 0; i < 3; i++) {
 132         phys_addr[i] = htons(read_eeprom(i));
 133     }
 134 
 135     {
 136         unsigned short iobase = read_eeprom(8);
 137         dev->if_port = iobase >> 14;
 138         ioaddr = 0x200 + ((iobase & 0x1f) << 4);
 139     }
 140     irq = read_eeprom(9) >> 12;
 141 
 142     /* The current Space.c structure makes it difficult to have more
 143        than one adaptor initialized.  Send me email if you have a need for
 144        multiple adaptors, and we'll work out something.  -becker@super.org */
 145     if (dev->base_addr != 0
 146         &&  dev->base_addr != (unsigned short)ioaddr) {
 147         return -ENODEV;
 148     }
 149 
 150     /* Set the adaptor tag so that the next card can be found. */
 151     outb(0xd0 + ++current_tag, ID_PORT);
 152 
 153     /* Activate the adaptor at the EEPROM location. */
 154     outb(0xff, ID_PORT);
 155 
 156     EL3WINDOW(0);
 157     if (inw(ioaddr) != 0x6d50)
 158         return -ENODEV;
 159 
 160     dev->base_addr = ioaddr;
 161     dev->irq = irq;
 162     snarf_region(dev->base_addr, 16);
 163 
 164     {
 165         char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
 166         printk("%s: 3c509 at %#3.3x  tag %d, %s port, address ",
 167                dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
 168     }
 169 
 170     /* Read in the station address. */
 171     for (i = 0; i < 6; i++)
 172         printk(" %2.2x", dev->dev_addr[i]);
 173     printk(", IRQ %d.\n", dev->irq);
 174 
 175     /* Make up a EL3-specific-data structure. */
 176     dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
 177     memset(dev->priv, 0, sizeof(struct el3_private));
 178 
 179     if (el3_debug > 0)
 180         printk(version);
 181 
 182     /* The EL3-specific entries in the device structure. */
 183     dev->open = &el3_open;
 184     dev->hard_start_xmit = &el3_start_xmit;
 185     dev->stop = &el3_close;
 186     dev->get_stats = &el3_get_stats;
 187 
 188     /* Fill in the generic field of the device structure. */
 189     for (i = 0; i < DEV_NUMBUFFS; i++)
 190         dev->buffs[i] = NULL;
 191 
 192     dev->hard_header    = eth_header;
 193     dev->add_arp        = eth_add_arp;
 194     dev->queue_xmit     = dev_queue_xmit;
 195     dev->rebuild_header = eth_rebuild_header;
 196     dev->type_trans     = eth_type_trans;
 197 
 198     dev->type           = ARPHRD_ETHER;
 199     dev->hard_header_len = ETH_HLEN;
 200     dev->mtu            = 1500; /* eth_mtu */
 201     dev->addr_len       = ETH_ALEN;
 202     for (i = 0; i < ETH_ALEN; i++) {
 203         dev->broadcast[i]=0xff;
 204     }
 205 
 206     /* New-style flags. */
 207     dev->flags          = IFF_BROADCAST;
 208     dev->family         = AF_INET;
 209     dev->pa_addr        = 0;
 210     dev->pa_brdaddr     = 0;
 211     dev->pa_mask        = 0;
 212     dev->pa_alen        = sizeof(unsigned long);
 213 
 214     return 0;
 215 }
 216 
 217 
 218 static int
 219 read_eeprom(int index)
     /* [previous][next][first][last][top][bottom][index][help] */
 220 {
 221     int timer, bit, word = 0;
 222     
 223     /* Issue read command, and pause for at least 162 us. for it to complete.
 224        Assume extra-fast 16Mhz bus. */
 225     outb(EEPROM_READ + index, ID_PORT);
 226 
 227     /* This should really be done by looking at one of the timer channels. */
 228     for (timer = 0; timer < 162*4 + 400; timer++)
 229         SLOW_DOWN_IO;
 230 
 231     for (bit = 15; bit >= 0; bit--)
 232         word = (word << 1) + (inb(ID_PORT) & 0x01);
 233         
 234     if (el3_debug > 3)
 235         printk("  3c509 EEPROM word %d %#4.4x.\n", index, word);
 236 
 237     return word;
 238 }
 239 
 240 
 241 
 242 static int
 243 el3_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 244 {
 245     int ioaddr = dev->base_addr;
 246     int i;
 247 
 248     if (request_irq(dev->irq, &el3_interrupt)) {
 249         return -EAGAIN;
 250     }
 251 
 252     EL3WINDOW(0);
 253     if (el3_debug > 3)
 254         printk("%s: Opening, IRQ %d  status@%x %4.4x.\n", dev->name,
 255                dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
 256 
 257     /* Activate board: this is probably unnecessary. */
 258     outw(0x0001, ioaddr + 4);
 259 
 260     irq2dev_map[dev->irq] = dev;
 261 
 262     /* Set the IRQ line. */
 263     outw((dev->irq << 12) | 0x0f00, ioaddr + 8);
 264 
 265     /* Set the station address in window 2 each time opened. */
 266     EL3WINDOW(2);
 267 
 268     for (i = 0; i < 6; i++)
 269         outb(dev->dev_addr[i], ioaddr + i);
 270 
 271     if (dev->if_port == 3)
 272         /* Start the thinnet transceiver. We should really wait 50ms...*/
 273         outw(0x1000, ioaddr + EL3_CMD);
 274     else if (dev->if_port == 0) {
 275         /* 10baseT interface, enabled link beat and jabber check. */
 276         EL3WINDOW(4);
 277         outw(inw(ioaddr + WN4_MEDIA) | 0x00C0, ioaddr + WN4_MEDIA);
 278     }
 279 
 280     /* Switch to register set 1 for normal use. */
 281     EL3WINDOW(1);
 282 
 283     outw(0x8005, ioaddr + EL3_CMD); /* Accept b-case and phys addr only. */
 284     outw(0xA800, ioaddr + EL3_CMD); /* Turn on statistics. */
 285     outw(0x2000, ioaddr + EL3_CMD); /* Enable the receiver. */
 286     outw(0x4800, ioaddr + EL3_CMD); /* Enable transmitter. */
 287     outw(0x78ff, ioaddr + EL3_CMD); /* Allow all status bits to be seen. */
 288     dev->interrupt = 0;
 289     dev->tbusy = 0;
 290     dev->start = 1;
 291     outw(0x7098, ioaddr + EL3_CMD); /* Set interrupt mask. */
 292 
 293     if (el3_debug > 3)
 294         printk("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
 295                dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
 296 
 297     return 0;                   /* Always succeed */
 298 }
 299 
 300 static int
 301 el3_start_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 302 {
 303     struct el3_private *lp = (struct el3_private *)dev->priv;
 304     int ioaddr = dev->base_addr;
 305 
 306     /* Transmitter timeout, serious problems. */
 307     if (dev->tbusy) {
 308         int tickssofar = jiffies - dev->trans_start;
 309         if (tickssofar < 10)
 310             return 1;
 311         printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
 312                dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS));
 313         dev->trans_start = jiffies;
 314         /* Issue TX_RESET and TX_START commands. */
 315         outw(0x5800, ioaddr + EL3_CMD); /* TX_RESET */
 316         outw(0x4800, ioaddr + EL3_CMD); /* TX_START */
 317         dev->tbusy = 0;
 318     }
 319 
 320     if (skb == NULL) {
 321         dev_tint(dev);
 322         return 0;
 323     }
 324 
 325     /* Fill in the ethernet header. */
 326     if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
 327         skb->dev = dev;
 328         arp_queue (skb);
 329         return 0;
 330     }
 331 
 332     if (skb->len <= 0)
 333         return 0;
 334 
 335     if (el3_debug > 4) {
 336         printk("%s: el3_start_xmit(lenght = %d) called, status %4.4x.\n",
 337                dev->name, skb->len, inw(ioaddr + EL3_STATUS));
 338     }
 339 
 340     if (inw(ioaddr + EL3_STATUS) & 0x0001) { /* IRQ line active, missed one. */
 341       printk("%s: Missed interrupt, status %4.4x  Tx %2.2x Rx %4.4x.\n",
 342              dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
 343              inw(ioaddr + RX_STATUS));
 344       outw(0x7800, ioaddr + EL3_CMD); /* Fake interrupt trigger. */
 345       outw(0x6899, ioaddr + EL3_CMD); /* Ack IRQ */
 346       outw(0x78ff, ioaddr + EL3_CMD); /* Allow all status bits to be seen. */
 347     }
 348 
 349     /* Avoid timer-based retransmission conflicts. */
 350     dev->tbusy=1;
 351 
 352     /* Put out the doubleword header... */
 353     outw(skb->len, ioaddr + TX_FIFO);
 354     outw(0x00, ioaddr + TX_FIFO);
 355     /* ... and the packet rounded to a doubleword. */
 356     port_write_l(ioaddr + TX_FIFO, (void *)(skb+1), (skb->len + 3) >> 2);
 357     
 358     dev->trans_start = jiffies;
 359     if (skb->free)
 360         kfree_skb (skb, FREE_WRITE);
 361     
 362     if (inw(ioaddr + TX_FREE) > 1536) {
 363         dev->tbusy=0;
 364     } else
 365         /* Interrupt us when the FIFO has room for max-sized packet. */
 366         outw(0x9000 + 1536, ioaddr + EL3_CMD);
 367 
 368     if (el3_debug > 4)
 369         printk("        Finished queueing packet, FIFO room remaining %d.\n",
 370                inw(ioaddr + TX_FREE));
 371     /* Clear the Tx status stack. */
 372     {
 373         short tx_status;
 374         int i = 4;
 375 
 376         while (--i > 0  &&  (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
 377             if (el3_debug > 5)
 378                 printk("        Tx status %4.4x.\n", tx_status);
 379             if (tx_status & 0x38) lp->stats.tx_aborted_errors++;
 380             if (tx_status & 0x30) outw(0x5800, ioaddr + EL3_CMD);
 381             if (tx_status & 0x3C) outw(0x4800, ioaddr + EL3_CMD);
 382             outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
 383         }
 384     }
 385     return 0;
 386 }
 387 
 388 /* The EL3 interrupt handler. */
 389 static void
 390 el3_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 391 {
 392     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 393     struct device *dev = (struct device *)(irq2dev_map[irq]);
 394     int ioaddr, status;
 395     int i = 0;
 396 
 397     if (dev == NULL) {
 398         printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
 399         return;
 400     }
 401 
 402     if (dev->interrupt)
 403         printk("%s: Re-entering the interrupt handler.\n", dev->name);
 404     dev->interrupt = 1;
 405 
 406     ioaddr = dev->base_addr;
 407     status = inw(ioaddr + EL3_STATUS);
 408 
 409     if (el3_debug > 4)
 410         printk("%s: interrupt, status %4.4x.\n", dev->name, status);
 411     
 412     while ((status = inw(ioaddr + EL3_STATUS)) & 0x01) {
 413 
 414         if (status & 0x10)
 415             el3_rx(dev);
 416 
 417         if (status & 0x08) {
 418             if (el3_debug > 5)
 419                 printk("    TX room bit was handled.\n");
 420             /* There's room in the FIFO for a full-sized packet. */
 421             outw(0x6808, ioaddr + EL3_CMD); /* Ack IRQ */
 422             dev->tbusy = 0;
 423             mark_bh(INET_BH);
 424         }
 425         if (status & 0x80)              /* Statistics full. */
 426             update_stats(ioaddr, dev);
 427         
 428         if (++i > 10) {
 429             printk("%s: Infinite loop in interrupt, status %4.4x.\n",
 430                    dev->name, status);
 431             break;
 432         }
 433         /* Clear the other interrupts we have handled. */
 434         outw(0x6899, ioaddr + EL3_CMD); /* Ack IRQ */
 435     }
 436 
 437     if (el3_debug > 4) {
 438         printk("%s: exiting interrupt, status %4.4x.\n", dev->name,
 439                inw(ioaddr + EL3_STATUS));
 440     }
 441     
 442     dev->interrupt = 0;
 443     return;
 444 }
 445 
 446 
 447 static struct enet_statistics *
 448 el3_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 449 {
 450     struct el3_private *lp = (struct el3_private *)dev->priv;
 451 
 452     sti();
 453     update_stats(dev->base_addr, dev);
 454     cli();
 455     return &lp->stats;
 456 }
 457 
 458 /* Update statistics.  We change to register window 6, so this
 459    should be run single-threaded if the device is active. This
 460    is expected to be a rare operation, and not worth a special
 461    window-state variable. */
 462 static void update_stats(int ioaddr, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 463 {
 464     struct el3_private *lp = (struct el3_private *)dev->priv;
 465 
 466     if (el3_debug > 5)
 467         printk("   Updating the statistics.\n");
 468     /* Turn off statistics updates while reading. */
 469     outw(0xB000, ioaddr + EL3_CMD);
 470     /* Switch to the stats window, and read everything. */
 471     EL3WINDOW(6);
 472     lp->stats.tx_carrier_errors += inb(ioaddr + 0);
 473     lp->stats.tx_heartbeat_errors       += inb(ioaddr + 1);
 474     /* Multiple collisions. */     inb(ioaddr + 2);
 475     lp->stats.collisions                += inb(ioaddr + 3);
 476     lp->stats.tx_window_errors  += inb(ioaddr + 4);
 477     lp->stats.rx_fifo_errors    += inb(ioaddr + 5);
 478     lp->stats.tx_packets                += inb(ioaddr + 6);
 479     lp->stats.rx_packets                += inb(ioaddr + 7);
 480     /* Tx deferrals */             inb(ioaddr + 8);
 481     inw(ioaddr + 10);   /* Total Rx and Tx octets. */
 482     inw(ioaddr + 12);
 483 
 484     /* Back to window 1, and turn statistics back on. */
 485     EL3WINDOW(1);
 486     outw(0xA800, ioaddr + EL3_CMD);
 487     return;
 488 }
 489 
 490 static int
 491 el3_rx(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 492 {
 493     struct el3_private *lp = (struct el3_private *)dev->priv;
 494     int ioaddr = dev->base_addr;
 495     short rx_status;
 496 
 497     if (el3_debug > 5)
 498         printk("       In rx_packet(), status %4.4x, rx_status %4.4x.\n",
 499                inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
 500     while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
 501         if (rx_status & 0x4000) { /* Error, update stats. */
 502             short error = rx_status & 0x3C00;
 503             lp->stats.rx_errors++;
 504             switch (error) {
 505             case 0x2000:        lp->stats.rx_over_errors++; break;
 506             case 0x2C00:        lp->stats.rx_length_errors++; break;
 507             case 0x3400:        lp->stats.rx_crc_errors++; break;
 508             case 0x2400:        lp->stats.rx_length_errors++; break;
 509             case 0x3000:        lp->stats.rx_frame_errors++; break;
 510             case 0x0800:        lp->stats.rx_frame_errors++; break;
 511             }
 512         }
 513         if ( (! (rx_status & 0x4000))
 514             || ! (rx_status & 0x2000)) { /* Dribble bits are OK. */
 515             short pkt_len = rx_status & 0x7ff;
 516             int sksize = sizeof(struct sk_buff) + pkt_len + 3;
 517             struct sk_buff *skb;
 518             skb = (struct sk_buff *) kmalloc(sksize, GFP_ATOMIC);
 519 
 520             if (el3_debug > 4)
 521                 printk("       Receiving packet size %d status %4.4x.\n",
 522                        pkt_len, rx_status);
 523             if (skb != NULL) {
 524                 skb->mem_len = sksize;
 525                 skb->mem_addr = skb;
 526                 skb->len = pkt_len;
 527                 skb->dev = dev;
 528 
 529                 /* 'skb+1' points to the start of sk_buff data area. */
 530                 port_read_l(ioaddr+RX_FIFO, (void *)(skb+1),
 531                             (pkt_len + 3) >> 2);
 532 
 533 #ifdef HAVE_NETIF_RX
 534                 netif_rx(skb);
 535                 outw(0x4000, ioaddr + EL3_CMD); /* Rx discard */
 536                 continue;
 537 #else
 538                 skb->lock = 0;
 539                 if (dev_rint((unsigned char *)skb, pkt_len,
 540                              IN_SKBUFF,dev)== 0){
 541                     if (el3_debug > 6)
 542                         printk("     dev_rint() happy, status %4.4x.\n",
 543                         inb(ioaddr + EL3_STATUS));
 544                     outw(0x4000, ioaddr + EL3_CMD); /* Rx discard */
 545                     while (inw(ioaddr + EL3_STATUS) & 0x1000)
 546                       printk("  Waiting for 3c509 to discard packet, status %x.\n",
 547                              inw(ioaddr + EL3_STATUS) );
 548                     if (el3_debug > 6)
 549                         printk("     discarded packet, status %4.4x.\n",
 550                         inb(ioaddr + EL3_STATUS));
 551                     continue;
 552                 } else {
 553                     printk("%s: receive buffers full.\n", dev->name);
 554                     kfree_s(skb, sksize);
 555                 }
 556 #endif
 557             } else if (el3_debug)
 558                 printk("%s: Couldn't allocate a sk_buff of size %d.\n",
 559                        dev->name, sksize);
 560         }
 561         lp->stats.rx_dropped++;
 562         outw(0x4000, ioaddr + EL3_CMD); /* Rx discard */
 563         while (inw(ioaddr + EL3_STATUS) & 0x1000)
 564           printk("  Waiting for 3c509 to discard packet, status %x.\n",
 565                  inw(ioaddr + EL3_STATUS) );
 566     }
 567 
 568     if (el3_debug > 5)
 569         printk("       Exiting rx_packet(), status %4.4x, rx_status %4.4x.\n",
 570                inw(ioaddr+EL3_STATUS), inw(ioaddr+8));
 571 
 572     return 0;
 573 }
 574 
 575 static int
 576 el3_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 577 {
 578     int ioaddr = dev->base_addr;
 579 
 580     if (el3_debug > 2)
 581         printk("%s: Shutting down ethercard.\n", dev->name);
 582 
 583     dev->tbusy = 1;
 584     dev->start = 0;
 585 
 586     /* Turn off statistics.  We update lp->stats below. */
 587     outw(0xB000, ioaddr + EL3_CMD);
 588 
 589     /* Disable the receiver and transmitter. */
 590     outw(0x1800, ioaddr + EL3_CMD);
 591     outw(0x5000, ioaddr + EL3_CMD);
 592 
 593     if (dev->if_port == 3)
 594         /* Turn off thinnet power. */
 595         outw(0xb800, ioaddr + EL3_CMD);
 596     else if (dev->if_port == 0) {
 597         /* Disable link beat and jabber, if_port may change ere next open(). */
 598         EL3WINDOW(4);
 599         outw(inw(ioaddr + WN4_MEDIA) & ~ 0x00C0, ioaddr + WN4_MEDIA);
 600     }
 601 
 602     free_irq(dev->irq);
 603     /* Switching back to window 0 disables the IRQ. */
 604     EL3WINDOW(0);
 605     /* But we explicitly zero the IRQ line select anyway. */
 606     outw(0x0f00, ioaddr + 8);
 607 
 608 
 609     irq2dev_map[dev->irq] = 0;
 610 
 611     update_stats(ioaddr, dev);
 612     return 0;
 613 }
 614 
 615 /*
 616  * Local variables:
 617  *  compile-command: "gcc -D__KERNEL__ -Wall -O6 -x c++ -c 3c509.c"
 618  * End:
 619  */

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