Jerome Pouiller <Jerome.Pouiller@xxxxxxxxxx> writes: > From: Jérôme Pouiller <jerome.pouiller@xxxxxxxxxx> > > Signed-off-by: Jérôme Pouiller <jerome.pouiller@xxxxxxxxxx> [...] > +/* It is not really necessary to run scan request asynchronously. However, > + * there is a bug in "iw scan" when ieee80211_scan_completed() is called before > + * wfx_hw_scan() return > + */ > +void wfx_hw_scan_work(struct work_struct *work) > +{ > + struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan_work); > + struct ieee80211_scan_request *hw_req = wvif->scan_req; > + int chan_cur, ret, err; > + > + mutex_lock(&wvif->wdev->conf_mutex); > + mutex_lock(&wvif->scan_lock); > + if (wvif->join_in_progress) { > + dev_info(wvif->wdev->dev, "abort in-progress REQ_JOIN"); > + wfx_reset(wvif); > + } > + update_probe_tmpl(wvif, &hw_req->req); > + chan_cur = 0; > + err = 0; > + do { > + ret = send_scan_req(wvif, &hw_req->req, chan_cur); > + if (ret > 0) { > + chan_cur += ret; > + err = 0; > + } > + if (!ret) > + err++; > + if (err > 2) { > + dev_err(wvif->wdev->dev, "scan has not been able to start\n"); > + ret = -ETIMEDOUT; > + } > + } while (ret >= 0 && chan_cur < hw_req->req.n_channels); > + mutex_unlock(&wvif->scan_lock); > + mutex_unlock(&wvif->wdev->conf_mutex); > + __ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); > +} > + > +int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, > + struct ieee80211_scan_request *hw_req) > +{ > + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; > + > + WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); > + wvif->scan_req = hw_req; > + schedule_work(&wvif->scan_work); > + return 0; > +} This scan logic looks fishy to me, but no time to investigate in detail. Though not a blocker. -- https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches