aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c86
1 files changed, 51 insertions, 35 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 5219b3a5689d..46ff7cd52d92 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -1718,6 +1718,47 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
1718 iwl_mvm_unref(mvm, IWL_MVM_REF_BSS_CHANGED); 1718 iwl_mvm_unref(mvm, IWL_MVM_REF_BSS_CHANGED);
1719} 1719}
1720 1720
1721static int iwl_mvm_cancel_scan_wait_notif(struct iwl_mvm *mvm,
1722 enum iwl_scan_status scan_type)
1723{
1724 int ret;
1725 bool wait_for_handlers = false;
1726
1727 mutex_lock(&mvm->mutex);
1728
1729 if (mvm->scan_status != scan_type) {
1730 ret = 0;
1731 /* make sure there are no pending notifications */
1732 wait_for_handlers = true;
1733 goto out;
1734 }
1735
1736 switch (scan_type) {
1737 case IWL_MVM_SCAN_SCHED:
1738 ret = iwl_mvm_scan_offload_stop(mvm, true);
1739 break;
1740 case IWL_MVM_SCAN_OS:
1741 ret = iwl_mvm_cancel_scan(mvm);
1742 break;
1743 case IWL_MVM_SCAN_NONE:
1744 default:
1745 WARN_ON_ONCE(1);
1746 ret = -EINVAL;
1747 break;
1748 }
1749 if (ret)
1750 goto out;
1751
1752 wait_for_handlers = true;
1753out:
1754 mutex_unlock(&mvm->mutex);
1755
1756 /* make sure we consume the completion notification */
1757 if (wait_for_handlers)
1758 iwl_mvm_wait_for_async_handlers(mvm);
1759
1760 return ret;
1761}
1721static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw, 1762static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1722 struct ieee80211_vif *vif, 1763 struct ieee80211_vif *vif,
1723 struct ieee80211_scan_request *hw_req) 1764 struct ieee80211_scan_request *hw_req)
@@ -1730,19 +1771,13 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1730 req->n_channels > mvm->fw->ucode_capa.n_scan_channels) 1771 req->n_channels > mvm->fw->ucode_capa.n_scan_channels)
1731 return -EINVAL; 1772 return -EINVAL;
1732 1773
1774 ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_SCHED);
1775 if (ret)
1776 return ret;
1777
1733 mutex_lock(&mvm->mutex); 1778 mutex_lock(&mvm->mutex);
1734 1779
1735 switch (mvm->scan_status) { 1780 if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
1736 case IWL_MVM_SCAN_SCHED:
1737 ret = iwl_mvm_scan_offload_stop(mvm, true);
1738 if (ret) {
1739 ret = -EBUSY;
1740 goto out;
1741 }
1742 break;
1743 case IWL_MVM_SCAN_NONE:
1744 break;
1745 default:
1746 ret = -EBUSY; 1781 ret = -EBUSY;
1747 goto out; 1782 goto out;
1748 } 1783 }
@@ -1758,8 +1793,6 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1758 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1793 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1759out: 1794out:
1760 mutex_unlock(&mvm->mutex); 1795 mutex_unlock(&mvm->mutex);
1761 /* make sure to flush the Rx handler before the next scan arrives */
1762 iwl_mvm_wait_for_async_handlers(mvm);
1763 return ret; 1796 return ret;
1764} 1797}
1765 1798
@@ -2135,6 +2168,10 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
2135 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2168 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2136 int ret; 2169 int ret;
2137 2170
2171 ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_OS);
2172 if (ret)
2173 return ret;
2174
2138 mutex_lock(&mvm->mutex); 2175 mutex_lock(&mvm->mutex);
2139 2176
2140 if (!iwl_mvm_is_idle(mvm)) { 2177 if (!iwl_mvm_is_idle(mvm)) {
@@ -2142,26 +2179,7 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
2142 goto out; 2179 goto out;
2143 } 2180 }
2144 2181
2145 switch (mvm->scan_status) { 2182 if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
2146 case IWL_MVM_SCAN_OS:
2147 IWL_DEBUG_SCAN(mvm, "Stopping previous scan for sched_scan\n");
2148 ret = iwl_mvm_cancel_scan(mvm);
2149 if (ret) {
2150 ret = -EBUSY;
2151 goto out;
2152 }
2153
2154 /*
2155 * iwl_mvm_rx_scan_complete() will be called soon but will
2156 * not reset the scan status as it won't be IWL_MVM_SCAN_OS
2157 * any more since we queue the next scan immediately (below).
2158 * We make sure it is called before the next scan starts by
2159 * flushing the async-handlers work.
2160 */
2161 break;
2162 case IWL_MVM_SCAN_NONE:
2163 break;
2164 default:
2165 ret = -EBUSY; 2183 ret = -EBUSY;
2166 goto out; 2184 goto out;
2167 } 2185 }
@@ -2189,8 +2207,6 @@ err:
2189 mvm->scan_status = IWL_MVM_SCAN_NONE; 2207 mvm->scan_status = IWL_MVM_SCAN_NONE;
2190out: 2208out:
2191 mutex_unlock(&mvm->mutex); 2209 mutex_unlock(&mvm->mutex);
2192 /* make sure to flush the Rx handler before the next scan arrives */
2193 iwl_mvm_wait_for_async_handlers(mvm);
2194 return ret; 2210 return ret;
2195} 2211}
2196 2212