Skip to content

Commit

Permalink
iwlwifi: mvm: wait for handlers when stopping scans
Browse files Browse the repository at this point in the history
The recent unified scan api change introduced issues
when stopping ongoing scans, since both regular and
sched scan now use same stopped notification.

When issuing a new scan right after a running one,
we get the "old" notification and handle it wrongly
as notification for the current scan.

Fix it by introducing a new function that make sure
we consume the pending notifications before issuing
a new scan.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Reviewed-by: ArikX Nemtsov <arik@wizery.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
  • Loading branch information
Eliad Peller authored and Emmanuel Grumbach committed Jul 22, 2014
1 parent 45bbb2c commit 4660dfb
Showing 1 changed file with 51 additions and 35 deletions.
86 changes: 51 additions & 35 deletions drivers/net/wireless/iwlwifi/mvm/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1718,6 +1718,47 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
iwl_mvm_unref(mvm, IWL_MVM_REF_BSS_CHANGED);
}

static int iwl_mvm_cancel_scan_wait_notif(struct iwl_mvm *mvm,
enum iwl_scan_status scan_type)
{
int ret;
bool wait_for_handlers = false;

mutex_lock(&mvm->mutex);

if (mvm->scan_status != scan_type) {
ret = 0;
/* make sure there are no pending notifications */
wait_for_handlers = true;
goto out;
}

switch (scan_type) {
case IWL_MVM_SCAN_SCHED:
ret = iwl_mvm_scan_offload_stop(mvm, true);
break;
case IWL_MVM_SCAN_OS:
ret = iwl_mvm_cancel_scan(mvm);
break;
case IWL_MVM_SCAN_NONE:
default:
WARN_ON_ONCE(1);
ret = -EINVAL;
break;
}
if (ret)
goto out;

wait_for_handlers = true;
out:
mutex_unlock(&mvm->mutex);

/* make sure we consume the completion notification */
if (wait_for_handlers)
iwl_mvm_wait_for_async_handlers(mvm);

return ret;
}
static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_scan_request *hw_req)
Expand All @@ -1730,19 +1771,13 @@ 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;

mutex_lock(&mvm->mutex);

switch (mvm->scan_status) {
case IWL_MVM_SCAN_SCHED:
ret = iwl_mvm_scan_offload_stop(mvm, true);
if (ret) {
ret = -EBUSY;
goto out;
}
break;
case IWL_MVM_SCAN_NONE:
break;
default:
if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
ret = -EBUSY;
goto out;
}
Expand All @@ -1758,8 +1793,6 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
out:
mutex_unlock(&mvm->mutex);
/* make sure to flush the Rx handler before the next scan arrives */
iwl_mvm_wait_for_async_handlers(mvm);
return ret;
}

Expand Down Expand Up @@ -2135,33 +2168,18 @@ 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;

mutex_lock(&mvm->mutex);

if (!iwl_mvm_is_idle(mvm)) {
ret = -EBUSY;
goto out;
}

switch (mvm->scan_status) {
case IWL_MVM_SCAN_OS:
IWL_DEBUG_SCAN(mvm, "Stopping previous scan for sched_scan\n");
ret = iwl_mvm_cancel_scan(mvm);
if (ret) {
ret = -EBUSY;
goto out;
}

/*
* iwl_mvm_rx_scan_complete() will be called soon but will
* not reset the scan status as it won't be IWL_MVM_SCAN_OS
* any more since we queue the next scan immediately (below).
* We make sure it is called before the next scan starts by
* flushing the async-handlers work.
*/
break;
case IWL_MVM_SCAN_NONE:
break;
default:
if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
ret = -EBUSY;
goto out;
}
Expand Down Expand Up @@ -2189,8 +2207,6 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
mvm->scan_status = IWL_MVM_SCAN_NONE;
out:
mutex_unlock(&mvm->mutex);
/* make sure to flush the Rx handler before the next scan arrives */
iwl_mvm_wait_for_async_handlers(mvm);
return ret;
}

Expand Down

0 comments on commit 4660dfb

Please sign in to comment.