int wl1271_scan_sched_scan_config(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct cfg80211_sched_scan_request *req, struct ieee80211_sched_scan_ies *ies) { struct wl1271_cmd_sched_scan_config *cfg = NULL; struct conf_sched_scan_settings *c = &wl->conf.sched_scan; int i, ret; bool force_passive = !req->n_ssids; wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); if (!cfg) return -ENOMEM; cfg->rssi_threshold = c->rssi_threshold; cfg->snr_threshold = c->snr_threshold; cfg->n_probe_reqs = c->num_probe_reqs; cfg->cycles = 0; cfg->report_after = 1; cfg->terminate = 0; cfg->tag = WL1271_SCAN_DEFAULT_TAG; cfg->bss_type = SCAN_BSS_TYPE_ANY; for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) cfg->intervals[i] = cpu_to_le32(req->interval); cfg->ssid_len = 0; ret = wl12xx_scan_sched_scan_ssid_list(wl, req); if (ret < 0) goto out; cfg->filter_type = ret; wl1271_debug(DEBUG_SCAN, "filter_type = %d", cfg->filter_type); if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { wl1271_error("scan channel list is empty"); ret = -EINVAL; goto out; } if (!force_passive && cfg->active[0]) { u8 band = IEEE80211_BAND_2GHZ; ret = wl12xx_cmd_build_probe_req(wl, wlvif, wlvif->dev_role_id, band, req->ssids[0].ssid, req->ssids[0].ssid_len, ies->ie[band], ies->len[band]); if (ret < 0) { wl1271_error("2.4GHz PROBE request template failed"); goto out; } } if (!force_passive && cfg->active[1]) { u8 band = IEEE80211_BAND_5GHZ; ret = wl12xx_cmd_build_probe_req(wl, wlvif, wlvif->dev_role_id, band, req->ssids[0].ssid, req->ssids[0].ssid_len, ies->ie[band], ies->len[band]); if (ret < 0) { wl1271_error("5GHz PROBE request template failed"); goto out; } } wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg)); ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg, sizeof(*cfg), 0); if (ret < 0) { wl1271_error("SCAN configuration failed"); goto out; } out: kfree(cfg); return ret; }
int wl1271_scan_sched_scan_config(struct wl1271 *wl, struct cfg80211_sched_scan_request *req, struct ieee80211_sched_scan_ies *ies) { struct wl1271_cmd_sched_scan_config *cfg = NULL; struct conf_sched_scan_settings *c = &wl->conf.sched_scan; int i, ret; bool force_passive = !req->n_ssids; wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); if (!cfg) return -ENOMEM; cfg->rssi_threshold = c->rssi_threshold; cfg->snr_threshold = c->snr_threshold; cfg->n_probe_reqs = c->num_probe_reqs; /* cycles set to 0 it means infinite (until manually stopped) */ cfg->cycles = 0; /* report APs when at least 1 is found */ cfg->report_after = 1; /* don't stop scanning automatically when something is found */ cfg->terminate = 0; cfg->tag = WL1271_SCAN_DEFAULT_TAG; /* don't filter on BSS type */ cfg->bss_type = SCAN_BSS_TYPE_ANY; /* currently NL80211 supports only a single interval */ for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) cfg->intervals[i] = cpu_to_le32(req->interval); if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) { cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC; cfg->ssid_len = req->ssids[0].ssid_len; memcpy(cfg->ssid, req->ssids[0].ssid, req->ssids[0].ssid_len); } else { cfg->filter_type = SCAN_SSID_FILTER_ANY; cfg->ssid_len = 0; } if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { wl1271_error("scan channel list is empty"); ret = -EINVAL; goto out; } if (!force_passive && cfg->active[0]) { ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, req->ssids[0].ssid_len, ies->ie[IEEE80211_BAND_2GHZ], ies->len[IEEE80211_BAND_2GHZ], IEEE80211_BAND_2GHZ); if (ret < 0) { wl1271_error("2.4GHz PROBE request template failed"); goto out; } } if (!force_passive && cfg->active[1]) { ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, req->ssids[0].ssid_len, ies->ie[IEEE80211_BAND_5GHZ], ies->len[IEEE80211_BAND_5GHZ], IEEE80211_BAND_5GHZ); if (ret < 0) { wl1271_error("5GHz PROBE request template failed"); goto out; } } wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg)); ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg, sizeof(*cfg), 0); if (ret < 0) { wl1271_error("SCAN configuration failed"); goto out; } out: kfree(cfg); return ret; }
int wl1271_scan_sched_scan_config(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct cfg80211_sched_scan_request *req, struct ieee80211_sched_scan_ies *ies) { struct wl1271_cmd_sched_scan_config *cfg = NULL; struct conf_sched_scan_settings *c = &wl->conf.sched_scan; int i, ret; bool force_passive = !req->n_ssids; wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); if (req->n_short_intervals > SCAN_MAX_SHORT_INTERVALS) { wl1271_warning("Number of short intervals requested (%d)" "exceeds limit (%d)", req->n_short_intervals, SCAN_MAX_SHORT_INTERVALS); return -EINVAL; } cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); if (!cfg) return -ENOMEM; cfg->role_id = wlvif->dev_role_id; cfg->rssi_threshold = c->rssi_threshold; cfg->snr_threshold = c->snr_threshold; cfg->n_probe_reqs = c->num_probe_reqs; /* cycles set to 0 it means infinite (until manually stopped) */ cfg->cycles = 0; /* report APs when at least 1 is found */ cfg->report_after = 1; /* don't stop scanning automatically when something is found */ cfg->terminate = 0; cfg->tag = WL1271_SCAN_DEFAULT_TAG; /* don't filter on BSS type */ cfg->bss_type = SCAN_BSS_TYPE_ANY; for (i = 1; i < SCAN_MAX_CYCLE_INTERVALS; i++) { if (i <= req->n_short_intervals) cfg->intervals[i] = cpu_to_le32(req->short_interval); else cfg->intervals[i] = cpu_to_le32(req->long_interval); } cfg->ssid_len = 0; ret = wl12xx_scan_sched_scan_ssid_list(wl, wlvif, req); if (ret < 0) goto out; cfg->filter_type = ret; wl1271_debug(DEBUG_SCAN, "filter_type = %d", cfg->filter_type); if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { wl1271_error("scan channel list is empty"); ret = -EINVAL; goto out; } if (!force_passive && cfg->active[0]) { u8 band = IEEE80211_BAND_2GHZ; ret = wl12xx_cmd_build_probe_req(wl, wlvif, wlvif->dev_role_id, band, req->ssids[0].ssid, req->ssids[0].ssid_len, ies->ie[band], ies->len[band], true); if (ret < 0) { wl1271_error("2.4GHz PROBE request template failed"); goto out; } } if (!force_passive && cfg->active[1]) { u8 band = IEEE80211_BAND_5GHZ; ret = wl12xx_cmd_build_probe_req(wl, wlvif, wlvif->dev_role_id, band, req->ssids[0].ssid, req->ssids[0].ssid_len, ies->ie[band], ies->len[band], true); if (ret < 0) { wl1271_error("5GHz PROBE request template failed"); goto out; } } wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg)); ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg, sizeof(*cfg), 0); if (ret < 0) { wl1271_error("SCAN configuration failed"); goto out; } out: kfree(cfg); return ret; }