Browse Source

qcacmn: refactor DFS code Part-I

Reduced the max indentation level to five.
Spilt functions to several smaller functions.
Only a few functions were split
in this commit. Rest need to be done in future commits.

Change-Id: I1c9dcf3ae12edef6bcce37023f93d062705e0142
CRs-Fixed: 2098511
Abhijit Pradhan 7 years ago
parent
commit
382c50fff7

+ 11 - 48
umac/dfs/core/src/dfs.h

@@ -67,6 +67,8 @@
  * XXX Peregrine reports pulses in microseconds, not hardware clocks!
  */
 
+#define MAX_DUR_FOR_LOW_RSSI 4
+
 /**
  * Cascade has issue with reported duration especially when there is a
  * crossover of chirp from one segment to another. It may report a value
@@ -231,7 +233,7 @@
  * struct dfs_pulseparams - DFS pulse param structure.
  * @p_time:        Time for start of pulse in usecs.
  * @p_dur:         Duration of pulse in usecs.
- * @p_rssi:        Duration of pulse in usecs.
+ * @p_rssi:        RSSI of pulse.
  */
 struct dfs_pulseparams {
 	uint64_t p_time;
@@ -497,7 +499,7 @@ struct dfs_nolelem {
 /**
  * struct dfs_info - DFS Info.
  * @rn_use_nol:            Use the NOL when radar found (default: TRUE).
- * @rn_numradars:          Number of different types of radars.
+ * @rn_ftindex:            Number of different types of radars.
  * @rn_lastfull_ts:        Last 64 bit timstamp from recv interrupt.
  * @rn_last_ts:            last 15 bit ts from recv descriptor.
  * @rn_last_unique_ts:     last unique 32 bit ts from recv descriptor.
@@ -513,7 +515,7 @@ struct dfs_nolelem {
  */
 struct dfs_info {
 	int       rn_use_nol;
-	uint32_t  rn_numradars;
+	uint32_t  rn_ftindex;
 	uint64_t  rn_lastfull_ts;
 	uint16_t  rn_last_ts;
 	uint32_t  rn_last_unique_ts;
@@ -663,7 +665,7 @@ struct dfs_event_log {
  * @dfs_radarf[]:          dfs_radarf - One filter for each radar pulse type.
  * @dfs_rinfo:             State vars for radar processing.
  * @dfs_b5radars:          array of bin5 radar events.
- * @dfs_radartable:        map of radar durs to filter types.
+ * @dfs_ftindextable:        map of radar durs to filter types.
  * @dfs_nol:               Non occupancy list for radar.
  * @dfs_nol_count:         How many items?
  * @dfs_defaultparams:     Default phy params per radar state.
@@ -752,7 +754,7 @@ struct wlan_dfs {
 	struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES];
 	struct dfs_info dfs_rinfo;
 	struct dfs_bin5radars *dfs_b5radars;
-	int8_t **dfs_radartable;
+	int8_t **dfs_ftindextable;
 	struct dfs_nolelem *dfs_nol;
 	int dfs_nol_count;
 	struct wlan_dfs_phyerr_param dfs_defaultparams;
@@ -1012,7 +1014,8 @@ void dfs_radar_found_action(struct wlan_dfs *dfs);
  * and ext channels as being unavailable.  This should be fixed for 802.11ac
  * or we'll quickly run out of valid channels to use.
  *
- * Return: If a radar event is found, return 1.  Otherwise, return 0.
+ * Return: If a radar event found on non-DFS channel return 0.
+ * Otherwise, return 1.
  */
 int dfs_process_radarevent(struct wlan_dfs *dfs,
 		struct dfs_ieee80211_channel *chan);
@@ -1229,18 +1232,6 @@ void dfs_add_pulse(struct wlan_dfs *dfs,
 		uint32_t deltaT,
 		uint64_t this_ts);
 
-/**
- * dfs_bin_fixedpattern_check() - Checks the BIN pattern.
- * @dfs: Pointer to wlan_dfs structure.
- * @rf:  Pointer to dfs_filter structure.
- * @dur: Duration.
- * ext_chan_flag : Ext channel flag.
- */
-int dfs_bin_fixedpattern_check(struct wlan_dfs *dfs,
-		struct dfs_filter *rf,
-		uint32_t dur,
-		int ext_chan_flag);
-
 /**
  * dfs_bin_check() - BIN check
  * @dfs: Pointer to wlan_dfs structure.
@@ -1845,7 +1836,6 @@ int dfs_process_phyerr_merlin(struct wlan_dfs *dfs,
  * __dfs_process_radarevent() - Continuation of process a radar event function.
  * @dfs: Pointer to wlan_dfs structure.
  * @ft: Pointer to dfs_filtertype structure.
- * @rf: Pointer to dfs_filter structure.
  * @re: Pointer to dfs_event structure.
  * @this_ts: Timestamp.
  *
@@ -1858,7 +1848,6 @@ int dfs_process_phyerr_merlin(struct wlan_dfs *dfs,
  */
 void __dfs_process_radarevent(struct wlan_dfs *dfs,
 		struct dfs_filtertype *ft,
-		struct dfs_filter *rf,
 		struct dfs_event *re,
 		uint64_t this_ts,
 		int *found);
@@ -1879,34 +1868,8 @@ void bin5_rules_check_internal(struct wlan_dfs *dfs,
 		uint32_t *numevents,
 		uint32_t prev,
 		uint32_t i,
-		uint32_t this);
-
-/**
- * count_the_other_delay_elements() - Counts the ther delay elements.
- * @dfs: Pointer to wlan_dfs structure.
- * @rf: Pointer to dfs_filter structure.
- * @dl: Pointer to dfs_delayline structure.
- * @i: Index value.
- * @refpri: Current "filter" time for start of pulse in usecs.
- * @refdur: Duration value.
- * @primargin: Primary margin.
- * @durmargin: Duration margin.
- * @numpulses: Number of pulses.
- * @prev_good_timestamp: Previous good timestamp.
- * @fundamentalpri: Highest PRI.
- */
-void count_the_other_delay_elements(struct wlan_dfs *dfs,
-		struct dfs_filter *rf,
-		struct dfs_delayline *dl,
-		uint32_t i,
-		uint32_t refpri,
-		uint32_t refdur,
-		uint32_t primargin,
-		uint32_t durmargin,
-		int *numpulses,
-		uint32_t *prev_good_timestamp,
-		int fundamentalpri
-		);
+		uint32_t this,
+		int *index);
 
 /**
  * dfs_main_timer_init() - Initialize dfs timers.

+ 581 - 192
umac/dfs/core/src/filtering/dfs_bindetects.c

@@ -25,102 +25,249 @@
 
 #include "../dfs.h"
 
-int dfs_bin_fixedpattern_check(struct wlan_dfs *dfs,
-		struct dfs_filter *rf,
-		uint32_t dur,
-		int ext_chan_flag)
+/**
+ * dfs_find_first_index_within_window() - Find first index within window
+ * @pl: Pointer to dfs_pulseline structure.
+ * @index: Index to dfs pulse elements.
+ * @start_ts: Start timestamp.
+ *
+ * Return: Returns index.
+ */
+static inline uint32_t dfs_find_first_index_within_window(
+		struct dfs_pulseline *pl,
+		uint32_t index,
+		uint64_t start_ts)
 {
-	struct dfs_pulseline *pl = dfs->pulses;
-	int i, n, refpri, primargin, numpulses = 0;
-	uint64_t start_ts, end_ts, event_ts, prev_event_ts;
-	uint64_t next_event_ts, window_start, window_end;
-	uint32_t index, next_index, deltadur;
-
-	/* For fixed pattern types, rf->rf_patterntype=1. */
-	primargin = dfs_get_pri_margin(dfs, ext_chan_flag,
-		(rf->rf_patterntype == 1));
-
-	refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
-	index = pl->pl_lastelem;
-	end_ts = pl->pl_elems[index].p_time;
-	start_ts = end_ts - (refpri*rf->rf_numpulses);
-
-	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS3,
-		"lastelem ts=%llu start_ts=%llu, end_ts=%llu\n",
-		(unsigned long long)pl->pl_elems[index].p_time,
-		(unsigned long long)start_ts,
-		(unsigned long long) end_ts);
+	uint16_t i;
 
 	/* Find the index of first element in our window of interest. */
 	for (i = 0; i < pl->pl_numelems; i++) {
 		index = (index - 1) & DFS_MAX_PULSE_BUFFER_MASK;
-		if (pl->pl_elems[index].p_time >= start_ts)
+		if (pl->pl_elems[index].p_time >= start_ts) {
 			continue;
-		else {
+		} else {
 			index = (index) & DFS_MAX_PULSE_BUFFER_MASK;
 			break;
 		}
 	}
-	for (n = 0; n <= rf->rf_numpulses; n++) {
-		window_start = (start_ts + (refpri*n))-(primargin+n);
-		window_end = window_start + 2*(primargin+n);
-		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-			"window_start %u window_end %u\n",
-			(uint32_t)window_start, (uint32_t)window_end);
-
-		for (i = 0; i < pl->pl_numelems; i++) {
-			prev_event_ts = pl->pl_elems[index].p_time;
-			index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK;
-			event_ts = pl->pl_elems[index].p_time;
-			next_index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK;
-			next_event_ts = pl->pl_elems[next_index].p_time;
-			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2, "ts %u\n",
+
+	return index;
+}
+
+/**
+ * dfs_ts_within_window() - Calculate pulses for timestamp within window
+ * @dfs: Pointer to wlan_dfs structure.
+ * @pl: Pointer to dfs_pulseline structure.
+ * @index: Index to dfs pulse elements.
+ * @dur: Pulse duration/width
+ * @numpulses: Number of pulses
+ *
+ * Return: Returns 1 if pulse count is incremented else returns 0.
+ */
+static inline bool dfs_ts_within_window(
+		struct wlan_dfs *dfs,
+		struct dfs_pulseline *pl,
+		uint32_t *index,
+		uint32_t dur,
+		int *numpulses)
+{
+	uint32_t deltadur;
+
+	deltadur = DFS_DIFF(pl->pl_elems[*index].p_dur, dur);
+	if ((pl->pl_elems[*index].p_dur == 1) ||
+			((dur != 1) && (deltadur <= 2))) {
+		(*numpulses)++;
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2, "numpulses %u\n", *numpulses);
+		return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * dfs_ts_eq_prevts() - Calculate pulses for timestamp equals to prev event
+ * @dfs: Pointer to wlan_dfs structure.
+ * @pl: Pointer to dfs_pulseline structure.
+ * @index: Index to dfs pulse elements.
+ * @dur: Pulse duration/width
+ * @numpulses: Number of pulses
+ *
+ * Return: Returns 1 if pulse count is incremented else returns 0.
+ */
+static inline bool dfs_ts_eq_prevts(
+		struct wlan_dfs *dfs,
+		struct dfs_pulseline *pl,
+		uint64_t next_event_ts,
+		uint64_t event_ts,
+		uint32_t refpri,
+		uint32_t *index,
+		uint32_t dur,
+		int *numpulses)
+
+{
+	uint32_t deltadur;
+
+	if (((next_event_ts - event_ts) > refpri) ||
+			((next_event_ts - event_ts) == 0)) {
+		deltadur = DFS_DIFF(pl->pl_elems[*index].p_dur, dur);
+		if ((pl->pl_elems[*index].p_dur == 1) ||
+				((pl->pl_elems[*index].p_dur != 1) &&
+				 (deltadur <= 2))) {
+			(*numpulses)++;
+			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+					"zero PRI: numpulses %u\n", *numpulses);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * dfs_pulses_within_window() - Calculate pulses within window
+ * @dfs: Pointer to wlan_dfs structure.
+ * @window_start: Start of the window.
+ * @window_end: End of the window.
+ * @index: Index to dfs pulse elements.
+ * @dur: Pulse duration/width.
+ * @refpri: reference PRI.
+ *
+ * Return: Returns 1 if pulse count is incremented else returns 0.
+ */
+static inline int dfs_pulses_within_window(
+		struct wlan_dfs *dfs,
+		uint64_t window_start,
+		uint64_t window_end,
+		uint32_t *index,
+		uint32_t dur,
+		uint32_t refpri)
+{
+	int numpulses = 0;
+	uint32_t i;
+	struct dfs_pulseline *pl = dfs->pulses;
+	uint64_t event_ts, prev_event_ts, next_event_ts;
+	uint32_t next_index;
+
+	for (i = 0; i < pl->pl_numelems; i++) {
+		prev_event_ts = pl->pl_elems[*index].p_time;
+		*index = (*index+1) & DFS_MAX_PULSE_BUFFER_MASK;
+		event_ts = pl->pl_elems[*index].p_time;
+		next_index = (*index+1) & DFS_MAX_PULSE_BUFFER_MASK;
+		next_event_ts = pl->pl_elems[next_index].p_time;
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2, "ts %u\n",
 				(uint32_t)event_ts);
 
-			if ((event_ts <= window_end) &&
-				(event_ts >= window_start)) {
-				deltadur = DFS_DIFF(pl->pl_elems[index].p_dur,
-					dur);
-				if ((pl->pl_elems[index].p_dur == 1) ||
-					((dur != 1) && (deltadur <= 2))) {
-					numpulses++;
-					DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-						"numpulses %u\n", numpulses);
-					break;
-				}
-			} else if (event_ts > window_end) {
-				index = (index-1) & DFS_MAX_PULSE_BUFFER_MASK;
+		if ((event_ts <= window_end) && (event_ts >= window_start)) {
+			if (dfs_ts_within_window(dfs, pl, index, dur,
+					&numpulses))
+				break;
+		} else if (event_ts > window_end) {
+			*index = (*index-1) & DFS_MAX_PULSE_BUFFER_MASK;
+			break;
+		} else if (event_ts == prev_event_ts) {
+			if (dfs_ts_eq_prevts(dfs, pl, next_event_ts, event_ts,
+					refpri, index, dur, &numpulses))
 				break;
-			} else if (event_ts == prev_event_ts) {
-				if (((next_event_ts - event_ts) > refpri) ||
-					((next_event_ts - event_ts) == 0)) {
-					deltadur =
-					    DFS_DIFF(pl->pl_elems[index].p_dur,
-						    dur);
-					if ((pl->pl_elems[index].p_dur == 1) ||
-						((pl->pl_elems[index].p_dur !=
-						  1) && (deltadur <= 2))) {
-						numpulses++;
-						DFS_DPRINTK(dfs,
-							WLAN_DEBUG_DFS2,
-							"zero PRI: numpulses %u\n",
-							numpulses);
-						break;
-					}
-				}
-			}
 		}
 	}
-	if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) {
+
+	return numpulses;
+}
+
+/**
+ * dfs_count_pulses() - Count pulses
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rf:  Pointer to dfs_filter structure.
+ * @dur: Pulse duration/width.
+ * @ext_chan_flag : Ext channel flag.
+ * @primargin: Primary margin.
+ * @index: Index to dfs pulse elements.
+ * @refpri: reference PRI.
+ * @start_ts: Start timestamp.
+ *
+ * Return: Returns number of pulses within window.
+ */
+static inline int dfs_count_pulses(
+		struct wlan_dfs *dfs,
+		struct dfs_filter *rf,
+		uint32_t dur,
+		int ext_chan_flag,
+		int primargin,
+		uint32_t index,
+		uint32_t refpri,
+		uint64_t start_ts)
+{
+	uint32_t n;
+	int numpulses = 0;
+	uint64_t window_start, window_end;
+
+	for (n = 0; n <= rf->rf_numpulses; n++) {
+		window_start = (start_ts + (refpri*n))-(primargin+n);
+		window_end = window_start + 2*(primargin+n);
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+				"window_start %u window_end %u\n",
+				(uint32_t)window_start, (uint32_t)window_end);
+		numpulses += dfs_pulses_within_window(dfs, window_start,
+				window_end, &index, dur, refpri);
+	}
+
+	return numpulses;
+}
+
+/**
+ * dfs_bin_fixedpattern_check() - Fixed pattern check
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rf:  Pointer to dfs_filter structure.
+ * @dur: Pulse duration/width.
+ * @ext_chan_flag : Ext channel flag.
+ */
+static int  dfs_bin_fixedpattern_check(
+		struct wlan_dfs *dfs,
+		struct dfs_filter *rf,
+		uint32_t dur,
+		int ext_chan_flag)
+{
+	struct dfs_pulseline *pl = dfs->pulses;
+	int primargin, numpulses, fil_thresh;
+	uint64_t start_ts, end_ts;
+	uint32_t last_index, first_index;
+	uint32_t refpri;
+
+	refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
+	last_index = pl->pl_lastelem;
+	end_ts = pl->pl_elems[last_index].p_time;
+	start_ts = end_ts - (refpri*rf->rf_numpulses);
+
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS3,
+		"lastelem ts=%llu start_ts=%llu, end_ts=%llu\n",
+		(unsigned long long)pl->pl_elems[last_index].p_time,
+		(unsigned long long)start_ts,
+		(unsigned long long) end_ts);
+
+	first_index = dfs_find_first_index_within_window(pl, last_index,
+			start_ts);
+
+	/* For fixed pattern types, rf->rf_patterntype=1. */
+	primargin = dfs_get_pri_margin(dfs, ext_chan_flag,
+			(rf->rf_patterntype == 1));
+
+	numpulses = dfs_count_pulses(dfs, rf, dur, ext_chan_flag, primargin,
+			first_index, refpri, start_ts);
+
+	fil_thresh = dfs_get_filter_threshold(dfs, rf, ext_chan_flag);
+
+	if (numpulses >= fil_thresh) {
 		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
 			"%s FOUND filterID=%u numpulses=%d unadj thresh=%d\n",
 			__func__, rf->rf_pulseid, numpulses, rf->rf_threshold);
 		return 1;
-	} else
+	} else {
 		return 0;
+	}
 }
 
-void dfs_add_pulse(struct wlan_dfs *dfs,
+void dfs_add_pulse(
+		struct wlan_dfs *dfs,
 		struct dfs_filter *rf,
 		struct dfs_event *re,
 		uint32_t deltaT,
@@ -165,85 +312,107 @@ void dfs_add_pulse(struct wlan_dfs *dfs,
 			dl->dl_firstelem, dl->dl_lastelem);
 }
 
-int dfs_bin_check(struct wlan_dfs *dfs,
-		struct dfs_filter *rf,
-		uint32_t deltaT,
-		uint32_t width,
-		int ext_chan_flag)
+/**
+ * dfs_find_lowestpri() - Find lowest PRI
+ * @dl: Pointer to dfs delayline.
+ * @lowpriindex: Low PRI index.
+ * @lowpri: Low PRI
+ */
+static inline void dfs_find_lowestpri(
+	struct dfs_delayline *dl,
+	uint32_t *lowpriindex,
+	uint32_t *lowpri)
 {
-	struct dfs_delayline *dl;
-	uint32_t refpri, refdur, searchpri, deltapri, deltapri_2, deltapri_3;
-	uint32_t averagerefpri, n, i, primargin, durmargin, highscore;
-	uint32_t highscoreindex;
-	int score[DFS_MAX_DL_SIZE], delayindex, dindex, found = 0;
-	uint32_t scoreindex, lowpriindex = 0, lowpri = 0xffff;
-	int numpulses = 0;
-	int lowprichk = 3, pri_match = 0;
-
-	dl = &rf->rf_dl;
-	if (dl->dl_numelems < (rf->rf_threshold-1))
-		return 0;
-
-	if (deltaT > rf->rf_filterlen)
-		return 0;
-
-	primargin = dfs_get_pri_margin(dfs, ext_chan_flag,
-			(rf->rf_patterntype == 1));
-
-	if (rf->rf_maxdur < 10)
-		durmargin = 4;
-	else
-		durmargin = 6;
-
-	if (rf->rf_patterntype == 1) {
-		found = dfs_bin_fixedpattern_check(dfs, rf, width,
-				ext_chan_flag);
-		if (found)
-			dl->dl_numelems = 0;
-		return found;
-	}
+	int delayindex;
+	uint32_t refpri;
+	uint32_t n;
 
-	qdf_mem_zero(score, sizeof(int)*DFS_MAX_DL_SIZE);
 	/* Find out the lowest pri. */
 	for (n = 0; n < dl->dl_numelems; n++) {
 		delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
 		refpri = dl->dl_elems[delayindex].de_time;
 		if (refpri == 0) {
 			continue;
-		} else if (refpri < lowpri) {
-			lowpri = dl->dl_elems[delayindex].de_time;
-			lowpriindex = n;
+		} else if (refpri < *lowpri) {
+			*lowpri = dl->dl_elems[delayindex].de_time;
+			*lowpriindex = n;
 		}
 	}
-	/* Find out the each delay element's pri score. */
+}
+
+/**
+ * dfs_calculate_score() - Calculate score for the score index
+ * if PRI match is found
+ * @dl: Pointer to dfs delayline.
+ * @rf: Pointer to dfs_filter structure.
+ * @score: score array.
+ * @refpri: reference PRI.
+ * @primargin: PRI margin.
+ * @score_index: Score index.
+ */
+static inline void dfs_calculate_score(
+	struct dfs_delayline *dl,
+	struct dfs_filter *rf,
+	int *score,
+	uint32_t refpri,
+	uint32_t primargin,
+	uint32_t score_index)
+{
+	int pri_match = 0;
+	int dindex;
+	uint32_t searchpri, deltapri, deltapri_2, deltapri_3;
+	uint32_t i;
+
+	for (i = 0; i < dl->dl_numelems; i++) {
+		dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
+		searchpri = dl->dl_elems[dindex].de_time;
+		deltapri = DFS_DIFF(searchpri, refpri);
+		deltapri_2 = DFS_DIFF(searchpri, 2*refpri);
+		deltapri_3 = DFS_DIFF(searchpri, 3*refpri);
+		if (rf->rf_ignore_pri_window == 2)
+			pri_match = ((deltapri < primargin) ||
+					(deltapri_2 < primargin) ||
+					(deltapri_3 < primargin));
+		else
+			pri_match = (deltapri < primargin);
+
+		if (pri_match)
+			score[score_index]++;
+	}
+}
+
+/**
+ * dfs_find_priscores() - Find PRI score
+ * @dl: Pointer to dfs delayline.
+ * @rf: Pointer to dfs_filter structure.
+ * @score: score array.
+ * @primargin: PRI margin.
+ */
+static void dfs_find_priscores(
+	struct dfs_delayline *dl,
+	struct dfs_filter *rf,
+	int *score,
+	uint32_t primargin)
+{
+	int delayindex;
+	uint32_t refpri;
+	uint32_t n;
+
+	qdf_mem_zero(score, sizeof(int)*DFS_MAX_DL_SIZE);
+
 	for (n = 0; n < dl->dl_numelems; n++) {
-		delayindex = (dl->dl_firstelem + n) &
-			DFS_MAX_DL_MASK;
+		delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
 		refpri = dl->dl_elems[delayindex].de_time;
 		if (refpri == 0)
 			continue;
 		if (refpri < rf->rf_maxpri) {
 			/* Use only valid PRI range for high score. */
-			for (i = 0; i < dl->dl_numelems; i++) {
-				dindex = (dl->dl_firstelem + i) &
-				    DFS_MAX_DL_MASK;
-				searchpri = dl->dl_elems[dindex].de_time;
-				deltapri = DFS_DIFF(searchpri, refpri);
-				deltapri_2 = DFS_DIFF(searchpri, 2*refpri);
-				deltapri_3 = DFS_DIFF(searchpri, 3*refpri);
-				if (rf->rf_ignore_pri_window == 2) {
-					pri_match = ((deltapri < primargin) ||
-						(deltapri_2 < primargin) ||
-						(deltapri_3 < primargin));
-				} else {
-					pri_match = (deltapri < primargin);
-				}
-				if (pri_match)
-					score[n]++;
-			}
+			dfs_calculate_score(dl, rf, score, refpri, primargin,
+				n);
 		} else {
 			score[n] = 0;
 		}
+
 		if (score[n] > rf->rf_threshold) {
 			/*
 			 * We got the most possible candidate,
@@ -252,67 +421,301 @@ int dfs_bin_check(struct wlan_dfs *dfs,
 			break;
 		}
 	}
+}
+
+/**
+ * dfs_find_highscore() - Find PRI high score
+ * @dl: Pointer to dfs delayline.
+ * @score: score array.
+ * @highscore: High score.
+ * @highscoreindex: High score index.
+ */
+static inline void dfs_find_highscore(
+		struct dfs_delayline *dl,
+		int *score,
+		uint32_t *highscore,
+		uint32_t *highscoreindex)
+{
+	int delayindex, dindex;
+	uint32_t n;
+
+	*highscore = 0;
+	*highscoreindex = 0;
 
-	/* Find out the high scorer. */
-	highscore = 0;
-	highscoreindex = 0;
 	for (n = 0; n < dl->dl_numelems; n++) {
-		if (score[n] > highscore) {
-			highscore = score[n];
-			highscoreindex = n;
-		} else if (score[n] == highscore) {
+		if (score[n] > *highscore) {
+			*highscore = score[n];
+			*highscoreindex = n;
+		} else if (score[n] == *highscore) {
 			/*
 			 * More than one pri has highscore take the least pri.
 			 */
-			delayindex = (dl->dl_firstelem + highscoreindex) &
+			delayindex = (dl->dl_firstelem + *highscoreindex) &
 				DFS_MAX_DL_MASK;
 			dindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
 			if (dl->dl_elems[dindex].de_time <=
 					dl->dl_elems[delayindex].de_time) {
-				highscoreindex = n;
+				*highscoreindex = n;
 			}
 		}
 	}
 
-	/*
-	 * Find the average pri of pulses around the pri of highscore
-	 * or the pulses around the lowest pri.
-	 */
+	return;
+}
+
+/**
+ * dfs_get_durmargin() - Find duration margin
+ * @rf: Pointer to dfs_filter structure.
+ * @durmargin: Duration margin
+ */
+static inline void dfs_get_durmargin(
+		struct dfs_filter *rf,
+		uint32_t *durmargin)
+{
+#define DUR_THRESH 10
+#define LOW_MARGIN 4
+#define HIGH_MARGIN 6
+
+	if (rf->rf_maxdur < DUR_THRESH)
+		*durmargin = LOW_MARGIN;
+	else
+		*durmargin = HIGH_MARGIN;
+
+#undef DUR_THRESH
+#undef LOW_MARGIN
+#undef HIGH_MARGIN
+}
+
+/**
+ * dfs_handle_fixedpattern() - Handle Fixed pattern radar
+ * @dfs: Pointer to wlan_dfs structure.
+ * @dl: Pointer to dfs delayline.
+ * @rf: Pointer to dfs_filter structure.
+ * @dur: Pulse duration/width
+ * @ext_chan_flag : Ext channel flag.
+ */
+static inline int dfs_handle_fixedpattern(
+		struct wlan_dfs *dfs,
+		struct dfs_delayline *dl,
+		struct dfs_filter *rf,
+		uint32_t dur,
+		int ext_chan_flag)
+{
+	int found = 0;
+
+	found = dfs_bin_fixedpattern_check(dfs, rf, dur, ext_chan_flag);
+	if (found)
+		dl->dl_numelems = 0;
+
+	return found;
+}
+
+/**
+ * dfs_bin_basic_sanity() - Sanity check
+ * @dl: Pointer to dfs delayline.
+ * @rf: Pointer to dfs_filter structure.
+ * @deltaT: Delta time.
+ */
+static inline int dfs_bin_basic_sanity(
+		struct dfs_delayline *dl,
+		struct dfs_filter *rf,
+		uint32_t *deltaT)
+{
+	if (dl->dl_numelems < (rf->rf_threshold-1))
+		return 0;
+
+	if (*deltaT > rf->rf_filterlen)
+		return 0;
+
+	return 1;
+}
+
+/**
+ * dfs_find_scoreindex() - Find score index
+ * @rf: Pointer to dfs_filter structure.
+ * @highscore: High score.
+ * @lowpriindex: Low PRI index.
+ * @highscoreindex: High score index.
+ * @scoreindex: score index.
+ */
+static inline void dfs_find_scoreindex(
+		struct dfs_filter *rf,
+		uint32_t highscore,
+		uint32_t lowpriindex,
+		uint32_t highscoreindex,
+		uint32_t *scoreindex)
+{
+	int lowprichk = 3;
+
 	if (rf->rf_ignore_pri_window > 0)
 		lowprichk = (rf->rf_threshold >> 1)+1;
 	else
 		lowprichk = 3;
 
 	if (highscore < lowprichk)
-		scoreindex = lowpriindex;
+		*scoreindex = lowpriindex;
 	else
-		scoreindex = highscoreindex;
+		*scoreindex = highscoreindex;
+}
+
+/**
+ * dfs_find_refs() - Find reference values.
+ * @dl: Pointer to dfs delayline.
+ * @rf: Pointer to dfs_filter structure.
+ * @scoreindex: score index.
+ * @refdur: Duration value.
+ * @refpri: Current "filter" time for start of pulse in usecs.
+ */
+static inline void dfs_find_refs(
+		struct dfs_delayline *dl,
+		struct dfs_filter *rf,
+		uint32_t scoreindex,
+		uint32_t *refdur,
+		uint32_t *refpri)
+{
+	int delayindex;
 
-	/* We got the possible pri, save its parameters as reference. */
 	delayindex = (dl->dl_firstelem + scoreindex) & DFS_MAX_DL_MASK;
-	refdur = dl->dl_elems[delayindex].de_dur;
-	refpri = dl->dl_elems[delayindex].de_time;
-	averagerefpri = 0;
+	*refdur = dl->dl_elems[delayindex].de_dur;
+	*refpri = dl->dl_elems[delayindex].de_time;
 
 	if (rf->rf_fixed_pri_radar_pulse)
-		refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
+		*refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
+}
 
-	numpulses = dfs_bin_pri_check(dfs, rf, dl, score[scoreindex], refpri,
-			refdur, ext_chan_flag, refpri);
-	if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) {
-		found = 1;
-		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
+/**
+ * dfs_bin_success_print() - Debug print
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rf: Pointer to dfs_filter structure.
+ * @ext_chan_flag: Extension channel flag.
+ * @numpulses: Number of pulses.
+ * @refpri: Current "filter" time for start of pulse in usecs.
+ * @refdur: Duration value.
+ * @primargin: PRI margin.
+ */
+static inline void dfs_bin_success_print(
+		struct wlan_dfs *dfs,
+		struct dfs_filter *rf,
+		int ext_chan_flag,
+		int numpulses,
+		uint32_t refpri,
+		uint32_t refdur,
+		uint32_t primargin)
+{
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
 			"ext_flag=%d MATCH filter=%u numpulses=%u thresh=%u refdur=%d refpri=%d primargin=%d\n",
 			ext_chan_flag, rf->rf_pulseid, numpulses,
 			rf->rf_threshold, refdur, refpri, primargin);
-		dfs_print_delayline(dfs, &rf->rf_dl);
-		dfs_print_filter(dfs, rf);
+	dfs_print_delayline(dfs, &rf->rf_dl);
+	dfs_print_filter(dfs, rf);
+}
+
+int dfs_bin_check(
+		struct wlan_dfs *dfs,
+		struct dfs_filter *rf,
+		uint32_t deltaT,
+		uint32_t width,
+		int ext_chan_flag)
+{
+	struct dfs_delayline *dl;
+	uint32_t refpri, refdur;
+	uint32_t highscoreindex;
+	uint32_t primargin, highscore;
+	int score[DFS_MAX_DL_SIZE], found = 0;
+	uint32_t scoreindex, lowpriindex = 0, lowpri = 0xffff;
+	int numpulses = 0;
+	int fil_thresh;
+
+	dl = &rf->rf_dl;
+	if (!dfs_bin_basic_sanity(dl, rf, &deltaT))
+		return 0;
+
+	primargin = dfs_get_pri_margin(dfs, ext_chan_flag,
+			(rf->rf_patterntype == 1));
+
+
+	if (rf->rf_patterntype == 1)
+		return dfs_handle_fixedpattern(dfs, dl, rf, width,
+				ext_chan_flag);
+
+	dfs_find_lowestpri(dl, &lowpriindex, &lowpri);
+
+	/* Find out the each delay element's pri score. */
+	dfs_find_priscores(dl, rf, score, primargin);
+
+	/* Find out the high scorer. */
+	dfs_find_highscore(dl, score, &highscore, &highscoreindex);
+
+	/*
+	 * Find the average pri of pulses around the pri of highscore
+	 * or the pulses around the lowest pri.
+	 */
+	dfs_find_scoreindex(rf, highscore, lowpriindex, highscoreindex,
+			&scoreindex);
+
+	/* We got the possible pri, save its parameters as reference. */
+	dfs_find_refs(dl, rf, scoreindex, &refdur, &refpri);
+
+	numpulses = dfs_bin_pri_check(dfs, rf, dl, score[scoreindex], refpri,
+			refdur, ext_chan_flag, refpri);
+
+	fil_thresh = dfs_get_filter_threshold(dfs, rf, ext_chan_flag);
+
+	if (numpulses >= fil_thresh) {
+		found = 1;
+		dfs_bin_success_print(dfs, rf, ext_chan_flag, numpulses,
+				refpri, refdur, primargin);
 	}
 
 	return found;
 }
 
-void count_the_other_delay_elements(struct wlan_dfs *dfs,
+/**
+ * dfs_check_pulses_for_delta_variance() - Check pulses for delta variance.
+ * @rf: Pointer to dfs_filter structure.
+ * @numpulsetochk: Number of pulses to check.
+ * @delta_time_stamps: Delta time stamp.
+ * @fundamentalpri: Highest PRI.
+ * @primargin: Primary margin.
+ * @numpulses: Number of pulses.
+ */
+static inline void dfs_check_pulses_for_delta_variance(
+		struct dfs_filter *rf,
+		int numpulsetochk,
+		uint32_t delta_time_stamps,
+		int fundamentalpri,
+		uint32_t primargin,
+		int *numpulses)
+{
+	uint32_t delta_ts_variance, j;
+
+	for (j = 0; j < numpulsetochk; j++) {
+		delta_ts_variance = DFS_DIFF(delta_time_stamps,
+				((j + 1) * fundamentalpri));
+		if (delta_ts_variance < (2 * (j + 1) * primargin)) {
+			(*numpulses)++;
+			if (rf->rf_ignore_pri_window > 0)
+				break;
+		}
+	}
+}
+
+/**
+ * dfs_count_the_other_delay_elements() - Counts the ther delay elements.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rf: Pointer to dfs_filter structure.
+ * @dl: Pointer to dfs_delayline structure.
+ * @i: Index value.
+ * @refpri: Current "filter" time for start of pulse in usecs.
+ * @refdur: Duration value.
+ * @primargin: Primary margin.
+ * @durmargin: Duration margin.
+ * @numpulses: Number of pulses.
+ * @prev_good_timestamp: Previous good timestamp.
+ * @fundamentalpri: Highest PRI.
+ */
+static void dfs_count_the_other_delay_elements(
+		struct wlan_dfs *dfs,
 		struct dfs_filter *rf,
 		struct dfs_delayline *dl,
 		uint32_t i,
@@ -322,12 +725,11 @@ void count_the_other_delay_elements(struct wlan_dfs *dfs,
 		uint32_t durmargin,
 		int *numpulses,
 		uint32_t *prev_good_timestamp,
-		int fundamentalpri
-		)
+		int fundamentalpri)
 {
 	int delayindex;
 	uint32_t searchpri, searchdur, deltadur, deltapri1, deltapri2;
-	uint32_t j = 0, delta_time_stamps, delta_ts_variance, deltapri;
+	uint32_t j = 0, delta_time_stamps, deltapri;
 	int dindex, primatch, numpulsetochk = 2;
 
 	delayindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
@@ -348,21 +750,16 @@ void count_the_other_delay_elements(struct wlan_dfs *dfs,
 	deltapri2 = DFS_DIFF(searchpri, 2 * refpri);
 	primatch = 0;
 
-	if ((rf->rf_ignore_pri_window > 0) &&
-			(rf->rf_patterntype != 2)) {
+	if ((rf->rf_ignore_pri_window > 0) && (rf->rf_patterntype != 2)) {
 		for (j = 0; j < rf->rf_numpulses; j++) {
-			deltapri1 = DFS_DIFF(searchpri,
-					(j + 1) * refpri);
+			deltapri1 = DFS_DIFF(searchpri, (j + 1) * refpri);
 			if (deltapri1 < (2 * primargin)) {
 				primatch = 1;
 				break;
 			}
 		}
-	} else {
-		if ((deltapri1 < primargin) ||
-				(deltapri2 < primargin)) {
-			primatch = 1;
-		}
+	} else if ((deltapri1 < primargin) || (deltapri2 < primargin)) {
+		primatch = 1;
 	}
 
 	if (primatch && (deltadur < durmargin)) {
@@ -380,16 +777,10 @@ void count_the_other_delay_elements(struct wlan_dfs *dfs,
 			} else {
 				numpulsetochk = 4;
 			}
-			for (j = 0; j < numpulsetochk; j++) {
-				delta_ts_variance = DFS_DIFF(delta_time_stamps,
-					((j + 1) * fundamentalpri));
-				if (delta_ts_variance <
-					(2 * (j + 1) * primargin)) {
-					(*numpulses)++;
-					if (rf->rf_ignore_pri_window > 0)
-						break;
-				}
-			}
+
+			dfs_check_pulses_for_delta_variance(rf, numpulsetochk,
+					delta_time_stamps, fundamentalpri,
+					primargin, numpulses);
 		}
 		*prev_good_timestamp = dl->dl_elems[delayindex].de_ts;
 
@@ -400,7 +791,8 @@ void count_the_other_delay_elements(struct wlan_dfs *dfs,
 	}
 }
 
-int dfs_bin_pri_check(struct wlan_dfs *dfs,
+int dfs_bin_pri_check(
+		struct wlan_dfs *dfs,
 		struct dfs_filter *rf,
 		struct dfs_delayline *dl,
 		uint32_t score,
@@ -433,10 +825,7 @@ int dfs_bin_pri_check(struct wlan_dfs *dfs,
 		return numpulses;
 	}
 
-	if (rf->rf_maxdur < 10)
-		durmargin = 4;
-	else
-		durmargin = 6;
+	dfs_get_durmargin(rf, &durmargin);
 
 	if ((!rf->rf_fixed_pri_radar_pulse)) {
 		if (rf->rf_ignore_pri_window == 1)
@@ -481,9 +870,9 @@ int dfs_bin_pri_check(struct wlan_dfs *dfs,
 	 * in the acceptable range from the reference one.
 	 */
 	for (i = 0; i < dl->dl_numelems; i++)
-		count_the_other_delay_elements(dfs, rf, dl, i, refpri, refdur,
-			primargin, durmargin, &numpulses, &prev_good_timestamp,
-			fundamentalpri);
+		dfs_count_the_other_delay_elements(dfs, rf, dl, i, refpri,
+				refdur, primargin, durmargin, &numpulses,
+				&prev_good_timestamp, fundamentalpri);
 
 	return numpulses;
 }

+ 27 - 17
umac/dfs/core/src/filtering/dfs_debug.c

@@ -44,11 +44,33 @@ void dfs_print_filter(struct wlan_dfs *dfs, struct dfs_filter *rf)
 		rf->rf_maxdur);
 }
 
+/**
+ * dfs_print_filtertype() - Print the filtertype
+ * @dfs: Pointer to wlan_dfs structure.
+ * @ft:  Pointer to dfs_filtertype structure.
+ */
+static void dfs_print_filtertype(
+		struct wlan_dfs *dfs,
+		struct dfs_filtertype *ft)
+{
+	uint32_t j;
+	struct dfs_filter *rf;
+
+	for (j = 0; j < ft->ft_numfilters; j++) {
+		rf = &(ft->ft_filters[j]);
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+				"filter[%d] filterID = %d rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n",
+				j, rf->rf_pulseid, rf->rf_numpulses,
+				rf->rf_minpri, rf->rf_maxpri,
+				rf->rf_threshold, rf->rf_filterlen,
+				rf->rf_mindur, rf->rf_maxdur);
+	}
+}
+
 void dfs_print_filters(struct wlan_dfs *dfs)
 {
 	struct dfs_filtertype *ft = NULL;
-	struct dfs_filter *rf;
-	int i, j;
+	uint8_t i;
 
 	if (dfs == NULL) {
 		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
@@ -64,21 +86,9 @@ void dfs_print_filters(struct wlan_dfs *dfs)
 				continue;
 			}
 			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-				"===========ft->ft_numfilters = %u===========\n",
-				ft->ft_numfilters);
-			for (j = 0; j < ft->ft_numfilters; j++) {
-				rf = &(ft->ft_filters[j]);
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-					"filter[%d] filterID = %d rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n",
-					j, rf->rf_pulseid,
-					rf->rf_numpulses,
-					rf->rf_minpri,
-					rf->rf_maxpri,
-					rf->rf_threshold,
-					rf->rf_filterlen,
-					rf->rf_mindur,
-					rf->rf_maxdur);
-			}
+					"===========ft->ft_numfilters = %u===========\n",
+					ft->ft_numfilters);
+			dfs_print_filtertype(dfs, ft);
 		}
 	}
 }

+ 65 - 41
umac/dfs/core/src/filtering/dfs_fcc_bin5.c

@@ -127,17 +127,70 @@ int dfs_bin5_addpulse(struct wlan_dfs *dfs,
 	return 1;
 }
 
+/**
+ * dfs_calculate_bursts_for_same_rssi() - Calculate bursts for same rssi.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @br: Pointer to dfs_bin5radars structure.
+ * @bursts: Bursts.
+ * @numevents: Number of events.
+ * @prev: prev index.
+ * @this: index to br_elems[].
+ * @index: index array.
+ */
+static inline void dfs_calculate_bursts_for_same_rssi(
+		struct wlan_dfs *dfs,
+		struct dfs_bin5radars *br,
+		uint32_t *bursts,
+		uint32_t *numevents,
+		uint32_t prev,
+		uint32_t this,
+		int *index)
+{
+	uint32_t rssi_diff;
+
+	if (br->br_elems[this].be_rssi >= br->br_elems[prev].be_rssi)
+		rssi_diff = (br->br_elems[this].be_rssi -
+				br->br_elems[prev].be_rssi);
+	else
+		rssi_diff = (br->br_elems[prev].be_rssi -
+				br->br_elems[this].be_rssi);
+
+	if (rssi_diff <= DFS_BIN5_RSSI_MARGIN) {
+		(*bursts)++;
+		/*
+		 * Save the indexes of this pair for later
+		 * width variance check.
+		 */
+		if ((*numevents) >= 2) {
+			/*
+			 * Make sure the event is not duplicated, possible in
+			 * a 3 pulse burst.
+			 */
+			if (index[(*numevents)-1] != prev)
+				index[(*numevents)++] = prev;
+		} else {
+			index[(*numevents)++] = prev;
+		}
+
+		index[(*numevents)++] = this;
+	} else {
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_BIN5,
+				"%s %d Bin5 rssi_diff=%d\n",
+				__func__, __LINE__, rssi_diff);
+	}
+}
+
 void bin5_rules_check_internal(struct wlan_dfs *dfs,
 		struct dfs_bin5radars *br,
 		uint32_t *bursts,
 		uint32_t *numevents,
 		uint32_t prev,
 		uint32_t i,
-		uint32_t this)
+		uint32_t this,
+		int *index)
 {
 	uint64_t pri = 0;
-	uint32_t width_diff = 0, rssi_diff = 0;
-	int index[DFS_MAX_B5_SIZE];
+	uint32_t width_diff = 0;
 
 	/* Rule 1: 1000 <= PRI <= 2000 + some margin. */
 	if (br->br_elems[this].be_ts >= br->br_elems[prev].be_ts) {
@@ -168,42 +221,15 @@ void bin5_rules_check_internal(struct wlan_dfs *dfs,
 			width_diff = (br->br_elems[prev].be_dur
 					- br->br_elems[this].be_dur);
 		}
-		if (width_diff <= DFS_BIN5_WIDTH_MARGIN) {
+
+		if (width_diff <= DFS_BIN5_WIDTH_MARGIN)
 			/*
 			 * Rule 3: RSSI of the pulses in the
 			 * burst should be same (+/- margin)
 			 */
-			if (br->br_elems[this].be_rssi >=
-					br->br_elems[prev].be_rssi) {
-				rssi_diff = (br->br_elems[this].be_rssi -
-						br->br_elems[prev].be_rssi);
-			} else {
-				rssi_diff = (br->br_elems[prev].be_rssi -
-						br->br_elems[this].be_rssi);
-			}
-			if (rssi_diff <= DFS_BIN5_RSSI_MARGIN) {
-				(*bursts)++;
-				/*
-				 * Save the indexes of this pair for later
-				 * width variance check.
-				 */
-				if ((*numevents) >= 2) {
-					/*
-					 * Make sure the event is not
-					 * duplicated, possible in a 3 pulse
-					 * burst.
-					 */
-					if (index[(*numevents)-1] != prev)
-						index[(*numevents)++] = prev;
-				} else
-					index[(*numevents)++] = prev;
-
-				index[(*numevents)++] = this;
-			} else
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_BIN5,
-					"%s %d Bin5 rssi_diff=%d\n",
-					__func__, __LINE__, rssi_diff);
-		} else
+			dfs_calculate_bursts_for_same_rssi(dfs, br, bursts,
+					numevents, prev, this, index);
+		 else
 			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_BIN5,
 				"%s %d Bin5 width_diff=%d\n",
 				__func__, __LINE__, width_diff);
@@ -224,6 +250,7 @@ int dfs_bin5_check(struct wlan_dfs *dfs)
 	uint32_t n = 0, i = 0, i1 = 0, this = 0, prev = 0;
 	uint32_t bursts = 0, total_diff = 0, average_diff = 0;
 	uint32_t total_width = 0, average_width = 0, numevents = 0;
+	int index[DFS_MAX_B5_SIZE];
 
 	if (dfs == NULL) {
 		DFS_PRINTK("%s: dfs is NULL\n", __func__);
@@ -258,7 +285,7 @@ int dfs_bin5_check(struct wlan_dfs *dfs)
 				continue;
 			}
 			bin5_rules_check_internal(dfs, br, &bursts, &numevents,
-					prev, i, this);
+					prev, i, this, index);
 			prev = this;
 		}
 
