]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/iwlwifi/mvm/mac80211.c
iwlwifi: mvm: declare TDLS support
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / mvm / mac80211.c
index f308e52781f6f060e61d21608b313505b145ac48..801abcfbaa7fd2072ef8ff04e7b78ebde387b873 100644 (file)
@@ -254,6 +254,26 @@ static void iwl_mvm_unref_all_except(struct iwl_mvm *mvm,
        spin_unlock_bh(&mvm->refs_lock);
 }
 
+bool iwl_mvm_ref_taken(struct iwl_mvm *mvm)
+{
+       int i;
+       bool taken = false;
+
+       if (!iwl_mvm_is_d0i3_supported(mvm))
+               return true;
+
+       spin_lock_bh(&mvm->refs_lock);
+       for (i = 0; i < IWL_MVM_REF_COUNT; i++) {
+               if (mvm->refs[i]) {
+                       taken = true;
+                       break;
+               }
+       }
+       spin_unlock_bh(&mvm->refs_lock);
+
+       return taken;
+}
+
 int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
 {
        iwl_mvm_ref(mvm, ref_type);
@@ -323,8 +343,13 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
                hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
        }
 
-       if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
+       if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN ||
+           mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) {
                hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS;
+               hw->wiphy->features |=
+                       NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
+                       NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
+       }
 
        hw->sta_data_size = sizeof(struct iwl_mvm_sta);
        hw->vif_data_size = sizeof(struct iwl_mvm_vif);
@@ -403,7 +428,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
                               NL80211_FEATURE_LOW_PRIORITY_SCAN |
                               NL80211_FEATURE_P2P_GO_OPPPS |
                               NL80211_FEATURE_DYNAMIC_SMPS |
-                              NL80211_FEATURE_STATIC_SMPS;
+                              NL80211_FEATURE_STATIC_SMPS |
+                              NL80211_FEATURE_SUPPORTS_WMM_ADMISSION;
 
        if (mvm->fw->ucode_capa.capa[0] &
            IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT)
@@ -464,6 +490,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
        if (ret)
                return ret;
 
+       if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_TDLS_SUPPORT) {
+               IWL_DEBUG_TDLS(mvm, "TDLS supported\n");
+               hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
+       }
+
        ret = ieee80211_register_hw(mvm->hw);
        if (ret)
                iwl_mvm_leds_exit(mvm);
@@ -819,12 +850,18 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
 
 static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
 {
-       iwl_mvm_fw_error_dump(mvm);
+       /* clear the D3 reconfig, we only need it to avoid dumping a
+        * firmware coredump on reconfiguration, we shouldn't do that
+        * on D3->D0 transition
+        */
+       if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status))
+               iwl_mvm_fw_error_dump(mvm);
 
        iwl_trans_stop_device(mvm->trans);
 
        mvm->scan_status = IWL_MVM_SCAN_NONE;
        mvm->ps_disabled = false;
+       mvm->calibrating = false;
 
        /* just in case one was running */
        ieee80211_remain_on_channel_expired(mvm->hw);
@@ -914,6 +951,25 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
        mutex_unlock(&mvm->mutex);
 }
 
+static void iwl_mvm_resume_complete(struct iwl_mvm *mvm)
+{
+       bool exit_now;
+
+       if (!iwl_mvm_is_d0i3_supported(mvm))
+               return;
+
+       mutex_lock(&mvm->d0i3_suspend_mutex);
+       __clear_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
+       exit_now = __test_and_clear_bit(D0I3_PENDING_WAKEUP,
+                                       &mvm->d0i3_suspend_flags);
+       mutex_unlock(&mvm->d0i3_suspend_mutex);
+
+       if (exit_now) {
+               IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n");
+               _iwl_mvm_exit_d0i3(mvm);
+       }
+}
+
 static void
 iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
                              enum ieee80211_reconfig_type reconfig_type)
@@ -925,6 +981,7 @@ iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
                iwl_mvm_restart_complete(mvm);
                break;
        case IEEE80211_RECONFIG_TYPE_SUSPEND:
+               iwl_mvm_resume_complete(mvm);
                break;
        }
 }
@@ -1888,9 +1945,11 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
            req->n_channels > mvm->fw->ucode_capa.n_scan_channels)
                return -EINVAL;
 
-       ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_SCHED);
-       if (ret)
-               return ret;
+       if (!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
+               ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_SCHED);
+               if (ret)
+                       return ret;
+       }
 
        mutex_lock(&mvm->mutex);
 
@@ -1901,7 +1960,9 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
 
        iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN);
 
-       if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
+       if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)
+               ret = iwl_mvm_scan_umac(mvm, vif, hw_req);
+       else if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
                ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req);
        else
                ret = iwl_mvm_scan_request(mvm, vif, req);
@@ -2200,9 +2261,11 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        int ret;
 
-       ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_OS);
-       if (ret)
-               return ret;
+       if (!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
+               ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_OS);
+               if (ret)
+                       return ret;
+       }
 
        mutex_lock(&mvm->mutex);
 
@@ -2222,11 +2285,10 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
                goto out;
        }
 
-       mvm->scan_status = IWL_MVM_SCAN_SCHED;
-
        ret = iwl_mvm_scan_offload_start(mvm, vif, req, ies);
        if (ret)
                mvm->scan_status = IWL_MVM_SCAN_NONE;
+
 out:
        mutex_unlock(&mvm->mutex);
        return ret;
@@ -2244,6 +2306,7 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
        iwl_mvm_wait_for_async_handlers(mvm);
 
        return ret;
+
 }
 
 static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
@@ -2272,12 +2335,16 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
                break;
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_WEP104:
-               /*
-                * Support for TX only, at least for now, so accept
-                * the key and do nothing else. Then mac80211 will
-                * pass it for TX but we don't have to use it for RX.
+               /* For non-client mode, only use WEP keys for TX as we probably
+                * don't have a station yet anyway and would then have to keep
+                * track of the keys, linking them to each of the clients/peers
+                * as they appear. For now, don't do that, for performance WEP
+                * offload doesn't really matter much, but we need it for some
+                * other offload features in client mode.
                 */
-               return 0;
+               if (vif->type != NL80211_IFTYPE_STATION)
+                       return 0;
+               break;
        default:
                /* currently FW supports only one optional cipher scheme */
                if (hw->n_cipher_schemes &&
@@ -2594,7 +2661,7 @@ static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
        IWL_DEBUG_MAC80211(mvm, "enter\n");
 
        mutex_lock(&mvm->mutex);
-       iwl_mvm_stop_p2p_roc(mvm);
+       iwl_mvm_stop_roc(mvm);
        mutex_unlock(&mvm->mutex);
 
        IWL_DEBUG_MAC80211(mvm, "leave\n");