iwlwifi: mvm: wait for d0i3 exit in some more ampdu actions
authorEliad Peller <eliad@wizery.com>
Tue, 22 Apr 2014 10:33:29 +0000 (13:33 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 6 May 2014 20:32:45 +0000 (23:32 +0300)
Some ampdu actions change queues by direct target access.

Since the bus is disabled in d0i3, make sure to exit d0i3
before handling these actions.

Signed-off-by: Eliad Peller <eliadx.peller@intel.com>
Reviewed-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/mac80211.c

index 97c3deae655273ff3c5184cd86a4722f34714eae..db55d670dce0f62fdaebd476b84cef998239c6d7 100644 (file)
@@ -539,13 +539,22 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
                return -EACCES;
 
        /* return from D0i3 before starting a new Tx aggregation */
-       if (action == IEEE80211_AMPDU_TX_START) {
+       switch (action) {
+       case IEEE80211_AMPDU_TX_START:
+       case IEEE80211_AMPDU_TX_STOP_CONT:
+       case IEEE80211_AMPDU_TX_STOP_FLUSH:
+       case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+       case IEEE80211_AMPDU_TX_OPERATIONAL:
                iwl_mvm_ref(mvm, IWL_MVM_REF_TX_AGG);
                tx_agg_ref = true;
 
                /*
-                * wait synchronously until D0i3 exit to get the correct
-                * sequence number for the tid
+                * for tx start, wait synchronously until D0i3 exit to
+                * get the correct sequence number for the tid.
+                * additionally, some other ampdu actions use direct
+                * target access, which is not handled automatically
+                * by the trans layer (unlike commands), so wait for
+                * d0i3 exit in these cases as well.
                 */
                if (!wait_event_timeout(mvm->d0i3_exit_waitq,
                          !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status), HZ)) {
@@ -553,6 +562,9 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
                        iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG);
                        return -EIO;
                }
+               break;
+       default:
+               break;
        }
 
        mutex_lock(&mvm->mutex);