iwlwifi: rely on API version read from firmware
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl3945-base.c
index 0f992d0f69ad2187bc4a7749c4378a83b68d6e68..1d3efa9d01b451c6ae55367740858628fb2fefc0 100644 (file)
@@ -519,7 +519,7 @@ static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
 
 /*************** HOST COMMAND QUEUE FUNCTIONS   *****/
 
-#define IWL_CMD(x) case x : return #x
+#define IWL_CMD(x) case x: return #x
 
 static const char *get_cmd_string(u8 cmd)
 {
@@ -1418,9 +1418,16 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
        return priv->ibss_beacon->len;
 }
 
-static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
+static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
 {
        u8 i;
+       int rate_mask;
+
+       /* Set rate mask*/
+       if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+               rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
+       else
+               rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
 
        for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
             i = iwl3945_rates[i].next_ieee) {
@@ -1428,7 +1435,11 @@ static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
                        return iwl3945_rates[i].plcp;
        }
 
-       return IWL_RATE_INVALID;
+       /* No valid rate was found. Assign the lowest one */
+       if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+               return IWL_RATE_1M_PLCP;
+       else
+               return IWL_RATE_6M_PLCP;
 }
 
 static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
@@ -1446,16 +1457,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
                return -ENOMEM;
        }
 
-       if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {
-               rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic &
-                                               0xFF0);
-               if (rate == IWL_INVALID_RATE)
-                       rate = IWL_RATE_6M_PLCP;
-       } else {
-               rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
-               if (rate == IWL_INVALID_RATE)
-                       rate = IWL_RATE_1M_PLCP;
-       }
+       rate = iwl3945_rate_get_lowest_plcp(priv);
 
        frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
 
@@ -4309,35 +4311,6 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
        /* Safely ignore these bits for debug checks below */
        inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
 
-       /* HW RF KILL switch toggled (4965 only) */
-       if (inta & CSR_INT_BIT_RF_KILL) {
-               int hw_rf_kill = 0;
-               if (!(iwl3945_read32(priv, CSR_GP_CNTRL) &
-                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-                       hw_rf_kill = 1;
-
-               IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL | IWL_DL_ISR,
-                               "RF_KILL bit toggled to %s.\n",
-                               hw_rf_kill ? "disable radio":"enable radio");
-
-               /* Queue restart only if RF_KILL switch was set to "kill"
-                *   when we loaded driver, and is now set to "enable".
-                * After we're Alive, RF_KILL gets handled by
-                *   iwl3945_rx_card_state_notif() */
-               if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
-                       clear_bit(STATUS_RF_KILL_HW, &priv->status);
-                       queue_work(priv->workqueue, &priv->restart);
-               }
-
-               handled |= CSR_INT_BIT_RF_KILL;
-       }
-
-       /* Chip got too hot and stopped itself (4965 only) */
-       if (inta & CSR_INT_BIT_CT_KILL) {
-               IWL_ERROR("Microcode CT kill error detected.\n");
-               handled |= CSR_INT_BIT_CT_KILL;
-       }
-
        /* Error detected by uCode */
        if (inta & CSR_INT_BIT_SW_ERR) {
                IWL_ERROR("Microcode SW error detected.  Restarting 0x%X.\n",
@@ -4438,7 +4411,7 @@ static irqreturn_t iwl3945_isr(int irq, void *data)
 
        if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
                /* Hardware disappeared */
-               IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta);
+               IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
                goto unplugged;
        }
 
@@ -4741,7 +4714,7 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
 #define IWL_PASSIVE_DWELL_BASE      (100)
 #define IWL_CHANNEL_TUNE_TIME       5
 
-#define IWL_SCAN_PROBE_MASK(n)  cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+#define IWL_SCAN_PROBE_MASK(n)  (BIT(n) | (BIT(n) - BIT(1)))
 
 static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
                                                enum ieee80211_band band,
