fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / tulip / xircom_tulip_cb.c
index a01cc1b..a998c5d 100644 (file)
        410 Severn Ave., Suite 210
        Annapolis MD 21403
 
-       -----------------------------------------------------------
-
-       Linux kernel-specific changes:
-
-       LK1.0 (Ion Badulescu)
-       - Major cleanup
-       - Use 2.4 PCI API
-       - Support ethtool
-       - Rewrite perfect filter/hash code
-       - Use interrupts for media changes
-
-       LK1.1 (Ion Badulescu)
-       - Disallow negotiation of unsupported full-duplex modes
 */
 
 #define DRV_NAME       "xircom_tulip_cb"
-#define DRV_VERSION    "0.91+LK1.1"
-#define DRV_RELDATE    "October 11, 2001"
-
-#define CARDBUS 1
+#define DRV_VERSION    "0.92"
+#define DRV_RELDATE    "June 27, 2006"
 
 /* A few user-configurable values. */
 
+#define xircom_debug debug
+#ifdef XIRCOM_DEBUG
+static int xircom_debug = XIRCOM_DEBUG;
+#else
+static int xircom_debug = 1;
+#endif
+
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 25;
 
@@ -91,8 +83,8 @@ static int csr0 = 0x00A00000 | 0x4800;
 /* PCI registers */
 #define PCI_POWERMGMT  0x40
 
-#include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -116,22 +108,17 @@ KERN_INFO " unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDATE
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Xircom CBE-100 ethernet driver");
 MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRV_VERSION);
 
