linux/drivers/net/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/slab.h>
  92#include <linux/string.h>
  93#include <linux/nubus.h>
  94#include <linux/errno.h>
  95#include <linux/init.h>
  96#include <linux/netdevice.h>
  97#include <linux/etherdevice.h>
  98#include <linux/skbuff.h>
  99#include <linux/delay.h>
 100#include <linux/bitops.h>
 101
 102#include <asm/system.h>
 103#include <asm/io.h>
 104#include <asm/hwtest.h>
 105#include <asm/macints.h>
 106
 107#include "cs89x0.h"
 108
 109static unsigned int net_debug = NET_DEBUG;
 110
 111/* Information that need to be kept for each board. */
 112struct net_local {
 113        struct net_device_stats stats;
 114        int chip_type;          /* one of: CS8900, CS8920, CS8920M */
 115        char chip_revision;     /* revision letter of the chip ('A'...) */
 116        int send_cmd;           /* the propercommand used to send a packet. */
 117        int rx_mode;
 118        int curr_rx_cfg;
 119        int send_underrun;      /* keep track of how many underruns in a row we get */
 120        struct sk_buff *skb;
 121};
 122
 123/* Index to functions, as function prototypes. */
 124
 125#if 0
 126extern void reset_chip(struct net_device *dev);
 127#endif
 128static int net_open(struct net_device *dev);
 129static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
 130static irqreturn_t net_interrupt(int irq, void *dev_id);
 131static void set_multicast_list(struct net_device *dev);
 132static void net_rx(struct net_device *dev);
 133static int net_close(struct net_device *dev);
 134static struct net_device_stats *net_get_stats(struct net_device *dev);
 135static int set_mac_address(struct net_device *dev, void *addr);
 136
 137
 138/* Example routines you must write ;->. */
 139#define tx_done(dev) 1
 140
 141/* For reading/writing registers ISA-style */
 142static inline int
 143readreg_io(struct net_device *dev, int portno)
 144{
 145        nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
 146        return swab16(nubus_readw(dev->base_addr + DATA_PORT));
 147}
 148
 149static inline void
 150writereg_io(struct net_device *dev, int portno, int value)
 151{
 152        nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
 153        nubus_writew(swab16(value), dev->base_addr + DATA_PORT);
 154}
 155
 156/* These are for reading/writing registers in shared memory */
 157static inline int
 158readreg(struct net_device *dev, int portno)
 159{
 160        return swab16(nubus_readw(dev->mem_start + portno));
 161}
 162
 163static inline void
 164writereg(struct net_device *dev, int portno, int value)
 165{
 166        nubus_writew(swab16(value), dev->mem_start + portno);
 167}
 168
 169static const struct net_device_ops mac89x0_netdev_ops = {
 170        .ndo_open               = net_open,
 171        .ndo_stop               = net_close,
 172        .ndo_start_xmit         = net_send_packet,
 173        .ndo_get_stats          = net_get_stats,
 174        .ndo_set_multicast_list = set_multicast_list,
 175        .ndo_set_mac_address    = set_mac_address,
 176        .ndo_validate_addr      = eth_validate_addr,
 177        .ndo_change_mtu         = eth_change_mtu,
 178};
 179
 180/* Probe for the CS8900 card in slot E.  We won't bother looking
 181   anywhere else until we have a really good reason to do so. */
 182struct net_device * __init mac89x0_probe(int unit)
 183{
 184        struct net_device *dev;
 185        static int once_is_enough;
 186        struct net_local *lp;
 187        static unsigned version_printed;
 188        int i, slot;
 189        unsigned rev_type = 0;
 190        unsigned long ioaddr;
 191        unsigned short sig;
 192        int err = -ENODEV;
 193
 194        if (!MACH_IS_MAC)
 195                return ERR_PTR(-ENODEV);
 196
 197        dev = alloc_etherdev(sizeof(struct net_local));
 198        if (!dev)
 199                return ERR_PTR(-ENOMEM);
 200
 201        if (unit >= 0) {
 202                sprintf(dev->name, "eth%d", unit);
 203                netdev_boot_setup_check(dev);
 204        }
 205
 206        if (once_is_enough)
 207                goto out;
 208        once_is_enough = 1;
 209
 210        /* We might have to parameterize this later */
 211        slot = 0xE;
 212        /* Get out now if there's a real NuBus card in slot E */
 213        if (nubus_find_slot(slot, NULL) != NULL)
 214                goto out;
 215
 216        /* The pseudo-ISA bits always live at offset 0x300 (gee,
 217           wonder why...) */
 218        ioaddr = (unsigned long)
 219                nubus_slot_addr(slot) | (((slot&0xf) << 20) + DEFAULTIOBASE);
 220        {
 221                unsigned long flags;
 222                int card_present;
 223
 224                local_irq_save(flags);
 225                card_present = hwreg_present((void*) ioaddr+4)
 226                  && hwreg_present((void*) ioaddr + DATA_PORT);
 227                local_irq_restore(flags);
 228
 229                if (!card_present)
 230                        goto out;
 231        }
 232
 233        nubus_writew(0, ioaddr + ADD_PORT);
 234        sig = nubus_readw(ioaddr + DATA_PORT);
 235        if (sig != swab16(CHIP_EISA_ID_SIG))
 236                goto out;
 237
 238        /* Initialize the net_device structure. */
 239        lp = netdev_priv(dev);
 240
 241        /* Fill in the 'dev' fields. */
 242        dev->base_addr = ioaddr;
 243        dev->mem_start = (unsigned long)
 244                nubus_slot_addr(slot) | (((slot&0xf) << 20) + MMIOBASE);
 245        dev->mem_end = dev->mem_start + 0x1000;
 246
 247        /* Turn on shared memory */
 248        writereg_io(dev, PP_BusCTL, MEMORY_ON);
 249
 250        /* get the chip type */
 251        rev_type = readreg(dev, PRODUCT_ID_ADD);
 252        lp->chip_type = rev_type &~ REVISON_BITS;
 253        lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
 254
 255        /* Check the chip type and revision in order to set the correct send command
 256        CS8920 revision C and CS8900 revision F can use the faster send. */
 257        lp->send_cmd = TX_AFTER_381;
 258        if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
 259                lp->send_cmd = TX_NOW;
 260        if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
 261                lp->send_cmd = TX_NOW;
 262
 263        if (net_debug && version_printed++ == 0)
 264                printk(version);
 265
 266        printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#8lx",
 267               dev->name,
 268               lp->chip_type==CS8900?'0':'2',
 269               lp->chip_type==CS8920M?"M":"",
 270               lp->chip_revision,
 271               dev->base_addr);
 272
 273        /* Try to read the MAC address */
 274        if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
 275                printk("\nmac89x0: No EEPROM, giving up now.\n");
 276                goto out1;
 277        } else {
 278                for (i = 0; i < ETH_ALEN; i += 2) {
 279                        /* Big-endian (why??!) */
 280                        unsigned short s = readreg(dev, PP_IA + i);
 281                        dev->dev_addr[i] = s >> 8;
 282                        dev->dev_addr[i+1] = s & 0xff;
 283                }
 284        }
 285
 286        dev->irq = SLOT2IRQ(slot);
 287
 288        /* print the IRQ and ethernet address. */
 289
 290        printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr);
 291
 292        dev->netdev_ops         = &mac89x0_netdev_ops;
 293
 294        err = register_netdev(dev);
 295        if (err)
 296                goto out1;
 297        return NULL;
 298out1:
 299        nubus_writew(0, dev->base_addr + ADD_PORT);
 300out:
 301        free_netdev(dev);
 302        return ERR_PTR(err);
 303}
 304
 305#if 0
 306/* This is useful for something, but I don't know what yet. */
 307void __init reset_chip(struct net_device *dev)
 308{
 309        int reset_start_time;
 310
 311        writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
 312
 313        /* wait 30 ms */
 314        msleep_interruptible(30);
 315
 316        /* Wait until the chip is reset */
 317        reset_start_time = jiffies;
 318        while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
 319                ;
 320}
 321#endif
 322
 323/* Open/initialize the board.  This is called (in the current kernel)
 324   sometime after booting when the 'ifconfig' program is run.
 325
 326   This routine should set everything up anew at each open, even
 327   registers that "should" only need to be set once at boot, so that
 328   there is non-reboot way to recover if something goes wrong.
 329   */
 330static int
 331net_open(struct net_device *dev)
 332{
 333        struct net_local *lp = netdev_priv(dev);
 334        int i;
 335
 336        /* Disable the interrupt for now */
 337        writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) & ~ENABLE_IRQ);
 338
 339        /* Grab the interrupt */
 340        if (request_irq(dev->irq, &net_interrupt, 0, "cs89x0", dev))
 341                return -EAGAIN;
 342
 343        /* Set up the IRQ - Apparently magic */
 344        if (lp->chip_type == CS8900)
 345                writereg(dev, PP_CS8900_ISAINT, 0);
 346        else
 347                writereg(dev, PP_CS8920_ISAINT, 0);
 348
 349        /* set the Ethernet address */
 350        for (i=0; i < ETH_ALEN/2; i++)
 351                writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
 352
 353        /* Turn on both receive and transmit operations */
 354        writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
 355
 356        /* Receive only error free packets addressed to this card */
 357        lp->rx_mode = 0;
 358        writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
 359
 360        lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
 361
 362        writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
 363
 364        writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
 365               TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
 366
 367        writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
 368                 TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
 369
 370        /* now that we've got our act together, enable everything */
 371        writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
 372        netif_start_queue(dev);
 373        return 0;
 374}
 375
 376static int
 377net_send_packet(struct sk_buff *skb, struct net_device *dev)
 378{
 379        struct net_local *lp = netdev_priv(dev);
 380        unsigned long flags;
 381
 382        if (net_debug > 3)
 383                printk("%s: sent %d byte packet of type %x\n",
 384                       dev->name, skb->len,
 385                       (skb->data[ETH_ALEN+ETH_ALEN] << 8)
 386                       | skb->data[ETH_ALEN+ETH_ALEN+1]);
 387
 388        /* keep the upload from being interrupted, since we
 389           ask the chip to start transmitting before the
 390           whole packet has been completely uploaded. */
 391        local_irq_save(flags);
 392        netif_stop_queue(dev);
 393
 394        /* initiate a transmit sequence */
 395        writereg(dev, PP_TxCMD, lp->send_cmd);
 396        writereg(dev, PP_TxLength, skb->len);
 397
 398        /* Test to see if the chip has allocated memory for the packet */
 399        if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
 400                /* Gasp!  It hasn't.  But that shouldn't happen since
 401                   we're waiting for TxOk, so return 1 and requeue this packet. */
 402                local_irq_restore(flags);
 403                return NETDEV_TX_BUSY;
 404        }
 405
 406        /* Write the contents of the packet */
 407        skb_copy_from_linear_data(skb, (void *)(dev->mem_start + PP_TxFrame),
 408                                  skb->len+1);
 409
 410        local_irq_restore(flags);
 411        dev->trans_start = jiffies;
 412        dev_kfree_skb (skb);
 413
 414        return NETDEV_TX_OK;
 415}
 416
 417/* The typical workload of the driver:
 418   Handle the network interface interrupts. */
 419static irqreturn_t net_interrupt(int irq, void *dev_id)
 420{
 421        struct net_device *dev = dev_id;
 422        struct net_local *lp;
 423        int ioaddr, status;
 424
 425        if (dev == NULL) {
 426                printk ("net_interrupt(): irq %d for unknown device.\n", irq);
 427                return IRQ_NONE;
 428        }
 429
 430        ioaddr = dev->base_addr;
 431        lp = netdev_priv(dev);
 432
 433        /* we MUST read all the events out of the ISQ, otherwise we'll never
 434           get interrupted again.  As a consequence, we can't have any limit
 435           on the number of times we loop in the interrupt handler.  The
 436           hardware guarantees that eventually we'll run out of events.  Of
 437           course, if you're on a slow machine, and packets are arriving
 438           faster than you can read them off, you're screwed.  Hasta la
 439           vista, baby!  */
 440        while ((status = swab16(nubus_readw(dev->base_addr + ISQ_PORT)))) {
 441                if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
 442                switch(status & ISQ_EVENT_MASK) {
 443                case ISQ_RECEIVER_EVENT:
 444                        /* Got a packet(s). */
 445                        net_rx(dev);
 446                        break;
 447                case ISQ_TRANSMITTER_EVENT:
 448                        lp->stats.tx_packets++;
 449                        netif_wake_queue(dev);
 450                        if ((status & TX_OK) == 0) lp->stats.tx_errors++;
 451                        if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
 452                        if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
 453                        if (status & TX_LATE_COL) lp->stats.tx_window_errors++;
 454                        if (status & TX_16_COL) lp->stats.tx_aborted_errors++;
 455                        break;
 456                case ISQ_BUFFER_EVENT:
 457                        if (status & READY_FOR_TX) {
 458                                /* we tried to transmit a packet earlier,
 459                                   but inexplicably ran out of buffers.
 460                                   That shouldn't happen since we only ever
 461                                   load one packet.  Shrug.  Do the right
 462                                   thing anyway. */
 463                                netif_wake_queue(dev);
 464                        }
 465                        if (status & TX_UNDERRUN) {
 466                                if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
 467                                lp->send_underrun++;
 468                                if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
 469                                else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
 470                        }
 471                        break;
 472                case ISQ_RX_MISS_EVENT:
 473                        lp->stats.rx_missed_errors += (status >>6);
 474                        break;
 475                case ISQ_TX_COL_EVENT:
 476                        lp->stats.collisions += (status >>6);
 477                        break;
 478                }
 479        }
 480        return IRQ_HANDLED;
 481}
 482
 483/* We have a good packet(s), get it/them out of the buffers. */
 484static void
 485net_rx(struct net_device *dev)
 486{
 487        struct net_local *lp = netdev_priv(dev);
 488        struct sk_buff *skb;
 489        int status, length;
 490
 491        status = readreg(dev, PP_RxStatus);
 492        if ((status & RX_OK) == 0) {
 493                lp->stats.rx_errors++;
 494                if (status & RX_RUNT) lp->stats.rx_length_errors++;
 495                if (status & RX_EXTRA_DATA) lp->stats.rx_length_errors++;
 496                if (status & RX_CRC_ERROR) if (!(status & (RX_EXTRA_DATA|RX_RUNT)))
 497                        /* per str 172 */
 498                        lp->stats.rx_crc_errors++;
 499                if (status & RX_DRIBBLE) lp->stats.rx_frame_errors++;
 500                return;
 501        }
 502
 503        length = readreg(dev, PP_RxLength);
 504        /* Malloc up new buffer. */
 505        skb = alloc_skb(length, GFP_ATOMIC);
 506        if (skb == NULL) {
 507                printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 508                lp->stats.rx_dropped++;
 509                return;
 510        }
 511        skb_put(skb, length);
 512
 513        skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame),
 514                                length);
 515
 516        if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
 517                                 dev->name, length,
 518                                 (skb->data[ETH_ALEN+ETH_ALEN] << 8)
 519                                 | skb->data[ETH_ALEN+ETH_ALEN+1]);
 520
 521        skb->protocol=eth_type_trans(skb,dev);
 522        netif_rx(skb);
 523        lp->stats.rx_packets++;
 524        lp->stats.rx_bytes += length;
 525}
 526
 527/* The inverse routine to net_open(). */
 528static int
 529net_close(struct net_device *dev)
 530{
 531
 532        writereg(dev, PP_RxCFG, 0);
 533        writereg(dev, PP_TxCFG, 0);
 534        writereg(dev, PP_BufCFG, 0);
 535        writereg(dev, PP_BusCTL, 0);
 536
 537        netif_stop_queue(dev);
 538
 539        free_irq(dev->irq, dev);
 540
 541        /* Update the statistics here. */
 542
 543        return 0;
 544
 545}
 546
 547/* Get the current statistics.  This may be called with the card open or
 548   closed. */
 549static struct net_device_stats *
 550net_get_stats(struct net_device *dev)
 551{
 552        struct net_local *lp = netdev_priv(dev);
 553        unsigned long flags;
 554
 555        local_irq_save(flags);
 556        /* Update the statistics from the device registers. */
 557        lp->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
 558        lp->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
 559        local_irq_restore(flags);
 560
 561        return &lp->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        }
 572        else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
 573        {
 574                /* The multicast-accept list is initialized to accept-all, and we
 575                   rely on higher-level filtering for now. */
 576                lp->rx_mode = RX_MULTCAST_ACCEPT;
 577        }
 578        else
 579                lp->rx_mode = 0;
 580
 581        writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
 582
 583        /* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
 584        writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
 585             (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
 586}
 587
 588
 589static int set_mac_address(struct net_device *dev, void *addr)
 590{
 591        int i;
 592        printk("%s: Setting MAC address to ", dev->name);
 593        for (i = 0; i < 6; i++)
 594                printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
 595        printk(".\n");
 596        /* set the Ethernet address */
 597        for (i=0; i < ETH_ALEN/2; i++)
 598                writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
 599
 600        return 0;
 601}
 602
 603#ifdef MODULE
 604
 605static struct net_device *dev_cs89x0;
 606static int debug;
 607
 608module_param(debug, int, 0);
 609MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)");
 610MODULE_LICENSE("GPL");
 611
 612int __init
 613init_module(void)
 614{
 615        net_debug = debug;
 616        dev_cs89x0 = mac89x0_probe(-1);
 617        if (IS_ERR(dev_cs89x0)) {
 618                printk(KERN_WARNING "mac89x0.c: No card found\n");
 619                return PTR_ERR(dev_cs89x0);
 620        }
 621        return 0;
 622}
 623
 624void
 625cleanup_module(void)
 626{
 627        unregister_netdev(dev_cs89x0);
 628        nubus_writew(0, dev_cs89x0->base_addr + ADD_PORT);
 629        free_netdev(dev_cs89x0);
 630}
 631#endif /* MODULE */
 632