linux-bk/drivers/net/7990.c
<<
>>
Prefs
   1/* 
   2 * 7990.c -- LANCE ethernet IC generic routines. 
   3 * This is an attempt to separate out the bits of various ethernet
   4 * drivers that are common because they all use the AMD 7990 LANCE 
   5 * (Local Area Network Controller for Ethernet) chip.
   6 *
   7 * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
   8 *
   9 * Most of this stuff was obtained by looking at other LANCE drivers,
  10 * in particular a2065.[ch]. The AMD C-LANCE datasheet was also helpful.
  11 * NB: this was made easy by the fact that Jes Sorensen had cleaned up
  12 * most of a2025 and sunlance with the aim of merging them, so the 
  13 * common code was pretty obvious.
  14 */
  15#include <linux/crc32.h>
  16#include <linux/delay.h>
  17#include <linux/dio.h>
  18#include <linux/errno.h>
  19#include <linux/netdevice.h>
  20#include <linux/etherdevice.h>
  21#include <linux/init.h>
  22#include <linux/module.h>
  23#include <linux/kernel.h>
  24#include <linux/types.h>
  25#include <linux/fcntl.h>
  26#include <linux/interrupt.h>
  27#include <linux/ioport.h>
  28#include <linux/in.h>
  29#include <linux/route.h>
  30#include <linux/slab.h>
  31#include <linux/string.h>
  32#include <linux/skbuff.h>
  33/* Used for the temporal inet entries and routing */
  34#include <linux/socket.h>
  35
  36#include <asm/system.h>
  37#include <asm/bitops.h>
  38#include <asm/io.h>
  39#include <asm/dma.h>
  40#include <asm/pgtable.h>
  41
  42#include "7990.h"
  43
  44/* Lossage Factor Nine, Mr Sulu. */
  45#define WRITERAP(x) (lp->writerap(lp,x))
  46#define WRITERDP(x) (lp->writerdp(lp,x))
  47#define READRDP() (lp->readrdp(lp))
  48/* These used to be ll->rap = x, ll->rdp = x, and (ll->rdp). Sigh. 
  49 * If you want to switch them back then 
  50 * #define DECLARE_LL volatile struct lance_regs *ll = lp->ll
  51 */
  52#define DECLARE_LL /* nothing to declare */
  53
  54/* debugging output macros, various flavours */
  55/* #define TEST_HITS */
  56#ifdef UNDEF
  57#define PRINT_RINGS() \
  58do { \
  59        int t; \
  60        for (t=0; t < RX_RING_SIZE; t++) { \
  61                printk("R%d: @(%02X %04X) len %04X, mblen %04X, bits %02X\n",\
  62                       t, ib->brx_ring[t].rmd1_hadr, ib->brx_ring[t].rmd0,\
  63                       ib->brx_ring[t].length,\
  64                       ib->brx_ring[t].mblength, ib->brx_ring[t].rmd1_bits);\
  65        }\
  66        for (t=0; t < TX_RING_SIZE; t++) { \
  67                printk("T%d: @(%02X %04X) len %04X, misc %04X, bits %02X\n",\
  68                       t, ib->btx_ring[t].tmd1_hadr, ib->btx_ring[t].tmd0,\
  69                       ib->btx_ring[t].length,\
  70                       ib->btx_ring[t].misc, ib->btx_ring[t].tmd1_bits);\
  71        }\
  72} while (0) 
  73#else
  74#define PRINT_RINGS()
  75#endif        
  76
  77/* Load the CSR registers. The LANCE has to be STOPped when we do this! */
  78static void load_csrs (struct lance_private *lp)
  79{
  80        volatile struct lance_init_block *aib = lp->lance_init_block;
  81        int leptr;
  82        DECLARE_LL;
  83
  84        leptr = LANCE_ADDR (aib);
  85
  86        WRITERAP(LE_CSR1);                        /* load address of init block */
  87        WRITERDP(leptr & 0xFFFF);
  88        WRITERAP(LE_CSR2);
  89        WRITERDP(leptr >> 16);
  90        WRITERAP(LE_CSR3);
  91        WRITERDP(lp->busmaster_regval);           /* set byteswap/ALEctrl/byte ctrl */
  92
  93        /* Point back to csr0 */
  94        WRITERAP(LE_CSR0);
  95}
  96
  97/* #define to 0 or 1 appropriately */
  98#define DEBUG_IRING 0
  99/* Set up the Lance Rx and Tx rings and the init block */
 100static void lance_init_ring (struct net_device *dev)
 101{
 102        struct lance_private *lp = (struct lance_private *) dev->priv;
 103        volatile struct lance_init_block *ib = lp->init_block;
 104        volatile struct lance_init_block *aib; /* for LANCE_ADDR computations */
 105        int leptr;
 106        int i;
 107
 108        aib = lp->lance_init_block;
 109
 110        lp->rx_new = lp->tx_new = 0;
 111        lp->rx_old = lp->tx_old = 0;
 112
 113        ib->mode = LE_MO_PROM;                             /* normal, enable Tx & Rx */
 114
 115        /* Copy the ethernet address to the lance init block
 116         * Notice that we do a byteswap if we're big endian.
 117         * [I think this is the right criterion; at least, sunlance,
 118         * a2065 and atarilance do the byteswap and lance.c (PC) doesn't.
 119         * However, the datasheet says that the BSWAP bit doesn't affect
 120         * the init block, so surely it should be low byte first for
 121         * everybody? Um.] 
 122         * We could define the ib->physaddr as three 16bit values and
 123         * use (addr[1] << 8) | addr[0] & co, but this is more efficient.
 124         */
 125#ifdef __BIG_ENDIAN
 126        ib->phys_addr [0] = dev->dev_addr [1];
 127        ib->phys_addr [1] = dev->dev_addr [0];
 128        ib->phys_addr [2] = dev->dev_addr [3];
 129        ib->phys_addr [3] = dev->dev_addr [2];
 130        ib->phys_addr [4] = dev->dev_addr [5];
 131        ib->phys_addr [5] = dev->dev_addr [4];
 132#else
 133        for (i=0; i<6; i++)
 134           ib->phys_addr[i] = dev->dev_addr[i];
 135#endif        
 136
 137        if (DEBUG_IRING)
 138                printk ("TX rings:\n");
 139    
 140        lp->tx_full = 0;
 141        /* Setup the Tx ring entries */
 142        for (i = 0; i < (1<<lp->lance_log_tx_bufs); i++) {
 143                leptr = LANCE_ADDR(&aib->tx_buf[i][0]);
 144                ib->btx_ring [i].tmd0      = leptr;
 145                ib->btx_ring [i].tmd1_hadr = leptr >> 16;
 146                ib->btx_ring [i].tmd1_bits = 0;
 147                ib->btx_ring [i].length    = 0xf000; /* The ones required by tmd2 */
 148                ib->btx_ring [i].misc      = 0;
 149                if (DEBUG_IRING) 
 150                   printk ("%d: 0x%8.8x\n", i, leptr);
 151        }
 152
 153        /* Setup the Rx ring entries */
 154        if (DEBUG_IRING)
 155                printk ("RX rings:\n");
 156        for (i = 0; i < (1<<lp->lance_log_rx_bufs); i++) {
 157                leptr = LANCE_ADDR(&aib->rx_buf[i][0]);
 158
 159                ib->brx_ring [i].rmd0      = leptr;
 160                ib->brx_ring [i].rmd1_hadr = leptr >> 16;
 161                ib->brx_ring [i].rmd1_bits = LE_R1_OWN;
 162                /* 0xf000 == bits that must be one (reserved, presumably) */
 163                ib->brx_ring [i].length    = -RX_BUFF_SIZE | 0xf000;
 164                ib->brx_ring [i].mblength  = 0;
 165                if (DEBUG_IRING)
 166                        printk ("%d: 0x%8.8x\n", i, leptr);
 167        }
 168
 169        /* Setup the initialization block */
 170    
 171        /* Setup rx descriptor pointer */
 172        leptr = LANCE_ADDR(&aib->brx_ring);
 173        ib->rx_len = (lp->lance_log_rx_bufs << 13) | (leptr >> 16);
 174        ib->rx_ptr = leptr;
 175        if (DEBUG_IRING)
 176                printk ("RX ptr: %8.8x\n", leptr);
 177    
 178        /* Setup tx descriptor pointer */
 179        leptr = LANCE_ADDR(&aib->btx_ring);
 180        ib->tx_len = (lp->lance_log_tx_bufs << 13) | (leptr >> 16);
 181        ib->tx_ptr = leptr;
 182        if (DEBUG_IRING)
 183                printk ("TX ptr: %8.8x\n", leptr);
 184
 185        /* Clear the multicast filter */
 186        ib->filter [0] = 0;
 187        ib->filter [1] = 0;
 188        PRINT_RINGS();
 189}
 190
 191/* LANCE must be STOPped before we do this, too... */
 192static int init_restart_lance (struct lance_private *lp)
 193{
 194        int i;
 195        DECLARE_LL;
 196
 197        WRITERAP(LE_CSR0);
 198        WRITERDP(LE_C0_INIT);
 199
 200        /* Need a hook here for sunlance ledma stuff */
 201
 202        /* Wait for the lance to complete initialization */
 203        for (i = 0; (i < 100) && !(READRDP() & (LE_C0_ERR | LE_C0_IDON)); i++)
 204                barrier();
 205        if ((i == 100) || (READRDP() & LE_C0_ERR)) {
 206                printk ("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, READRDP());
 207                return -1;
 208        }
 209
 210        /* Clear IDON by writing a "1", enable interrupts and start lance */
 211        WRITERDP(LE_C0_IDON);
 212        WRITERDP(LE_C0_INEA | LE_C0_STRT);
 213
 214        return 0;
 215}
 216
 217static int lance_reset (struct net_device *dev)
 218{
 219        struct lance_private *lp = (struct lance_private *)dev->priv;
 220        int status;
 221        DECLARE_LL;
 222    
 223        /* Stop the lance */
 224        WRITERAP(LE_CSR0);
 225        WRITERDP(LE_C0_STOP);
 226
 227        load_csrs (lp);
 228        lance_init_ring (dev);
 229        dev->trans_start = jiffies;
 230        status = init_restart_lance (lp);
 231#ifdef DEBUG_DRIVER
 232        printk ("Lance restart=%d\n", status);
 233#endif
 234        return status;
 235}
 236
 237static int lance_rx (struct net_device *dev)
 238{
 239        struct lance_private *lp = (struct lance_private *) dev->priv;
 240        volatile struct lance_init_block *ib = lp->init_block;
 241        volatile struct lance_rx_desc *rd;
 242        unsigned char bits;
 243        int len = 0;                    /* XXX shut up gcc warnings */
 244        struct sk_buff *skb = 0;        /* XXX shut up gcc warnings */
 245#ifdef TEST_HITS
 246        int i;
 247#endif
 248        DECLARE_LL;
 249
 250#ifdef TEST_HITS
 251        printk ("[");
 252        for (i = 0; i < RX_RING_SIZE; i++) {
 253                if (i == lp->rx_new)
 254                        printk ("%s",
 255                                ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "_" : "X");
 256                else
 257                        printk ("%s",
 258                                ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "." : "1");
 259        }
 260        printk ("]");
 261#endif
 262    
 263        WRITERDP(LE_C0_RINT | LE_C0_INEA);     /* ack Rx int, reenable ints */
 264        for (rd = &ib->brx_ring [lp->rx_new];     /* For each Rx ring we own... */
 265             !((bits = rd->rmd1_bits) & LE_R1_OWN);
 266             rd = &ib->brx_ring [lp->rx_new]) {
 267
 268                /* We got an incomplete frame? */
 269                if ((bits & LE_R1_POK) != LE_R1_POK) {
 270                        lp->stats.rx_over_errors++;
 271                        lp->stats.rx_errors++;
 272                        continue;
 273                } else if (bits & LE_R1_ERR) {
 274                        /* Count only the end frame as a rx error,
 275                         * not the beginning
 276                         */
 277                        if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++;
 278                        if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++;
 279                        if (bits & LE_R1_OFL) lp->stats.rx_over_errors++;
 280                        if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++;
 281                        if (bits & LE_R1_EOP) lp->stats.rx_errors++;
 282                } else {
 283                        len = (rd->mblength & 0xfff) - 4;
 284                        skb = dev_alloc_skb (len+2);
 285
 286                        if (skb == 0) {
 287                                printk ("%s: Memory squeeze, deferring packet.\n",
 288                                        dev->name);
 289                                lp->stats.rx_dropped++;
 290                                rd->mblength = 0;
 291                                rd->rmd1_bits = LE_R1_OWN;
 292                                lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
 293                                return 0;
 294                        }
 295            
 296                        skb->dev = dev;
 297                        skb_reserve (skb, 2);           /* 16 byte align */
 298                        skb_put (skb, len);             /* make room */
 299                        eth_copy_and_sum(skb,
 300                                         (unsigned char *)&(ib->rx_buf [lp->rx_new][0]),
 301                                         len, 0);
 302                        skb->protocol = eth_type_trans (skb, dev);
 303                        netif_rx (skb);
 304                        dev->last_rx = jiffies;
 305                        lp->stats.rx_packets++;
 306                        lp->stats.rx_bytes += len;
 307                }
 308
 309                /* Return the packet to the pool */
 310                rd->mblength = 0;
 311                rd->rmd1_bits = LE_R1_OWN;
 312                lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
 313        }
 314        return 0;
 315}
 316
 317static int lance_tx (struct net_device *dev)
 318{
 319        struct lance_private *lp = (struct lance_private *) dev->priv;
 320        volatile struct lance_init_block *ib = lp->init_block;
 321        volatile struct lance_tx_desc *td;
 322        int i, j;
 323        int status;
 324        DECLARE_LL;
 325
 326        /* csr0 is 2f3 */
 327        WRITERDP(LE_C0_TINT | LE_C0_INEA);
 328        /* csr0 is 73 */
 329
 330        j = lp->tx_old;
 331        for (i = j; i != lp->tx_new; i = j) {
 332                td = &ib->btx_ring [i];
 333
 334                /* If we hit a packet not owned by us, stop */
 335                if (td->tmd1_bits & LE_T1_OWN)
 336                        break;
 337                
 338                if (td->tmd1_bits & LE_T1_ERR) {
 339                        status = td->misc;
 340            
 341                        lp->stats.tx_errors++;
 342                        if (status & LE_T3_RTY)  lp->stats.tx_aborted_errors++;
 343                        if (status & LE_T3_LCOL) lp->stats.tx_window_errors++;
 344
 345                        if (status & LE_T3_CLOS) {
 346                                lp->stats.tx_carrier_errors++;
 347                                if (lp->auto_select) {
 348                                        lp->tpe = 1 - lp->tpe;
 349                                        printk("%s: Carrier Lost, trying %s\n",
 350                                               dev->name, lp->tpe?"TPE":"AUI");
 351                                        /* Stop the lance */
 352                                        WRITERAP(LE_CSR0);
 353                                        WRITERDP(LE_C0_STOP);
 354                                        lance_init_ring (dev);
 355                                        load_csrs (lp);
 356                                        init_restart_lance (lp);
 357                                        return 0;
 358                                }
 359                        }
 360
 361                        /* buffer errors and underflows turn off the transmitter */
 362                        /* Restart the adapter */
 363                        if (status & (LE_T3_BUF|LE_T3_UFL)) {
 364                                lp->stats.tx_fifo_errors++;
 365
 366                                printk ("%s: Tx: ERR_BUF|ERR_UFL, restarting\n",
 367                                        dev->name);
 368                                /* Stop the lance */
 369                                WRITERAP(LE_CSR0);
 370                                WRITERDP(LE_C0_STOP);
 371                                lance_init_ring (dev);
 372                                load_csrs (lp);
 373                                init_restart_lance (lp);
 374                                return 0;
 375                        }
 376                } else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {
 377                        /*
 378                         * So we don't count the packet more than once.
 379                         */
 380                        td->tmd1_bits &= ~(LE_T1_POK);
 381
 382                        /* One collision before packet was sent. */
 383                        if (td->tmd1_bits & LE_T1_EONE)
 384                                lp->stats.collisions++;
 385
 386                        /* More than one collision, be optimistic. */
 387                        if (td->tmd1_bits & LE_T1_EMORE)
 388                                lp->stats.collisions += 2;
 389
 390                        lp->stats.tx_packets++;
 391                }
 392        
 393                j = (j + 1) & lp->tx_ring_mod_mask;
 394        }
 395        lp->tx_old = j;
 396        WRITERDP(LE_C0_TINT | LE_C0_INEA);
 397        return 0;
 398}
 399
 400static irqreturn_t
 401lance_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 402{
 403        struct net_device *dev = (struct net_device *)dev_id;
 404        struct lance_private *lp = (struct lance_private *)dev->priv;
 405        int csr0;
 406        DECLARE_LL;
 407
 408        spin_lock (&lp->devlock);
 409
 410        WRITERAP(LE_CSR0);              /* LANCE Controller Status */
 411        csr0 = READRDP();
 412
 413        PRINT_RINGS();
 414        
 415        if (!(csr0 & LE_C0_INTR)) {     /* Check if any interrupt has */
 416                spin_lock (&lp->devlock);
 417                return IRQ_NONE;        /* been generated by the Lance. */
 418        }
 419
 420        /* Acknowledge all the interrupt sources ASAP */
 421        WRITERDP(csr0 & ~(LE_C0_INEA|LE_C0_TDMD|LE_C0_STOP|LE_C0_STRT|LE_C0_INIT));
 422
 423        if ((csr0 & LE_C0_ERR)) {
 424                /* Clear the error condition */
 425                WRITERDP(LE_C0_BABL|LE_C0_ERR|LE_C0_MISS|LE_C0_INEA);
 426        }
 427
 428        if (csr0 & LE_C0_RINT)
 429                lance_rx (dev);
 430
 431        if (csr0 & LE_C0_TINT)
 432                lance_tx (dev);
 433
 434        /* Log misc errors. */
 435        if (csr0 & LE_C0_BABL)
 436                lp->stats.tx_errors++;       /* Tx babble. */
 437        if (csr0 & LE_C0_MISS)
 438                lp->stats.rx_errors++;       /* Missed a Rx frame. */
 439        if (csr0 & LE_C0_MERR) {
 440                printk("%s: Bus master arbitration failure, status %4.4x.\n", 
 441                       dev->name, csr0);
 442                /* Restart the chip. */
 443                WRITERDP(LE_C0_STRT);
 444        }
 445
 446        if (lp->tx_full && netif_queue_stopped(dev) && (TX_BUFFS_AVAIL >= 0)) {
 447                lp->tx_full = 0;
 448                netif_wake_queue (dev);
 449        }
 450        
 451        WRITERAP(LE_CSR0);
 452        WRITERDP(LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_MERR|LE_C0_IDON|LE_C0_INEA);
 453
 454        spin_unlock (&lp->devlock);
 455        return IRQ_HANDLED;
 456}
 457
 458int lance_open (struct net_device *dev)
 459{
 460        struct lance_private *lp = (struct lance_private *)dev->priv;
 461        int res;
 462        DECLARE_LL;
 463        
 464        /* Install the Interrupt handler. Or we could shunt this out to specific drivers? */
 465        if (request_irq(lp->irq, lance_interrupt, 0, lp->name, dev))
 466                return -EAGAIN;
 467
 468        res = lance_reset(dev);
 469        lp->devlock = SPIN_LOCK_UNLOCKED;
 470        netif_start_queue (dev);
 471
 472        return res;
 473}
 474
 475int lance_close (struct net_device *dev)
 476{
 477        struct lance_private *lp = (struct lance_private *) dev->priv;
 478        DECLARE_LL;
 479        
 480        netif_stop_queue (dev);
 481
 482        /* Stop the LANCE */
 483        WRITERAP(LE_CSR0);
 484        WRITERDP(LE_C0_STOP);
 485
 486        free_irq(lp->irq, dev);
 487
 488        return 0;
 489}
 490
 491void lance_tx_timeout(struct net_device *dev)
 492{
 493        printk("lance_tx_timeout\n");
 494        lance_reset(dev);
 495        dev->trans_start = jiffies;
 496        netif_wake_queue (dev);
 497}
 498
 499
 500int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
 501{
 502        struct lance_private *lp = (struct lance_private *)dev->priv;
 503        volatile struct lance_init_block *ib = lp->init_block;
 504        int entry, skblen, len;
 505        static int outs;
 506        unsigned long flags;
 507        DECLARE_LL;
 508
 509        if (!TX_BUFFS_AVAIL)
 510                return -1;
 511
 512        netif_stop_queue (dev);
 513
 514        skblen = skb->len;
 515
 516#ifdef DEBUG_DRIVER
 517        /* dump the packet */
 518        {
 519                int i;
 520        
 521                for (i = 0; i < 64; i++) {
 522                        if ((i % 16) == 0)
 523                                printk ("\n");
 524                        printk ("%2.2x ", skb->data [i]);
 525                }
 526        }
 527#endif
 528        len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
 529        entry = lp->tx_new & lp->tx_ring_mod_mask;
 530        ib->btx_ring [entry].length = (-len) | 0xf000;
 531        ib->btx_ring [entry].misc = 0;
 532    
 533        if (skb->len < ETH_ZLEN)
 534                memset((char *)&ib->tx_buf[entry][0], 0, ETH_ZLEN);
 535        memcpy ((char *)&ib->tx_buf [entry][0], skb->data, skblen);
 536    
 537        /* Now, give the packet to the lance */
 538        ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
 539        lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask;
 540
 541        outs++;
 542        /* Kick the lance: transmit now */
 543        WRITERDP(LE_C0_INEA | LE_C0_TDMD);
 544        dev->trans_start = jiffies;
 545        dev_kfree_skb (skb);
 546    
 547        spin_lock_irqsave (&lp->devlock, flags);
 548        if (TX_BUFFS_AVAIL)
 549                netif_start_queue (dev);
 550        else
 551                lp->tx_full = 1;
 552        spin_unlock_irqrestore (&lp->devlock, flags);
 553
 554        return 0;
 555}
 556
 557struct net_device_stats *lance_get_stats (struct net_device *dev)
 558{
 559        struct lance_private *lp = (struct lance_private *) dev->priv;
 560
 561        return &lp->stats;
 562}
 563
 564/* taken from the depca driver via a2065.c */
 565static void lance_load_multicast (struct net_device *dev)
 566{
 567        struct lance_private *lp = (struct lance_private *) dev->priv;
 568        volatile struct lance_init_block *ib = lp->init_block;
 569        volatile u16 *mcast_table = (u16 *)&ib->filter;
 570        struct dev_mc_list *dmi=dev->mc_list;
 571        char *addrs;
 572        int i;
 573        u32 crc;
 574        
 575        /* set all multicast bits */
 576        if (dev->flags & IFF_ALLMULTI){ 
 577                ib->filter [0] = 0xffffffff;
 578                ib->filter [1] = 0xffffffff;
 579                return;
 580        }
 581        /* clear the multicast filter */
 582        ib->filter [0] = 0;
 583        ib->filter [1] = 0;
 584
 585        /* Add addresses */
 586        for (i = 0; i < dev->mc_count; i++){
 587                addrs = dmi->dmi_addr;
 588                dmi   = dmi->next;
 589
 590                /* multicast address? */
 591                if (!(*addrs & 1))
 592                        continue;
 593                
 594                crc = ether_crc_le(6, addrs);
 595                crc = crc >> 26;
 596                mcast_table [crc >> 4] |= 1 << (crc & 0xf);
 597        }
 598        return;
 599}
 600
 601
 602void lance_set_multicast (struct net_device *dev)
 603{
 604        struct lance_private *lp = (struct lance_private *) dev->priv;
 605        volatile struct lance_init_block *ib = lp->init_block;
 606        int stopped;
 607        DECLARE_LL;
 608
 609        stopped = netif_queue_stopped(dev);
 610        if (!stopped)
 611                netif_stop_queue (dev);
 612
 613        while (lp->tx_old != lp->tx_new)
 614                schedule();
 615
 616        WRITERAP(LE_CSR0);
 617        WRITERDP(LE_C0_STOP);
 618        lance_init_ring (dev);
 619
 620        if (dev->flags & IFF_PROMISC) {
 621                ib->mode |= LE_MO_PROM;
 622        } else {
 623                ib->mode &= ~LE_MO_PROM;
 624                lance_load_multicast (dev);
 625        }
 626        load_csrs (lp);
 627        init_restart_lance (lp);
 628
 629        if (!stopped)
 630                netif_start_queue (dev);
 631}
 632
 633MODULE_LICENSE("GPL");
 634
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.