/*
 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by 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.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

#include "dfs.h"
/* TO DO DFS
   #include <ieee80211_var.h>
 */
/* TO DO DFS
   #include <ieee80211_channel.h>
 */
#include "dfs_phyerr.h"
#include "dfs_phyerr_tlv.h"

/*
 * Parsed radar status
 */
struct rx_radar_status {
	uint32_t raw_tsf;
	uint32_t tsf_offset;
	int rssi;
	int pulse_duration;
	int is_chirp:1;
	int delta_peak;
	int delta_diff;
	int sidx;
	int freq_offset;        /* in KHz */
};

struct rx_search_fft_report {
	uint32_t total_gain_db;
	uint32_t base_pwr_db;
	int fft_chn_idx;
	int peak_sidx;
	int relpwr_db;
	int avgpwr_db;
	int peak_mag;
	int num_str_bins_ib;
};

/*
 * XXX until "fastclk" is stored in the DFS configuration..
 */
#define  PERE_IS_OVERSAMPLING(_dfs) (1)

/*
 * XXX there _has_ to be a better way of doing this!
 * -adrian
 */
static int32_t sign_extend_32(uint32_t v, int nb)
{
	uint32_t m = 1U << (nb - 1);

	/* Chop off high bits, just in case */
	v &= v & ((1U << nb) - 1);

	/* Extend */
	return (v ^ m) - m;
}

/*
 * Calculate the frequency offset from the given signed bin index
 * from the radar summary report.
 *
 * This takes the oversampling mode into account.
 *
 * For oversampling, each bin has resolution 44MHz/128.
 * For non-oversampling, each bin has resolution 40MHz/128.
 *
 * It returns kHz - ie, 1000th's of MHz.
 */
static int calc_freq_offset(int sindex, int is_oversampling)
{

	if (is_oversampling)
		return sindex * (44000 / 128);
	else
		return sindex * (40000 / 128);
}

static void
radar_summary_print(struct ath_dfs *dfs,
		    struct rx_radar_status *rsu,
		    bool enable_log)
{
	if (!enable_log)
		return;

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "\n ############ Radar Summary ############\n");

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: Radar Summary - pulsedur = %d micro seconds\n", __func__,
		  rsu->pulse_duration);

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: Radar Summary - rssi = %d dbm\n", __func__,
		  rsu->rssi);

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: Radar Summary - ischirp = %d\n", __func__,
		  rsu->is_chirp);

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: Radar Summary - sidx = %d\n", __func__,
		  rsu->sidx);

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: Radar Summary - delta_peak = %d\n", __func__,
		  rsu->delta_peak);

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: Radar Summary - delta_diff = %d\n", __func__,
		  rsu->delta_diff);

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: Radar Summary - raw tsf = %d\n", __func__,
		  rsu->raw_tsf);

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: Radar Summary - tsf_offset = %d micro seconds\n",
		  __func__, rsu->tsf_offset);

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: Radar Summary - cooked tsf = %d\n", __func__,
		  (rsu->raw_tsf - rsu->tsf_offset));

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "%s: frequency offset = %d.%d MHz (oversampling = %d)\n",
		  __func__, (int) (rsu->freq_offset / 1000),
		  (int) abs(rsu->freq_offset % 1000),
		  PERE_IS_OVERSAMPLING(dfs));

	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
		  "\n ###################################\n");
}

/*
 * Parse the radar summary frame.
 *
 * The frame contents _minus_ the TLV are passed in.
 */
static void
radar_summary_parse(struct ath_dfs *dfs, const char *buf, size_t len,
		    struct rx_radar_status *rsu)
{
	uint32_t rs[2];
	int freq_centre, freq;

	/* Drop out if we have < 2 DWORDs available */
	if (len < sizeof(rs)) {
		DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR |
			    ATH_DEBUG_DFS_PHYERR_SUM,
			    "%s: len (%zu) < expected (%zu)!",
			    __func__, len, sizeof(rs));
	}

	/*
	 * Since the TLVs may be unaligned for some reason
	 * we take a private copy into aligned memory.
	 * This enables us to use the HAL-like accessor macros
	 * into the DWORDs to access sub-DWORD fields.
	 */
	OS_MEMCPY(rs, buf, sizeof(rs));

	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
		    "%s: two 32 bit values are: %08x %08x", __func__, rs[0],
		    rs[1]);
/* DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s (p=%p):", __func__, buf); */

	/* Populate the fields from the summary report */
	rsu->tsf_offset =
		MS(rs[RADAR_REPORT_PULSE_REG_2], RADAR_REPORT_PULSE_TSF_OFFSET);
	rsu->pulse_duration =
		MS(rs[RADAR_REPORT_PULSE_REG_2], RADAR_REPORT_PULSE_DUR);
	rsu->is_chirp =
		MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_IS_CHIRP);
	rsu->sidx =
		sign_extend_32(MS
				       (rs[RADAR_REPORT_PULSE_REG_1],
				       RADAR_REPORT_PULSE_SIDX), 10);
	rsu->freq_offset =
		calc_freq_offset(rsu->sidx, PERE_IS_OVERSAMPLING(dfs));

	/* These are only relevant if the pulse is a chirp */
	rsu->delta_peak =
		sign_extend_32(MS
				       (rs[RADAR_REPORT_PULSE_REG_1],
				       RADAR_REPORT_PULSE_DELTA_PEAK), 6);
	rsu->delta_diff =
		MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_DELTA_DIFF);

	/* WAR for FCC Type 4 */
	/*
	 * HW is giving longer pulse duration (in case of VHT80, with traffic)
	 * which fails to detect FCC type4 radar pulses. Added a work around to
	 * fix the pulse duration and duration delta.
	 *
	 * IF VHT80
	 *   && (primary_channel==30MHz || primary_channel== -30MHz)
	 *   && -4 <= pulse_index <= 4
	 *   && !chirp
	 *   && pulse duration > 20 us
	 * THEN
	 *   Set pulse duration to 20 us
	 */

	freq = ieee80211_chan2freq(dfs->ic, dfs->ic->ic_curchan);
	freq_centre = dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1;

	if ((IEEE80211_IS_CHAN_11AC_VHT80(dfs->ic->ic_curchan) &&
	     (abs(freq - freq_centre) == 30) &&
	     !rsu->is_chirp &&
	     abs(rsu->sidx) <= 4 && rsu->pulse_duration > 20)) {
		rsu->pulse_duration = 20;
	}

}

static void
radar_fft_search_report_parse(struct ath_dfs *dfs, const char *buf, size_t len,
			      struct rx_search_fft_report *rsfr)
{
	uint32_t rs[2];

	/* Drop out if we have < 2 DWORDs available */
	if (len < sizeof(rs)) {
		DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR |
			    ATH_DEBUG_DFS_PHYERR_SUM,
			    "%s: len (%zu) < expected (%zu)!",
			    __func__, len, sizeof(rs));
	}

	/*
	 * Since the TLVs may be unaligned for some reason
	 * we take a private copy into aligned memory.
	 * This enables us to use the HAL-like accessor macros
	 * into the DWORDs to access sub-DWORD fields.
	 */
	OS_MEMCPY(rs, buf, sizeof(rs));
	rsfr->total_gain_db =
		MS(rs[SEARCH_FFT_REPORT_REG_1],
			SEARCH_FFT_REPORT_TOTAL_GAIN_DB);
	rsfr->base_pwr_db =
		MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_BASE_PWR_DB);
	rsfr->fft_chn_idx =
		MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_FFT_CHN_IDX);
	rsfr->peak_sidx =
		sign_extend_32(MS
				       (rs[SEARCH_FFT_REPORT_REG_1],
				       SEARCH_FFT_REPORT_PEAK_SIDX), 12);
	rsfr->relpwr_db =
		MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_RELPWR_DB);
	rsfr->avgpwr_db =
		MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_AVGPWR_DB);
	rsfr->peak_mag =
		MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_PEAK_MAG);
	rsfr->num_str_bins_ib =
		MS(rs[SEARCH_FFT_REPORT_REG_2],
			SEARCH_FFT_REPORT_NUM_STR_BINS_IB);

	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
		    "%s: two 32 bit values are: %08x %08x", __func__, rs[0],
		    rs[1]);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->total_gain_db = %d",
		    __func__, rsfr->total_gain_db);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->base_pwr_db = %d",
		    __func__, rsfr->base_pwr_db);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->fft_chn_idx = %d",
		    __func__, rsfr->fft_chn_idx);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->peak_sidx = %d",
		    __func__, rsfr->peak_sidx);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->relpwr_db = %d",
		    __func__, rsfr->relpwr_db);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->avgpwr_db = %d",
		    __func__, rsfr->avgpwr_db);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->peak_mag = %d",
		    __func__, rsfr->peak_mag);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->num_str_bins_ib = %d",
		    __func__, rsfr->num_str_bins_ib);
}

