From 04106ec5bb025f275d0e18553c253adf12a0cc8a Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Wed, 4 Oct 2023 19:28:41 +0200 Subject: [PATCH] wifi: wfx: scan_lock is global to the device MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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: Jérôme Pouiller Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20231004172843.195332-7-jerome.pouiller@silabs.com --- drivers/net/wireless/silabs/wfx/main.c | 2 ++ drivers/net/wireless/silabs/wfx/scan.c | 4 ++-- drivers/net/wireless/silabs/wfx/sta.c | 11 +++-------- drivers/net/wireless/silabs/wfx/wfx.h | 3 +-- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/silabs/wfx/main.c b/drivers/net/wireless/silabs/wfx/main.c index ede822d771aa..4bf16bceb0bb 100644 --- a/drivers/net/wireless/silabs/wfx/main.c +++ b/drivers/net/wireless/silabs/wfx/main.c @@ -246,6 +246,7 @@ static void wfx_free_common(void *data) mutex_destroy(&wdev->tx_power_loop_info_lock); mutex_destroy(&wdev->rx_stats_lock); + mutex_destroy(&wdev->scan_lock); mutex_destroy(&wdev->conf_mutex); ieee80211_free_hw(wdev->hw); } @@ -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"); mutex_init(&wdev->conf_mutex); + mutex_init(&wdev->scan_lock); mutex_init(&wdev->rx_stats_lock); mutex_init(&wdev->tx_power_loop_info_lock); init_completion(&wdev->firmware_ready); diff --git a/drivers/net/wireless/silabs/wfx/scan.c b/drivers/net/wireless/silabs/wfx/scan.c index 16f619ed22e0..d6f98035f684 100644 --- a/drivers/net/wireless/silabs/wfx/scan.c +++ b/drivers/net/wireless/silabs/wfx/scan.c @@ -95,7 +95,7 @@ void wfx_hw_scan_work(struct work_struct *work) int chan_cur, ret, err; mutex_lock(&wvif->wdev->conf_mutex); - mutex_lock(&wvif->scan_lock); + mutex_lock(&wvif->wdev->scan_lock); if (wvif->join_in_progress) { dev_info(wvif->wdev->dev, "abort in-progress REQ_JOIN"); wfx_reset(wvif); @@ -116,7 +116,7 @@ void wfx_hw_scan_work(struct work_struct *work) ret = -ETIMEDOUT; } } 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); wfx_ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); } diff --git a/drivers/net/wireless/silabs/wfx/sta.c b/drivers/net/wireless/silabs/wfx/sta.c index cb03a5cf7ffa..8533bad6caea 100644 --- a/drivers/net/wireless/silabs/wfx/sta.c +++ b/drivers/net/wireless/silabs/wfx/sta.c @@ -97,7 +97,7 @@ void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, FIF_PROBE_REQ | FIF_PSPOLL; /* 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; mutex_lock(&wdev->conf_mutex); @@ -621,18 +621,14 @@ 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) { - struct wfx_vif *wvif_it; - if (notify_cmd != STA_NOTIFY_AWAKE) return; /* 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. */ - wvif_it = NULL; - while ((wvif_it = wvif_iterate(wvif->wdev, wvif_it)) != NULL) - if (mutex_is_locked(&wvif_it->scan_lock)) - return; + if (mutex_is_locked(&wvif->wdev->scan_lock)) + return; if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed) dev_warn(wvif->wdev->dev, "incorrect sequence (%d CAB in queue)", @@ -730,7 +726,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) complete(&wvif->set_pm_mode_complete); INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work); - mutex_init(&wvif->scan_lock); init_completion(&wvif->scan_complete); INIT_WORK(&wvif->scan_work, wfx_hw_scan_work); diff --git a/drivers/net/wireless/silabs/wfx/wfx.h b/drivers/net/wireless/silabs/wfx/wfx.h index 13ba84b3b2c3..a41b2c35fa41 100644 --- a/drivers/net/wireless/silabs/wfx/wfx.h +++ b/drivers/net/wireless/silabs/wfx/wfx.h @@ -43,6 +43,7 @@ struct wfx_dev { struct delayed_work cooling_timeout_work; bool poll_irq; bool chip_frozen; + struct mutex scan_lock; struct mutex conf_mutex; struct wfx_hif_cmd hif_cmd; @@ -80,8 +81,6 @@ struct wfx_vif { unsigned long uapsd_mask; - /* avoid some operations in parallel with scan */ - struct mutex scan_lock; struct work_struct scan_work; struct completion scan_complete; int scan_nb_chan_done; -- 2.25.1