/*
 * Copyright (c) 2013 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 <linux/relay.h>
#include "core.h"
#include "debug.h"
#include "wmi-ops.h"

static void send_fft_sample(struct ath10k *ar,
			    const struct fft_sample_tlv *fft_sample_tlv)
{
	int length;

	if (!ar->spectral.rfs_chan_spec_scan)
		return;

	length = __be16_to_cpu(fft_sample_tlv->length) +
		 sizeof(*fft_sample_tlv);
	relay_write(ar->spectral.rfs_chan_spec_scan, fft_sample_tlv, length);
}

static uint8_t get_max_exp(s8 max_index, u16 max_magnitude, size_t bin_len,
			   u8 *data)
{
	int dc_pos;
	u8 max_exp;

	dc_pos = bin_len / 2;

	/* peak index outside of bins */
	if (dc_pos < max_index || -dc_pos >= max_index)
		return 0;

	for (max_exp = 0; max_exp < 8; max_exp++) {
		if (data[dc_pos + max_index] == (max_magnitude >> max_exp))
			break;
	}

	/* max_exp not found */
	if (data[dc_pos + max_index] != (max_magnitude >> max_exp))
		return 0;

	return max_exp;
}

int ath10k_spectral_process_fft(struct ath10k *ar,
				const struct wmi_phyerr *phyerr,
				const struct phyerr_fft_report *fftr,
				size_t bin_len, u64 tsf)
{
	struct fft_sample_ath10k *fft_sample;
	u8 buf[sizeof(*fft_sample) + SPECTRAL_ATH10K_MAX_NUM_BINS];
	u16 freq1, freq2, total_gain_db, base_pwr_db, length, peak_mag;
	u32 reg0, reg1;
	u8 chain_idx, *bins;
	int dc_pos;

	fft_sample = (struct fft_sample_ath10k *)&buf;

	if (bin_len < 64 || bin_len > SPECTRAL_ATH10K_MAX_NUM_BINS)
		return -EINVAL;

	reg0 = __le32_to_cpu(fftr->reg0);
	reg1 = __le32_to_cpu(fftr->reg1);

	length = sizeof(*fft_sample) - sizeof(struct fft_sample_tlv) + bin_len;
	fft_sample->tlv.type = ATH_FFT_SAMPLE_ATH10K;
	fft_sample->tlv.length = __cpu_to_be16(length);

	/* TODO: there might be a reason why the hardware reports 20/40/80 MHz,
	 * but the results/plots suggest that its actually 22/44/88 MHz.
	 */
	switch (phyerr->chan_width_mhz) {
	case 20:
		fft_sample->chan_width_mhz = 22;
		break;
	case 40:
		fft_sample->chan_width_mhz = 44;
		break;
	case 80:
		/* TODO: As experiments with an analogue sender and various
		 * configuaritions (fft-sizes of 64/128/256 and 20/40/80 Mhz)
		 * show, the particular configuration of 80 MHz/64 bins does
		 * not match with the other smaples at all. Until the reason
		 * for that is found, don't report these samples.
		 */
		if (bin_len == 64)
			return -EINVAL;
		fft_sample->chan_width_mhz = 88;
		break;
	default:
		fft_sample->chan_width_mhz = phyerr->chan_width_mhz;
	}

	fft_sample->relpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB);
	fft_sample->avgpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB);

	peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG);
	fft_sample->max_magnitude = __cpu_to_be16(peak_mag);
	fft_sample->max_index = MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX);
	fft_sample->rssi = phyerr->rssi_combined;

	total_gain_db = MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB);
	base_pwr_db = MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB);
	fft_sample->total_gain_db = __cpu_to_be16(total_gain_db);
	fft_sample->base_pwr_db = __cpu_to_be16(base_pwr_db);

	freq1 = __le16_to_cpu(phyerr->freq1);
	freq2 = __le16_to_cpu(phyerr->freq2);
	fft_sample->freq1 = __cpu_to_be16(freq1);
	fft_sample->freq2 = __cpu_to_be16(freq2);

	chain_idx = MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX);

	fft_sample->noise = __cpu_to_be16(
			__le16_to_cpu(phyerr->nf_chains[chain_idx]));

	bins = (u8 *)fftr;
	bins += sizeof(*fftr);

	fft_sample->tsf = __cpu_to_be64(tsf);

	/* max_exp has been directly reported by previous hardware (ath9k),
	 * maybe its possible to get it by other means?
	 */
	fft_sample->max_exp = get_max_exp(fft_sample->max_index, peak_mag,
					  bin_len, bins);

	memcpy(fft_sample->data, bins, bin_len);

	/* DC value (value in the middle) is the blind spot of the spectral
	 * sample and invalid, interpolate it.
	 */
	dc_pos = bin_len / 2;
	fft_sample->data[dc_pos] = (fft_sample->data[dc_pos + 1] +
				    fft_sample->data[dc_pos - 1]) / 2;

	send_fft_sample(ar, &fft_sample->tlv);

	return 0;
}

