linux/drivers/net/isa-skeleton.c
<<
>>
Prefs
   1/* isa-skeleton.c: A network driver outline for linux.
   2 *
   3 *      Written 1993-94 by Donald Becker.
   4 *
   5 *      Copyright 1993 United States Government as represented by the
   6 *      Director, National Security Agency.
   7 *
   8 *      This software may be used and distributed according to the terms
   9 *      of the GNU General Public License, incorporated herein by reference.
  10 *
  11 *      The author may be reached as becker@scyld.com, or C/O
  12 *      Scyld Computing Corporation
  13 *      410 Severn Ave., Suite 210
  14 *      Annapolis MD 21403
  15 *
  16 *      This file is an outline for writing a network device driver for the
  17 *      the Linux operating system.
  18 *
  19 *      To write (or understand) a driver, have a look at the "loopback.c" file to
  20 *      get a feel of what is going on, and then use the code below as a skeleton
  21 *      for the new driver.
  22 *
  23 */
  24
  25static const char *version =
  26        "isa-skeleton.c:v1.51 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
  27
  28/*
  29 *  Sources:
  30 *      List your sources of programming information to document that
  31 *      the driver is your own creation, and give due credit to others
  32 *      that contributed to the work. Remember that GNU project code
  33 *      cannot use proprietary or trade secret information. Interface
  34 *      definitions are generally considered non-copyrightable to the
  35 *      extent that the same names and structures must be used to be
  36 *      compatible.
  37 *
  38 *      Finally, keep in mind that the Linux kernel is has an API, not
  39 *      ABI. Proprietary object-code-only distributions are not permitted
  40 *      under the GPL.
  41 */
  42
  43#include <linux/module.h>
  44#include <linux/kernel.h>
  45#include <linux/types.h>
  46#include <linux/fcntl.h>
  47#include <linux/interrupt.h>
  48#include <linux/ioport.h>
  49#include <linux/in.h>
  50#include <linux/slab.h>
  51#include <linux/string.h>
  52#include <linux/spinlock.h>
  53#include <linux/errno.h>
  54#include <linux/init.h>
  55#include <linux/netdevice.h>
  56#include <linux/etherdevice.h>
  57#include <linux/skbuff.h>
  58#include <linux/bitops.h>
  59
  60#include <asm/system.h>
  61#include <asm/io.h>
  62#include <asm/dma.h>
  63
  64/*
  65 * The name of the card. Is used for messages and in the requests for
  66 * io regions, irqs and dma channels
  67 */
  68static const char* cardname = "netcard";
  69
  70/* First, a few definitions that the brave might change. */
  71
  72/* A zero-terminated list of I/O addresses to be probed. */
  73static unsigned int netcard_portlist[] __initdata =
  74   { 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
  75
  76/* use 0 for production, 1 for verification, >2 for debug */
  77#ifndef NET_DEBUG
  78#define NET_DEBUG 2
  79#endif
  80static unsigned int net_debug = NET_DEBUG;
  81
  82/* The number of low I/O ports used by the ethercard. */
  83#define NETCARD_IO_EXTENT       32
  84
  85#define MY_TX_TIMEOUT  ((400*HZ)/1000)
  86
  87/* Information that need to be kept for each board. */
  88struct net_local {
  89        struct net_device_stats stats;
  90        long open_time;                 /* Useless example local info. */
  91
  92        /* Tx control lock.  This protects the transmit buffer ring
  93         * state along with the "tx full" state of the driver.  This
  94         * means all netif_queue flow control actions are protected
  95         * by this lock as well.
  96         */
  97        spinlock_t lock;
  98};
  99
 100/* The station (ethernet) address prefix, used for IDing the board. */
 101#define SA_ADDR0 0x00
 102#define SA_ADDR1 0x42
 103#define SA_ADDR2 0x65
 104
 105/* Index to functions, as function prototypes. */
 106
 107static int      netcard_probe1(struct net_device *dev, int ioaddr);
 108static int      net_open(struct net_device *dev);
 109static int      net_send_packet(struct sk_buff *skb, struct net_device *dev);
 110static irqreturn_t net_interrupt(int irq, void *dev_id);
 111static void     net_rx(struct net_device *dev);
 112static int      net_close(struct net_device *dev);
 113static struct   net_device_stats *net_get_stats(struct net_device *dev);
 114static void     set_multicast_list(struct net_device *dev);
 115static void     net_tx_timeout(struct net_device *dev);
 116
 117
 118/* Example routines you must write ;->. */
 119#define tx_done(dev) 1
 120static void     hardware_send_packet(short ioaddr, char *buf, int length);
 121static void     chipset_init(struct net_device *dev, int startp);
 122
 123/*
 124 * Check for a network adaptor of this type, and return '0' iff one exists.
 125 * If dev->base_addr == 0, probe all likely locations.
 126 * If dev->base_addr == 1, always return failure.
 127 * If dev->base_addr == 2, allocate space for the device and return success
 128 * (detachable devices only).
 129 */
 130static int __init do_netcard_probe(struct net_device *dev)
 131{
 132        int i;
 133        int base_addr = dev->base_addr;
 134        int irq = dev->irq;
 135
 136        if (base_addr > 0x1ff)    /* Check a single specified location. */
 137                return netcard_probe1(dev, base_addr);
 138        else if (base_addr != 0)  /* Don't probe at all. */
 139                return -ENXIO;
 140
 141        for (i = 0; netcard_portlist[i]; i++) {
 142                int ioaddr = netcard_portlist[i];
 143                if (netcard_probe1(dev, ioaddr) == 0)
 144                        return 0;
 145                dev->irq = irq;
 146        }
 147
 148        return -ENODEV;
 149}
 150
 151static void cleanup_card(struct net_device *dev)
 152{
 153#ifdef jumpered_dma
 154        free_dma(dev->dma);
 155#endif
 156#ifdef jumpered_interrupts
 157        free_irq(dev->irq, dev);
 158#endif
 159        release_region(dev->base_addr, NETCARD_IO_EXTENT);
 160}
 161
 162#ifndef MODULE
 163struct net_device * __init netcard_probe(int unit)
 164{
 165        struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
 166        int err;
 167
 168        if (!dev)
 169                return ERR_PTR(-ENOMEM);
 170
 171        sprintf(dev->name, "eth%d", unit);
 172        netdev_boot_setup_check(dev);
 173
 174        err = do_netcard_probe(dev);
 175        if (err)
 176                goto out;
 177        return dev;
 178out:
 179        free_netdev(dev);
 180        return ERR_PTR(err);
 181}
 182#endif
 183
 184static const struct net_device_ops netcard_netdev_ops = {
 185        .ndo_open               = net_open,
 186        .ndo_stop               = net_close,
 187        .ndo_start_xmit         = net_send_packet,
 188        .ndo_get_stats          = net_get_stats,
 189        .ndo_set_multicast_list = set_multicast_list,
 190        .ndo_tx_timeout         = net_tx_timeout,
 191        .ndo_validate_addr      = eth_validate_addr,
 192        .ndo_set_mac_address    = eth_mac_addr,
 193        .ndo_change_mtu         = eth_change_mtu,
 194};
 195
 196/*
 197 * This is the real probe routine. Linux has a history of friendly device
 198 * probes on the ISA bus. A good device probes avoids doing writes, and
 199 * verifies that the correct device exists and functions.
 200 */
 201static int __init netcard_probe1(struct net_device *dev, int ioaddr)
 202{
 203        struct net_local *np;
 204        static unsigned version_printed;
 205        int i;
 206        int err = -ENODEV;
 207
 208        /* Grab the region so that no one else tries to probe our ioports. */
 209        if (!request_region(ioaddr, NETCARD_IO_EXTENT, cardname))
 210                return -EBUSY;
 211
 212        /*
 213         * For ethernet adaptors the first three octets of the station address
 214         * contains the manufacturer's unique code. That might be a good probe
 215         * method. Ideally you would add additional checks.
 216         */
 217        if (inb(ioaddr + 0) != SA_ADDR0
 218                ||       inb(ioaddr + 1) != SA_ADDR1
 219                ||       inb(ioaddr + 2) != SA_ADDR2)
 220                goto out;
 221
 222        if (net_debug  &&  version_printed++ == 0)
 223                printk(KERN_DEBUG "%s", version);
 224
 225        printk(KERN_INFO "%s: %s found at %#3x, ", dev->name, cardname, ioaddr);
 226
 227        /* Fill in the 'dev' fields. */
 228        dev->base_addr = ioaddr;
 229
 230        /* Retrieve and print the ethernet address. */
 231        for (i = 0; i < 6; i++)
 232                dev->dev_addr[i] = inb(ioaddr + i);
 233
 234        printk("%pM", dev->dev_addr);
 235
 236        err = -EAGAIN;
 237#ifdef jumpered_interrupts
 238        /*
 239         * If this board has jumpered interrupts, allocate the interrupt
 240         * vector now. There is no point in waiting since no other device
 241         * can use the interrupt, and this marks the irq as busy. Jumpered
 242         * interrupts are typically not reported by the boards, and we must
 243         * used autoIRQ to find them.
 244         */
 245
 246        if (dev->irq == -1)
 247                ;       /* Do nothing: a user-level program will set it. */
 248        else if (dev->irq < 2) {        /* "Auto-IRQ" */
 249                unsigned long irq_mask = probe_irq_on();
 250                /* Trigger an interrupt here. */
 251
 252                dev->irq = probe_irq_off(irq_mask);
 253                if (net_debug >= 2)
 254                        printk(" autoirq is %d", dev->irq);
 255        } else if (dev->irq == 2)
 256                /*
 257                 * Fixup for users that don't know that IRQ 2 is really
 258                 * IRQ9, or don't know which one to set.
 259                 */
 260                dev->irq = 9;
 261
 262        {
 263                int irqval = request_irq(dev->irq, &net_interrupt, 0, cardname, dev);
 264                if (irqval) {
 265                        printk("%s: unable to get IRQ %d (irqval=%d).\n",
 266                                   dev->name, dev->irq, irqval);
 267                        goto out;
 268                }
 269        }
 270#endif  /* jumpered interrupt */
 271#ifdef jumpered_dma
 272        /*
 273         * If we use a jumpered DMA channel, that should be probed for and
 274         * allocated here as well. See lance.c for an example.
 275         */
 276        if (dev->dma == 0) {
 277                if (request_dma(dev->dma, cardname)) {
 278                        printk("DMA %d allocation failed.\n", dev->dma);
 279                        goto out1;
 280                } else
 281                        printk(", assigned DMA %d.\n", dev->dma);
 282        } else {
 283                short dma_status, new_dma_status;
 284
 285                /* Read the DMA channel status registers. */
 286                dma_status = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
 287                        (inb(DMA2_STAT_REG) & 0xf0);
 288                /* Trigger a DMA request, perhaps pause a bit. */
 289                outw(0x1234, ioaddr + 8);
 290                /* Re-read the DMA status registers. */
 291                new_dma_status = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
 292                        (inb(DMA2_STAT_REG) & 0xf0);
 293                /*
 294                 * Eliminate the old and floating requests,
 295                 * and DMA4 the cascade.
 296                 */
 297                new_dma_status ^= dma_status;
 298                new_dma_status &= ~0x10;
 299                for (i = 7; i > 0; i--)
 300                        if (test_bit(i, &new_dma_status)) {
 301                                dev->dma = i;
 302                                break;
 303                        }
 304                if (i <= 0) {
 305                        printk("DMA probe failed.\n");
 306                        goto out1;
 307                }
 308                if (request_dma(dev->dma, cardname)) {
 309                        printk("probed DMA %d allocation failed.\n", dev->dma);
 310                        goto out1;
 311                }
 312        }
 313#endif  /* jumpered DMA */
 314
 315        np = netdev_priv(dev);
 316        spin_lock_init(&np->lock);
 317
 318        dev->netdev_ops         = &netcard_netdev_ops;
 319        dev->watchdog_timeo     = MY_TX_TIMEOUT;
 320
 321        err = register_netdev(dev);
 322        if (err)
 323                goto out2;
 324        return 0;
 325out2:
 326#ifdef jumpered_dma
 327        free_dma(dev->dma);
 328#endif
 329out1:
 330#ifdef jumpered_interrupts
 331        free_irq(dev->irq, dev);
 332#endif
 333out:
 334        release_region(base_addr, NETCARD_IO_EXTENT);
 335        return err;
 336}
 337
 338static void net_tx_timeout(struct net_device *dev)
 339{
 340        struct net_local *np = netdev_priv(dev);
 341
 342        printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
 343               tx_done(dev) ? "IRQ conflict" : "network cable problem");
 344
 345        /* Try to restart the adaptor. */
 346        chipset_init(dev, 1);
 347
 348        np->stats.tx_errors++;
 349
 350        /* If we have space available to accept new transmit
 351         * requests, wake up the queueing layer.  This would
 352         * be the case if the chipset_init() call above just
 353         * flushes out the tx queue and empties it.
 354         *
 355         * If instead, the tx queue is retained then the
 356         * netif_wake_queue() call should be placed in the
 357         * TX completion interrupt handler of the driver instead
 358         * of here.
 359         */
 360        if (!tx_full(dev))
 361                netif_wake_queue(dev);
 362}
 363
 364/*
 365 * Open/initialize the board. This is called (in the current kernel)
 366 * sometime after booting when the 'ifconfig' program is run.
 367 *
 368 * This routine should set everything up anew at each open, even
 369 * registers that "should" only need to be set once at boot, so that
 370 * there is non-reboot way to recover if something goes wrong.
 371 */
 372static int
 373net_open(struct net_device *dev)
 374{
 375        struct net_local *np = netdev_priv(dev);
 376        int ioaddr = dev->base_addr;
 377        /*
 378         * This is used if the interrupt line can turned off (shared).
 379         * See 3c503.c for an example of selecting the IRQ at config-time.
 380         */
 381        if (request_irq(dev->irq, &net_interrupt, 0, cardname, dev)) {
 382                return -EAGAIN;
 383        }
 384        /*
 385         * Always allocate the DMA channel after the IRQ,
 386         * and clean up on failure.
 387         */
 388        if (request_dma(dev->dma, cardname)) {
 389                free_irq(dev->irq, dev);
 390                return -EAGAIN;
 391        }
 392
 393        /* Reset the hardware here. Don't forget to set the station address. */
 394        chipset_init(dev, 1);
 395        outb(0x00, ioaddr);
 396        np->open_time = jiffies;
 397
 398        /* We are now ready to accept transmit requeusts from
 399         * the queueing layer of the networking.
 400         */
 401        netif_start_queue(dev);
 402
 403        return 0;
 404}
 405
 406/* This will only be invoked if your driver is _not_ in XOFF state.
 407 * What this means is that you need not check it, and that this
 408 * invariant will hold if you make sure that the netif_*_queue()
 409 * calls are done at the proper times.
 410 */
 411static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
 412{
 413        struct net_local *np = netdev_priv(dev);
 414        int ioaddr = dev->base_addr;
 415        short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 416        unsigned char *buf = skb->data;
 417
 418        /* If some error occurs while trying to transmit this
 419         * packet, you should return '1' from this function.
 420         * In such a case you _may not_ do anything to the
 421         * SKB, it is still owned by the network queueing
 422         * layer when an error is returned.  This means you
 423         * may not modify any SKB fields, you may not free
 424         * the SKB, etc.
 425         */
 426
 427#if TX_RING
 428        /* This is the most common case for modern hardware.
 429         * The spinlock protects this code from the TX complete
 430         * hardware interrupt handler.  Queue flow control is
 431         * thus managed under this lock as well.
 432         */
 433        unsigned long flags;
 434        spin_lock_irqsave(&np->lock, flags);
 435
 436        add_to_tx_ring(np, skb, length);
 437        dev->trans_start = jiffies;
 438
 439        /* If we just used up the very last entry in the
 440         * TX ring on this device, tell the queueing
 441         * layer to send no more.
 442         */
 443        if (tx_full(dev))
 444                netif_stop_queue(dev);
 445
 446        /* When the TX completion hw interrupt arrives, this
 447         * is when the transmit statistics are updated.
 448         */
 449
 450        spin_unlock_irqrestore(&np->lock, flags);
 451#else
 452        /* This is the case for older hardware which takes
 453         * a single transmit buffer at a time, and it is
 454         * just written to the device via PIO.
 455         *
 456         * No spin locking is needed since there is no TX complete
 457         * event.  If by chance your card does have a TX complete
 458         * hardware IRQ then you may need to utilize np->lock here.
 459         */
 460        hardware_send_packet(ioaddr, buf, length);
 461        np->stats.tx_bytes += skb->len;
 462
 463        dev->trans_start = jiffies;
 464
 465        /* You might need to clean up and record Tx statistics here. */
 466        if (inw(ioaddr) == /*RU*/81)
 467                np->stats.tx_aborted_errors++;
 468        dev_kfree_skb (skb);
 469#endif
 470
 471        return NETDEV_TX_OK;
 472}
 473
 474#if TX_RING
 475/* This handles TX complete events posted by the device
 476 * via interrupts.
 477 */
 478void net_tx(struct net_device *dev)
 479{
 480        struct net_local *np = netdev_priv(dev);
 481        int entry;
 482
 483        /* This protects us from concurrent execution of
 484         * our dev->hard_start_xmit function above.
 485         */
 486        spin_lock(&np->lock);
 487
 488        entry = np->tx_old;
 489        while (tx_entry_is_sent(np, entry)) {
 490                struct sk_buff *skb = np->skbs[entry];
 491
 492                np->stats.tx_bytes += skb->len;
 493                dev_kfree_skb_irq (skb);
 494
 495                entry = next_tx_entry(np, entry);
 496        }
 497        np->tx_old = entry;
 498
 499        /* If we had stopped the queue due to a "tx full"
 500         * condition, and space has now been made available,
 501         * wake up the queue.
 502         */
 503        if (netif_queue_stopped(dev) && ! tx_full(dev))
 504                netif_wake_queue(dev);
 505
 506        spin_unlock(&np->lock);
 507}
 508#endif
 509
 510/*
 511 * The typical workload of the driver:
 512 * Handle the network interface interrupts.
 513 */
 514static irqreturn_t net_interrupt(int irq, void *dev_id)
 515{
 516        struct net_device *dev = dev_id;
 517        struct net_local *np;
 518        int ioaddr, status;
 519        int handled = 0;
 520
 521        ioaddr = dev->base_addr;
 522
 523        np = netdev_priv(dev);
 524        status = inw(ioaddr + 0);
 525
 526        if (status == 0)
 527                goto out;
 528        handled = 1;
 529
 530        if (status & RX_INTR) {
 531                /* Got a packet(s). */
 532                net_rx(dev);
 533        }
 534#if TX_RING
 535        if (status & TX_INTR) {
 536                /* Transmit complete. */
 537                net_tx(dev);
 538                np->stats.tx_packets++;
 539                netif_wake_queue(dev);
 540        }
 541#endif
 542        if (status & COUNTERS_INTR) {
 543                /* Increment the appropriate 'localstats' field. */
 544                np->stats.tx_window_errors++;
 545        }
 546out:
 547        return IRQ_RETVAL(handled);
 548}
 549
 550/* We have a good packet(s), get it/them out of the buffers. */
 551static void
 552net_rx(struct net_device *dev)
 553{
 554        struct net_local *lp = netdev_priv(dev);
 555        int ioaddr = dev->base_addr;
 556        int boguscount = 10;
 557
 558        do {
 559                int status = inw(ioaddr);
 560                int pkt_len = inw(ioaddr);
 561
 562                if (pkt_len == 0)               /* Read all the frames? */
 563                        break;                  /* Done for now */
 564
 565                if (status & 0x40) {    /* There was an error. */
 566                        lp->stats.rx_errors++;
 567                        if (status & 0x20) lp->stats.rx_frame_errors++;
 568                        if (status & 0x10) lp->stats.rx_over_errors++;
 569                        if (status & 0x08) lp->stats.rx_crc_errors++;
 570                        if (status & 0x04) lp->stats.rx_fifo_errors++;
 571                } else {
 572                        /* Malloc up new buffer. */
 573                        struct sk_buff *skb;
 574
 575                        lp->stats.rx_bytes+=pkt_len;
 576
 577                        skb = dev_alloc_skb(pkt_len);
 578                        if (skb == NULL) {
 579                                printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
 580                                           dev->name);
 581                                lp->stats.rx_dropped++;
 582                                break;
 583                        }
 584                        skb->dev = dev;
 585
 586                        /* 'skb->data' points to the start of sk_buff data area. */
 587                        memcpy(skb_put(skb,pkt_len), (void*)dev->rmem_start,
 588                                   pkt_len);
 589                        /* or */
 590                        insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
 591
 592                        netif_rx(skb);
 593                        lp->stats.rx_packets++;
 594                        lp->stats.rx_bytes += pkt_len;
 595                }
 596        } while (--boguscount);
 597
 598        return;
 599}
 600
 601/* The inverse routine to net_open(). */
 602static int
 603net_close(struct net_device *dev)
 604{
 605        struct net_local *lp = netdev_priv(dev);
 606        int ioaddr = dev->base_addr;
 607
 608        lp->open_time = 0;
 609
 610        netif_stop_queue(dev);
 611
 612        /* Flush the Tx and disable Rx here. */
 613
 614        disable_dma(dev->dma);
 615
 616        /* If not IRQ or DMA jumpered, free up the line. */
 617        outw(0x00, ioaddr+0);   /* Release the physical interrupt line. */
 618
 619        free_irq(dev->irq, dev);
 620        free_dma(dev->dma);
 621
 622        /* Update the statistics here. */
 623
 624        return 0;
 625
 626}
 627
 628/*
 629 * Get the current statistics.
 630 * This may be called with the card open or closed.
 631 */
 632static struct net_device_stats *net_get_stats(struct net_device *dev)
 633{
 634        struct net_local *lp = netdev_priv(dev);
 635        short ioaddr = dev->base_addr;
 636
 637        /* Update the statistics from the device registers. */
 638        lp->stats.rx_missed_errors = inw(ioaddr+1);
 639        return &lp->stats;
 640}
 641
 642/*
 643 * Set or clear the multicast filter for this adaptor.
 644 * num_addrs == -1      Promiscuous mode, receive all packets
 645 * num_addrs == 0       Normal mode, clear multicast list
 646 * num_addrs > 0        Multicast mode, receive normal and MC packets,
 647 *                      and do best-effort filtering.
 648 */
 649static void
 650set_multicast_list(struct net_device *dev)
 651{
 652        short ioaddr = dev->base_addr;
 653        if (dev->flags&IFF_PROMISC)
 654        {
 655                /* Enable promiscuous mode */
 656                outw(MULTICAST|PROMISC, ioaddr);
 657        }
 658        else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS)
 659        {
 660                /* Disable promiscuous mode, use normal mode. */
 661                hardware_set_filter(NULL);
 662
 663                outw(MULTICAST, ioaddr);
 664        }
 665        else if(dev->mc_count)
 666        {
 667                /* Walk the address list, and load the filter */
 668                hardware_set_filter(dev->mc_list);
 669
 670                outw(MULTICAST, ioaddr);
 671        }
 672        else
 673                outw(0, ioaddr);
 674}
 675
 676#ifdef MODULE
 677
 678static struct net_device *this_device;
 679static int io = 0x300;
 680static int irq;
 681static int dma;
 682static int mem;
 683MODULE_LICENSE("GPL");
 684
 685int init_module(void)
 686{
 687        struct net_device *dev;
 688        int result;
 689
 690        if (io == 0)
 691                printk(KERN_WARNING "%s: You shouldn't use auto-probing with insmod!\n",
 692                           cardname);
 693        dev = alloc_etherdev(sizeof(struct net_local));
 694        if (!dev)
 695                return -ENOMEM;
 696
 697        /* Copy the parameters from insmod into the device structure. */
 698        dev->base_addr = io;
 699        dev->irq       = irq;
 700        dev->dma       = dma;
 701        dev->mem_start = mem;
 702        if (do_netcard_probe(dev) == 0) {
 703                this_device = dev;
 704                return 0;
 705        }
 706        free_netdev(dev);
 707        return -ENXIO;
 708}
 709
 710void
 711cleanup_module(void)
 712{
 713        unregister_netdev(this_device);
 714        cleanup_card(this_device);
 715        free_netdev(this_device);
 716}
 717
 718#endif /* MODULE */
 719