Bladeren bron

qcacmn: Refine chirp check for ETSI type 4 radar

Currently if the delta peak of the ETSI type 4 radar pulse is 0, it will
be considered as radar false dection, which affects normal dfs ETSI type
4 certification test.

More checks are added when delta peak of the ETSI type 4 radar pulse is 0.
If psidx_diff, the difference in the FFT peak index between the short FFT
and the first long FFT, is greater than 4 and less than 16, it is still
considered as valid ETSI type 4 radar pulse.

Change-Id: Iee9c22e0c208023bb9f0f70121f8269169b63d18
CRs-Fixed: 2173576
bings 7 jaren geleden
bovenliggende
commit
3a7cf9b158

+ 21 - 0
umac/dfs/core/src/dfs.h

@@ -262,6 +262,11 @@
 #define DFS_NO_FAST_CLOCK_MULTIPLIER (80)
 #define DFS_BIG_SIDX 10000
 
+/* Min value of valid psidx diff */
+#define DFS_MIN_PSIDX_DIFF 4
+/* Max value of valid psidx diff */
+#define DFS_MAX_PSIDX_DIFF 16
+
 /**
  * Software use: channel interference used for as AR as well as RADAR
  * interference detection.
@@ -368,6 +373,8 @@
  * @p_seg_id:      Segment id.
  * @p_sidx:        Sidx value.
  * @p_delta_peak:  Delta peak value.
+ * @p_psidx_diff:  The difference in the FFT peak index between the short FFT
+ *                 and the first long FFT.
  * @p_seq_num:     Sequence number.
  */
 struct dfs_pulseparams {
@@ -377,6 +384,7 @@ struct dfs_pulseparams {
 	uint8_t  p_seg_id;
 	int16_t  p_sidx;
 	int8_t   p_delta_peak;
+	int16_t  p_psidx_diff;
 	uint32_t p_seq_num;
 } qdf_packed;
 
@@ -397,6 +405,8 @@ struct dfs_pulseline {
 #define DFS_EVENT_CHECKCHIRP  0x01 /* Whether to check the chirp flag */
 #define DFS_EVENT_HW_CHIRP    0x02 /* hardware chirp */
 #define DFS_EVENT_SW_CHIRP    0x04 /* software chirp */
+/* Whether the event contains valid psidx diff value*/
+#define DFS_EVENT_VALID_PSIDX_DIFF 0x08
 
 /* Use this only if the event has CHECKCHIRP set. */
 #define DFS_EVENT_ISCHIRP(e) \
@@ -431,6 +441,7 @@ struct dfs_pulseline {
  * @re_relpwr_db:        Relpower in db.
  * @re_delta_diff:       Delta diff.
  * @re_delta_peak:       Delta peak.
+ * @re_psidx_diff:       Psidx diff.
  * @re_list:             List of radar events.
  */
 struct dfs_event {
@@ -452,6 +463,7 @@ struct dfs_event {
 	int       re_relpwr_db;
 	uint8_t   re_delta_diff;
 	int8_t    re_delta_peak;
+	int16_t   re_psidx_diff;
 
 	STAILQ_ENTRY(dfs_event) re_list;
 } qdf_packed;
@@ -506,6 +518,7 @@ struct dfs_ar_state {
  * @de_seg_id:     Segment id for HT80_80/HT160 use.
  * @de_sidx:       Sidx value.
  * @de_delta_peak: Delta peak.
+ * @de_psidx_diff: Psidx diff.
  * @de_seq_num:    Sequence number.
  */
 struct dfs_delayelem {
@@ -516,6 +529,7 @@ struct dfs_delayelem {
 	uint8_t  de_seg_id;
 	int16_t  de_sidx;
 	int8_t   de_delta_peak;
+	int16_t  de_psidx_diff;
 	uint32_t de_seq_num;
 } qdf_packed;
 
@@ -545,6 +559,8 @@ struct dfs_delayelem {
  *                     Used for sidx spread check.
  * @dl_delta_peak_match_count: Number of pulse in the delay line that had valid
  *                             delta peak value.
+ * @dl_psidx_diff_match_count: Number of pulse in the delay line that had valid
+ *                             psidx diff value.
  */
 struct dfs_delayline {
 	struct dfs_delayelem dl_elems[DFS_MAX_DL_SIZE];
@@ -559,6 +575,7 @@ struct dfs_delayline {
 	int16_t  dl_min_sidx;
 	int8_t   dl_max_sidx;
 	uint8_t  dl_delta_peak_match_count;
+	uint8_t  dl_psidx_diff_match_count;
 } qdf_packed;
 
 /**
@@ -795,6 +812,7 @@ struct dfs_stats {
  * @relpwr_db:        Relpower in db.
  * @delta_diff:       Delta diff.
  * @delta_peak:       Delta peak.
+ * @psidx_diff:       Psidx diff.
  */
 
 struct dfs_event_log {
@@ -812,6 +830,7 @@ struct dfs_event_log {
 	int       relpwr_db;
 	uint8_t   delta_diff;
 	int8_t    delta_peak;
+	int16_t   psidx_diff;
 };
 
 #define WLAN_DFS_RESET_TIME_S 7
@@ -1161,6 +1180,7 @@ enum {
  * @relpwr_db:           Relpower in DB.
  * @pulse_delta_diff:    Pulse delta diff.
  * @pulse_delta_peak:    Pulse delta peak.
+ * @pulse_psidx_diff:    Pulse psidx diff.
  *
  * Chirp notes!
  *
@@ -1230,6 +1250,7 @@ struct dfs_phy_err {
 	int      relpwr_db;
 	uint8_t  pulse_delta_diff;
 	int8_t   pulse_delta_peak;
+	int16_t  pulse_psidx_diff;
 };
 
 /**

+ 25 - 5
umac/dfs/core/src/filtering/dfs_bindetects.c

@@ -292,6 +292,7 @@ void dfs_add_pulse(
 	dl->dl_elems[index].de_seg_id = re->re_seg_id;
 	dl->dl_elems[index].de_sidx = re->re_sidx;
 	dl->dl_elems[index].de_delta_peak = re->re_delta_peak;
+	dl->dl_elems[index].de_psidx_diff = re->re_psidx_diff;
 	dl->dl_elems[index].de_seq_num = dfs->dfs_seq_num;
 
 	dfs_debug(dfs, WLAN_DEBUG_DFS2,
@@ -681,6 +682,7 @@ int dfs_bin_check(
  * @sidx_min: Sidx min.
  * @sidx_max: Sidx max.
  * @delta_peak_match_count: Delta peak match count.
+ * @psidx_diff_match_count: Psidx diff match count.
  * @rf: Pointer to dfs_filter structure.
  */
 static inline void dfs_update_min_and_max_sidx(
@@ -689,6 +691,7 @@ static inline void dfs_update_min_and_max_sidx(
 		int32_t *sidx_min,
 		int32_t *sidx_max,
 		uint8_t *delta_peak_match_count,
+		uint8_t *psidx_diff_match_count,
 		struct dfs_filter *rf)
 {
 	/* update sidx min/max for false detection check later */
@@ -698,9 +701,15 @@ static inline void dfs_update_min_and_max_sidx(
 	if (*sidx_max < dl->dl_elems[delayindex].de_sidx)
 		*sidx_max = dl->dl_elems[delayindex].de_sidx;
 
-	if ((rf->rf_check_delta_peak) &&
-			(dl->dl_elems[delayindex].de_delta_peak != 0))
-		(*delta_peak_match_count)++;
+	if (rf->rf_check_delta_peak) {
+		if (dl->dl_elems[delayindex].de_delta_peak != 0)
+			(*delta_peak_match_count)++;
+		else if ((dl->dl_elems[delayindex].de_psidx_diff >=
+				DFS_MIN_PSIDX_DIFF) &&
+			(dl->dl_elems[delayindex].de_psidx_diff <=
+				DFS_MAX_PSIDX_DIFF))
+			(*psidx_diff_match_count)++;
+	}
 }
 
 /**
@@ -715,6 +724,7 @@ static inline void dfs_update_min_and_max_sidx(
  * @sidx_min: Sidx min.
  * @sidx_max: Sidx max.
  * @delta_peak_match_count: Delta peak match count.
+ * @psidx_diff_match_count: Psidx diff match count.
  * @dl: Pointer to dfs_delayline structure.
  */
 static inline void dfs_check_pulses_for_delta_variance(
@@ -728,6 +738,7 @@ static inline void dfs_check_pulses_for_delta_variance(
 		int32_t *sidx_min,
 		int32_t *sidx_max,
 		uint8_t *delta_peak_match_count,
+		uint8_t *psidx_diff_match_count,
 		struct dfs_delayline *dl)
 {
 	uint32_t delta_ts_variance, j;
@@ -741,6 +752,7 @@ static inline void dfs_check_pulses_for_delta_variance(
 			dfs_update_min_and_max_sidx(dl, delayindex,
 					sidx_min, sidx_max,
 					delta_peak_match_count,
+					psidx_diff_match_count,
 					rf);
 			(*numpulses)++;
 			if (rf->rf_ignore_pri_window > 0)
@@ -761,6 +773,7 @@ static inline void dfs_check_pulses_for_delta_variance(
  * @durmargin: Duration margin.
  * @numpulses: Number of pulses.
  * @delta_peak_match_count: Pointer to delta_peak_match_count.
+ * @psidx_diff_match_count: Pointer to psidx_diff_match_count.
  * @prev_good_timestamp: Previous good timestamp.
  * @fundamentalpri: Highest PRI.
  */
@@ -775,6 +788,7 @@ static void dfs_count_the_other_delay_elements(
 		uint32_t durmargin,
 		int *numpulses,
 		uint8_t *delta_peak_match_count,
+		uint8_t *psidx_diff_match_count,
 		uint32_t *prev_good_timestamp,
 		int fundamentalpri)
 {
@@ -822,6 +836,7 @@ static void dfs_count_the_other_delay_elements(
 			dfs_update_min_and_max_sidx(dl, delayindex,
 					&sidx_min, &sidx_max,
 					delta_peak_match_count,
+					psidx_diff_match_count,
 					rf);
 			(*numpulses)++;
 		} else {
@@ -842,6 +857,7 @@ static void dfs_count_the_other_delay_elements(
 					primargin, numpulses, delayindex,
 					&sidx_min, &sidx_max,
 					delta_peak_match_count,
+					psidx_diff_match_count,
 					dl);
 		}
 		*prev_good_timestamp = dl->dl_elems[delayindex].de_ts;
@@ -849,11 +865,13 @@ static void dfs_count_the_other_delay_elements(
 		dl->dl_min_sidx = sidx_min;
 		dl->dl_max_sidx = sidx_max;
 		dl->dl_delta_peak_match_count = *delta_peak_match_count;
+		dl->dl_psidx_diff_match_count = *psidx_diff_match_count;
 
 		dfs_debug(dfs, WLAN_DEBUG_DFS2,
-			"rf->minpri=%d rf->maxpri=%d searchpri = %d index = %d numpulses = %d delta peak match count = %d deltapri=%d j=%d",
+			"rf->minpri=%d rf->maxpri=%d searchpri = %d index = %d numpulses = %d delta peak match count = %d psidx diff match count = %d deltapri=%d j=%d",
 			rf->rf_minpri, rf->rf_maxpri, searchpri, i,
-			*numpulses, *delta_peak_match_count, deltapri, j);
+			*numpulses, *delta_peak_match_count,
+			*psidx_diff_match_count, deltapri, j);
 	}
 }
 
@@ -879,6 +897,7 @@ int dfs_bin_pri_check(
 	 */
 	int numpulses = 1;
 	uint8_t delta_peak_match_count = 1;
+	uint8_t psidx_diff_match_count = 1;
 	int priscorechk = 1;
 
 	/* Use the adjusted PRI margin to reduce false alarms
@@ -940,6 +959,7 @@ int dfs_bin_pri_check(
 		dfs_count_the_other_delay_elements(dfs, rf, dl, i, refpri,
 				refdur, primargin, durmargin, &numpulses,
 				&delta_peak_match_count,
+				&psidx_diff_match_count,
 				&prev_good_timestamp, fundamentalpri);
 
 	return numpulses;

+ 4 - 3
umac/dfs/core/src/filtering/dfs_debug.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2018 The Linux Foundation. All rights reserved.
  * Copyright (c) 2002-2010, Atheros Communications Inc.
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -29,10 +29,11 @@ void dfs_print_delayline(struct wlan_dfs *dfs, struct dfs_delayline *dl)
 	for (i = 0; i < dl->dl_numelems; i++) {
 		de = &dl->dl_elems[index];
 		dfs_debug(dfs, WLAN_DEBUG_DFS2,
-				"Elem %u: ts=%llu diff_ts=%u (0x%x) dur=%u, seg_id=%d sidx=%d delta_peak=%d seq_num=%d",
+				"Elem %u: ts=%llu diff_ts=%u (0x%x) dur=%u, seg_id=%d sidx=%d delta_peak=%d psidx_diff=%d seq_num=%d",
 				i, de->de_ts, de->de_time, de->de_time,
 				de->de_dur, de->de_seg_id, de->de_sidx,
-				de->de_delta_peak, de->de_seq_num);
+				de->de_delta_peak, de->de_psidx_diff,
+				de->de_seq_num);
 
 		index = (index + 1) & DFS_MAX_DL_MASK;
 	}

+ 35 - 9
umac/dfs/core/src/filtering/dfs_phyerr_tlv.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012, 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -295,6 +295,7 @@ static inline void dfs_check_for_false_detection(
  * @len: Phyerr buflen.
  * @rssi: RSSI.
  * @first_short_fft_peak_mag: first short FFT peak_mag.
+ * @psidx_diff: Pointer to psidx diff.
  *
  * This routine parses each TLV, prints out what's going on and calls an
  * appropriate sub-function. Since the TLV format doesn't _specify_ all TLV
@@ -307,13 +308,17 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
 		const char *buf,
 		size_t len,
 		uint8_t rssi,
-		int *first_short_fft_peak_mag)
+		int *first_short_fft_peak_mag,
+		int16_t *psidx_diff)
 {
 	int i = 0;
 	uint32_t tlv_hdr[1];
-	bool first_tlv = true;
 	bool false_detect = false;
+	/* total search FFT reports including short and long */
+	int8_t sfr_count = 0;
+	int16_t first_short_fft_psidx = 0;
 
+	*psidx_diff = 0;
 	dfs_debug(dfs, WLAN_DEBUG_DFS_PHYERR,
 			"total length = %zu bytes", len);
 	while ((i < len) && (false_detect == false)) {
@@ -363,6 +368,7 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
 					rssi);
 			break;
 		case TAG_ID_SEARCH_FFT_REPORT:
+			sfr_count++;
 			dfs_radar_fft_search_report_parse(dfs, buf + i,
 					MS(tlv_hdr[TLV_REG], TLV_LEN), rsfr);
 
@@ -372,8 +378,10 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
 			 * BB_srch_fft_ctrl_4.radar_fft_short_rpt_scl is set to
 			 * 0.
 			 */
-			if (first_tlv)
+			if (sfr_count == 1) {
 				*first_short_fft_peak_mag = rsfr->peak_mag;
+				first_short_fft_psidx = rsfr->peak_sidx;
+			}
 
 			/*
 			 * Check for possible false detection on Peregrine.
@@ -391,7 +399,8 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
 			 * RSSI estimate, but value indicated by HW for RF
 			 * saturation event.
 			 */
-			if (PERE_IS_OVERSAMPLING(dfs) && (first_tlv == true) &&
+			if (PERE_IS_OVERSAMPLING(dfs) &&
+				(sfr_count == 1) &&
 				(rssi == dfs->wlan_dfs_false_rssi_thres) &&
 				(rsfr->peak_mag < (2 * dfs->wlan_dfs_peak_mag))
 				) {
@@ -399,6 +408,21 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
 				dfs_debug(dfs, WLAN_DEBUG_DFS_PHYERR,
 					"setting false_detect to TRUE because of false_rssi_thres");
 			}
+
+			/*
+			 * The first FFT report indicated by (sfr_count == 1)
+			 * should correspond to the first short FFT report from
+			 * HW and the second FFT report indicated by
+			 * (sfr_count == 2) should correspond to the first long
+			 * FFT report from HW for the same pulse. The short and
+			 * log FFT reports have a factor of 4 difference in
+			 * resolution; hence the need to multiply by 4 when
+			 * computing the psidx_diff.
+			 */
+			if (sfr_count == 2)
+				*psidx_diff = rsfr->peak_sidx -
+					      4 * first_short_fft_psidx;
+
 			break;
 		default:
 			dfs_debug(dfs, WLAN_DEBUG_DFS_PHYERR,
@@ -408,7 +432,6 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
 
 		/* Skip the payload. */
 		i += MS(tlv_hdr[TLV_REG], TLV_LEN);
-		first_tlv = false;
 	}
 	dfs_debug(dfs, WLAN_DEBUG_DFS_PHYERR, "done");
 
@@ -649,6 +672,7 @@ int dfs_process_phyerr_bb_tlv(struct wlan_dfs *dfs,
 	struct rx_radar_status rs;
 	struct rx_search_fft_report rsfr;
 	int first_short_fft_peak_mag = 0;
+	int16_t psidx_diff;
 
 	qdf_mem_zero(&rs, sizeof(rs));
 	qdf_mem_zero(&rsfr, sizeof(rsfr));
@@ -663,7 +687,7 @@ int dfs_process_phyerr_bb_tlv(struct wlan_dfs *dfs,
 
 	/* Try parsing the TLV set. */
 	if (!dfs_tlv_parse_frame(dfs, &rs, &rsfr, buf, datalen, rssi,
-				&first_short_fft_peak_mag))
+				&first_short_fft_peak_mag, &psidx_diff))
 		return 0;
 
 	/* For debugging, print what we have parsed. */
@@ -703,6 +727,7 @@ int dfs_process_phyerr_bb_tlv(struct wlan_dfs *dfs,
 	e->mb_gain = rs.agc_mb_gain;
 	e->relpwr_db = rsfr.relpwr_db;
 	e->pulse_delta_peak = rs.delta_peak;
+	e->pulse_psidx_diff = psidx_diff;
 	e->pulse_delta_diff = rs.delta_diff;
 
 	dfs_debug(dfs, WLAN_DEBUG_DFS_PHYERR_SUM,
@@ -716,14 +741,15 @@ int dfs_process_phyerr_bb_tlv(struct wlan_dfs *dfs,
 		(int) abs(e->freq_hi) % 1000);
 
 	dfs_debug(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, delta_peak=%d, delta_diff=%d",
+		"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, delta_peak=%d, delta_diff=%d, psidx_diff=%d",
 		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,
 		rsfr.relpwr_db,
 		rs.delta_peak,
-		rs.delta_diff);
+		rs.delta_diff,
+		psidx_diff);
 
 	return 1;
 }

+ 7 - 0
umac/dfs/core/src/filtering/dfs_process_phyerr.c

@@ -811,6 +811,9 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
 			event->re_relpwr_db = e.relpwr_db;
 			event->re_delta_diff = e.pulse_delta_diff;
 			event->re_delta_peak = e.pulse_delta_peak;
+			event->re_psidx_diff = e.pulse_psidx_diff;
+			event->re_flags = 0;
+			event->re_flags |= DFS_EVENT_VALID_PSIDX_DIFF;
 			/* Handle chirp flags. */
 			if (e.do_check_chirp) {
 				event->re_flags |= DFS_EVENT_CHECKCHIRP;
@@ -941,6 +944,10 @@ void dfs_process_phyerr_filter_offload(struct wlan_dfs *dfs,
 	event->re_delta_diff = wlan_radar_event->delta_diff;
 	event->re_delta_peak = wlan_radar_event->delta_peak;
 	event->re_flags = 0;
+	if (wlan_radar_event->is_psidx_diff_valid) {
+		event->re_flags |= DFS_EVENT_VALID_PSIDX_DIFF;
+		event->re_psidx_diff = wlan_radar_event->psidx_diff;
+	}
 
 	/*
 	 * Handle chirp flags.

+ 31 - 10
umac/dfs/core/src/filtering/dfs_process_radarevent.c

@@ -113,7 +113,7 @@ static void dfs_print_radar_events(struct wlan_dfs *dfs)
 	for (i = 0; (i < DFS_EVENT_LOG_SIZE) && (i < dfs->dfs_event_log_count);
 			i++) {
 		dfs_debug(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, delta_diff=%d, delta_peak=%d",
+			"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, delta_diff=%d, delta_peak=%d, psidx_diff=%d",
 			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,
@@ -125,7 +125,8 @@ static void dfs_print_radar_events(struct wlan_dfs *dfs)
 			dfs->radar_log[i].mb_gain,
 			dfs->radar_log[i].relpwr_db,
 			dfs->radar_log[i].delta_diff,
-			dfs->radar_log[i].delta_peak);
+			dfs->radar_log[i].delta_peak,
+			dfs->radar_log[i].psidx_diff);
 	}
 	dfs->dfs_event_log_count = 0;
 	dfs->dfs_phyerr_count = 0;
@@ -191,11 +192,12 @@ static int dfs_confirm_radar(struct wlan_dfs *dfs,
 			index =  (pl->pl_firstelem + i) &
 				DFS_MAX_PULSE_BUFFER_MASK;
 			dfs_debug(dfs, WLAN_DEBUG_DFS2,
-					"Elem %u: ts=%llu dur=%u, seq_num=%d, delta_peak=%d\n",
+					"Elem %u: ts=%llu dur=%u, seq_num=%d, delta_peak=%d, psidx_diff=%d\n",
 					i, pl->pl_elems[index].p_time,
 					pl->pl_elems[index].p_dur,
 					pl->pl_elems[index].p_seq_num,
-					pl->pl_elems[index].p_delta_peak);
+					pl->pl_elems[index].p_delta_peak,
+					pl->pl_elems[index].p_psidx_diff);
 		}
 	}
 
@@ -280,12 +282,14 @@ static int dfs_confirm_radar(struct wlan_dfs *dfs,
 	}
 
 	if ((rf->rf_check_delta_peak) &&
-			((dl->dl_delta_peak_match_count) <
-			 rf->rf_threshold)) {
+			((dl->dl_delta_peak_match_count +
+			dl->dl_psidx_diff_match_count - 1) <
+			rf->rf_threshold)) {
 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
-				"%s: Rejecting Radar since delta peak values are invalid : dl_delta_peak_match_count=%d, rf_threshold=%d\n",
-				__func__, dl->dl_delta_peak_match_count,
-				rf->rf_threshold);
+			"%s: Rejecting Radar since delta peak values are invalid : dl_delta_peak_match_count=%d, dl_psidx_diff_match_count=%d, rf_threshold=%d\n",
+			__func__, dl->dl_delta_peak_match_count,
+			dl->dl_psidx_diff_match_count,
+			rf->rf_threshold);
 		return 0;
 	}
 
@@ -385,6 +389,7 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs,
 	uint64_t deltaT = 0;
 	int ext_chan_event_flag = 0;
 	struct dfs_filter *rf = NULL;
+	int8_t ori_rf_check_delta_peak = 0;
 
 	for (p = 0, *found = 0; (p < ft->ft_numfilters) &&
 			(!(*found)) && !(*false_radar_found); p++) {
@@ -417,11 +422,24 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs,
 					(uint32_t) deltaT, re->re_dur,
 					ext_chan_event_flag);
 
-				if (*found)
+				if (*found) {
+					ori_rf_check_delta_peak =
+						rf->rf_check_delta_peak;
+					/*
+					 * If FW does not send valid psidx_diff
+					 * Do not do chirp check.
+					 */
+					if (rf->rf_check_delta_peak &&
+						(!(re->re_flags &
+						DFS_EVENT_VALID_PSIDX_DIFF)))
+						rf->rf_check_delta_peak = false;
 					dfs_confirm_radar_check(dfs,
 							rf, ext_chan_event_flag,
 							found,
 							false_radar_found);
+					rf->rf_check_delta_peak =
+						ori_rf_check_delta_peak;
+				}
 			}
 
 			if (dfs->dfs_debug_mask & WLAN_DEBUG_DFS2)
@@ -739,6 +757,7 @@ static inline void dfs_log_event(
 		dfs->radar_log[i].relpwr_db = (*re).re_relpwr_db;
 		dfs->radar_log[i].delta_diff = (*re).re_delta_diff;
 		dfs->radar_log[i].delta_peak = (*re).re_delta_peak;
+		dfs->radar_log[i].psidx_diff = (*re).re_psidx_diff;
 		dfs->radar_log[i].is_chirp = DFS_EVENT_NOTCHIRP(re) ?
 			0 : 1;
 		dfs->dfs_event_log_count++;
@@ -1098,6 +1117,7 @@ static inline void dfs_add_to_pulseline(
 	pl->pl_elems[*index].p_rssi = (*re).re_rssi;
 	pl->pl_elems[*index].p_sidx = (*re).re_sidx;
 	pl->pl_elems[*index].p_delta_peak = (*re).re_delta_peak;
+	pl->pl_elems[*index].p_psidx_diff = (*re).re_psidx_diff;
 	*diff_ts = (uint32_t)*this_ts - *test_ts;
 	*test_ts = (uint32_t)*this_ts;
 
@@ -1151,6 +1171,7 @@ static inline void dfs_conditional_clear_delaylines(
 		pl->pl_elems[index].p_rssi = re.re_rssi;
 		pl->pl_elems[index].p_sidx = re.re_sidx;
 		pl->pl_elems[index].p_delta_peak = re.re_delta_peak;
+		pl->pl_elems[index].p_psidx_diff = re.re_psidx_diff;
 		dfs->dfs_seq_num++;
 		pl->pl_elems[index].p_seq_num = dfs->dfs_seq_num;
 	}

+ 3 - 2
umac/dfs/core/src/misc/dfs.c

@@ -399,7 +399,7 @@ int dfs_control(struct wlan_dfs *dfs,
 #define FREQ_OFFSET1 ((int)dfs->radar_log[i].freq_offset_khz / 1000)
 #define FREQ_OFFSET2 ((int)abs(dfs->radar_log[i].freq_offset_khz) % 1000)
 			dfs_debug(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, delta_diff=%d, delta_peak=%d\n",
+					"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, delta_diff=%d, delta_peak=%d, psidx_diff=%d\n",
 					dfs->radar_log[i].ts,
 					dfs->radar_log[i].diff_ts,
 					dfs->radar_log[i].rssi,
@@ -414,7 +414,8 @@ int dfs_control(struct wlan_dfs *dfs,
 					dfs->radar_log[i].mb_gain,
 					dfs->radar_log[i].relpwr_db,
 					dfs->radar_log[i].delta_diff,
-					dfs->radar_log[i].delta_peak);
+					dfs->radar_log[i].delta_peak,
+					dfs->radar_log[i].psidx_diff);
 		}
 		dfs->dfs_event_log_count = 0;
 		dfs->dfs_phyerr_count = 0;

+ 6 - 0
umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h

@@ -78,6 +78,10 @@ struct dfs_acs_info {
  *  the time that the radar event uploading to host.
  * @peak_sidx: index of peak magnitude bin (signed)
  * @pdev_id: pdev_id for identifying the MAC.
+ * @delta_diff: Delta diff value.
+ * @delta_peak: Delta peak value.
+ * @psidx_diff: Psidx diff value.
+ * @is_psidx_diff_valid: Does fw send valid psidx diff.
  */
 struct radar_event_info {
 	uint8_t  pulse_is_chirp;
@@ -91,6 +95,8 @@ struct radar_event_info {
 	uint8_t  pdev_id;
 	uint8_t  delta_diff;
 	int8_t   delta_peak;
+	int8_t   psidx_diff;
+	int8_t   is_psidx_diff_valid;
 };
 
 /**

+ 8 - 0
wmi/src/wmi_unified_tlv.c

@@ -21203,6 +21203,14 @@ static QDF_STATUS extract_wlan_radar_event_info_tlv(
 	wlan_radar_event->peak_sidx = radar_event->peak_sidx;
 	wlan_radar_event->delta_peak = radar_event->pulse_delta_peak;
 	wlan_radar_event->delta_diff = radar_event->pulse_delta_diff;
+	if (radar_event->pulse_flags &
+			WMI_DFS_RADAR_PULSE_FLAG_MASK_PSIDX_DIFF_VALID) {
+		wlan_radar_event->is_psidx_diff_valid = true;
+		wlan_radar_event->psidx_diff = radar_event->psidx_diff;
+	} else {
+		wlan_radar_event->is_psidx_diff_valid = false;
+	}
+
 	wlan_radar_event->pdev_id = radar_event->pdev_id;
 
 	return QDF_STATUS_SUCCESS;