From 3a7cf9b15854a8ee43f5f3a6dbbcda3b0e07585a Mon Sep 17 00:00:00 2001 From: bings Date: Sun, 11 Feb 2018 16:40:08 +0800 Subject: [PATCH] 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 --- umac/dfs/core/src/dfs.h | 21 +++++++++ umac/dfs/core/src/filtering/dfs_bindetects.c | 30 ++++++++++--- umac/dfs/core/src/filtering/dfs_debug.c | 7 +-- umac/dfs/core/src/filtering/dfs_phyerr_tlv.c | 44 +++++++++++++++---- .../core/src/filtering/dfs_process_phyerr.c | 7 +++ .../src/filtering/dfs_process_radarevent.c | 41 ++++++++++++----- umac/dfs/core/src/misc/dfs.c | 5 ++- .../dispatcher/inc/wlan_dfs_public_struct.h | 6 +++ wmi/src/wmi_unified_tlv.c | 8 ++++ 9 files changed, 140 insertions(+), 29 deletions(-) diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 4d387538d715..39ff31b29c69 100644 --- a/umac/dfs/core/src/dfs.h +++ b/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; }; /** diff --git a/umac/dfs/core/src/filtering/dfs_bindetects.c b/umac/dfs/core/src/filtering/dfs_bindetects.c index 5aaa23c96e02..13c500aba0f5 100644 --- a/umac/dfs/core/src/filtering/dfs_bindetects.c +++ b/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; diff --git a/umac/dfs/core/src/filtering/dfs_debug.c b/umac/dfs/core/src/filtering/dfs_debug.c index 85a056748cee..930f621472af 100644 --- a/umac/dfs/core/src/filtering/dfs_debug.c +++ b/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; } diff --git a/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c b/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c index 6f1d7fccf8d8..6cb60691b19e 100644 --- a/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c +++ b/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; } diff --git a/umac/dfs/core/src/filtering/dfs_process_phyerr.c b/umac/dfs/core/src/filtering/dfs_process_phyerr.c index 5ea9e5454077..bb4aff53302b 100644 --- a/umac/dfs/core/src/filtering/dfs_process_phyerr.c +++ b/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. diff --git a/umac/dfs/core/src/filtering/dfs_process_radarevent.c b/umac/dfs/core/src/filtering/dfs_process_radarevent.c index ff6223d2e70e..455325f51c24 100644 --- a/umac/dfs/core/src/filtering/dfs_process_radarevent.c +++ b/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; } diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index a540abe9dd28..4ffe07ba20f8 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/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; diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h b/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h index b4035331e9fe..2201bfc84527 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_public_struct.h +++ b/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; }; /** diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index be5ef006e1a6..902e93cc2505 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/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;