/*
 * Copyright (c) 2008-2011 Atheros Communications Inc.
 * Copyright (c) 2011 Neratec Solutions AG
 *
 * 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 "hw.h"
#include "hw-ops.h"
#include "ath9k.h"
#include "dfs.h"
#include "dfs_debug.h"

/* internal struct to pass radar data */
struct ath_radar_data {
	u8 pulse_bw_info;
	u8 rssi;
	u8 ext_rssi;
	u8 pulse_length_ext;
	u8 pulse_length_pri;
};

/**** begin: CHIRP ************************************************************/

/* min and max gradients for defined FCC chirping pulses, given by
 * - 20MHz chirp width over a pulse width of  50us
 * -  5MHz chirp width over a pulse width of 100us
 */
static const int BIN_DELTA_MIN		= 1;
static const int BIN_DELTA_MAX		= 10;

/* we need at least 3 deltas / 4 samples for a reliable chirp detection */
#define NUM_DIFFS 3
#define FFT_NUM_SAMPLES		(NUM_DIFFS + 1)

/* Threshold for difference of delta peaks */
static const int MAX_DIFF		= 2;

/* width range to be checked for chirping */
static const int MIN_CHIRP_PULSE_WIDTH	= 20;
static const int MAX_CHIRP_PULSE_WIDTH	= 110;

struct ath9k_dfs_fft_20 {
	u8 bin[28];
	u8 lower_bins[3];
} __packed;
struct ath9k_dfs_fft_40 {
	u8 bin[64];
	u8 lower_bins[3];
	u8 upper_bins[3];
} __packed;

static inline int fft_max_index(u8 *bins)
{
	return (bins[2] & 0xfc) >> 2;
}
static inline int fft_max_magnitude(u8 *bins)
{
	return (bins[0] & 0xc0) >> 6 | bins[1] << 2 | (bins[2] & 0x03) << 10;
}
static inline u8 fft_bitmap_weight(u8 *bins)
{
	return bins[0] & 0x3f;
}

static int ath9k_get_max_index_ht40(struct ath9k_dfs_fft_40 *fft,
				    bool is_ctl, bool is_ext)
{
	const int DFS_UPPER_BIN_OFFSET = 64;
	/* if detected radar on both channels, select the significant one */
	if (is_ctl && is_ext) {
		/* first check wether channels have 'strong' bins */
		is_ctl = fft_bitmap_weight(fft->lower_bins) != 0;
		is_ext = fft_bitmap_weight(fft->upper_bins) != 0;

		/* if still unclear, take higher magnitude */
		if (is_ctl && is_ext) {
			int mag_lower = fft_max_magnitude(fft->lower_bins);
			int mag_upper = fft_max_magnitude(fft->upper_bins);
			if (mag_upper > mag_lower)
				is_ctl = false;
			else
				is_ext = false;
		}
	}
	if (is_ctl)
		return fft_max_index(fft->lower_bins);
	return fft_max_index(fft->upper_bins) + DFS_UPPER_BIN_OFFSET;
}
static bool ath9k_check_chirping(struct ath_softc *sc, u8 *data,
				 int datalen, bool is_ctl, bool is_ext)
{
	int i;
	int max_bin[FFT_NUM_SAMPLES];
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
	int prev_delta;

	if (IS_CHAN_HT40(ah->curchan)) {
		struct ath9k_dfs_fft_40 *fft = (struct ath9k_dfs_fft_40 *) data;
		int num_fft_packets = datalen / sizeof(*fft);
		if (num_fft_packets == 0)
			return false;

		ath_dbg(common, DFS, "HT40: datalen=%d, num_fft_packets=%d\n",
			datalen, num_fft_packets);
		if (num_fft_packets < FFT_NUM_SAMPLES) {
			ath_dbg(common, DFS, "not enough packets for chirp\n");
			return false;
		}
		/* HW sometimes adds 2 garbage bytes in front of FFT samples */
		if ((datalen % sizeof(*fft)) == 2) {
			fft = (struct ath9k_dfs_fft_40 *) (data + 2);
			ath_dbg(common, DFS, "fixing datalen by 2\n");
		}
		if (IS_CHAN_HT40MINUS(ah->curchan))
			swap(is_ctl, is_ext);

		for (i = 0; i < FFT_NUM_SAMPLES; i++)
			max_bin[i] = ath9k_get_max_index_ht40(fft + i, is_ctl,
							      is_ext);
	} else {
		struct ath9k_dfs_fft_20 *fft = (struct ath9k_dfs_fft_20 *) data;
		int num_fft_packets = datalen / sizeof(*fft);
		if (num_fft_packets == 0)
			return false;
		ath_dbg(common, DFS, "HT20: datalen=%d, num_fft_packets=%d\n",
			datalen, num_fft_packets);
		if (num_fft_packets < FFT_NUM_SAMPLES) {
			ath_dbg(common, DFS, "not enough packets for chirp\n");
			return false;
		}
		/* in ht20, this is a 6-bit signed number => shift it to 0 */
		for (i = 0; i < FFT_NUM_SAMPLES; i++)
			max_bin[i] = fft_max_index(fft[i].lower_bins) ^ 0x20;
	}
	ath_dbg(common, DFS, "bin_max = [%d, %d, %d, %d]\n",
		max_bin[0], max_bin[1], max_bin[2], max_bin[3]);

	/* Check for chirp attributes within specs
	 * a) delta of adjacent max_bins is within range
	 * b) delta of adjacent deltas are within tolerance
	 */
	prev_delta = 0;
	for (i = 0; i < NUM_DIFFS; i++) {
		int ddelta = -1;
		int delta = max_bin[i + 1] - max_bin[i];

		/* ensure gradient is within valid range */
		if (abs(delta) < BIN_DELTA_MIN || abs(delta) > BIN_DELTA_MAX) {
			ath_dbg(common, DFS, "CHIRP: invalid delta %d "
				"in sample %d\n", delta, i);
			return false;
		}
		if (i == 0)
			goto done;
		ddelta = delta - prev_delta;
		if (abs(ddelta) > MAX_DIFF) {
			ath_dbg(common, DFS, "CHIRP: ddelta %d too high\n",
				ddelta);
			return false;
		}
done:
		ath_dbg(common, DFS, "CHIRP - %d: delta=%d, ddelta=%d\n",
			i, delta, ddelta);
		prev_delta = delta;
	}
	return true;
}
/**** end: CHIRP **************************************************************/

