cregit-Linux how code gets into the kernel

Release 4.18 drivers/net/wireless/ath/wil6210/p2p.c

/*
 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 * 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_vif *vif) { struct wil6210_priv *wil = vif_to_wil(vif); struct wil_p2p_info *p2p = &vif->p2p; u8 channel = p2p->listen_chan.hw_value; int rc; lockdep_assert_held(&wil->mutex); rc = wmi_p2p_cfg(vif, channel, P2P_DEFAULT_BI); if (rc) { wil_err(wil, "wmi_p2p_cfg failed\n"); goto out; } rc = wmi_set_ssid(vif, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); if (rc) { wil_err(wil, "wmi_set_ssid failed\n"); goto out_stop; } rc = wmi_start_listen(vif); 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(vif); out: return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Lior David174100.00%2100.00%
Total174100.00%2100.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

PersonTokensPropCommitsCommitProp
Lior David32100.00%1100.00%
Total32100.00%1100.00%


int wil_p2p_search(struct wil6210_vif *vif, struct cfg80211_scan_request *request) { struct wil6210_priv *wil = vif_to_wil(vif); int rc; struct wil_p2p_info *p2p = &vif->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(vif, P2P_DMG_SOCIAL_CHANNEL, P2P_DEFAULT_BI); if (rc) { wil_err(wil, "wmi_p2p_cfg failed\n"); goto out; } rc = wmi_set_ssid(vif, 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(vif, 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(vif, 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(vif); 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(vif); out: return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Dedy Lansky24389.01%120.00%
Lior David196.96%240.00%
Lazar Alexei72.56%120.00%
Kees Cook41.47%120.00%
Total273100.00%5100.00%


int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev, unsigned int duration, struct ieee80211_channel *chan, u64 *cookie) { struct wil6210_vif *vif = wdev_to_vif(wil, wdev); struct wil_p2p_info *p2p = &vif->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->vif_mutex); if (vif->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->vif_mutex); goto out; } mutex_unlock(&wil->vif_mutex); rc = wil_p2p_start_listen(vif); if (rc) goto out; p2p->discovery_started = 1; if (vif->mid == 0) wil->radio_wdev = wdev; cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL); out: mutex_unlock(&wil->mutex); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Dedy Lansky13754.58%116.67%
Lior David10742.63%350.00%
Maya Erez51.99%116.67%
Lazar Alexei20.80%116.67%
Total251100.00%6100.00%


u8 wil_p2p_stop_discovery(struct wil6210_vif *vif) { struct wil_p2p_info *p2p = &vif->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(vif); } p2p->discovery_started = 0; } return started; }

Contributors

PersonTokensPropCommitsCommitProp
Dedy Lansky3850.67%125.00%
Lior David3749.33%375.00%
Total75100.00%4100.00%


int wil_p2p_cancel_listen(struct wil6210_vif *vif, u64 cookie) { struct wil6210_priv *wil = vif_to_wil(vif); struct wil_p2p_info *p2p = &vif->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(vif); mutex_unlock(&wil->mutex); if (!started) { wil_err(wil, "listen not started\n"); return -ENOENT; } mutex_lock(&wil->vif_mutex); cfg80211_remain_on_channel_expired(vif_to_radio_wdev(wil, vif), p2p->cookie, &p2p->listen_chan, GFP_KERNEL); if (vif->mid == 0) wil->radio_wdev = wil->main_ndev->ieee80211_ptr; mutex_unlock(&wil->vif_mutex); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Lior David10964.12%466.67%
Dedy Lansky5934.71%116.67%
Lazar Alexei21.18%116.67%
Total170100.00%6100.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_vif *vif = container_of(p2p, struct wil6210_vif, p2p); struct wil6210_priv *wil = vif_to_wil(vif); u8 started; wil_dbg_misc(wil, "p2p_listen_expired\n"); mutex_lock(&wil->mutex); started = wil_p2p_stop_discovery(vif); mutex_unlock(&wil->mutex); if (!started) return; mutex_lock(&wil->vif_mutex); cfg80211_remain_on_channel_expired(vif_to_radio_wdev(wil, vif), p2p->cookie, &p2p->listen_chan, GFP_KERNEL); if (vif->mid == 0) wil->radio_wdev = wil->main_ndev->ieee80211_ptr; mutex_unlock(&wil->vif_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Lior David8055.56%466.67%
Dedy Lansky6343.75%116.67%
Lazar Alexei10.69%116.67%
Total144100.00%6100.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_vif *vif = container_of(p2p, struct wil6210_vif, p2p); struct wil6210_priv *wil = vif_to_wil(vif); u8 started; wil_dbg_misc(wil, "p2p_search_expired\n"); mutex_lock(&wil->mutex); started = wil_p2p_stop_discovery(vif); mutex_unlock(&wil->mutex); if (started) { struct cfg80211_scan_info info = { .aborted = false, }; mutex_lock(&wil->vif_mutex); if (vif->scan_request) { cfg80211_scan_done(vif->scan_request, &info); vif->scan_request = NULL; if (vif->mid == 0) wil->radio_wdev = wil->main_ndev->ieee80211_ptr; } mutex_unlock(&wil->vif_mutex); } }

Contributors

PersonTokensPropCommitsCommitProp
Lior David8654.43%562.50%
Dedy Lansky5836.71%112.50%
Avraham Stern138.23%112.50%
Lazar Alexei10.63%112.50%
Total158100.00%8100.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_vif *vif = container_of(p2p, struct wil6210_vif, p2p); struct wil6210_priv *wil = vif_to_wil(vif); 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->vif_mutex); if (vif->scan_request) { /* another scan started, wait again... */ mutex_unlock(&wil->vif_mutex); goto out; } mutex_unlock(&wil->vif_mutex); rc = wil_p2p_start_listen(vif); mutex_lock(&wil->vif_mutex); if (rc) { cfg80211_remain_on_channel_expired(p2p->pending_listen_wdev, p2p->cookie, &p2p->listen_chan, GFP_KERNEL); if (vif->mid == 0) wil->radio_wdev = wil->main_ndev->ieee80211_ptr; } else { cfg80211_ready_on_channel(p2p->pending_listen_wdev, p2p->cookie, &p2p->listen_chan, p2p->listen_duration, GFP_KERNEL); if (vif->mid == 0) wil->radio_wdev = p2p->pending_listen_wdev; } p2p->pending_listen_wdev = NULL; mutex_unlock(&wil->vif_mutex); out: mutex_unlock(&wil->mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Lior David24099.59%583.33%
Dedy Lansky10.41%116.67%
Total241100.00%6100.00%


void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) { struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev); struct wil_p2p_info *p2p = &vif->p2p; struct cfg80211_scan_info info = { .aborted = true, }; lockdep_assert_held(&wil->mutex); lockdep_assert_held(&wil->vif_mutex); if (wil->radio_wdev != wil->p2p_wdev) goto out; if (!p2p->discovery_started) { /* Regular scan on the p2p device */ if (vif->scan_request && vif->scan_request->wdev == wil->p2p_wdev) wil_abort_scan(vif, true); goto out; } /* Search or listen on p2p device */ mutex_unlock(&wil->vif_mutex); wil_p2p_stop_discovery(vif); mutex_lock(&wil->vif_mutex); if (vif->scan_request) { /* search */ cfg80211_scan_done(vif->scan_request, &info); vif->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->main_ndev->ieee80211_ptr; }

Contributors

PersonTokensPropCommitsCommitProp
Maya Erez16386.24%250.00%
Lior David2613.76%250.00%
Total189100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Lior David91152.66%646.15%
Dedy Lansky62135.90%17.69%
Maya Erez1689.71%323.08%
Avraham Stern130.75%17.69%
Lazar Alexei130.75%17.69%
Kees Cook40.23%17.69%
Total1730100.00%13100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.