Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / net / wireless / prism54 / islpci_dev.c
index d96d621..5ddf295 100644 (file)
@@ -19,7 +19,6 @@
  *
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 
 #include <linux/netdevice.h>
@@ -44,6 +43,7 @@
 
 static int prism54_bring_down(islpci_private *);
 static int islpci_alloc_memory(islpci_private *);
+static struct net_device_stats *islpci_statistics(struct net_device *);
 
 /* Temporary dummy MAC address to use until firmware is loaded.
  * The idea there is that some tools (such as nameif) may query
@@ -52,13 +52,13 @@ static int islpci_alloc_memory(islpci_private *);
  * Of course, this is not the final/real MAC address. It doesn't
  * matter, as you are suppose to be able to change it anytime via
  * ndev->set_mac_address. Jean II */
-const unsigned char    dummy_mac[6] = { 0x00, 0x30, 0xB4, 0x00, 0x00, 0x00 };
+static const unsigned char     dummy_mac[6] = { 0x00, 0x30, 0xB4, 0x00, 0x00, 0x00 };
 
 static int
 isl_upload_firmware(islpci_private *priv)
 {
        u32 reg, rc;
-       void *device_base = priv->device_base;
+       void __iomem *device_base = priv->device_base;
 
        /* clear the RAMBoot and the Reset bit */
        reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
@@ -105,7 +105,7 @@ isl_upload_firmware(islpci_private *priv)
                               "%s: firmware '%s' size is not multiple of 32bit, aborting!\n",
                               "prism54", priv->firmware);
                        release_firmware(fw_entry);
-                       return EILSEQ; /* Illegal byte sequence  */;
+                       return -EILSEQ; /* Illegal byte sequence  */;
                }
 
                while (fw_len > 0) {
@@ -113,7 +113,7 @@ isl_upload_firmware(islpci_private *priv)
                            (fw_len >
                             ISL38XX_MEMORY_WINDOW_SIZE) ?
                            ISL38XX_MEMORY_WINDOW_SIZE : fw_len;
-                       u32 *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
+                       u32 __iomem *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
 
                        /* set the cards base address for writting the data */
                        isl38xx_w32_flush(device_base, reg,
@@ -142,6 +142,10 @@ isl_upload_firmware(islpci_private *priv)
 
                BUG_ON(fw_len != 0);
 
+               /* Firmware version is at offset 40 (also for "newmac") */
+               printk(KERN_DEBUG "%s: firmware version: %.8s\n",
+                      priv->ndev->name, fw_entry->data + 40);
+
                release_firmware(fw_entry);
        }
 
@@ -183,7 +187,7 @@ islpci_interrupt(int irq, void *config, struct pt_regs *regs)
        u32 reg;
        islpci_private *priv = config;
        struct net_device *ndev = priv->ndev;
-       void *device = priv->device_base;
+       void __iomem *device = priv->device_base;
        int powerstate = ISL38XX_PSM_POWERSAVE_STATE;
 
        /* lock the interrupt handler */
@@ -375,8 +379,6 @@ islpci_open(struct net_device *ndev)
        u32 rc;
        islpci_private *priv = netdev_priv(ndev);
 
-       printk(KERN_DEBUG "%s: islpci_open()\n", ndev->name);
-
        /* reset data structures, upload firmware and reset device */
        rc = islpci_reset(priv,1);
        if (rc) {
@@ -405,7 +407,7 @@ islpci_close(struct net_device *ndev)
 static int
 prism54_bring_down(islpci_private *priv)
 {
-       void *device_base = priv->device_base;
+       void __iomem *device_base = priv->device_base;
        u32 reg;
        /* we are going to shutdown the device */
        islpci_set_state(priv, PRV_STATE_PREBOOT);
@@ -417,7 +419,7 @@ prism54_bring_down(islpci_private *priv)
         * currently in progress by emptying the TX and RX queues. */
 
        /* wait until interrupts have finished executing on other CPUs */
-       prism54_synchronize_irq(priv->pdev->irq);
+       synchronize_irq(priv->pdev->irq);
 
        reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
        reg &= ~(ISL38XX_CTRL_STAT_RESET | ISL38XX_CTRL_STAT_RAMBOOT);
@@ -436,8 +438,7 @@ prism54_bring_down(islpci_private *priv)
        wmb();
 
        /* wait a while for the device to reset */
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(50*HZ/1000);
+       schedule_timeout_uninterruptible(msecs_to_jiffies(50));
 
        return 0;
 }
@@ -462,8 +463,7 @@ islpci_upload_fw(islpci_private *priv)
                return rc;
        }
 
-       printk(KERN_DEBUG
-              "%s: firmware uploaded done, now triggering reset...\n",
+       printk(KERN_DEBUG "%s: firmware upload complete\n",
               priv->ndev->name);
 
        islpci_set_state(priv, PRV_STATE_POSTBOOT);
@@ -489,7 +489,7 @@ islpci_reset_if(islpci_private *priv)
                /* The software reset acknowledge needs about 220 msec here.
                 * Be conservative and wait for up to one second. */
        
-               remaining = schedule_timeout(HZ);
+               remaining = schedule_timeout_uninterruptible(HZ);
 
                if(remaining > 0) {
                        result = 0;
@@ -499,15 +499,16 @@ islpci_reset_if(islpci_private *priv)
                /* If we're here it's because our IRQ hasn't yet gone through. 
                 * Retry a bit more...
                 */
-                printk(KERN_ERR "%s: device soft reset timed out\n",
-                      priv->ndev->name);
-
+               printk(KERN_ERR "%s: no 'reset complete' IRQ seen - retrying\n",
+                       priv->ndev->name);
        }
 
        finish_wait(&priv->reset_done, &wait);
 
-       if(result)
+       if (result) {
+               printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
                return result;
+       }
 
        islpci_set_state(priv, PRV_STATE_INIT);
 
@@ -519,11 +520,17 @@ islpci_reset_if(islpci_private *priv)
        isl38xx_enable_common_interrupts(priv->device_base);
 
        down_write(&priv->mib_sem);
-       mgt_commit(priv);
+       result = mgt_commit(priv);
+       if (result) {
+               printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
+               up_write(&priv->mib_sem);
+               return result;
+       }
        up_write(&priv->mib_sem);
 
        islpci_set_state(priv, PRV_STATE_READY);
 
+       printk(KERN_DEBUG "%s: interface reset complete\n", priv->ndev->name);
        return 0;
 }
 
@@ -584,27 +591,27 @@ islpci_reset(islpci_private *priv, int reload_firmware)
        /* now that the data structures are cleaned up, upload
         * firmware and reset interface */
                rc = islpci_upload_fw(priv);
-               if (rc) 
+               if (rc) {
+                       printk(KERN_ERR "%s: islpci_reset: failure\n",
+                               priv->ndev->name);
                        return rc;
+               }
        }
 
        /* finally reset interface */
        rc = islpci_reset_if(priv);