/*
 * Parse a Peregrine BB TLV frame.
 *
 * This routine parses each TLV, prints out what's going on and
 * calls an appropriate sub-function.
 *
 * Since the TLV format doesn't _specify_ all TLV components are
 * DWORD aligned, we must treat them as not and access the fields
 * appropriately.
 */
static int
tlv_parse_frame(struct ath_dfs *dfs, struct rx_radar_status *rs,
		struct rx_search_fft_report *rsfr, const char *buf, size_t len,
		uint8_t rssi)
{
	int i = 0;
	uint32_t tlv_hdr[1];
	bool first_tlv = true;
	bool false_detect = false;

	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
		    "%s: total length = %zu bytes", __func__, len);
	while ((i < len) && (false_detect == false)) {
		/* Ensure we at least have four bytes */
		if ((len - i) < sizeof(tlv_hdr)) {
			DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR |
				    ATH_DEBUG_DFS_PHYERR_SUM,
				    "%s: ran out of bytes, len=%zu, i=%d",
				    __func__, len, i);
			return 0;
		}

		/*
		 * Copy the offset into the header,
		 * so the DWORD style access macros
		 * can be used.
		 */
		OS_MEMCPY(&tlv_hdr, buf + i, sizeof(tlv_hdr));

		DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
			    "%s: HDR: TLV SIG=0x%x, TAG=0x%x, LEN=%d bytes",
			    __func__,
			    MS(tlv_hdr[TLV_REG], TLV_SIG),
			    MS(tlv_hdr[TLV_REG], TLV_TAG),
			    MS(tlv_hdr[TLV_REG], TLV_LEN));

		/*
		 * Sanity check the length field is available in
		 * the remaining frame.  Drop out if this isn't
		 * the case - we can't trust the rest of the TLV
		 * entries.
		 */
		if (MS(tlv_hdr[TLV_REG], TLV_LEN) + i >= len) {
			DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
				    "%s: TLV oversize: LEN=%d, avail=%zu, i=%d",
				    __func__,
				    MS(tlv_hdr[TLV_REG], TLV_LEN), len, i);
			break;
		}

		/* Skip the TLV header - one DWORD */
		i += sizeof(tlv_hdr);

		/* Handle the payload */
		/* XXX TODO! */
		switch (MS(tlv_hdr[TLV_REG], TLV_SIG)) {
		case TAG_ID_RADAR_PULSE_SUMMARY:    /* Radar pulse summary */
			/* XXX TODO verify return value */
			/* XXX TODO validate only seeing one of these */
			radar_summary_parse(dfs, buf + i,
					    MS(tlv_hdr[TLV_REG], TLV_LEN), rs);
			break;
		case TAG_ID_SEARCH_FFT_REPORT:
			radar_fft_search_report_parse(dfs, buf + i,
						      MS(tlv_hdr[TLV_REG],
							 TLV_LEN), rsfr);
			/*
			 * we examine search FFT report and make the following
			 * assumption as per algorithms group's input:
			 * (1) There may be multiple TLV
			 * (2) We make false detection decison solely based on
			 * the first TLV
			 * (3) If the first TLV is a serch FFT report then we
			 * check the peak_mag value. When RSSI is equal to
			 * dfs->ath_dfs_false_rssI_thres (default 50) and
			 * peak_mag is less than 2 * dfs->ath_dfs_peak_mag
			 * (default 40) we treat it as false detect.
			 * Please note that 50 is not a true RSSI estimate,
			 * but value indicated by HW for RF saturation event.
			 */

			if ((first_tlv == true) &&
			    (rssi == dfs->ath_dfs_false_rssi_thres) &&
			    (rsfr->peak_mag < (2 * dfs->ath_dfs_peak_mag))) {
				false_detect = true;
				DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
					    "%s: setting false_detect to true",
					    __func__);
			}

			break;
		default:
			DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
				    "%s: unknown entry, SIG=0x%02x",
				    __func__, MS(tlv_hdr[TLV_REG], TLV_SIG));
		}

		/* Skip the payload */
		i += MS(tlv_hdr[TLV_REG], TLV_LEN);
		first_tlv = false;
	}
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: done", __func__);

	return false_detect ? 0 : 1;
}