-MODULE_PARM(debug, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(csr0, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+module_param(debug, int, 0);
+module_param(max_interrupt_work, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(csr0, int, 0);
 
-#define RUN_AT(x) (jiffies + (x))
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
 
-#define xircom_debug debug
-#ifdef XIRCOM_DEBUG
-static int xircom_debug = XIRCOM_DEBUG;
-#else
-static int xircom_debug = 1;
-#endif
+#define RUN_AT(x) (jiffies + (x))
 
 /*
                                Theory of Operation
@@ -304,10 +291,10 @@ struct xircom_private {
        struct xircom_tx_desc tx_ring[TX_RING_SIZE];
        /* The saved address of a sent-in-place packet/buffer, for skfree(). */
        struct sk_buff* tx_skbuff[TX_RING_SIZE];
-#ifdef CARDBUS
+
        /* The X3201-3 requires 4-byte aligned tx bufs */
        struct sk_buff* tx_aligned_skbuff[TX_RING_SIZE];
-#endif
+
        /* The addresses of receive-in-place skbuffs. */
        struct sk_buff* rx_skbuff[RX_RING_SIZE];
        u16 setup_frame[PKT_SETUP_SZ / sizeof(u16)];    /* Pseudo-Tx frame to init address table. */
@@ -329,9 +316,6 @@ struct xircom_private {
        int saved_if_port;
        struct pci_dev *pdev;
        spinlock_t lock;
-#ifdef CONFIG_PM
-       u32 pci_state[16];
-#endif
 };
 
 static int mdio_read(struct net_device *dev, int phy_id, int location);
@@ -344,12 +328,13 @@ static void xircom_init_ring(struct net_device *dev);
 static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int xircom_rx(struct net_device *dev);
 static void xircom_media_change(struct net_device *dev);
-static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t xircom_interrupt(int irq, void *dev_instance);
 static int xircom_close(struct net_device *dev);
 static struct net_device_stats *xircom_get_stats(struct net_device *dev);
 static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void set_rx_mode(struct net_device *dev);
 static void check_duplex(struct net_device *dev);
+static const struct ethtool_ops ops;
 
 
 /* The Xircom cards are picky about when certain bits in CSR6 can be
@@ -450,7 +435,7 @@ static void __devinit read_mac_address(struct net_device *dev)
  */
 static void find_mii_transceivers(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        int phy, phy_idx;
 
        if (media_cap[tp->default_port] & MediaIsMII) {
@@ -505,7 +490,7 @@ static void find_mii_transceivers(struct net_device *dev)
  */
 static void transceiver_voodoo(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
 
        /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
@@ -584,9 +569,9 @@ static int __devinit xircom_init_one(struct pci_dev *pdev, const struct pci_devi
        /* Clear the missed-packet counter. */
        (volatile int)inl(ioaddr + CSR8);
 
-       tp = dev->priv;
+       tp = netdev_priv(dev);
 
-       tp->lock = SPIN_LOCK_UNLOCKED;
+       spin_lock_init(&tp->lock);
        tp->pdev = pdev;
        tp->chip_id = chip_idx;
        /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles. */
@@ -626,6 +611,7 @@ static int __devinit xircom_init_one(struct pci_dev *pdev, const struct pci_devi
 #endif
        dev->tx_timeout = xircom_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
+       SET_ETHTOOL_OPS(dev, &ops);
 
        transceiver_voodoo(dev);
 
@@ -749,14 +735,14 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
 static void
 xircom_up(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        int i;
 
        xircom_init_ring(dev);
        /* Clear the tx ring */
        for (i = 0; i < TX_RING_SIZE; i++) {
-               tp->tx_skbuff[i] = 0;
+               tp->tx_skbuff[i] = NULL;
                tp->tx_ring[i].status = 0;
        }
 
@@ -804,9 +790,9 @@ xircom_up(struct net_device *dev)
 static int
 xircom_open(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
 
-       if (request_irq(dev->irq, &xircom_interrupt, SA_SHIRQ, dev->name, dev))
+       if (request_irq(dev->irq, &xircom_interrupt, IRQF_SHARED, dev->name, dev))
                return -EAGAIN;
 
        xircom_up(dev);
@@ -818,7 +804,7 @@ xircom_open(struct net_device *dev)
 
 static void xircom_tx_timeout(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
 
        if (media_cap[dev->if_port] & MediaIsMII) {
@@ -870,7 +856,7 @@ static void xircom_tx_timeout(struct net_device *dev)
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
 static void xircom_init_ring(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        int i;
 
        tp->tx_full = 0;
@@ -897,20 +883,18 @@ static void xircom_init_ring(struct net_device *dev)
                        break;
                skb->dev = dev;                 /* Mark as being used by this device. */
                tp->rx_ring[i].status = Rx0DescOwned;   /* Owned by Xircom chip */
-               tp->rx_ring[i].buffer1 = virt_to_bus(skb->tail);
+               tp->rx_ring[i].buffer1 = virt_to_bus(skb->data);
        }
        tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 
        /* The Tx buffer descriptor is filled in as needed, but we
           do need to clear the ownership bit. */
        for (i = 0; i < TX_RING_SIZE; i++) {
-               tp->tx_skbuff[i] = 0;
+               tp->tx_skbuff[i] = NULL;
                tp->tx_ring[i].status = 0;
                tp->tx_ring[i].buffer2 = virt_to_bus(&tp->tx_ring[i+1]);
-#ifdef CARDBUS
                if (tp->chip_id == X3201_3)
                        tp->tx_aligned_skbuff[i] = dev_alloc_skb(PKT_BUF_SZ);
-#endif /* CARDBUS */
        }
        tp->tx_ring[i-1].buffer2 = virt_to_bus(&tp->tx_ring[0]);
 }
@@ -919,7 +903,7 @@ static void xircom_init_ring(struct net_device *dev)
 static int
 xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        int entry;
        u32 flag;
 
@@ -930,12 +914,10 @@ xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
        entry = tp->cur_tx % TX_RING_SIZE;
 
        tp->tx_skbuff[entry] = skb;
-#ifdef CARDBUS
        if (tp->chip_id == X3201_3) {
                memcpy(tp->tx_aligned_skbuff[entry]->data,skb->data,skb->len);
                tp->tx_ring[entry].buffer1 = virt_to_bus(tp->tx_aligned_skbuff[entry]->data);
        } else
-#endif
                tp->tx_ring[entry].buffer1 = virt_to_bus(skb->data);
 
        if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
@@ -971,7 +953,7 @@ xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static void xircom_media_change(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        u16 reg0, reg1, reg4, reg5;
        u32 csr6 = inl(ioaddr + CSR6), newcsr6;
@@ -1032,7 +1014,7 @@ static void xircom_media_change(struct net_device *dev)
 
 static void check_duplex(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        u16 reg0;
 
        mdio_write(dev, tp->phys[0], MII_BMCR, BMCR_RESET);
@@ -1062,10 +1044,10 @@ static void check_duplex(struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        int csr5, work_budget = max_interrupt_work;
        int handled = 0;
@@ -1128,7 +1110,7 @@ static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs
 
                                /* Free the original skb. */
                                dev_kfree_skb_irq(tp->tx_skbuff[entry]);
-                               tp->tx_skbuff[entry] = 0;
+                               tp->tx_skbuff[entry] = NULL;
                        }
 
 #ifndef final_version
@@ -1203,7 +1185,7 @@ static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs
 static int
 xircom_rx(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        int entry = tp->cur_rx % RX_RING_SIZE;
        int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
        int work_done = 0;
@@ -1289,7 +1271,7 @@ xircom_rx(struct net_device *dev)
                        if (skb == NULL)
                                break;
                        skb->dev = dev;                 /* Mark as being used by this device. */
-                       tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail);
+                       tp->rx_ring[entry].buffer1 = virt_to_bus(skb->data);
                        work_done++;
                }
                tp->rx_ring[entry].status = Rx0DescOwned;
@@ -1303,7 +1285,7 @@ static void
 xircom_down(struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
 
        /* Disable interrupts by clearing the interrupt mask. */
        outl(0, ioaddr + CSR7);
@@ -1321,7 +1303,7 @@ static int
 xircom_close(struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        int i;
 
        if (xircom_debug > 1)
@@ -1338,7 +1320,7 @@ xircom_close(struct net_device *dev)
        /* Free all the skbuffs in the Rx queue. */
        for (i = 0; i < RX_RING_SIZE; i++) {
                struct sk_buff *skb = tp->rx_skbuff[i];
-               tp->rx_skbuff[i] = 0;
+               tp->rx_skbuff[i] = NULL;
                tp->rx_ring[i].status = 0;              /* Not owned by Xircom chip. */
                tp->rx_ring[i].length = 0;
                tp->rx_ring[i].buffer1 = 0xBADF00D0; /* An invalid address. */
@@ -1349,7 +1331,7 @@ xircom_close(struct net_device *dev)
        for (i = 0; i < TX_RING_SIZE; i++) {
                if (tp->tx_skbuff[i])
                        dev_kfree_skb(tp->tx_skbuff[i]);
-               tp->tx_skbuff[i] = 0;
+               tp->tx_skbuff[i] = NULL;
        }
 
        tp->open = 0;
@@ -1359,7 +1341,7 @@ xircom_close(struct net_device *dev)
 
 static struct net_device_stats *xircom_get_stats(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
 
        if (netif_device_present(dev))
@@ -1368,18 +1350,10 @@ static struct net_device_stats *xircom_get_stats(struct net_device *dev)
        return &tp->stats;
 }
 
-
-static int xircom_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
+static int xircom_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
-       struct ethtool_cmd ecmd;
-       struct xircom_private *tp = dev->priv;
-
-       if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
-               return -EFAULT;
-
-       switch (ecmd.cmd) {
-       case ETHTOOL_GSET:
-               ecmd.supported =
+       struct xircom_private *tp = netdev_priv(dev);
+       ecmd->supported =
                        SUPPORTED_10baseT_Half |
                        SUPPORTED_10baseT_Full |
                        SUPPORTED_100baseT_Half |
@@ -1387,98 +1361,90 @@ static int xircom_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
                        SUPPORTED_Autoneg |
                        SUPPORTED_MII;
 
-               ecmd.advertising = ADVERTISED_MII;
-               if (tp->advertising[0] & ADVERTISE_10HALF)
-                       ecmd.advertising |= ADVERTISED_10baseT_Half;
-               if (tp->advertising[0] & ADVERTISE_10FULL)
-                       ecmd.advertising |= ADVERTISED_10baseT_Full;
-               if (tp->advertising[0] & ADVERTISE_100HALF)
-                       ecmd.advertising |= ADVERTISED_100baseT_Half;
-               if (tp->advertising[0] & ADVERTISE_100FULL)
-                       ecmd.advertising |= ADVERTISED_100baseT_Full;
-               if (tp->autoneg) {
-                       ecmd.advertising |= ADVERTISED_Autoneg;
-                       ecmd.autoneg = AUTONEG_ENABLE;
-               } else
-                       ecmd.autoneg = AUTONEG_DISABLE;
-
-               ecmd.port = PORT_MII;
-               ecmd.transceiver = XCVR_INTERNAL;
-               ecmd.phy_address = tp->phys[0];
-               ecmd.speed = tp->speed100 ? SPEED_100 : SPEED_10;
-               ecmd.duplex = tp->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
-               ecmd.maxtxpkt = TX_RING_SIZE / 2;
-               ecmd.maxrxpkt = 0;
-
-               if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
-                       return -EFAULT;
-               return 0;
+       ecmd->advertising = ADVERTISED_MII;
+       if (tp->advertising[0] & ADVERTISE_10HALF)
+               ecmd->advertising |= ADVERTISED_10baseT_Half;
+       if (tp->advertising[0] & ADVERTISE_10FULL)
+               ecmd->advertising |= ADVERTISED_10baseT_Full;
+       if (tp->advertising[0] & ADVERTISE_100HALF)
+               ecmd->advertising |= ADVERTISED_100baseT_Half;
+       if (tp->advertising[0] & ADVERTISE_100FULL)
+               ecmd->advertising |= ADVERTISED_100baseT_Full;
+       if (tp->autoneg) {
+               ecmd->advertising |= ADVERTISED_Autoneg;
+               ecmd->autoneg = AUTONEG_ENABLE;
+       } else
+               ecmd->autoneg = AUTONEG_DISABLE;
+
+       ecmd->port = PORT_MII;
+       ecmd->transceiver = XCVR_INTERNAL;
+       ecmd->phy_address = tp->phys[0];
+       ecmd->speed = tp->speed100 ? SPEED_100 : SPEED_10;
+       ecmd->duplex = tp->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+       ecmd->maxtxpkt = TX_RING_SIZE / 2;
+       ecmd->maxrxpkt = 0;
+       return 0;
+}
 
-       case ETHTOOL_SSET: {
-               u16 autoneg, speed100, full_duplex;
-
-               autoneg = (ecmd.autoneg == AUTONEG_ENABLE);
-               speed100 = (ecmd.speed == SPEED_100);
-               full_duplex = (ecmd.duplex == DUPLEX_FULL);
-
-               tp->autoneg = autoneg;
-               if (speed100 != tp->speed100 ||
-                   full_duplex != tp->full_duplex) {
-                       tp->speed100 = speed100;
-                       tp->full_duplex = full_duplex;
-                       /* change advertising bits */
-                       tp->advertising[0] &= ~(ADVERTISE_10HALF |
-                                            ADVERTISE_10FULL |
-                                            ADVERTISE_100HALF |
-                                            ADVERTISE_100FULL |
-                                            ADVERTISE_100BASE4);
-                       if (speed100) {
-                               if (full_duplex)
-                                       tp->advertising[0] |= ADVERTISE_100FULL;
-                               else
-                                       tp->advertising[0] |= ADVERTISE_100HALF;
-                       } else {
-                               if (full_duplex)
-                                       tp->advertising[0] |= ADVERTISE_10FULL;
-                               else
-                                       tp->advertising[0] |= ADVERTISE_10HALF;
-                       }
+static int xircom_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct xircom_private *tp = netdev_priv(dev);
+       u16 autoneg, speed100, full_duplex;
+
+       autoneg = (ecmd->autoneg == AUTONEG_ENABLE);
+       speed100 = (ecmd->speed == SPEED_100);
+       full_duplex = (ecmd->duplex == DUPLEX_FULL);
+
+       tp->autoneg = autoneg;
+       if (speed100 != tp->speed100 ||
+           full_duplex != tp->full_duplex) {
+               tp->speed100 = speed100;
+               tp->full_duplex = full_duplex;
+               /* change advertising bits */
+               tp->advertising[0] &= ~(ADVERTISE_10HALF |
+                                    ADVERTISE_10FULL |
+                                    ADVERTISE_100HALF |
+                                    ADVERTISE_100FULL |
+                                    ADVERTISE_100BASE4);
+               if (speed100) {
+                       if (full_duplex)
+                               tp->advertising[0] |= ADVERTISE_100FULL;
+                       else
+                               tp->advertising[0] |= ADVERTISE_100HALF;
+               } else {
+                       if (full_duplex)
+                               tp->advertising[0] |= ADVERTISE_10FULL;
+                       else
+                               tp->advertising[0] |= ADVERTISE_10HALF;
                }
-               check_duplex(dev);
-               return 0;
-       }
-
-       case ETHTOOL_GDRVINFO: {
-               struct ethtool_drvinfo info;
-               memset(&info, 0, sizeof(info));
-               info.cmd = ecmd.cmd;
-               strcpy(info.driver, DRV_NAME);
-               strcpy(info.version, DRV_VERSION);
-               *info.fw_version = 0;
-               strcpy(info.bus_info, pci_name(tp->pdev));
-               if (copy_to_user(useraddr, &info, sizeof(info)))
-                      return -EFAULT;
-               return 0;
        }
+       check_duplex(dev);
+       return 0;
+}
 
-       default:
-               return -EOPNOTSUPP;
-       }
+static void xircom_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       struct xircom_private *tp = netdev_priv(dev);
+       strcpy(info->driver, DRV_NAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->bus_info, pci_name(tp->pdev));
 }
 
+static const struct ethtool_ops ops = {
+       .get_settings = xircom_get_settings,
+       .set_settings = xircom_set_settings,
+       .get_drvinfo = xircom_get_drvinfo,
+};
 
 /* Provide ioctl() calls to examine the MII xcvr state. */
 static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        u16 *data = (u16 *)&rq->ifr_ifru;
        int phy = tp->phys[0] & 0x1f;
        unsigned long flags;
 
        switch(cmd) {
-       case SIOCETHTOOL:
-               return xircom_ethtool_ioctl(dev, rq->ifr_data);
-
        /* Legacy mii-diag interface */
        case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
                if (tp->mii_cnt)
@@ -1531,7 +1497,7 @@ static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
    when re-entered but still correct. */
 static void set_rx_mode(struct net_device *dev)
 {
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        struct dev_mc_list *mclist;
        long ioaddr = dev->base_addr;
        int csr6 = inl(ioaddr + CSR6);
@@ -1629,7 +1595,7 @@ static void set_rx_mode(struct net_device *dev)
 
                if (entry != 0) {
                        /* Avoid a chip errata by prefixing a dummy entry. */
-                       tp->tx_skbuff[entry] = 0;
+                       tp->tx_skbuff[entry] = NULL;
                        tp->tx_ring[entry].length =
                                (entry == TX_RING_SIZE - 1) ? Tx1RingWrap : 0;
                        tp->tx_ring[entry].buffer1 = 0;
@@ -1638,7 +1604,7 @@ static void set_rx_mode(struct net_device *dev)
                        entry = tp->cur_tx++ % TX_RING_SIZE;
                }
 
-               tp->tx_skbuff[entry] = 0;
+               tp->tx_skbuff[entry] = NULL;
                /* Put the setup frame on the Tx list. */
                if (entry == TX_RING_SIZE - 1)
                        tx_flags |= Tx1RingWrap;                /* Wrap ring. */
@@ -1669,15 +1635,15 @@ MODULE_DEVICE_TABLE(pci, xircom_pci_table);
 
 
 #ifdef CONFIG_PM
-static int xircom_suspend(struct pci_dev *pdev, u32 state)
+static int xircom_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        printk(KERN_INFO "xircom_suspend(%s)\n", dev->name);
        if (tp->open)
                xircom_down(dev);
 
-       pci_save_state(pdev, tp->pci_state);
+       pci_save_state(pdev);
        pci_disable_device(pdev);
        pci_set_power_state(pdev, 3);
 
@@ -1688,12 +1654,12 @@ static int xircom_suspend(struct pci_dev *pdev, u32 state)
 static int xircom_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       struct xircom_private *tp = dev->priv;
+       struct xircom_private *tp = netdev_priv(dev);
        printk(KERN_INFO "xircom_resume(%s)\n", dev->name);
 
        pci_set_power_state(pdev,0);
        pci_enable_device(pdev);
-       pci_restore_state(pdev, tp->pci_state);
+       pci_restore_state(pdev);
 
        /* Bring the chip out of sleep mode.
           Caution: Snooze mode does not work with some boards! */
@@ -1741,7 +1707,7 @@ static int __init xircom_init(void)
 #ifdef MODULE
        printk(version);
 #endif
-       return pci_module_init(&xircom_driver);
+       return pci_register_driver(&xircom_driver);
 }