@@ -272,12 +299,9 @@ int dfs_bin5_check(struct wlan_dfs *dfs)
 
 			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_BIN5,
 				"bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n",
-				bursts, numevents,
-				total_width, average_width,
+				bursts, numevents, total_width, average_width,
 				total_diff, average_diff);
-			DFS_PRINTK(
-				"bin 5 radar detected, bursts=%d\n",
-				bursts);
+			DFS_PRINTK("bin 5 radar detected, bursts=%d\n", bursts);
 			return 1;
 		}
 	}

+ 131 - 83
umac/dfs/core/src/filtering/dfs_init.c

@@ -23,13 +23,32 @@
 #include "../dfs.h"
 #include "wlan_dfs_lmac_api.h"
 
-void dfs_reset_alldelaylines(struct wlan_dfs *dfs)
+/**
+ * dfs_reset_filtertype() - Reset filtertype.
+ * @ft: Pointer to dfs_filtertype structure.
+ */
+static inline void dfs_reset_filtertype(
+		struct dfs_filtertype *ft)
 {
-	struct dfs_filtertype *ft = NULL;
+	int j;
 	struct dfs_filter *rf;
 	struct dfs_delayline *dl;
+
+	for (j = 0; j < ft->ft_numfilters; j++) {
+		rf = &(ft->ft_filters[j]);
+		dl = &(rf->rf_dl);
+		if (dl != NULL) {
+			qdf_mem_zero(dl, sizeof(*dl));
+			dl->dl_lastelem = (0xFFFFFFFF) & DFS_MAX_DL_MASK;
+		}
+	}
+}
+
+void dfs_reset_alldelaylines(struct wlan_dfs *dfs)
+{
+	struct dfs_filtertype *ft = NULL;
 	struct dfs_pulseline *pl;
-	int i, j;
+	int i;
 
 	if (dfs == NULL) {
 		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
@@ -57,16 +76,7 @@ void dfs_reset_alldelaylines(struct wlan_dfs *dfs)
 	for (i = 0; i < DFS_MAX_RADAR_TYPES; i++) {
 		if (dfs->dfs_radarf[i] != NULL) {
 			ft = dfs->dfs_radarf[i];
-			for (j = 0; j < ft->ft_numfilters; j++) {
-				rf = &(ft->ft_filters[j]);
-				dl = &(rf->rf_dl);
-				if (dl != NULL) {
-					qdf_mem_zero(dl,
-						sizeof(struct dfs_delayline));
-					dl->dl_lastelem =
-						(0xFFFFFFFF) & DFS_MAX_DL_MASK;
-				}
-			}
+			dfs_reset_filtertype(ft);
 		}
 	}
 
@@ -119,6 +129,93 @@ void dfs_reset_radarq(struct wlan_dfs *dfs)
 	WLAN_DFSQ_UNLOCK(dfs);
 }
 
+/**
+ * dfs_fill_ft_index_table() - DFS fill ft index table.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @i: Duration used as an index.
+ *
+ * Return: 1 if too many overlapping radar filters else 0.
+ */
+static inline bool dfs_fill_ft_index_table(
+		struct wlan_dfs *dfs,
+		int i)
+{
+	uint32_t stop = 0, tableindex = 0;
+
+	while ((tableindex < DFS_MAX_RADAR_OVERLAP) && (!stop)) {
+		if ((dfs->dfs_ftindextable[i])[tableindex] == -1)
+			stop = 1;
+		else
+			tableindex++;
+	}
+
+	if (stop) {
+		(dfs->dfs_ftindextable[i])[tableindex] =
+			(int8_t)(dfs->dfs_rinfo.rn_ftindex);
+	} else {
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
+				"%s: Too many overlapping radar filters\n",
+				__func__);
+		return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * dfs_fill_filter_type() - DFS fill filter type.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @ft: Double pointer to dfs_filtertype structure.
+ * @dfs_radars: Pointer to dfs_pulse structure.
+ * @min_rssithresh: Minimum RSSI threshold.
+ * @max_pulsedur: Maximum RSSI threshold.
+ * @p: Index to dfs_pulse structure.
+ *
+ * Return: 1 if too many overlapping radar filters else 0.
+ */
+static inline bool dfs_fill_filter_type(
+		struct wlan_dfs *dfs,
+		struct dfs_filtertype **ft,
+		struct dfs_pulse *dfs_radars,
+		int32_t *min_rssithresh,
+		uint32_t *max_pulsedur,
+		int p)
+{
+	int i;
+
+	/* No filter of the appropriate dur was found. */
+	if ((dfs->dfs_rinfo.rn_ftindex + 1) > DFS_MAX_RADAR_TYPES) {
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
+				"%s: Too many filter types\n", __func__);
+		return 1;
+	}
+	(*ft) = dfs->dfs_radarf[dfs->dfs_rinfo.rn_ftindex];
+	(*ft)->ft_numfilters = 0;
+	(*ft)->ft_numpulses = dfs_radars[p].rp_numpulses;
+	(*ft)->ft_patterntype = dfs_radars[p].rp_patterntype;
+	(*ft)->ft_mindur = dfs_radars[p].rp_mindur;
+	(*ft)->ft_maxdur = dfs_radars[p].rp_maxdur;
+	(*ft)->ft_filterdur = dfs_radars[p].rp_pulsedur;
+	(*ft)->ft_rssithresh = dfs_radars[p].rp_rssithresh;
+	(*ft)->ft_rssimargin = dfs_radars[p].rp_rssimargin;
+	(*ft)->ft_minpri = 1000000;
+
+	if ((*ft)->ft_rssithresh < *min_rssithresh)
+		*min_rssithresh = (*ft)->ft_rssithresh;
+
+	if ((*ft)->ft_maxdur > *max_pulsedur)
+		*max_pulsedur = (*ft)->ft_maxdur;
+
+	for (i = (*ft)->ft_mindur; i <= (*ft)->ft_maxdur; i++) {
+		if (dfs_fill_ft_index_table(dfs, i))
+			return 1;
+	}
+
+	dfs->dfs_rinfo.rn_ftindex++;
+
+	return 0;
+}
+
 int dfs_init_radar_filters(struct wlan_dfs *dfs,
 		struct wlan_dfs_radar_tab_info *radar_info)
 {
@@ -131,6 +228,7 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
 	uint32_t max_pulsedur = 0;
 	int numpulses, p, n, i;
 	int numradars = 0, numb5radars = 0;
+	int retval;
 
 	if (dfs == NULL) {
 		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS, "dfs is NULL %s", __func__);
@@ -167,17 +265,17 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
 	dfs->dfs_defaultparams = radar_info->dfs_defaultparams;
 
 	dfs->wlan_dfs_isdfsregdomain = 1;
-	dfs->dfs_rinfo.rn_numradars = 0;
+	dfs->dfs_rinfo.rn_ftindex = 0;
 	/* Clear filter type table. */
 	for (n = 0; n < 256; n++) {
 		for (i = 0; i < DFS_MAX_RADAR_OVERLAP; i++)
-			(dfs->dfs_radartable[n])[i] = -1;
+			(dfs->dfs_ftindextable[n])[i] = -1;
 	}
 
 	/* Now, initialize the radar filters. */
 	for (p = 0; p < numradars; p++) {
 		ft = NULL;
-		for (n = 0; n < dfs->dfs_rinfo.rn_numradars; n++) {
+		for (n = 0; n < dfs->dfs_rinfo.rn_ftindex; n++) {
 			if ((dfs_radars[p].rp_pulsedur ==
 				    dfs->dfs_radarf[n]->ft_filterdur) &&
 				(dfs_radars[p].rp_numpulses ==
@@ -190,57 +288,14 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
 				break;
 			}
 		}
+
 		if (ft == NULL) {
-			/* No filter of the appropriate dur was found. */
-			if ((dfs->dfs_rinfo.rn_numradars + 1) >
-					DFS_MAX_RADAR_TYPES) {
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
-						"%s: Too many filter types\n",
-						__func__);
+			retval = dfs_fill_filter_type(dfs, &ft, dfs_radars,
+					&min_rssithresh, &max_pulsedur, p);
+			if (retval == 1)
 				goto bad4;
-			}
-			ft = dfs->dfs_radarf[dfs->dfs_rinfo.rn_numradars];
-			ft->ft_numfilters = 0;
-			ft->ft_numpulses = dfs_radars[p].rp_numpulses;
-			ft->ft_patterntype = dfs_radars[p].rp_patterntype;
-			ft->ft_mindur = dfs_radars[p].rp_mindur;
-			ft->ft_maxdur = dfs_radars[p].rp_maxdur;
-			ft->ft_filterdur = dfs_radars[p].rp_pulsedur;
-			ft->ft_rssithresh = dfs_radars[p].rp_rssithresh;
-			ft->ft_rssimargin = dfs_radars[p].rp_rssimargin;
-			ft->ft_minpri = 1000000;
-
-			if (ft->ft_rssithresh < min_rssithresh)
-				min_rssithresh = ft->ft_rssithresh;
-
-			if (ft->ft_maxdur > max_pulsedur)
-				max_pulsedur = ft->ft_maxdur;
-
-			for (i = ft->ft_mindur; i <= ft->ft_maxdur; i++) {
-				uint32_t stop = 0, tableindex = 0;
-
-				while ((tableindex < DFS_MAX_RADAR_OVERLAP) &&
-						(!stop)) {
-					if ((dfs->dfs_radartable[i])[tableindex]
-							== -1)
-						stop = 1;
-					else
-						tableindex++;
-				}
-
-				if (stop) {
-					(dfs->dfs_radartable[i])[tableindex] =
-					    (int8_t)
-					    (dfs->dfs_rinfo.rn_numradars);
-				} else {
-					DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
-							"%s: Too many overlapping radar filters\n",
-							__func__);
-					goto bad4;
-				}
-			}
-			dfs->dfs_rinfo.rn_numradars++;
 		}
+
 		rf = &(ft->ft_filters[ft->ft_numfilters++]);
 		dfs_reset_delayline(&rf->rf_dl);
 		numpulses = dfs_radars[p].rp_numpulses;
@@ -254,21 +309,19 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
 		rf->rf_ignore_pri_window = dfs_radars[p].rp_ignore_pri_window;
 		T = (100000000 / dfs_radars[p].rp_max_pulsefreq) -
 			100 * (dfs_radars[p].rp_meanoffset);
-		rf->rf_minpri =
-			dfs_round((int32_t)T -
-					(100 * (dfs_radars[p].rp_pulsevar)));
+		rf->rf_minpri = dfs_round((int32_t)T -
+				(100 * (dfs_radars[p].rp_pulsevar)));
 		Tmax = (100000000 / dfs_radars[p].rp_pulsefreq) -
 			100 * (dfs_radars[p].rp_meanoffset);
-		rf->rf_maxpri =
-			dfs_round((int32_t)Tmax +
-					(100 * (dfs_radars[p].rp_pulsevar)));
+		rf->rf_maxpri = dfs_round((int32_t)Tmax +
+				(100 * (dfs_radars[p].rp_pulsevar)));
 
 		if (rf->rf_minpri < ft->ft_minpri)
 			ft->ft_minpri = rf->rf_minpri;
 
-		rf->rf_fixed_pri_radar_pulse =
-			(dfs_radars[p].rp_max_pulsefreq ==
-	   dfs_radars[p].rp_pulsefreq) ?  1 : 0;
+		rf->rf_fixed_pri_radar_pulse = (
+				dfs_radars[p].rp_max_pulsefreq ==
+				dfs_radars[p].rp_pulsefreq) ?  1 : 0;
 		rf->rf_threshold = dfs_radars[p].rp_threshold;
 		rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses;
 
@@ -307,10 +360,8 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
 			min_rssithresh =
 				dfs->dfs_b5radars[n].br_pulse.b5_rssithresh;
 
-		if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur
-				> max_pulsedur)
-			max_pulsedur =
-				dfs->dfs_b5radars[n].br_pulse.b5_maxdur;
+		if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur > max_pulsedur)
+			max_pulsedur = dfs->dfs_b5radars[n].br_pulse.b5_maxdur;
 	}
 	dfs_reset_alldelaylines(dfs);
 	dfs_reset_radarq(dfs);
