|
@@ -568,23 +568,59 @@ out:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
|
|
|
- struct ieee80211_vif *vif,
|
|
|
- const u8 *mac_addr)
|
|
|
+static void wcn36xx_hw_scan_worker(struct work_struct *work)
|
|
|
{
|
|
|
- struct wcn36xx *wcn = hw->priv;
|
|
|
+ struct wcn36xx *wcn = container_of(work, struct wcn36xx, scan_work);
|
|
|
+ struct cfg80211_scan_request *req = wcn->scan_req;
|
|
|
+ u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
|
|
|
+ struct cfg80211_scan_info scan_info = {};
|
|
|
+ int i;
|
|
|
+
|
|
|
+ wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 scan %d channels worker\n", req->n_channels);
|
|
|
+
|
|
|
+ for (i = 0; i < req->n_channels; i++)
|
|
|
+ channels[i] = req->channels[i]->hw_value;
|
|
|
+
|
|
|
+ wcn36xx_smd_update_scan_params(wcn, channels, req->n_channels);
|
|
|
|
|
|
wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
|
|
|
- wcn36xx_smd_start_scan(wcn);
|
|
|
+ for (i = 0; i < req->n_channels; i++) {
|
|
|
+ wcn->scan_freq = req->channels[i]->center_freq;
|
|
|
+ wcn->scan_band = req->channels[i]->band;
|
|
|
+
|
|
|
+ wcn36xx_smd_start_scan(wcn, req->channels[i]->hw_value);
|
|
|
+ msleep(30);
|
|
|
+ wcn36xx_smd_end_scan(wcn, req->channels[i]->hw_value);
|
|
|
+
|
|
|
+ wcn->scan_freq = 0;
|
|
|
+ }
|
|
|
+ wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
|
|
|
+
|
|
|
+ scan_info.aborted = false;
|
|
|
+ ieee80211_scan_completed(wcn->hw, &scan_info);
|
|
|
+
|
|
|
+ mutex_lock(&wcn->scan_lock);
|
|
|
+ wcn->scan_req = NULL;
|
|
|
+ mutex_unlock(&wcn->scan_lock);
|
|
|
}
|
|
|
|
|
|
-static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
|
|
|
- struct ieee80211_vif *vif)
|
|
|
+static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
|
|
|
+ struct ieee80211_vif *vif,
|
|
|
+ struct ieee80211_scan_request *hw_req)
|
|
|
{
|
|
|
struct wcn36xx *wcn = hw->priv;
|
|
|
|
|
|
- wcn36xx_smd_end_scan(wcn);
|
|
|
- wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
|
|
|
+ mutex_lock(&wcn->scan_lock);
|
|
|
+ if (wcn->scan_req) {
|
|
|
+ mutex_unlock(&wcn->scan_lock);
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+ wcn->scan_req = &hw_req->req;
|
|
|
+ mutex_unlock(&wcn->scan_lock);
|
|
|
+
|
|
|
+ schedule_work(&wcn->scan_work);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
|
|
@@ -997,8 +1033,7 @@ static const struct ieee80211_ops wcn36xx_ops = {
|
|
|
.configure_filter = wcn36xx_configure_filter,
|
|
|
.tx = wcn36xx_tx,
|
|
|
.set_key = wcn36xx_set_key,
|
|
|
- .sw_scan_start = wcn36xx_sw_scan_start,
|
|
|
- .sw_scan_complete = wcn36xx_sw_scan_complete,
|
|
|
+ .hw_scan = wcn36xx_hw_scan,
|
|
|
.bss_info_changed = wcn36xx_bss_info_changed,
|
|
|
.set_rts_threshold = wcn36xx_set_rts_threshold,
|
|
|
.sta_add = wcn36xx_sta_add,
|
|
@@ -1023,6 +1058,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
|
|
|
ieee80211_hw_set(wcn->hw, SUPPORTS_PS);
|
|
|
ieee80211_hw_set(wcn->hw, SIGNAL_DBM);
|
|
|
ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL);
|
|
|
+ ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS);
|
|
|
|
|
|
wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
|
|
BIT(NL80211_IFTYPE_AP) |
|
|
@@ -1032,6 +1068,9 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
|
|
|
wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz;
|
|
|
wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz;
|
|
|
|
|
|
+ wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
|
|
|
+ wcn->hw->wiphy->max_scan_ie_len = WCN36XX_MAX_SCAN_IE_LEN;
|
|
|
+
|
|
|
wcn->hw->wiphy->cipher_suites = cipher_suites;
|
|
|
wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
|
|
|
|
|
@@ -1152,6 +1191,9 @@ static int wcn36xx_probe(struct platform_device *pdev)
|
|
|
wcn->hw = hw;
|
|
|
wcn->dev = &pdev->dev;
|
|
|
mutex_init(&wcn->hal_mutex);
|
|
|
+ mutex_init(&wcn->scan_lock);
|
|
|
+
|
|
|
+ INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);
|
|
|
|
|
|
wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process);
|
|
|
if (IS_ERR(wcn->smd_channel)) {
|