iwlwifi: set interrupt coalescing timer range and default
[safe/jmp/linux-2.6] / drivers / net / wireless / iwlwifi / iwl-core.c
index c3c31dc..29eb7b4 100644 (file)
@@ -257,8 +257,8 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
        spin_lock_irqsave(&priv->lock, flags);
        priv->cfg->ops->lib->apm_ops.init(priv);
 
-       /* Set interrupt coalescing timer to 512 usecs */
-       iwl_write8(priv, CSR_INT_COALESCING, 512 / 32);
+       /* Set interrupt coalescing calibration timer to default (512 usecs) */
+       iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -450,8 +450,6 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
        if (priv->cfg->ht_greenfield_support)
                ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
        ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
-       ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
-                            (priv->cfg->sm_ps_mode << 2));
        max_bit_rate = MAX_BIT_RATE_20_MHZ;
        if (priv->hw_params.ht40_channel & BIT(band)) {
                ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -636,7 +634,7 @@ EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag);
 
 static bool is_single_rx_stream(struct iwl_priv *priv)
 {
-       return !priv->current_ht_config.is_ht ||
+       return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
               priv->current_ht_config.single_chain_sufficient;
 }
 
@@ -1003,28 +1001,18 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
  */
 static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
 {
-       int idle_cnt = active_cnt;
-       bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
-
-       /* # Rx chains when idling and maybe trying to save power */
-       switch (priv->cfg->sm_ps_mode) {
-       case WLAN_HT_CAP_SM_PS_STATIC:
-               idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE;
-               break;
-       case WLAN_HT_CAP_SM_PS_DYNAMIC:
-               idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
-                       IWL_NUM_IDLE_CHAINS_SINGLE;
-               break;
-       case WLAN_HT_CAP_SM_PS_DISABLED:
-               break;
-       case WLAN_HT_CAP_SM_PS_INVALID:
+       /* # Rx chains when idling, depending on SMPS mode */
+       switch (priv->current_ht_config.smps) {
+       case IEEE80211_SMPS_STATIC:
+       case IEEE80211_SMPS_DYNAMIC:
+               return IWL_NUM_IDLE_CHAINS_SINGLE;
+       case IEEE80211_SMPS_OFF:
+               return active_cnt;
        default:
-               IWL_ERR(priv, "invalid sm_ps mode %u\n",
-                       priv->cfg->sm_ps_mode);
-               WARN_ON(1);
-               break;
+               WARN(1, "invalid SMPS mode %d",
+                    priv->current_ht_config.smps);
+               return active_cnt;
        }
-       return idle_cnt;
 }
 
 /* up to 4 chains */
@@ -2346,6 +2334,21 @@ static void iwl_ht_conf(struct iwl_priv *priv,
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
+static inline void iwl_set_no_assoc(struct iwl_priv *priv)
+{
+       priv->assoc_id = 0;
+       iwl_led_disassociate(priv);
+       /*
+        * inform the ucode that there is no longer an
+        * association and that no more packets should be
+        * sent
+        */
+       priv->staging_rxon.filter_flags &=
+               ~RXON_FILTER_ASSOC_MSK;
+       priv->staging_rxon.assoc_id = 0;
+       iwlcore_commit_rxon(priv);
+}
+
 #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
 void iwl_bss_info_changed(struct ieee80211_hw *hw,
                          struct ieee80211_vif *vif,
@@ -2477,20 +2480,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
                                        IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
                        if (!iwl_is_rfkill(priv))
                                priv->cfg->ops->lib->post_associate(priv);
-               } else {
-                       priv->assoc_id = 0;
-                       iwl_led_disassociate(priv);
-
-                       /*
-                        * inform the ucode that there is no longer an
-                        * association and that no more packets should be
-                        * send
-                        */
-                       priv->staging_rxon.filter_flags &=
-                               ~RXON_FILTER_ASSOC_MSK;
-                       priv->staging_rxon.assoc_id = 0;
-                       iwlcore_commit_rxon(priv);
-               }
+               } else
+                       iwl_set_no_assoc(priv);
        }
 
        if (changes && iwl_is_associated(priv) && priv->assoc_id) {
@@ -2505,12 +2496,14 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
                }
        }
 