@@ -5323,25 +5296,41 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv)
 static int iwl3945_read_ucode(struct iwl3945_priv *priv)
 {
        struct iwl3945_ucode *ucode;
-       int ret = 0;
+       int ret = -EINVAL, index;
        const struct firmware *ucode_raw;
        /* firmware file name contains uCode/driver compatibility version */
-       const char *name = priv->cfg->fw_name;
+       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 ver, inst_size, data_size, init_size, init_data_size, boot_size;
+       u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size;
 
        /* Ask kernel firmware_class module to get the boot firmware off disk.
         * request_firmware() is synchronous, file is in memory on return. */
-       ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev);
-       if (ret < 0) {
-               IWL_ERROR("%s firmware file req failed: Reason %d\n",
-                               name, ret);
-               goto error;
+       for (index = api_max; index >= api_min; index--) {
+               sprintf(buf, "%s%u%s", name_pre, index, ".ucode");
+               ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
+               if (ret < 0) {
+                       IWL_ERROR("%s firmware file req failed: Reason %d\n",
+                                 buf, ret);
+                       if (ret == -ENOENT)
+                               continue;
+                       else
+                               goto error;
+               } else {
+                       if (index < api_max)
+                               IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+                                         buf, api_max);
+                       IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
+                                      buf, ucode_raw->size);
+                       break;
+               }
        }
 
-       IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
-                      name, ucode_raw->size);
+       if (ret < 0)
+               goto error;
 
        /* Make sure that we got at least our header! */
        if (ucode_raw->size < sizeof(*ucode)) {
@@ -5353,20 +5342,46 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
        /* Data from ucode file:  header followed by uCode images */
        ucode = (void *)ucode_raw->data;
 
-       ver = le32_to_cpu(ucode->ver);
+       priv->ucode_ver = le32_to_cpu(ucode->ver);
+       api_ver = IWL_UCODE_API(priv->ucode_ver);
        inst_size = le32_to_cpu(ucode->inst_size);
        data_size = le32_to_cpu(ucode->data_size);
        init_size = le32_to_cpu(ucode->init_size);
        init_data_size = le32_to_cpu(ucode->init_data_size);
        boot_size = le32_to_cpu(ucode->boot_size);
 
-       IWL_DEBUG_INFO("f/w package hdr ucode version = 0x%x\n", ver);
+       /* api_ver should match the api version forming part of the
+        * firmware filename ... but we don't check for that and only rely
+        * on the API version read from firware header from here on forward */
+
+       if (api_ver < api_min || api_ver > api_max) {
+               IWL_ERROR("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;
+       }
+       if (api_ver != api_max)
+               IWL_ERROR("Firmware has old API version. Expected %u, "
+                         "got %u. New firmware can be obtained "
+                         "from http://www.intellinuxwireless.org.\n",
+                         api_max, api_ver);
+
+       printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
+                      IWL_UCODE_MAJOR(priv->ucode_ver),
+                      IWL_UCODE_MINOR(priv->ucode_ver),
+                      IWL_UCODE_API(priv->ucode_ver),
+                      IWL_UCODE_SERIAL(priv->ucode_ver));
+       IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
+                      priv->ucode_ver);
        IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size);
        IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size);
        IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size);
        IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size);
        IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size);
 
+
        /* Verify size of file vs. image size info in file's header */
        if (ucode_raw->size < sizeof(*ucode) +
                inst_size + data_size + init_size +
@@ -5994,24 +6009,6 @@ static void iwl3945_bg_rf_kill(struct work_struct *work)
        iwl3945_rfkill_set_hw_state(priv);
 }
 
-static void iwl3945_bg_set_monitor(struct work_struct *work)
-{
-       struct iwl3945_priv *priv = container_of(work,
-                               struct iwl3945_priv, set_monitor);
-
-       IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n");
-
-       mutex_lock(&priv->mutex);
-
-       if (!iwl3945_is_ready(priv))
-               IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
-       else
-               if (iwl3945_set_mode(priv, NL80211_IFTYPE_MONITOR) != 0)
-                       IWL_ERROR("iwl3945_set_mode() failed\n");
-
-       mutex_unlock(&priv->mutex);
-}
-
 #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
 
 static void iwl3945_bg_scan_check(struct work_struct *data)
