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;