/*
 * Calculate the channel centre in MHz.
 */
static int tlv_calc_freq_info(struct ath_dfs *dfs, struct rx_radar_status *rs)
{
	uint32_t chan_centre;
	uint32_t chan_width;
	int chan_offset;

	/*
	 * For now, just handle up to VHT80 correctly.
	 */
	if (dfs->ic == NULL || dfs->ic->ic_curchan == NULL) {
		DFS_PRINTK("%s: dfs->ic=%p, that or curchan is null?",
			   __func__, dfs->ic);
		return 0;
		/*
		 * For now, the only 11ac channel with freq1/freq2 setup is
		 * VHT80.
		 *
		 * XXX should have a flag macro to check this!
		 */
	} else if (IEEE80211_IS_CHAN_11AC_VHT80(dfs->ic->ic_curchan)) {
		/* 11AC, so cfreq1/cfreq2 are setup */

		/*
		 * XXX if it's 80+80 this won't work - need to use seg
		 * appropriately!
		 */

		chan_centre = dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1;
	} else {
		/* HT20/HT40 */

		/*
		 * XXX this is hard-coded - it should be 5 or 10 for
		 * half/quarter appropriately.
		 */
		chan_width = 20;

		/* Grab default channel centre */
		chan_centre = ieee80211_chan2freq(dfs->ic, dfs->ic->ic_curchan);

		/* Calculate offset based on HT40U/HT40D and VHT40U/VHT40D */
		if (IEEE80211_IS_CHAN_11N_HT40PLUS(dfs->ic->ic_curchan) ||
		    dfs->ic->ic_curchan->ic_flags & IEEE80211_CHAN_VHT40PLUS)
			chan_offset = chan_width;
		else if (IEEE80211_IS_CHAN_11N_HT40MINUS(dfs->ic->ic_curchan) ||
			 dfs->ic->ic_curchan->
			 ic_flags & IEEE80211_CHAN_VHT40MINUS)
			chan_offset = -chan_width;
		else
			chan_offset = 0;

		/* Calculate new _real_ channel centre */
		chan_centre += (chan_offset / 2);
	}

	/*
	 * XXX half/quarter rate support!
	 */

	/* Return ev_chan_centre in MHz */
	return chan_centre;
}

/*
 * Calculate the centre frequency and low/high range for a radar pulse event.
 *
 * XXX TODO: Handle half/quarter rates correctly!
 * XXX TODO: handle VHT160 correctly!
 * XXX TODO: handle VHT80+80 correctly!
 */
