ath6kl: rework scheduled scan

This patch reflects changes in the firmware scheduled scan
implementation to behave better in cases with multiple concurrent vifs.
Major changes:

	- scheduled scan filters and state are now programmed per-vif.
	- decouple scheduled scan from host sleep.

To maintain graceful failure with old firmwares, a new firmware
capability bit is introduced: ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2.
ath6kl simply won't advertise scheduled scan to cfg80211 if the
SCHED_SCAN_V2 is not supported.

Since firmwares from here on out won't support the previous implicit API
for scheduled scan (set WoW filters and host sleep), bump the firmware
API to protect old drivers.

Unfortunately, due to firmware RAM constraints ath6kl still cannot
expect a scan complete event at the end of a scheduled scan results
cycle, so the sched_scan_timer is retained.

Signed-off-by: Thomas Pedersen <c_tpeder@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
Thomas Pedersen
2012-08-15 16:51:24 -07:00
committed by Kalle Valo
parent a3b3842c2e
commit b1f47e3a96
7 changed files with 50 additions and 60 deletions

View File

@@ -147,15 +147,11 @@ static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
{
struct ath6kl *ar = vif->ar;
if (ar->state != ATH6KL_STATE_SCHED_SCAN)
if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
return false;
del_timer_sync(&vif->sched_scan_timer);
ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
ATH6KL_HOST_MODE_AWAKE);
ar->state = ATH6KL_STATE_ON;
ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false);
return true;
}
@@ -2448,13 +2444,6 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
break;
case ATH6KL_CFG_SUSPEND_SCHED_SCAN:
/*
* Nothing needed for schedule scan, firmware is already in
* wow mode and sleeping most of the time.
*/
break;
default:
break;
}
@@ -2502,9 +2491,6 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
}
break;
case ATH6KL_STATE_SCHED_SCAN:
break;
default:
break;
}
@@ -3246,10 +3232,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
if (vif->sme_state != SME_DISCONNECTED)
return -EBUSY;
/* The FW currently can't support multi-vif WoW properly. */
if (ar->num_vif > 1)
return -EIO;
ath6kl_cfg80211_scan_complete_event(vif, true);
ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
@@ -3295,15 +3277,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
interval, interval,
vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
ATH6KL_WOW_MODE_ENABLE,
WOW_FILTER_SSID,
WOW_HOST_REQ_DELAY);
if (ret) {
ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret);
return ret;
}
/* this also clears IE in fw if it's not set */
ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
WMI_FRAME_PROBE_REQ,
@@ -3314,17 +3287,13 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
return ret;
}
ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
ATH6KL_HOST_MODE_ASLEEP);
if (ret) {
ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n",
ret);
ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
if (ret)
return ret;
}
ar->state = ATH6KL_STATE_SCHED_SCAN;
set_bit(SCHED_SCANNING, &vif->flags);
return ret;
return 0;
}
static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
@@ -3763,7 +3732,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,