1 // SPDX-License-Identifier: GPL-2.0-only
3 * This file is part of wl1271
5 * Copyright (C) 2009-2010 Nokia Corporation
7 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
10 #include <linux/ieee80211.h>
11 #include <linux/pm_runtime.h>
20 void wl1271_scan_complete_work(struct work_struct
*work
)
22 struct delayed_work
*dwork
;
24 struct wl12xx_vif
*wlvif
;
25 struct cfg80211_scan_info info
= {
30 dwork
= to_delayed_work(work
);
31 wl
= container_of(dwork
, struct wl1271
, scan_complete_work
);
33 wl1271_debug(DEBUG_SCAN
, "Scanning complete");
35 mutex_lock(&wl
->mutex
);
37 if (unlikely(wl
->state
!= WLCORE_STATE_ON
))
40 if (wl
->scan
.state
== WL1271_SCAN_STATE_IDLE
)
43 wlvif
= wl
->scan_wlvif
;
46 * Rearm the tx watchdog just before idling scan. This
47 * prevents just-finished scans from triggering the watchdog
49 wl12xx_rearm_tx_watchdog_locked(wl
);
51 wl
->scan
.state
= WL1271_SCAN_STATE_IDLE
;
52 memset(wl
->scan
.scanned_ch
, 0, sizeof(wl
->scan
.scanned_ch
));
54 wl
->scan_wlvif
= NULL
;
56 ret
= pm_runtime_get_sync(wl
->dev
);
58 pm_runtime_put_noidle(wl
->dev
);
62 if (test_bit(WLVIF_FLAG_STA_ASSOCIATED
, &wlvif
->flags
)) {
63 /* restore hardware connection monitoring template */
64 wl1271_cmd_build_ap_probe_req(wl
, wlvif
, wlvif
->probereq
);
67 if (wl
->scan
.failed
) {
68 wl1271_info("Scan completed due to error.");
69 wl12xx_queue_recovery_work(wl
);
72 wlcore_cmd_regdomain_config_locked(wl
);
74 pm_runtime_mark_last_busy(wl
->dev
);
75 pm_runtime_put_autosuspend(wl
->dev
);
77 ieee80211_scan_completed(wl
->hw
, &info
);
80 mutex_unlock(&wl
->mutex
);
84 static void wlcore_started_vifs_iter(void *data
, u8
*mac
,
85 struct ieee80211_vif
*vif
)
87 struct wl12xx_vif
*wlvif
= wl12xx_vif_to_data(vif
);
89 int *count
= (int *)data
;
92 * count active interfaces according to interface type.
93 * checking only bss_conf.idle is bad for some cases, e.g.
94 * we don't want to count sta in p2p_find as active interface.
96 switch (wlvif
->bss_type
) {
97 case BSS_TYPE_STA_BSS
:
98 if (test_bit(WLVIF_FLAG_STA_ASSOCIATED
, &wlvif
->flags
))
102 case BSS_TYPE_AP_BSS
:
103 if (wlvif
->wl
->active_sta_count
> 0)
115 static int wlcore_count_started_vifs(struct wl1271
*wl
)
119 ieee80211_iterate_active_interfaces_atomic(wl
->hw
,
120 IEEE80211_IFACE_ITER_RESUME_ALL
,
121 wlcore_started_vifs_iter
, &count
);
126 wlcore_scan_get_channels(struct wl1271
*wl
,
127 struct ieee80211_channel
*req_channels
[],
130 struct conn_scan_ch_params
*channels
,
131 u32 band
, bool radar
, bool passive
,
132 int start
, int max_channels
,
138 bool force_passive
= !n_ssids
;
139 u32 min_dwell_time_active
, max_dwell_time_active
;
140 u32 dwell_time_passive
, dwell_time_dfs
;
142 /* configure dwell times according to scan type */
143 if (scan_type
== SCAN_TYPE_SEARCH
) {
144 struct conf_scan_settings
*c
= &wl
->conf
.scan
;
145 bool active_vif_exists
= !!wlcore_count_started_vifs(wl
);
147 min_dwell_time_active
= active_vif_exists
?
148 c
->min_dwell_time_active
:
149 c
->min_dwell_time_active_long
;
150 max_dwell_time_active
= active_vif_exists
?
151 c
->max_dwell_time_active
:
152 c
->max_dwell_time_active_long
;
153 dwell_time_passive
= c
->dwell_time_passive
;
154 dwell_time_dfs
= c
->dwell_time_dfs
;
156 struct conf_sched_scan_settings
*c
= &wl
->conf
.sched_scan
;
159 if (band
== NL80211_BAND_5GHZ
)
160 delta_per_probe
= c
->dwell_time_delta_per_probe_5
;
162 delta_per_probe
= c
->dwell_time_delta_per_probe
;
164 min_dwell_time_active
= c
->base_dwell_time
+
165 n_ssids
* c
->num_probe_reqs
* delta_per_probe
;
167 max_dwell_time_active
= min_dwell_time_active
+
168 c
->max_dwell_time_delta
;
169 dwell_time_passive
= c
->dwell_time_passive
;
170 dwell_time_dfs
= c
->dwell_time_dfs
;
172 min_dwell_time_active
= DIV_ROUND_UP(min_dwell_time_active
, 1000);
173 max_dwell_time_active
= DIV_ROUND_UP(max_dwell_time_active
, 1000);
174 dwell_time_passive
= DIV_ROUND_UP(dwell_time_passive
, 1000);
175 dwell_time_dfs
= DIV_ROUND_UP(dwell_time_dfs
, 1000);
177 for (i
= 0, j
= start
;
178 i
< n_channels
&& j
< max_channels
;
180 flags
= req_channels
[i
]->flags
;
183 flags
|= IEEE80211_CHAN_NO_IR
;
185 if ((req_channels
[i
]->band
== band
) &&
186 !(flags
& IEEE80211_CHAN_DISABLED
) &&
187 (!!(flags
& IEEE80211_CHAN_RADAR
) == radar
) &&
188 /* if radar is set, we ignore the passive flag */
190 !!(flags
& IEEE80211_CHAN_NO_IR
) == passive
)) {
191 if (flags
& IEEE80211_CHAN_RADAR
) {
192 channels
[j
].flags
|= SCAN_CHANNEL_FLAGS_DFS
;
194 channels
[j
].passive_duration
=
195 cpu_to_le16(dwell_time_dfs
);
197 channels
[j
].passive_duration
=
198 cpu_to_le16(dwell_time_passive
);
201 channels
[j
].min_duration
=
202 cpu_to_le16(min_dwell_time_active
);
203 channels
[j
].max_duration
=
204 cpu_to_le16(max_dwell_time_active
);
206 channels
[j
].tx_power_att
= req_channels
[i
]->max_power
;
207 channels
[j
].channel
= req_channels
[i
]->hw_value
;
210 (band
== NL80211_BAND_2GHZ
) &&
211 (channels
[j
].channel
>= 12) &&
212 (channels
[j
].channel
<= 14) &&
213 (flags
& IEEE80211_CHAN_NO_IR
) &&
215 /* pactive channels treated as DFS */
216 channels
[j
].flags
= SCAN_CHANNEL_FLAGS_DFS
;
219 * n_pactive_ch is counted down from the end of
220 * the passive channel list
223 wl1271_debug(DEBUG_SCAN
, "n_pactive_ch = %d",
227 wl1271_debug(DEBUG_SCAN
, "freq %d, ch. %d, flags 0x%x, power %d, min/max_dwell %d/%d%s%s",
228 req_channels
[i
]->center_freq
,
229 req_channels
[i
]->hw_value
,
230 req_channels
[i
]->flags
,
231 req_channels
[i
]->max_power
,
232 min_dwell_time_active
,
233 max_dwell_time_active
,
234 flags
& IEEE80211_CHAN_RADAR
?
236 flags
& IEEE80211_CHAN_NO_IR
?
246 wlcore_set_scan_chan_params(struct wl1271
*wl
,
247 struct wlcore_scan_channels
*cfg
,
248 struct ieee80211_channel
*channels
[],
256 wlcore_scan_get_channels(wl
,
267 wlcore_scan_get_channels(wl
,
279 wlcore_scan_get_channels(wl
,
290 wlcore_scan_get_channels(wl
,
302 wlcore_scan_get_channels(wl
,
309 cfg
->passive
[1] + cfg
->dfs
,
314 /* 802.11j channels are not supported yet */
318 cfg
->passive_active
= n_pactive_ch
;
320 wl1271_debug(DEBUG_SCAN
, " 2.4GHz: active %d passive %d",
321 cfg
->active
[0], cfg
->passive
[0]);
322 wl1271_debug(DEBUG_SCAN
, " 5GHz: active %d passive %d",
323 cfg
->active
[1], cfg
->passive
[1]);
324 wl1271_debug(DEBUG_SCAN
, " DFS: %d", cfg
->dfs
);
326 return cfg
->passive
[0] || cfg
->active
[0] ||
327 cfg
->passive
[1] || cfg
->active
[1] || cfg
->dfs
||
328 cfg
->passive
[2] || cfg
->active
[2];
330 EXPORT_SYMBOL_GPL(wlcore_set_scan_chan_params
);
332 int wlcore_scan(struct wl1271
*wl
, struct ieee80211_vif
*vif
,
333 const u8
*ssid
, size_t ssid_len
,
334 struct cfg80211_scan_request
*req
)
336 struct wl12xx_vif
*wlvif
= wl12xx_vif_to_data(vif
);
339 * cfg80211 should guarantee that we don't get more channels
340 * than what we have registered.
342 BUG_ON(req
->n_channels
> WL1271_MAX_CHANNELS
);
344 if (wl
->scan
.state
!= WL1271_SCAN_STATE_IDLE
)
347 wl
->scan
.state
= WL1271_SCAN_STATE_2GHZ_ACTIVE
;
349 if (ssid_len
&& ssid
) {
350 wl
->scan
.ssid_len
= ssid_len
;
351 memcpy(wl
->scan
.ssid
, ssid
, ssid_len
);
353 wl
->scan
.ssid_len
= 0;
356 wl
->scan_wlvif
= wlvif
;
358 memset(wl
->scan
.scanned_ch
, 0, sizeof(wl
->scan
.scanned_ch
));
360 /* we assume failure so that timeout scenarios are handled correctly */
361 wl
->scan
.failed
= true;
362 ieee80211_queue_delayed_work(wl
->hw
, &wl
->scan_complete_work
,
363 msecs_to_jiffies(WL1271_SCAN_TIMEOUT
));
365 wl
->ops
->scan_start(wl
, wlvif
, req
);
369 /* Returns the scan type to be used or a negative value on error */
371 wlcore_scan_sched_scan_ssid_list(struct wl1271
*wl
,
372 struct wl12xx_vif
*wlvif
,
373 struct cfg80211_sched_scan_request
*req
)
375 struct wl1271_cmd_sched_scan_ssid_list
*cmd
= NULL
;
376 struct cfg80211_match_set
*sets
= req
->match_sets
;
377 struct cfg80211_ssid
*ssids
= req
->ssids
;
378 int ret
= 0, type
, i
, j
, n_match_ssids
= 0;
380 wl1271_debug((DEBUG_CMD
| DEBUG_SCAN
), "cmd sched scan ssid list");
382 /* count the match sets that contain SSIDs */
383 for (i
= 0; i
< req
->n_match_sets
; i
++)
384 if (sets
[i
].ssid
.ssid_len
> 0)
387 /* No filter, no ssids or only bcast ssid */
388 if (!n_match_ssids
&&
390 (req
->n_ssids
== 1 && req
->ssids
[0].ssid_len
== 0))) {
391 type
= SCAN_SSID_FILTER_ANY
;
395 cmd
= kzalloc(sizeof(*cmd
), GFP_KERNEL
);
401 cmd
->role_id
= wlvif
->role_id
;
402 if (!n_match_ssids
) {
403 /* No filter, with ssids */
404 type
= SCAN_SSID_FILTER_DISABLED
;
406 for (i
= 0; i
< req
->n_ssids
; i
++) {
407 cmd
->ssids
[cmd
->n_ssids
].type
= (ssids
[i
].ssid_len
) ?
408 SCAN_SSID_TYPE_HIDDEN
: SCAN_SSID_TYPE_PUBLIC
;
409 cmd
->ssids
[cmd
->n_ssids
].len
= ssids
[i
].ssid_len
;
410 memcpy(cmd
->ssids
[cmd
->n_ssids
].ssid
, ssids
[i
].ssid
,
415 type
= SCAN_SSID_FILTER_LIST
;
417 /* Add all SSIDs from the filters */
418 for (i
= 0; i
< req
->n_match_sets
; i
++) {
419 /* ignore sets without SSIDs */
420 if (!sets
[i
].ssid
.ssid_len
)
423 cmd
->ssids
[cmd
->n_ssids
].type
= SCAN_SSID_TYPE_PUBLIC
;
424 cmd
->ssids
[cmd
->n_ssids
].len
= sets
[i
].ssid
.ssid_len
;
425 memcpy(cmd
->ssids
[cmd
->n_ssids
].ssid
,
426 sets
[i
].ssid
.ssid
, sets
[i
].ssid
.ssid_len
);
429 if ((req
->n_ssids
> 1) ||
430 (req
->n_ssids
== 1 && req
->ssids
[0].ssid_len
> 0)) {
432 * Mark all the SSIDs passed in the SSID list as HIDDEN,
433 * so they're used in probe requests.
435 for (i
= 0; i
< req
->n_ssids
; i
++) {
436 if (!req
->ssids
[i
].ssid_len
)
439 for (j
= 0; j
< cmd
->n_ssids
; j
++)
440 if ((req
->ssids
[i
].ssid_len
==
441 cmd
->ssids
[j
].len
) &&
442 !memcmp(req
->ssids
[i
].ssid
,
444 req
->ssids
[i
].ssid_len
)) {
446 SCAN_SSID_TYPE_HIDDEN
;
449 /* Fail if SSID isn't present in the filters */
450 if (j
== cmd
->n_ssids
) {
458 ret
= wl1271_cmd_send(wl
, CMD_CONNECTION_SCAN_SSID_CFG
, cmd
,
461 wl1271_error("cmd sched scan ssid list failed");
472 EXPORT_SYMBOL_GPL(wlcore_scan_sched_scan_ssid_list
);
474 void wlcore_scan_sched_scan_results(struct wl1271
*wl
)
476 wl1271_debug(DEBUG_SCAN
, "got periodic scan results");
478 ieee80211_sched_scan_results(wl
->hw
);
480 EXPORT_SYMBOL_GPL(wlcore_scan_sched_scan_results
);