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);
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);
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)
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);
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);
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)
iwl_mvm_restart_complete(mvm);
break;
case IEEE80211_RECONFIG_TYPE_SUSPEND:
+ iwl_mvm_resume_complete(mvm);
break;
}
}
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);
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);
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);
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;
iwl_mvm_wait_for_async_handlers(mvm);
return ret;
+
}
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 &&
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");