static struct ath10k_vif *ath10k_get_spectral_vdev(struct ath10k *ar)
{
	struct ath10k_vif *arvif;

	lockdep_assert_held(&ar->conf_mutex);

	if (list_empty(&ar->arvifs))
		return NULL;

	/* if there already is a vif doing spectral, return that. */
	list_for_each_entry(arvif, &ar->arvifs, list)
		if (arvif->spectral_enabled)
			return arvif;

	/* otherwise, return the first vif. */
	return list_first_entry(&ar->arvifs, typeof(*arvif), list);
}

static int ath10k_spectral_scan_trigger(struct ath10k *ar)
{
	struct ath10k_vif *arvif;
	int res;
	int vdev_id;

	lockdep_assert_held(&ar->conf_mutex);

	arvif = ath10k_get_spectral_vdev(ar);
	if (!arvif)
		return -ENODEV;
	vdev_id = arvif->vdev_id;

	if (ar->spectral.mode == SPECTRAL_DISABLED)
		return 0;

	res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id,
					      WMI_SPECTRAL_TRIGGER_CMD_CLEAR,
					      WMI_SPECTRAL_ENABLE_CMD_ENABLE);
	if (res < 0)
		return res;

	res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id,
					      WMI_SPECTRAL_TRIGGER_CMD_TRIGGER,
					      WMI_SPECTRAL_ENABLE_CMD_ENABLE);
	if (res < 0)
		return res;

	return 0;
}

static int ath10k_spectral_scan_config(struct ath10k *ar,
				       enum ath10k_spectral_mode mode)
{
	struct wmi_vdev_spectral_conf_arg arg;
	struct ath10k_vif *arvif;
	int vdev_id, count, res = 0;

	lockdep_assert_held(&ar->conf_mutex);

	arvif = ath10k_get_spectral_vdev(ar);
	if (!arvif)
		return -ENODEV;

	vdev_id = arvif->vdev_id;

	arvif->spectral_enabled = (mode != SPECTRAL_DISABLED);
	ar->spectral.mode = mode;

	res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id,
					      WMI_SPECTRAL_TRIGGER_CMD_CLEAR,
					      WMI_SPECTRAL_ENABLE_CMD_DISABLE);
	if (res < 0) {
		ath10k_warn(ar, "failed to enable spectral scan: %d\n", res);
		return res;
	}

	if (mode == SPECTRAL_DISABLED)
		return 0;

	if (mode == SPECTRAL_BACKGROUND)
		count = WMI_SPECTRAL_COUNT_DEFAULT;
	else
		count = max_t(u8, 1, ar->spectral.config.count);

	arg.vdev_id = vdev_id;
	arg.scan_count = count;
	arg.scan_period = WMI_SPECTRAL_PERIOD_DEFAULT;
	arg.scan_priority = WMI_SPECTRAL_PRIORITY_DEFAULT;
	arg.scan_fft_size = ar->spectral.config.fft_size;
	arg.scan_gc_ena = WMI_SPECTRAL_GC_ENA_DEFAULT;
	arg.scan_restart_ena = WMI_SPECTRAL_RESTART_ENA_DEFAULT;
	arg.scan_noise_floor_ref = WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT;
	arg.scan_init_delay = WMI_SPECTRAL_INIT_DELAY_DEFAULT;
	arg.scan_nb_tone_thr = WMI_SPECTRAL_NB_TONE_THR_DEFAULT;
	arg.scan_str_bin_thr = WMI_SPECTRAL_STR_BIN_THR_DEFAULT;
	arg.scan_wb_rpt_mode = WMI_SPECTRAL_WB_RPT_MODE_DEFAULT;
	arg.scan_rssi_rpt_mode = WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT;
	arg.scan_rssi_thr = WMI_SPECTRAL_RSSI_THR_DEFAULT;
	arg.scan_pwr_format = WMI_SPECTRAL_PWR_FORMAT_DEFAULT;
	arg.scan_rpt_mode = WMI_SPECTRAL_RPT_MODE_DEFAULT;
	arg.scan_bin_scale = WMI_SPECTRAL_BIN_SCALE_DEFAULT;
	arg.scan_dbm_adj = WMI_SPECTRAL_DBM_ADJ_DEFAULT;
	arg.scan_chn_mask = WMI_SPECTRAL_CHN_MASK_DEFAULT;

	res = ath10k_wmi_vdev_spectral_conf(ar, &arg);
	if (res < 0) {
		ath10k_warn(ar, "failed to configure spectral scan: %d\n", res);
		return res;
	}

	return 0;
}

