int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie) { struct wil_p2p_info *p2p = &wil->p2p; u8 started; mutex_lock(&wil->mutex); if (cookie != p2p->cookie) { wil_info(wil, "Cookie mismatch: 0x%016llx vs. 0x%016llx\n", p2p->cookie, cookie); mutex_unlock(&wil->mutex); return -ENOENT; } started = wil_p2p_stop_discovery(wil); mutex_unlock(&wil->mutex); if (!started) { wil_err(wil, "listen not started\n"); return -ENOENT; } mutex_lock(&wil->p2p_wdev_mutex); cfg80211_remain_on_channel_expired(wil->radio_wdev, p2p->cookie, &p2p->listen_chan, GFP_KERNEL); wil->radio_wdev = wil->wdev; mutex_unlock(&wil->p2p_wdev_mutex); return 0; }
void wil_p2p_listen_expired(struct work_struct *work) { struct wil_p2p_info *p2p = container_of(work, struct wil_p2p_info, discovery_expired_work); struct wil6210_priv *wil = container_of(p2p, struct wil6210_priv, p2p); u8 started; wil_dbg_misc(wil, "p2p_listen_expired\n"); mutex_lock(&wil->mutex); started = wil_p2p_stop_discovery(wil); mutex_unlock(&wil->mutex); if (started) { mutex_lock(&wil->p2p_wdev_mutex); cfg80211_remain_on_channel_expired(wil->radio_wdev, p2p->cookie, &p2p->listen_chan, GFP_KERNEL); wil->radio_wdev = wil->wdev; mutex_unlock(&wil->p2p_wdev_mutex); } }
void wil_p2p_search_expired(struct work_struct *work) { struct wil_p2p_info *p2p = container_of(work, struct wil_p2p_info, discovery_expired_work); struct wil6210_priv *wil = container_of(p2p, struct wil6210_priv, p2p); u8 started; wil_dbg_misc(wil, "%s()\n", __func__); mutex_lock(&wil->mutex); started = wil_p2p_stop_discovery(wil); mutex_unlock(&wil->mutex); if (started) { struct cfg80211_scan_info info = { .aborted = false, }; mutex_lock(&wil->p2p_wdev_mutex); cfg80211_scan_done(wil->scan_request, &info); wil->scan_request = NULL; wil->radio_wdev = wil->wdev; mutex_unlock(&wil->p2p_wdev_mutex); } }
void wil_p2p_search_expired(struct work_struct *work) { struct wil_p2p_info *p2p = container_of(work, struct wil_p2p_info, discovery_expired_work); struct wil6210_priv *wil = container_of(p2p, struct wil6210_priv, p2p); u8 started; wil_dbg_misc(wil, "p2p_search_expired\n"); mutex_lock(&wil->mutex); started = wil_p2p_stop_discovery(wil); mutex_unlock(&wil->mutex); if (started) { struct cfg80211_scan_info info = { .aborted = false, }; mutex_lock(&wil->p2p_wdev_mutex); if (wil->scan_request) { cfg80211_scan_done(wil->scan_request, &info); wil->scan_request = NULL; wil->radio_wdev = wil->wdev; } mutex_unlock(&wil->p2p_wdev_mutex); } } void wil_p2p_delayed_listen_work(struct work_struct *work) { struct wil_p2p_info *p2p = container_of(work, struct wil_p2p_info, delayed_listen_work); struct wil6210_priv *wil = container_of(p2p, struct wil6210_priv, p2p); int rc; mutex_lock(&wil->mutex); wil_dbg_misc(wil, "Checking delayed p2p listen\n"); if (!p2p->discovery_started || !p2p->pending_listen_wdev) goto out; mutex_lock(&wil->p2p_wdev_mutex); if (wil->scan_request) { /* another scan started, wait again... */ mutex_unlock(&wil->p2p_wdev_mutex); goto out; } mutex_unlock(&wil->p2p_wdev_mutex); rc = wil_p2p_start_listen(wil); mutex_lock(&wil->p2p_wdev_mutex); if (rc) { cfg80211_remain_on_channel_expired(p2p->pending_listen_wdev, p2p->cookie, &p2p->listen_chan, GFP_KERNEL); wil->radio_wdev = wil->wdev; } else { cfg80211_ready_on_channel(p2p->pending_listen_wdev, p2p->cookie, &p2p->listen_chan, p2p->listen_duration, GFP_KERNEL); wil->radio_wdev = p2p->pending_listen_wdev; } p2p->pending_listen_wdev = NULL; mutex_unlock(&wil->p2p_wdev_mutex); out: mutex_unlock(&wil->mutex); } void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) { struct wil_p2p_info *p2p = &wil->p2p; struct cfg80211_scan_info info = { .aborted = true, }; lockdep_assert_held(&wil->mutex); lockdep_assert_held(&wil->p2p_wdev_mutex); if (wil->radio_wdev != wil->p2p_wdev) goto out; if (!p2p->discovery_started) { /* Regular scan on the p2p device */ if (wil->scan_request && wil->scan_request->wdev == wil->p2p_wdev) wil_abort_scan(wil, true); goto out; } /* Search or listen on p2p device */ mutex_unlock(&wil->p2p_wdev_mutex); wil_p2p_stop_discovery(wil); mutex_lock(&wil->p2p_wdev_mutex); if (wil->scan_request) { /* search */ cfg80211_scan_done(wil->scan_request, &info); wil->scan_request = NULL; } else { /* listen */ cfg80211_remain_on_channel_expired(wil->radio_wdev, p2p->cookie, &p2p->listen_chan, GFP_KERNEL); } out: wil->radio_wdev = wil->wdev; }