@@ -6337,10 +6334,7 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
 
        case NL80211_IFTYPE_ADHOC:
 
-               /* clear out the station table */
-               iwl3945_clear_stations_table(priv);
-
-               iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
+               priv->assoc_id = 1;
                iwl3945_add_station(priv, priv->bssid, 0, 0);
                iwl3945_sync_sta(priv, IWL_STA_ID,
                                 (priv->band == IEEE80211_BAND_5GHZ) ?
@@ -6828,16 +6822,43 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
                                 int mc_count, struct dev_addr_list *mc_list)
 {
        struct iwl3945_priv *priv = hw->priv;
+       __le32 *filter_flags = &priv->staging_rxon.filter_flags;
+
+       IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
+                       changed_flags, *total_flags);
 
-       if (changed_flags & (*total_flags) & FIF_OTHER_BSS) {
-               IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n",
-                                  NL80211_IFTYPE_MONITOR,
-                                  changed_flags, *total_flags);
-               /* queue work 'cuz mac80211 is holding a lock which
-                * prevents us from issuing (synchronous) f/w cmds */
-               queue_work(priv->workqueue, &priv->set_monitor);
+       if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
+               if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
+                       *filter_flags |= RXON_FILTER_PROMISC_MSK;
+               else
+                       *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
+       }
+       if (changed_flags & FIF_ALLMULTI) {
+               if (*total_flags & FIF_ALLMULTI)
+                       *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
+               else
+                       *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
+       }
+       if (changed_flags & FIF_CONTROL) {
+               if (*total_flags & FIF_CONTROL)
+                       *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
+               else
+                       *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
+       }
+       if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+               if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+                       *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
+               else
+                       *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
        }
-       *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI |
+
+       /* We avoid iwl_commit_rxon here to commit the new filter flags
+        * since mac80211 will call ieee80211_hw_config immediately.
+        * (mc_list is not supported at this time). Otherwise, we need to
+        * queue a background iwl_commit_rxon work.
+        */
+
+       *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
                        FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
 }
 
@@ -7713,7 +7734,6 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
        INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
        INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
        INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
-       INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor);
        INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
        INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
        INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
@@ -7785,6 +7805,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
        unsigned long flags;
 
+       /***********************
+        * 1. Allocating HW data
+        * ********************/
+
        /* Disabling hardware scan means that mac80211 will perform scans
         * "the hard way", rather than using device's scan. */
        if (iwl3945_param_disable_hw_scan) {
@@ -7808,48 +7832,41 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
                err = -ENOMEM;
                goto out;
        }
-       SET_IEEE80211_DEV(hw, &pdev->dev);
 
-       hw->rate_control_algorithm = "iwl-3945-rs";
-       hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
+       SET_IEEE80211_DEV(hw, &pdev->dev);
 
-       IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
        priv = hw->priv;
        priv->hw = hw;
-
        priv->pci_dev = pdev;
        priv->cfg = cfg;
 
+       IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
+       hw->rate_control_algorithm = "iwl-3945-rs";
+       hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
+
        /* Select antenna (may be helpful if only one antenna is connected) */
        priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
 #ifdef CONFIG_IWL3945_DEBUG
        iwl3945_debug_level = iwl3945_param_debug;
        atomic_set(&priv->restrict_refcnt, 0);
 #endif
-       priv->retry_rate = 1;
-
-       priv->ibss_beacon = NULL;
 
        /* Tell mac80211 our characteristics */
        hw->flags = IEEE80211_HW_SIGNAL_DBM |
                    IEEE80211_HW_NOISE_DBM;
 
        hw->wiphy->interface_modes =
-               BIT(NL80211_IFTYPE_AP) |
                BIT(NL80211_IFTYPE_STATION) |
                BIT(NL80211_IFTYPE_ADHOC);
 
+       hw->wiphy->fw_handles_regulatory = true;
+
        /* 4 EDCA QOS priorities */
        hw->queues = 4;
 