-       if ((changes & BSS_CHANGED_BEACON_ENABLED) &&
-           vif->bss_conf.enable_beacon) {
-               memcpy(priv->staging_rxon.bssid_addr,
-                      bss_conf->bssid, ETH_ALEN);
-               memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
-               iwlcore_config_ap(priv);
+       if (changes & BSS_CHANGED_BEACON_ENABLED) {
+               if (vif->bss_conf.enable_beacon) {
+                       memcpy(priv->staging_rxon.bssid_addr,
+                              bss_conf->bssid, ETH_ALEN);
+                       memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+                       iwlcore_config_ap(priv);
+               } else
+                       iwl_set_no_assoc(priv);
        }
 
        mutex_unlock(&priv->mutex);
@@ -2596,12 +2589,12 @@ int iwl_set_mode(struct iwl_priv *priv, int mode)
 EXPORT_SYMBOL(iwl_set_mode);
 
 int iwl_mac_add_interface(struct ieee80211_hw *hw,
-                                struct ieee80211_if_init_conf *conf)
+                                struct ieee80211_vif *vif)
 {
        struct iwl_priv *priv = hw->priv;
        unsigned long flags;
 
-       IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
+       IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type);
 
        if (priv->vif) {
                IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
@@ -2609,19 +2602,19 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       priv->vif = conf->vif;
-       priv->iw_mode = conf->type;
+       priv->vif = vif;
+       priv->iw_mode = vif->type;
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
        mutex_lock(&priv->mutex);
 
-       if (conf->mac_addr) {
-               IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
-               memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
+       if (vif->addr) {
+               IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
+               memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
        }
 
-       if (iwl_set_mode(priv, conf->type) == -EAGAIN)
+       if (iwl_set_mode(priv, vif->type) == -EAGAIN)
                /* we are not ready, will run again when ready */
                set_bit(STATUS_MODE_PENDING, &priv->status);
 
@@ -2633,7 +2626,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
 EXPORT_SYMBOL(iwl_mac_add_interface);
 
 void iwl_mac_remove_interface(struct ieee80211_hw *hw,
-                                    struct ieee80211_if_init_conf *conf)
+                                    struct ieee80211_vif *vif)
 {
        struct iwl_priv *priv = hw->priv;
 
@@ -2646,7 +2639,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
                iwlcore_commit_rxon(priv);
        }
-       if (priv->vif == conf->vif) {
+       if (priv->vif == vif) {
                priv->vif = NULL;
                memset(priv->bssid, 0, ETH_ALEN);
        }
@@ -2686,6 +2679,21 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
                IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
        }
 
+       if (changed & (IEEE80211_CONF_CHANGE_SMPS |
+                      IEEE80211_CONF_CHANGE_CHANNEL)) {
+               /* mac80211 uses static for non-HT which is what we want */
+               priv->current_ht_config.smps = conf->smps_mode;
+
+               /*
+                * Recalculate chain counts.
+                *
+                * If monitor mode is enabled then mac80211 will
+                * set up the SM PS mode to OFF if an HT channel is
+                * configured.
+                */
+               if (priv->cfg->ops->hcmd->set_rxon_chain)
+                       priv->cfg->ops->hcmd->set_rxon_chain(priv);
+       }
 
        /* during scanning mac80211 will delay channel setting until
         * scan finish with changed = 0
@@ -2782,10 +2790,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
                iwl_set_tx_power(priv, conf->power_level, false);
        }
 
-       /* call to ensure that 4965 rx_chain is set properly in monitor mode */
-       if (priv->cfg->ops->hcmd->set_rxon_chain)
-               priv->cfg->ops->hcmd->set_rxon_chain(priv);
-
        if (!iwl_is_ready(priv)) {
                IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
                goto out;