static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf,
				       size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	char *mode = "";
	unsigned int len;
	enum ath10k_spectral_mode spectral_mode;

	mutex_lock(&ar->conf_mutex);
	spectral_mode = ar->spectral.mode;
	mutex_unlock(&ar->conf_mutex);

	switch (spectral_mode) {
	case SPECTRAL_DISABLED:
		mode = "disable";
		break;
	case SPECTRAL_BACKGROUND:
		mode = "background";
		break;
	case SPECTRAL_MANUAL:
		mode = "manual";
		break;
	}

	len = strlen(mode);
	return simple_read_from_buffer(user_buf, count, ppos, mode, len);
}

static ssize_t write_file_spec_scan_ctl(struct file *file,
					const char __user *user_buf,
					size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	char buf[32];
	ssize_t len;
	int res;

	len = min(count, sizeof(buf) - 1);
	if (copy_from_user(buf, user_buf, len))
		return -EFAULT;

	buf[len] = '\0';

	mutex_lock(&ar->conf_mutex);

	if (strncmp("trigger", buf, 7) == 0) {
		if (ar->spectral.mode == SPECTRAL_MANUAL ||
		    ar->spectral.mode == SPECTRAL_BACKGROUND) {
			/* reset the configuration to adopt possibly changed
			 * debugfs parameters
			 */
			res = ath10k_spectral_scan_config(ar,
							  ar->spectral.mode);
			if (res < 0) {
				ath10k_warn(ar, "failed to reconfigure spectral scan: %d\n",
					    res);
			}
			res = ath10k_spectral_scan_trigger(ar);
			if (res < 0) {
				ath10k_warn(ar, "failed to trigger spectral scan: %d\n",
					    res);
			}
		} else {
			res = -EINVAL;
		}
	} else if (strncmp("background", buf, 9) == 0) {
		res = ath10k_spectral_scan_config(ar, SPECTRAL_BACKGROUND);
	} else if (strncmp("manual", buf, 6) == 0) {
		res = ath10k_spectral_scan_config(ar, SPECTRAL_MANUAL);
	} else if (strncmp("disable", buf, 7) == 0) {
		res = ath10k_spectral_scan_config(ar, SPECTRAL_DISABLED);
	} else {
		res = -EINVAL;
	}

	mutex_unlock(&ar->conf_mutex);

	if (res < 0)
		return res;

	return count;
}

static const struct file_operations fops_spec_scan_ctl = {
	.read = read_file_spec_scan_ctl,
	.write = write_file_spec_scan_ctl,
	.open = simple_open,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
};

static ssize_t read_file_spectral_count(struct file *file,
					char __user *user_buf,
					size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	char buf[32];
	unsigned int len;
	u8 spectral_count;

	mutex_lock(&ar->conf_mutex);
	spectral_count = ar->spectral.config.count;
	mutex_unlock(&ar->conf_mutex);

	len = sprintf(buf, "%d\n", spectral_count);
	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}

static ssize_t write_file_spectral_count(struct file *file,
					 const char __user *user_buf,
					 size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	unsigned long val;
	char buf[32];
	ssize_t len;

	len = min(count, sizeof(buf) - 1);
	if (copy_from_user(buf, user_buf, len))
		return -EFAULT;

	buf[len] = '\0';
	if (kstrtoul(buf, 0, &val))
		return -EINVAL;

	if (val < 0 || val > 255)
		return -EINVAL;

	mutex_lock(&ar->conf_mutex);
	ar->spectral.config.count = val;
	mutex_unlock(&ar->conf_mutex);

	return count;
}

