Release 4.11 drivers/net/wireless/ath/wil6210/p2p.c
/*
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "wil6210.h"
#include "wmi.h"
#define P2P_WILDCARD_SSID "DIRECT-"
#define P2P_DMG_SOCIAL_CHANNEL 2
#define P2P_SEARCH_DURATION_MS 500
#define P2P_DEFAULT_BI 100
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Lior David | 164 | 100.00% | 1 | 100.00% |
Total | 164 | 100.00% | 1 | 100.00% |
bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request)
{
return (request->n_channels == 1) &&
(request->channels[0]->hw_value == P2P_DMG_SOCIAL_CHANNEL);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Lior David | 32 | 100.00% | 1 | 100.00% |
Total | 32 | 100.00% | 1 | 100.00% |
void wil_p2p_discovery_timer_fn(ulong x)
{
struct wil6210_priv *wil = (void *)x;
wil_dbg_misc(wil, "p2p_discovery_timer_fn\n");
schedule_work(&wil->p2p.discovery_expired_work);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Dedy Lansky | 35 | 97.22% | 1 | 50.00% |
Lazar Alexei | 1 | 2.78% | 1 | 50.00% |
Total | 36 | 100.00% | 2 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Dedy Lansky | 255 | 96.96% | 1 | 33.33% |
Lazar Alexei | 7 | 2.66% | 1 | 33.33% |
Lior David | 1 | 0.38% | 1 | 33.33% |
Total | 263 | 100.00% | 3 | 100.00% |
int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
unsigned int duration, struct ieee80211_channel *chan,
u64 *cookie)
{
struct wil_p2p_info *p2p = &wil->p2p;
int rc;
if (!chan)
return -EINVAL;
wil_dbg_misc(wil, "p2p_listen: duration %d\n", duration);
mutex_lock(&wil->mutex);
if (p2p->discovery_started) {
wil_err(wil, "discovery already ongoing\n");
rc = -EBUSY;
goto out;
}
memcpy(&p2p->listen_chan, chan, sizeof(*chan));
*cookie = ++p2p->cookie;
p2p->listen_duration = duration;
mutex_lock(&wil->p2p_wdev_mutex);
if (wil->scan_request) {
wil_dbg_misc(wil, "Delaying p2p listen until scan done\n");
p2p->pending_listen_wdev = wdev;
p2p->discovery_started = 1;
rc = 0;
mutex_unlock(&wil->p2p_wdev_mutex);
goto out;
}
mutex_unlock(&wil->p2p_wdev_mutex);
rc = wil_p2p_start_listen(wil);
if (rc)
goto out;
p2p->discovery_started = 1;
wil->radio_wdev = wdev;
cfg80211_ready_on_channel(wdev, *cookie, chan, duration,
GFP_KERNEL);
out:
mutex_unlock(&wil->mutex);
return rc;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Dedy Lansky | 138 | 59.74% | 1 | 25.00% |
Lior David | 86 | 37.23% | 1 | 25.00% |
Maya Erez | 5 | 2.16% | 1 | 25.00% |
Lazar Alexei | 2 | 0.87% | 1 | 25.00% |
Total | 231 | 100.00% | 4 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Dedy Lansky | 41 | 54.67% | 1 | 33.33% |
Lior David | 34 | 45.33% | 2 | 66.67% |
Total | 75 | 100.00% | 3 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Lior David | 81 | 55.10% | 2 | 50.00% |
Dedy Lansky | 64 | 43.54% | 1 | 25.00% |
Lazar Alexei | 2 | 1.36% | 1 | 25.00% |
Total | 147 | 100.00% | 4 | 100.00% |
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);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Dedy Lansky | 68 | 56.20% | 1 | 25.00% |
Lior David | 52 | 42.98% | 2 | 50.00% |
Lazar Alexei | 1 | 0.83% | 1 | 25.00% |
Total | 121 | 100.00% | 4 | 100.00% |
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);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Dedy Lansky | 64 | 46.38% | 1 | 16.67% |
Lior David | 60 | 43.48% | 3 | 50.00% |
Avraham Stern | 13 | 9.42% | 1 | 16.67% |
Lazar Alexei | 1 | 0.72% | 1 | 16.67% |
Total | 138 | 100.00% | 6 | 100.00% |
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);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Lior David | 212 | 99.53% | 3 | 75.00% |
Dedy Lansky | 1 | 0.47% | 1 | 25.00% |
Total | 213 | 100.00% | 4 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maya Erez | 175 | 100.00% | 2 | 100.00% |
Total | 175 | 100.00% | 2 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Lior David | 722 | 44.62% | 4 | 40.00% |
Dedy Lansky | 688 | 42.52% | 1 | 10.00% |
Maya Erez | 180 | 11.12% | 3 | 30.00% |
Lazar Alexei | 15 | 0.93% | 1 | 10.00% |
Avraham Stern | 13 | 0.80% | 1 | 10.00% |
Total | 1618 | 100.00% | 10 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.