int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration, struct ieee80211_channel *chan, u64 *cookie) { struct wil_p2p_info *p2p = &wil->p2p; u8 channel = P2P_DMG_SOCIAL_CHANNEL; int rc; if (!chan) return -EINVAL; channel = chan->hw_value; wil_dbg_misc(wil, "%s: duration %d\n", __func__, duration); mutex_lock(&wil->mutex); if (p2p->discovery_started) { wil_err(wil, "%s: discovery already ongoing\n", __func__); rc = -EBUSY; goto out; } rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI); if (rc) { wil_err(wil, "%s: wmi_p2p_cfg failed\n", __func__); goto out; } rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); if (rc) { wil_err(wil, "%s: wmi_set_ssid failed\n", __func__); goto out_stop; } rc = wmi_start_listen(wil); if (rc) { wil_err(wil, "%s: wmi_start_listen failed\n", __func__); goto out_stop; } memcpy(&p2p->listen_chan, chan, sizeof(*chan)); *cookie = ++p2p->cookie; p2p->discovery_started = 1; INIT_WORK(&p2p->discovery_expired_work, wil_p2p_listen_expired); mod_timer(&p2p->discovery_timer, jiffies + msecs_to_jiffies(duration)); out_stop: if (rc) wmi_stop_discovery(wil); out: mutex_unlock(&wil->mutex); return rc; }
u8 wil_p2p_stop_discovery(struct wil6210_priv *wil) { struct wil_p2p_info *p2p = &wil->p2p; u8 started = p2p->discovery_started; if (p2p->discovery_started) { del_timer_sync(&p2p->discovery_timer); p2p->discovery_started = 0; wmi_stop_discovery(wil); } return started; }
u8 wil_p2p_stop_discovery(struct wil6210_priv *wil) { struct wil_p2p_info *p2p = &wil->p2p; u8 started = p2p->discovery_started; if (p2p->discovery_started) { if (p2p->pending_listen_wdev) { /* discovery not really started, only pending */ p2p->pending_listen_wdev = NULL; } else { del_timer_sync(&p2p->discovery_timer); wmi_stop_discovery(wil); } p2p->discovery_started = 0; } return started; }
static int wil_p2p_start_listen(struct wil6210_priv *wil) { struct wil_p2p_info *p2p = &wil->p2p; u8 channel = p2p->listen_chan.hw_value; int rc; lockdep_assert_held(&wil->mutex); rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI); if (rc) { wil_err(wil, "wmi_p2p_cfg failed\n"); goto out; } rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); if (rc) { wil_err(wil, "wmi_set_ssid failed\n"); goto out_stop; } rc = wmi_start_listen(wil); if (rc) { wil_err(wil, "wmi_start_listen failed\n"); goto out_stop; } INIT_WORK(&p2p->discovery_expired_work, wil_p2p_listen_expired); mod_timer(&p2p->discovery_timer, jiffies + msecs_to_jiffies(p2p->listen_duration)); out_stop: if (rc) wmi_stop_discovery(wil); out: return rc; }
int wil_p2p_search(struct wil6210_priv *wil, struct cfg80211_scan_request *request) { int rc; struct wil_p2p_info *p2p = &wil->p2p; wil_dbg_misc(wil, "p2p_search: channel %d\n", P2P_DMG_SOCIAL_CHANNEL); lockdep_assert_held(&wil->mutex); if (p2p->discovery_started) { wil_err(wil, "search failed. discovery already ongoing\n"); rc = -EBUSY; goto out; } rc = wmi_p2p_cfg(wil, P2P_DMG_SOCIAL_CHANNEL, P2P_DEFAULT_BI); if (rc) { wil_err(wil, "wmi_p2p_cfg failed\n"); goto out; } rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); if (rc) { wil_err(wil, "wmi_set_ssid failed\n"); goto out_stop; } /* Set application IE to probe request and probe response */ rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie); if (rc) { wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n"); goto out_stop; } /* supplicant doesn't provide Probe Response IEs. As a workaround - * re-use Probe Request IEs */ rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, request->ie_len, request->ie); if (rc) { wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n"); goto out_stop; } rc = wmi_start_search(wil); if (rc) { wil_err(wil, "wmi_start_search failed\n"); goto out_stop; } p2p->discovery_started = 1; INIT_WORK(&p2p->discovery_expired_work, wil_p2p_search_expired); mod_timer(&p2p->discovery_timer, jiffies + msecs_to_jiffies(P2P_SEARCH_DURATION_MS)); out_stop: if (rc) wmi_stop_discovery(wil); out: return rc; }