aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm
diff options
context:
space:
mode:
authorGregory Greenman <gregory.greenman@intel.com>2014-06-25 08:08:50 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-07-06 04:16:15 -0400
commitd40fc489f308951f6361742e8b9689326c831f41 (patch)
tree8ae458d1fe70d8c2f40f2548a7ca22bc3dc3368c /drivers/net/wireless/iwlwifi/mvm
parent5bfe6f53283de44855ee45a102210abbfac995f9 (diff)
iwlwifi: mvm: wait for d0i3 exit in add interface flow
This patch makes sure there're no target accesses in the add interface flow before d0i3 exit completes. Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c40
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h1
2 files changed, 32 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 5e425d3fddeb..7dde944a68fb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -243,6 +243,21 @@ iwl_mvm_unref_all_except(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref)
243 } 243 }
244} 244}
245 245
246static int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
247{
248 iwl_mvm_ref(mvm, ref_type);
249
250 if (!wait_event_timeout(mvm->d0i3_exit_waitq,
251 !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status),
252 HZ)) {
253 WARN_ON_ONCE(1);
254 iwl_mvm_unref(mvm, ref_type);
255 return -EIO;
256 }
257
258 return 0;
259}
260
246static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm) 261static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
247{ 262{
248 int i; 263 int i;
@@ -559,9 +574,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
559 case IEEE80211_AMPDU_TX_STOP_FLUSH: 574 case IEEE80211_AMPDU_TX_STOP_FLUSH:
560 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 575 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
561 case IEEE80211_AMPDU_TX_OPERATIONAL: 576 case IEEE80211_AMPDU_TX_OPERATIONAL:
562 iwl_mvm_ref(mvm, IWL_MVM_REF_TX_AGG);
563 tx_agg_ref = true;
564
565 /* 577 /*
566 * for tx start, wait synchronously until D0i3 exit to 578 * for tx start, wait synchronously until D0i3 exit to
567 * get the correct sequence number for the tid. 579 * get the correct sequence number for the tid.
@@ -570,12 +582,11 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
570 * by the trans layer (unlike commands), so wait for 582 * by the trans layer (unlike commands), so wait for
571 * d0i3 exit in these cases as well. 583 * d0i3 exit in these cases as well.
572 */ 584 */
573 if (!wait_event_timeout(mvm->d0i3_exit_waitq, 585 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_TX_AGG);
574 !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status), HZ)) { 586 if (ret)
575 WARN_ON_ONCE(1); 587 return ret;
576 iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG); 588
577 return -EIO; 589 tx_agg_ref = true;
578 }
579 break; 590 break;
580 default: 591 default:
581 break; 592 break;
@@ -904,6 +915,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
904 int ret; 915 int ret;
905 916
906 /* 917 /*
918 * make sure D0i3 exit is completed, otherwise a target access
919 * during tx queue configuration could be done when still in
920 * D0i3 state.
921 */
922 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_ADD_IF);
923 if (ret)
924 return ret;
925
926 /*
907 * Not much to do here. The stack will not allow interface 927 * Not much to do here. The stack will not allow interface
908 * types or combinations that we didn't advertise, so we 928 * types or combinations that we didn't advertise, so we
909 * don't really have to check the types. 929 * don't really have to check the types.
@@ -1017,6 +1037,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1017 out_unlock: 1037 out_unlock:
1018 mutex_unlock(&mvm->mutex); 1038 mutex_unlock(&mvm->mutex);
1019 1039
1040 iwl_mvm_unref(mvm, IWL_MVM_REF_ADD_IF);
1041
1020 return ret; 1042 return ret;
1021} 1043}
1022 1044
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index e067d9762603..6fe93a7335c1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -230,6 +230,7 @@ enum iwl_mvm_ref_type {
230 IWL_MVM_REF_USER, 230 IWL_MVM_REF_USER,
231 IWL_MVM_REF_TX, 231 IWL_MVM_REF_TX,
232 IWL_MVM_REF_TX_AGG, 232 IWL_MVM_REF_TX_AGG,
233 IWL_MVM_REF_ADD_IF,
233 IWL_MVM_REF_EXIT_WORK, 234 IWL_MVM_REF_EXIT_WORK,
234 235
235 IWL_MVM_REF_COUNT, 236 IWL_MVM_REF_COUNT,