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 <jerome.pouiller@silabs.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20231004172843.195332-7-jerome.pouiller@silabs.com
 
        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);
 }
                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);
 
        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);
                        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);
 }
 
                        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);
 
 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)",
        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);
 
 
        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;
 
        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;