@@ -325,15 +376,12 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
 	 * Relax the max pulse duration a little bit due to inaccuracy
 	 * caused by chirping.
 	 */
-	dfs->dfs_rinfo.rn_maxpulsedur =
-		dfs->dfs_rinfo.rn_maxpulsedur + 20;
+	dfs->dfs_rinfo.rn_maxpulsedur = dfs->dfs_rinfo.rn_maxpulsedur + 20;
 
-	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
-			"DFS min filter rssiThresh = %d\n",
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS, "DFS min filter rssiThresh = %d\n",
 			min_rssithresh);
 
-	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
-			"DFS max pulse dur = %d ticks\n",
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS, "DFS max pulse dur = %d ticks\n",
 			dfs->dfs_rinfo.rn_maxpulsedur);
 
 	return 0;

+ 26 - 35
umac/dfs/core/src/filtering/dfs_misc.c

@@ -71,6 +71,30 @@ static int dfs_adjust_thresh_per_chan_busy(int ext_chan_busy, int thresh)
 	return adjust_thresh;
 }
 
+/**
+ * dfs_get_cached_ext_chan_busy() - Get cached ext chan busy.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @ext_chan_busy: Extension channel PRI.
+ */
+static inline void dfs_get_cached_ext_chan_busy(
+		struct wlan_dfs *dfs,
+		int *ext_chan_busy)
+{
+	*ext_chan_busy = 0;
+	/* Check to see if the cached value of ext_chan_busy can be used. */
+
+	if (dfs->dfs_rinfo.dfs_ext_chan_busy &&
+			(dfs->dfs_rinfo.rn_lastfull_ts <
+			 dfs->dfs_rinfo.ext_chan_busy_ts)) {
+		*ext_chan_busy = dfs->dfs_rinfo.dfs_ext_chan_busy;
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+				"Use cached copy of ext_chan_busy extchanbusy=%d rn_lastfull_ts=%llu ext_chan_busy_ts=%llu\n",
+				*ext_chan_busy,
+				(uint64_t)dfs->dfs_rinfo.rn_lastfull_ts,
+				(uint64_t)dfs->dfs_rinfo.ext_chan_busy_ts);
+	}
+}
+
 int dfs_get_pri_margin(struct wlan_dfs *dfs,
 		int is_extchan_detect,
 		int is_fixed_pattern)
