Commit 04106ec5 authored by Jérôme Pouiller's avatar Jérôme Pouiller Committed by Kalle Valo

wifi: wfx: scan_lock is global to the device

Currently, one scan_lock is associated to each vif. However, concurrent
scan on vifs is explicitly prohibited by the device. Currently,
scan_lock is associated with a vif but it is always locked with
conf_mutex (there is a case where conf_mutex is not associated to
scan_lock but scan_lock is tested on all interfaces). So concurrent scan
on vifs cannot happen.

So, this patch relocate scan_lock to the device and simplify the code.
Signed-off-by: default avatarJérôme Pouiller <jerome.pouiller@silabs.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20231004172843.195332-7-jerome.pouiller@silabs.com
parent f091bcb6
...@@ -246,6 +246,7 @@ static void wfx_free_common(void *data) ...@@ -246,6 +246,7 @@ static void wfx_free_common(void *data)
mutex_destroy(&wdev->tx_power_loop_info_lock); mutex_destroy(&wdev->tx_power_loop_info_lock);
mutex_destroy(&wdev->rx_stats_lock); mutex_destroy(&wdev->rx_stats_lock);
mutex_destroy(&wdev->scan_lock);
mutex_destroy(&wdev->conf_mutex); mutex_destroy(&wdev->conf_mutex);
ieee80211_free_hw(wdev->hw); ieee80211_free_hw(wdev->hw);
} }
...@@ -314,6 +315,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, const struct wfx_platform_da ...@@ -314,6 +315,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, const struct wfx_platform_da
gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup"); gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup");
mutex_init(&wdev->conf_mutex); mutex_init(&wdev->conf_mutex);
mutex_init(&wdev->scan_lock);
mutex_init(&wdev->rx_stats_lock); mutex_init(&wdev->rx_stats_lock);
mutex_init(&wdev->tx_power_loop_info_lock); mutex_init(&wdev->tx_power_loop_info_lock);
init_completion(&wdev->firmware_ready); init_completion(&wdev->firmware_ready);
......
...@@ -95,7 +95,7 @@ void wfx_hw_scan_work(struct work_struct *work) ...@@ -95,7 +95,7 @@ void wfx_hw_scan_work(struct work_struct *work)
int chan_cur, ret, err; int chan_cur, ret, err;
mutex_lock(&wvif->wdev->conf_mutex); mutex_lock(&wvif->wdev->conf_mutex);
mutex_lock(&wvif->scan_lock); mutex_lock(&wvif->wdev->scan_lock);
if (wvif->join_in_progress) { if (wvif->join_in_progress) {
dev_info(wvif->wdev->dev, "abort in-progress REQ_JOIN"); dev_info(wvif->wdev->dev, "abort in-progress REQ_JOIN");
wfx_reset(wvif); wfx_reset(wvif);
...@@ -116,7 +116,7 @@ void wfx_hw_scan_work(struct work_struct *work) ...@@ -116,7 +116,7 @@ void wfx_hw_scan_work(struct work_struct *work)
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
} }
} while (ret >= 0 && chan_cur < hw_req->req.n_channels); } while (ret >= 0 && chan_cur < hw_req->req.n_channels);
mutex_unlock(&wvif->scan_lock); mutex_unlock(&wvif->wdev->scan_lock);
mutex_unlock(&wvif->wdev->conf_mutex); mutex_unlock(&wvif->wdev->conf_mutex);
wfx_ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); wfx_ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0);
} }
......
...@@ -97,7 +97,7 @@ void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, ...@@ -97,7 +97,7 @@ void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
FIF_PROBE_REQ | FIF_PSPOLL; FIF_PROBE_REQ | FIF_PSPOLL;
/* Filters are ignored during the scan. No frames are filtered. */ /* Filters are ignored during the scan. No frames are filtered. */
if (mutex_is_locked(&wvif->scan_lock)) if (mutex_is_locked(&wdev->scan_lock))
return; return;
mutex_lock(&wdev->conf_mutex); mutex_lock(&wdev->conf_mutex);
...@@ -621,17 +621,13 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) ...@@ -621,17 +621,13 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd) void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd)
{ {
struct wfx_vif *wvif_it;
if (notify_cmd != STA_NOTIFY_AWAKE) if (notify_cmd != STA_NOTIFY_AWAKE)
return; return;
/* Device won't be able to honor CAB if a scan is in progress on any interface. Prefer to /* Device won't be able to honor CAB if a scan is in progress on any interface. Prefer to
* skip this DTIM and wait for the next one. * skip this DTIM and wait for the next one.
*/ */
wvif_it = NULL; if (mutex_is_locked(&wvif->wdev->scan_lock))
while ((wvif_it = wvif_iterate(wvif->wdev, wvif_it)) != NULL)
if (mutex_is_locked(&wvif_it->scan_lock))
return; return;
if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed) if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed)
...@@ -730,7 +726,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -730,7 +726,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
complete(&wvif->set_pm_mode_complete); complete(&wvif->set_pm_mode_complete);
INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work); INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
mutex_init(&wvif->scan_lock);
init_completion(&wvif->scan_complete); init_completion(&wvif->scan_complete);
INIT_WORK(&wvif->scan_work, wfx_hw_scan_work); INIT_WORK(&wvif->scan_work, wfx_hw_scan_work);
......
...@@ -43,6 +43,7 @@ struct wfx_dev { ...@@ -43,6 +43,7 @@ struct wfx_dev {
struct delayed_work cooling_timeout_work; struct delayed_work cooling_timeout_work;
bool poll_irq; bool poll_irq;
bool chip_frozen; bool chip_frozen;
struct mutex scan_lock;
struct mutex conf_mutex; struct mutex conf_mutex;
struct wfx_hif_cmd hif_cmd; struct wfx_hif_cmd hif_cmd;
...@@ -80,8 +81,6 @@ struct wfx_vif { ...@@ -80,8 +81,6 @@ struct wfx_vif {
unsigned long uapsd_mask; unsigned long uapsd_mask;
/* avoid some operations in parallel with scan */
struct mutex scan_lock;
struct work_struct scan_work; struct work_struct scan_work;
struct completion scan_complete; struct completion scan_complete;
int scan_nb_chan_done; int scan_nb_chan_done;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment