/*
 * Copyright (c) 2016 Broadcom
 *
 * 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 <linux/netdevice.h>
#include <linux/gcd.h>
#include <net/cfg80211.h>

#include "core.h"
#include "debug.h"
#include "fwil.h"
#include "fwil_types.h"
#include "cfg80211.h"
#include "pno.h"

#define BRCMF_PNO_VERSION		2
#define BRCMF_PNO_REPEAT		4
#define BRCMF_PNO_FREQ_EXPO_MAX		3
#define BRCMF_PNO_IMMEDIATE_SCAN_BIT	3
#define BRCMF_PNO_ENABLE_BD_SCAN_BIT	5
#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT	6
#define BRCMF_PNO_REPORT_SEPARATELY_BIT	11
#define BRCMF_PNO_SCAN_INCOMPLETE	0
#define BRCMF_PNO_WPA_AUTH_ANY		0xFFFFFFFF
#define BRCMF_PNO_HIDDEN_BIT		2
#define BRCMF_PNO_SCHED_SCAN_PERIOD	30

#define BRCMF_PNO_MAX_BUCKETS		16
#define GSCAN_BATCH_NO_THR_SET			101
#define GSCAN_RETRY_THRESHOLD			3

struct brcmf_pno_info {
	int n_reqs;
	struct cfg80211_sched_scan_request *reqs[BRCMF_PNO_MAX_BUCKETS];
	struct mutex req_lock;
};

#define ifp_to_pno(_ifp)	((_ifp)->drvr->config->pno)

static int brcmf_pno_store_request(struct brcmf_pno_info *pi,
				   struct cfg80211_sched_scan_request *req)
{
	if (WARN(pi->n_reqs == BRCMF_PNO_MAX_BUCKETS,
		 "pno request storage full\n"))
		return -ENOSPC;

	brcmf_dbg(SCAN, "reqid=%llu\n", req->reqid);
	mutex_lock(&pi->req_lock);
	pi->reqs[pi->n_reqs++] = req;
	mutex_unlock(&pi->req_lock);
	return 0;
}

static int brcmf_pno_remove_request(struct brcmf_pno_info *pi, u64 reqid)
{
	int i, err = 0;

	mutex_lock(&pi->req_lock);

	/* find request */
	for (i = 0; i < pi->n_reqs; i++) {
		if (pi->reqs[i]->reqid == reqid)
			break;
	}
	/* request not found */
	if (WARN(i == pi->n_reqs, "reqid not found\n")) {
		err = -ENOENT;
		goto done;
	}

	brcmf_dbg(SCAN, "reqid=%llu\n", reqid);
	pi->n_reqs--;

	/* if last we are done */
	if (!pi->n_reqs || i == pi->n_reqs)
		goto done;

	/* fill the gap with remaining requests */
	while (i <= pi->n_reqs - 1) {
		pi->reqs[i] = pi->reqs[i + 1];
		i++;
	}

done:
	mutex_unlock(&pi->req_lock);
	return err;
}

static int brcmf_pno_channel_config(struct brcmf_if *ifp,
				    struct brcmf_pno_config_le *cfg)
{
	cfg->reporttype = 0;
	cfg->flags = 0;

	return brcmf_fil_iovar_data_set(ifp, "pfn_cfg", cfg, sizeof(*cfg));
}