@@ -90,21 +114,7 @@ int dfs_get_pri_margin(struct wlan_dfs *dfs,
 				lmac_get_tsf64(dfs->dfs_pdev_obj);
 			dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
 		} else {
-			/*
-			 * Check to see if the cached value of ext_chan_busy
-			 * can be used.
-			 */
-			ext_chan_busy = 0;
-			if (dfs->dfs_rinfo.dfs_ext_chan_busy) {
-				if (dfs->dfs_rinfo.rn_lastfull_ts <
-					dfs->dfs_rinfo.ext_chan_busy_ts) {
-					ext_chan_busy =
-					    dfs->dfs_rinfo.dfs_ext_chan_busy;
-					DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-						"PRI Use cached copy of ext_chan_busy extchanbusy=%d\n",
-						ext_chan_busy);
-				}
-			}
+			dfs_get_cached_ext_chan_busy(dfs, &ext_chan_busy);
 		}
 		adjust_pri = dfs_adjust_pri_per_chan_busy(ext_chan_busy,
 			pri_margin);
@@ -130,26 +140,7 @@ int dfs_get_filter_threshold(struct wlan_dfs *dfs,
 				lmac_get_tsf64(dfs->dfs_pdev_obj);
 			dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
 		} else {
-			/*
-			 * Check to see if the cached value of ext_chan_busy
-			 * can be used.
-			 */
-			ext_chan_busy = 0;
-			if (dfs->dfs_rinfo.dfs_ext_chan_busy) {
-				if (dfs->dfs_rinfo.rn_lastfull_ts <
-					dfs->dfs_rinfo.ext_chan_busy_ts) {
-					ext_chan_busy =
-					    dfs->dfs_rinfo.dfs_ext_chan_busy;
-					DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-						"THRESH Use cached copy of ext_chan_busy extchanbusy=%d rn_lastfull_ts=%llu ext_chan_busy_ts=%llu\n",
-						ext_chan_busy,
-						(uint64_t)
-						dfs->dfs_rinfo.rn_lastfull_ts,
-						(uint64_t)
-						dfs->dfs_rinfo.ext_chan_busy_ts
-						);
-				}
-			}
+			dfs_get_cached_ext_chan_busy(dfs, &ext_chan_busy);
 		}
 
 		adjust_thresh =

+ 57 - 65
umac/dfs/core/src/filtering/dfs_phyerr_tlv.c

@@ -255,6 +255,52 @@ static void dfs_radar_fft_search_report_parse(struct wlan_dfs *dfs,
 	}
 }
 
+/**
+ * dfs_check_for_false_detection() -  Check for possible false detection on
+ * beeliner this may also work for Cascade but parameters
+ * (e.g. AGC_MB_GAIN_THRESH1) may be different for Cascade.
+ * @dfs: pointer to wlan_dfs structure.
+ * @rs: pointer to rx_radar_status structure.
+ * @false_detect: Pointer to save false detect value.
+ * @rssi: RSSI.
+ */
+static inline void dfs_check_for_false_detection(
+		struct wlan_dfs *dfs,
+		struct rx_radar_status *rs,
+		bool *false_detect,
+		uint8_t rssi)
+{
+	bool is_ht160 = false;
+	bool is_false_detect = false;
+
+	is_ht160 = dfs->dfs_caps.wlan_chip_is_ht160;
+	is_false_detect = dfs->dfs_caps.wlan_chip_is_false_detect;
+
+	if ((dfs->dfs_caps.wlan_chip_is_over_sampled == 0) &&
+			(is_ht160 == 0 && is_false_detect)) {
+		if ((rs->agc_mb_gain > AGC_MB_GAIN_THRESH1) &&
+				((rs->agc_total_gain - rs->agc_mb_gain) <
+				 AGC_OTHER_GAIN_THRESH1)) {
+			*false_detect = true;
+		}
+
+		if ((rs->agc_mb_gain > AGC_MB_GAIN_THRESH2) &&
+				((rs->agc_total_gain - rs->agc_mb_gain) >
+				 AGC_OTHER_GAIN_THRESH2) &&
+				(rssi > AGC_GAIN_RSSI_THRESH)) {
+			*false_detect = true;
+		}
+	}
+
+	if (*false_detect)
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
+				"%s: setting false_detect to TRUE because of mb/total_gain/rssi, agc_mb_gain=%d, agc_total_gain=%d, rssi=%d\n",
+				__func__,
+				rs->agc_mb_gain,
+				rs->agc_total_gain,
+				rssi);
+}
+
 /**
  * dfs_tlv_parse_frame () - Parse a Peregrine BB TLV frame.
  * @dfs: pointer to wlan_dfs structure.
@@ -282,8 +328,6 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
 	uint32_t tlv_hdr[1];
 	bool first_tlv = true;
 	bool false_detect = false;
-	bool is_ht160 = false;
-	bool is_false_detect = false;
 
 	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
 			"%s: total length = %zu bytes\n",
@@ -335,47 +379,8 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
 			dfs_radar_summary_parse(dfs, buf + i,
 					MS(tlv_hdr[TLV_REG], TLV_LEN), rs);
 
-			/*
-			 * Check for possible false detection on
-			 * beeliner this may also work for Cascade but
-			 * parameters (e.g. AGC_MB_GAIN_THRESH1) may
-			 * be different for Cascade.
-			 */
-			is_ht160 = dfs->dfs_caps.wlan_chip_is_ht160;
-			is_false_detect =
-			    dfs->dfs_caps.wlan_chip_is_false_detect;
-
-			if ((dfs->dfs_caps.wlan_chip_is_over_sampled == 0) &&
-					(is_ht160 == 0 && is_false_detect)
-			   ) {
-				if ((rs->agc_mb_gain > AGC_MB_GAIN_THRESH1) &&
-					((rs->agc_total_gain - rs->agc_mb_gain)
-					 < AGC_OTHER_GAIN_THRESH1)) {
-					false_detect = true;
-					DFS_DPRINTK(dfs,
-						WLAN_DEBUG_DFS_PHYERR,
-						"%s: setting false_detect to TRUE because of mb/total_gain, agc_mb_gain=%d, agc_total_gain=%d, rssi=%d\n",
-						__func__,
-						rs->agc_mb_gain,
-						rs->agc_total_gain,
-						rssi);
-				}
-
-				if ((rs->agc_mb_gain > AGC_MB_GAIN_THRESH2) &&
-					((rs->agc_total_gain - rs->agc_mb_gain)
-					 > AGC_OTHER_GAIN_THRESH2) &&
-					(rssi > AGC_GAIN_RSSI_THRESH)
-				   ) {
-					false_detect = true;
-					DFS_DPRINTK(dfs,
-						WLAN_DEBUG_DFS_PHYERR,
-						"%s: setting false_detect to TRUE because of mb/total_gain/rssi, agc_mb_gain=%d, agc_total_gain=%d, rssi=%d\n",
-						__func__,
-						rs->agc_mb_gain,
-						rs->agc_total_gain,
-						rssi);
-				}
-			}
+			dfs_check_for_false_detection(dfs, rs, &false_detect,
+					rssi);
 			break;
 		case TAG_ID_SEARCH_FFT_REPORT:
 			dfs_radar_fft_search_report_parse(dfs, buf + i,
@@ -722,33 +727,20 @@ int dfs_process_phyerr_bb_tlv(struct wlan_dfs *dfs,
 
 	DFS_DPRINTK(dfs, WLAN_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\n",
-		__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,
+		__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);
 
 	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_FALSE_DET,
 		"ts=%u, dur=%d, rssi=%d, freq_offset=%d.%dMHz, is_chirp=%d, seg_id=%d, peak_mag=%d, total_gain=%d, mb_gain=%d, relpwr_db=%d\n",
-		e->rs_tstamp,
-		rs.pulse_duration,
-		rs.rssi,
+		e->rs_tstamp, rs.pulse_duration, rs.rssi,
 		(int)e->freq_offset_khz / 1000,
-		(int)abs(e->freq_offset_khz) % 1000,
-		(int)rs.is_chirp,
-		rsfr.seg_id,
-		rsfr.peak_mag,
-		rs.agc_total_gain,
-		rs.agc_mb_gain,
+		(int)abs(e->freq_offset_khz) % 1000, (int)rs.is_chirp,
+		rsfr.seg_id, rsfr.peak_mag, rs.agc_total_gain, rs.agc_mb_gain,
 		rsfr.relpwr_db);
 
 	return 1;

+ 125 - 88
umac/dfs/core/src/filtering/dfs_process_phyerr.c

@@ -162,11 +162,7 @@ int dfs_process_phyerr_owl(struct wlan_dfs *dfs,
 
 	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR_SUM,
 		"%s: rssi=%u dur=%u, freq=%d MHz, freq_lo=%d MHz, freq_hi=%d MHz\n",
-		__func__,
-		rssi,
-		dur,
-		e->freq/1000,
-		e->freq_lo/1000,
+		__func__, rssi, dur, e->freq/1000, e->freq_lo/1000,
 		e->freq_hi / 1000);
 
 	return 1;
@@ -266,8 +262,7 @@ int dfs_process_phyerr_sowl(struct wlan_dfs *dfs,
 		if (!pulse_bw_info) {
 			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
 				"ERROR channel dur=%u rssi=%u pulse_bw_info=0x%x datalen MOD 4 = %d\n",
-				dur, rssi, pulse_bw_info,
-				(datalen & 0x3));
+				dur, rssi, pulse_bw_info, (datalen & 0x3));
 			/*
 			 * Bogus bandwidth info received in descriptor, so
 			 * ignore this PHY error.
@@ -305,15 +300,8 @@ int dfs_process_phyerr_sowl(struct wlan_dfs *dfs,
 
 	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR_SUM,
 		"%s: pulse_bw_info=0x%x pulse_length_ext=%u pulse_length_pri=%u rssi=%u ext_rssi=%u, freq=%d MHz, freq_lo=%d MHz, freq_hi=%d MHz\n",
-		__func__,
-		pulse_bw_info,
-		pulse_length_ext,
-		pulse_length_pri,
-		rssi,
-		ext_rssi,
-		e->freq/1000,
-		e->freq_lo/1000,
-		e->freq_hi/1000);
+		__func__, pulse_bw_info, pulse_length_ext, pulse_length_pri,
+		rssi, ext_rssi, e->freq/1000, e->freq_lo/1000, e->freq_hi/1000);
 #undef EXT_CH_RADAR_FOUND
 #undef PRI_CH_RADAR_FOUND
 #undef EXT_CH_RADAR_EARLY_FOUND
@@ -354,8 +342,7 @@ int dfs_process_phyerr_merlin(struct wlan_dfs *dfs,
 	case 0x01:
 		/* Radar in ctrl channel */
 		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
-			"RAW RSSI: rssi=%u ext_rssi=%u\n",
-			rssi, ext_rssi);
+			"RAW RSSI: rssi=%u ext_rssi=%u\n", rssi, ext_rssi);
 		if (ext_rssi >= (rssi + 3)) {
 			/*
 			 * Cannot use ctrl channel RSSI if extension channel is
@@ -367,8 +354,7 @@ int dfs_process_phyerr_merlin(struct wlan_dfs *dfs,
 	case 0x02:
 		/* Radar in extension channel */
 		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
-			"RAW RSSI: rssi=%u ext_rssi=%u\n",
-			rssi, ext_rssi);
+			"RAW RSSI: rssi=%u ext_rssi=%u\n", rssi, ext_rssi);
 		if (rssi >= (ext_rssi + 12)) {
 			/*
 			 * Cannot use extension channel RSSI if control channel
@@ -435,6 +421,111 @@ static void dfs_dump_phyerr_contents(const char *d, int len)
 		DFS_PRINTK("%s: %s\n", __func__, buf);
 }
 
+/**
+ * dfs_bump_up_bin5_pulse_dur() - Bump up to a random BIN 5 pulse duration.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @e: Pointer to dfs_phy_err structure.
+ * @slope: Slope value.
+ */
+static inline void dfs_bump_up_bin5_pulse_dur(
+		struct wlan_dfs *dfs,
+		struct dfs_phy_err *e,
+		int slope)
+{
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR, "old dur %d slope =%d\n",
+			e->dur, slope);
+
+	e->is_sw_chirp = 1;
+	/* bump up to a random bin5 pulse duration */
+	if (e->dur < MIN_BIN5_DUR)
+		e->dur = dfs_get_random_bin5_dur(dfs, e->fulltsf);
+
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR, "new dur %d\n", e->dur);
+}
+
+/**
+ * dfs_filter_short_pulses() - Filter short pulses.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @e: Pointer to dfs_phy_err structure.
+ * @retval: Return value
+ *
+ * Rssi is not accurate for short pulses, so donot filter based on that for
+ * short duration pulses.
+ */
+static inline void dfs_filter_short_pulses(
+		struct wlan_dfs *dfs,
+		struct dfs_phy_err *e,
+		int *retval)
+{
+	if (dfs->dfs_caps.wlan_dfs_ext_chan_ok) {
+		if ((e->rssi < dfs->dfs_rinfo.rn_minrssithresh &&
+					(e->dur > MAX_DUR_FOR_LOW_RSSI)) ||
+				e->dur > (dfs->dfs_rinfo.rn_maxpulsedur)) {
+			dfs->wlan_dfs_stats.rssi_discards++;
+			*retval = 1;
+		}
+	} else if (e->rssi < dfs->dfs_rinfo.rn_minrssithresh ||
+			e->dur > dfs->dfs_rinfo.rn_maxpulsedur) {
+		dfs->wlan_dfs_stats.rssi_discards++;
+		*retval = 1;
+	}
+
+	if (*retval) {
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
+				"%s pulse is discarded: dur=%d, maxpulsedur=%d, rssi=%d, minrssi=%d\n",
+				(dfs->dfs_caps.wlan_dfs_ext_chan_ok) ?
+				"Extension channel" : "",
+				e->dur, dfs->dfs_rinfo.rn_maxpulsedur,
+				e->rssi, dfs->dfs_rinfo.rn_minrssithresh);
+	}
+}
+
+/**
+ * dfs_is_second_seg_radar_disabled() - Check for second segment radar disabled.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @seg_id: Segment id.
+ *
+ * Return: true if the second segment RADAR is enabled else false.
+ */
+static inline bool dfs_is_second_seg_radar_disabled(
+		struct wlan_dfs *dfs,
+		int seg_id)
+{
+	if ((seg_id == SEG_ID_SECONDARY) &&
+			!(dfs->dfs_proc_phyerr &
+				DFS_SECOND_SEGMENT_RADAR_EN)) {
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS3,
+				"%s: Do not process PHY error data from Second segment, DFS_SECOND_SEGMENT_RADAR_EN is not enabled\n",
+				__func__);
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * dfs_set_chan_index() - Set channel index.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @e: Pointer to dfs_phy_err structure.
+ * @event: Pointer to dfs_event structure.
+ */
+static inline void dfs_set_chan_index(
+		struct wlan_dfs *dfs,
+		struct dfs_phy_err *e,
+		struct dfs_event *event)
+{
+	if (e->is_pri) {
+		event->re_chanindex = dfs->dfs_curchan_radindex;
+	} else {
+		event->re_chanindex = dfs->dfs_extchan_radindex;
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
+				"%s %s New extension channel event is added to queue\n",
+				__func__,
+				(event->re_chanindex == -1) ?
+				"- phyerr on ext channel\n" : "");
+	}
+}
+
 void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
 		uint8_t r_rssi, uint8_t r_ext_rssi, uint32_t r_rs_tstamp,
 		uint64_t r_fulltsf)