/* convert pulse duration to usecs, considering clock mode */
static u32 dur_to_usecs(struct ath_hw *ah, u32 dur)
{
	const u32 AR93X_NSECS_PER_DUR = 800;
	const u32 AR93X_NSECS_PER_DUR_FAST = (8000 / 11);
	u32 nsecs;

	if (IS_CHAN_A_FAST_CLOCK(ah, ah->curchan))
		nsecs = dur * AR93X_NSECS_PER_DUR_FAST;
	else
		nsecs = dur * AR93X_NSECS_PER_DUR;

	return (nsecs + 500) / 1000;
}

#define PRI_CH_RADAR_FOUND 0x01
#define EXT_CH_RADAR_FOUND 0x02
static bool
ath9k_postprocess_radar_event(struct ath_softc *sc,
			      struct ath_radar_data *ard,
			      struct pulse_event *pe)
{
	u8 rssi;
	u16 dur;

	/*
	 * Only the last 2 bits of the BW info are relevant, they indicate
	 * which channel the radar was detected in.
	 */
	ard->pulse_bw_info &= 0x03;

	switch (ard->pulse_bw_info) {
	case PRI_CH_RADAR_FOUND:
		/* radar in ctrl channel */
		dur = ard->pulse_length_pri;
		DFS_STAT_INC(sc, pri_phy_errors);
		/*
		 * cannot use ctrl channel RSSI
		 * if extension channel is stronger
		 */
		rssi = (ard->ext_rssi >= (ard->rssi + 3)) ? 0 : ard->rssi;
		break;
	case EXT_CH_RADAR_FOUND:
		/* radar in extension channel */
		dur = ard->pulse_length_ext;
		DFS_STAT_INC(sc, ext_phy_errors);
		/*
		 * cannot use extension channel RSSI
		 * if control channel is stronger
		 */
		rssi = (ard->rssi >= (ard->ext_rssi + 12)) ? 0 : ard->ext_rssi;
		break;
	case (PRI_CH_RADAR_FOUND | EXT_CH_RADAR_FOUND):
		/*
		 * Conducted testing, when pulse is on DC, both pri and ext
		 * durations are reported to be same
		 *
		 * Radiated testing, when pulse is on DC, different pri and
		 * ext durations are reported, so take the larger of the two
		 */
		if (ard->pulse_length_ext >= ard->pulse_length_pri)
			dur = ard->pulse_length_ext;
		else
			dur = ard->pulse_length_pri;
		DFS_STAT_INC(sc, dc_phy_errors);

		/* when both are present use stronger one */
		rssi = max(ard->rssi, ard->ext_rssi);
		break;
	default:
		/*
		 * Bogus bandwidth info was received in descriptor,
		 * so ignore this PHY error
		 */
		DFS_STAT_INC(sc, bwinfo_discards);
		return false;
	}

