iwlwifi: fix rf_kill state inconsistent during suspend and resume
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl3945-base.c
index 4f22a7174caff31747511ced655ac0ce12a375cc..3d1da0759b977b0885220ce3a0404e452252033d 100644 (file)
@@ -2915,6 +2915,10 @@ static void iwl_set_rate(struct iwl_priv *priv)
        int i;
 
        hw = iwl_get_hw_mode(priv, priv->phymode);
+       if (!hw) {
+               IWL_ERROR("Failed to set rate: unable to get hw mode\n");
+               return;
+       }
 
        priv->active_rate = 0;
        priv->active_rate_basic = 0;
@@ -4739,8 +4743,10 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                 *   when we loaded driver, and is now set to "enable".
                 * After we're Alive, RF_KILL gets handled by
                 *   iwl_rx_card_state_notif() */
-               if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status))
+               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;
        }
@@ -4850,7 +4856,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
        if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
                /* Hardware disappeared */
                IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta);
-               goto none;
+               goto unplugged;
        }
 
        IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
@@ -4858,6 +4864,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
 
        /* iwl_irq_tasklet() will service interrupts and re-enable them */
        tasklet_schedule(&priv->irq_tasklet);
+unplugged:
        spin_unlock(&priv->lock);
 
        return IRQ_HANDLED;
@@ -5331,13 +5338,13 @@ static int iwl_init_geos(struct iwl_priv *priv)
        /* 5.2GHz channels start after the 2.4GHz channels */
        modes[A].mode = MODE_IEEE80211A;
        modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
-       modes[A].rates = rates;
+       modes[A].rates = &rates[4];
        modes[A].num_rates = 8; /* just OFDM */
        modes[A].num_channels = 0;
 
        modes[B].mode = MODE_IEEE80211B;
        modes[B].channels = channels;
-       modes[B].rates = &rates[8];
+       modes[B].rates = rates;
        modes[B].num_rates = 4; /* just CCK */
        modes[B].num_channels = 0;
 
@@ -6166,6 +6173,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
                mutex_lock(&priv->mutex);
 
                if (rc) {
+                       iwl_rate_control_unregister(priv->hw);
                        IWL_ERROR("Failed to register network "
                                  "device (error %d)\n", rc);
                        return;
@@ -6935,13 +6943,10 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
        DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_MAC80211("enter: id %d, type %d\n", conf->if_id, conf->type);
-       if (conf->mac_addr)
-               IWL_DEBUG_MAC80211("enter: MAC %s\n",
-                                  print_mac(mac, conf->mac_addr));
 
        if (priv->interface_id) {
                IWL_DEBUG_MAC80211("leave - interface_id != 0\n");
-               return 0;
+               return -EOPNOTSUPP;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -6950,6 +6955,12 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
        spin_unlock_irqrestore(&priv->lock, flags);
 
        mutex_lock(&priv->mutex);
+
+       if (conf->mac_addr) {
+               IWL_DEBUG_MAC80211("Set: %s\n", print_mac(mac, conf->mac_addr));
+               memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
+       }
+
        iwl_set_mode(priv, conf->type);
 
        IWL_DEBUG_MAC80211("leave\n");
@@ -8269,6 +8280,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 {
        iwl_hw_cancel_deferred_work(priv);
 
+       cancel_delayed_work_sync(&priv->init_alive_start);
        cancel_delayed_work(&priv->scan_check);
        cancel_delayed_work(&priv->alive_start);
        cancel_delayed_work(&priv->post_associate);
@@ -8354,6 +8366,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        SET_IEEE80211_DEV(hw, &pdev->dev);
 
+       hw->rate_control_algorithm = "iwl-3945-rs";
+
        IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
        priv = hw->priv;
        priv->hw = hw;
This page took 0.043239 seconds and 5 git commands to generate.