@@ -595,16 +686,7 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
 					(e.is_pri ? 1 : 0),
 					(e.is_ext ? 1 : 0), &slope, &dc_found);
 			if (add_dur) {
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
-					"old dur %d slope =%d\n", e.dur, slope);
-				e.is_sw_chirp = 1;
-				/* bump up to a random bin5 pulse duration */
-				if (e.dur < MIN_BIN5_DUR) {
-					e.dur = dfs_get_random_bin5_dur(dfs,
-							e.fulltsf);
-				}
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
-					"new dur %d\n", e.dur);
+				dfs_bump_up_bin5_pulse_dur(dfs, &e, slope);
 			} else {
 				/* Set the duration so that it is rejected. */
 				e.is_sw_chirp = 0;
@@ -616,7 +698,7 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
 		} else {
 			/*
 			 * We have a pulse that is either bigger than
-			 * MAX_BIN5_DUR or * less than MAYBE_BIN5_DUR
+			 * MAX_BIN5_DUR or less than MAYBE_BIN5_DUR
 			 */
 			if ((dfs->dfsdomain == DFS_FCC_DOMAIN) ||
 					(dfs->dfsdomain == DFS_MKK4_DOMAIN)) {
@@ -654,8 +736,7 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
 	if ((dfs->dfs_curchan->dfs_ch_flags & CHANNEL_108G) == CHANNEL_108G) {
 		if (!(dfs->dfs_proc_phyerr & DFS_AR_EN)) {
 			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-				"%s: DFS_AR_EN not enabled\n",
-				__func__);
+				"%s: DFS_AR_EN not enabled\n", __func__);
 			return;
 		}
 		WLAN_DFSEVENTQ_LOCK(dfs);
@@ -663,8 +744,7 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
 		if (event == NULL) {
 			WLAN_DFSEVENTQ_UNLOCK(dfs);
 			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
-				"%s: no more events space left\n",
-				__func__);
+				"%s: no more events space left\n", __func__);
 			return;
 		}
 		STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list);
@@ -694,54 +774,22 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
 		      IEEE80211_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) &&
 		     IEEE80211_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan))) ||
 			(dfs_is_precac_timer_running(dfs))) {
+
+			int retval = 0;
+
 			if (!(dfs->dfs_proc_phyerr & DFS_RADAR_EN)) {
 				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS3,
 					"%s: DFS_RADAR_EN not enabled\n",
 					__func__);
 				return;
 			}
-			/*
-			 * Rssi is not accurate for short pulses, so donot
-			 * filter based on that for short duration pulses.
-			 */
-			if (dfs->dfs_caps.wlan_dfs_ext_chan_ok) {
-				if ((e.rssi < dfs->dfs_rinfo.rn_minrssithresh &&
-					    (e.dur > 4)) || e.dur >
-					(dfs->dfs_rinfo.rn_maxpulsedur)) {
-					dfs->wlan_dfs_stats.rssi_discards++;
-					DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
-						"Extension channel pulse is discarded: dur=%d, maxpulsedur=%d, rssi=%d, minrssi=%d\n",
-						e.dur,
-						dfs->dfs_rinfo.rn_maxpulsedur,
-						e.rssi,
-						dfs->dfs_rinfo.rn_minrssithresh
-						);
-					return;
-				}
-			} else {
-				if (e.rssi < dfs->dfs_rinfo.rn_minrssithresh ||
-						e.dur >
-						dfs->dfs_rinfo.rn_maxpulsedur) {
-					dfs->wlan_dfs_stats.rssi_discards++;
-					DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
-						"Pulse is discarded: dur=%d, maxpulsedur=%d, rssi=%d, minrssi=%d\n",
-						e.dur,
-						dfs->dfs_rinfo.rn_maxpulsedur,
-						e.rssi,
-						dfs->dfs_rinfo.rn_minrssithresh
-						);
-					return;
-				}
-			}
 
-			if ((e.seg_id == SEG_ID_SECONDARY) &&
-					!(dfs->dfs_proc_phyerr &
-						DFS_SECOND_SEGMENT_RADAR_EN)){
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS3,
-						"%s: Do not process PHY error data from Second segment, DFS_SECOND_SEGMENT_RADAR_EN is not enabled\n",
-						__func__);
+			dfs_filter_short_pulses(dfs, &e, &retval);
+			if (retval)
+				return;
+
+			if (dfs_is_second_seg_radar_disabled(dfs, e.seg_id))
 				return;
-			}
 
 			/* Add the event to the list, if there's space. */
 			WLAN_DFSEVENTQ_LOCK(dfs);
@@ -781,19 +829,8 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
 			}
 
 			/* Correctly set which channel is being reported on */
-			if (e.is_pri) {
-				event->re_chanindex = dfs->dfs_curchan_radindex;
-			} else {
-				if (dfs->dfs_extchan_radindex == -1) {
-					DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
-						"%s - phyerr on ext channel\n",
-						__func__);
-				}
-				event->re_chanindex = dfs->dfs_extchan_radindex;
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
-					"%s New extension channel event is added to queue\n",
-					__func__);
-			}
+			dfs_set_chan_index(dfs, &e, event);
+
 			WLAN_DFSQ_LOCK(dfs);
 			STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list);
 			WLAN_DFSQ_UNLOCK(dfs);

+ 735 - 459
umac/dfs/core/src/filtering/dfs_process_radarevent.c

@@ -47,6 +47,13 @@ static int debug_dup_cnt;
  * Peregrine reports the pulse duration in microseconds regardless of the
  * operating mode. (XXX TODO: verify this, obviously.)
  *
+ * The hardware returns the duration in a variety of formats,
+ * so it's converted from the hardware format to TSF (usec)
+ * values here.
+ * XXX TODO: this should really be done when the PHY error
+ * is processed, rather than way out here..
+ *
+ *
  * Return: Returns the duration.
  */
 static inline uint8_t dfs_process_pulse_dur(struct wlan_dfs *dfs,
@@ -84,31 +91,23 @@ static void dfs_print_radar_events(struct wlan_dfs *dfs)
 	int i;
 
 	DFS_PRINTK("%s:#Phyerr=%d, #false detect=%d, #queued=%d\n",
-		__func__,
-		dfs->dfs_phyerr_count,
-		dfs->dfs_phyerr_reject_count,
+		__func__, dfs->dfs_phyerr_count, dfs->dfs_phyerr_reject_count,
 		dfs->dfs_phyerr_queued_count);
 
 	DFS_PRINTK("%s:dfs_phyerr_freq_min=%d, dfs_phyerr_freq_max=%d\n",
-		__func__,
-		dfs->dfs_phyerr_freq_min,
-		dfs->dfs_phyerr_freq_max);
+		__func__, dfs->dfs_phyerr_freq_min, dfs->dfs_phyerr_freq_max);
 
 	DFS_PRINTK(
 		"%s:Total radar events detected=%d, entries in the radar queue follows:\n",
-		__func__,
-		dfs->dfs_event_log_count);
+		__func__, dfs->dfs_event_log_count);
 
 	for (i = 0; (i < DFS_EVENT_LOG_SIZE) && (i < dfs->dfs_event_log_count);
 			i++) {
 		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
 			"ts=%llu diff_ts=%u rssi=%u dur=%u, is_chirp=%d, seg_id=%d, sidx=%d, freq_offset=%d.%dMHz, peak_mag=%d, total_gain=%d, mb_gain=%d, relpwr_db=%d\n",
-			dfs->radar_log[i].ts,
-			dfs->radar_log[i].diff_ts,
-			dfs->radar_log[i].rssi,
-			dfs->radar_log[i].dur,
-			dfs->radar_log[i].is_chirp,
-			dfs->radar_log[i].seg_id,
+			dfs->radar_log[i].ts, dfs->radar_log[i].diff_ts,
+			dfs->radar_log[i].rssi, dfs->radar_log[i].dur,
+			dfs->radar_log[i].is_chirp, dfs->radar_log[i].seg_id,
 			dfs->radar_log[i].sidx,
 			(int)dfs->radar_log[i].freq_offset_khz/1000,
 			(int)abs(dfs->radar_log[i].freq_offset_khz)%1000,
@@ -125,9 +124,66 @@ static void dfs_print_radar_events(struct wlan_dfs *dfs)
 	dfs->dfs_phyerr_freq_max = 0;
 }
 
+/*
+ * dfs_reject_on_pri() - Rejecting on individual filter based on min PRI .
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rf: Pointer to dfs_filter structure.
+ * @deltaT: deltaT value.
+ * @this_ts: Timestamp.
+ */
+static inline bool dfs_reject_on_pri(
+		struct wlan_dfs *dfs,
+		struct dfs_filter *rf,
+		uint64_t deltaT,
+		uint64_t this_ts)
+{
+	if ((deltaT < rf->rf_minpri) && (deltaT != 0)) {
+		/* Second line of PRI filtering. */
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+				"filterID %d : Rejecting on individual filter min PRI deltaT=%lld rf->rf_minpri=%u\n",
+				rf->rf_pulseid, (uint64_t)deltaT,
+				rf->rf_minpri);
+		return 1;
+	}
+
+	if (rf->rf_ignore_pri_window > 0) {
+		if (deltaT < rf->rf_minpri) {
+			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+					"filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u\n",
+					rf->rf_pulseid, (uint64_t)deltaT,
+					rf->rf_minpri);
+			/* But update the last time stamp. */
+			rf->rf_dl.dl_last_ts = this_ts;
+			return 1;
+		}
+	} else {
+		/*
+		 * The HW may miss some pulses especially with
+		 * high channel loading. This is true for Japan
+		 * W53 where channel loaoding is 50%. Also for
+		 * ETSI where channel loading is 30% this can
+		 * be an issue too. To take care of missing
+		 * pulses, we introduce pri_margin multiplie.
+		 * This is normally 2 but can be higher for W53.
+		 */
+
+		if ((deltaT > (dfs->dfs_pri_multiplier * rf->rf_maxpri)) ||
+				(deltaT < rf->rf_minpri)) {
+			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+					"filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u\n",
+					rf->rf_pulseid, (uint64_t) deltaT,
+					rf->rf_minpri);
+			/* But update the last time stamp. */
+			rf->rf_dl.dl_last_ts = this_ts;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 void __dfs_process_radarevent(struct wlan_dfs *dfs,
 		struct dfs_filtertype *ft,
-		struct dfs_filter *rf,
 		struct dfs_event *re,
 		uint64_t this_ts,
 		int *found)
@@ -135,6 +191,7 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs,
 	int p;
 	uint64_t deltaT = 0;
 	int ext_chan_event_flag = 0;
+	struct dfs_filter *rf = NULL;
 
 	for (p = 0, *found = 0; (p < ft->ft_numfilters) &&
 			(!(*found)); p++) {
@@ -147,56 +204,9 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs,
 				    this_ts + 1) :
 			    this_ts - rf->rf_dl.dl_last_ts;
 
-			if ((deltaT < rf->rf_minpri) && (deltaT != 0)) {
-				/* Second line of PRI filtering. */
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-					"filterID %d : Rejecting on individual filter min PRI deltaT=%lld rf->rf_minpri=%u\n",
-					rf->rf_pulseid,
-					(uint64_t)deltaT,
-					rf->rf_minpri);
+			if (dfs_reject_on_pri(dfs, rf, deltaT, this_ts))
 				continue;
-			}
 