	if (rssi == 0) {
		DFS_STAT_INC(sc, rssi_discards);
		return false;
	}

	/* convert duration to usecs */
	pe->width = dur_to_usecs(sc->sc_ah, dur);
	pe->rssi = rssi;

	DFS_STAT_INC(sc, pulses_detected);
	return true;
}

static void
ath9k_dfs_process_radar_pulse(struct ath_softc *sc, struct pulse_event *pe)
{
	struct dfs_pattern_detector *pd = sc->dfs_detector;
	DFS_STAT_INC(sc, pulses_processed);
	if (pd == NULL)
		return;
	if (!pd->add_pulse(pd, pe, NULL))
		return;
	DFS_STAT_INC(sc, radar_detected);
	ieee80211_radar_detected(sc->hw);
}

/*
 * DFS: check PHY-error for radar pulse and feed the detector
 */
void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
			      struct ath_rx_status *rs, u64 mactime)
{
	struct ath_radar_data ard;
	u16 datalen;
	char *vdata_end;
	struct pulse_event pe;
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);

	DFS_STAT_INC(sc, pulses_total);
	if ((rs->rs_phyerr != ATH9K_PHYERR_RADAR) &&
	    (rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT)) {
		ath_dbg(common, DFS,
			"Error: rs_phyer=0x%x not a radar error\n",
			rs->rs_phyerr);
		DFS_STAT_INC(sc, pulses_no_dfs);
		return;
	}

	datalen = rs->rs_datalen;
	if (datalen == 0) {
		DFS_STAT_INC(sc, datalen_discards);
		return;
	}

	ard.rssi = rs->rs_rssi_ctl[0];
	ard.ext_rssi = rs->rs_rssi_ext[0];

	/*
	 * hardware stores this as 8 bit signed value.
	 * we will cap it at 0 if it is a negative number
	 */
	if (ard.rssi & 0x80)
		ard.rssi = 0;
	if (ard.ext_rssi & 0x80)
		ard.ext_rssi = 0;

	vdata_end = data + datalen;
	ard.pulse_bw_info = vdata_end[-1];
	ard.pulse_length_ext = vdata_end[-2];
	ard.pulse_length_pri = vdata_end[-3];
	pe.freq = ah->curchan->channel;
	pe.ts = mactime;
	if (!ath9k_postprocess_radar_event(sc, &ard, &pe))
		return;

	if (pe.width > MIN_CHIRP_PULSE_WIDTH &&
	    pe.width < MAX_CHIRP_PULSE_WIDTH) {
		bool is_ctl = !!(ard.pulse_bw_info & PRI_CH_RADAR_FOUND);
		bool is_ext = !!(ard.pulse_bw_info & EXT_CH_RADAR_FOUND);
		int clen = datalen - 3;
		pe.chirp = ath9k_check_chirping(sc, data, clen, is_ctl, is_ext);
	} else {
		pe.chirp = false;
	}

	ath_dbg(common, DFS,
		"ath9k_dfs_process_phyerr: type=%d, freq=%d, ts=%llu, "
		"width=%d, rssi=%d, delta_ts=%llu\n",
		ard.pulse_bw_info, pe.freq, pe.ts, pe.width, pe.rssi,
		pe.ts - sc->dfs_prev_pulse_ts);
	sc->dfs_prev_pulse_ts = pe.ts;
	if (ard.pulse_bw_info & PRI_CH_RADAR_FOUND)
		ath9k_dfs_process_radar_pulse(sc, &pe);
	if (IS_CHAN_HT40(ah->curchan) &&
	    ard.pulse_bw_info & EXT_CH_RADAR_FOUND) {
		pe.freq += IS_CHAN_HT40PLUS(ah->curchan) ? 20 : -20;
		ath9k_dfs_process_radar_pulse(sc, &pe);
	}
}
#undef PRI_CH_RADAR_FOUND
#undef EXT_CH_RADAR_FOUND
