diff options
author | 2019-09-19 14:25:48 +0000 | |
---|---|---|
committer | 2019-10-04 10:48:54 +0200 | |
commit | 40115bbc40e2fd2de0e01ef2a28e0d09a1b5d0d1 (patch) | |
tree | d3d7723d90f9ec8ae5c77e30ce61df6ffd523640 /drivers/staging/wfx/scan.c | |
parent | staging: wfx: implement 802.11 key handling (diff) | |
download | linux-dev-40115bbc40e2fd2de0e01ef2a28e0d09a1b5d0d1.tar.xz linux-dev-40115bbc40e2fd2de0e01ef2a28e0d09a1b5d0d1.zip |
staging: wfx: implement the rest of mac80211 API
Finish to fill struct ieee80211_ops with necessary callbacks. Driver is
now ready to be registered to mac80211.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20190919142527.31797-21-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/wfx/scan.c')
-rw-r--r-- | drivers/staging/wfx/scan.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 207b26ebc9fd..ea5001c915f6 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -21,11 +21,26 @@ static void __ieee80211_scan_completed_compat(struct ieee80211_hw *hw, bool abor ieee80211_scan_completed(hw, &info); } +static void wfx_scan_restart_delayed(struct wfx_vif *wvif) +{ + if (wvif->delayed_unjoin) { + wvif->delayed_unjoin = false; + if (!schedule_work(&wvif->unjoin_work)) + wfx_tx_unlock(wvif->wdev); + } else if (wvif->delayed_link_loss) { + wvif->delayed_link_loss = 0; + wfx_cqm_bssloss_sm(wvif, 1, 0, 0); + } +} + static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan) { int ret; int tmo = 500; + if (wvif->state == WFX_STATE_PRE_STA) + return -EBUSY; + tmo += scan->scan_req.num_of_channels * ((20 * (scan->scan_req.max_channel_time)) + 10); atomic_set(&wvif->scan.in_progress, 1); @@ -38,6 +53,7 @@ static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan) atomic_set(&wvif->scan.in_progress, 0); atomic_set(&wvif->wdev->scan_in_progress, 0); cancel_delayed_work_sync(&wvif->scan.timeout); + wfx_scan_restart_delayed(wvif); } return ret; } @@ -56,6 +72,9 @@ int wfx_hw_scan(struct ieee80211_hw *hw, if (!wvif) return -EINVAL; + if (wvif->state == WFX_STATE_AP) + return -EOPNOTSUPP; + if (req->n_ssids == 1 && !req->ssids[0].ssid_len) req->n_ssids = 0; @@ -121,11 +140,23 @@ void wfx_scan_work(struct work_struct *work) .scan_req.scan_type.type = 0, /* Foreground */ }; struct ieee80211_channel *first; + bool first_run = (wvif->scan.begin == wvif->scan.curr && + wvif->scan.begin != wvif->scan.end); int i; down(&wvif->scan.lock); mutex_lock(&wvif->wdev->conf_mutex); + if (first_run) { + if (wvif->state == WFX_STATE_STA && + !(wvif->powersave_mode.pm_mode.enter_psm)) { + struct hif_req_set_pm_mode pm = wvif->powersave_mode; + + pm.pm_mode.enter_psm = 1; + wfx_set_pm(wvif, &pm); + } + } + if (!wvif->scan.req || wvif->scan.curr == wvif->scan.end) { if (wvif->scan.output_power != wvif->wdev->output_power) hif_set_output_power(wvif, wvif->wdev->output_power * 10); @@ -138,10 +169,14 @@ void wfx_scan_work(struct work_struct *work) dev_dbg(wvif->wdev->dev, "scan canceled\n"); wvif->scan.req = NULL; + wfx_scan_restart_delayed(wvif); wfx_tx_unlock(wvif->wdev); mutex_unlock(&wvif->wdev->conf_mutex); __ieee80211_scan_completed_compat(wvif->wdev->hw, wvif->scan.status ? 1 : 0); up(&wvif->scan.lock); + if (wvif->state == WFX_STATE_STA && + !(wvif->powersave_mode.pm_mode.enter_psm)) + wfx_set_pm(wvif, &wvif->powersave_mode); return; } first = *wvif->scan.curr; @@ -170,6 +205,11 @@ void wfx_scan_work(struct work_struct *work) scan.ssids = &wvif->scan.ssids[0]; scan.scan_req.num_of_channels = it - wvif->scan.curr; scan.scan_req.probe_delay = 100; + // FIXME: Check if FW can do active scan while joined. + if (wvif->state == WFX_STATE_STA) { + scan.scan_req.scan_type.type = 1; + scan.scan_req.scan_flags.fbg = 1; + } scan.ch = kcalloc(scan.scan_req.num_of_channels, sizeof(u8), GFP_KERNEL); |