static int
tlv_calc_event_freq_pulse(struct ath_dfs *dfs, struct rx_radar_status *rs,
			  uint32_t *freq_centre, uint32_t *freq_lo,
			  uint32_t *freq_hi)
{
	int chan_width;
	int chan_centre;

	/* Fetch the channel centre frequency in MHz */
	chan_centre = tlv_calc_freq_info(dfs, rs);

	/* Convert to KHz */
	chan_centre *= 1000;

	/*
	 * XXX hard-code event width to be 2 * bin size for now;
	 * XXX this needs to take into account the core clock speed
	 * XXX for half/quarter rate mode.
	 */
	if (PERE_IS_OVERSAMPLING(dfs))
		chan_width = (44000 * 2 / 128);
	else
		chan_width = (40000 * 2 / 128);

	/* XXX adjust chan_width for half/quarter rate! */

	/*
	 * Now we can do the math to figure out the correct channel range.
	 */
	(*freq_centre) = (uint32_t) (chan_centre + rs->freq_offset);
	(*freq_lo) = (uint32_t) ((chan_centre + rs->freq_offset)
				 - chan_width);
	(*freq_hi) = (uint32_t) ((chan_centre + rs->freq_offset)
				 + chan_width);

	return 1;
}

/*
 * The chirp bandwidth in KHz is defined as:
 *
 * totalBW(KHz) = delta_peak(mean)
 *    * [ (bin resolution in KHz) / (radar_fft_long_period in uS) ]
 *    * pulse_duration (us)
 *
 * The bin resolution depends upon oversampling.
 *
 * For now, we treat the radar_fft_long_period as a hard-coded 8uS.
 */
static int
tlv_calc_event_freq_chirp(struct ath_dfs *dfs, struct rx_radar_status *rs,
			  uint32_t *freq_centre, uint32_t *freq_lo,
			  uint32_t *freq_hi)
{
	int32_t bin_resolution; /* KHz * 100 */
	int32_t radar_fft_long_period = 8;      /* microseconds */
	int32_t delta_peak;
	int32_t pulse_duration;
	int32_t total_bw;
	int32_t chan_centre;
	int32_t freq_1, freq_2;

	/*
	 * KHz isn't enough resolution here!
	 * So treat it as deci-hertz (10Hz) and convert back to KHz
	 * later.
	 */
	if (PERE_IS_OVERSAMPLING(dfs))
		bin_resolution = (44000 * 100) / 128;
	else
		bin_resolution = (40000 * 100) / 128;

	delta_peak = rs->delta_peak;
	pulse_duration = rs->pulse_duration;

	total_bw = delta_peak * (bin_resolution / radar_fft_long_period) *
		   pulse_duration;

	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | ATH_DEBUG_DFS_PHYERR_SUM,
		    "%s: delta_peak=%d, pulse_duration=%d, bin_resolution=%d.%dKHz, "
		    "radar_fft_long_period=%d, total_bw=%d.%ldKHz",
		    __func__,
		    delta_peak,
		    pulse_duration,
		    bin_resolution / 1000,
		    bin_resolution % 1000,
		    radar_fft_long_period, total_bw / 100, abs(total_bw % 100));

	total_bw /= 100;        /* back to KHz */

	/* Grab the channel centre frequency in MHz */
	chan_centre = tlv_calc_freq_info(dfs, rs);

	/* Early abort! */
	if (chan_centre == 0) {
		(*freq_centre) = 0;
		return 0;
	}

	/* Convert to KHz */
	chan_centre *= 1000;

	/*
	 * sidx is the starting frequency; total_bw is a signed value and
	 * for negative chirps (ie, moving down in frequency rather than up)
	 * the end frequency may be less than the start frequency.
	 */
	if (total_bw > 0) {
		freq_1 = chan_centre + rs->freq_offset;
		freq_2 = chan_centre + rs->freq_offset + total_bw;
	} else {
		freq_1 = chan_centre + rs->freq_offset + total_bw;
		freq_2 = chan_centre + rs->freq_offset;
	}

	(*freq_lo) = (uint32_t) (freq_1);
	(*freq_hi) = (uint32_t) (freq_2);
	(*freq_centre) = (uint32_t) (freq_1 + (abs(total_bw) / 2));

	return 1;
}

/*
 * Calculate the centre and band edge frequencies of the given radar
 * event.
 */