static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
			    u32 mscan, u32 bestn)
{
	struct brcmf_pub *drvr = ifp->drvr;
	struct brcmf_pno_param_le pfn_param;
	u16 flags;
	u32 pfnmem;
	s32 err;

	memset(&pfn_param, 0, sizeof(pfn_param));
	pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);

	/* set extra pno params */
	flags = BIT(BRCMF_PNO_IMMEDIATE_SCAN_BIT) |
		BIT(BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
	pfn_param.repeat = BRCMF_PNO_REPEAT;
	pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;

	/* set up pno scan fr */
	pfn_param.scan_freq = cpu_to_le32(scan_freq);

	if (mscan) {
		pfnmem = bestn;

		/* set bestn in firmware */
		err = brcmf_fil_iovar_int_set(ifp, "pfnmem", pfnmem);
		if (err < 0) {
			bphy_err(drvr, "failed to set pfnmem\n");
			goto exit;
		}
		/* get max mscan which the firmware supports */
		err = brcmf_fil_iovar_int_get(ifp, "pfnmem", &pfnmem);
		if (err < 0) {
			bphy_err(drvr, "failed to get pfnmem\n");
			goto exit;
		}
		mscan = min_t(u32, mscan, pfnmem);
		pfn_param.mscan = mscan;
		pfn_param.bestn = bestn;
		flags |= BIT(BRCMF_PNO_ENABLE_BD_SCAN_BIT);
		brcmf_dbg(INFO, "mscan=%d, bestn=%d\n", mscan, bestn);
	}

	pfn_param.flags = cpu_to_le16(flags);
	err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
				       sizeof(pfn_param));
	if (err)
		bphy_err(drvr, "pfn_set failed, err=%d\n", err);

exit:
	return err;
}

static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
{
	struct brcmf_pub *drvr = ifp->drvr;
	struct brcmf_pno_macaddr_le pfn_mac;
	u8 *mac_addr = NULL;
	u8 *mac_mask = NULL;
	int err, i;

	for (i = 0; i < pi->n_reqs; i++)
		if (pi->reqs[i]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
			mac_addr = pi->reqs[i]->mac_addr;
			mac_mask = pi->reqs[i]->mac_addr_mask;
			break;
		}

	/* no random mac requested */
	if (!mac_addr)
		return 0;

	pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
	pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;

	memcpy(pfn_mac.mac, mac_addr, ETH_ALEN);
	for (i = 0; i < ETH_ALEN; i++) {
		pfn_mac.mac[i] &= mac_mask[i];
		pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
	}
	/* Clear multi bit */
	pfn_mac.mac[0] &= 0xFE;
	/* Set locally administered */
	pfn_mac.mac[0] |= 0x02;

	brcmf_dbg(SCAN, "enabling random mac: reqid=%llu mac=%pM\n",
		  pi->reqs[i]->reqid, pfn_mac.mac);
	err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
				       sizeof(pfn_mac));
	if (err)
		bphy_err(drvr, "pfn_macaddr failed, err=%d\n", err);

	return err;
}

static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
			      bool active)
{
	struct brcmf_pub *drvr = ifp->drvr;
	struct brcmf_pno_net_param_le pfn;
	int err;

	pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
	pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
	pfn.wsec = cpu_to_le32(0);
	pfn.infra = cpu_to_le32(1);
	pfn.flags = 0;
	if (active)
		pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
	pfn.ssid.SSID_len = cpu_to_le32(ssid->ssid_len);
	memcpy(pfn.ssid.SSID, ssid->ssid, ssid->ssid_len);

	brcmf_dbg(SCAN, "adding ssid=%.32s (active=%d)\n", ssid->ssid, active);
	err = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn));
	if (err < 0)
		bphy_err(drvr, "adding failed: err=%d\n", err);
	return err;
}

static int brcmf_pno_add_bssid(struct brcmf_if *ifp, const u8 *bssid)
{
	struct brcmf_pub *drvr = ifp->drvr;
	struct brcmf_pno_bssid_le bssid_cfg;
	int err;

	memcpy(bssid_cfg.bssid, bssid, ETH_ALEN);
	bssid_cfg.flags = 0;

	brcmf_dbg(SCAN, "adding bssid=%pM\n", bssid);
	err = brcmf_fil_iovar_data_set(ifp, "pfn_add_bssid", &bssid_cfg,
				       sizeof(bssid_cfg));
	if (err < 0)
		bphy_err(drvr, "adding failed: err=%d\n", err);
	return err;
}

static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid,
				 struct cfg80211_sched_scan_request *req)
{
	int i;

