/*
 * Copyright (c) 2014-2016 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

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);
}

void wil_p2p_discovery_timer_fn(ulong x)
{
	struct wil6210_priv *wil = (void *)x;

	wil_dbg_misc(wil, "%s\n", __func__);

	schedule_work(&wil->p2p.discovery_expired_work);
}

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, "%s: channel %d\n",
		     __func__, P2P_DMG_SOCIAL_CHANNEL);

	mutex_lock(&wil->mutex);

	if (p2p->discovery_started) {
		wil_err(wil, "%s: search failed. discovery already ongoing\n",
			__func__);
		rc = -EBUSY;
		goto out;
	}

	rc = wmi_p2p_cfg(wil, P2P_DMG_SOCIAL_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;
	}

	/* 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, "%s: wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n",
			__func__);
		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, "%s: wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n",
			__func__);
		goto out_stop;
	}

	rc = wmi_start_search(wil);
	if (rc) {
		wil_err(wil, "%s: wmi_start_search failed\n", __func__);
		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:
	mutex_unlock(&wil->mutex);
	return rc;
}

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;
}

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, "%s: Cookie mismatch: 0x%016llx vs. 0x%016llx\n",
			 __func__, p2p->cookie, cookie);
		mutex_unlock(&wil->mutex);
		return -ENOENT;
	}

	started = wil_p2p_stop_discovery(wil);

	mutex_unlock(&wil->mutex);

	if (!started) {
		wil_err(wil, "%s: listen not started\n", __func__);
		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, "%s()\n", __func__);

	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_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);

	mutex_lock(&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) {
			cfg80211_scan_done(wil->scan_request, &info);
			wil->scan_request = NULL;
		}
		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;
	mutex_unlock(&wil->p2p_wdev_mutex);
}