-			if (rf->rf_ignore_pri_window > 0) {
-				if (deltaT < rf->rf_minpri) {
-					DFS_DPRINTK(dfs,
-						WLAN_DEBUG_DFS2,
-						"filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u\n",
-						rf->rf_pulseid,
-						(uint64_t)
-						deltaT,
-						rf->rf_minpri);
-					/* But update the last time stamp. */
-					rf->rf_dl.dl_last_ts = this_ts;
-					continue;
-				}
-			} else {
-				/*
-				 * The HW may miss some pulses especially with
-				 * high channel loading. This is true for Japan
-				 * W53 where channel loaoding is 50%. Also for
-				 * ETSI where channel loading is 30% this can
-				 * be an issue too. To take care of missing
-				 * pulses, we introduce pri_margin multiplie.
-				 * This is normally 2 but can be higher for W53.
-				 */
-
-				if ((deltaT > (dfs->dfs_pri_multiplier *
-						rf->rf_maxpri)) ||
-					(deltaT < rf->rf_minpri)
-				   ) {
-					DFS_DPRINTK(dfs,
-						WLAN_DEBUG_DFS2,
-						"filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u\n",
-						rf->rf_pulseid,
-						(uint64_t)
-						deltaT,
-						rf->rf_minpri);
-					/* But update the last time stamp. */
-					rf->rf_dl.dl_last_ts = this_ts;
-					continue;
-				}
-			}
 			dfs_add_pulse(dfs, rf, re, deltaT, this_ts);
 
 			/*
@@ -220,28 +230,90 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs,
 			rf->rf_dl.dl_last_ts = this_ts;
 		}
 	}
+
+	if (*found) {
+		DFS_PRINTK("Found on channel minDur = %d, filterId = %d\n",
+				ft->ft_mindur,
+				rf != NULL ?  rf->rf_pulseid : -1);
+	}
+
+	return;
 }
 
-int dfs_process_radarevent(struct wlan_dfs *dfs,
-	struct dfs_ieee80211_channel *chan)
+/**
+ * dfs_radarfound_reset_vars() - Reset dfs variables after radar found
+ * @dfs: Pointer to wlan_dfs structure.
+ * @rs: Pointer to dfs_state.
+ * @chan: Current  channel.
+ */
+static inline void dfs_radarfound_reset_vars(
+		struct wlan_dfs *dfs,
+		struct dfs_state *rs,
+		struct dfs_ieee80211_channel *chan,
+		uint8_t   seg_id)
 {
-	struct dfs_event re, *event;
-	struct dfs_state *rs = NULL;
-	struct dfs_filtertype *ft;
-	struct dfs_filter *rf;
-	int found, retval = 0, p, empty;
-	int events_processed = 0;
-	uint32_t tabledepth, index;
-	uint64_t deltafull_ts = 0, this_ts, deltaT;
 	struct dfs_ieee80211_channel *thischan;
-	struct dfs_pulseline *pl;
-	static uint32_t  test_ts;
-	static uint32_t  diff_ts;
-	int i;
-	uint8_t   seg_id = 0;
 
-	pl = dfs->pulses;
+	/*
+	 * TODO: Instead of discarding the radar, create a workqueue
+	 * if the channel change is happenning through userspace and
+	 * process the radar event once the channel change is completed.
+	 */
+
+	/* Collect stats */
+	dfs->wlan_dfs_stats.num_radar_detects++;
+	thischan = &rs->rs_chan;
+	if ((seg_id == SEG_ID_SECONDARY) &&
+			(dfs_is_precac_timer_running(dfs))) {
+		dfs->is_radar_during_precac = 1;
+		DFS_PRINTK("Radar found on second segment VHT80 freq=%d MHz\n",
+				dfs->dfs_precac_secondary_freq);
+	} else {
+		DFS_PRINTK("Radar found on channel %d (%d MHz)\n",
+				thischan->dfs_ch_ieee, thischan->dfs_ch_freq);
+	}
+
+	/*
+	 * If event log is on then dump the radar event queue on
+	 * filter match. This can be used to collect information
+	 * on false radar detection.
+	 */
+	if (dfs->dfs_event_log_on)
+		dfs_print_radar_events(dfs);
+
+	dfs_reset_radarq(dfs);
+	dfs_reset_alldelaylines(dfs);
+
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
+			"Primary channel freq = %u flags=0x%x\n",
+			chan->dfs_ch_freq, chan->dfs_ch_flagext);
+
+	if (chan->dfs_ch_freq != thischan->dfs_ch_freq)
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
+				"Ext channel freq = %u flags=0x%x\n",
+				thischan->dfs_ch_freq,
+				thischan->dfs_ch_flagext);
+
+	dfs->dfs_phyerr_freq_min = 0x7fffffff;
+	dfs->dfs_phyerr_freq_max = 0;
+	dfs->dfs_phyerr_w53_counter = 0;
+	if (seg_id == SEG_ID_SECONDARY) {
+		dfs->wlan_dfs_stats.num_seg_two_radar_detects++;
+		dfs->is_radar_found_on_secondary_seg = 1;
+	}
+}
 
+/**
+ * dfs_radarevent_basic_sanity - Check basic sanity of the radar event
+ * @dfs: Pointer to wlan_dfs structure.
+ * @chan: Current channel.
+ * Return: If a radar event found on NON-DFS channel  return 0.  Otherwise,
+ * return 1.
+ */
+static inline int dfs_radarevent_basic_sanity(
+	struct wlan_dfs *dfs,
+	struct dfs_ieee80211_channel *chan)
+{
 	if (!(dfs->dfs_second_segment_bangradar ||
 				dfs_is_precac_timer_running(dfs)))
 		if (!(IEEE80211_IS_CHAN_DFS(chan) ||
@@ -249,28 +321,41 @@ int dfs_process_radarevent(struct wlan_dfs *dfs,
 			      IEEE80211_IS_CHAN_11AC_VHT80_80(chan)) &&
 			     IEEE80211_IS_CHAN_DFS_CFREQ2(chan)))) {
 			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-				"%s: radar event on non-DFS chan\n",
-				__func__);
+				"%s: radar event on non-DFS chan\n", __func__);
 			dfs_reset_radarq(dfs);
 			dfs_reset_alldelaylines(dfs);
 			dfs->dfs_bangradar = 0;
 			return 0;
 		}
 
-	/*
-	 * TEST : Simulate radar bang, make sure we add the channel to NOL
-	 * (bug 29968)
-	 */
+	return 1;
+}
+
+/**
+ * dfs_handle_bangradar - Handle the case of bangradar
+ * @dfs: Pointer to wlan_dfs structure.
+ * @chan: Current channel.
+ * @rs: Pointer to dfs_state.
+ * Return: if bangradar then  return 0.  Otherwise, return 1.
+ */
+static inline int dfs_handle_bangradar(
+	struct wlan_dfs *dfs,
+	struct dfs_ieee80211_channel *chan,
+	struct dfs_state **rs,
+	uint8_t *seg_id,
+	int *retval)
+{
+
 	if (dfs->dfs_bangradar) {
 		/*
 		 * Bangradar will always simulate radar found on the primary
 		 * channel.
 		 */
-		rs = &dfs->dfs_radar[dfs->dfs_curchan_radindex];
+		*rs = &dfs->dfs_radar[dfs->dfs_curchan_radindex];
 		dfs->dfs_bangradar = 0; /* Reset */
 		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS, "%s: bangradar\n", __func__);
-		retval = 1;
-		goto dfsfound;
+		*retval = 1;
+		return 1;
 	}
 
 	if (dfs->dfs_second_segment_bangradar) {
@@ -278,445 +363,636 @@ int dfs_process_radarevent(struct wlan_dfs *dfs,
 				IEEE80211_IS_CHAN_11AC_VHT160(chan) ||
 				IEEE80211_IS_CHAN_11AC_VHT80_80(chan)) {
 			dfs->is_radar_found_on_secondary_seg = 1;
-			rs = &dfs->dfs_radar[dfs->dfs_curchan_radindex];
+			*rs = &dfs->dfs_radar[dfs->dfs_curchan_radindex];
 			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
 					"%s: second segment bangradar on cfreq = %u\n",
 					__func__,
 					dfs->dfs_precac_secondary_freq);
-			retval = 1;
-			seg_id = SEG_ID_SECONDARY;
+			*retval = 1;
+			*seg_id = SEG_ID_SECONDARY;
 		} else {
 			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
 					"%s: Do not process the second segment bangradar\n",
 					__func__);
 		}
 		dfs->dfs_second_segment_bangradar = 0; /* Reset */
-		goto dfsfound;
+		return 1;
 	}
 
-	/*
-	 * The HW may miss some pulses especially with high channel loading.
-	 * This is true for Japan W53 where channel loaoding is 50%. Also
-	 * for ETSI where channel loading is 30% this can be an issue too.
-	 * To take care of missing pulses, we introduce pri_margin multiplie.
-	 * This is normally 2 but can be higher for W53.
-	 */
+	return 0;
+}
 
-	if ((dfs->dfsdomain  == DFS_MKK4_DOMAIN) &&
-		(dfs->dfs_caps.wlan_chip_is_bb_tlv) &&
-		(chan->dfs_ch_freq < FREQ_5500_MHZ)) {
+/**
+ * dfs_process_w53_pulses() - Prrocess w53 pulses
+ * @dfs: Pointer to wlan_dfs structure.
+ *
+ * For chips that support frequency information, we can relax PRI
+ * restriction if the frequency spread is narrow.
+ */
+static inline void dfs_process_w53_pulses(
+		struct wlan_dfs *dfs)
+{
+	if ((dfs->dfs_phyerr_freq_max - dfs->dfs_phyerr_freq_min) <
+			DFS_MAX_FREQ_SPREAD)
+		dfs->dfs_pri_multiplier = DFS_LARGE_PRI_MULTIPLIER;
+
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
+			"%s: w53_counter=%d, freq_max=%d, freq_min=%d, pri_multiplier=%d\n",
+			__func__, dfs->dfs_phyerr_w53_counter,
+			dfs->dfs_phyerr_freq_max, dfs->dfs_phyerr_freq_min,
+			dfs->dfs_pri_multiplier);
 
+	dfs->dfs_phyerr_freq_min = 0x7fffffff;
+	dfs->dfs_phyerr_freq_max = 0;
+}
+
+/**
+ * dfs_handle_missing_pulses - Handle the case of missing pulses
+ * @dfs: Pointer to wlan_dfs structure.
+ * @chan: Current channel.
+ *
+ * The HW may miss some pulses especially with high channel loading.
+ * This is true for Japan W53 where channel loaoding is 50%. Also
+ * for ETSI where channel loading is 30% this can be an issue too.
+ * To take care of missing pulses, we introduce pri_margin multiplie.
+ * This is normally 2 but can be higher for W53.
+ * Return: If not enough pulses return 0.  Otherwise, return 1.
+ */
+static inline int dfs_handle_missing_pulses(
+		struct wlan_dfs *dfs,
+		struct dfs_ieee80211_channel *chan)
+{
+	if ((dfs->dfsdomain  == DFS_MKK4_DOMAIN) &&
+			(dfs->dfs_caps.wlan_chip_is_bb_tlv) &&
+			(chan->dfs_ch_freq < FREQ_5500_MHZ)) {
 		dfs->dfs_pri_multiplier = DFS_W53_DEFAULT_PRI_MULTIPLIER;
 		/*
 		 * Do not process W53 pulses unless we have a minimum number
 		 * of them.
 		 */
-		if (dfs->dfs_phyerr_w53_counter >= 5) {
-			/*
-			 * For chips that support frequency information, we
-			 * can relax PRI restriction if the frequency spread
-			 * is narrow.
-			 */
-			if ((dfs->dfs_phyerr_freq_max -
-				    dfs->dfs_phyerr_freq_min) <
-				DFS_MAX_FREQ_SPREAD) {
-				dfs->dfs_pri_multiplier =
-				    DFS_LARGE_PRI_MULTIPLIER;
-			}
-
-			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
-				"%s: w53_counter=%d, freq_max=%d, freq_min=%d, pri_multiplier=%d\n",
-				__func__,
-				dfs->dfs_phyerr_w53_counter,
-				dfs->dfs_phyerr_freq_max,
-				dfs->dfs_phyerr_freq_min,
-				dfs->dfs_pri_multiplier);
-			dfs->dfs_phyerr_freq_min = 0x7fffffff;
-			dfs->dfs_phyerr_freq_max = 0;
-		} else {
+		if (dfs->dfs_phyerr_w53_counter >= 5)
+			dfs_process_w53_pulses(dfs);
+		else
 			return 0;
-		}
 	}
-	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
-			"%s: pri_multiplier=%d\n",
+
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1, "%s: pri_multiplier=%d\n",
 			__func__, dfs->dfs_pri_multiplier);
 
+	return 1;
+}
+
+/**
+ * dfs_is_radarq_empty - check if radarq is empty
+ * @dfs: Pointer to wlan_dfs structure.
+ * @empty: Pointer to empty
+ */
+static inline void dfs_is_radarq_empty(
+		struct wlan_dfs *dfs,
+		int *empty)
+{
 	WLAN_DFSQ_LOCK(dfs);
-	empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
+	*empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
 	WLAN_DFSQ_UNLOCK(dfs);
+}
 
-	while ((!empty) && (!retval) && (events_processed < MAX_EVENTS)) {
-		WLAN_DFSQ_LOCK(dfs);
-		event = STAILQ_FIRST(&(dfs->dfs_radarq));
-		if (event != NULL)
-			STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list);
-		WLAN_DFSQ_UNLOCK(dfs);
+/**
+ * dfs_remove_event_from_radarq - remove event from radarq
+ * @dfs: Pointer to wlan_dfs structure.
+ * @event: Double pointer to the event structure
+ */
+static inline void dfs_remove_event_from_radarq(
+		struct wlan_dfs *dfs,
+		struct dfs_event **event)
+{
+	WLAN_DFSQ_LOCK(dfs);
+	*event = STAILQ_FIRST(&(dfs->dfs_radarq));
+	if (*event != NULL)
+		STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list);
+	WLAN_DFSQ_UNLOCK(dfs);
+}
 
-		if (event == NULL) {
-			empty = 1;
-			break;
-		}
-		events_processed++;
-		re = *event;
+/**
+ * dfs_return_event_to_eventq - return event to eventq
+ * @dfs: Pointer to wlan_dfs structure.
+ * @event: Pointer to the event structure
+ */
+static inline void dfs_return_event_to_eventq(
+		struct wlan_dfs *dfs,
+		struct dfs_event *event)
+{
+	qdf_mem_zero(event, sizeof(struct dfs_event));
+	WLAN_DFSEVENTQ_LOCK(dfs);
+	STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list);
+	WLAN_DFSEVENTQ_UNLOCK(dfs);
+}
 
-		qdf_mem_zero(event, sizeof(struct dfs_event));
-		WLAN_DFSEVENTQ_LOCK(dfs);
-		STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list);
-		WLAN_DFSEVENTQ_UNLOCK(dfs);
+/**
+ * dfs_log_event - log dfs event
+ * @dfs: Pointer to wlan_dfs structure.
+ * @re:  Pointer to dfs_event re
+ * @this_ts: Current time stamp 64bit
+ * @diff_ts: Difference between 2 timestamps 32bit
+ */
+static inline void dfs_log_event(
+		struct wlan_dfs *dfs,
+		struct dfs_event *re,
+		uint64_t this_ts,
+		uint32_t diff_ts)
+{
+	uint8_t i;
+
+	if (dfs->dfs_event_log_on) {
+		i = dfs->dfs_event_log_count % DFS_EVENT_LOG_SIZE;
+		dfs->radar_log[i].ts = this_ts;
+		dfs->radar_log[i].diff_ts = diff_ts;
+		dfs->radar_log[i].rssi = (*re).re_rssi;
+		dfs->radar_log[i].dur = (*re).re_dur;
+		dfs->radar_log[i].seg_id = (*re).re_seg_id;
+		dfs->radar_log[i].sidx = (*re).re_sidx;
+		dfs->radar_log[i].freq_offset_khz =
+			(*re).re_freq_offset_khz;
+		dfs->radar_log[i].peak_mag = (*re).re_peak_mag;
+		dfs->radar_log[i].total_gain = (*re).re_total_gain;
+		dfs->radar_log[i].mb_gain = (*re).re_mb_gain;
+		dfs->radar_log[i].relpwr_db = (*re).re_relpwr_db;
+		dfs->radar_log[i].is_chirp = DFS_EVENT_NOTCHIRP(re) ?
+			0 : 1;
+		dfs->dfs_event_log_count++;
+	}
+}
 
-		seg_id = re.re_seg_id;
-		found = 0;
-		if (re.re_chanindex < DFS_NUM_RADAR_STATES)
-			rs = &dfs->dfs_radar[re.re_chanindex];
-		else {
-			WLAN_DFSQ_LOCK(dfs);
-			empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
-			WLAN_DFSQ_UNLOCK(dfs);
-			continue;
-		}
-		if (rs->rs_chan.dfs_ch_flagext & CHANNEL_INTERFERENCE) {
-			WLAN_DFSQ_LOCK(dfs);
-			empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
-			WLAN_DFSQ_UNLOCK(dfs);
+/**
+ * dfs_check_if_nonbin5 - Check if radar, other than bin5, is found
+ * @dfs: Pointer to wlan_dfs structure.
+ * @re: Pointer to re (radar event)
+ * @rs: Double Pointer to rs (radar state)
+ * @this_ts: Current time stamp 64bit
+ * @diff_ts: Difference between 2 timestamps 32bit
+ * @found: Pointer to found. If radar found or not.
+ * @retval: Pointer to retval(return value).
+ */
+static inline void dfs_check_if_nonbin5(
+	struct wlan_dfs *dfs,
+	struct dfs_event *re,
+	struct dfs_state **rs,
+	uint64_t this_ts,
+	uint32_t diff_ts,
+	int *found,
+	int *retval)
+{
+
+	uint32_t tabledepth = 0;
+	struct dfs_filtertype *ft;
+	uint64_t deltaT;
+
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
+			"  *** chan freq (%d): ts %llu dur %u rssi %u\n",
+			(*rs)->rs_chan.dfs_ch_freq, (uint64_t)this_ts,
+			(*re).re_dur, (*re).re_rssi);
+
+	while ((tabledepth < DFS_MAX_RADAR_OVERLAP) &&
+			((dfs->dfs_ftindextable[(*re).re_dur])[tabledepth] !=
+			 -1) && (!*retval)) {
+		ft = dfs->dfs_radarf[((dfs->dfs_ftindextable[(*re).re_dur])
+				[tabledepth])];
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+				"  ** RD (%d): ts %x dur %u rssi %u\n",
+				(*rs)->rs_chan.dfs_ch_freq, (*re).re_ts,
+				(*re).re_dur, (*re).re_rssi);
+
+		if ((*re).re_rssi < ft->ft_rssithresh &&
+				(*re).re_dur > MAX_DUR_FOR_LOW_RSSI) {
+			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+					"%s : Rejecting on rssi rssi=%u thresh=%u\n",
+					__func__, (*re).re_rssi,
+					ft->ft_rssithresh);
+			tabledepth++;
 			continue;
 		}
+		deltaT = this_ts - ft->ft_last_ts;
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+				"deltaT = %lld (ts: 0x%llx) (last ts: 0x%llx)\n",
+				(uint64_t)deltaT, (uint64_t)this_ts,
+				(uint64_t)ft->ft_last_ts);
 
