1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
10 #define P2P_WILDCARD_SSID "DIRECT-"
11 #define P2P_DMG_SOCIAL_CHANNEL 2
12 #define P2P_SEARCH_DURATION_MS 500
13 #define P2P_DEFAULT_BI 100
15 static int wil_p2p_start_listen(struct wil6210_vif
*vif
)
17 struct wil6210_priv
*wil
= vif_to_wil(vif
);
18 struct wil_p2p_info
*p2p
= &vif
->p2p
;
19 u8 channel
= p2p
->listen_chan
.hw_value
;
22 lockdep_assert_held(&wil
->mutex
);
24 rc
= wmi_p2p_cfg(vif
, channel
, P2P_DEFAULT_BI
);
26 wil_err(wil
, "wmi_p2p_cfg failed\n");
30 rc
= wmi_set_ssid(vif
, strlen(P2P_WILDCARD_SSID
), P2P_WILDCARD_SSID
);
32 wil_err(wil
, "wmi_set_ssid failed\n");
36 rc
= wmi_start_listen(vif
);
38 wil_err(wil
, "wmi_start_listen failed\n");
42 INIT_WORK(&p2p
->discovery_expired_work
, wil_p2p_listen_expired
);
43 mod_timer(&p2p
->discovery_timer
,
44 jiffies
+ msecs_to_jiffies(p2p
->listen_duration
));
47 wmi_stop_discovery(vif
);
53 bool wil_p2p_is_social_scan(struct cfg80211_scan_request
*request
)
55 return (request
->n_channels
== 1) &&
56 (request
->channels
[0]->hw_value
== P2P_DMG_SOCIAL_CHANNEL
);
59 int wil_p2p_search(struct wil6210_vif
*vif
,
60 struct cfg80211_scan_request
*request
)
62 struct wil6210_priv
*wil
= vif_to_wil(vif
);
64 struct wil_p2p_info
*p2p
= &vif
->p2p
;
66 wil_dbg_misc(wil
, "p2p_search: channel %d\n", P2P_DMG_SOCIAL_CHANNEL
);
68 lockdep_assert_held(&wil
->mutex
);
70 if (p2p
->discovery_started
) {
71 wil_err(wil
, "search failed. discovery already ongoing\n");
76 rc
= wmi_p2p_cfg(vif
, P2P_DMG_SOCIAL_CHANNEL
, P2P_DEFAULT_BI
);
78 wil_err(wil
, "wmi_p2p_cfg failed\n");
82 rc
= wmi_set_ssid(vif
, strlen(P2P_WILDCARD_SSID
), P2P_WILDCARD_SSID
);
84 wil_err(wil
, "wmi_set_ssid failed\n");
88 /* Set application IE to probe request and probe response */
89 rc
= wmi_set_ie(vif
, WMI_FRAME_PROBE_REQ
,
90 request
->ie_len
, request
->ie
);
92 wil_err(wil
, "wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n");
96 /* supplicant doesn't provide Probe Response IEs. As a workaround -
97 * re-use Probe Request IEs
99 rc
= wmi_set_ie(vif
, WMI_FRAME_PROBE_RESP
,
100 request
->ie_len
, request
->ie
);
102 wil_err(wil
, "wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n");
106 rc
= wmi_start_search(vif
);
108 wil_err(wil
, "wmi_start_search failed\n");
112 p2p
->discovery_started
= 1;
113 INIT_WORK(&p2p
->discovery_expired_work
, wil_p2p_search_expired
);
114 mod_timer(&p2p
->discovery_timer
,
115 jiffies
+ msecs_to_jiffies(P2P_SEARCH_DURATION_MS
));
119 wmi_stop_discovery(vif
);
125 int wil_p2p_listen(struct wil6210_priv
*wil
, struct wireless_dev
*wdev
,
126 unsigned int duration
, struct ieee80211_channel
*chan
,
129 struct wil6210_vif
*vif
= wdev_to_vif(wil
, wdev
);
130 struct wil_p2p_info
*p2p
= &vif
->p2p
;
136 wil_dbg_misc(wil
, "p2p_listen: duration %d\n", duration
);
138 mutex_lock(&wil
->mutex
);
140 if (p2p
->discovery_started
) {
141 wil_err(wil
, "discovery already ongoing\n");
146 memcpy(&p2p
->listen_chan
, chan
, sizeof(*chan
));
147 *cookie
= ++p2p
->cookie
;
148 p2p
->listen_duration
= duration
;
150 mutex_lock(&wil
->vif_mutex
);
151 if (vif
->scan_request
) {
152 wil_dbg_misc(wil
, "Delaying p2p listen until scan done\n");
153 p2p
->pending_listen_wdev
= wdev
;
154 p2p
->discovery_started
= 1;
156 mutex_unlock(&wil
->vif_mutex
);
159 mutex_unlock(&wil
->vif_mutex
);
161 rc
= wil_p2p_start_listen(vif
);
165 p2p
->discovery_started
= 1;
167 wil
->radio_wdev
= wdev
;
169 cfg80211_ready_on_channel(wdev
, *cookie
, chan
, duration
,
173 mutex_unlock(&wil
->mutex
);
177 u8
wil_p2p_stop_discovery(struct wil6210_vif
*vif
)
179 struct wil_p2p_info
*p2p
= &vif
->p2p
;
180 u8 started
= p2p
->discovery_started
;
182 if (p2p
->discovery_started
) {
183 if (p2p
->pending_listen_wdev
) {
184 /* discovery not really started, only pending */
185 p2p
->pending_listen_wdev
= NULL
;
187 del_timer_sync(&p2p
->discovery_timer
);
188 wmi_stop_discovery(vif
);
190 p2p
->discovery_started
= 0;
196 int wil_p2p_cancel_listen(struct wil6210_vif
*vif
, u64 cookie
)
198 struct wil6210_priv
*wil
= vif_to_wil(vif
);
199 struct wil_p2p_info
*p2p
= &vif
->p2p
;
202 mutex_lock(&wil
->mutex
);
204 if (cookie
!= p2p
->cookie
) {
205 wil_info(wil
, "Cookie mismatch: 0x%016llx vs. 0x%016llx\n",
206 p2p
->cookie
, cookie
);
207 mutex_unlock(&wil
->mutex
);
211 started
= wil_p2p_stop_discovery(vif
);
213 mutex_unlock(&wil
->mutex
);
216 wil_err(wil
, "listen not started\n");
220 mutex_lock(&wil
->vif_mutex
);
221 cfg80211_remain_on_channel_expired(vif_to_radio_wdev(wil
, vif
),
226 wil
->radio_wdev
= wil
->main_ndev
->ieee80211_ptr
;
227 mutex_unlock(&wil
->vif_mutex
);
231 void wil_p2p_listen_expired(struct work_struct
*work
)
233 struct wil_p2p_info
*p2p
= container_of(work
,
234 struct wil_p2p_info
, discovery_expired_work
);
235 struct wil6210_vif
*vif
= container_of(p2p
,
236 struct wil6210_vif
, p2p
);
237 struct wil6210_priv
*wil
= vif_to_wil(vif
);
240 wil_dbg_misc(wil
, "p2p_listen_expired\n");
242 mutex_lock(&wil
->mutex
);
243 started
= wil_p2p_stop_discovery(vif
);
244 mutex_unlock(&wil
->mutex
);
249 mutex_lock(&wil
->vif_mutex
);
250 cfg80211_remain_on_channel_expired(vif_to_radio_wdev(wil
, vif
),
255 wil
->radio_wdev
= wil
->main_ndev
->ieee80211_ptr
;
256 mutex_unlock(&wil
->vif_mutex
);
259 void wil_p2p_search_expired(struct work_struct
*work
)
261 struct wil_p2p_info
*p2p
= container_of(work
,
262 struct wil_p2p_info
, discovery_expired_work
);
263 struct wil6210_vif
*vif
= container_of(p2p
,
264 struct wil6210_vif
, p2p
);
265 struct wil6210_priv
*wil
= vif_to_wil(vif
);
268 wil_dbg_misc(wil
, "p2p_search_expired\n");
270 mutex_lock(&wil
->mutex
);
271 started
= wil_p2p_stop_discovery(vif
);
272 mutex_unlock(&wil
->mutex
);
275 struct cfg80211_scan_info info
= {
279 mutex_lock(&wil
->vif_mutex
);
280 if (vif
->scan_request
) {
281 cfg80211_scan_done(vif
->scan_request
, &info
);
282 vif
->scan_request
= NULL
;
285 wil
->main_ndev
->ieee80211_ptr
;
287 mutex_unlock(&wil
->vif_mutex
);
291 void wil_p2p_delayed_listen_work(struct work_struct
*work
)
293 struct wil_p2p_info
*p2p
= container_of(work
,
294 struct wil_p2p_info
, delayed_listen_work
);
295 struct wil6210_vif
*vif
= container_of(p2p
,
296 struct wil6210_vif
, p2p
);
297 struct wil6210_priv
*wil
= vif_to_wil(vif
);
300 mutex_lock(&wil
->mutex
);
302 wil_dbg_misc(wil
, "Checking delayed p2p listen\n");
303 if (!p2p
->discovery_started
|| !p2p
->pending_listen_wdev
)
306 mutex_lock(&wil
->vif_mutex
);
307 if (vif
->scan_request
) {
308 /* another scan started, wait again... */
309 mutex_unlock(&wil
->vif_mutex
);
312 mutex_unlock(&wil
->vif_mutex
);
314 rc
= wil_p2p_start_listen(vif
);
316 mutex_lock(&wil
->vif_mutex
);
318 cfg80211_remain_on_channel_expired(p2p
->pending_listen_wdev
,
323 wil
->radio_wdev
= wil
->main_ndev
->ieee80211_ptr
;
325 cfg80211_ready_on_channel(p2p
->pending_listen_wdev
, p2p
->cookie
,
327 p2p
->listen_duration
, GFP_KERNEL
);
329 wil
->radio_wdev
= p2p
->pending_listen_wdev
;
331 p2p
->pending_listen_wdev
= NULL
;
332 mutex_unlock(&wil
->vif_mutex
);
335 mutex_unlock(&wil
->mutex
);
338 void wil_p2p_stop_radio_operations(struct wil6210_priv
*wil
)
340 struct wil6210_vif
*vif
= ndev_to_vif(wil
->main_ndev
);
341 struct wil_p2p_info
*p2p
= &vif
->p2p
;
342 struct cfg80211_scan_info info
= {
346 lockdep_assert_held(&wil
->mutex
);
347 lockdep_assert_held(&wil
->vif_mutex
);
349 if (wil
->radio_wdev
!= wil
->p2p_wdev
)
352 if (!p2p
->discovery_started
) {
353 /* Regular scan on the p2p device */
354 if (vif
->scan_request
&&
355 vif
->scan_request
->wdev
== wil
->p2p_wdev
)
356 wil_abort_scan(vif
, true);
360 /* Search or listen on p2p device */
361 mutex_unlock(&wil
->vif_mutex
);
362 wil_p2p_stop_discovery(vif
);
363 mutex_lock(&wil
->vif_mutex
);
365 if (vif
->scan_request
) {
367 cfg80211_scan_done(vif
->scan_request
, &info
);
368 vif
->scan_request
= NULL
;
371 cfg80211_remain_on_channel_expired(wil
->radio_wdev
,
378 wil
->radio_wdev
= wil
->main_ndev
->ieee80211_ptr
;