davinci*/tlan/cpmac: Move the Texas Instruments (TI) drivers
[sfrench/cifs-2.6.git] / drivers / net / tlan.c
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
deleted file mode 100644 (file)
index 145871b..0000000
+++ /dev/null
@@ -1,3258 +0,0 @@
-/*******************************************************************************
- *
- *  Linux ThunderLAN Driver
- *
- *  tlan.c
- *  by James Banks
- *
- *  (C) 1997-1998 Caldera, Inc.
- *  (C) 1998 James Banks
- *  (C) 1999-2001 Torben Mathiasen
- *  (C) 2002 Samuel Chessman
- *
- *  This software may be used and distributed according to the terms
- *  of the GNU General Public License, incorporated herein by reference.
- *
- ** Useful (if not required) reading:
- *
- *             Texas Instruments, ThunderLAN Programmer's Guide,
- *                     TI Literature Number SPWU013A
- *                     available in PDF format from www.ti.com
- *             Level One, LXT901 and LXT970 Data Sheets
- *                     available in PDF format from www.level1.com
- *             National Semiconductor, DP83840A Data Sheet
- *                     available in PDF format from www.national.com
- *             Microchip Technology, 24C01A/02A/04A Data Sheet
- *                     available in PDF format from www.microchip.com
- *
- ******************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/hardirq.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/eisa.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-
-#include "tlan.h"
-
-
-/* For removing EISA devices */
-static struct net_device       *tlan_eisa_devices;
-
-static int             tlan_devices_installed;
-
-/* Set speed, duplex and aui settings */
-static  int aui[MAX_TLAN_BOARDS];
-static  int duplex[MAX_TLAN_BOARDS];
-static  int speed[MAX_TLAN_BOARDS];
-static  int boards_found;
-module_param_array(aui, int, NULL, 0);
-module_param_array(duplex, int, NULL, 0);
-module_param_array(speed, int, NULL, 0);
-MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
-MODULE_PARM_DESC(duplex,
-                "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
-MODULE_PARM_DESC(speed, "ThunderLAN port speed setting(s) (0,10,100)");
-
-MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
-MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
-MODULE_LICENSE("GPL");
-
-
-/* Define this to enable Link beat monitoring */
-#undef MONITOR
-
-/* Turn on debugging. See Documentation/networking/tlan.txt for details */
-static  int            debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
-
-static const char tlan_signature[] = "TLAN";
-static  const char tlan_banner[] = "ThunderLAN driver v1.17\n";
-static  int tlan_have_pci;
-static  int tlan_have_eisa;
-
-static const char * const media[] = {
-       "10BaseT-HD", "10BaseT-FD", "100baseTx-HD",
-       "100BaseTx-FD", "100BaseT4", NULL
-};
-
-static struct board {
-       const char      *device_label;
-       u32             flags;
-       u16             addr_ofs;
-} board_info[] = {
-       { "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
-       { "Compaq Netelligent 10/100 TX PCI UTP",
-         TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
-       { "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
-       { "Compaq NetFlex-3/P",
-         TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
-       { "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
-       { "Compaq Netelligent Integrated 10/100 TX UTP",
-         TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
-       { "Compaq Netelligent Dual 10/100 TX PCI UTP",
-         TLAN_ADAPTER_NONE, 0x83 },
-       { "Compaq Netelligent 10/100 TX Embedded UTP",
-         TLAN_ADAPTER_NONE, 0x83 },
-       { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
-       { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 },
-       { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xf8 },
-       { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
-       { "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 },
-       { "Compaq NetFlex-3/E",
-         TLAN_ADAPTER_ACTIVITY_LED |   /* EISA card */
-         TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
-       { "Compaq NetFlex-3/E",
-         TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
-};
-
-static DEFINE_PCI_DEVICE_TABLE(tlan_pci_tbl) = {
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
-       { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-       { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
-       { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
-       { 0,}
-};
-MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);
-
-static void    tlan_eisa_probe(void);
-static void    tlan_eisa_cleanup(void);
-static int      tlan_init(struct net_device *);
-static int     tlan_open(struct net_device *dev);
-static netdev_tx_t tlan_start_tx(struct sk_buff *, struct net_device *);
-static irqreturn_t tlan_handle_interrupt(int, void *);
-static int     tlan_close(struct net_device *);
-static struct  net_device_stats *tlan_get_stats(struct net_device *);
-static void    tlan_set_multicast_list(struct net_device *);
-static int     tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int      tlan_probe1(struct pci_dev *pdev, long ioaddr,
-                           int irq, int rev, const struct pci_device_id *ent);
-static void    tlan_tx_timeout(struct net_device *dev);
-static void    tlan_tx_timeout_work(struct work_struct *work);
-static int     tlan_init_one(struct pci_dev *pdev,
-                             const struct pci_device_id *ent);
-
-static u32     tlan_handle_tx_eof(struct net_device *, u16);
-static u32     tlan_handle_stat_overflow(struct net_device *, u16);
-static u32     tlan_handle_rx_eof(struct net_device *, u16);
-static u32     tlan_handle_dummy(struct net_device *, u16);
-static u32     tlan_handle_tx_eoc(struct net_device *, u16);
-static u32     tlan_handle_status_check(struct net_device *, u16);
-static u32     tlan_handle_rx_eoc(struct net_device *, u16);
-
-static void    tlan_timer(unsigned long);
-
-static void    tlan_reset_lists(struct net_device *);
-static void    tlan_free_lists(struct net_device *);
-static void    tlan_print_dio(u16);
-static void    tlan_print_list(struct tlan_list *, char *, int);
-static void    tlan_read_and_clear_stats(struct net_device *, int);
-static void    tlan_reset_adapter(struct net_device *);
-static void    tlan_finish_reset(struct net_device *);
-static void    tlan_set_mac(struct net_device *, int areg, char *mac);
-
-static void    tlan_phy_print(struct net_device *);
-static void    tlan_phy_detect(struct net_device *);
-static void    tlan_phy_power_down(struct net_device *);
-static void    tlan_phy_power_up(struct net_device *);
-static void    tlan_phy_reset(struct net_device *);
-static void    tlan_phy_start_link(struct net_device *);
-static void    tlan_phy_finish_auto_neg(struct net_device *);
-#ifdef MONITOR
-static void     tlan_phy_monitor(struct net_device *);
-#endif
-
-/*
-  static int   tlan_phy_nop(struct net_device *);
-  static int   tlan_phy_internal_check(struct net_device *);
-  static int   tlan_phy_internal_service(struct net_device *);
-  static int   tlan_phy_dp83840a_check(struct net_device *);
-*/
-
-static bool    tlan_mii_read_reg(struct net_device *, u16, u16, u16 *);
-static void    tlan_mii_send_data(u16, u32, unsigned);
-static void    tlan_mii_sync(u16);
-static void    tlan_mii_write_reg(struct net_device *, u16, u16, u16);
-
-static void    tlan_ee_send_start(u16);
-static int     tlan_ee_send_byte(u16, u8, int);
-static void    tlan_ee_receive_byte(u16, u8 *, int);
-static int     tlan_ee_read_byte(struct net_device *, u8, u8 *);
-
-
-static inline void
-tlan_store_skb(struct tlan_list *tag, struct sk_buff *skb)
-{
-       unsigned long addr = (unsigned long)skb;
-       tag->buffer[9].address = addr;
-       tag->buffer[8].address = upper_32_bits(addr);
-}
-
-static inline struct sk_buff *
-tlan_get_skb(const struct tlan_list *tag)
-{
-       unsigned long addr;
-
-       addr = tag->buffer[9].address;
-       addr |= (tag->buffer[8].address << 16) << 16;
-       return (struct sk_buff *) addr;
-}
-
-static u32
-(*tlan_int_vector[TLAN_INT_NUMBER_OF_INTS])(struct net_device *, u16) = {
-       NULL,
-       tlan_handle_tx_eof,
-       tlan_handle_stat_overflow,
-       tlan_handle_rx_eof,
-       tlan_handle_dummy,
-       tlan_handle_tx_eoc,
-       tlan_handle_status_check,
-       tlan_handle_rx_eoc
-};
-
-static inline void
-tlan_set_timer(struct net_device *dev, u32 ticks, u32 type)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-       unsigned long flags = 0;
-
-       if (!in_irq())
-               spin_lock_irqsave(&priv->lock, flags);
-       if (priv->timer.function != NULL &&
-           priv->timer_type != TLAN_TIMER_ACTIVITY) {
-               if (!in_irq())
-                       spin_unlock_irqrestore(&priv->lock, flags);
-               return;
-       }
-       priv->timer.function = tlan_timer;
-       if (!in_irq())
-               spin_unlock_irqrestore(&priv->lock, flags);
-
-       priv->timer.data = (unsigned long) dev;
-       priv->timer_set_at = jiffies;
-       priv->timer_type = type;
-       mod_timer(&priv->timer, jiffies + ticks);
-
-}
-
-
-/*****************************************************************************
-******************************************************************************
-
-ThunderLAN driver primary functions
-
-these functions are more or less common to all linux network drivers.
-
-******************************************************************************
-*****************************************************************************/
-
-
-
-
-
-/***************************************************************
- *     tlan_remove_one
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             None
- *
- *     Goes through the TLanDevices list and frees the device
- *     structs and memory associated with each device (lists
- *     and buffers).  It also ureserves the IO port regions
- *     associated with this device.
- *
- **************************************************************/
-
-
-static void __devexit tlan_remove_one(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct tlan_priv        *priv = netdev_priv(dev);
-
-       unregister_netdev(dev);
-
-       if (priv->dma_storage) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->dma_size, priv->dma_storage,
-                                   priv->dma_storage_dma);
-       }
-
-#ifdef CONFIG_PCI
-       pci_release_regions(pdev);
-#endif
-
-       free_netdev(dev);
-
-       pci_set_drvdata(pdev, NULL);
-}
-
-static void tlan_start(struct net_device *dev)
-{
-       tlan_reset_lists(dev);
-       /* NOTE: It might not be necessary to read the stats before a
-          reset if you don't care what the values are.
-       */
-       tlan_read_and_clear_stats(dev, TLAN_IGNORE);
-       tlan_reset_adapter(dev);
-       netif_wake_queue(dev);
-}
-
-static void tlan_stop(struct net_device *dev)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-
-       tlan_read_and_clear_stats(dev, TLAN_RECORD);
-       outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
-       /* Reset and power down phy */
-       tlan_reset_adapter(dev);
-       if (priv->timer.function != NULL) {
-               del_timer_sync(&priv->timer);
-               priv->timer.function = NULL;
-       }
-}
-
-#ifdef CONFIG_PM
-
-static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-
-       if (netif_running(dev))
-               tlan_stop(dev);
-
-       netif_device_detach(dev);
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_wake_from_d3(pdev, false);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       return 0;
-}
-
-static int tlan_resume(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       pci_enable_wake(pdev, 0, 0);
-       netif_device_attach(dev);
-
-       if (netif_running(dev))
-               tlan_start(dev);
-
-       return 0;
-}
-
-#else /* CONFIG_PM */
-
-#define tlan_suspend   NULL
-#define tlan_resume    NULL
-
-#endif /* CONFIG_PM */
-
-
-static struct pci_driver tlan_driver = {
-       .name           = "tlan",
-       .id_table       = tlan_pci_tbl,
-       .probe          = tlan_init_one,
-       .remove         = __devexit_p(tlan_remove_one),
-       .suspend        = tlan_suspend,
-       .resume         = tlan_resume,
-};
-
-static int __init tlan_probe(void)
-{
-       int rc = -ENODEV;
-
-       pr_info("%s", tlan_banner);
-
-       TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
-
-       /* Use new style PCI probing. Now the kernel will
-          do most of this for us */
-       rc = pci_register_driver(&tlan_driver);
-
-       if (rc != 0) {
-               pr_err("Could not register pci driver\n");
-               goto err_out_pci_free;
-       }
-
-       TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
-       tlan_eisa_probe();
-
-       pr_info("%d device%s installed, PCI: %d  EISA: %d\n",
-               tlan_devices_installed, tlan_devices_installed == 1 ? "" : "s",
-               tlan_have_pci, tlan_have_eisa);
-
-       if (tlan_devices_installed == 0) {
-               rc = -ENODEV;
-               goto  err_out_pci_unreg;
-       }
-       return 0;
-
-err_out_pci_unreg:
-       pci_unregister_driver(&tlan_driver);
-err_out_pci_free:
-       return rc;
-}
-
-
-static int __devinit tlan_init_one(struct pci_dev *pdev,
-                                  const struct pci_device_id *ent)
-{
-       return tlan_probe1(pdev, -1, -1, 0, ent);
-}
-
-
-/*
-***************************************************************
-*      tlan_probe1
-*
-*      Returns:
-*              0 on success, error code on error
-*      Parms:
-*              none
-*
-*      The name is lower case to fit in with all the rest of
-*      the netcard_probe names.  This function looks for
-*      another TLan based adapter, setting it up with the
-*      allocated device struct if one is found.
-*      tlan_probe has been ported to the new net API and
-*      now allocates its own device structure. This function
-*      is also used by modules.
-*
-**************************************************************/
-
-static int __devinit tlan_probe1(struct pci_dev *pdev,
-                                long ioaddr, int irq, int rev,
-                                const struct pci_device_id *ent)
-{
-
-       struct net_device  *dev;
-       struct tlan_priv  *priv;
-       u16                device_id;
-       int                reg, rc = -ENODEV;
-
-#ifdef CONFIG_PCI
-       if (pdev) {
-               rc = pci_enable_device(pdev);
-               if (rc)
-                       return rc;
-
-               rc = pci_request_regions(pdev, tlan_signature);
-               if (rc) {
-                       pr_err("Could not reserve IO regions\n");
-                       goto err_out;
-               }
-       }
-#endif  /*  CONFIG_PCI  */
-
-       dev = alloc_etherdev(sizeof(struct tlan_priv));
-       if (dev == NULL) {
-               pr_err("Could not allocate memory for device\n");
-               rc = -ENOMEM;
-               goto err_out_regions;
-       }
-       SET_NETDEV_DEV(dev, &pdev->dev);
-
-       priv = netdev_priv(dev);
-
-       priv->pci_dev = pdev;
-       priv->dev = dev;
-
-       /* Is this a PCI device? */
-       if (pdev) {
-               u32                pci_io_base = 0;
-
-               priv->adapter = &board_info[ent->driver_data];
-
-               rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-               if (rc) {
-                       pr_err("No suitable PCI mapping available\n");
-                       goto err_out_free_dev;
-               }
-
-               for (reg = 0; reg <= 5; reg++) {
-                       if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
-                               pci_io_base = pci_resource_start(pdev, reg);
-                               TLAN_DBG(TLAN_DEBUG_GNRL,
-                                        "IO mapping is available at %x.\n",
-                                        pci_io_base);
-                               break;
-                       }
-               }
-               if (!pci_io_base) {
-                       pr_err("No IO mappings available\n");
-                       rc = -EIO;
-                       goto err_out_free_dev;
-               }
-
-               dev->base_addr = pci_io_base;
-               dev->irq = pdev->irq;
-               priv->adapter_rev = pdev->revision;
-               pci_set_master(pdev);
-               pci_set_drvdata(pdev, dev);
-
-       } else  {     /* EISA card */
-               /* This is a hack. We need to know which board structure
-                * is suited for this adapter */
-               device_id = inw(ioaddr + EISA_ID2);
-               priv->is_eisa = 1;
-               if (device_id == 0x20F1) {
-                       priv->adapter = &board_info[13]; /* NetFlex-3/E */
-                       priv->adapter_rev = 23;         /* TLAN 2.3 */
-               } else {
-                       priv->adapter = &board_info[14];
-                       priv->adapter_rev = 10;         /* TLAN 1.0 */
-               }
-               dev->base_addr = ioaddr;
-               dev->irq = irq;
-       }
-
-       /* Kernel parameters */
-       if (dev->mem_start) {
-               priv->aui    = dev->mem_start & 0x01;
-               priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0
-                       : (dev->mem_start & 0x06) >> 1;
-               priv->speed  = ((dev->mem_start & 0x18) == 0x18) ? 0
-                       : (dev->mem_start & 0x18) >> 3;
-
-               if (priv->speed == 0x1)
-                       priv->speed = TLAN_SPEED_10;
-               else if (priv->speed == 0x2)
-                       priv->speed = TLAN_SPEED_100;
-
-               debug = priv->debug = dev->mem_end;
-       } else {
-               priv->aui    = aui[boards_found];
-               priv->speed  = speed[boards_found];
-               priv->duplex = duplex[boards_found];
-               priv->debug = debug;
-       }
-
-       /* This will be used when we get an adapter error from
-        * within our irq handler */
-       INIT_WORK(&priv->tlan_tqueue, tlan_tx_timeout_work);
-
-       spin_lock_init(&priv->lock);
-
-       rc = tlan_init(dev);
-       if (rc) {
-               pr_err("Could not set up device\n");
-               goto err_out_free_dev;
-       }
-
-       rc = register_netdev(dev);
-       if (rc) {
-               pr_err("Could not register device\n");
-               goto err_out_uninit;
-       }
-
-
-       tlan_devices_installed++;
-       boards_found++;
-
-       /* pdev is NULL if this is an EISA device */
-       if (pdev)
-               tlan_have_pci++;
-       else {
-               priv->next_device = tlan_eisa_devices;
-               tlan_eisa_devices = dev;
-               tlan_have_eisa++;
-       }
-
-       netdev_info(dev, "irq=%2d, io=%04x, %s, Rev. %d\n",
-                   (int)dev->irq,
-                   (int)dev->base_addr,
-                   priv->adapter->device_label,
-                   priv->adapter_rev);
-       return 0;
-
-err_out_uninit:
-       pci_free_consistent(priv->pci_dev, priv->dma_size, priv->dma_storage,
-                           priv->dma_storage_dma);
-err_out_free_dev:
-       free_netdev(dev);
-err_out_regions:
-#ifdef CONFIG_PCI
-       if (pdev)
-               pci_release_regions(pdev);
-#endif
-err_out:
-       if (pdev)
-               pci_disable_device(pdev);
-       return rc;
-}
-
-
-static void tlan_eisa_cleanup(void)
-{
-       struct net_device *dev;
-       struct tlan_priv *priv;
-
-       while (tlan_have_eisa) {
-               dev = tlan_eisa_devices;
-               priv = netdev_priv(dev);
-               if (priv->dma_storage) {
-                       pci_free_consistent(priv->pci_dev, priv->dma_size,
-                                           priv->dma_storage,
-                                           priv->dma_storage_dma);
-               }
-               release_region(dev->base_addr, 0x10);
-               unregister_netdev(dev);
-               tlan_eisa_devices = priv->next_device;
-               free_netdev(dev);
-               tlan_have_eisa--;
-       }
-}
-
-
-static void __exit tlan_exit(void)
-{
-       pci_unregister_driver(&tlan_driver);
-
-       if (tlan_have_eisa)
-               tlan_eisa_cleanup();
-
-}
-
-
-/* Module loading/unloading */
-module_init(tlan_probe);
-module_exit(tlan_exit);
-
-
-
-/**************************************************************
- *     tlan_eisa_probe
- *
- *     Returns: 0 on success, 1 otherwise
- *
- *     Parms:   None
- *
- *
- *     This functions probes for EISA devices and calls
- *     TLan_probe1 when one is found.
- *
- *************************************************************/
-
-static void  __init tlan_eisa_probe(void)
-{
-       long    ioaddr;
-       int     rc = -ENODEV;
-       int     irq;
-       u16     device_id;
-
-       if (!EISA_bus) {
-               TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
-               return;
-       }
-
-       /* Loop through all slots of the EISA bus */
-       for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
-
-               TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
-                        (int) ioaddr + 0xc80, inw(ioaddr + EISA_ID));
-               TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
-                        (int) ioaddr + 0xc82, inw(ioaddr + EISA_ID2));
-
-
-               TLAN_DBG(TLAN_DEBUG_PROBE,
-                        "Probing for EISA adapter at IO: 0x%4x : ",
-                        (int) ioaddr);
-               if (request_region(ioaddr, 0x10, tlan_signature) == NULL)
-                       goto out;
-
-               if (inw(ioaddr + EISA_ID) != 0x110E) {
-                       release_region(ioaddr, 0x10);
-                       goto out;
-               }
-
-               device_id = inw(ioaddr + EISA_ID2);
-               if (device_id !=  0x20F1 && device_id != 0x40F1) {
-                       release_region(ioaddr, 0x10);
-                       goto out;
-               }
-
-               /* check if adapter is enabled */
-               if (inb(ioaddr + EISA_CR) != 0x1) {
-                       release_region(ioaddr, 0x10);
-                       goto out2;
-               }
-
-               if (debug == 0x10)
-                       pr_info("Found one\n");
-
-
-               /* Get irq from board */
-               switch (inb(ioaddr + 0xcc0)) {
-               case(0x10):
-                       irq = 5;
-                       break;
-               case(0x20):
-                       irq = 9;
-                       break;
-               case(0x40):
-                       irq = 10;
-                       break;
-               case(0x80):
-                       irq = 11;
-                       break;
-               default:
-                       goto out;
-               }
-
-
-               /* Setup the newly found eisa adapter */
-               rc = tlan_probe1(NULL, ioaddr, irq,
-                                12, NULL);
-               continue;
-
-out:
-               if (debug == 0x10)
-                       pr_info("None found\n");
-               continue;
-
-out2:
-               if (debug == 0x10)
-                       pr_info("Card found but it is not enabled, skipping\n");
-               continue;
-
-       }
-
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void tlan_poll(struct net_device *dev)
-{
-       disable_irq(dev->irq);
-       tlan_handle_interrupt(dev->irq, dev);
-       enable_irq(dev->irq);
-}
-#endif
-
-static const struct net_device_ops tlan_netdev_ops = {
-       .ndo_open               = tlan_open,
-       .ndo_stop               = tlan_close,
-       .ndo_start_xmit         = tlan_start_tx,
-       .ndo_tx_timeout         = tlan_tx_timeout,
-       .ndo_get_stats          = tlan_get_stats,
-       .ndo_set_multicast_list = tlan_set_multicast_list,
-       .ndo_do_ioctl           = tlan_ioctl,
-       .ndo_change_mtu         = eth_change_mtu,
-       .ndo_set_mac_address    = eth_mac_addr,
-       .ndo_validate_addr      = eth_validate_addr,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller     = tlan_poll,
-#endif
-};
-
-
-
-/***************************************************************
- *     tlan_init
- *
- *     Returns:
- *             0 on success, error code otherwise.
- *     Parms:
- *             dev     The structure of the device to be
- *                     init'ed.
- *
- *     This function completes the initialization of the
- *     device structure and driver.  It reserves the IO
- *     addresses, allocates memory for the lists and bounce
- *     buffers, retrieves the MAC address from the eeprom
- *     and assignes the device's methods.
- *
- **************************************************************/
-
-static int tlan_init(struct net_device *dev)
-{
-       int             dma_size;
-       int             err;
-       int             i;
-       struct tlan_priv        *priv;
-
-       priv = netdev_priv(dev);
-
-       dma_size = (TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS)
-               * (sizeof(struct tlan_list));
-       priv->dma_storage = pci_alloc_consistent(priv->pci_dev,
-                                                dma_size,
-                                                &priv->dma_storage_dma);
-       priv->dma_size = dma_size;
-
-       if (priv->dma_storage == NULL) {
-               pr_err("Could not allocate lists and buffers for %s\n",
-                      dev->name);
-               return -ENOMEM;
-       }
-       memset(priv->dma_storage, 0, dma_size);
-       priv->rx_list = (struct tlan_list *)
-               ALIGN((unsigned long)priv->dma_storage, 8);
-       priv->rx_list_dma = ALIGN(priv->dma_storage_dma, 8);
-       priv->tx_list = priv->rx_list + TLAN_NUM_RX_LISTS;
-       priv->tx_list_dma =
-               priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS;
-
-       err = 0;
-       for (i = 0;  i < 6 ; i++)
-               err |= tlan_ee_read_byte(dev,
-                                        (u8) priv->adapter->addr_ofs + i,
-                                        (u8 *) &dev->dev_addr[i]);
-       if (err) {
-               pr_err("%s: Error reading MAC from eeprom: %d\n",
-                      dev->name, err);
-       }
-       dev->addr_len = 6;
-
-       netif_carrier_off(dev);
-
-       /* Device methods */
-       dev->netdev_ops = &tlan_netdev_ops;
-       dev->watchdog_timeo = TX_TIMEOUT;
-
-       return 0;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_open
- *
- *     Returns:
- *             0 on success, error code otherwise.
- *     Parms:
- *             dev     Structure of device to be opened.
- *
- *     This routine puts the driver and TLAN adapter in a
- *     state where it is ready to send and receive packets.
- *     It allocates the IRQ, resets and brings the adapter
- *     out of reset, and allows interrupts.  It also delays
- *     the startup for autonegotiation or sends a Rx GO
- *     command to the adapter, as appropriate.
- *
- **************************************************************/
-
-static int tlan_open(struct net_device *dev)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       int             err;
-
-       priv->tlan_rev = tlan_dio_read8(dev->base_addr, TLAN_DEF_REVISION);
-       err = request_irq(dev->irq, tlan_handle_interrupt, IRQF_SHARED,
-                         dev->name, dev);
-
-       if (err) {
-               netdev_err(dev, "Cannot open because IRQ %d is already in use\n",
-                          dev->irq);
-               return err;
-       }
-
-       init_timer(&priv->timer);
-
-       tlan_start(dev);
-
-       TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened.  TLAN Chip Rev: %x\n",
-                dev->name, priv->tlan_rev);
-
-       return 0;
-
-}
-
-
-
-/**************************************************************
- *     tlan_ioctl
- *
- *     Returns:
- *             0 on success, error code otherwise
- *     Params:
- *             dev     structure of device to receive ioctl.
- *
- *             rq      ifreq structure to hold userspace data.
- *
- *             cmd     ioctl command.
- *
- *
- *************************************************************/
-
-static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-       struct mii_ioctl_data *data = if_mii(rq);
-       u32 phy   = priv->phy[priv->phy_num];
-
-       if (!priv->phy_online)
-               return -EAGAIN;
-
-       switch (cmd) {
-       case SIOCGMIIPHY:               /* get address of MII PHY in use. */
-               data->phy_id = phy;
-
-
-       case SIOCGMIIREG:               /* read MII PHY register. */
-               tlan_mii_read_reg(dev, data->phy_id & 0x1f,
-                                 data->reg_num & 0x1f, &data->val_out);
-               return 0;
-
-
-       case SIOCSMIIREG:               /* write MII PHY register. */
-               tlan_mii_write_reg(dev, data->phy_id & 0x1f,
-                                  data->reg_num & 0x1f, data->val_in);
-               return 0;
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-
-/***************************************************************
- *     tlan_tx_timeout
- *
- *     Returns: nothing
- *
- *     Params:
- *             dev     structure of device which timed out
- *                     during transmit.
- *
- **************************************************************/
-
-static void tlan_tx_timeout(struct net_device *dev)
-{
-
-       TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
-
-       /* Ok so we timed out, lets see what we can do about it...*/
-       tlan_free_lists(dev);
-       tlan_reset_lists(dev);
-       tlan_read_and_clear_stats(dev, TLAN_IGNORE);
-       tlan_reset_adapter(dev);
-       dev->trans_start = jiffies; /* prevent tx timeout */
-       netif_wake_queue(dev);
-
-}
-
-
-/***************************************************************
- *     tlan_tx_timeout_work
- *
- *     Returns: nothing
- *
- *     Params:
- *             work    work item of device which timed out
- *
- **************************************************************/
-
-static void tlan_tx_timeout_work(struct work_struct *work)
-{
-       struct tlan_priv        *priv =
-               container_of(work, struct tlan_priv, tlan_tqueue);
-
-       tlan_tx_timeout(priv->dev);
-}
-
-
-
-/***************************************************************
- *     tlan_start_tx
- *
- *     Returns:
- *             0 on success, non-zero on failure.
- *     Parms:
- *             skb     A pointer to the sk_buff containing the
- *                     frame to be sent.
- *             dev     The device to send the data on.
- *
- *     This function adds a frame to the Tx list to be sent
- *     ASAP.  First it verifies that the adapter is ready and
- *     there is room in the queue.  Then it sets up the next
- *     available list, copies the frame to the corresponding
- *     buffer.  If the adapter Tx channel is idle, it gives
- *     the adapter a Tx Go command on the list, otherwise it
- *     sets the forward address of the previous list to point
- *     to this one.  Then it frees the sk_buff.
- *
- **************************************************************/
-
-static netdev_tx_t tlan_start_tx(struct sk_buff *skb, struct net_device *dev)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-       dma_addr_t      tail_list_phys;
-       struct tlan_list        *tail_list;
-       unsigned long   flags;
-       unsigned int    txlen;
-
-       if (!priv->phy_online) {
-               TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT:  %s PHY is not ready\n",
-                        dev->name);
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
-               return NETDEV_TX_OK;
-       txlen = max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE);
-
-       tail_list = priv->tx_list + priv->tx_tail;
-       tail_list_phys =
-               priv->tx_list_dma + sizeof(struct tlan_list)*priv->tx_tail;
-
-       if (tail_list->c_stat != TLAN_CSTAT_UNUSED) {
-               TLAN_DBG(TLAN_DEBUG_TX,
-                        "TRANSMIT:  %s is busy (Head=%d Tail=%d)\n",
-                        dev->name, priv->tx_head, priv->tx_tail);
-               netif_stop_queue(dev);
-               priv->tx_busy_count++;
-               return NETDEV_TX_BUSY;
-       }
-
-       tail_list->forward = 0;
-
-       tail_list->buffer[0].address = pci_map_single(priv->pci_dev,
-                                                     skb->data, txlen,
-                                                     PCI_DMA_TODEVICE);
-       tlan_store_skb(tail_list, skb);
-
-       tail_list->frame_size = (u16) txlen;
-       tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) txlen;
-       tail_list->buffer[1].count = 0;
-       tail_list->buffer[1].address = 0;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       tail_list->c_stat = TLAN_CSTAT_READY;
-       if (!priv->tx_in_progress) {
-               priv->tx_in_progress = 1;
-               TLAN_DBG(TLAN_DEBUG_TX,
-                        "TRANSMIT:  Starting TX on buffer %d\n",
-                        priv->tx_tail);
-               outl(tail_list_phys, dev->base_addr + TLAN_CH_PARM);
-               outl(TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD);
-       } else {
-               TLAN_DBG(TLAN_DEBUG_TX,
-                        "TRANSMIT:  Adding buffer %d to TX channel\n",
-                        priv->tx_tail);
-               if (priv->tx_tail == 0) {
-                       (priv->tx_list + (TLAN_NUM_TX_LISTS - 1))->forward
-                               = tail_list_phys;
-               } else {
-                       (priv->tx_list + (priv->tx_tail - 1))->forward
-                               = tail_list_phys;
-               }
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       CIRC_INC(priv->tx_tail, TLAN_NUM_TX_LISTS);
-
-       return NETDEV_TX_OK;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_handle_interrupt
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             irq     The line on which the interrupt
- *                     occurred.
- *             dev_id  A pointer to the device assigned to
- *                     this irq line.
- *
- *     This function handles an interrupt generated by its
- *     assigned TLAN adapter.  The function deactivates
- *     interrupts on its adapter, records the type of
- *     interrupt, executes the appropriate subhandler, and
- *     acknowdges the interrupt to the adapter (thus
- *     re-enabling adapter interrupts.
- *
- **************************************************************/
-
-static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id)
-{
-       struct net_device       *dev = dev_id;
-       struct tlan_priv *priv = netdev_priv(dev);
-       u16             host_int;
-       u16             type;
-
-       spin_lock(&priv->lock);
-
-       host_int = inw(dev->base_addr + TLAN_HOST_INT);
-       type = (host_int & TLAN_HI_IT_MASK) >> 2;
-       if (type) {
-               u32     ack;
-               u32     host_cmd;
-
-               outw(host_int, dev->base_addr + TLAN_HOST_INT);
-               ack = tlan_int_vector[type](dev, host_int);
-
-               if (ack) {
-                       host_cmd = TLAN_HC_ACK | ack | (type << 18);
-                       outl(host_cmd, dev->base_addr + TLAN_HOST_CMD);
-               }
-       }
-
-       spin_unlock(&priv->lock);
-
-       return IRQ_RETVAL(type);
-}
-
-
-
-
-/***************************************************************
- *     tlan_close
- *
- *     Returns:
- *             An error code.
- *     Parms:
- *             dev     The device structure of the device to
- *                     close.
- *
- *     This function shuts down the adapter.  It records any
- *     stats, puts the adapter into reset state, deactivates
- *     its time as needed, and frees the irq it is using.
- *
- **************************************************************/
-
-static int tlan_close(struct net_device *dev)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-
-       priv->neg_be_verbose = 0;
-       tlan_stop(dev);
-
-       free_irq(dev->irq, dev);
-       tlan_free_lists(dev);
-       TLAN_DBG(TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name);
-
-       return 0;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_get_stats
- *
- *     Returns:
- *             A pointer to the device's statistics structure.
- *     Parms:
- *             dev     The device structure to return the
- *                     stats for.
- *
- *     This function updates the devices statistics by reading
- *     the TLAN chip's onboard registers.  Then it returns the
- *     address of the statistics structure.
- *
- **************************************************************/
-
-static struct net_device_stats *tlan_get_stats(struct net_device *dev)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       int i;
-
-       /* Should only read stats if open ? */
-       tlan_read_and_clear_stats(dev, TLAN_RECORD);
-
-       TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE:  %s EOC count = %d\n", dev->name,
-                priv->rx_eoc_count);
-       TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT:  %s Busy count = %d\n", dev->name,
-                priv->tx_busy_count);
-       if (debug & TLAN_DEBUG_GNRL) {
-               tlan_print_dio(dev->base_addr);
-               tlan_phy_print(dev);
-       }
-       if (debug & TLAN_DEBUG_LIST) {
-               for (i = 0; i < TLAN_NUM_RX_LISTS; i++)
-                       tlan_print_list(priv->rx_list + i, "RX", i);
-               for (i = 0; i < TLAN_NUM_TX_LISTS; i++)
-                       tlan_print_list(priv->tx_list + i, "TX", i);
-       }
-
-       return &dev->stats;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_set_multicast_list
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             dev     The device structure to set the
- *                     multicast list for.
- *
- *     This function sets the TLAN adaptor to various receive
- *     modes.  If the IFF_PROMISC flag is set, promiscuous
- *     mode is acitviated.  Otherwise, promiscuous mode is
- *     turned off.  If the IFF_ALLMULTI flag is set, then
- *     the hash table is set to receive all group addresses.
- *     Otherwise, the first three multicast addresses are
- *     stored in AREG_1-3, and the rest are selected via the
- *     hash table, as necessary.
- *
- **************************************************************/
-
-static void tlan_set_multicast_list(struct net_device *dev)
-{
-       struct netdev_hw_addr *ha;
-       u32                     hash1 = 0;
-       u32                     hash2 = 0;
-       int                     i;
-       u32                     offset;
-       u8                      tmp;
-
-       if (dev->flags & IFF_PROMISC) {
-               tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
-               tlan_dio_write8(dev->base_addr,
-                               TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF);
-       } else {
-               tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
-               tlan_dio_write8(dev->base_addr,
-                               TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF);
-               if (dev->flags & IFF_ALLMULTI) {
-                       for (i = 0; i < 3; i++)
-                               tlan_set_mac(dev, i + 1, NULL);
-                       tlan_dio_write32(dev->base_addr, TLAN_HASH_1,
-                                        0xffffffff);
-                       tlan_dio_write32(dev->base_addr, TLAN_HASH_2,
-                                        0xffffffff);
-               } else {
-                       i = 0;
-                       netdev_for_each_mc_addr(ha, dev) {
-                               if (i < 3) {
-                                       tlan_set_mac(dev, i + 1,
-                                                    (char *) &ha->addr);
-                               } else {
-                                       offset =
-                                               tlan_hash_func((u8 *)&ha->addr);
-                                       if (offset < 32)
-                                               hash1 |= (1 << offset);
-                                       else
-                                               hash2 |= (1 << (offset - 32));
-                               }
-                               i++;
-                       }
-                       for ( ; i < 3; i++)
-                               tlan_set_mac(dev, i + 1, NULL);
-                       tlan_dio_write32(dev->base_addr, TLAN_HASH_1, hash1);
-                       tlan_dio_write32(dev->base_addr, TLAN_HASH_2, hash2);
-               }
-       }
-
-}
-
-
-
-/*****************************************************************************
-******************************************************************************
-
-ThunderLAN driver interrupt vectors and table
-
-please see chap. 4, "Interrupt Handling" of the "ThunderLAN
-Programmer's Guide" for more informations on handling interrupts
-generated by TLAN based adapters.
-
-******************************************************************************
-*****************************************************************************/
-
-
-
-
-/***************************************************************
- *     tlan_handle_tx_eof
- *
- *     Returns:
- *             1
- *     Parms:
- *             dev             Device assigned the IRQ that was
- *                             raised.
- *             host_int        The contents of the HOST_INT
- *                             port.
- *
- *     This function handles Tx EOF interrupts which are raised
- *     by the adapter when it has completed sending the
- *     contents of a buffer.  If detemines which list/buffer
- *     was completed and resets it.  If the buffer was the last
- *     in the channel (EOC), then the function checks to see if
- *     another buffer is ready to send, and if so, sends a Tx
- *     Go command.  Finally, the driver activates/continues the
- *     activity LED.
- *
- **************************************************************/
-
-static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       int             eoc = 0;
-       struct tlan_list        *head_list;
-       dma_addr_t      head_list_phys;
-       u32             ack = 0;
-       u16             tmp_c_stat;
-
-       TLAN_DBG(TLAN_DEBUG_TX,
-                "TRANSMIT:  Handling TX EOF (Head=%d Tail=%d)\n",
-                priv->tx_head, priv->tx_tail);
-       head_list = priv->tx_list + priv->tx_head;
-
-       while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
-              && (ack < 255)) {
-               struct sk_buff *skb = tlan_get_skb(head_list);
-
-               ack++;
-               pci_unmap_single(priv->pci_dev, head_list->buffer[0].address,
-                                max(skb->len,
-                                    (unsigned int)TLAN_MIN_FRAME_SIZE),
-                                PCI_DMA_TODEVICE);
-               dev_kfree_skb_any(skb);
-               head_list->buffer[8].address = 0;
-               head_list->buffer[9].address = 0;
-
-               if (tmp_c_stat & TLAN_CSTAT_EOC)
-                       eoc = 1;
-
-               dev->stats.tx_bytes += head_list->frame_size;
-
-               head_list->c_stat = TLAN_CSTAT_UNUSED;
-               netif_start_queue(dev);
-               CIRC_INC(priv->tx_head, TLAN_NUM_TX_LISTS);
-               head_list = priv->tx_list + priv->tx_head;
-       }
-
-       if (!ack)
-               netdev_info(dev,
-                           "Received interrupt for uncompleted TX frame\n");
-
-       if (eoc) {
-               TLAN_DBG(TLAN_DEBUG_TX,
-                        "TRANSMIT:  handling TX EOC (Head=%d Tail=%d)\n",
-                        priv->tx_head, priv->tx_tail);
-               head_list = priv->tx_list + priv->tx_head;
-               head_list_phys = priv->tx_list_dma
-                       + sizeof(struct tlan_list)*priv->tx_head;
-               if ((head_list->c_stat & TLAN_CSTAT_READY)
-                   == TLAN_CSTAT_READY) {
-                       outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
-                       ack |= TLAN_HC_GO;
-               } else {
-                       priv->tx_in_progress = 0;
-               }
-       }
-
-       if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
-               tlan_dio_write8(dev->base_addr,
-                               TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
-               if (priv->timer.function == NULL) {
-                       priv->timer.function = tlan_timer;
-                       priv->timer.data = (unsigned long) dev;
-                       priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
-                       priv->timer_set_at = jiffies;
-                       priv->timer_type = TLAN_TIMER_ACTIVITY;
-                       add_timer(&priv->timer);
-               } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
-                       priv->timer_set_at = jiffies;
-               }
-       }
-
-       return ack;
-
-}
-
-
-
-
-/***************************************************************
- *     TLan_HandleStatOverflow
- *
- *     Returns:
- *             1
- *     Parms:
- *             dev             Device assigned the IRQ that was
- *                             raised.
- *             host_int        The contents of the HOST_INT
- *                             port.
- *
- *     This function handles the Statistics Overflow interrupt
- *     which means that one or more of the TLAN statistics
- *     registers has reached 1/2 capacity and needs to be read.
- *
- **************************************************************/
-
-static u32 tlan_handle_stat_overflow(struct net_device *dev, u16 host_int)
-{
-       tlan_read_and_clear_stats(dev, TLAN_RECORD);
-
-       return 1;
-
-}
-
-
-
-
-/***************************************************************
- *     TLan_HandleRxEOF
- *
- *     Returns:
- *             1
- *     Parms:
- *             dev             Device assigned the IRQ that was
- *                             raised.
- *             host_int        The contents of the HOST_INT
- *                             port.
- *
- *     This function handles the Rx EOF interrupt which
- *     indicates a frame has been received by the adapter from
- *     the net and the frame has been transferred to memory.
- *     The function determines the bounce buffer the frame has
- *     been loaded into, creates a new sk_buff big enough to
- *     hold the frame, and sends it to protocol stack.  It
- *     then resets the used buffer and appends it to the end
- *     of the list.  If the frame was the last in the Rx
- *     channel (EOC), the function restarts the receive channel
- *     by sending an Rx Go command to the adapter.  Then it
- *     activates/continues the activity LED.
- *
- **************************************************************/
-
-static u32 tlan_handle_rx_eof(struct net_device *dev, u16 host_int)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       u32             ack = 0;
-       int             eoc = 0;
-       struct tlan_list        *head_list;
-       struct sk_buff  *skb;
-       struct tlan_list        *tail_list;
-       u16             tmp_c_stat;
-       dma_addr_t      head_list_phys;
-
-       TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE:  handling RX EOF (Head=%d Tail=%d)\n",
-                priv->rx_head, priv->rx_tail);
-       head_list = priv->rx_list + priv->rx_head;
-       head_list_phys =
-               priv->rx_list_dma + sizeof(struct tlan_list)*priv->rx_head;
-
-       while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
-              && (ack < 255)) {
-               dma_addr_t frame_dma = head_list->buffer[0].address;
-               u32 frame_size = head_list->frame_size;
-               struct sk_buff *new_skb;
-
-               ack++;
-               if (tmp_c_stat & TLAN_CSTAT_EOC)
-                       eoc = 1;
-
-               new_skb = netdev_alloc_skb_ip_align(dev,
-                                                   TLAN_MAX_FRAME_SIZE + 5);
-               if (!new_skb)
-                       goto drop_and_reuse;
-
-               skb = tlan_get_skb(head_list);
-               pci_unmap_single(priv->pci_dev, frame_dma,
-                                TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
-               skb_put(skb, frame_size);
-
-               dev->stats.rx_bytes += frame_size;
-
-               skb->protocol = eth_type_trans(skb, dev);
-               netif_rx(skb);
-
-               head_list->buffer[0].address =
-                       pci_map_single(priv->pci_dev, new_skb->data,
-                                      TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
-
-               tlan_store_skb(head_list, new_skb);
-drop_and_reuse:
-               head_list->forward = 0;
-               head_list->c_stat = 0;
-               tail_list = priv->rx_list + priv->rx_tail;
-               tail_list->forward = head_list_phys;
-
-               CIRC_INC(priv->rx_head, TLAN_NUM_RX_LISTS);
-               CIRC_INC(priv->rx_tail, TLAN_NUM_RX_LISTS);
-               head_list = priv->rx_list + priv->rx_head;
-               head_list_phys = priv->rx_list_dma
-                       + sizeof(struct tlan_list)*priv->rx_head;
-       }
-
-       if (!ack)
-               netdev_info(dev,
-                           "Received interrupt for uncompleted RX frame\n");
-
-
-       if (eoc) {
-               TLAN_DBG(TLAN_DEBUG_RX,
-                        "RECEIVE:  handling RX EOC (Head=%d Tail=%d)\n",
-                        priv->rx_head, priv->rx_tail);
-               head_list = priv->rx_list + priv->rx_head;
-               head_list_phys = priv->rx_list_dma
-                       + sizeof(struct tlan_list)*priv->rx_head;
-               outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
-               ack |= TLAN_HC_GO | TLAN_HC_RT;
-               priv->rx_eoc_count++;
-       }
-
-       if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
-               tlan_dio_write8(dev->base_addr,
-                               TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
-               if (priv->timer.function == NULL)  {
-                       priv->timer.function = tlan_timer;
-                       priv->timer.data = (unsigned long) dev;
-                       priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
-                       priv->timer_set_at = jiffies;
-                       priv->timer_type = TLAN_TIMER_ACTIVITY;
-                       add_timer(&priv->timer);
-               } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
-                       priv->timer_set_at = jiffies;
-               }
-       }
-
-       return ack;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_handle_dummy
- *
- *     Returns:
- *             1
- *     Parms:
- *             dev             Device assigned the IRQ that was
- *                             raised.
- *             host_int        The contents of the HOST_INT
- *                             port.
- *
- *     This function handles the Dummy interrupt, which is
- *     raised whenever a test interrupt is generated by setting
- *     the Req_Int bit of HOST_CMD to 1.
- *
- **************************************************************/
-
-static u32 tlan_handle_dummy(struct net_device *dev, u16 host_int)
-{
-       netdev_info(dev, "Test interrupt\n");
-       return 1;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_handle_tx_eoc
- *
- *     Returns:
- *             1
- *     Parms:
- *             dev             Device assigned the IRQ that was
- *                             raised.
- *             host_int        The contents of the HOST_INT
- *                             port.
- *
- *     This driver is structured to determine EOC occurrences by
- *     reading the CSTAT member of the list structure.  Tx EOC
- *     interrupts are disabled via the DIO INTDIS register.
- *     However, TLAN chips before revision 3.0 didn't have this
- *     functionality, so process EOC events if this is the
- *     case.
- *
- **************************************************************/
-
-static u32 tlan_handle_tx_eoc(struct net_device *dev, u16 host_int)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       struct tlan_list                *head_list;
-       dma_addr_t              head_list_phys;
-       u32                     ack = 1;
-
-       host_int = 0;
-       if (priv->tlan_rev < 0x30) {
-               TLAN_DBG(TLAN_DEBUG_TX,
-                        "TRANSMIT:  handling TX EOC (Head=%d Tail=%d) -- IRQ\n",
-                        priv->tx_head, priv->tx_tail);
-               head_list = priv->tx_list + priv->tx_head;
-               head_list_phys = priv->tx_list_dma
-                       + sizeof(struct tlan_list)*priv->tx_head;
-               if ((head_list->c_stat & TLAN_CSTAT_READY)
-                   == TLAN_CSTAT_READY) {
-                       netif_stop_queue(dev);
-                       outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
-                       ack |= TLAN_HC_GO;
-               } else {
-                       priv->tx_in_progress = 0;
-               }
-       }
-
-       return ack;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_handle_status_check
- *
- *     Returns:
- *             0 if Adapter check, 1 if Network Status check.
- *     Parms:
- *             dev             Device assigned the IRQ that was
- *                             raised.
- *             host_int        The contents of the HOST_INT
- *                             port.
- *
- *     This function handles Adapter Check/Network Status
- *     interrupts generated by the adapter.  It checks the
- *     vector in the HOST_INT register to determine if it is
- *     an Adapter Check interrupt.  If so, it resets the
- *     adapter.  Otherwise it clears the status registers
- *     and services the PHY.
- *
- **************************************************************/
-
-static u32 tlan_handle_status_check(struct net_device *dev, u16 host_int)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       u32             ack;
-       u32             error;
-       u8              net_sts;
-       u32             phy;
-       u16             tlphy_ctl;
-       u16             tlphy_sts;
-
-       ack = 1;
-       if (host_int & TLAN_HI_IV_MASK) {
-               netif_stop_queue(dev);
-               error = inl(dev->base_addr + TLAN_CH_PARM);
-               netdev_info(dev, "Adaptor Error = 0x%x\n", error);
-               tlan_read_and_clear_stats(dev, TLAN_RECORD);
-               outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
-
-               schedule_work(&priv->tlan_tqueue);
-
-               netif_wake_queue(dev);
-               ack = 0;
-       } else {
-               TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name);
-               phy = priv->phy[priv->phy_num];
-
-               net_sts = tlan_dio_read8(dev->base_addr, TLAN_NET_STS);
-               if (net_sts) {
-                       tlan_dio_write8(dev->base_addr, TLAN_NET_STS, net_sts);
-                       TLAN_DBG(TLAN_DEBUG_GNRL, "%s:    Net_Sts = %x\n",
-                                dev->name, (unsigned) net_sts);
-               }
-               if ((net_sts & TLAN_NET_STS_MIRQ) &&  (priv->phy_num == 0)) {
-                       tlan_mii_read_reg(dev, phy, TLAN_TLPHY_STS, &tlphy_sts);
-                       tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
-                       if (!(tlphy_sts & TLAN_TS_POLOK) &&
-                           !(tlphy_ctl & TLAN_TC_SWAPOL)) {
-                               tlphy_ctl |= TLAN_TC_SWAPOL;
-                               tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
-                                                  tlphy_ctl);
-                       } else if ((tlphy_sts & TLAN_TS_POLOK) &&
-                                  (tlphy_ctl & TLAN_TC_SWAPOL)) {
-                               tlphy_ctl &= ~TLAN_TC_SWAPOL;
-                               tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
-                                                  tlphy_ctl);
-                       }
-
-                       if (debug)
-                               tlan_phy_print(dev);
-               }
-       }
-
-       return ack;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_handle_rx_eoc
- *
- *     Returns:
- *             1
- *     Parms:
- *             dev             Device assigned the IRQ that was
- *                             raised.
- *             host_int        The contents of the HOST_INT
- *                             port.
- *
- *     This driver is structured to determine EOC occurrences by
- *     reading the CSTAT member of the list structure.  Rx EOC
- *     interrupts are disabled via the DIO INTDIS register.
- *     However, TLAN chips before revision 3.0 didn't have this
- *     CSTAT member or a INTDIS register, so if this chip is
- *     pre-3.0, process EOC interrupts normally.
- *
- **************************************************************/
-
-static u32 tlan_handle_rx_eoc(struct net_device *dev, u16 host_int)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       dma_addr_t      head_list_phys;
-       u32             ack = 1;
-
-       if (priv->tlan_rev < 0x30) {
-               TLAN_DBG(TLAN_DEBUG_RX,
-                        "RECEIVE:  Handling RX EOC (head=%d tail=%d) -- IRQ\n",
-                        priv->rx_head, priv->rx_tail);
-               head_list_phys = priv->rx_list_dma
-                       + sizeof(struct tlan_list)*priv->rx_head;
-               outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
-               ack |= TLAN_HC_GO | TLAN_HC_RT;
-               priv->rx_eoc_count++;
-       }
-
-       return ack;
-
-}
-
-
-
-
-/*****************************************************************************
-******************************************************************************
-
-ThunderLAN driver timer function
-
-******************************************************************************
-*****************************************************************************/
-
-
-/***************************************************************
- *     tlan_timer
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             data    A value given to add timer when
- *                     add_timer was called.
- *
- *     This function handles timed functionality for the
- *     TLAN driver.  The two current timer uses are for
- *     delaying for autonegotionation and driving the ACT LED.
- *     -       Autonegotiation requires being allowed about
- *             2 1/2 seconds before attempting to transmit a
- *             packet.  It would be a very bad thing to hang
- *             the kernel this long, so the driver doesn't
- *             allow transmission 'til after this time, for
- *             certain PHYs.  It would be much nicer if all
- *             PHYs were interrupt-capable like the internal
- *             PHY.
- *     -       The ACT LED, which shows adapter activity, is
- *             driven by the driver, and so must be left on
- *             for a short period to power up the LED so it
- *             can be seen.  This delay can be changed by
- *             changing the TLAN_TIMER_ACT_DELAY in tlan.h,
- *             if desired.  100 ms  produces a slightly
- *             sluggish response.
- *
- **************************************************************/
-
-static void tlan_timer(unsigned long data)
-{
-       struct net_device       *dev = (struct net_device *) data;
-       struct tlan_priv        *priv = netdev_priv(dev);
-       u32             elapsed;
-       unsigned long   flags = 0;
-
-       priv->timer.function = NULL;
-
-       switch (priv->timer_type) {
-#ifdef MONITOR
-       case TLAN_TIMER_LINK_BEAT:
-               tlan_phy_monitor(dev);
-               break;
-#endif
-       case TLAN_TIMER_PHY_PDOWN:
-               tlan_phy_power_down(dev);
-               break;
-       case TLAN_TIMER_PHY_PUP:
-               tlan_phy_power_up(dev);
-               break;
-       case TLAN_TIMER_PHY_RESET:
-               tlan_phy_reset(dev);
-               break;
-       case TLAN_TIMER_PHY_START_LINK:
-               tlan_phy_start_link(dev);
-               break;
-       case TLAN_TIMER_PHY_FINISH_AN:
-               tlan_phy_finish_auto_neg(dev);
-               break;
-       case TLAN_TIMER_FINISH_RESET:
-               tlan_finish_reset(dev);
-               break;
-       case TLAN_TIMER_ACTIVITY:
-               spin_lock_irqsave(&priv->lock, flags);
-               if (priv->timer.function == NULL) {
-                       elapsed = jiffies - priv->timer_set_at;
-                       if (elapsed >= TLAN_TIMER_ACT_DELAY) {
-                               tlan_dio_write8(dev->base_addr,
-                                               TLAN_LED_REG, TLAN_LED_LINK);
-                       } else  {
-                               priv->timer.function = tlan_timer;
-                               priv->timer.expires = priv->timer_set_at
-                                       + TLAN_TIMER_ACT_DELAY;
-                               spin_unlock_irqrestore(&priv->lock, flags);
-                               add_timer(&priv->timer);
-                               break;
-                       }
-               }
-               spin_unlock_irqrestore(&priv->lock, flags);
-               break;
-       default:
-               break;
-       }
-
-}
-
-
-
-
-/*****************************************************************************
-******************************************************************************
-
-ThunderLAN driver adapter related routines
-
-******************************************************************************
-*****************************************************************************/
-
-
-/***************************************************************
- *     tlan_reset_lists
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             dev     The device structure with the list
- *                     stuctures to be reset.
- *
- *     This routine sets the variables associated with managing
- *     the TLAN lists to their initial values.
- *
- **************************************************************/
-
-static void tlan_reset_lists(struct net_device *dev)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-       int             i;
-       struct tlan_list        *list;
-       dma_addr_t      list_phys;
-       struct sk_buff  *skb;
-
-       priv->tx_head = 0;
-       priv->tx_tail = 0;
-       for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
-               list = priv->tx_list + i;
-               list->c_stat = TLAN_CSTAT_UNUSED;
-               list->buffer[0].address = 0;
-               list->buffer[2].count = 0;
-               list->buffer[2].address = 0;
-               list->buffer[8].address = 0;
-               list->buffer[9].address = 0;
-       }
-
-       priv->rx_head = 0;
-       priv->rx_tail = TLAN_NUM_RX_LISTS - 1;
-       for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
-               list = priv->rx_list + i;
-               list_phys = priv->rx_list_dma + sizeof(struct tlan_list)*i;
-               list->c_stat = TLAN_CSTAT_READY;
-               list->frame_size = TLAN_MAX_FRAME_SIZE;
-               list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
-               skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
-               if (!skb) {
-                       netdev_err(dev, "Out of memory for received data\n");
-                       break;
-               }
-
-               list->buffer[0].address = pci_map_single(priv->pci_dev,
-                                                        skb->data,
-                                                        TLAN_MAX_FRAME_SIZE,
-                                                        PCI_DMA_FROMDEVICE);
-               tlan_store_skb(list, skb);
-               list->buffer[1].count = 0;
-               list->buffer[1].address = 0;
-               list->forward = list_phys + sizeof(struct tlan_list);
-       }
-
-       /* in case ran out of memory early, clear bits */
-       while (i < TLAN_NUM_RX_LISTS) {
-               tlan_store_skb(priv->rx_list + i, NULL);
-               ++i;
-       }
-       list->forward = 0;
-
-}
-
-
-static void tlan_free_lists(struct net_device *dev)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-       int             i;
-       struct tlan_list        *list;
-       struct sk_buff  *skb;
-
-       for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
-               list = priv->tx_list + i;
-               skb = tlan_get_skb(list);
-               if (skb) {
-                       pci_unmap_single(
-                               priv->pci_dev,
-                               list->buffer[0].address,
-                               max(skb->len,
-                                   (unsigned int)TLAN_MIN_FRAME_SIZE),
-                               PCI_DMA_TODEVICE);
-                       dev_kfree_skb_any(skb);
-                       list->buffer[8].address = 0;
-                       list->buffer[9].address = 0;
-               }
-       }
-
-       for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
-               list = priv->rx_list + i;
-               skb = tlan_get_skb(list);
-               if (skb) {
-                       pci_unmap_single(priv->pci_dev,
-                                        list->buffer[0].address,
-                                        TLAN_MAX_FRAME_SIZE,
-                                        PCI_DMA_FROMDEVICE);
-                       dev_kfree_skb_any(skb);
-                       list->buffer[8].address = 0;
-                       list->buffer[9].address = 0;
-               }
-       }
-}
-
-
-
-
-/***************************************************************
- *     tlan_print_dio
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             io_base         Base IO port of the device of
- *                             which to print DIO registers.
- *
- *     This function prints out all the internal (DIO)
- *     registers of a TLAN chip.
- *
- **************************************************************/
-
-static void tlan_print_dio(u16 io_base)
-{
-       u32 data0, data1;
-       int     i;
-
-       pr_info("Contents of internal registers for io base 0x%04hx\n",
-               io_base);
-       pr_info("Off.  +0        +4\n");
-       for (i = 0; i < 0x4C; i += 8) {
-               data0 = tlan_dio_read32(io_base, i);
-               data1 = tlan_dio_read32(io_base, i + 0x4);
-               pr_info("0x%02x  0x%08x 0x%08x\n", i, data0, data1);
-       }
-
-}
-
-
-
-
-/***************************************************************
- *     TLan_PrintList
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             list    A pointer to the struct tlan_list structure to
- *                     be printed.
- *             type    A string to designate type of list,
- *                     "Rx" or "Tx".
- *             num     The index of the list.
- *
- *     This function prints out the contents of the list
- *     pointed to by the list parameter.
- *
- **************************************************************/
-
-static void tlan_print_list(struct tlan_list *list, char *type, int num)
-{
-       int i;
-
-       pr_info("%s List %d at %p\n", type, num, list);
-       pr_info("   Forward    = 0x%08x\n",  list->forward);
-       pr_info("   CSTAT      = 0x%04hx\n", list->c_stat);
-       pr_info("   Frame Size = 0x%04hx\n", list->frame_size);
-       /* for (i = 0; i < 10; i++) { */
-       for (i = 0; i < 2; i++) {
-               pr_info("   Buffer[%d].count, addr = 0x%08x, 0x%08x\n",
-                       i, list->buffer[i].count, list->buffer[i].address);
-       }
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_read_and_clear_stats
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             dev     Pointer to device structure of adapter
- *                     to which to read stats.
- *             record  Flag indicating whether to add
- *
- *     This functions reads all the internal status registers
- *     of the TLAN chip, which clears them as a side effect.
- *     It then either adds the values to the device's status
- *     struct, or discards them, depending on whether record
- *     is TLAN_RECORD (!=0)  or TLAN_IGNORE (==0).
- *
- **************************************************************/
-
-static void tlan_read_and_clear_stats(struct net_device *dev, int record)
-{
-       u32             tx_good, tx_under;
-       u32             rx_good, rx_over;
-       u32             def_tx, crc, code;
-       u32             multi_col, single_col;
-       u32             excess_col, late_col, loss;
-
-       outw(TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR);
-       tx_good  = inb(dev->base_addr + TLAN_DIO_DATA);
-       tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
-       tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
-       tx_under = inb(dev->base_addr + TLAN_DIO_DATA + 3);
-
-       outw(TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR);
-       rx_good  = inb(dev->base_addr + TLAN_DIO_DATA);
-       rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
-       rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
-       rx_over  = inb(dev->base_addr + TLAN_DIO_DATA + 3);
-
-       outw(TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR);
-       def_tx  = inb(dev->base_addr + TLAN_DIO_DATA);
-       def_tx += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
-       crc     = inb(dev->base_addr + TLAN_DIO_DATA + 2);
-       code    = inb(dev->base_addr + TLAN_DIO_DATA + 3);
-
-       outw(TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
-       multi_col   = inb(dev->base_addr + TLAN_DIO_DATA);
-       multi_col  += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
-       single_col  = inb(dev->base_addr + TLAN_DIO_DATA + 2);
-       single_col += inb(dev->base_addr + TLAN_DIO_DATA + 3) << 8;
-
-       outw(TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
-       excess_col = inb(dev->base_addr + TLAN_DIO_DATA);
-       late_col   = inb(dev->base_addr + TLAN_DIO_DATA + 1);
-       loss       = inb(dev->base_addr + TLAN_DIO_DATA + 2);
-
-       if (record) {
-               dev->stats.rx_packets += rx_good;
-               dev->stats.rx_errors  += rx_over + crc + code;
-               dev->stats.tx_packets += tx_good;
-               dev->stats.tx_errors  += tx_under + loss;
-               dev->stats.collisions += multi_col
-                       + single_col + excess_col + late_col;
-
-               dev->stats.rx_over_errors    += rx_over;
-               dev->stats.rx_crc_errors     += crc;
-               dev->stats.rx_frame_errors   += code;
-
-               dev->stats.tx_aborted_errors += tx_under;
-               dev->stats.tx_carrier_errors += loss;
-       }
-
-}
-
-
-
-
-/***************************************************************
- *     TLan_Reset
- *
- *     Returns:
- *             0
- *     Parms:
- *             dev     Pointer to device structure of adapter
- *                     to be reset.
- *
- *     This function resets the adapter and it's physical
- *     device.  See Chap. 3, pp. 9-10 of the "ThunderLAN
- *     Programmer's Guide" for details.  The routine tries to
- *     implement what is detailed there, though adjustments
- *     have been made.
- *
- **************************************************************/
-
-static void
-tlan_reset_adapter(struct net_device *dev)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       int             i;
-       u32             addr;
-       u32             data;
-       u8              data8;
-
-       priv->tlan_full_duplex = false;
-       priv->phy_online = 0;
-       netif_carrier_off(dev);
-
-/*  1. Assert reset bit. */
-
-       data = inl(dev->base_addr + TLAN_HOST_CMD);
-       data |= TLAN_HC_AD_RST;
-       outl(data, dev->base_addr + TLAN_HOST_CMD);
-
-       udelay(1000);
-
-/*  2. Turn off interrupts. (Probably isn't necessary) */
-
-       data = inl(dev->base_addr + TLAN_HOST_CMD);
-       data |= TLAN_HC_INT_OFF;
-       outl(data, dev->base_addr + TLAN_HOST_CMD);
-
-/*  3. Clear AREGs and HASHs. */
-
-       for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4)
-               tlan_dio_write32(dev->base_addr, (u16) i, 0);
-
-/*  4. Setup NetConfig register. */
-
-       data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
-       tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
-
-/*  5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
-
-       outl(TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD);
-       outl(TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD);
-
-/*  6. Unreset the MII by setting NMRST (in NetSio) to 1. */
-
-       outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
-       addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
-       tlan_set_bit(TLAN_NET_SIO_NMRST, addr);
-
-/*  7. Setup the remaining registers. */
-
-       if (priv->tlan_rev >= 0x30) {
-               data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
-               tlan_dio_write8(dev->base_addr, TLAN_INT_DIS, data8);
-       }
-       tlan_phy_detect(dev);
-       data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
-
-       if (priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY) {
-               data |= TLAN_NET_CFG_BIT;
-               if (priv->aui == 1) {
-                       tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x0a);
-               } else if (priv->duplex == TLAN_DUPLEX_FULL) {
-                       tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x00);
-                       priv->tlan_full_duplex = true;
-               } else {
-                       tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x08);
-               }
-       }
-
-       if (priv->phy_num == 0)
-               data |= TLAN_NET_CFG_PHY_EN;
-       tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
-
-       if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY)
-               tlan_finish_reset(dev);
-       else
-               tlan_phy_power_down(dev);
-
-}
-
-
-
-
-static void
-tlan_finish_reset(struct net_device *dev)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       u8              data;
-       u32             phy;
-       u8              sio;
-       u16             status;
-       u16             partner;
-       u16             tlphy_ctl;
-       u16             tlphy_par;
-       u16             tlphy_id1, tlphy_id2;
-       int             i;
-
-       phy = priv->phy[priv->phy_num];
-
-       data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
-       if (priv->tlan_full_duplex)
-               data |= TLAN_NET_CMD_DUPLEX;
-       tlan_dio_write8(dev->base_addr, TLAN_NET_CMD, data);
-       data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
-       if (priv->phy_num == 0)
-               data |= TLAN_NET_MASK_MASK7;
-       tlan_dio_write8(dev->base_addr, TLAN_NET_MASK, data);
-       tlan_dio_write16(dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7);
-       tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &tlphy_id1);
-       tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &tlphy_id2);
-
-       if ((priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) ||
-           (priv->aui)) {
-               status = MII_GS_LINK;
-               netdev_info(dev, "Link forced\n");
-       } else {
-               tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
-               udelay(1000);
-               tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
-               if ((status & MII_GS_LINK) &&
-                   /* We only support link info on Nat.Sem. PHY's */
-                   (tlphy_id1 == NAT_SEM_ID1) &&
-                   (tlphy_id2 == NAT_SEM_ID2)) {
-                       tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner);
-                       tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par);
-
-                       netdev_info(dev,
-                                   "Link active with %s %uMbps %s-Duplex\n",
-                                   !(tlphy_par & TLAN_PHY_AN_EN_STAT)
-                                   ? "forced" : "Autonegotiation enabled,",
-                                   tlphy_par & TLAN_PHY_SPEED_100
-                                   ? 100 : 10,
-                                   tlphy_par & TLAN_PHY_DUPLEX_FULL
-                                   ? "Full" : "Half");
-
-                       if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
-                               netdev_info(dev, "Partner capability:");
-                               for (i = 5; i < 10; i++)
-                                       if (partner & (1 << i))
-                                               pr_cont(" %s", media[i-5]);
-                               pr_cont("\n");
-                       }
-
-                       tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
-                                       TLAN_LED_LINK);
-#ifdef MONITOR
-                       /* We have link beat..for now anyway */
-                       priv->link = 1;
-                       /*Enabling link beat monitoring */
-                       tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT);
-#endif
-               } else if (status & MII_GS_LINK)  {
-                       netdev_info(dev, "Link active\n");
-                       tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
-                                       TLAN_LED_LINK);
-               }
-       }
-
-       if (priv->phy_num == 0) {
-               tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
-               tlphy_ctl |= TLAN_TC_INTEN;
-               tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
-               sio = tlan_dio_read8(dev->base_addr, TLAN_NET_SIO);
-               sio |= TLAN_NET_SIO_MINTEN;
-               tlan_dio_write8(dev->base_addr, TLAN_NET_SIO, sio);
-       }
-
-       if (status & MII_GS_LINK) {
-               tlan_set_mac(dev, 0, dev->dev_addr);
-               priv->phy_online = 1;
-               outb((TLAN_HC_INT_ON >> 8), dev->base_addr + TLAN_HOST_CMD + 1);
-               if (debug >= 1 && debug != TLAN_DEBUG_PROBE)
-                       outb((TLAN_HC_REQ_INT >> 8),
-                            dev->base_addr + TLAN_HOST_CMD + 1);
-               outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM);
-               outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD);
-               netif_carrier_on(dev);
-       } else {
-               netdev_info(dev, "Link inactive, will retry in 10 secs...\n");
-               tlan_set_timer(dev, (10*HZ), TLAN_TIMER_FINISH_RESET);
-               return;
-       }
-       tlan_set_multicast_list(dev);
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_set_mac
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             dev     Pointer to device structure of adapter
- *                     on which to change the AREG.
- *             areg    The AREG to set the address in (0 - 3).
- *             mac     A pointer to an array of chars.  Each
- *                     element stores one byte of the address.
- *                     IE, it isn't in ascii.
- *
- *     This function transfers a MAC address to one of the
- *     TLAN AREGs (address registers).  The TLAN chip locks
- *     the register on writing to offset 0 and unlocks the
- *     register after writing to offset 5.  If NULL is passed
- *     in mac, then the AREG is filled with 0's.
- *
- **************************************************************/
-
-static void tlan_set_mac(struct net_device *dev, int areg, char *mac)
-{
-       int i;
-
-       areg *= 6;
-
-       if (mac != NULL) {
-               for (i = 0; i < 6; i++)
-                       tlan_dio_write8(dev->base_addr,
-                                       TLAN_AREG_0 + areg + i, mac[i]);
-       } else {
-               for (i = 0; i < 6; i++)
-                       tlan_dio_write8(dev->base_addr,
-                                       TLAN_AREG_0 + areg + i, 0);
-       }
-
-}
-
-
-
-
-/*****************************************************************************
-******************************************************************************
-
-ThunderLAN driver PHY layer routines
-
-******************************************************************************
-*****************************************************************************/
-
-
-
-/*********************************************************************
- *     tlan_phy_print
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             dev     A pointer to the device structure of the
- *                     TLAN device having the PHYs to be detailed.
- *
- *     This function prints the registers a PHY (aka transceiver).
- *
- ********************************************************************/
-
-static void tlan_phy_print(struct net_device *dev)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-       u16 i, data0, data1, data2, data3, phy;
-
-       phy = priv->phy[priv->phy_num];
-
-       if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
-               netdev_info(dev, "Unmanaged PHY\n");
-       } else if (phy <= TLAN_PHY_MAX_ADDR) {
-               netdev_info(dev, "PHY 0x%02x\n", phy);
-               pr_info("   Off.  +0     +1     +2     +3\n");
-               for (i = 0; i < 0x20; i += 4) {
-                       tlan_mii_read_reg(dev, phy, i, &data0);
-                       tlan_mii_read_reg(dev, phy, i + 1, &data1);
-                       tlan_mii_read_reg(dev, phy, i + 2, &data2);
-                       tlan_mii_read_reg(dev, phy, i + 3, &data3);
-                       pr_info("   0x%02x 0x%04hx 0x%04hx 0x%04hx 0x%04hx\n",
-                               i, data0, data1, data2, data3);
-               }
-       } else {
-               netdev_info(dev, "Invalid PHY\n");
-       }
-
-}
-
-
-
-
-/*********************************************************************
- *     tlan_phy_detect
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             dev     A pointer to the device structure of the adapter
- *                     for which the PHY needs determined.
- *
- *     So far I've found that adapters which have external PHYs
- *     may also use the internal PHY for part of the functionality.
- *     (eg, AUI/Thinnet).  This function finds out if this TLAN
- *     chip has an internal PHY, and then finds the first external
- *     PHY (starting from address 0) if it exists).
- *
- ********************************************************************/
-
-static void tlan_phy_detect(struct net_device *dev)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-       u16             control;
-       u16             hi;
-       u16             lo;
-       u32             phy;
-
-       if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
-               priv->phy_num = 0xffff;
-               return;
-       }
-
-       tlan_mii_read_reg(dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi);
-
-       if (hi != 0xffff)
-               priv->phy[0] = TLAN_PHY_MAX_ADDR;
-       else
-               priv->phy[0] = TLAN_PHY_NONE;
-
-       priv->phy[1] = TLAN_PHY_NONE;
-       for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) {
-               tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &control);
-               tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &hi);
-               tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &lo);
-               if ((control != 0xffff) ||
-                   (hi != 0xffff) || (lo != 0xffff)) {
-                       TLAN_DBG(TLAN_DEBUG_GNRL,
-                                "PHY found at %02x %04x %04x %04x\n",
-                                phy, control, hi, lo);
-                       if ((priv->phy[1] == TLAN_PHY_NONE) &&
-                           (phy != TLAN_PHY_MAX_ADDR)) {
-                               priv->phy[1] = phy;
-                       }
-               }
-       }
-
-       if (priv->phy[1] != TLAN_PHY_NONE)
-               priv->phy_num = 1;
-       else if (priv->phy[0] != TLAN_PHY_NONE)
-               priv->phy_num = 0;
-       else
-               netdev_info(dev, "Cannot initialize device, no PHY was found!\n");
-
-}
-
-
-
-
-static void tlan_phy_power_down(struct net_device *dev)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       u16             value;
-
-       TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name);
-       value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
-       tlan_mii_sync(dev->base_addr);
-       tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
-       if ((priv->phy_num == 0) &&
-           (priv->phy[1] != TLAN_PHY_NONE) &&
-           (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) {
-               tlan_mii_sync(dev->base_addr);
-               tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value);
-       }
-
-       /* Wait for 50 ms and powerup
-        * This is abitrary.  It is intended to make sure the
-        * transceiver settles.
-        */
-       tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_PUP);
-
-}
-
-
-
-
-static void tlan_phy_power_up(struct net_device *dev)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       u16             value;
-
-       TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name);
-       tlan_mii_sync(dev->base_addr);
-       value = MII_GC_LOOPBK;
-       tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
-       tlan_mii_sync(dev->base_addr);
-       /* Wait for 500 ms and reset the
-        * transceiver.  The TLAN docs say both 50 ms and
-        * 500 ms, so do the longer, just in case.
-        */
-       tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_RESET);
-
-}
-
-
-
-
-static void tlan_phy_reset(struct net_device *dev)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       u16             phy;
-       u16             value;
-
-       phy = priv->phy[priv->phy_num];
-
-       TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name);
-       tlan_mii_sync(dev->base_addr);
-       value = MII_GC_LOOPBK | MII_GC_RESET;
-       tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value);
-       tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
-       while (value & MII_GC_RESET)
-               tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
-
-       /* Wait for 500 ms and initialize.
-        * I don't remember why I wait this long.
-        * I've changed this to 50ms, as it seems long enough.
-        */
-       tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_START_LINK);
-
-}
-
-
-
-
-static void tlan_phy_start_link(struct net_device *dev)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       u16             ability;
-       u16             control;
-       u16             data;
-       u16             phy;
-       u16             status;
-       u16             tctl;
-
-       phy = priv->phy[priv->phy_num];
-       TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name);
-       tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
-       tlan_mii_read_reg(dev, phy, MII_GEN_STS, &ability);
-
-       if ((status & MII_GS_AUTONEG) &&
-           (!priv->aui)) {
-               ability = status >> 11;
-               if (priv->speed  == TLAN_SPEED_10 &&
-                   priv->duplex == TLAN_DUPLEX_HALF) {
-                       tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0000);
-               } else if (priv->speed == TLAN_SPEED_10 &&
-                          priv->duplex == TLAN_DUPLEX_FULL) {
-                       priv->tlan_full_duplex = true;
-                       tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0100);
-               } else if (priv->speed == TLAN_SPEED_100 &&
-                          priv->duplex == TLAN_DUPLEX_HALF) {
-                       tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2000);
-               } else if (priv->speed == TLAN_SPEED_100 &&
-                          priv->duplex == TLAN_DUPLEX_FULL) {
-                       priv->tlan_full_duplex = true;
-                       tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2100);
-               } else {
-
-                       /* Set Auto-Neg advertisement */
-                       tlan_mii_write_reg(dev, phy, MII_AN_ADV,
-                                          (ability << 5) | 1);
-                       /* Enablee Auto-Neg */
-                       tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1000);
-                       /* Restart Auto-Neg */
-                       tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1200);
-                       /* Wait for 4 sec for autonegotiation
-                        * to complete.  The max spec time is less than this
-                        * but the card need additional time to start AN.
-                        * .5 sec should be plenty extra.
-                        */
-                       netdev_info(dev, "Starting autonegotiation\n");
-                       tlan_set_timer(dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN);
-                       return;
-               }
-
-       }
-
-       if ((priv->aui) && (priv->phy_num != 0)) {
-               priv->phy_num = 0;
-               data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
-                       | TLAN_NET_CFG_PHY_EN;
-               tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
-               tlan_set_timer(dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN);
-               return;
-       } else if (priv->phy_num == 0) {
-               control = 0;
-               tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tctl);
-               if (priv->aui) {
-                       tctl |= TLAN_TC_AUISEL;
-               } else {
-                       tctl &= ~TLAN_TC_AUISEL;
-                       if (priv->duplex == TLAN_DUPLEX_FULL) {
-                               control |= MII_GC_DUPLEX;
-                               priv->tlan_full_duplex = true;
-                       }
-                       if (priv->speed == TLAN_SPEED_100)
-                               control |= MII_GC_SPEEDSEL;
-               }
-               tlan_mii_write_reg(dev, phy, MII_GEN_CTL, control);
-               tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tctl);
-       }
-
-       /* Wait for 2 sec to give the transceiver time
-        * to establish link.
-        */
-       tlan_set_timer(dev, (4*HZ), TLAN_TIMER_FINISH_RESET);
-
-}
-
-
-
-
-static void tlan_phy_finish_auto_neg(struct net_device *dev)
-{
-       struct tlan_priv        *priv = netdev_priv(dev);
-       u16             an_adv;
-       u16             an_lpa;
-       u16             data;
-       u16             mode;
-       u16             phy;
-       u16             status;
-
-       phy = priv->phy[priv->phy_num];
-
-       tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
-       udelay(1000);
-       tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
-
-       if (!(status & MII_GS_AUTOCMPLT)) {
-               /* Wait for 8 sec to give the process
-                * more time.  Perhaps we should fail after a while.
-                */
-               if (!priv->neg_be_verbose++) {
-                       pr_info("Giving autonegotiation more time.\n");
-                       pr_info("Please check that your adapter has\n");
-                       pr_info("been properly connected to a HUB or Switch.\n");
-                       pr_info("Trying to establish link in the background...\n");
-               }
-               tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN);
-               return;
-       }
-
-       netdev_info(dev, "Autonegotiation complete\n");
-       tlan_mii_read_reg(dev, phy, MII_AN_ADV, &an_adv);
-       tlan_mii_read_reg(dev, phy, MII_AN_LPA, &an_lpa);
-       mode = an_adv & an_lpa & 0x03E0;
-       if (mode & 0x0100)
-               priv->tlan_full_duplex = true;
-       else if (!(mode & 0x0080) && (mode & 0x0040))
-               priv->tlan_full_duplex = true;
-
-       if ((!(mode & 0x0180)) &&
-           (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) &&
-           (priv->phy_num != 0)) {
-               priv->phy_num = 0;
-               data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
-                       | TLAN_NET_CFG_PHY_EN;
-               tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
-               tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN);
-               return;
-       }
-
-       if (priv->phy_num == 0) {
-               if ((priv->duplex == TLAN_DUPLEX_FULL) ||
-                   (an_adv & an_lpa & 0x0040)) {
-                       tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
-                                          MII_GC_AUTOENB | MII_GC_DUPLEX);
-                       netdev_info(dev, "Starting internal PHY with FULL-DUPLEX\n");
-               } else {
-                       tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
-                                          MII_GC_AUTOENB);
-                       netdev_info(dev, "Starting internal PHY with HALF-DUPLEX\n");
-               }
-       }
-
-       /* Wait for 100 ms.  No reason in partiticular.
-        */
-       tlan_set_timer(dev, (HZ/10), TLAN_TIMER_FINISH_RESET);
-
-}
-
-#ifdef MONITOR
-
-/*********************************************************************
- *
- *     tlan_phy_monitor
- *
- *     Returns:
- *           None
- *
- *     Params:
- *           dev            The device structure of this device.
- *
- *
- *     This function monitors PHY condition by reading the status
- *     register via the MII bus. This can be used to give info
- *     about link changes (up/down), and possible switch to alternate
- *     media.
- *
- *******************************************************************/
-
-void tlan_phy_monitor(struct net_device *dev)
-{
-       struct tlan_priv *priv = netdev_priv(dev);
-       u16     phy;
-       u16     phy_status;
-
-       phy = priv->phy[priv->phy_num];
-
-       /* Get PHY status register */
-       tlan_mii_read_reg(dev, phy, MII_GEN_STS, &phy_status);
-
-       /* Check if link has been lost */
-       if (!(phy_status & MII_GS_LINK)) {
-               if (priv->link) {
-                       priv->link = 0;
-                       printk(KERN_DEBUG "TLAN: %s has lost link\n",
-                              dev->name);
-                       netif_carrier_off(dev);
-                       tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
-                       return;
-               }
-       }
-
-       /* Link restablished? */
-       if ((phy_status & MII_GS_LINK) && !priv->link) {
-               priv->link = 1;
-               printk(KERN_DEBUG "TLAN: %s has reestablished link\n",
-                      dev->name);
-               netif_carrier_on(dev);
-       }
-
-       /* Setup a new monitor */
-       tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
-}
-
-#endif /* MONITOR */
-
-
-/*****************************************************************************
-******************************************************************************
-
-ThunderLAN driver MII routines
-
-these routines are based on the information in chap. 2 of the
-"ThunderLAN Programmer's Guide", pp. 15-24.
-
-******************************************************************************
-*****************************************************************************/
-
-
-/***************************************************************
- *     tlan_mii_read_reg
- *
- *     Returns:
- *             false   if ack received ok
- *             true    if no ack received or other error
- *
- *     Parms:
- *             dev             The device structure containing
- *                             The io address and interrupt count
- *                             for this device.
- *             phy             The address of the PHY to be queried.
- *             reg             The register whose contents are to be
- *                             retrieved.
- *             val             A pointer to a variable to store the
- *                             retrieved value.
- *
- *     This function uses the TLAN's MII bus to retrieve the contents
- *     of a given register on a PHY.  It sends the appropriate info
- *     and then reads the 16-bit register value from the MII bus via
- *     the TLAN SIO register.
- *
- **************************************************************/
-
-static bool
-tlan_mii_read_reg(struct net_device *dev, u16 phy, u16 reg, u16 *val)
-{
-       u8      nack;
-       u16     sio, tmp;
-       u32     i;
-       bool    err;
-       int     minten;
-       struct tlan_priv *priv = netdev_priv(dev);
-       unsigned long flags = 0;
-
-       err = false;
-       outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
-       sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
-
-       if (!in_irq())
-               spin_lock_irqsave(&priv->lock, flags);
-
-       tlan_mii_sync(dev->base_addr);
-
-       minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
-       if (minten)
-               tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
-
-       tlan_mii_send_data(dev->base_addr, 0x1, 2);     /* start (01b) */
-       tlan_mii_send_data(dev->base_addr, 0x2, 2);     /* read  (10b) */
-       tlan_mii_send_data(dev->base_addr, phy, 5);     /* device #      */
-       tlan_mii_send_data(dev->base_addr, reg, 5);     /* register #    */
-
-
-       tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio);        /* change direction */
-
-       tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);         /* clock idle bit */
-       tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
-       tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);         /* wait 300ns */
-
-       nack = tlan_get_bit(TLAN_NET_SIO_MDATA, sio);   /* check for ACK */
-       tlan_set_bit(TLAN_NET_SIO_MCLK, sio);           /* finish ACK */
-       if (nack) {                                     /* no ACK, so fake it */
-               for (i = 0; i < 16; i++) {
-                       tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
-                       tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
-               }
-               tmp = 0xffff;
-               err = true;
-       } else {                                        /* ACK, so read data */
-               for (tmp = 0, i = 0x8000; i; i >>= 1) {
-                       tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
-                       if (tlan_get_bit(TLAN_NET_SIO_MDATA, sio))
-                               tmp |= i;
-                       tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
-               }
-       }
-
-
-       tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);         /* idle cycle */
-       tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
-
-       if (minten)
-               tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
-
-       *val = tmp;
-
-       if (!in_irq())
-               spin_unlock_irqrestore(&priv->lock, flags);
-
-       return err;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_mii_send_data
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             base_port       The base IO port of the adapter in
- *                             question.
- *             dev             The address of the PHY to be queried.
- *             data            The value to be placed on the MII bus.
- *             num_bits        The number of bits in data that are to
- *                             be placed on the MII bus.
- *
- *     This function sends on sequence of bits on the MII
- *     configuration bus.
- *
- **************************************************************/
-
-static void tlan_mii_send_data(u16 base_port, u32 data, unsigned num_bits)
-{
-       u16 sio;
-       u32 i;
-
-       if (num_bits == 0)
-               return;
-
-       outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
-       sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
-       tlan_set_bit(TLAN_NET_SIO_MTXEN, sio);
-
-       for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {
-               tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
-               (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
-               if (data & i)
-                       tlan_set_bit(TLAN_NET_SIO_MDATA, sio);
-               else
-                       tlan_clear_bit(TLAN_NET_SIO_MDATA, sio);
-               tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
-               (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
-       }
-
-}
-
-
-
-
-/***************************************************************
- *     TLan_MiiSync
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             base_port       The base IO port of the adapter in
- *                             question.
- *
- *     This functions syncs all PHYs in terms of the MII configuration
- *     bus.
- *
- **************************************************************/
-
-static void tlan_mii_sync(u16 base_port)
-{
-       int i;
-       u16 sio;
-
-       outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
-       sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
-
-       tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio);
-       for (i = 0; i < 32; i++) {
-               tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
-               tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
-       }
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_mii_write_reg
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             dev             The device structure for the device
- *                             to write to.
- *             phy             The address of the PHY to be written to.
- *             reg             The register whose contents are to be
- *                             written.
- *             val             The value to be written to the register.
- *
- *     This function uses the TLAN's MII bus to write the contents of a
- *     given register on a PHY.  It sends the appropriate info and then
- *     writes the 16-bit register value from the MII configuration bus
- *     via the TLAN SIO register.
- *
- **************************************************************/
-
-static void
-tlan_mii_write_reg(struct net_device *dev, u16 phy, u16 reg, u16 val)
-{
-       u16     sio;
-       int     minten;
-       unsigned long flags = 0;
-       struct tlan_priv *priv = netdev_priv(dev);
-
-       outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
-       sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
-
-       if (!in_irq())
-               spin_lock_irqsave(&priv->lock, flags);
-
-       tlan_mii_sync(dev->base_addr);
-
-       minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
-       if (minten)
-               tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
-
-       tlan_mii_send_data(dev->base_addr, 0x1, 2);     /* start (01b) */
-       tlan_mii_send_data(dev->base_addr, 0x1, 2);     /* write (01b) */
-       tlan_mii_send_data(dev->base_addr, phy, 5);     /* device #      */
-       tlan_mii_send_data(dev->base_addr, reg, 5);     /* register #    */
-
-       tlan_mii_send_data(dev->base_addr, 0x2, 2);     /* send ACK */
-       tlan_mii_send_data(dev->base_addr, val, 16);    /* send data */
-
-       tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
-       tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
-
-       if (minten)
-               tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
-
-       if (!in_irq())
-               spin_unlock_irqrestore(&priv->lock, flags);
-
-}
-
-
-
-
-/*****************************************************************************
-******************************************************************************
-
-ThunderLAN driver eeprom routines
-
-the Compaq netelligent 10 and 10/100 cards use a microchip 24C02A
-EEPROM.  these functions are based on information in microchip's
-data sheet.  I don't know how well this functions will work with
-other Eeproms.
-
-******************************************************************************
-*****************************************************************************/
-
-
-/***************************************************************
- *     tlan_ee_send_start
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             io_base         The IO port base address for the
- *                             TLAN device with the EEPROM to
- *                             use.
- *
- *     This function sends a start cycle to an EEPROM attached
- *     to a TLAN chip.
- *
- **************************************************************/
-
-static void tlan_ee_send_start(u16 io_base)
-{
-       u16     sio;
-
-       outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
-       sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
-
-       tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
-       tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
-       tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
-       tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
-       tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_ee_send_byte
- *
- *     Returns:
- *             If the correct ack was received, 0, otherwise 1
- *     Parms:  io_base         The IO port base address for the
- *                             TLAN device with the EEPROM to
- *                             use.
- *             data            The 8 bits of information to
- *                             send to the EEPROM.
- *             stop            If TLAN_EEPROM_STOP is passed, a
- *                             stop cycle is sent after the
- *                             byte is sent after the ack is
- *                             read.
- *
- *     This function sends a byte on the serial EEPROM line,
- *     driving the clock to send each bit. The function then
- *     reverses transmission direction and reads an acknowledge
- *     bit.
- *
- **************************************************************/
-
-static int tlan_ee_send_byte(u16 io_base, u8 data, int stop)
-{
-       int     err;
-       u8      place;
-       u16     sio;
-
-       outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
-       sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
-
-       /* Assume clock is low, tx is enabled; */
-       for (place = 0x80; place != 0; place >>= 1) {
-               if (place & data)
-                       tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
-               else
-                       tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
-               tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
-               tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
-       }
-       tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
-       tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
-       err = tlan_get_bit(TLAN_NET_SIO_EDATA, sio);
-       tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
-       tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
-
-       if ((!err) && stop) {
-               /* STOP, raise data while clock is high */
-               tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
-               tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
-               tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
-       }
-
-       return err;
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_ee_receive_byte
- *
- *     Returns:
- *             Nothing
- *     Parms:
- *             io_base         The IO port base address for the
- *                             TLAN device with the EEPROM to
- *                             use.
- *             data            An address to a char to hold the
- *                             data sent from the EEPROM.
- *             stop            If TLAN_EEPROM_STOP is passed, a
- *                             stop cycle is sent after the
- *                             byte is received, and no ack is
- *                             sent.
- *
- *     This function receives 8 bits of data from the EEPROM
- *     over the serial link.  It then sends and ack bit, or no
- *     ack and a stop bit.  This function is used to retrieve
- *     data after the address of a byte in the EEPROM has been
- *     sent.
- *
- **************************************************************/
-
-static void tlan_ee_receive_byte(u16 io_base, u8 *data, int stop)
-{
-       u8  place;
-       u16 sio;
-
-       outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
-       sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
-       *data = 0;
-
-       /* Assume clock is low, tx is enabled; */
-       tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
-       for (place = 0x80; place; place >>= 1) {
-               tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
-               if (tlan_get_bit(TLAN_NET_SIO_EDATA, sio))
-                       *data |= place;
-               tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
-       }
-
-       tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
-       if (!stop) {
-               tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); /* ack = 0 */
-               tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
-               tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
-       } else {
-               tlan_set_bit(TLAN_NET_SIO_EDATA, sio);  /* no ack = 1 (?) */
-               tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
-               tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
-               /* STOP, raise data while clock is high */
-               tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
-               tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
-               tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
-       }
-
-}
-
-
-
-
-/***************************************************************
- *     tlan_ee_read_byte
- *
- *     Returns:
- *             No error = 0, else, the stage at which the error
- *             occurred.
- *     Parms:
- *             io_base         The IO port base address for the
- *                             TLAN device with the EEPROM to
- *                             use.
- *             ee_addr         The address of the byte in the
- *                             EEPROM whose contents are to be
- *                             retrieved.
- *             data            An address to a char to hold the
- *                             data obtained from the EEPROM.
- *
- *     This function reads a byte of information from an byte
- *     cell in the EEPROM.
- *
- **************************************************************/
-
-static int tlan_ee_read_byte(struct net_device *dev, u8 ee_addr, u8 *data)
-{
-       int err;
-       struct tlan_priv *priv = netdev_priv(dev);
-       unsigned long flags = 0;
-       int ret = 0;
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       tlan_ee_send_start(dev->base_addr);
-       err = tlan_ee_send_byte(dev->base_addr, 0xa0, TLAN_EEPROM_ACK);
-       if (err) {
-               ret = 1;
-               goto fail;
-       }
-       err = tlan_ee_send_byte(dev->base_addr, ee_addr, TLAN_EEPROM_ACK);
-       if (err) {
-               ret = 2;
-               goto fail;
-       }
-       tlan_ee_send_start(dev->base_addr);
-       err = tlan_ee_send_byte(dev->base_addr, 0xa1, TLAN_EEPROM_ACK);
-       if (err) {
-               ret = 3;
-               goto fail;
-       }
-       tlan_ee_receive_byte(dev->base_addr, data, TLAN_EEPROM_STOP);
-fail:
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       return ret;
-
-}
-
-
-