-       if (!rc) /* If successful */
-               return rc;
-       
-       printk(KERN_DEBUG  "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n");
+       if (rc)
+               printk(KERN_ERR "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n");
        return rc;
-
 }
 
-struct net_device_stats *
+static struct net_device_stats *
 islpci_statistics(struct net_device *ndev)
 {
        islpci_private *priv = netdev_priv(ndev);
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
-       DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics \n");
+       DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics\n");
 #endif
 
        return &priv->statistics;
@@ -746,8 +753,7 @@ islpci_free_memory(islpci_private *priv)
                        pci_unmap_single(priv->pdev, buf->pci_addr,
                                         buf->size, PCI_DMA_FROMDEVICE);
                buf->pci_addr = 0;
-               if (buf->mem)
-                       kfree(buf->mem);
+               kfree(buf->mem);
                buf->size = 0;
                buf->mem = NULL;
         }
@@ -805,7 +811,6 @@ islpci_setup(struct pci_dev *pdev)
        ndev->open = &islpci_open;
        ndev->stop = &islpci_close;
        ndev->get_stats = &islpci_statistics;
-       ndev->get_wireless_stats = &prism54_get_wireless_stats;
        ndev->do_ioctl = &prism54_ioctl;
        ndev->wireless_handlers =
            (struct iw_handler_def *) &prism54_handler_def;
@@ -830,6 +835,10 @@ islpci_setup(struct pci_dev *pdev)
        priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
                priv->monitor_type : ARPHRD_ETHER;
 
+       /* Add pointers to enable iwspy support. */
+       priv->wireless_data.spy_data = &priv->spy_data;
+       ndev->wireless_data = &priv->wireless_data;
+
        /* save the start and end address of the PCI memory area */
        ndev->mem_start = (unsigned long) priv->device_base;
        ndev->mem_end = ndev->mem_start + ISL38XX_PCI_MEM_SIZE;