	if (!ssid || !req->ssids || !req->n_ssids)
		return false;

	for (i = 0; i < req->n_ssids; i++) {
		if (ssid->ssid_len == req->ssids[i].ssid_len) {
			if (!strncmp(ssid->ssid, req->ssids[i].ssid,
				     ssid->ssid_len))
				return true;
		}
	}
	return false;
}

static int brcmf_pno_clean(struct brcmf_if *ifp)
{
	struct brcmf_pub *drvr = ifp->drvr;
	int ret;

	/* Disable pfn */
	ret = brcmf_fil_iovar_int_set(ifp, "pfn", 0);
	if (ret == 0) {
		/* clear pfn */
		ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0);
	}
	if (ret < 0)
		bphy_err(drvr, "failed code %d\n", ret);

	return ret;
}

static int brcmf_pno_get_bucket_channels(struct cfg80211_sched_scan_request *r,
					 struct brcmf_pno_config_le *pno_cfg)
{
	u32 n_chan = le32_to_cpu(pno_cfg->channel_num);
	u16 chan;
	int i, err = 0;

	for (i = 0; i < r->n_channels; i++) {
		if (n_chan >= BRCMF_NUMCHANNELS) {
			err = -ENOSPC;
			goto done;
		}
		chan = r->channels[i]->hw_value;
		brcmf_dbg(SCAN, "[%d] Chan : %u\n", n_chan, chan);
		pno_cfg->channel_list[n_chan++] = cpu_to_le16(chan);
	}
	/* return number of channels */
	err = n_chan;
done:
	pno_cfg->channel_num = cpu_to_le32(n_chan);
	return err;
}

static int brcmf_pno_prep_fwconfig(struct brcmf_pno_info *pi,
				   struct brcmf_pno_config_le *pno_cfg,
				   struct brcmf_gscan_bucket_config **buckets,
				   u32 *scan_freq)
{
	struct cfg80211_sched_scan_request *sr;
	struct brcmf_gscan_bucket_config *fw_buckets;
	int i, err, chidx;

	brcmf_dbg(SCAN, "n_reqs=%d\n", pi->n_reqs);
	if (WARN_ON(!pi->n_reqs))
		return -ENODATA;

	/*
	 * actual scan period is determined using gcd() for each
	 * scheduled scan period.
	 */
	*scan_freq = pi->reqs[0]->scan_plans[0].interval;
	for (i = 1; i < pi->n_reqs; i++) {
		sr = pi->reqs[i];
		*scan_freq = gcd(sr->scan_plans[0].interval, *scan_freq);
	}
	if (*scan_freq < BRCMF_PNO_SCHED_SCAN_MIN_PERIOD) {
		brcmf_dbg(SCAN, "scan period too small, using minimum\n");
		*scan_freq = BRCMF_PNO_SCHED_SCAN_MIN_PERIOD;
	}

	*buckets = NULL;
	fw_buckets = kcalloc(pi->n_reqs, sizeof(*fw_buckets), GFP_KERNEL);
	if (!fw_buckets)
		return -ENOMEM;

	memset(pno_cfg, 0, sizeof(*pno_cfg));
	for (i = 0; i < pi->n_reqs; i++) {
		sr = pi->reqs[i];
		chidx = brcmf_pno_get_bucket_channels(sr, pno_cfg);
		if (chidx < 0) {
			err = chidx;
			goto fail;
		}
		fw_buckets[i].bucket_end_index = chidx - 1;
		fw_buckets[i].bucket_freq_multiple =
			sr->scan_plans[0].interval / *scan_freq;
		/* assure period is non-zero */
		if (!fw_buckets[i].bucket_freq_multiple)
			fw_buckets[i].bucket_freq_multiple = 1;
		fw_buckets[i].flag = BRCMF_PNO_REPORT_NO_BATCH;
	}

	if (BRCMF_SCAN_ON()) {
		brcmf_err("base period=%u\n", *scan_freq);
		for (i = 0; i < pi->n_reqs; i++) {
			brcmf_err("[%d] period %u max %u repeat %u flag %x idx %u\n",
				  i, fw_buckets[i].bucket_freq_multiple,
				  le16_to_cpu(fw_buckets[i].max_freq_multiple),
				  fw_buckets[i].repeat, fw_buckets[i].flag,
				  fw_buckets[i].bucket_end_index);
		}
	}
	*buckets = fw_buckets;
	return pi->n_reqs;

fail:
	kfree(fw_buckets);
	return err;
}