-		if (dfs->dfs_rinfo.rn_lastfull_ts == 0) {
+		if ((deltaT < ft->ft_minpri) && (deltaT != 0)) {
 			/*
-			 * Either not started, or 64-bit rollover exactly to
-			 * zero Just prepend zeros to the 15-bit ts.
+			 * This check is for the whole filter type.
+			 * Individual filters will check this again.
+			 * This is first line of filtering.
 			 */
-			dfs->dfs_rinfo.rn_ts_prefix = 0;
-		} else {
-			/* WAR 23031- patch duplicate ts on very short pulses.
-			 * This pacth has two problems in linux environment.
-			 * 1)The time stamp created and hence PRI depends
-			 * entirely on the latency. If the latency is high, it
-			 * possibly can split two consecutive pulses in the
-			 * same burst so far away (the same amount of latency)
-			 * that make them look like they are from differenct
-			 * bursts. It is observed to happen too often. It sure
-			 * makes the detection fail.
-			 * 2)Even if the latency is not that bad, it simply
-			 * shifts the duplicate timestamps to a new duplicate
-			 * timestamp based on how they are processed.
-			 * This is not worse but not good either.
-			 * Take this pulse as a good one and create a probable
-			 * PRI later.
-			 */
-			if (re.re_dur == 0 && re.re_ts ==
-					dfs->dfs_rinfo.rn_last_unique_ts) {
-				debug_dup[debug_dup_cnt++] = '1';
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
-					"\n %s deltaT is 0\n", __func__);
-			} else {
-				dfs->dfs_rinfo.rn_last_unique_ts = re.re_ts;
-				debug_dup[debug_dup_cnt++] = '0';
-			}
-
-			if (debug_dup_cnt >= 32)
-				debug_dup_cnt = 0;
-
-			if (re.re_ts <= dfs->dfs_rinfo.rn_last_ts) {
-				dfs->dfs_rinfo.rn_ts_prefix +=
-					(((uint64_t) 1) << DFS_TSSHIFT);
-				/* Now, see if it's been more than 1 wrap */
-				deltafull_ts = re.re_full_ts -
-					dfs->dfs_rinfo.rn_lastfull_ts;
-				if (deltafull_ts >
-					((uint64_t)((DFS_TSMASK -
-						dfs->dfs_rinfo.rn_last_ts)
-					    + 1 + re.re_ts)))
-					deltafull_ts -= (DFS_TSMASK -
-						dfs->dfs_rinfo.rn_last_ts) + 1 +
-					    re.re_ts;
-				deltafull_ts = deltafull_ts >> DFS_TSSHIFT;
-
-				if (deltafull_ts > 1) {
-					dfs->dfs_rinfo.rn_ts_prefix +=
-						((deltafull_ts - 1) <<
-						 DFS_TSSHIFT);
-				}
-			} else {
-				deltafull_ts = re.re_full_ts -
-					dfs->dfs_rinfo.rn_lastfull_ts;
-				if (deltafull_ts > (uint64_t) DFS_TSMASK) {
-					deltafull_ts =
-					    deltafull_ts >> DFS_TSSHIFT;
-					dfs->dfs_rinfo.rn_ts_prefix +=
-					    ((deltafull_ts - 1) << DFS_TSSHIFT);
-				}
-			}
+			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
+					"%s: Rejecting on pri pri=%lld minpri=%u\n",
+					__func__, (uint64_t)deltaT,
+					ft->ft_minpri);
+			tabledepth++;
+			continue;
 		}
 
+		__dfs_process_radarevent(dfs, ft, re, this_ts, found);
+
+		ft->ft_last_ts = this_ts;
+		*retval |= *found;
+		tabledepth++;
+	}
+}
+
+/**
+ * dfs_check_each_b5radar() - Check each bin5 radar
+ * @dfs: Pointer to wlan_dfs structure.
+ * @re:  Pointer to re(radar event).
+ * @br: Pointer to dfs_bin5radars structure.
+ * @this_ts: Current time stamp 64bit.
+ * @diff_ts: Difference between 2 timestamps 32bit.
+ * @found: Pointer to found. If radar found or not.
+ */
+static inline void dfs_check_each_b5radar(
+		struct wlan_dfs *dfs,
+		struct dfs_event *re,
+		struct dfs_bin5radars *br,
+		uint64_t this_ts,
+		uint32_t diff_ts,
+		int *found)
+{
+	if (dfs_bin5_check_pulse(dfs, re, br)) {
 		/*
-		 * At this stage rn_ts_prefix has either been blanked or
-		 * calculated, so it's safe to use.
+		 * This is a valid Bin5 pulse, check if it belongs to a
+		 * burst.
 		 */
-		this_ts = dfs->dfs_rinfo.rn_ts_prefix | ((uint64_t) re.re_ts);
-		dfs->dfs_rinfo.rn_lastfull_ts = re.re_full_ts;
-		dfs->dfs_rinfo.rn_last_ts = re.re_ts;
-
+		(*re).re_dur = dfs_retain_bin5_burst_pattern(dfs, diff_ts,
+				(*re).re_dur);
 		/*
-		 * The hardware returns the duration in a variety of formats,
-		 * so it's converted from the hardware format to TSF (usec)
-		 * values here.
-		 * XXX TODO: this should really be done when the PHY error
-		 * is processed, rather than way out here..
+		 * Remember our computed duration for the next pulse in the
+		 * burst (if needed).
 		 */
-		re.re_dur = dfs_process_pulse_dur(dfs, re.re_dur);
+		dfs->dfs_rinfo.dfs_bin5_chirp_ts = this_ts;
+		dfs->dfs_rinfo.dfs_last_bin5_dur = (*re).re_dur;
+
+		if (dfs_bin5_addpulse(dfs, br, re, this_ts))
+			*found |= dfs_bin5_check(dfs);
+	} else {
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_BIN5_PULSE,
+				"%s not a BIN5 pulse (dur=%d)\n",
+				__func__, (*re).re_dur);
+	}
+}
+
+/**
+ * dfs_check_if_bin5() - Check if bin5 radar is found
+ * @dfs: Pointer to wlan_dfs structure.
+ * @re:  Pointer to re(radar event).
+ * @this_ts: Current time stamp 64bit.
+ * @diff_ts: Difference between 2 timestamps 32bit.
+ * @found: Pointer to found. If radar found or not.
+ */
+static inline void dfs_check_if_bin5(
+	struct wlan_dfs *dfs,
+	struct dfs_event *re,
+	uint64_t this_ts,
+	uint32_t diff_ts,
+	int *found)
+{
+	int p;
+
+	/* BIN5 pulses are FCC and Japan specific. */
+	if ((dfs->dfsdomain == DFS_FCC_DOMAIN) ||
+			(dfs->dfsdomain == DFS_MKK4_DOMAIN)) {
+		for (p = 0; (p < dfs->dfs_rinfo.rn_numbin5radars) && (!*found);
+				p++) {
+			struct dfs_bin5radars *br;
+
+			br = &(dfs->dfs_b5radars[p]);
+			dfs_check_each_b5radar(dfs, re, br, this_ts, diff_ts,
+					found);
+		}
+	}
+
+	if (*found)
+		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
+				"%s: Found bin5 radar\n", __func__);
+}
+
+/**
+ * dfs_skip_the_event() - Skip the Radar event
+ * @dfs: Pointer to wlan_dfs structure.
+ * @re: Pointer to re(radar event).
+ * @rs: Pointer to dfs_state.
+ */
+static inline bool dfs_skip_the_event(
+	struct wlan_dfs *dfs,
+	struct dfs_event *re,
+	struct dfs_state **rs)
+{
+	if ((*re).re_chanindex < DFS_NUM_RADAR_STATES)
+		(*rs) = &dfs->dfs_radar[(*re).re_chanindex];
+	else
+		return 1;
+
+	if ((*rs)->rs_chan.dfs_ch_flagext & CHANNEL_INTERFERENCE)
+		return 1;
+
+	return 0;
+}
+
+/**
+ * dfs_check_ts_wrap() - dfs check for timestamp wrap.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @re: Pointer to re(radar event).
+ * @deltafull_ts: Deltafull ts.
+ *
+ * Return: Deltafull ts.
+ */
+static inline uint64_t dfs_check_ts_wrap(
+		struct wlan_dfs *dfs,
+		struct dfs_event *re,
+		uint64_t deltafull_ts)
+{
+	if (deltafull_ts >
+			((uint64_t)((DFS_TSMASK -
+					dfs->dfs_rinfo.rn_last_ts) +
+				1 + (*re).re_ts)))
+		deltafull_ts -=
+			(DFS_TSMASK - dfs->dfs_rinfo.rn_last_ts) +
+			1 + (*re).re_ts;
+
+	return deltafull_ts;
+}
 
+/**
+ * dfs_calculate_ts_prefix() - Calculate deltafull ts value.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @re: Pointer to re(radar event).
+ */
+static inline void dfs_calculate_ts_prefix(
+		struct wlan_dfs *dfs,
+		struct dfs_event *re)
+{
+	uint64_t deltafull_ts;
+
+	if ((*re).re_ts <= dfs->dfs_rinfo.rn_last_ts) {
+		dfs->dfs_rinfo.rn_ts_prefix += (((uint64_t) 1) << DFS_TSSHIFT);
+		/* Now, see if it's been more than 1 wrap */
+		deltafull_ts = (*re).re_full_ts - dfs->dfs_rinfo.rn_lastfull_ts;
+		deltafull_ts = dfs_check_ts_wrap(dfs, re, deltafull_ts);
+		deltafull_ts >>= DFS_TSSHIFT;
+
+		if (deltafull_ts > 1)
+			dfs->dfs_rinfo.rn_ts_prefix +=
+				((deltafull_ts - 1) << DFS_TSSHIFT);
+	} else {
+		deltafull_ts = (*re).re_full_ts -
+			dfs->dfs_rinfo.rn_lastfull_ts;
+		if (deltafull_ts > (uint64_t) DFS_TSMASK) {
+			deltafull_ts >>= DFS_TSSHIFT;
+			dfs->dfs_rinfo.rn_ts_prefix +=
+				((deltafull_ts - 1) << DFS_TSSHIFT);
+		}
+	}
+}
+
+/**
+ * dfs_calculate_timestamps() - Calculate various timestamps
+ * @dfs: Pointer to wlan_dfs structure.
+ * @re: Pointer to re(radar event)
+ * @this_ts : Pointer to  this_ts (this timestamp)
+ */
+
+static inline void  dfs_calculate_timestamps(
+	struct wlan_dfs *dfs,
+	struct dfs_event *re,
+	uint64_t *this_ts)
+{
+	if (dfs->dfs_rinfo.rn_lastfull_ts == 0) {
 		/*
-		 * Calculate the start of the radar pulse.
-		 *
-		 * The TSF is stamped by the MAC upon reception of the event,
-		 * which is (typically?) at the end of the event. But the
-		 * pattern matching code expects the event timestamps to be at
-		 * the start of the event. So to fake it, we subtract the pulse
-		 * duration from the given TSF. This is done after the 64-bit
-		 * timestamp has been calculated so long pulses correctly
-		 * under-wrap the counter.  Ie, if this was done on the 32
-		 * (or 15!) bit TSF when the TSF value is closed to 0, it will
-		 * underflow to 0xfffffXX, which would mess up the logical "OR"
-		 * operation done above.
-		 * This isn't valid for Peregrine as the hardware gives us the
-		 * actual TSF offset of the radar event, not just the MAC TSF
-		 * of the completed receive.
-		 *
-		 * XXX TODO: ensure that the TLV PHY error processing code will
-		 * correctly calculate the TSF to be the start of the radar
-		 * pulse.
-		 *
-		 * XXX TODO TODO: modify the TLV parsing code to subtract the
-		 * duration from the TSF, based on the current fast clock value.
+		 * Either not started, or 64-bit rollover exactly to
+		 * zero Just prepend zeros to the 15-bit ts.
+		 */
+		dfs->dfs_rinfo.rn_ts_prefix = 0;
+	} else {
+		/* WAR 23031- patch duplicate ts on very short pulses.
+		 * This pacth has two problems in linux environment.
+		 * 1)The time stamp created and hence PRI depends
+		 * entirely on the latency. If the latency is high, it
+		 * possibly can split two consecutive pulses in the
+		 * same burst so far away (the same amount of latency)
+		 * that make them look like they are from differenct
+		 * bursts. It is observed to happen too often. It sure
+		 * makes the detection fail.
+		 * 2)Even if the latency is not that bad, it simply
+		 * shifts the duplicate timestamps to a new duplicate
+		 * timestamp based on how they are processed.
+		 * This is not worse but not good either.
+		 * Take this pulse as a good one and create a probable
+		 * PRI later.
 		 */
-		if ((!dfs->dfs_caps.wlan_chip_is_bb_tlv) && re.re_dur != 1)
-			this_ts -= re.re_dur;
+		if ((*re).re_dur == 0 && (*re).re_ts ==
+				dfs->dfs_rinfo.rn_last_unique_ts) {
+			debug_dup[debug_dup_cnt++] = '1';
+			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
+					"\n %s deltaT is 0\n", __func__);
+		} else {
+			dfs->dfs_rinfo.rn_last_unique_ts = (*re).re_ts;
+			debug_dup[debug_dup_cnt++] = '0';
+		}
 
-		/* Save the pulse parameters in the pulse buffer(pulse line). */
-		index = (pl->pl_lastelem + 1) & DFS_MAX_PULSE_BUFFER_MASK;
+		if (debug_dup_cnt >= 32)
+			debug_dup_cnt = 0;
 
-		if (pl->pl_numelems == DFS_MAX_PULSE_BUFFER_SIZE)
-			pl->pl_firstelem = (pl->pl_firstelem+1) &
-				DFS_MAX_PULSE_BUFFER_MASK;
-		else
-			pl->pl_numelems++;
+		dfs_calculate_ts_prefix(dfs, re);
+	}
 
-		pl->pl_lastelem = index;
-		pl->pl_elems[index].p_time = this_ts;
-		pl->pl_elems[index].p_dur = re.re_dur;
-		pl->pl_elems[index].p_rssi = re.re_rssi;
-		diff_ts = (uint32_t)this_ts - test_ts;
-		test_ts = (uint32_t)this_ts;
+	/*
+	 * At this stage rn_ts_prefix has either been blanked or
+	 * calculated, so it's safe to use.
+	 */
+	*this_ts = dfs->dfs_rinfo.rn_ts_prefix | ((uint64_t) (*re).re_ts);
+	dfs->dfs_rinfo.rn_lastfull_ts = (*re).re_full_ts;
+	dfs->dfs_rinfo.rn_last_ts = (*re).re_ts;
+}
 
-		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
+/**
+ * dfs_add_to_pulseline - Extract necessary items from dfs_event and
+ * add it as pulse in the pulseline
+ * @dfs: Pointer to wlan_dfs structure.
+ * @re:  Pointer to re(radar event)
+ * @this_ts : Pointer to  this_ts (this timestamp)
+ */
+static inline void dfs_add_to_pulseline(
+	struct wlan_dfs *dfs,
+	struct dfs_event *re,
+	uint64_t *this_ts,
+	uint32_t *test_ts,
+	uint32_t *diff_ts)
+{
+	uint32_t index;
+	struct dfs_pulseline *pl;
+
+	/*
+	 * Calculate the start of the radar pulse.
+	 *
+	 * The TSF is stamped by the MAC upon reception of the event,
+	 * which is (typically?) at the end of the event. But the
+	 * pattern matching code expects the event timestamps to be at
+	 * the start of the event. So to fake it, we subtract the pulse
+	 * duration from the given TSF. This is done after the 64-bit
+	 * timestamp has been calculated so long pulses correctly
+	 * under-wrap the counter.  Ie, if this was done on the 32
+	 * (or 15!) bit TSF when the TSF value is closed to 0, it will
+	 * underflow to 0xfffffXX, which would mess up the logical "OR"
+	 * operation done above.
+	 * This isn't valid for Peregrine as the hardware gives us the
+	 * actual TSF offset of the radar event, not just the MAC TSF
+	 * of the completed receive.
+	 *
+	 * XXX TODO: ensure that the TLV PHY error processing code will
+	 * correctly calculate the TSF to be the start of the radar
+	 * pulse.
+	 *
+	 * XXX TODO TODO: modify the TLV parsing code to subtract the
+	 * duration from the TSF, based on the current fast clock value.
+	 */
+	if ((!dfs->dfs_caps.wlan_chip_is_bb_tlv) && (*re).re_dur != 1)
+		*this_ts -= (*re).re_dur;
+
+	pl = dfs->pulses;
+	/* Save the pulse parameters in the pulse buffer(pulse line). */
+	index = (pl->pl_lastelem + 1) & DFS_MAX_PULSE_BUFFER_MASK;
+
+	if (pl->pl_numelems == DFS_MAX_PULSE_BUFFER_SIZE)
+		pl->pl_firstelem = (pl->pl_firstelem+1) &
+			DFS_MAX_PULSE_BUFFER_MASK;
+	else
+		pl->pl_numelems++;
+
+	pl->pl_lastelem = index;
+	pl->pl_elems[index].p_time = *this_ts;
+	pl->pl_elems[index].p_dur = (*re).re_dur;
+	pl->pl_elems[index].p_rssi = (*re).re_rssi;
+	*diff_ts = (uint32_t)*this_ts - *test_ts;
+	*test_ts = (uint32_t)*this_ts;
+
+	DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
 			"ts%u %u %u diff %u pl->pl_lastelem.p_time=%llu\n",
-			(uint32_t)this_ts, re.re_dur,
-			re.re_rssi, diff_ts,
+			(uint32_t)*this_ts, (*re).re_dur,
+			(*re).re_rssi, *diff_ts,
 			(uint64_t)pl->pl_elems[index].p_time);
+}
 
