include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / net / wireless / iwlwifi / iwl-agn.c
index d026828..5e0c6bf 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
@@ -1463,59 +1464,66 @@ static void iwl_nic_start(struct iwl_priv *priv)
 }
 
 
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
+static int iwl_mac_setup_register(struct iwl_priv *priv);
+
+static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
+{
+       const char *name_pre = priv->cfg->fw_name_pre;
+
+       if (first)
+               priv->fw_index = priv->cfg->ucode_api_max;
+       else
+               priv->fw_index--;
+
+       if (priv->fw_index < priv->cfg->ucode_api_min) {
+               IWL_ERR(priv, "no suitable firmware found!\n");
+               return -ENOENT;
+       }
+
+       sprintf(priv->firmware_name, "%s%d%s",
+               name_pre, priv->fw_index, ".ucode");
+
+       IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n",
+                      priv->firmware_name);
+
+       return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
+                                      &priv->pci_dev->dev, GFP_KERNEL, priv,
+                                      iwl_ucode_callback);
+}
+
 /**
- * iwl_read_ucode - Read uCode images from disk file.
+ * iwl_ucode_callback - callback when firmware was loaded
  *
- * Copy into buffers for card to fetch via bus-mastering
+ * If loaded successfully, copies the firmware into buffers
+ * for the card to fetch (via DMA).
  */
-static int iwl_read_ucode(struct iwl_priv *priv)
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 {
+       struct iwl_priv *priv = context;
        struct iwl_ucode_header *ucode;
-       int ret = -EINVAL, index;
-       const struct firmware *ucode_raw;
-       const char *name_pre = priv->cfg->fw_name_pre;
        const unsigned int api_max = priv->cfg->ucode_api_max;
        const unsigned int api_min = priv->cfg->ucode_api_min;
-       char buf[25];
        u8 *src;
        size_t len;
        u32 api_ver, build;
        u32 inst_size, data_size, init_size, init_data_size, boot_size;
+       int err;
        u16 eeprom_ver;
 
-       /* Ask kernel firmware_class module to get the boot firmware off disk.
-        * request_firmware() is synchronous, file is in memory on return. */
-       for (index = api_max; index >= api_min; index--) {
-               sprintf(buf, "%s%d%s", name_pre, index, ".ucode");
-               ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
-               if (ret < 0) {
-                       IWL_ERR(priv, "%s firmware file req failed: %d\n",
-                                 buf, ret);
-                       if (ret == -ENOENT)
-                               continue;
-                       else
-                               goto error;
-               } else {
-                       if (index < api_max)
-                               IWL_ERR(priv, "Loaded firmware %s, "
-                                       "which is deprecated. "
-                                       "Please use API v%u instead.\n",
-                                         buf, api_max);
-
-                       IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n",
-                                      buf, ucode_raw->size);
-                       break;
-               }
+       if (!ucode_raw) {
+               IWL_ERR(priv, "request for firmware file '%s' failed.\n",
+                       priv->firmware_name);
+               goto try_again;
        }
 
-       if (ret < 0)
-               goto error;
+       IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
+                      priv->firmware_name, ucode_raw->size);
 
        /* Make sure that we got at least the v1 header! */
        if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
                IWL_ERR(priv, "File size way too small!\n");
-               ret = -EINVAL;
-               goto err_release;
+               goto try_again;
        }
 
        /* Data from ucode file:  header followed by uCode images */
@@ -1540,10 +1548,9 @@ static int iwl_read_ucode(struct iwl_priv *priv)
                IWL_ERR(priv, "Driver unable to support your firmware API. "
                          "Driver supports v%u, firmware is v%u.\n",
                          api_max, api_ver);
-               priv->ucode_ver = 0;
-               ret = -EINVAL;
-               goto err_release;
+               goto try_again;
        }
+
        if (api_ver != api_max)
                IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
                          "got v%u. New firmware can be obtained "
@@ -1585,6 +1592,12 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
                       boot_size);
 
+       /*
+        * For any of the failures below (before allocating pci memory)
+        * we will try to load a version with a smaller API -- maybe the
+        * user just got a corrupted version of the latest API.
+        */
+
        /* Verify size of file vs. image size info in file's header */
        if (ucode_raw->size !=
                priv->cfg->ops->ucode->get_header_size(api_ver) +
@@ -1594,41 +1607,35 @@ static int iwl_read_ucode(struct iwl_priv *priv)
                IWL_DEBUG_INFO(priv,
                        "uCode file size %d does not match expected size\n",
                        (int)ucode_raw->size);
-               ret = -EINVAL;
-               goto err_release;
+               goto try_again;
        }
 
        /* Verify that uCode images will fit in card's SRAM */
        if (inst_size > priv->hw_params.max_inst_size) {
                IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
                               inst_size);
-               ret = -EINVAL;
-               goto err_release;
+               goto try_again;
        }
 
        if (data_size > priv->hw_params.max_data_size) {
                IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
                                data_size);