static const struct file_operations fops_spectral_count = {
	.read = read_file_spectral_count,
	.write = write_file_spectral_count,
	.open = simple_open,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
};

static ssize_t read_file_spectral_bins(struct file *file,
				       char __user *user_buf,
				       size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	char buf[32];
	unsigned int len, bins, fft_size, bin_scale;

	mutex_lock(&ar->conf_mutex);

	fft_size = ar->spectral.config.fft_size;
	bin_scale = WMI_SPECTRAL_BIN_SCALE_DEFAULT;
	bins = 1 << (fft_size - bin_scale);

	mutex_unlock(&ar->conf_mutex);

	len = sprintf(buf, "%d\n", bins);
	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}

static ssize_t write_file_spectral_bins(struct file *file,
					const char __user *user_buf,
					size_t count, loff_t *ppos)
{
	struct ath10k *ar = file->private_data;
	unsigned long val;
	char buf[32];
	ssize_t len;

	len = min(count, sizeof(buf) - 1);
	if (copy_from_user(buf, user_buf, len))
		return -EFAULT;

	buf[len] = '\0';
	if (kstrtoul(buf, 0, &val))
		return -EINVAL;

	if (val < 64 || val > SPECTRAL_ATH10K_MAX_NUM_BINS)
		return -EINVAL;

	if (!is_power_of_2(val))
		return -EINVAL;

	mutex_lock(&ar->conf_mutex);
	ar->spectral.config.fft_size = ilog2(val);
	ar->spectral.config.fft_size += WMI_SPECTRAL_BIN_SCALE_DEFAULT;
	mutex_unlock(&ar->conf_mutex);

	return count;
}

static const struct file_operations fops_spectral_bins = {
	.read = read_file_spectral_bins,
	.write = write_file_spectral_bins,
	.open = simple_open,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
};

static struct dentry *create_buf_file_handler(const char *filename,
					      struct dentry *parent,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
					      umode_t mode,
#else
					      int mode,
#endif
					      struct rchan_buf *buf,
					      int *is_global)
{
	struct dentry *buf_file;

	buf_file = debugfs_create_file(filename, mode, parent, buf,
				       &relay_file_operations);
	*is_global = 1;
	return buf_file;
}

static int remove_buf_file_handler(struct dentry *dentry)
{
	debugfs_remove(dentry);

	return 0;
}

static struct rchan_callbacks rfs_spec_scan_cb = {
	.create_buf_file = create_buf_file_handler,
	.remove_buf_file = remove_buf_file_handler,
};

int ath10k_spectral_start(struct ath10k *ar)
{
	struct ath10k_vif *arvif;

	lockdep_assert_held(&ar->conf_mutex);

	list_for_each_entry(arvif, &ar->arvifs, list)
		arvif->spectral_enabled = 0;

	ar->spectral.mode = SPECTRAL_DISABLED;
	ar->spectral.config.count = WMI_SPECTRAL_COUNT_DEFAULT;
	ar->spectral.config.fft_size = WMI_SPECTRAL_FFT_SIZE_DEFAULT;

	return 0;
}

int ath10k_spectral_vif_stop(struct ath10k_vif *arvif)
{
	if (!arvif->spectral_enabled)
		return 0;

	return ath10k_spectral_scan_config(arvif->ar, SPECTRAL_DISABLED);
}

int ath10k_spectral_create(struct ath10k *ar)
{
	ar->spectral.rfs_chan_spec_scan = relay_open("spectral_scan",
						     ar->debug.debugfs_phy,
						     1024, 256,
						     &rfs_spec_scan_cb, NULL);
	debugfs_create_file("spectral_scan_ctl",
			    S_IRUSR | S_IWUSR,
			    ar->debug.debugfs_phy, ar,
			    &fops_spec_scan_ctl);
	debugfs_create_file("spectral_count",
			    S_IRUSR | S_IWUSR,
			    ar->debug.debugfs_phy, ar,
			    &fops_spectral_count);
	debugfs_create_file("spectral_bins",
			    S_IRUSR | S_IWUSR,
			    ar->debug.debugfs_phy, ar,
			    &fops_spectral_bins);

	return 0;
}

void ath10k_spectral_destroy(struct ath10k *ar)
{
	if (ar->spectral.rfs_chan_spec_scan) {
		relay_close(ar->spectral.rfs_chan_spec_scan);
		ar->spectral.rfs_chan_spec_scan = NULL;
	}
}
