linux/drivers/net/ethernet/amd/am79c961a.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/net/ethernet/amd/am79c961a.c
   3 *
   4 *  by Russell King <rmk@arm.linux.org.uk> 1995-2001.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * Derived from various things including skeleton.c
  11 *
  12 * This is a special driver for the am79c961A Lance chip used in the
  13 * Intel (formally Digital Equipment Corp) EBSA110 platform.  Please
  14 * note that this can not be built as a module (it doesn't make sense).
  15 */
  16#include <linux/kernel.h>
  17#include <linux/types.h>
  18#include <linux/interrupt.h>
  19#include <linux/ioport.h>
  20#include <linux/slab.h>
  21#include <linux/string.h>
  22#include <linux/errno.h>
  23#include <linux/netdevice.h>
  24#include <linux/etherdevice.h>
  25#include <linux/delay.h>
  26#include <linux/init.h>
  27#include <linux/crc32.h>
  28#include <linux/bitops.h>
  29#include <linux/platform_device.h>
  30#include <linux/io.h>
  31
  32#include <mach/hardware.h>
  33
  34#define TX_BUFFERS 15
  35#define RX_BUFFERS 25
  36
  37#include "am79c961a.h"
  38
  39static irqreturn_t
  40am79c961_interrupt (int irq, void *dev_id);
  41
  42static unsigned int net_debug = NET_DEBUG;
  43
  44static const char version[] =
  45        "am79c961 ethernet driver (C) 1995-2001 Russell King v0.04\n";
  46
  47/* --------------------------------------------------------------------------- */
  48
  49#ifdef __arm__
  50static void write_rreg(u_long base, u_int reg, u_int val)
  51{
  52        asm volatile(
  53        "str%?h %1, [%2]        @ NET_RAP\n\t"
  54        "str%?h %0, [%2, #-4]   @ NET_RDP"
  55        :
  56        : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
  57}
  58
  59static inline unsigned short read_rreg(u_long base_addr, u_int reg)
  60{
  61        unsigned short v;
  62        asm volatile(
  63        "str%?h %1, [%2]        @ NET_RAP\n\t"
  64        "ldr%?h %0, [%2, #-4]   @ NET_RDP"
  65        : "=r" (v)
  66        : "r" (reg), "r" (ISAIO_BASE + 0x0464));
  67        return v;
  68}
  69
  70static inline void write_ireg(u_long base, u_int reg, u_int val)
  71{
  72        asm volatile(
  73        "str%?h %1, [%2]        @ NET_RAP\n\t"
  74        "str%?h %0, [%2, #8]    @ NET_IDP"
  75        :
  76        : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
  77}
  78
  79static inline unsigned short read_ireg(u_long base_addr, u_int reg)
  80{
  81        u_short v;
  82        asm volatile(
  83        "str%?h %1, [%2]        @ NAT_RAP\n\t"
  84        "ldr%?h %0, [%2, #8]    @ NET_IDP\n\t"
  85        : "=r" (v)
  86        : "r" (reg), "r" (ISAIO_BASE + 0x0464));
  87        return v;
  88}
  89
  90#define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
  91#define am_readword(dev,off)      __raw_readw(ISAMEM_BASE + ((off) << 1))
  92
  93static void
  94am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
  95{
  96        offset = ISAMEM_BASE + (offset << 1);
  97        length = (length + 1) & ~1;
  98        if ((int)buf & 2) {
  99                asm volatile("str%?h    %2, [%0], #4"
 100                 : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
 101                buf += 2;
 102                length -= 2;
 103        }
 104        while (length > 8) {
 105                register unsigned int tmp asm("r2"), tmp2 asm("r3");
 106                asm volatile(
 107                        "ldm%?ia        %0!, {%1, %2}"
 108                        : "+r" (buf), "=&r" (tmp), "=&r" (tmp2));
 109                length -= 8;
 110                asm volatile(
 111                        "str%?h %1, [%0], #4\n\t"
 112                        "mov%?  %1, %1, lsr #16\n\t"
 113                        "str%?h %1, [%0], #4\n\t"
 114                        "str%?h %2, [%0], #4\n\t"
 115                        "mov%?  %2, %2, lsr #16\n\t"
 116                        "str%?h %2, [%0], #4"
 117                : "+r" (offset), "=&r" (tmp), "=&r" (tmp2));
 118        }
 119        while (length > 0) {
 120                asm volatile("str%?h    %2, [%0], #4"
 121                 : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
 122                buf += 2;
 123                length -= 2;
 124        }
 125}
 126
 127static void
 128am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
 129{
 130        offset = ISAMEM_BASE + (offset << 1);
 131        length = (length + 1) & ~1;
 132        if ((int)buf & 2) {
 133                unsigned int tmp;
 134                asm volatile(
 135                        "ldr%?h %2, [%0], #4\n\t"
 136                        "str%?b %2, [%1], #1\n\t"
 137                        "mov%?  %2, %2, lsr #8\n\t"
 138                        "str%?b %2, [%1], #1"
 139                : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
 140                length -= 2;
 141        }
 142        while (length > 8) {
 143                register unsigned int tmp asm("r2"), tmp2 asm("r3"), tmp3;
 144                asm volatile(
 145                        "ldr%?h %2, [%0], #4\n\t"
 146                        "ldr%?h %4, [%0], #4\n\t"
 147                        "ldr%?h %3, [%0], #4\n\t"
 148                        "orr%?  %2, %2, %4, lsl #16\n\t"
 149                        "ldr%?h %4, [%0], #4\n\t"
 150                        "orr%?  %3, %3, %4, lsl #16\n\t"
 151                        "stm%?ia        %1!, {%2, %3}"
 152                : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
 153                : "0" (offset), "1" (buf));
 154                length -= 8;
 155        }
 156        while (length > 0) {
 157                unsigned int tmp;
 158                asm volatile(
 159                        "ldr%?h %2, [%0], #4\n\t"
 160                        "str%?b %2, [%1], #1\n\t"
 161                        "mov%?  %2, %2, lsr #8\n\t"
 162                        "str%?b %2, [%1], #1"
 163                : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
 164                length -= 2;
 165        }
 166}
 167#else
 168#error Not compatible
 169#endif
 170
 171static int
 172am79c961_ramtest(struct net_device *dev, unsigned int val)
 173{
 174        unsigned char *buffer = kmalloc (65536, GFP_KERNEL);
 175        int i, error = 0, errorcount = 0;
 176
 177        if (!buffer)
 178                return 0;
 179        memset (buffer, val, 65536);
 180        am_writebuffer(dev, 0, buffer, 65536);
 181        memset (buffer, val ^ 255, 65536);
 182        am_readbuffer(dev, 0, buffer, 65536);
 183        for (i = 0; i < 65536; i++) {
 184                if (buffer[i] != val && !error) {
 185                        printk ("%s: buffer error (%02X %02X) %05X - ", dev->name, val, buffer[i], i);
 186                        error = 1;
 187                        errorcount ++;
 188                } else if (error && buffer[i] == val) {
 189                        printk ("%05X\n", i);
 190                        error = 0;
 191                }
 192        }
 193        if (error)
 194                printk ("10000\n");
 195        kfree (buffer);
 196        return errorcount;
 197}
 198
 199static void am79c961_mc_hash(char *addr, u16 *hash)
 200{
 201        int idx, bit;
 202        u32 crc;
 203
 204        crc = ether_crc_le(ETH_ALEN, addr);
 205
 206        idx = crc >> 30;
 207        bit = (crc >> 26) & 15;
 208
 209        hash[idx] |= 1 << bit;
 210}
 211
 212static unsigned int am79c961_get_rx_mode(struct net_device *dev, u16 *hash)
 213{
 214        unsigned int mode = MODE_PORT_10BT;
 215
 216        if (dev->flags & IFF_PROMISC) {
 217                mode |= MODE_PROMISC;
 218                memset(hash, 0xff, 4 * sizeof(*hash));
 219        } else if (dev->flags & IFF_ALLMULTI) {
 220                memset(hash, 0xff, 4 * sizeof(*hash));
 221        } else {
 222                struct netdev_hw_addr *ha;
 223
 224                memset(hash, 0, 4 * sizeof(*hash));
 225
 226                netdev_for_each_mc_addr(ha, dev)
 227                        am79c961_mc_hash(ha->addr, hash);
 228        }
 229
 230        return mode;
 231}
 232
 233static void
 234am79c961_init_for_open(struct net_device *dev)
 235{
 236        struct dev_priv *priv = netdev_priv(dev);
 237        unsigned long flags;
 238        unsigned char *p;
 239        u_int hdr_addr, first_free_addr;
 240        u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
 241        int i;
 242
 243        /*
 244         * Stop the chip.
 245         */
 246        spin_lock_irqsave(&priv->chip_lock, flags);
 247        write_rreg (dev->base_addr, CSR0, CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|CSR0_TINT|CSR0_RINT|CSR0_STOP);
 248        spin_unlock_irqrestore(&priv->chip_lock, flags);
 249
 250        write_ireg (dev->base_addr, 5, 0x00a0); /* Receive address LED */
 251        write_ireg (dev->base_addr, 6, 0x0081); /* Collision LED */
 252        write_ireg (dev->base_addr, 7, 0x0090); /* XMIT LED */
 253        write_ireg (dev->base_addr, 2, 0x0000); /* MODE register selects media */
 254
 255        for (i = LADRL; i <= LADRH; i++)
 256                write_rreg (dev->base_addr, i, multi_hash[i - LADRL]);
 257
 258        for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2)
 259                write_rreg (dev->base_addr, i, p[0] | (p[1] << 8));
 260
 261        write_rreg (dev->base_addr, MODE, mode);
 262        write_rreg (dev->base_addr, POLLINT, 0);
 263        write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS);
 264        write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS);
 265
 266        first_free_addr = RX_BUFFERS * 8 + TX_BUFFERS * 8 + 16;
 267        hdr_addr = 0;
 268
 269        priv->rxhead = 0;
 270        priv->rxtail = 0;
 271        priv->rxhdr = hdr_addr;
 272
 273        for (i = 0; i < RX_BUFFERS; i++) {
 274                priv->rxbuffer[i] = first_free_addr;
 275                am_writeword (dev, hdr_addr, first_free_addr);
 276                am_writeword (dev, hdr_addr + 2, RMD_OWN);
 277                am_writeword (dev, hdr_addr + 4, (-1600));
 278                am_writeword (dev, hdr_addr + 6, 0);
 279                first_free_addr += 1600;
 280                hdr_addr += 8;
 281        }
 282        priv->txhead = 0;
 283        priv->txtail = 0;
 284        priv->txhdr = hdr_addr;
 285        for (i = 0; i < TX_BUFFERS; i++) {
 286                priv->txbuffer[i] = first_free_addr;
 287                am_writeword (dev, hdr_addr, first_free_addr);
 288                am_writeword (dev, hdr_addr + 2, TMD_STP|TMD_ENP);
 289                am_writeword (dev, hdr_addr + 4, 0xf000);
 290                am_writeword (dev, hdr_addr + 6, 0);
 291                first_free_addr += 1600;
 292                hdr_addr += 8;
 293        }
 294
 295        write_rreg (dev->base_addr, BASERXL, priv->rxhdr);
 296        write_rreg (dev->base_addr, BASERXH, 0);
 297        write_rreg (dev->base_addr, BASETXL, priv->txhdr);
 298        write_rreg (dev->base_addr, BASERXH, 0);
 299        write_rreg (dev->base_addr, CSR0, CSR0_STOP);
 300        write_rreg (dev->base_addr, CSR3, CSR3_IDONM|CSR3_BABLM|CSR3_DXSUFLO);
 301        write_rreg (dev->base_addr, CSR4, CSR4_APAD_XMIT|CSR4_MFCOM|CSR4_RCVCCOM|CSR4_TXSTRTM|CSR4_JABM);
 302        write_rreg (dev->base_addr, CSR0, CSR0_IENA|CSR0_STRT);
 303}
 304
 305static void am79c961_timer(unsigned long data)
 306{
 307        struct net_device *dev = (struct net_device *)data;
 308        struct dev_priv *priv = netdev_priv(dev);
 309        unsigned int lnkstat, carrier;
 310        unsigned long flags;
 311
 312        spin_lock_irqsave(&priv->chip_lock, flags);
 313        lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
 314        spin_unlock_irqrestore(&priv->chip_lock, flags);
 315        carrier = netif_carrier_ok(dev);
 316
 317        if (lnkstat && !carrier) {
 318                netif_carrier_on(dev);
 319                printk("%s: link up\n", dev->name);
 320        } else if (!lnkstat && carrier) {
 321                netif_carrier_off(dev);
 322                printk("%s: link down\n", dev->name);
 323        }
 324
 325        mod_timer(&priv->timer, jiffies + msecs_to_jiffies(500));
 326}
 327
 328/*
 329 * Open/initialize the board.
 330 */
 331static int
 332am79c961_open(struct net_device *dev)
 333{
 334        struct dev_priv *priv = netdev_priv(dev);
 335        int ret;
 336
 337        ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev);
 338        if (ret)
 339                return ret;
 340
 341        am79c961_init_for_open(dev);
 342
 343        netif_carrier_off(dev);
 344
 345        priv->timer.expires = jiffies;
 346        add_timer(&priv->timer);
 347
 348        netif_start_queue(dev);
 349
 350        return 0;
 351}
 352
 353/*
 354 * The inverse routine to am79c961_open().
 355 */
 356static int
 357am79c961_close(struct net_device *dev)
 358{
 359        struct dev_priv *priv = netdev_priv(dev);
 360        unsigned long flags;
 361
 362        del_timer_sync(&priv->timer);
 363
 364        netif_stop_queue(dev);
 365        netif_carrier_off(dev);
 366
 367        spin_lock_irqsave(&priv->chip_lock, flags);
 368        write_rreg (dev->base_addr, CSR0, CSR0_STOP);
 369        write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
 370        spin_unlock_irqrestore(&priv->chip_lock, flags);
 371
 372        free_irq (dev->irq, dev);
 373
 374        return 0;
 375}
 376
 377/*
 378 * Set or clear promiscuous/multicast mode filter for this adapter.
 379 */
 380static void am79c961_setmulticastlist (struct net_device *dev)
 381{
 382        struct dev_priv *priv = netdev_priv(dev);
 383        unsigned long flags;
 384        u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
 385        int i, stopped;
 386
 387        spin_lock_irqsave(&priv->chip_lock, flags);
 388
 389        stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
 390
 391        if (!stopped) {
 392                /*
 393                 * Put the chip into suspend mode
 394                 */
 395                write_rreg(dev->base_addr, CTRL1, CTRL1_SPND);
 396
 397                /*
 398                 * Spin waiting for chip to report suspend mode
 399                 */
 400                while ((read_rreg(dev->base_addr, CTRL1) & CTRL1_SPND) == 0) {
 401                        spin_unlock_irqrestore(&priv->chip_lock, flags);
 402                        nop();
 403                        spin_lock_irqsave(&priv->chip_lock, flags);
 404                }
 405        }
 406
 407        /*
 408         * Update the multicast hash table
 409         */
 410        for (i = 0; i < ARRAY_SIZE(multi_hash); i++)
 411                write_rreg(dev->base_addr, i + LADRL, multi_hash[i]);
 412
 413        /*
 414         * Write the mode register
 415         */
 416        write_rreg(dev->base_addr, MODE, mode);
 417
 418        if (!stopped) {
 419                /*
 420                 * Put the chip back into running mode
 421                 */
 422                write_rreg(dev->base_addr, CTRL1, 0);
 423        }
 424
 425        spin_unlock_irqrestore(&priv->chip_lock, flags);
 426}
 427
 428static void am79c961_timeout(struct net_device *dev)
 429{
 430        printk(KERN_WARNING "%s: transmit timed out, network cable problem?\n",
 431                dev->name);
 432
 433        /*
 434         * ought to do some setup of the tx side here
 435         */
 436
 437        netif_wake_queue(dev);
 438}
 439
 440/*
 441 * Transmit a packet
 442 */
 443static int
 444am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
 445{
 446        struct dev_priv *priv = netdev_priv(dev);
 447        unsigned int hdraddr, bufaddr;
 448        unsigned int head;
 449        unsigned long flags;
 450
 451        head = priv->txhead;
 452        hdraddr = priv->txhdr + (head << 3);
 453        bufaddr = priv->txbuffer[head];
 454        head += 1;
 455        if (head >= TX_BUFFERS)
 456                head = 0;
 457
 458        am_writebuffer (dev, bufaddr, skb->data, skb->len);
 459        am_writeword (dev, hdraddr + 4, -skb->len);
 460        am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP);
 461        priv->txhead = head;
 462
 463        spin_lock_irqsave(&priv->chip_lock, flags);
 464        write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
 465        spin_unlock_irqrestore(&priv->chip_lock, flags);
 466
 467        /*
 468         * If the next packet is owned by the ethernet device,
 469         * then the tx ring is full and we can't add another
 470         * packet.
 471         */
 472        if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN)
 473                netif_stop_queue(dev);
 474
 475        dev_kfree_skb(skb);
 476
 477        return NETDEV_TX_OK;
 478}
 479
 480/*
 481 * If we have a good packet(s), get it/them out of the buffers.
 482 */
 483static void
 484am79c961_rx(struct net_device *dev, struct dev_priv *priv)
 485{
 486        do {
 487                struct sk_buff *skb;
 488                u_int hdraddr;
 489                u_int pktaddr;
 490                u_int status;
 491                int len;
 492
 493                hdraddr = priv->rxhdr + (priv->rxtail << 3);
 494                pktaddr = priv->rxbuffer[priv->rxtail];
 495
 496                status = am_readword (dev, hdraddr + 2);
 497                if (status & RMD_OWN) /* do we own it? */
 498                        break;
 499
 500                priv->rxtail ++;
 501                if (priv->rxtail >= RX_BUFFERS)
 502                        priv->rxtail = 0;
 503
 504                if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) {
 505                        am_writeword (dev, hdraddr + 2, RMD_OWN);
 506                        dev->stats.rx_errors++;
 507                        if (status & RMD_ERR) {
 508                                if (status & RMD_FRAM)
 509                                        dev->stats.rx_frame_errors++;
 510                                if (status & RMD_CRC)
 511                                        dev->stats.rx_crc_errors++;
 512                        } else if (status & RMD_STP)
 513                                dev->stats.rx_length_errors++;
 514                        continue;
 515                }
 516
 517                len = am_readword(dev, hdraddr + 6);
 518                skb = netdev_alloc_skb(dev, len + 2);
 519
 520                if (skb) {
 521                        skb_reserve(skb, 2);
 522
 523                        am_readbuffer(dev, pktaddr, skb_put(skb, len), len);
 524                        am_writeword(dev, hdraddr + 2, RMD_OWN);
 525                        skb->protocol = eth_type_trans(skb, dev);
 526                        netif_rx(skb);
 527                        dev->stats.rx_bytes += len;
 528                        dev->stats.rx_packets++;
 529                } else {
 530                        am_writeword (dev, hdraddr + 2, RMD_OWN);
 531                        dev->stats.rx_dropped++;
 532                        break;
 533                }
 534        } while (1);
 535}
 536
 537/*
 538 * Update stats for the transmitted packet
 539 */
 540static void
 541am79c961_tx(struct net_device *dev, struct dev_priv *priv)
 542{
 543        do {
 544                short len;
 545                u_int hdraddr;
 546                u_int status;
 547
 548                hdraddr = priv->txhdr + (priv->txtail << 3);
 549                status = am_readword (dev, hdraddr + 2);
 550                if (status & TMD_OWN)
 551                        break;
 552
 553                priv->txtail ++;
 554                if (priv->txtail >= TX_BUFFERS)
 555                        priv->txtail = 0;
 556
 557                if (status & TMD_ERR) {
 558                        u_int status2;
 559
 560                        dev->stats.tx_errors++;
 561
 562                        status2 = am_readword (dev, hdraddr + 6);
 563
 564                        /*
 565                         * Clear the error byte
 566                         */
 567                        am_writeword (dev, hdraddr + 6, 0);
 568
 569                        if (status2 & TST_RTRY)
 570                                dev->stats.collisions += 16;
 571                        if (status2 & TST_LCOL)
 572                                dev->stats.tx_window_errors++;
 573                        if (status2 & TST_LCAR)
 574                                dev->stats.tx_carrier_errors++;
 575                        if (status2 & TST_UFLO)
 576                                dev->stats.tx_fifo_errors++;
 577                        continue;
 578                }
 579                dev->stats.tx_packets++;
 580                len = am_readword (dev, hdraddr + 4);
 581                dev->stats.tx_bytes += -len;
 582        } while (priv->txtail != priv->txhead);
 583
 584        netif_wake_queue(dev);
 585}
 586
 587static irqreturn_t
 588am79c961_interrupt(int irq, void *dev_id)
 589{
 590        struct net_device *dev = (struct net_device *)dev_id;
 591        struct dev_priv *priv = netdev_priv(dev);
 592        u_int status, n = 100;
 593        int handled = 0;
 594
 595        do {
 596                status = read_rreg(dev->base_addr, CSR0);
 597                write_rreg(dev->base_addr, CSR0, status &
 598                           (CSR0_IENA|CSR0_TINT|CSR0_RINT|
 599                            CSR0_MERR|CSR0_MISS|CSR0_CERR|CSR0_BABL));
 600
 601                if (status & CSR0_RINT) {
 602                        handled = 1;
 603                        am79c961_rx(dev, priv);
 604                }
 605                if (status & CSR0_TINT) {
 606                        handled = 1;
 607                        am79c961_tx(dev, priv);
 608                }
 609                if (status & CSR0_MISS) {
 610                        handled = 1;
 611                        dev->stats.rx_dropped++;
 612                }
 613                if (status & CSR0_CERR) {
 614                        handled = 1;
 615                        mod_timer(&priv->timer, jiffies);
 616                }
 617        } while (--n && status & (CSR0_RINT | CSR0_TINT));
 618
 619        return IRQ_RETVAL(handled);
 620}
 621
 622#ifdef CONFIG_NET_POLL_CONTROLLER
 623static void am79c961_poll_controller(struct net_device *dev)
 624{
 625        unsigned long flags;
 626        local_irq_save(flags);
 627        am79c961_interrupt(dev->irq, dev);
 628        local_irq_restore(flags);
 629}
 630#endif
 631
 632/*
 633 * Initialise the chip.  Note that we always expect
 634 * to be entered with interrupts enabled.
 635 */
 636static int
 637am79c961_hw_init(struct net_device *dev)
 638{
 639        struct dev_priv *priv = netdev_priv(dev);
 640
 641        spin_lock_irq(&priv->chip_lock);
 642        write_rreg (dev->base_addr, CSR0, CSR0_STOP);
 643        write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
 644        spin_unlock_irq(&priv->chip_lock);
 645
 646        am79c961_ramtest(dev, 0x66);
 647        am79c961_ramtest(dev, 0x99);
 648
 649        return 0;
 650}
 651
 652static void __init am79c961_banner(void)
 653{
 654        static unsigned version_printed;
 655
 656        if (net_debug && version_printed++ == 0)
 657                printk(KERN_INFO "%s", version);
 658}
 659static const struct net_device_ops am79c961_netdev_ops = {
 660        .ndo_open               = am79c961_open,
 661        .ndo_stop               = am79c961_close,
 662        .ndo_start_xmit         = am79c961_sendpacket,
 663        .ndo_set_rx_mode        = am79c961_setmulticastlist,
 664        .ndo_tx_timeout         = am79c961_timeout,
 665        .ndo_validate_addr      = eth_validate_addr,
 666        .ndo_change_mtu         = eth_change_mtu,
 667        .ndo_set_mac_address    = eth_mac_addr,
 668#ifdef CONFIG_NET_POLL_CONTROLLER
 669        .ndo_poll_controller    = am79c961_poll_controller,
 670#endif
 671};
 672
 673static int am79c961_probe(struct platform_device *pdev)
 674{
 675        struct resource *res;
 676        struct net_device *dev;
 677        struct dev_priv *priv;
 678        int i, ret;
 679
 680        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 681        if (!res)
 682                return -ENODEV;
 683
 684        dev = alloc_etherdev(sizeof(struct dev_priv));
 685        ret = -ENOMEM;
 686        if (!dev)
 687                goto out;
 688
 689        SET_NETDEV_DEV(dev, &pdev->dev);
 690
 691        priv = netdev_priv(dev);
 692
 693        /*
 694         * Fixed address and IRQ lines here.
 695         * The PNP initialisation should have been
 696         * done by the ether bootp loader.
 697         */
 698        dev->base_addr = res->start;
 699        ret = platform_get_irq(pdev, 0);
 700
 701        if (ret < 0) {
 702                ret = -ENODEV;
 703                goto nodev;
 704        }
 705        dev->irq = ret;
 706
 707        ret = -ENODEV;
 708        if (!request_region(dev->base_addr, 0x18, dev->name))
 709                goto nodev;
 710
 711        /*
 712         * Reset the device.
 713         */
 714        inb(dev->base_addr + NET_RESET);
 715        udelay(5);
 716
 717        /*
 718         * Check the manufacturer part of the
 719         * ether address.
 720         */
 721        if (inb(dev->base_addr) != 0x08 ||
 722            inb(dev->base_addr + 2) != 0x00 ||
 723            inb(dev->base_addr + 4) != 0x2b)
 724                goto release;
 725
 726        for (i = 0; i < 6; i++)
 727                dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff;
 728
 729        am79c961_banner();
 730
 731        spin_lock_init(&priv->chip_lock);
 732        init_timer(&priv->timer);
 733        priv->timer.data = (unsigned long)dev;
 734        priv->timer.function = am79c961_timer;
 735
 736        if (am79c961_hw_init(dev))
 737                goto release;
 738
 739        dev->netdev_ops = &am79c961_netdev_ops;
 740
 741        ret = register_netdev(dev);
 742        if (ret == 0) {
 743                printk(KERN_INFO "%s: ether address %pM\n",
 744                       dev->name, dev->dev_addr);
 745                return 0;
 746        }
 747
 748release:
 749        release_region(dev->base_addr, 0x18);
 750nodev:
 751        free_netdev(dev);
 752out:
 753        return ret;
 754}
 755
 756static struct platform_driver am79c961_driver = {
 757        .probe          = am79c961_probe,
 758        .driver         = {
 759                .name   = "am79c961",
 760        },
 761};
 762
 763static int __init am79c961_init(void)
 764{
 765        return platform_driver_register(&am79c961_driver);
 766}
 767
 768__initcall(am79c961_init);
 769