-               ret = -EINVAL;
-               goto err_release;
+               goto try_again;
        }
        if (init_size > priv->hw_params.max_inst_size) {
                IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
                        init_size);
-               ret = -EINVAL;
-               goto err_release;
+               goto try_again;
        }
        if (init_data_size > priv->hw_params.max_data_size) {
                IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
                      init_data_size);
-               ret = -EINVAL;
-               goto err_release;
+               goto try_again;
        }
        if (boot_size > priv->hw_params.max_bsm_size) {
                IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
                        boot_size);
-               ret = -EINVAL;
-               goto err_release;
+               goto try_again;
        }
 
        /* Allocate ucode buffers for card's bus-master loading ... */
@@ -1712,20 +1719,36 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
        memcpy(priv->ucode_boot.v_addr, src, len);
 
+       /**************************************************
+        * This is still part of probe() in a sense...
+        *
+        * 9. Setup and register with mac80211 and debugfs
+        **************************************************/
+       err = iwl_mac_setup_register(priv);
+       if (err)
+               goto out_unbind;
+
+       err = iwl_dbgfs_register(priv, DRV_NAME);
+       if (err)
+               IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
+
        /* We have our copies now, allow OS release its copies */
        release_firmware(ucode_raw);
-       return 0;
+       return;
+
+ try_again:
+       /* try next, if any */
+       if (iwl_request_firmware(priv, false))
+               goto out_unbind;
+       release_firmware(ucode_raw);
+       return;
 
  err_pci_alloc:
        IWL_ERR(priv, "failed to allocate pci memory\n");
-       ret = -ENOMEM;
        iwl_dealloc_ucode_pci(priv);
-
- err_release:
+ out_unbind:
+       device_release_driver(&priv->pci_dev->dev);
        release_firmware(ucode_raw);
-
- error:
-       return ret;
 }
 
 static const char *desc_lookup_text[] = {
@@ -2667,21 +2690,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
 
        /* we should be verifying the device is ready to be opened */
        mutex_lock(&priv->mutex);
-
-       /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
-        * ucode filename and max sizes are card-specific. */
-
-       if (!priv->ucode_code.len) {
-               ret = iwl_read_ucode(priv);
-               if (ret) {
-                       IWL_ERR(priv, "Could not read microcode: %d\n", ret);
-                       mutex_unlock(&priv->mutex);
-                       return ret;
-               }
-       }
-
        ret = __iwl_up(priv);
-
        mutex_unlock(&priv->mutex);
 
        if (ret)
@@ -3353,6 +3362,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
        INIT_LIST_HEAD(&priv->free_frames);
 
        mutex_init(&priv->mutex);
+       mutex_init(&priv->sync_cmd_mutex);
 
        /* Clear the driver's (not device's) station table */
        iwl_clear_stations_table(priv);
@@ -3365,6 +3375,12 @@ static int iwl_init_drv(struct iwl_priv *priv)
        priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
        priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
 
+       /* initialize force reset */
+       priv->force_reset[IWL_RF_RESET].reset_duration =
+               IWL_DELAY_NEXT_FORCE_RF_RESET;
+       priv->force_reset[IWL_FW_RESET].reset_duration =
+               IWL_DELAY_NEXT_FORCE_FW_RELOAD;
+
        /* Choose which receivers/antennas to use */
        if (priv->cfg->ops->hcmd->set_rxon_chain)
                priv->cfg->ops->hcmd->set_rxon_chain(priv);
@@ -3440,7 +3456,6 @@ static struct ieee80211_ops iwl_hw_ops = {
        .set_key = iwl_mac_set_key,
        .update_tkip_key = iwl_mac_update_tkip_key,
        .get_stats = iwl_mac_get_stats,
-       .get_tx_stats = iwl_mac_get_tx_stats,
        .conf_tx = iwl_mac_conf_tx,
        .reset_tsf = iwl_mac_reset_tsf,
        .bss_info_changed = iwl_bss_info_changed,
@@ -3541,6 +3556,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         */
        spin_lock_init(&priv->reg_lock);
        spin_lock_init(&priv->lock);
+
+       /*
+        * stop and reset the on-board processor just in case it is in a
+        * strange state ... like being left stranded by a primary kernel
+        * and this is now the kdump kernel trying to start up
+        */
+       iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+
        iwl_hw_detect(priv);
        IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
                priv->cfg->name, priv->hw_rev);
@@ -3640,17 +3663,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        iwl_power_initialize(priv);
        iwl_tt_initialize(priv);
 
-       /**************************************************
-        * 9. Setup and register with mac80211 and debugfs
-        **************************************************/
-       err = iwl_mac_setup_register(priv);
+       err = iwl_request_firmware(priv, true);
        if (err)
                goto out_remove_sysfs;
 
-       err = iwl_dbgfs_register(priv, DRV_NAME);
-       if (err)
-               IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
-
        return 0;
 
  out_remove_sysfs: