iwlwifi: turn on RTS/CTS after aggregation become operational
authorWey-Yi Guy <wey-yi.w.guy@intel.com>
Fri, 18 Jun 2010 18:33:15 +0000 (11:33 -0700)
committerReinette Chatre <reinette.chatre@intel.com>
Fri, 25 Jun 2010 22:20:41 +0000 (15:20 -0700)
If RTS/CTS protection is needed for HT, wait until get operational
notification from mac80211, then inform uCode to switch to RTS/CTS
through RXON command.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-scan.c

index 40933a5..35c86d2 100644 (file)
@@ -324,18 +324,11 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
                              struct iwl_lq_sta *lq_data,
                              struct ieee80211_sta *sta)
 {
-       if ((tid < TID_MAX_LOAD_COUNT) &&
-           !rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta)) {
-               if (priv->cfg->use_rts_for_ht) {
-                       /*
-                        * switch to RTS/CTS if it is the prefer protection
-                        * method for HT traffic
-                        */
-                       IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
-                       priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
-                       iwlcore_commit_rxon(priv);
-               }
-       }
+       if (tid < TID_MAX_LOAD_COUNT)
+               rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
+       else
+               IWL_ERR(priv, "tid exceeds max load count: %d/%d\n",
+                       tid, TID_MAX_LOAD_COUNT);
 }
 
 static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
index 7488a68..3368cfd 100644 (file)
@@ -3368,6 +3368,25 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        return ret;
 }
 
+/*
+ * switch to RTS/CTS for TX
+ */
+static void iwl_enable_rts_cts(struct iwl_priv *priv)
+{
+
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+               return;
+
+       priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
+       if (!test_bit(STATUS_SCANNING, &priv->status)) {
+               IWL_DEBUG_INFO(priv, "use RTS/CTS protection\n");
+               iwlcore_commit_rxon(priv);
+       } else {
+               /* scanning, defer the request until scan completed */
+               IWL_DEBUG_INFO(priv, "defer setting RTS/CTS protection\n");
+       }
+}
+
 static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
                                struct ieee80211_vif *vif,
                                enum ieee80211_ampdu_mlme_action action,
@@ -3416,7 +3435,14 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
                        ret = 0;
                break;
        case IEEE80211_AMPDU_TX_OPERATIONAL:
-               /* do nothing, return value ignored */
+               if (priv->cfg->use_rts_for_ht) {
+                       /*
+                        * switch to RTS/CTS if it is the prefer protection
+                        * method for HT traffic
+                        */
+                       iwl_enable_rts_cts(priv);
+               }
+               ret = 0;
                break;
        }
        mutex_unlock(&priv->mutex);
index 798f93e..2a7c399 100644 (file)
@@ -537,6 +537,15 @@ void iwl_bg_scan_completed(struct work_struct *work)
        /* Since setting the TXPOWER may have been deferred while
         * performing the scan, fire one off */
        iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+
+       /*
+        * Since setting the RXON may have been deferred while
+        * performing the scan, fire one off if needed
+        */
+       if (memcmp(&priv->active_rxon,
+                  &priv->staging_rxon, sizeof(priv->staging_rxon)))
+               iwlcore_commit_rxon(priv);
+
  out:
        mutex_unlock(&priv->mutex);