static int
tlv_calc_event_freq(struct ath_dfs *dfs, struct rx_radar_status *rs,
		    uint32_t *freq_centre, uint32_t *freq_lo,
		    uint32_t *freq_hi)
{
	if (rs->is_chirp)
		return tlv_calc_event_freq_chirp(dfs, rs, freq_centre,
						 freq_lo, freq_hi);
	else
		return tlv_calc_event_freq_pulse(dfs, rs, freq_centre,
						 freq_lo, freq_hi);
}

/*
 * This is the public facing function which parses the PHY error
 * and populates the dfs_phy_err struct.
 */
int
dfs_process_phyerr_bb_tlv(struct ath_dfs *dfs, void *buf, uint16_t datalen,
			  uint8_t rssi, uint8_t ext_rssi, uint32_t rs_tstamp,
			  uint64_t fulltsf, struct dfs_phy_err *e,
			  bool enable_log)
{
	struct rx_radar_status rs;
	struct rx_search_fft_report rsfr;
	static int invalid_phyerr_count;

	OS_MEMZERO(&rs, sizeof(rs));

	/*
	 * Add the ppdu_start/ppdu_end fields given to us by the upper
	 * layers.  The firmware gives us a summary set of parameters rather
	 * than the whole PPDU_START/PPDU_END descriptor contenst.
	 */
	rs.rssi = rssi;
	rs.raw_tsf = rs_tstamp;
	/*
	 * Try parsing the TLV set.
	 */
	if (!tlv_parse_frame(dfs, &rs, &rsfr, buf, datalen, rssi)) {
		invalid_phyerr_count++;
		/*
		 * Print only at every 2 power times
		 * to avoid flushing of the kernel
		 * logs, since the frequency of
		 * invalid phyerrors is very high
		 * in noisy environments.
		 */
		if (!(invalid_phyerr_count & 0xFF)) {
			CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_DEBUG,
				"%s[%d]:parse failed invalid phyerror cnt = %d",
				__func__, __LINE__, invalid_phyerr_count);
		}
		return 0;
	}
	/* For debugging, print what we have parsed */
	radar_summary_print(dfs, &rs, enable_log);

	/* Populate dfs_phy_err from rs */
	OS_MEMSET(e, 0, sizeof(*e));
	e->rssi = rs.rssi;
	e->dur = rs.pulse_duration;
	e->sidx = rs.sidx;
	e->is_pri = 1;          /* XXX always PRI for now */
	e->is_ext = 0;
	e->is_dc = 0;
	e->is_early = 0;
	/*
	 * XXX TODO: add a "chirp detection enabled" capability or config
	 * bit somewhere, in case for some reason the hardware chirp
	 * detection AND FFTs are disabled.
	 */
	/* For now, assume this hardware always does chirp detection */
	e->do_check_chirp = 1;
	e->is_hw_chirp = !!(rs.is_chirp);
	e->is_sw_chirp = 0;     /* We don't yet do software chirp checking */

	e->fulltsf = fulltsf;
	e->rs_tstamp = rs.raw_tsf - rs.tsf_offset;

	/* XXX error check */
	(void)tlv_calc_event_freq(dfs, &rs, &e->freq, &e->freq_lo, &e->freq_hi);

	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM,
		    "%s: fbin=%d, freq=%d.%d MHz, raw tsf=%u, offset=%d, "
		    "cooked tsf=%u, rssi=%d, dur=%d, is_chirp=%d, fulltsf=%llu, "
		    "freq=%d.%d MHz, freq_lo=%d.%dMHz, freq_hi=%d.%d MHz",
		    __func__,
		    rs.sidx,
		    (int)(rs.freq_offset / 1000),
		    (int)abs(rs.freq_offset % 1000),
		    rs.raw_tsf,
		    rs.tsf_offset,
		    e->rs_tstamp,
		    rs.rssi,
		    rs.pulse_duration,
		    (int)rs.is_chirp,
		    (unsigned long long)fulltsf,
		    (int)e->freq / 1000,
		    (int)abs(e->freq) % 1000,
		    (int)e->freq_lo / 1000,
		    (int)abs(e->freq_lo) % 1000,
		    (int)e->freq_hi / 1000, (int)abs(e->freq_hi) % 1000);

	return 1;
}
