mac80211: use nl80211 interface types
[safe/jmp/linux-2.6] / drivers / net / wireless / iwlwifi / iwl-agn.c
index b8407d5..e8db33b 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -182,14 +181,14 @@ static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
 }
 
 /**
- * iwl4965_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
+ * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
  * @priv: staging_rxon is compared to active_rxon
  *
  * If the RXON structure is changing enough to require a new tune,
  * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
  * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
  */
-static int iwl4965_full_rxon_required(struct iwl_priv *priv)
+static int iwl_full_rxon_required(struct iwl_priv *priv)
 {
 
        /* These items are only settable from the full RXON command */
@@ -208,7 +207,6 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv)
             priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
            (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
             priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
-           (priv->staging_rxon.rx_chain != priv->active_rxon.rx_chain) ||
            (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
                return 1;
 
@@ -264,7 +262,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
        /* If we don't need to send a full RXON, we can use
         * iwl4965_rxon_assoc_cmd which is used to reconfigure filter
         * and other flags for the current radio configuration. */
-       if (!iwl4965_full_rxon_required(priv)) {
+       if (!iwl_full_rxon_required(priv)) {
                ret = iwl_send_rxon_assoc(priv);
                if (ret) {
                        IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret);
@@ -339,7 +337,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
        /* If we have set the ASSOC_MSK and we are in BSS mode then
         * add the IWL_AP_ID to the station rate table */
        if (new_assoc) {
-               if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
+               if (priv->iw_mode == NL80211_IFTYPE_STATION) {
                        ret = iwl_rxon_add_station(priv,
                                           priv->active_rxon.bssid_addr, 1);
                        if (ret == IWL_INVALID_STATION) {
@@ -450,8 +448,8 @@ static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
                                          const u8 *dest, int left)
 {
        if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
-           ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
-            (priv->iw_mode != IEEE80211_IF_TYPE_AP)))
+           ((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
+            (priv->iw_mode != NL80211_IFTYPE_AP)))
                return 0;
 
        if (priv->ibss_beacon->len > left)
@@ -487,7 +485,7 @@ static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
                return IWL_RATE_6M_PLCP;
 }
 
-unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
+static unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
                                       struct iwl_frame *frame, u8 rate)
 {
        struct iwl_tx_beacon_cmd *tx_beacon_cmd;
@@ -566,8 +564,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
        if (!iwl_conf->is_ht)
                return;
 
-       priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
-
        if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
                iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
        if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
@@ -588,8 +584,8 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
                iwl_conf->supported_chan_width = 0;
        }
 
-       iwl_conf->tx_mimo_ps_mode =
-               (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
+       iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
+
        memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
 
        iwl_conf->control_channel = ht_bss_conf->primary_channel;
@@ -676,7 +672,7 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
        beacon_int = priv->beacon_int;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
+       if (priv->iw_mode == NL80211_IFTYPE_STATION) {
                if (beacon_int == 0) {
                        priv->rxon_timing.beacon_interval = cpu_to_le16(100);
                        priv->rxon_timing.beacon_init_val = cpu_to_le32(102400);
@@ -725,7 +721,7 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv,
                else
                        priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
-               if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
+               if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
                        priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
                priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
@@ -744,23 +740,23 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
        memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
 
        switch (priv->iw_mode) {
-       case IEEE80211_IF_TYPE_AP:
+       case NL80211_IFTYPE_AP:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
                break;
 
-       case IEEE80211_IF_TYPE_STA:
+       case NL80211_IFTYPE_STATION:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
                priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
                break;
 
-       case IEEE80211_IF_TYPE_IBSS:
+       case NL80211_IFTYPE_ADHOC:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
                priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
                priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
                                                  RXON_FILTER_ACCEPT_GRP_MSK;
                break;
 
-       case IEEE80211_IF_TYPE_MNTR:
+       case NL80211_IFTYPE_MONITOR:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
                priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
                    RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
@@ -789,7 +785,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
         * in some case A channels are all non IBSS
         * in this case force B/G channel
         */
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
+       if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
            !(is_channel_ibss(ch_info)))
                ch_info = &priv->channel_info[0];
 
@@ -1186,7 +1182,7 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
                le32_to_cpu(beacon->low_tsf), rate);
 #endif
 
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
+       if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
            (!test_bit(STATUS_EXIT_PENDING, &priv->status)))
                queue_work(priv->workqueue, &priv->beacon_update);
 }
@@ -1274,7 +1270,7 @@ int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
 
        if (src == IWL_PWR_SRC_VAUX) {
                u32 val;
-               ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
+               ret = pci_read_config_dword(priv->pci_dev, PCI_CFG_POWER_SOURCE,
                                            &val);
 
                if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
@@ -2191,7 +2187,10 @@ static void __iwl4965_down(struct iwl_priv *priv)
        udelay(5);
 
        /* FIXME: apm_ops.suspend(priv) */
-       priv->cfg->ops->lib->apm_ops.reset(priv);
+       if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+               priv->cfg->ops->lib->apm_ops.stop(priv);
+       else
+               priv->cfg->ops->lib->apm_ops.reset(priv);
        priv->cfg->ops->lib->free_shared_mem(priv);
 
  exit:
@@ -2389,7 +2388,7 @@ static void iwl4965_bg_set_monitor(struct work_struct *work)
 
        mutex_lock(&priv->mutex);
 
-       ret = iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR);
+       ret = iwl4965_set_mode(priv, NL80211_IFTYPE_MONITOR);
 
        if (ret) {
                if (ret == -EAGAIN)
@@ -2470,7 +2469,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
        DECLARE_MAC_BUF(mac);
        unsigned long flags;
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
+       if (priv->iw_mode == NL80211_IFTYPE_AP) {
                IWL_ERROR("%s Should not be called in AP mode\n", __func__);
                return;
        }
@@ -2487,6 +2486,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
        if (!priv->vif || !priv->is_open)
                return;
 
+       iwl_power_cancel_timeout(priv);
        iwl_scan_cancel_timeout(priv, 200);
 
        conf = ieee80211_get_hw_conf(priv->hw);
@@ -2524,7 +2524,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
                else
                        priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
-               if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
+               if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
                        priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
        }
@@ -2532,10 +2532,10 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
        iwl4965_commit_rxon(priv);
 
        switch (priv->iw_mode) {
-       case IEEE80211_IF_TYPE_STA:
+       case NL80211_IFTYPE_STATION:
                break;
 
-       case IEEE80211_IF_TYPE_IBSS:
+       case NL80211_IFTYPE_ADHOC:
 
                /* assume default assoc id */
                priv->assoc_id = 1;
@@ -2551,18 +2551,23 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
                break;
        }
 
-       /* Enable Rx differential gain and sensitivity calibrations */
-       iwl_chain_noise_reset(priv);
-       priv->start_calib = 1;
-
-       if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
+       if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
                priv->assoc_station_added = 1;
 
        spin_lock_irqsave(&priv->lock, flags);
        iwl_activate_qos(priv, 0);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       iwl_power_update_mode(priv, 0);
+       /* the chain noise calibration will enabled PM upon completion
+        * If chain noise has already been run, then we need to enable
+        * power management here */
+       if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
+               iwl_power_enable_management(priv);
+
+       /* Enable Rx differential gain and sensitivity calibrations */
+       iwl_chain_noise_reset(priv);
+       priv->start_calib = 1;
+
        /* we have just associated, don't start scan too early */
        priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
 }
@@ -2603,6 +2608,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
 {
        struct iwl_priv *priv = hw->priv;
        int ret;
+       u16 pci_cmd;
 
        IWL_DEBUG_MAC80211("enter\n");
 
@@ -2613,6 +2619,13 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
        pci_restore_state(priv->pci_dev);
        pci_enable_msi(priv->pci_dev);
 
+       /* enable interrupts if needed: hw bug w/a */
+       pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
+       if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
+               pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+               pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
+       }
+
        ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED,
                          DRV_NAME, priv);
        if (ret) {
@@ -2719,13 +2732,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct iwl_priv *priv = hw->priv;
 
-       IWL_DEBUG_MAC80211("enter\n");
-
-       if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
-               IWL_DEBUG_MAC80211("leave - monitor\n");
-               dev_kfree_skb_any(skb);
-               return 0;
-       }
+       IWL_DEBUG_MACDUMP("enter\n");
 
        IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
                     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
@@ -2733,7 +2740,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        if (iwl_tx_skb(priv, skb))
                dev_kfree_skb_any(skb);
 
-       IWL_DEBUG_MAC80211("leave\n");
+       IWL_DEBUG_MACDUMP("leave\n");
        return 0;
 }
 