static int brcmf_pno_config_networks(struct brcmf_if *ifp,
				     struct brcmf_pno_info *pi)
{
	struct cfg80211_sched_scan_request *r;
	struct cfg80211_match_set *ms;
	bool active;
	int i, j, err = 0;

	for (i = 0; i < pi->n_reqs; i++) {
		r = pi->reqs[i];

		for (j = 0; j < r->n_match_sets; j++) {
			ms = &r->match_sets[j];
			if (ms->ssid.ssid_len) {
				active = brcmf_is_ssid_active(&ms->ssid, r);
				err = brcmf_pno_add_ssid(ifp, &ms->ssid,
							 active);
			}
			if (!err && is_valid_ether_addr(ms->bssid))
				err = brcmf_pno_add_bssid(ifp, ms->bssid);

			if (err < 0)
				return err;
		}
	}
	return 0;
}

static int brcmf_pno_config_sched_scans(struct brcmf_if *ifp)
{
	struct brcmf_pub *drvr = ifp->drvr;
	struct brcmf_pno_info *pi;
	struct brcmf_gscan_config *gscan_cfg;
	struct brcmf_gscan_bucket_config *buckets;
	struct brcmf_pno_config_le pno_cfg;
	size_t gsz;
	u32 scan_freq;
	int err, n_buckets;

	pi = ifp_to_pno(ifp);
	n_buckets = brcmf_pno_prep_fwconfig(pi, &pno_cfg, &buckets,
					    &scan_freq);
	if (n_buckets < 0)
		return n_buckets;

	gsz = sizeof(*gscan_cfg) + (n_buckets - 1) * sizeof(*buckets);
	gscan_cfg = kzalloc(gsz, GFP_KERNEL);
	if (!gscan_cfg) {
		err = -ENOMEM;
		goto free_buckets;
	}

	/* clean up everything */
	err = brcmf_pno_clean(ifp);
	if  (err < 0) {
		bphy_err(drvr, "failed error=%d\n", err);
		goto free_gscan;
	}

	/* configure pno */
	err = brcmf_pno_config(ifp, scan_freq, 0, 0);
	if (err < 0)
		goto free_gscan;

	err = brcmf_pno_channel_config(ifp, &pno_cfg);
	if (err < 0)
		goto clean;

	gscan_cfg->version = cpu_to_le16(BRCMF_GSCAN_CFG_VERSION);
	gscan_cfg->retry_threshold = GSCAN_RETRY_THRESHOLD;
	gscan_cfg->buffer_threshold = GSCAN_BATCH_NO_THR_SET;
	gscan_cfg->flags = BRCMF_GSCAN_CFG_ALL_BUCKETS_IN_1ST_SCAN;

	gscan_cfg->count_of_channel_buckets = n_buckets;
	memcpy(&gscan_cfg->bucket[0], buckets,
	       n_buckets * sizeof(*buckets));

	err = brcmf_fil_iovar_data_set(ifp, "pfn_gscan_cfg", gscan_cfg, gsz);

	if (err < 0)
		goto clean;

	/* configure random mac */
	err = brcmf_pno_set_random(ifp, pi);
	if (err < 0)
		goto clean;

	err = brcmf_pno_config_networks(ifp, pi);
	if (err < 0)
		goto clean;

	/* Enable the PNO */
	err = brcmf_fil_iovar_int_set(ifp, "pfn", 1);

clean:
	if (err < 0)
		brcmf_pno_clean(ifp);
free_gscan:
	kfree(gscan_cfg);
free_buckets:
	kfree(buckets);
	return err;
}

