linux/drivers/net/ethernet/cirrus/mac89x0.c
<<
>>
Prefs
   1/* mac89x0.c: A Crystal Semiconductor CS89[02]0 driver for linux. */
   2/*
   3        Written 1996 by Russell Nelson, with reference to skeleton.c
   4        written 1993-1994 by Donald Becker.
   5
   6        This software may be used and distributed according to the terms
   7        of the GNU General Public License, incorporated herein by reference.
   8
   9        The author may be reached at nelson@crynwr.com, Crynwr
  10        Software, 11 Grant St., Potsdam, NY 13676
  11
  12  Changelog:
  13
  14  Mike Cruse        : mcruse@cti-ltd.com
  15                    : Changes for Linux 2.0 compatibility.
  16                    : Added dev_id parameter in net_interrupt(),
  17                    : request_irq() and free_irq(). Just NULL for now.
  18
  19  Mike Cruse        : Added MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros
  20                    : in net_open() and net_close() so kerneld would know
  21                    : that the module is in use and wouldn't eject the
  22                    : driver prematurely.
  23
  24  Mike Cruse        : Rewrote init_module() and cleanup_module using 8390.c
  25                    : as an example. Disabled autoprobing in init_module(),
  26                    : not a good thing to do to other devices while Linux
  27                    : is running from all accounts.
  28
  29  Alan Cox          : Removed 1.2 support, added 2.1 extra counters.
  30
  31  David Huggins-Daines <dhd@debian.org>
  32
  33  Split this off into mac89x0.c, and gutted it of all parts which are
  34  not relevant to the existing CS8900 cards on the Macintosh
  35  (i.e. basically the Daynaport CS and LC cards).  To be precise:
  36
  37    * Removed all the media-detection stuff, because these cards are
  38    TP-only.
  39
  40    * Lobotomized the ISA interrupt bogosity, because these cards use
  41    a hardwired NuBus interrupt and a magic ISAIRQ value in the card.
  42
  43    * Basically eliminated everything not relevant to getting the
  44    cards minimally functioning on the Macintosh.
  45
  46  I might add that these cards are badly designed even from the Mac
  47  standpoint, in that Dayna, in their infinite wisdom, used NuBus slot
  48  I/O space and NuBus interrupts for these cards, but neglected to
  49  provide anything even remotely resembling a NuBus ROM.  Therefore we
  50  have to probe for them in a brain-damaged ISA-like fashion.
  51
  52  Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 11/01/2001
  53  check kmalloc and release the allocated memory on failure in
  54  mac89x0_probe and in init_module
  55  use local_irq_{save,restore}(flags) in net_get_stat, not just
  56  local_irq_{dis,en}able()
  57*/
  58
  59static char *version =
  60"cs89x0.c:v1.02 11/26/96 Russell Nelson <nelson@crynwr.com>\n";
  61
  62/* ======================= configure the driver here ======================= */
  63
  64/* use 0 for production, 1 for verification, >2 for debug */
  65#ifndef NET_DEBUG
  66#define NET_DEBUG 0
  67#endif
  68
  69/* ======================= end of configuration ======================= */
  70
  71
  72/* Always include 'config.h' first in case the user wants to turn on
  73   or override something. */
  74#include <linux/module.h>
  75
  76/*
  77  Sources:
  78
  79        Crynwr packet driver epktisa.
  80
  81        Crystal Semiconductor data sheets.
  82
  83*/
  84
  85#include <linux/kernel.h>
  86#include <linux/types.h>
  87#include <linux/fcntl.h>
  88#include <linux/interrupt.h>
  89#include <linux/ioport.h>
  90#include <linux/in.h>
  91#include <linux/string.h>
  92#include <linux/nubus.h>
  93#include <linux/errno.h>
  94#include <linux/init.h>
  95#include <linux/netdevice.h>
  96#include <linux/etherdevice.h>
  97#include <linux/skbuff.h>
  98#include <linux/delay.h>
  99#include <linux/bitops.h>
 100#include <linux/gfp.h>
 101
 102#include <asm/io.h>
 103#include <asm/hwtest.h>
 104#include <asm/macints.h>
 105
 106#include "cs89x0.h"
 107
 108static unsigned int net_debug = NET_DEBUG;
 109
 110/* Information that need to be kept for each board. */
 111struct net_local {
 112        int chip_type;          /* one of: CS8900, CS8920, CS8920M */
 113        char chip_revision;     /* revision letter of the chip ('A'...) */
 114        int send_cmd;           /* the propercommand used to send a packet. */
 115        int rx_mode;
 116        int curr_rx_cfg;
 117        int send_underrun;      /* keep track of how many underruns in a row we get */
 118        struct sk_buff *skb;
 119};
 120
 121/* Index to functions, as function prototypes. */
 122
 123#if 0
 124extern void reset_chip(struct net_device *dev);
 125#endif
 126static int net_open(struct net_device *dev);
 127static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
 128static irqreturn_t net_interrupt(int irq, void *dev_id);
 129static void set_multicast_list(struct net_device *dev);
 130static void net_rx(struct net_device *dev);
 131static int net_close(struct net_device *dev);
 132static struct net_device_stats *net_get_stats(struct net_device *dev);
 133static int set_mac_address(struct net_device *dev, void *addr);
 134
 135
 136/* Example routines you must write ;->. */
 137#define tx_done(dev) 1
 138
 139/* For reading/writing registers ISA-style */
 140static inline int
 141readreg_io(struct net_device *dev, int portno)
 142{
 143        nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
 144        return swab16(nubus_readw(dev->base_addr + DATA_PORT));
 145}
 146
 147static inline void
 148writereg_io(struct net_device *dev, int portno, int value)
 149{
 150        nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
 151        nubus_writew(swab16(value), dev->base_addr + DATA_PORT);
 152}
 153
 154/* These are for reading/writing registers in shared memory */
 155static inline int
 156readreg(struct net_device *dev, int portno)
 157{
 158        return swab16(nubus_readw(dev->mem_start + portno));
 159}
 160
 161static inline void
 162writereg(struct net_device *dev, int portno, int value)
 163{
 164        nubus_writew(swab16(value), dev->mem_start + portno);
 165}
 166
 167static const struct net_device_ops mac89x0_netdev_ops = {
 168        .ndo_open               = net_open,
 169        .ndo_stop               = net_close,
 170        .ndo_start_xmit         = net_send_packet,
 171        .ndo_get_stats          = net_get_stats,
 172        .ndo_set_rx_mode        = set_multicast_list,
 173        .ndo_set_mac_address    = set_mac_address,
 174        .ndo_validate_addr      = eth_validate_addr,
 175        .ndo_change_mtu         = eth_change_mtu,
 176};
 177
 178/* Probe for the CS8900 card in slot E.  We won't bother looking
 179   anywhere else until we have a really good reason to do so. */
 180struct net_device * __init mac89x0_probe(int unit)
 181{
 182        struct net_device *dev;
 183        static int once_is_enough;
 184        struct net_local *lp;
 185        static unsigned version_printed;
 186        int i, slot;
 187        unsigned rev_type = 0;
 188        unsigned long ioaddr;
 189        unsigned short sig;
 190        int err = -ENODEV;
 191
 192        if (!MACH_IS_MAC)
 193                return ERR_PTR(-ENODEV);
 194
 195        dev = alloc_etherdev(sizeof(struct net_local));
 196        if (!dev)
 197                return ERR_PTR(-ENOMEM);
 198
 199        if (unit >= 0) {
 200                sprintf(dev->name, "eth%d", unit);
 201                netdev_boot_setup_check(dev);
 202        }
 203
 204        if (once_is_enough)
 205                goto out;
 206        once_is_enough = 1;
 207
 208        /* We might have to parameterize this later */
 209        slot = 0xE;
 210        /* Get out now if there's a real NuBus card in slot E */
 211        if (nubus_find_slot(slot, NULL) != NULL)
 212                goto out;
 213
 214        /* The pseudo-ISA bits always live at offset 0x300 (gee,
 215           wonder why...) */
 216        ioaddr = (unsigned long)
 217                nubus_slot_addr(slot) | (((slot&0xf) << 20) + DEFAULTIOBASE);
 218        {
 219                int card_present;
 220
 221                card_present = (hwreg_present((void *)ioaddr + 4) &&
 222                                hwreg_present((void *)ioaddr + DATA_PORT));
 223                if (!card_present)
 224                        goto out;
 225        }
 226
 227        nubus_writew(0, ioaddr + ADD_PORT);
 228        sig = nubus_readw(ioaddr + DATA_PORT);
 229        if (sig != swab16(CHIP_EISA_ID_SIG))
 230                goto out;
 231
 232        /* Initialize the net_device structure. */
 233        lp = netdev_priv(dev);
 234
 235        /* Fill in the 'dev' fields. */
 236        dev->base_addr = ioaddr;
 237        dev->mem_start = (unsigned long)
 238                nubus_slot_addr(slot) | (((slot&0xf) << 20) + MMIOBASE);
 239        dev->mem_end = dev->mem_start + 0x1000;
 240
 241        /* Turn on shared memory */
 242        writereg_io(dev, PP_BusCTL, MEMORY_ON);
 243
 244        /* get the chip type */
 245        rev_type = readreg(dev, PRODUCT_ID_ADD);
 246        lp->chip_type = rev_type &~ REVISON_BITS;
 247        lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
 248
 249        /* Check the chip type and revision in order to set the correct send command
 250        CS8920 revision C and CS8900 revision F can use the faster send. */
 251        lp->send_cmd = TX_AFTER_381;
 252        if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
 253                lp->send_cmd = TX_NOW;
 254        if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
 255                lp->send_cmd = TX_NOW;
 256
 257        if (net_debug && version_printed++ == 0)
 258                printk(version);
 259
 260        printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#8lx",
 261               dev->name,
 262               lp->chip_type==CS8900?'0':'2',
 263               lp->chip_type==CS8920M?"M":"",
 264               lp->chip_revision,
 265               dev->base_addr);
 266
 267        /* Try to read the MAC address */
 268        if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
 269                printk("\nmac89x0: No EEPROM, giving up now.\n");
 270                goto out1;
 271        } else {
 272                for (i = 0; i < ETH_ALEN; i += 2) {
 273                        /* Big-endian (why??!) */
 274                        unsigned short s = readreg(dev, PP_IA + i);
 275                        dev->dev_addr[i] = s >> 8;
 276                        dev->dev_addr[i+1] = s & 0xff;
 277                }
 278        }
 279
 280        dev->irq = SLOT2IRQ(slot);
 281
 282        /* print the IRQ and ethernet address. */
 283
 284        printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr);
 285
 286        dev->netdev_ops         = &mac89x0_netdev_ops;
 287
 288        err = register_netdev(dev);
 289        if (err)
 290                goto out1;
 291        return NULL;
 292out1:
 293        nubus_writew(0, dev->base_addr + ADD_PORT);
 294out:
 295        free_netdev(dev);
 296        return ERR_PTR(err);
 297}
 298
 299#if 0
 300/* This is useful for something, but I don't know what yet. */
 301void __init reset_chip(struct net_device *dev)
 302{
 303        int reset_start_time;
 304
 305        writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
 306
 307        /* wait 30 ms */
 308        msleep_interruptible(30);
 309
 310        /* Wait until the chip is reset */
 311        reset_start_time = jiffies;
 312        while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
 313                ;
 314}
 315#endif
 316
 317/* Open/initialize the board.  This is called (in the current kernel)
 318   sometime after booting when the 'ifconfig' program is run.
 319
 320   This routine should set everything up anew at each open, even
 321   registers that "should" only need to be set once at boot, so that
 322   there is non-reboot way to recover if something goes wrong.
 323   */
 324static int
 325net_open(struct net_device *dev)
 326{
 327        struct net_local *lp = netdev_priv(dev);
 328        int i;
 329
 330        /* Disable the interrupt for now */
 331        writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) & ~ENABLE_IRQ);
 332
 333        /* Grab the interrupt */
 334        if (request_irq(dev->irq, net_interrupt, 0, "cs89x0", dev))
 335                return -EAGAIN;
 336
 337        /* Set up the IRQ - Apparently magic */
 338        if (lp->chip_type == CS8900)
 339                writereg(dev, PP_CS8900_ISAINT, 0);
 340        else
 341                writereg(dev, PP_CS8920_ISAINT, 0);
 342
 343        /* set the Ethernet address */
 344        for (i=0; i < ETH_ALEN/2; i++)
 345                writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
 346
 347        /* Turn on both receive and transmit operations */
 348        writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
 349
 350        /* Receive only error free packets addressed to this card */
 351        lp->rx_mode = 0;
 352        writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
 353
 354        lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
 355
 356        writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
 357
 358        writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
 359               TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
 360
 361        writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
 362                 TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
 363
 364        /* now that we've got our act together, enable everything */
 365        writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
 366        netif_start_queue(dev);
 367        return 0;
 368}
 369
 370static int
 371net_send_packet(struct sk_buff *skb, struct net_device *dev)
 372{
 373        struct net_local *lp = netdev_priv(dev);
 374        unsigned long flags;
 375
 376        if (net_debug > 3)
 377                printk("%s: sent %d byte packet of type %x\n",
 378                       dev->name, skb->len,
 379                       (skb->data[ETH_ALEN+ETH_ALEN] << 8)
 380                       | skb->data[ETH_ALEN+ETH_ALEN+1]);
 381
 382        /* keep the upload from being interrupted, since we
 383           ask the chip to start transmitting before the
 384           whole packet has been completely uploaded. */
 385        local_irq_save(flags);
 386        netif_stop_queue(dev);
 387
 388        /* initiate a transmit sequence */
 389        writereg(dev, PP_TxCMD, lp->send_cmd);
 390        writereg(dev, PP_TxLength, skb->len);
 391
 392        /* Test to see if the chip has allocated memory for the packet */
 393        if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
 394                /* Gasp!  It hasn't.  But that shouldn't happen since
 395                   we're waiting for TxOk, so return 1 and requeue this packet. */
 396                local_irq_restore(flags);
 397                return NETDEV_TX_BUSY;
 398        }
 399
 400        /* Write the contents of the packet */
 401        skb_copy_from_linear_data(skb, (void *)(dev->mem_start + PP_TxFrame),
 402                                  skb->len+1);
 403
 404        local_irq_restore(flags);
 405        dev_kfree_skb (skb);
 406
 407        return NETDEV_TX_OK;
 408}
 409
 410/* The typical workload of the driver:
 411   Handle the network interface interrupts. */
 412static irqreturn_t net_interrupt(int irq, void *dev_id)
 413{
 414        struct net_device *dev = dev_id;
 415        struct net_local *lp;
 416        int ioaddr, status;
 417
 418        if (dev == NULL) {
 419                printk ("net_interrupt(): irq %d for unknown device.\n", irq);
 420                return IRQ_NONE;
 421        }
 422
 423        ioaddr = dev->base_addr;
 424        lp = netdev_priv(dev);
 425
 426        /* we MUST read all the events out of the ISQ, otherwise we'll never
 427           get interrupted again.  As a consequence, we can't have any limit
 428           on the number of times we loop in the interrupt handler.  The
 429           hardware guarantees that eventually we'll run out of events.  Of
 430           course, if you're on a slow machine, and packets are arriving
 431           faster than you can read them off, you're screwed.  Hasta la
 432           vista, baby!  */
 433        while ((status = swab16(nubus_readw(dev->base_addr + ISQ_PORT)))) {
 434                if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
 435                switch(status & ISQ_EVENT_MASK) {
 436                case ISQ_RECEIVER_EVENT:
 437                        /* Got a packet(s). */
 438                        net_rx(dev);
 439                        break;
 440                case ISQ_TRANSMITTER_EVENT:
 441                        dev->stats.tx_packets++;
 442                        netif_wake_queue(dev);
 443                        if ((status & TX_OK) == 0)
 444                                dev->stats.tx_errors++;
 445                        if (status & TX_LOST_CRS)
 446                                dev->stats.tx_carrier_errors++;
 447                        if (status & TX_SQE_ERROR)
 448                                dev->stats.tx_heartbeat_errors++;
 449                        if (status & TX_LATE_COL)
 450                                dev->stats.tx_window_errors++;
 451                        if (status & TX_16_COL)
 452                                dev->stats.tx_aborted_errors++;
 453                        break;
 454                case ISQ_BUFFER_EVENT:
 455                        if (status & READY_FOR_TX) {
 456                                /* we tried to transmit a packet earlier,
 457                                   but inexplicably ran out of buffers.
 458                                   That shouldn't happen since we only ever
 459                                   load one packet.  Shrug.  Do the right
 460                                   thing anyway. */
 461                                netif_wake_queue(dev);
 462                        }
 463                        if (status & TX_UNDERRUN) {
 464                                if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
 465                                lp->send_underrun++;
 466                                if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
 467                                else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
 468                        }
 469                        break;
 470                case ISQ_RX_MISS_EVENT:
 471                        dev->stats.rx_missed_errors += (status >> 6);
 472                        break;
 473                case ISQ_TX_COL_EVENT:
 474                        dev->stats.collisions += (status >> 6);
 475                        break;
 476                }
 477        }
 478        return IRQ_HANDLED;
 479}
 480
 481/* We have a good packet(s), get it/them out of the buffers. */
 482static void
 483net_rx(struct net_device *dev)
 484{
 485        struct sk_buff *skb;
 486        int status, length;
 487
 488        status = readreg(dev, PP_RxStatus);
 489        if ((status & RX_OK) == 0) {
 490                dev->stats.rx_errors++;
 491                if (status & RX_RUNT)
 492                                dev->stats.rx_length_errors++;
 493                if (status & RX_EXTRA_DATA)
 494                                dev->stats.rx_length_errors++;
 495                if ((status & RX_CRC_ERROR) &&
 496                    !(status & (RX_EXTRA_DATA|RX_RUNT)))
 497                        /* per str 172 */
 498                        dev->stats.rx_crc_errors++;
 499                if (status & RX_DRIBBLE)
 500                                dev->stats.rx_frame_errors++;
 501                return;
 502        }
 503
 504        length = readreg(dev, PP_RxLength);
 505        /* Malloc up new buffer. */
 506        skb = alloc_skb(length, GFP_ATOMIC);
 507        if (skb == NULL) {
 508                printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 509                dev->stats.rx_dropped++;
 510                return;
 511        }
 512        skb_put(skb, length);
 513
 514        skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame),
 515                                length);
 516
 517        if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
 518                                 dev->name, length,
 519                                 (skb->data[ETH_ALEN+ETH_ALEN] << 8)
 520                                 | skb->data[ETH_ALEN+ETH_ALEN+1]);
 521
 522        skb->protocol=eth_type_trans(skb,dev);
 523        netif_rx(skb);
 524        dev->stats.rx_packets++;
 525        dev->stats.rx_bytes += length;
 526}
 527
 528/* The inverse routine to net_open(). */
 529static int
 530net_close(struct net_device *dev)
 531{
 532
 533        writereg(dev, PP_RxCFG, 0);
 534        writereg(dev, PP_TxCFG, 0);
 535        writereg(dev, PP_BufCFG, 0);
 536        writereg(dev, PP_BusCTL, 0);
 537
 538        netif_stop_queue(dev);
 539
 540        free_irq(dev->irq, dev);
 541
 542        /* Update the statistics here. */
 543
 544        return 0;
 545
 546}
 547
 548/* Get the current statistics.  This may be called with the card open or
 549   closed. */
 550static struct net_device_stats *
 551net_get_stats(struct net_device *dev)
 552{
 553        unsigned long flags;
 554
 555        local_irq_save(flags);
 556        /* Update the statistics from the device registers. */
 557        dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
 558        dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
 559        local_irq_restore(flags);
 560
 561        return &dev->stats;
 562}
 563
 564static void set_multicast_list(struct net_device *dev)
 565{
 566        struct net_local *lp = netdev_priv(dev);
 567
 568        if(dev->flags&IFF_PROMISC)
 569        {
 570                lp->rx_mode = RX_ALL_ACCEPT;
 571        } else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
 572                /* The multicast-accept list is initialized to accept-all, and we
 573                   rely on higher-level filtering for now. */
 574                lp->rx_mode = RX_MULTCAST_ACCEPT;
 575        }
 576        else
 577                lp->rx_mode = 0;
 578
 579        writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
 580
 581        /* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
 582        writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
 583             (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
 584}
 585
 586
 587static int set_mac_address(struct net_device *dev, void *addr)
 588{
 589        struct sockaddr *saddr = addr;
 590        int i;
 591
 592        if (!is_valid_ether_addr(saddr->sa_data))
 593                return -EADDRNOTAVAIL;
 594
 595        memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
 596        printk("%s: Setting MAC address to %pM\n", dev->name, dev->dev_addr);
 597
 598        /* set the Ethernet address */
 599        for (i=0; i < ETH_ALEN/2; i++)
 600                writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
 601
 602        return 0;
 603}
 604
 605#ifdef MODULE
 606
 607static struct net_device *dev_cs89x0;
 608static int debug;
 609
 610module_param(debug, int, 0);
 611MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)");
 612MODULE_LICENSE("GPL");
 613
 614int __init
 615init_module(void)
 616{
 617        net_debug = debug;
 618        dev_cs89x0 = mac89x0_probe(-1);
 619        if (IS_ERR(dev_cs89x0)) {
 620                printk(KERN_WARNING "mac89x0.c: No card found\n");
 621                return PTR_ERR(dev_cs89x0);
 622        }
 623        return 0;
 624}
 625
 626void
 627cleanup_module(void)
 628{
 629        unregister_netdev(dev_cs89x0);
 630        nubus_writew(0, dev_cs89x0->base_addr + ADD_PORT);
 631        free_netdev(dev_cs89x0);
 632}
 633#endif /* MODULE */
 634