@@ -2791,8 +2798,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
 
-       priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
-
        if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {
                IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");
                goto out;
@@ -2823,7 +2828,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
                goto out;
        }
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
+       if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
            !is_channel_ibss(ch_info)) {
                IWL_ERROR("channel %d in band %d not IBSS channel\n",
                        conf->channel->hw_value, conf->channel->band);
@@ -2844,7 +2849,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
        )
                priv->staging_rxon.flags = 0;
 
-       iwl_set_rxon_channel(priv, conf->channel->band, channel);
+       iwl_set_rxon_channel(priv, conf->channel);
 
        iwl_set_flags_for_band(priv, conf->channel->band);
 
@@ -2938,7 +2943,7 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
                                priv->staging_rxon.flags &=
                                        ~RXON_FLG_SHORT_SLOT_MSK;
 
-                       if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
+                       if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
                                priv->staging_rxon.flags &=
                                        ~RXON_FLG_SHORT_SLOT_MSK;
                }
@@ -2977,7 +2982,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
                return 0;
        }
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
+       if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
            conf->changed & IEEE80211_IFCC_BEACON) {
                struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
                if (!beacon)
@@ -2987,7 +2992,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
                        return rc;
        }
 
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
+       if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
            (!conf->ssid_len)) {
                IWL_DEBUG_MAC80211
                    ("Leaving in AP mode because HostAPD is not ready.\n");
@@ -3010,7 +3015,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
            !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
  */
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
+       if (priv->iw_mode == NL80211_IFTYPE_AP) {
                if (!conf->bssid) {
                        conf->bssid = priv->mac_addr;
                        memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
@@ -3045,11 +3050,11 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
                 * to verify) - jpk */
                memcpy(priv->bssid, conf->bssid, ETH_ALEN);
 
-               if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
+               if (priv->iw_mode == NL80211_IFTYPE_AP)
                        iwl4965_config_ap(priv);
                else {
                        rc = iwl4965_commit_rxon(priv);
-                       if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc)
+                       if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
                                iwl_rxon_add_station(
                                        priv, priv->active_rxon.bssid_addr, 1);
                }
@@ -3085,7 +3090,7 @@ static void iwl4965_configure_filter(struct ieee80211_hw *hw,
 
        if (changed_flags & (*total_flags) & FIF_OTHER_BSS) {
                IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n",
-                                  IEEE80211_IF_TYPE_MNTR,
+                                  NL80211_IFTYPE_MONITOR,
                                   changed_flags, *total_flags);
                /* queue work 'cuz mac80211 is holding a lock which
                 * prevents us from issuing (synchronous) f/w cmds */
@@ -3182,9 +3187,9 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
 
 }
 
-static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
+static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
 {
-       int rc = 0;
+       int ret;
        unsigned long flags;
        struct iwl_priv *priv = hw->priv;
 
@@ -3194,41 +3199,40 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
        spin_lock_irqsave(&priv->lock, flags);
 
        if (!iwl_is_ready_rf(priv)) {
-               rc = -EIO;
+               ret = -EIO;
                IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
                goto out_unlock;
        }
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {    /* APs don't scan */
-               rc = -EIO;
+       if (priv->iw_mode == NL80211_IFTYPE_AP) {       /* APs don't scan */
+               ret = -EIO;
                IWL_ERROR("ERROR: APs don't scan\n");
                goto out_unlock;
        }
 
        /* we don't schedule scan within next_scan_jiffies period */
        if (priv->next_scan_jiffies &&
-                       time_after(priv->next_scan_jiffies, jiffies)) {
-               rc = -EAGAIN;
+           time_after(priv->next_scan_jiffies, jiffies)) {
+               IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
+               ret = -EAGAIN;
                goto out_unlock;
        }
        /* if we just finished scan ask for delay */
-       if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
-                               IWL_DELAY_NEXT_SCAN, jiffies)) {
-               rc = -EAGAIN;
+       if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
+           time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
+               IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
+               ret = -EAGAIN;
                goto out_unlock;
        }
-       if (len) {
-               IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
-                              iwl_escape_essid(ssid, len), (int)len);
-
+       if (ssid_len) {
                priv->one_direct_scan = 1;
-               priv->direct_ssid_len = (u8)
-                   min((u8) len, (u8) IW_ESSID_MAX_SIZE);
+               priv->direct_ssid_len =  min_t(u8, ssid_len, IW_ESSID_MAX_SIZE);
                memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
-       } else
+       } else {
                priv->one_direct_scan = 0;
+       }
 