-		if (dfs->dfs_event_log_on) {
-			i = dfs->dfs_event_log_count % DFS_EVENT_LOG_SIZE;
-			dfs->radar_log[i].ts = this_ts;
-			dfs->radar_log[i].diff_ts = diff_ts;
-			dfs->radar_log[i].rssi = re.re_rssi;
-			dfs->radar_log[i].dur = re.re_dur;
-			dfs->radar_log[i].seg_id = re.re_seg_id;
-			dfs->radar_log[i].sidx = re.re_sidx;
-			dfs->radar_log[i].freq_offset_khz =
-				re.re_freq_offset_khz;
-			dfs->radar_log[i].peak_mag = re.re_peak_mag;
-			dfs->radar_log[i].total_gain = re.re_total_gain;
-			dfs->radar_log[i].mb_gain = re.re_mb_gain;
-			dfs->radar_log[i].relpwr_db = re.re_relpwr_db;
-			dfs->radar_log[i].is_chirp = DFS_EVENT_NOTCHIRP(&re) ?
-				0 : 1;
-			dfs->dfs_event_log_count++;
-		}
+/**
+ * dfs_conditional_clear_delaylines - Clear delay lines to remove  the
+ * false pulses.
+ * @dfs: Pointer to wlan_dfs structure.
+ * @diff_ts: diff between timerstamps
+ */
+static inline void dfs_conditional_clear_delaylines(
+	struct wlan_dfs *dfs,
+	uint32_t diff_ts)
+{
+	/* If diff_ts is very small, we might be getting false pulse
+	 * detects due to heavy interference. We might be getting
+	 * spectral splatter from adjacent channel. In order to prevent
+	 * false alarms we clear the delay-lines. This might impact
+	 * positive detections under harsh environments, but helps with
+	 * false detects.
+	 */
 
-		/* If diff_ts is very small, we might be getting false pulse
-		 * detects due to heavy interference. We might be getting
-		 * spectral splatter from adjacent channel. In order to prevent
-		 * false alarms we clear the delay-lines. This might impact
-		 * positive detections under harsh environments, but helps with
-		 * false detects.
-		 */
+	if (diff_ts < 100) {
+		dfs_reset_alldelaylines(dfs);
+		dfs_reset_radarq(dfs);
+	}
+}
+/**
+ * dfs_process_each_radarevent - remove each event from the dfs radar queue
+ * and process it.
+ * @dfs: Pointer to wlan_dfs structure.
+ * Return: If radar found then return 1 else return 0.
+ */
+static inline int dfs_process_each_radarevent(
+	struct wlan_dfs *dfs,
+	struct dfs_ieee80211_channel *chan,
+	struct dfs_state **rs,
+	uint8_t *seg_id,
+	int *retval)
+{
+	struct dfs_event re, *event;
+	int found, empty;
+	int events_processed = 0;
+	uint64_t this_ts;
+	static uint32_t  test_ts;
+	static uint32_t  diff_ts;
 
-		if (diff_ts < 100) {
-			dfs_reset_alldelaylines(dfs);
-			dfs_reset_radarq(dfs);
-		}
-		found = 0;
+	dfs_is_radarq_empty(dfs, &empty);
 
-		/* BIN5 pulses are FCC and Japan specific. */
-		if ((dfs->dfsdomain == DFS_FCC_DOMAIN) ||
-				(dfs->dfsdomain == DFS_MKK4_DOMAIN)) {
-			for (p = 0; (p < dfs->dfs_rinfo.rn_numbin5radars) &&
-					(!found); p++) {
-				struct dfs_bin5radars *br;
-
-				br = &(dfs->dfs_b5radars[p]);
-				if (dfs_bin5_check_pulse(dfs, &re, br)) {
-					/*
-					 * This is a valid Bin5 pulse, check if
-					 * it belongs to a burst.
-					 */
-					re.re_dur =
-					    dfs_retain_bin5_burst_pattern(dfs,
-						    diff_ts, re.re_dur);
-					/*
-					 * Remember our computed duration for
-					 * the next pulse in the burst
-					 * (if needed).
-					 */
-					dfs->dfs_rinfo.dfs_bin5_chirp_ts =
-						this_ts;
-					dfs->dfs_rinfo.dfs_last_bin5_dur =
-						re.re_dur;
-
-					if (dfs_bin5_addpulse(dfs, br, &re,
-								this_ts)) {
-						found |= dfs_bin5_check(dfs);
-					}
-				} else
-					DFS_DPRINTK(dfs,
-						WLAN_DEBUG_DFS_BIN5_PULSE,
-						"%s not a BIN5 pulse (dur=%d)\n",
-						__func__, re.re_dur);
-			}
+	while ((!empty) && (!*retval) && (events_processed < MAX_EVENTS)) {
+		dfs_remove_event_from_radarq(dfs, &event);
+		if (event == NULL) {
+			empty = 1;
+			break;
 		}
+		events_processed++;
+		re = *event;
 
-		if (found) {
-			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
-				"%s: Found bin5 radar\n", __func__);
-			retval |= found;
-			goto dfsfound;
+		dfs_return_event_to_eventq(dfs, event);
+
+		*seg_id = re.re_seg_id;
+		found = 0;
+		if (dfs_skip_the_event(dfs, &re, rs)) {
+			dfs_is_radarq_empty(dfs, &empty);
+			continue;
 		}
 
-		tabledepth = 0;
-		rf = NULL;
-		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
-			"  *** chan freq (%d): ts %llu dur %u rssi %u\n",
-			rs->rs_chan.dfs_ch_freq,
-			(uint64_t)this_ts,
-			re.re_dur,
-			re.re_rssi);
-
-		while ((tabledepth < DFS_MAX_RADAR_OVERLAP) &&
-				((dfs->dfs_radartable[re.re_dur])[tabledepth] !=
-				 -1) && (!retval)) {
-			ft = dfs->dfs_radarf[((dfs->dfs_radartable[re.re_dur])
-					[tabledepth])];
-			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-				"  ** RD (%d): ts %x dur %u rssi %u\n",
-				rs->rs_chan.dfs_ch_freq,
-				re.re_ts,
-				re.re_dur,
-				re.re_rssi);
+		dfs_calculate_timestamps(dfs, &re, &this_ts);
 
-			if (re.re_rssi < ft->ft_rssithresh && re.re_dur > 4) {
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-					"%s : Rejecting on rssi rssi=%u thresh=%u\n",
-					__func__,
-					re.re_rssi,
-					ft->ft_rssithresh);
-				tabledepth++;
-				WLAN_DFSQ_LOCK(dfs);
-				empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
-				WLAN_DFSQ_UNLOCK(dfs);
-				continue;
-			}
-			deltaT = this_ts - ft->ft_last_ts;
-			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-				"deltaT = %lld (ts: 0x%llx) (last ts: 0x%llx)\n",
-				(uint64_t)deltaT,
-				(uint64_t)this_ts,
-				(uint64_t)ft->ft_last_ts);
+		re.re_dur = dfs_process_pulse_dur(dfs, re.re_dur);
 
-			if ((deltaT < ft->ft_minpri) && (deltaT != 0)) {
-				/*
-				 * This check is for the whole filter type.
-				 * Individual filters will check this again.
-				 * This is first line of filtering.
-				 */
-				DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
-					"%s: Rejecting on pri pri=%lld minpri=%u\n",
-					__func__,
-					(uint64_t)deltaT,
-					ft->ft_minpri);
-				tabledepth++;
-				continue;
-			}
+		dfs_add_to_pulseline(dfs, &re, &this_ts, &test_ts, &diff_ts);
 
-			__dfs_process_radarevent(dfs, ft, rf, &re, this_ts,
-					&found);
-			ft->ft_last_ts = this_ts;
-			retval |= found;
-			if (found) {
-				DFS_PRINTK(
-					"Found on channel minDur = %d, filterId = %d\n",
-					ft->ft_mindur,
-					rf != NULL ?  rf->rf_pulseid : -1);
-			}
-			tabledepth++;
-		}
-		WLAN_DFSQ_LOCK(dfs);
-		empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
-		WLAN_DFSQ_UNLOCK(dfs);
-	}
-dfsfound:
-	if (retval) {
+		dfs_log_event(dfs, &re, this_ts, diff_ts);
 
-		/*
-		 * TODO: Instead of discarding the radar, create a workqueue
-		 * if the channel change is happenning through userspace and
-		 * process the radar event once the channel change is completed.
-		 */
+		dfs_conditional_clear_delaylines(dfs, diff_ts);
 
-		/* Collect stats */
-		dfs->wlan_dfs_stats.num_radar_detects++;
-		thischan = &rs->rs_chan;
-		if ((seg_id == SEG_ID_SECONDARY) &&
-				(dfs_is_precac_timer_running(dfs))) {
-			dfs->is_radar_during_precac = 1;
-			DFS_PRINTK(
-				"Radar found on second segment VHT80 freq=%d MHz\n",
-				dfs->dfs_precac_secondary_freq);
-		} else {
-			DFS_PRINTK(
-				"Radar found on channel %d (%d MHz)\n",
-				thischan->dfs_ch_ieee, thischan->dfs_ch_freq);
+		found = 0;
+		dfs_check_if_bin5(dfs, &re, this_ts, diff_ts, &found);
+		if (found) {
+			*retval |= found;
+			return 1;
 		}
 
-		/*
-		 * If event log is on then dump the radar event queue on
-		 * filter match. This can be used to collect information
-		 * on false radar detection.
-		 */
-		if (dfs->dfs_event_log_on)
-			dfs_print_radar_events(dfs);
+		dfs_check_if_nonbin5(dfs, &re, rs, this_ts, diff_ts, &found,
+				retval);
 
-		dfs_reset_radarq(dfs);
-		dfs_reset_alldelaylines(dfs);
+		dfs_is_radarq_empty(dfs, &empty);
+	}
 
-		DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
-			"Primary channel freq = %u flags=0x%x\n",
-			chan->dfs_ch_freq, chan->dfs_ch_flagext);
+	return 0;
+}
 
-		if (chan->dfs_ch_freq != thischan->dfs_ch_freq)
-			DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
-				"Ext channel freq = %u flags=0x%x\n",
-				thischan->dfs_ch_freq,
-				thischan->dfs_ch_flagext);
+int dfs_process_radarevent(
+	struct wlan_dfs *dfs,
+	struct dfs_ieee80211_channel *chan)
+{
+	struct dfs_state *rs = NULL;
+	uint8_t   seg_id = 0;
+	int retval = 0;
 
-		dfs->dfs_phyerr_freq_min = 0x7fffffff;
-		dfs->dfs_phyerr_freq_max = 0;
-		dfs->dfs_phyerr_w53_counter = 0;
-		if (seg_id == SEG_ID_SECONDARY) {
-			dfs->wlan_dfs_stats.num_seg_two_radar_detects++;
-			dfs->is_radar_found_on_secondary_seg = 1;
-		}
-	}
+	if (!dfs_radarevent_basic_sanity(dfs, chan))
+		return 0;
+	/*
+	 * TEST : Simulate radar bang, make sure we add the channel to NOL
+	 * (bug 29968)
+	 */
+	if (dfs_handle_bangradar(dfs, chan, &rs, &seg_id, &retval))
+		goto dfsfound;
+
+	if (!dfs_handle_missing_pulses(dfs, chan))
+		return 0;
+
+	dfs_process_each_radarevent(dfs, chan, &rs, &seg_id, &retval);
+
+dfsfound:
+	if (retval)
+		dfs_radarfound_reset_vars(dfs, rs, chan, seg_id);
 
 	return retval;
 }

+ 27 - 18
umac/dfs/core/src/filtering/dfs_radar.c

@@ -247,6 +247,32 @@ struct dfs_pulse dfs_korea_radars[] = {
 #define TARGET_TYPE_QCA9888   12
 #define RSSI_THERSH_AR900B    15
 
+/**
+ * dfs_assign_fcc_pulse_table() - Assign FCC pulse table
+ * @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
+ * @target_type: Target type.
+ */
+static inline void dfs_assign_fcc_pulse_table(
+		struct wlan_dfs_radar_tab_info *rinfo,
+		uint32_t target_type)
+{
+	rinfo->dfs_radars = dfs_fcc_radars;
+	rinfo->numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
+
+	if (target_type == TARGET_TYPE_AR900B ||
+			target_type == TARGET_TYPE_IPQ4019) {
+		rinfo->b5pulses = dfs_fcc_bin5pulses_ar900b;
+		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_ar900b);
+	} else if (target_type == TARGET_TYPE_QCA9984 ||
+			target_type == TARGET_TYPE_QCA9888) {
+		rinfo->b5pulses = dfs_fcc_bin5pulses_qca9984;
+		rinfo->numb5radars =
+			QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_qca9984);
+	} else {
+		rinfo->b5pulses = dfs_fcc_bin5pulses;
+		rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
+	}
+}
 void ol_if_dfs_configure(struct wlan_dfs *dfs)
 {
 	struct wlan_dfs_radar_tab_info rinfo;
@@ -284,24 +310,7 @@ void ol_if_dfs_configure(struct wlan_dfs *dfs)
 			rinfo.b5pulses = NULL;
 			rinfo.numb5radars = 0;
 		} else {
-			rinfo.dfs_radars = dfs_fcc_radars;
-			rinfo.numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
-
-			if (target_type == TARGET_TYPE_AR900B ||
-					target_type == TARGET_TYPE_IPQ4019) {
-				rinfo.b5pulses = dfs_fcc_bin5pulses_ar900b;
-				rinfo.numb5radars = QDF_ARRAY_SIZE(
-						dfs_fcc_bin5pulses_ar900b);
-			} else if (target_type == TARGET_TYPE_QCA9984 ||
-					target_type == TARGET_TYPE_QCA9888) {
-				rinfo.b5pulses = dfs_fcc_bin5pulses_qca9984;
-				rinfo.numb5radars = QDF_ARRAY_SIZE(
-						dfs_fcc_bin5pulses_qca9984);
-			} else {
-				rinfo.b5pulses = dfs_fcc_bin5pulses;
-				rinfo.numb5radars =
-					QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
-			}
+			dfs_assign_fcc_pulse_table(&rinfo, target_type);
 		}
 
 		break;

+ 18 - 21
umac/dfs/core/src/filtering/dfs_staggered.c

@@ -164,8 +164,13 @@ int dfs_staggered_check(struct wlan_dfs *dfs, struct dfs_filter *rf,
 		delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
 		refpri = dl->dl_elems[delayindex].de_time;
 
-		if ((score[n] >= highestscore) && (dfs_is_unique_pri(highestpri,
-				midpri, lowestpri, refpri))) {
+		if (!dfs_is_unique_pri(highestpri,
+					midpri,
+					lowestpri,
+					refpri))
+			continue;
+
+		if (score[n] >= highestscore) {
 			lowestscore = midscore;
 			lowestpri = midpri;
 			lowestscoreindex = midscoreindex;
@@ -175,25 +180,17 @@ int dfs_staggered_check(struct wlan_dfs *dfs, struct dfs_filter *rf,
 			highestscore = score[n];
 			highestpri = refpri;
 			highestscoreindex = n;
-		} else {
-			if ((score[n] >= midscore) &&
-					(dfs_is_unique_pri(highestpri, midpri,
-							   lowestpri, refpri))
-					) {
-				lowestscore = midscore;
-				lowestpri = midpri;
-				lowestscoreindex = midscoreindex;
-				midscore = score[n];
-				midpri = refpri;
-				midscoreindex = n;
-			} else if ((score[n] >= lowestscore) &&
-					(dfs_is_unique_pri(highestpri, midpri,
-							   lowestpri, refpri))
-					) {
-				lowestscore = score[n];
-				lowestpri = refpri;
-				lowestscoreindex = n;
-			}
+		} else if (score[n] >= midscore) {
+			lowestscore = midscore;
+			lowestpri = midpri;
+			lowestscoreindex = midscoreindex;
+			midscore = score[n];
+			midpri = refpri;
+			midscoreindex = n;
+		} else if (score[n] >= lowestscore) {
+			lowestscore = score[n];
+			lowestpri = refpri;
+			lowestscoreindex = n;
 		}
 	}
 

+ 12 - 12
umac/dfs/core/src/misc/dfs.c

@@ -233,17 +233,17 @@ int dfs_main_attach(struct wlan_dfs *dfs)
 	}
 
 	/* Allocate memory for radar table. */
-	dfs->dfs_radartable = (int8_t **)qdf_mem_malloc(256*sizeof(int8_t *));
-	if (dfs->dfs_radartable == NULL) {
+	dfs->dfs_ftindextable = (int8_t **)qdf_mem_malloc(256*sizeof(int8_t *));
+	if (dfs->dfs_ftindextable == NULL) {
 		DFS_PRINTK(
 				"%s: Cannot allocate memory for radar table\n",
 				__func__);
 		goto bad1;
 	}
 	for (n = 0; n < 256; n++) {
-		dfs->dfs_radartable[n] = qdf_mem_malloc(
+		dfs->dfs_ftindextable[n] = qdf_mem_malloc(
 				DFS_MAX_RADAR_OVERLAP*sizeof(int8_t));
-		if (dfs->dfs_radartable[n] == NULL) {
+		if (dfs->dfs_ftindextable[n] == NULL) {
 			DFS_PRINTK(
 					"%s: cannot allocate memory for radar table entry\n",
 					__func__);
@@ -290,8 +290,8 @@ int dfs_main_attach(struct wlan_dfs *dfs)
 	return 0;
 
 bad2:
-	qdf_mem_free(dfs->dfs_radartable);
-	dfs->dfs_radartable = NULL;
+	qdf_mem_free(dfs->dfs_ftindextable);
+	dfs->dfs_ftindextable = NULL;
 bad1:
 	for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
 		if (dfs->dfs_radarf[n] != NULL) {
@@ -391,15 +391,15 @@ void dfs_main_detach(struct wlan_dfs *dfs)
 		}
 	}
 
-	if (dfs->dfs_radartable != NULL) {
+	if (dfs->dfs_ftindextable != NULL) {
 		for (n = 0; n < 256; n++) {
-			if (dfs->dfs_radartable[n] != NULL) {
-				qdf_mem_free(dfs->dfs_radartable[n]);
-				dfs->dfs_radartable[n] = NULL;
+			if (dfs->dfs_ftindextable[n] != NULL) {
+				qdf_mem_free(dfs->dfs_ftindextable[n]);
+				dfs->dfs_ftindextable[n] = NULL;
 			}
 		}
-		qdf_mem_free(dfs->dfs_radartable);
-		dfs->dfs_radartable = NULL;
+		qdf_mem_free(dfs->dfs_ftindextable);
+		dfs->dfs_ftindextable = NULL;
 		dfs->wlan_dfs_isdfsregdomain = 0;
 	}