-       spin_lock_init(&priv->lock);
-       spin_lock_init(&priv->power_data.lock);
-       spin_lock_init(&priv->sta_lock);
-       spin_lock_init(&priv->hcmd_lock);
-
-       INIT_LIST_HEAD(&priv->free_frames);
-
-       mutex_init(&priv->mutex);
+       /***************************
+        * 2. Initializing PCI bus
+        * *************************/
        if (pci_enable_device(pdev)) {
                err = -ENODEV;
                goto out_ieee80211_free_hw;
@@ -7857,14 +7874,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        pci_set_master(pdev);
 
-       /* Clear the driver's (not device's) station table */
-       iwl3945_clear_stations_table(priv);
-
-       priv->data_retry_limit = -1;
-       priv->ieee_channels = NULL;
-       priv->ieee_rates = NULL;
-       priv->band = IEEE80211_BAND_2GHZ;
-
        err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        if (!err)
                err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
@@ -7878,10 +7887,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        if (err)
                goto out_pci_disable_device;
 
-       /* We disable the RETRY_TIMEOUT register (0x41) to keep
-        * PCI Tx retries from interfering with C3 CPU state */
-       pci_write_config_byte(pdev, 0x41, 0x00);
-
+       /***********************
+        * 3. Read REV Register
+        * ********************/
        priv->hw_base = pci_iomap(pdev, 0, 0);
        if (!priv->hw_base) {
                err = -ENODEV;
@@ -7892,25 +7900,70 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
                        (unsigned long long) pci_resource_len(pdev, 0));
        IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
 
-       /* Initialize module parameter values here */
+       /* We disable the RETRY_TIMEOUT register (0x41) to keep
+        * PCI Tx retries from interfering with C3 CPU state */
+       pci_write_config_byte(pdev, 0x41, 0x00);
 
-       /* Disable radio (SW RF KILL) via parameter when loading driver */
-       if (iwl3945_param_disable) {
-               set_bit(STATUS_RF_KILL_SW, &priv->status);
-               IWL_DEBUG_INFO("Radio disabled.\n");
-       }
+       /* nic init */
+       iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+                       CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 
-       priv->iw_mode = NL80211_IFTYPE_STATION;
+       iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+       err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
+                              CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+                              CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+       if (err < 0) {
+               IWL_DEBUG_INFO("Failed to init the card\n");
+               goto out_remove_sysfs;
+       }
 
-       printk(KERN_INFO DRV_NAME
-               ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
+       /***********************
+        * 4. Read EEPROM
+        * ********************/
+       /* Read the EEPROM */
+       err = iwl3945_eeprom_init(priv);
+       if (err) {
+               IWL_ERROR("Unable to init EEPROM\n");
+               goto out_remove_sysfs;
+       }
+       /* MAC Address location in EEPROM same for 3945/4965 */
+       get_eeprom_mac(priv, priv->mac_addr);
+       IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
+       SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
+       /***********************
+        * 5. Setup HW Constants
+        * ********************/
        /* Device-specific setup */
        if (iwl3945_hw_set_hw_setting(priv)) {
                IWL_ERROR("failed to set hw settings\n");
                goto out_iounmap;
        }
 
+       /***********************
+        * 6. Setup priv
+        * ********************/
+       priv->retry_rate = 1;
+       priv->ibss_beacon = NULL;
+
+       spin_lock_init(&priv->lock);
+       spin_lock_init(&priv->power_data.lock);
+       spin_lock_init(&priv->sta_lock);
+       spin_lock_init(&priv->hcmd_lock);
+
+       INIT_LIST_HEAD(&priv->free_frames);
+       mutex_init(&priv->mutex);
+
+       /* Clear the driver's (not device's) station table */
+       iwl3945_clear_stations_table(priv);
+
+       priv->data_retry_limit = -1;
+       priv->ieee_channels = NULL;
+       priv->ieee_rates = NULL;
+       priv->band = IEEE80211_BAND_2GHZ;
+
+       priv->iw_mode = NL80211_IFTYPE_STATION;
+
        if (iwl3945_param_qos_enable)
                priv->qos_data.qos_enable = 1;
 
@@ -7919,70 +7972,76 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        priv->qos_data.qos_active = 0;
        priv->qos_data.qos_cap.val = 0;
 
-       iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
-       iwl3945_setup_deferred_work(priv);
-       iwl3945_setup_rx_handlers(priv);
 
        priv->rates_mask = IWL_RATES_MASK;
        /* If power management is turned on, default to AC mode */
        priv->power_mode = IWL_POWER_AC;
        priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       iwl3945_disable_interrupts(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
+       err = iwl3945_init_channel_map(priv);
        if (err) {
-               IWL_ERROR("failed to create sysfs device attributes\n");
+               IWL_ERROR("initializing regulatory failed: %d\n", err);
                goto out_release_irq;
        }
 
-       /* nic init */
-       iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-                       CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-       iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-       err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
-                              CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-                              CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-       if (err < 0) {
-               IWL_DEBUG_INFO("Failed to init the card\n");
-               goto out_remove_sysfs;
-       }
-       /* Read the EEPROM */
-       err = iwl3945_eeprom_init(priv);
+       err = iwl3945_init_geos(priv);
        if (err) {
-               IWL_ERROR("Unable to init EEPROM\n");
-               goto out_remove_sysfs;
+               IWL_ERROR("initializing geos failed: %d\n", err);
+               goto out_free_channel_map;
        }
-       /* MAC Address location in EEPROM same for 3945/4965 */
-       get_eeprom_mac(priv, priv->mac_addr);
-       IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
-       SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
-       err = iwl3945_init_channel_map(priv);
-       if (err) {
-               IWL_ERROR("initializing regulatory failed: %d\n", err);
-               goto out_remove_sysfs;
+       printk(KERN_INFO DRV_NAME
+               ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
+
+       /***********************************
+        * 7. Initialize Module Parameters
+        * **********************************/
+
+       /* Initialize module parameter values here */
+       /* Disable radio (SW RF KILL) via parameter when loading driver */
+       if (iwl3945_param_disable) {
+               set_bit(STATUS_RF_KILL_SW, &priv->status);
+               IWL_DEBUG_INFO("Radio disabled.\n");
        }
 
-       err = iwl3945_init_geos(priv);
+
+       /***********************
+        * 8. Setup Services
+        * ********************/
+
+       spin_lock_irqsave(&priv->lock, flags);
+       iwl3945_disable_interrupts(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
        if (err) {
-               IWL_ERROR("initializing geos failed: %d\n", err);
-               goto out_free_channel_map;
+               IWL_ERROR("failed to create sysfs device attributes\n");
+               goto out_free_geos;
        }
 
+       iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
+       iwl3945_setup_deferred_work(priv);
+       iwl3945_setup_rx_handlers(priv);
+
+       /***********************
+        * 9. Conclude
+        * ********************/
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+
+       /*********************************
+        * 10. Setup and Register mac80211
+        * *******************************/
+
        err = ieee80211_register_hw(priv->hw);
        if (err) {
                IWL_ERROR("Failed to register network device (error %d)\n", err);
-               goto out_free_geos;
+               goto  out_remove_sysfs;
        }
 
        priv->hw->conf.beacon_int = 100;
        priv->mac80211_registered = 1;
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
+
 
        err = iwl3945_rfkill_init(priv);
        if (err)
@@ -7991,12 +8050,13 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        return 0;
 
+ out_remove_sysfs:
+       sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
  out_free_geos:
        iwl3945_free_geos(priv);
  out_free_channel_map:
        iwl3945_free_channel_map(priv);
- out_remove_sysfs:
-       sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
+
 
  out_release_irq:
        destroy_workqueue(priv->workqueue);
@@ -8280,7 +8340,7 @@ static void __exit iwl3945_exit(void)
        iwl3945_rate_control_unregister();
 }
 
-MODULE_FIRMWARE("iwlwifi-3945" IWL3945_UCODE_API ".ucode");
+MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
 
 module_param_named(antenna, iwl3945_param_antenna, int, 0444);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
This page took 0.035253 seconds and 5 git commands to generate.