-       rc = iwl_scan_initiate(priv);
+       ret = iwl_scan_initiate(priv);
 
        IWL_DEBUG_MAC80211("leave\n");
 
@@ -3236,7 +3240,7 @@ out_unlock:
        spin_unlock_irqrestore(&priv->lock, flags);
        mutex_unlock(&priv->mutex);
 
-       return rc;
+       return ret;
 }
 
 static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
@@ -3325,7 +3329,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
         * in 1X mode.
         * In legacy wep mode, we use another host command to the uCode */
        if (key->alg == ALG_WEP && sta_id == priv->hw_params.bcast_sta_id &&
-               priv->iw_mode != IEEE80211_IF_TYPE_AP) {
+               priv->iw_mode != NL80211_IFTYPE_AP) {
                if (cmd == SET_KEY)
                        is_default_wep_key = !priv->key_mapping_key;
                else
@@ -3396,7 +3400,7 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
        priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
        priv->qos_data.qos_active = 1;
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
+       if (priv->iw_mode == NL80211_IFTYPE_AP)
                iwl_activate_qos(priv, 1);
        else if (priv->assoc_id && iwl_is_associated(priv))
                iwl_activate_qos(priv, 0);
@@ -3514,7 +3518,7 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
 
        priv->beacon_int = priv->hw->conf.beacon_int;
        priv->timestamp = 0;
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_STA))
+       if ((priv->iw_mode == NL80211_IFTYPE_STATION))
                priv->beacon_int = 0;
 
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -3528,7 +3532,7 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
        /* we are restarting association process
         * clear RXON_FILTER_ASSOC_MSK bit
         */
