iwlwifi: mvm: teardown TDLS peers when initiating DCM
authorArik Nemtsov <arik@wizery.com>
Tue, 10 Jun 2014 16:56:27 +0000 (19:56 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 7 Jul 2014 18:41:24 +0000 (21:41 +0300)
The FW currently doesn't optimally support TDLS in DCM mode. Teardown
all TDLS peers when we have more than a single phy context.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/mac80211.c

index 8aa6fa4..2eb6ebe 100644 (file)
@@ -1885,6 +1885,28 @@ static void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm,
                iwl_mvm_power_update_mac(mvm);
 }
 
+static void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm)
+{
+       struct ieee80211_sta *sta;
+       struct iwl_mvm_sta *mvmsta;
+       int i;
+
+       lockdep_assert_held(&mvm->mutex);
+
+       for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
+               sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
+                                               lockdep_is_held(&mvm->mutex));
+               if (!sta || IS_ERR(sta) || !sta->tdls)
+                       continue;
+
+               mvmsta = iwl_mvm_sta_from_mac80211(sta);
+               ieee80211_tdls_oper_request(mvmsta->vif, sta->addr,
+                               NL80211_TDLS_TEARDOWN,
+                               WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED,
+                               GFP_KERNEL);
+       }
+}
+
 static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
                                 struct ieee80211_vif *vif,
                                 struct ieee80211_sta *sta,
@@ -1954,6 +1976,11 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
                                             true);
        } else if (old_state == IEEE80211_STA_ASSOC &&
                   new_state == IEEE80211_STA_AUTHORIZED) {
+
+               /* we don't support TDLS during DCM */
+               if (iwl_mvm_phy_ctx_count(mvm) > 1)
+                       iwl_mvm_teardown_tdls_peers(mvm);
+
                /* enable beacon filtering */
                WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
                ret = 0;