int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
			       struct cfg80211_sched_scan_request *req)
{
	struct brcmf_pno_info *pi;
	int ret;

	brcmf_dbg(TRACE, "reqid=%llu\n", req->reqid);

	pi = ifp_to_pno(ifp);
	ret = brcmf_pno_store_request(pi, req);
	if (ret < 0)
		return ret;

	ret = brcmf_pno_config_sched_scans(ifp);
	if (ret < 0) {
		brcmf_pno_remove_request(pi, req->reqid);
		if (pi->n_reqs)
			(void)brcmf_pno_config_sched_scans(ifp);
		return ret;
	}
	return 0;
}

int brcmf_pno_stop_sched_scan(struct brcmf_if *ifp, u64 reqid)
{
	struct brcmf_pno_info *pi;
	int err;

	brcmf_dbg(TRACE, "reqid=%llu\n", reqid);

	pi = ifp_to_pno(ifp);

	/* No PNO request */
	if (!pi->n_reqs)
		return 0;

	err = brcmf_pno_remove_request(pi, reqid);
	if (err)
		return err;

	brcmf_pno_clean(ifp);

	if (pi->n_reqs)
		(void)brcmf_pno_config_sched_scans(ifp);

	return 0;
}

int brcmf_pno_attach(struct brcmf_cfg80211_info *cfg)
{
	struct brcmf_pno_info *pi;

	brcmf_dbg(TRACE, "enter\n");
	pi = kzalloc(sizeof(*pi), GFP_KERNEL);
	if (!pi)
		return -ENOMEM;

	cfg->pno = pi;
	mutex_init(&pi->req_lock);
	return 0;
}

void brcmf_pno_detach(struct brcmf_cfg80211_info *cfg)
{
	struct brcmf_pno_info *pi;

	brcmf_dbg(TRACE, "enter\n");
	pi = cfg->pno;
	cfg->pno = NULL;

	WARN_ON(pi->n_reqs);
	mutex_destroy(&pi->req_lock);
	kfree(pi);
}

void brcmf_pno_wiphy_params(struct wiphy *wiphy, bool gscan)
{
	/* scheduled scan settings */
	wiphy->max_sched_scan_reqs = gscan ? BRCMF_PNO_MAX_BUCKETS : 1;
	wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
	wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
	wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
	wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD;
}

u64 brcmf_pno_find_reqid_by_bucket(struct brcmf_pno_info *pi, u32 bucket)
{
	u64 reqid = 0;

	mutex_lock(&pi->req_lock);

	if (bucket < pi->n_reqs)
		reqid = pi->reqs[bucket]->reqid;

	mutex_unlock(&pi->req_lock);
	return reqid;
}

u32 brcmf_pno_get_bucket_map(struct brcmf_pno_info *pi,
			     struct brcmf_pno_net_info_le *ni)
{
	struct cfg80211_sched_scan_request *req;
	struct cfg80211_match_set *ms;
	u32 bucket_map = 0;
	int i, j;

	mutex_lock(&pi->req_lock);
	for (i = 0; i < pi->n_reqs; i++) {
		req = pi->reqs[i];

		if (!req->n_match_sets)
			continue;
		for (j = 0; j < req->n_match_sets; j++) {
			ms = &req->match_sets[j];
			if (ms->ssid.ssid_len == ni->SSID_len &&
			    !memcmp(ms->ssid.ssid, ni->SSID, ni->SSID_len)) {
				bucket_map |= BIT(i);
				break;
			}
			if (is_valid_ether_addr(ms->bssid) &&
			    !memcmp(ms->bssid, ni->bssid, ETH_ALEN)) {
				bucket_map |= BIT(i);
				break;
			}
		}
	}
	mutex_unlock(&pi->req_lock);
	return bucket_map;
}