-       if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
+       if (priv->iw_mode != NL80211_IFTYPE_AP) {
                iwl_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
                iwl4965_commit_rxon(priv);
@@ -3537,7 +3541,17 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
        iwl_power_update_mode(priv, 0);
 
        /* Per mac80211.h: This is only used in IBSS mode... */
-       if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
+       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
+
+               /* switch to CAM during association period.
+                * the ucode will block any association/authentication
+                * frome during assiciation period if it can not hear
+                * the AP because of PM. the timer enable PM back is
+                * association do not complete
+                */
+               if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
+                                                    IEEE80211_CHAN_RADAR))
+                               iwl_power_disable_management(priv, 3000);
 
                IWL_DEBUG_MAC80211("leave - not in IBSS\n");
                mutex_unlock(&priv->mutex);
@@ -3566,7 +3580,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
                return -EIO;
        }
 
-       if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
+       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
                IWL_DEBUG_MAC80211("leave - not IBSS\n");
                mutex_unlock(&priv->mutex);
                return -EIO;
@@ -3581,7 +3595,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
 
        priv->assoc_id = 0;
        timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
-       priv->timestamp = le64_to_cpu(timestamp) +  (priv->beacon_int * 1000);
+       priv->timestamp = le64_to_cpu(timestamp);
 
        IWL_DEBUG_MAC80211("leave\n");
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -3623,11 +3637,11 @@ static ssize_t store_debug_level(struct device *d,
                                 const char *buf, size_t count)
 {
        struct iwl_priv *priv = d->driver_data;
-       char *p = (char *)buf;
-       u32 val;
+       unsigned long val;
+       int ret;
 
-       val = simple_strtoul(p, &p, 0);
-       if (p == buf)
+       ret = strict_strtoul(buf, 0, &val);
+       if (ret)
                printk(KERN_INFO DRV_NAME
                       ": %s is not in hex or decimal form.\n", buf);
        else
@@ -3699,11 +3713,11 @@ static ssize_t store_tx_power(struct device *d,
                              const char *buf, size_t count)
 {
        struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
-       char *p = (char *)buf;
-       u32 val;
+       unsigned long val;
+       int ret;
 
-       val = simple_strtoul(p, &p, 10);
-       if (p == buf)
+       ret = strict_strtoul(buf, 10, &val);
+       if (ret)
                printk(KERN_INFO DRV_NAME
                       ": %s is not in decimal form.\n", buf);
        else
@@ -3727,7 +3741,12 @@ static ssize_t store_flags(struct device *d,
                           const char *buf, size_t count)
 {
        struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
-       u32 flags = simple_strtoul(buf, NULL, 0);
+       unsigned long val;
+       u32 flags;
+       int ret = strict_strtoul(buf, 0, &val);
+       if (ret)
+               return ret;
+       flags = (u32)val;
 
        mutex_lock(&priv->mutex);
        if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
@@ -3735,8 +3754,7 @@ static ssize_t store_flags(struct device *d,
                if (iwl_scan_cancel_timeout(priv, 100))
                        IWL_WARNING("Could not cancel scan.\n");
                else {
-                       IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
-                                      flags);
+                       IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags);
                        priv->staging_rxon.flags = cpu_to_le32(flags);
                        iwl4965_commit_rxon(priv);
                }
@@ -3762,7 +3780,12 @@ static ssize_t store_filter_flags(struct device *d,
                                  const char *buf, size_t count)
 {
        struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
-       u32 filter_flags = simple_strtoul(buf, NULL, 0);
+       unsigned long val;
+       u32 filter_flags;
+       int ret = strict_strtoul(buf, 0, &val);
+       if (ret)
+               return ret;
+       filter_flags = (u32)val;
 
        mutex_lock(&priv->mutex);
        if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
@@ -3863,10 +3886,12 @@ static ssize_t store_retry_rate(struct device *d,
                                const char *buf, size_t count)
 {
        struct iwl_priv *priv = dev_get_drvdata(d);
+       long val;
+       int ret  = strict_strtol(buf, 10, &val);
+       if (!ret)
+               return ret;
 
-       priv->retry_rate = simple_strtoul(buf, NULL, 0);
-       if (priv->retry_rate <= 0)
-               priv->retry_rate = 1;
+       priv->retry_rate = (val > 0) ? val : 1;
 
        return count;
 }
@@ -3887,9 +3912,9 @@ static ssize_t store_power_level(struct device *d,
 {
        struct iwl_priv *priv = dev_get_drvdata(d);
        int ret;
-       int mode;
+       unsigned long mode;
+
 
-       mode = simple_strtoul(buf, NULL, 0);
        mutex_lock(&priv->mutex);
 
        if (!iwl_is_ready(priv)) {
@@ -3897,6 +3922,10 @@ static ssize_t store_power_level(struct device *d,
                goto out;
        }
 
+       ret = strict_strtoul(buf, 10, &mode);
+       if (ret)
+               goto out;
+
        ret = iwl_power_set_user_mode(priv, mode);
        if (ret) {
                IWL_DEBUG_MAC80211("failed setting power mode.\n");
@@ -4076,6 +4105,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        /* FIXME : remove when resolved PENDING */
        INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
        iwl_setup_scan_deferred_work(priv);
+       iwl_setup_power_deferred_work(priv);
 
        if (priv->cfg->ops->lib->setup_deferred_work)
                priv->cfg->ops->lib->setup_deferred_work(priv);
@@ -4095,6 +4125,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 
        cancel_delayed_work_sync(&priv->init_alive_start);
        cancel_delayed_work(&priv->scan_check);
+       cancel_delayed_work_sync(&priv->set_power_save);
        cancel_delayed_work(&priv->alive_start);
        cancel_work_sync(&priv->beacon_update);
        del_timer_sync(&priv->statistics_periodic);
@@ -4143,7 +4174,7 @@ static struct ieee80211_ops iwl4965_hw_ops = {
        .reset_tsf = iwl4965_mac_reset_tsf,
        .bss_info_changed = iwl4965_bss_info_changed,
        .ampdu_action = iwl4965_mac_ampdu_action,
-       .hw_scan = iwl4965_mac_hw_scan
+       .hw_scan = iwl_mac_hw_scan
 };
 
 static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -4218,9 +4249,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        pci_set_drvdata(pdev, priv);
 
-       /* 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
@@ -4240,6 +4268,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
                ": Detected Intel Wireless WiFi Link %s REV=0x%X\n",
                priv->cfg->name, priv->hw_rev);
 
+       /* We disable the RETRY_TIMEOUT register (0x41) to keep
+        * PCI Tx retries from interfering with C3 CPU state */
+       pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
+
        /* amp init */
        err = priv->cfg->ops->lib->apm_ops.init(priv);
        if (err < 0) {
@@ -4365,15 +4397,18 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
        iwl_dbgfs_unregister(priv);
        sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
 
+       /* ieee80211_unregister_hw call wil cause iwl4965_mac_stop to
+        * to be called and iwl4965_down since we are removing the device
+        * we need to set STATUS_EXIT_PENDING bit.
+        */
+       set_bit(STATUS_EXIT_PENDING, &priv->status);
        if (priv->mac80211_registered) {
                ieee80211_unregister_hw(priv->hw);
                priv->mac80211_registered = 0;
+       } else {
+               iwl4965_down(priv);
        }
 
-       set_bit(STATUS_EXIT_PENDING, &priv->status);
-
-       iwl4965_down(priv);
-
        /* make sure we flush any pending irq or
         * tasklet for the driver
         */