diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 99685fe2c294..db8a37366a18 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -235,6 +235,7 @@ #define DFS_FAST_CLOCK_MULTIPLIER (800/11) #define DFS_NO_FAST_CLOCK_MULTIPLIER (80) +#define DFS_BIG_SIDX 10000 /** * Software use: channel interference used for as AR as well as RADAR @@ -284,11 +285,19 @@ * @p_time: Time for start of pulse in usecs. * @p_dur: Duration of pulse in usecs. * @p_rssi: RSSI of pulse. + * @p_seg_id: Segment id. + * @p_sidx: Sidx value. + * @p_delta_peak: Delta peak value. + * @p_seq_num: Sequence number. */ struct dfs_pulseparams { uint64_t p_time; - uint8_t p_dur; - uint8_t p_rssi; + uint8_t p_dur; + uint8_t p_rssi; + uint8_t p_seg_id; + int16_t p_sidx; + int8_t p_delta_peak; + uint32_t p_seq_num; } qdf_packed; /** @@ -340,6 +349,8 @@ struct dfs_pulseline { * @re_total_gain: Total gain. * @re_mb_gain: Mb gain. * @re_relpwr_db: Relpower in db. + * @re_delta_diff: Delta diff. + * @re_delta_peak: Delta peak. * @re_list: List of radar events. */ struct dfs_event { @@ -352,13 +363,15 @@ struct dfs_event { uint32_t re_freq; uint32_t re_freq_lo; uint32_t re_freq_hi; - u_int re_seg_id; + uint8_t re_seg_id; int re_sidx; u_int re_freq_offset_khz; int re_peak_mag; int re_total_gain; int re_mb_gain; int re_relpwr_db; + uint8_t re_delta_diff; + int8_t re_delta_peak; STAILQ_ENTRY(dfs_event) re_list; } qdf_packed; @@ -377,6 +390,9 @@ struct dfs_event { /* Number of different radar types */ #define DFS_MAX_RADAR_TYPES 32 +/* RADAR filter pattern type 1*/ +#define WLAN_DFS_RF_PATTERN_TYPE_1 1 + /** * struct dfs_ar_state - DFS AR state structure. * @ar_prevwidth: Previous width. @@ -401,16 +417,24 @@ struct dfs_ar_state { /** * struct dfs_delayelem - Delay Element. - * @de_time: Current "filter" time for start of pulse in usecs. - * @de_dur: Duration of pulse in usecs. - * @de_rssi: Rssi of pulse in dB. - * @de_ts: Time stamp for this delay element. + * @de_time: Current "filter" time for start of pulse in usecs. + * @de_dur: Duration of pulse in usecs. + * @de_rssi: Rssi of pulse in dB. + * @de_ts: Time stamp for this delay element. + * @de_seg_id: Segment id for HT80_80/HT160 use. + * @de_sidx: Sidx value. + * @de_delta_peak: Delta peak. + * @de_seq_num: Sequence number. */ struct dfs_delayelem { uint32_t de_time; uint8_t de_dur; uint8_t de_rssi; uint64_t de_ts; + uint8_t de_seg_id; + int16_t de_sidx; + int8_t de_delta_peak; + uint32_t de_seq_num; } qdf_packed; /** @@ -420,6 +444,25 @@ struct dfs_delayelem { * @dl_firstelem: Index of the first element. * @dl_lastelem: Index of the last element. * @dl_numelems: Number of elements in the delay line. + * The following is to handle fractional PRI pulses that can cause false + * detection. + * @dl_seq_num_start: Sequence number of first pulse that was part of + * threshold match. + * @dl_seq_num_stop: Sequence number of last pulse that was part of threshold + * match. + * The following is required because the first pulse may or may not be in the + * delay line but we will find it iin the pulse line using dl_seq_num_second's + * diff_ts value. + * @dl_seq_num_second: Sequence number of second pulse that was part of + * threshold match. + * @dl_search_pri: We need final search PRI to identify possible fractional + * PRI issue. + * @dl_min_sidx: Minimum sidx value of pulses used to match thershold. + * Used for sidx spread check. + * @dl_max_sidx: Maximum sidx value of pulses used to match thershold. + * Used for sidx spread check. + * @dl_delta_peak_match_count: Number of pulse in the delay line that had valid + * delta peak value. */ struct dfs_delayline { struct dfs_delayelem dl_elems[DFS_MAX_DL_SIZE]; @@ -427,6 +470,13 @@ struct dfs_delayline { uint32_t dl_firstelem; uint32_t dl_lastelem; uint32_t dl_numelems; + uint32_t dl_seq_num_start; + uint32_t dl_seq_num_stop; + uint32_t dl_seq_num_second; + uint32_t dl_search_pri; + int16_t dl_min_sidx; + int8_t dl_max_sidx; + uint8_t dl_delta_peak_match_count; } qdf_packed; /** @@ -443,6 +493,12 @@ struct dfs_delayline { * @rf_maxdur: Max duration for this radar filter. * @rf_ignore_pri_window: Ignore pri window. * @rf_pulseid: Unique ID corresponding to the original filter ID. + * To reduce false detection, look at frequency spread. For now we will use + * sidx spread. But for HT160 frequency spread will be a better measure. + * @rf_sidx_spread: Maximum SIDX value spread in a matched sequence + * excluding FCC Bin 5. + * @rf_check_delta_peak: Minimum allowed delta_peak value for a pulse to be + * considetred for this filter's match. */ struct dfs_filter { struct dfs_delayline rf_dl; @@ -457,6 +513,8 @@ struct dfs_filter { uint32_t rf_maxdur; uint32_t rf_ignore_pri_window; uint32_t rf_pulseid; + uint16_t rf_sidx_spread; + int8_t rf_check_delta_peak; } qdf_packed; /** @@ -652,6 +710,8 @@ struct dfs_stats { * @total_gain: Total gain. * @mb_gain: Mb gain. * @relpwr_db: Relpower in db. + * @delta_diff: Delta diff. + * @delta_peak: Delta peak. */ struct dfs_event_log { @@ -660,13 +720,15 @@ struct dfs_event_log { uint8_t rssi; uint8_t dur; int is_chirp; - u_int seg_id; + uint8_t seg_id; int sidx; u_int freq_offset_khz; int peak_mag; int total_gain; int mb_gain; int relpwr_db; + uint8_t delta_diff; + int8_t delta_peak; }; #define WLAN_DFS_RESET_TIME_S 7 @@ -761,6 +823,7 @@ struct dfs_event_log { * the radar type. * @wlan_dfs_nol_timeout: NOL timeout. * @update_nol: Update NOL. + * @dfs_seq_num: Sequence number. * @dfs_nol_event[]: NOL event. * @dfs_nol_timer: NOL list processing. * @dfs_cac_timer: CAC timer. @@ -849,6 +912,7 @@ struct wlan_dfs { int dfs_pri_multiplier; int wlan_dfs_nol_timeout; bool update_nol; + uint32_t dfs_seq_num; int dfs_nol_event[IEEE80211_CHAN_MAX]; os_timer_t dfs_nol_timer; os_timer_t dfs_cac_timer; @@ -887,6 +951,8 @@ struct wlan_dfs { * @WLAN_DEBUG_DFS_BIN5_FFT: BIN5 FFT check. * @WLAN_DEBUG_DFS_BIN5_PULSE: BIN5 pulse check. * @WLAN_DEBUG_DFS_FALSE_DET: False detection debug related prints. + * @WLAN_DEBUG_DFS_FALSE_DET2: Second level check to confirm poisitive + * detection. * @WLAN_DEBUG_DFS_RANDOM_CHAN: Random channel selection. */ enum { @@ -902,7 +968,8 @@ enum { WLAN_DEBUG_DFS_BIN5_FFT = 0x00020000, WLAN_DEBUG_DFS_BIN5_PULSE = 0x00040000, WLAN_DEBUG_DFS_FALSE_DET = 0x00080000, - WLAN_DEBUG_DFS_RANDOM_CHAN = 0x00100000, + WLAN_DEBUG_DFS_FALSE_DET2 = 0x00100000, + WLAN_DEBUG_DFS_RANDOM_CHAN = 0x00200000, WLAN_DEBUG_DFS_MAX = 0x80000000, WLAN_DEBUG_DFS_ALWAYS = WLAN_DEBUG_DFS_MAX }; @@ -930,6 +997,8 @@ enum { * @total_gain: Total gain. * @mb_gain: Mb gain. * @relpwr_db: Relpower in DB. + * @pulse_delta_diff: Pulse delta diff. + * @pulse_delta_peak: Pulse delta peak. * * Chirp notes! * @@ -990,13 +1059,15 @@ struct dfs_phy_err { uint32_t freq_hi; uint8_t rssi; uint8_t dur; - u_int seg_id; + uint8_t seg_id; int sidx; u_int freq_offset_khz; int peak_mag; int total_gain; int mb_gain; int relpwr_db; + uint8_t pulse_delta_diff; + int8_t pulse_delta_peak; }; /** @@ -1886,7 +1957,8 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs, struct dfs_filtertype *ft, struct dfs_event *re, uint64_t this_ts, - int *found); + int *found, + int *false_radar_found); /** * bin5_rules_check_internal() - This is a extension of dfs_bin5_check(). diff --git a/umac/dfs/core/src/dfs_structs.h b/umac/dfs/core/src/dfs_structs.h index 23a6a0274726..92099b40bc31 100644 --- a/umac/dfs/core/src/dfs_structs.h +++ b/umac/dfs/core/src/dfs_structs.h @@ -93,6 +93,16 @@ struct wlan_dfs_caps { * rssi 3dBm. lower than in non TURBO mode. This * will be used to offset that diff. * @rp_ignore_pri_window: Ignore PRI window. + * @rp_sidx_spread: To reduce false detection use sidx spread. For HT160, + * for consistency, push all pulses at center of the + * channel to 80MHz ext when both segments are DFS. + * Maximum SIDX value spread in a matched sequence + * excluding FCC Bin 5. + * @rp_check_delta_peak: This is mainly used for ETSI Type 4 5MHz chirp pulses + * which HW cnanot identify. + * Reliably as chirping but can correctly characterize + * these with delta_peak non-zero. + * Is delta_peak check required for this filter. * @rp_pulseid: Unique ID for identifying filter. */ struct dfs_pulse { @@ -109,7 +119,9 @@ struct dfs_pulse { uint32_t rp_meanoffset; int32_t rp_rssimargin; uint32_t rp_ignore_pri_window; - uint32_t rp_pulseid; + uint16_t rp_sidx_spread; + int8_t rp_check_delta_peak; + uint16_t rp_pulseid; }; /** diff --git a/umac/dfs/core/src/filtering/ar5416_radar.c b/umac/dfs/core/src/filtering/ar5416_radar.c index c6128226ed68..1a25375f4d84 100644 --- a/umac/dfs/core/src/filtering/ar5416_radar.c +++ b/umac/dfs/core/src/filtering/ar5416_radar.c @@ -45,25 +45,25 @@ struct dfs_pulse ar5416_etsi_radars[] = { /* TYPE staggered pulse */ /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ - {20, 2, 300, 400, 2, 30, 4, 0, 2, 15, 0, 0, 0, 31}, + {20, 2, 300, 400, 2, 30, 4, 0, 2, 15, 0, 0, 0, 0, 0, 31}, /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */ - {30, 2, 400, 1200, 2, 30, 7, 0, 2, 15, 0, 0, 0, 32}, + {30, 2, 400, 1200, 2, 30, 7, 0, 2, 15, 0, 0, 0, 0, 0, 32}, /* constant PRF based */ /* 0.8-5us, 200 300 PRF, 10 pulses */ - {10, 5, 200, 400, 0, 24, 5, 0, 8, 18, 0, 0, 0, 33}, - {10, 5, 400, 600, 0, 24, 5, 0, 8, 18, 0, 0, 0, 37}, - {10, 5, 600, 800, 0, 24, 5, 0, 8, 18, 0, 0, 0, 38}, - {10, 5, 800, 1000, 0, 24, 5, 0, 8, 18, 0, 0, 0, 39}, + {10, 5, 200, 400, 0, 24, 5, 0, 8, 18, 0, 0, 0, 0, 0, 33}, + {10, 5, 400, 600, 0, 24, 5, 0, 8, 18, 0, 0, 0, 0, 0, 37}, + {10, 5, 600, 800, 0, 24, 5, 0, 8, 18, 0, 0, 0, 0, 0, 38}, + {10, 5, 800, 1000, 0, 24, 5, 0, 8, 18, 0, 0, 0, 0, 0, 39}, /* 0.8-15us, 200-1600 PRF, 15 pulses */ - {15, 15, 200, 1600, 0, 24, 6, 0, 18, 15, 0, 0, 0, 34}, + {15, 15, 200, 1600, 0, 24, 6, 0, 18, 15, 0, 0, 0, 0, 0, 34}, /* 0.8-15us, 2300-4000 PRF, 25 pulses*/ - {25, 15, 2300, 4000, 0, 24, 8, 0, 18, 15, 0, 0, 0, 35}, + {25, 15, 2300, 4000, 0, 24, 8, 0, 18, 15, 0, 0, 0, 0, 0, 35}, /* 20-30us, 2000-4000 PRF, 20 pulses*/ - {20, 30, 2000, 4000, 0, 24, 8, 19, 33, 15, 0, 0, 0, 36}, + {20, 30, 2000, 4000, 0, 24, 8, 19, 33, 15, 0, 0, 0, 0, 0, 36}, }; /** @@ -73,28 +73,28 @@ struct dfs_pulse ar5416_etsi_radars[] = { struct dfs_pulse ar5416_fcc_radars[] = { /* following two filters are specific to Japan/MKK4 */ /* 1389 +/- 6 us */ - {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, + {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 0, 0, 17}, /* 4000 +/- 6 us */ - {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, + {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 0, 0, 18}, /* 3846 +/- 7 us */ - {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 0, 19}, + {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 0, 0, 0, 19}, /* following filters are common to both FCC and JAPAN */ /* FCC TYPE 1 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, - {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, + {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0, 0, 0}, + {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0, 0, 0}, /* FCC TYPE 6 */ - {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 0, 1}, + {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 0, 0, 0, 1}, /* FCC TYPE 2 */ - {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 20, 0, 3, 0, 2}, + {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 20, 0, 3, 0, 0, 0, 2}, /* FCC TYPE 3 */ - {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 20, 0, 3, 0, 5}, + {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 20, 0, 3, 0, 0, 0, 5}, /* FCC TYPE 4 */ - {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 20, 0, 3, 0, 11}, + {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 20, 0, 3, 0, 0, 0, 11}, }; /** diff --git a/umac/dfs/core/src/filtering/ar9300_radar.c b/umac/dfs/core/src/filtering/ar9300_radar.c index c93208370f52..f383640e6409 100644 --- a/umac/dfs/core/src/filtering/ar9300_radar.c +++ b/umac/dfs/core/src/filtering/ar9300_radar.c @@ -60,30 +60,30 @@ struct dfs_pulse ar9300_etsi_radars[] = { /* TYPE staggered pulse */ /* Type 5*/ /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ - {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, + {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 0, 0, 31}, /* Type 6 */ /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */ - {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, + {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 0, 0, 32}, /* constant PRF based */ /* Type 1 */ /* 0.8-5us, 200 300 PRF, 10 pulses */ - {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, - {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, - {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, - {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, + {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 0, 0, 33}, + {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 0, 0, 37}, + {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 0, 0, 38}, + {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 0, 0, 39}, /* Type 2 */ /* 0.8-15us, 200-1600 PRF, 15 pulses */ - {15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 34}, + {15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 0, 0, 34}, /* Type 3 */ /* 0.8-15us, 2300-4000 PRF, 25 pulses*/ - {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 35}, + {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 0, 0, 35}, /* Type 4 */ /* 20-30us, 2000-4000 PRF, 20 pulses*/ - {20, 30, 2000, 4000, 0, 24, 8, 19, 33, 24, 0, 0, 0, 36}, + {20, 30, 2000, 4000, 0, 24, 8, 19, 33, 24, 0, 0, 0, 0, 0, 36}, }; /** @@ -99,42 +99,42 @@ struct dfs_pulse ar9300_fcc_radars[] = { /* following two filters are specific to Japan/MKK4 */ /* 1389 +/- 6 us */ - {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, + {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 0, 0, 17}, /* 4000 +/- 6 us */ - {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, + {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 0, 0, 18}, /* 3846 +/- 7 us */ - {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, + {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 0, 0, 19}, /* 3846 +/- 7 us */ - {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 1, 20}, + {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 1, 0, 0, 20}, /* following filters are common to both FCC and JAPAN */ /* FCC TYPE 1 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 8}, - {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, + {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0, 0, 8}, + {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0, 0, 0}, /* FCC TYPE 6 */ - {9, 1, 3003, 3003, 0, 7, 5, 0, 1, 18, 0, 0, 1, 1}, + {9, 1, 3003, 3003, 0, 7, 5, 0, 1, 18, 0, 0, 1, 0, 0, 1}, /* FCC TYPE 2 */ - {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2}, + {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 0, 0, 2}, /* FCC TYPE 3 */ - {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5}, + {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 0, 0, 5}, /* FCC TYPE 4 */ - {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11}, + {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 0, 0, 11}, /* FCC NEW TYPE 1 */ /* Search duration is numpulses*maxpri. * The last theshold can be increased if false detects happen */ /* 518us to 938us pulses (min 56 pulses) */ - {57, 1, 1066, 1930, 0, 6, 20, 0, 1, 22, 0, 3, 0, 21}, + {57, 1, 1066, 1930, 0, 6, 20, 0, 1, 22, 0, 3, 0, 0, 0, 21}, /* 938us to 2000 pulses (min 26 pulses) */ - {27, 1, 500, 1066, 0, 6, 13, 0, 1, 22, 0, 3, 0, 22}, + {27, 1, 500, 1066, 0, 6, 13, 0, 1, 22, 0, 3, 0, 0, 0, 22}, /* 2000 to 3067us pulses (min 17 pulses)*/ - {18, 1, 325, 500, 0, 6, 9, 0, 1, 22, 0, 3, 0, 23}, + {18, 1, 325, 500, 0, 6, 9, 0, 1, 22, 0, 3, 0, 0, 0, 23}, }; @@ -150,13 +150,13 @@ struct dfs_bin5pulse ar9300_bin5pulses[] = { */ struct dfs_pulse ar9300_korea_radars[] = { /* Korea Type 1 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 40}, + {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0, 0, 40}, /* Korea Type 2 */ - {10, 1, 1800, 1800, 0, 6, 4, 0, 1, 18, 0, 3, 1, 41}, + {10, 1, 1800, 1800, 0, 6, 4, 0, 1, 18, 0, 3, 1, 0, 0, 41}, /* Korea Type 3 */ - {70, 1, 330, 330, 0, 6, 20, 0, 2, 18, 0, 3, 1, 42}, + {70, 1, 330, 330, 0, 6, 20, 0, 2, 18, 0, 3, 1, 0, 0, 42}, /* Korea Type 4 */ - {3, 1, 3003, 3003, 1, 7, 2, 0, 1, 18, 0, 0, 1, 43}, + {3, 1, 3003, 3003, 1, 7, 2, 0, 1, 18, 0, 0, 1, 0, 0, 43}, }; void dfs_get_radars_for_ar9300(struct wlan_dfs *dfs) diff --git a/umac/dfs/core/src/filtering/dfs_bindetects.c b/umac/dfs/core/src/filtering/dfs_bindetects.c index b493f4932e90..ccf098aac955 100644 --- a/umac/dfs/core/src/filtering/dfs_bindetects.c +++ b/umac/dfs/core/src/filtering/dfs_bindetects.c @@ -289,6 +289,10 @@ void dfs_add_pulse( window = deltaT; dl->dl_elems[index].de_dur = re->re_dur; dl->dl_elems[index].de_rssi = re->re_rssi; + 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_seq_num = dfs->dfs_seq_num; dfs_debug(dfs, WLAN_DEBUG_DFS2, "adding: filter id %d, dur=%d, rssi=%d, ts=%llu", @@ -670,6 +674,35 @@ int dfs_bin_check( return found; } +/** + * dfs_update_min_and_max_sidx() - Calculate min and max sidx. + * @dl: Pointer to dfs_delayline structure. + * @delayindex: Delay index. + * @sidx_min: Sidx min. + * @sidx_max: Sidx max. + * @delta_peak_match_count: Delta peak match count. + * @rf: Pointer to dfs_filter structure. + */ +static inline void dfs_update_min_and_max_sidx( + struct dfs_delayline *dl, + int delayindex, + int32_t *sidx_min, + int32_t *sidx_max, + uint8_t *delta_peak_match_count, + struct dfs_filter *rf) +{ + /* update sidx min/max for false detection check later */ + if (*sidx_min > dl->dl_elems[delayindex].de_sidx) + *sidx_min = dl->dl_elems[delayindex].de_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)++; +} + /** * dfs_check_pulses_for_delta_variance() - Check pulses for delta variance. * @rf: Pointer to dfs_filter structure. @@ -678,6 +711,11 @@ int dfs_bin_check( * @fundamentalpri: Highest PRI. * @primargin: Primary margin. * @numpulses: Number of pulses. + * @delayindex: Delay index. + * @sidx_min: Sidx min. + * @sidx_max: Sidx max. + * @delta_peak_match_count: Delta peak match count. + * @dl: Pointer to dfs_delayline structure. */ static inline void dfs_check_pulses_for_delta_variance( struct dfs_filter *rf, @@ -685,7 +723,12 @@ static inline void dfs_check_pulses_for_delta_variance( uint32_t delta_time_stamps, int fundamentalpri, uint32_t primargin, - int *numpulses) + int *numpulses, + int delayindex, + int32_t *sidx_min, + int32_t *sidx_max, + uint8_t *delta_peak_match_count, + struct dfs_delayline *dl) { uint32_t delta_ts_variance, j; @@ -693,6 +736,12 @@ static inline void dfs_check_pulses_for_delta_variance( delta_ts_variance = DFS_DIFF(delta_time_stamps, ((j + 1) * fundamentalpri)); if (delta_ts_variance < (2 * (j + 1) * primargin)) { + dl->dl_seq_num_stop = + dl->dl_elems[delayindex].de_seq_num; + dfs_update_min_and_max_sidx(dl, delayindex, + sidx_min, sidx_max, + delta_peak_match_count, + rf); (*numpulses)++; if (rf->rf_ignore_pri_window > 0) break; @@ -731,6 +780,9 @@ static void dfs_count_the_other_delay_elements( uint32_t searchpri, searchdur, deltadur, deltapri1, deltapri2; uint32_t j = 0, delta_time_stamps, deltapri; int dindex, primatch, numpulsetochk = 2; + int32_t sidx_min = DFS_BIG_SIDX; + int32_t sidx_max = -DFS_BIG_SIDX; + uint8_t delta_peak_match_count = 1; delayindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; searchpri = dl->dl_elems[delayindex].de_time; @@ -764,6 +816,12 @@ static void dfs_count_the_other_delay_elements( if (primatch && (deltadur < durmargin)) { if ((*numpulses == 1)) { + dl->dl_seq_num_second = + dl->dl_elems[delayindex].de_seq_num; + dfs_update_min_and_max_sidx(dl, delayindex, + &sidx_min, &sidx_max, + &delta_peak_match_count, + rf); (*numpulses)++; } else { delta_time_stamps = (dl->dl_elems[delayindex].de_ts - @@ -780,9 +838,16 @@ static void dfs_count_the_other_delay_elements( dfs_check_pulses_for_delta_variance(rf, numpulsetochk, delta_time_stamps, fundamentalpri, - primargin, numpulses); + primargin, numpulses, delayindex, + &sidx_min, &sidx_max, + &delta_peak_match_count, + dl); } *prev_good_timestamp = dl->dl_elems[delayindex].de_ts; + dl->dl_search_pri = searchpri; + dl->dl_min_sidx = sidx_min; + dl->dl_max_sidx = sidx_max; + dl->dl_delta_peak_match_count = delta_peak_match_count; dfs_debug(dfs, WLAN_DEBUG_DFS2, "rf->minpri=%d rf->maxpri=%d searchpri = %d index = %d numpulses = %d deltapri=%d j=%d", diff --git a/umac/dfs/core/src/filtering/dfs_debug.c b/umac/dfs/core/src/filtering/dfs_debug.c index 187f548c15b0..85a056748cee 100644 --- a/umac/dfs/core/src/filtering/dfs_debug.c +++ b/umac/dfs/core/src/filtering/dfs_debug.c @@ -25,13 +25,16 @@ void dfs_print_delayline(struct wlan_dfs *dfs, struct dfs_delayline *dl) int i = 0, index; struct dfs_delayelem *de; - index = dl->dl_lastelem; + index = dl->dl_firstelem; for (i = 0; i < dl->dl_numelems; i++) { de = &dl->dl_elems[index]; dfs_debug(dfs, WLAN_DEBUG_DFS2, - "Elem %d: ts = %u (0x%x) dur=%u", - i, de->de_time, de->de_time, de->de_dur); - index = (index - 1) & DFS_MAX_DL_MASK; + "Elem %u: ts=%llu diff_ts=%u (0x%x) dur=%u, seg_id=%d sidx=%d delta_peak=%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); + + index = (index + 1) & DFS_MAX_DL_MASK; } } diff --git a/umac/dfs/core/src/filtering/dfs_init.c b/umac/dfs/core/src/filtering/dfs_init.c index 9bd802fd5783..8146d7169bb5 100644 --- a/umac/dfs/core/src/filtering/dfs_init.c +++ b/umac/dfs/core/src/filtering/dfs_init.c @@ -296,6 +296,8 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs, rf->rf_numpulses = numpulses; rf->rf_patterntype = dfs_radars[p].rp_patterntype; + rf->rf_sidx_spread = dfs_radars[p].rp_sidx_spread; + rf->rf_check_delta_peak = dfs_radars[p].rp_check_delta_peak; rf->rf_pulseid = dfs_radars[p].rp_pulseid; rf->rf_mindur = dfs_radars[p].rp_mindur; rf->rf_maxdur = dfs_radars[p].rp_maxdur; diff --git a/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c b/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c index bf052d50f2a8..4e317710c079 100644 --- a/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c +++ b/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c @@ -702,6 +702,8 @@ int dfs_process_phyerr_bb_tlv(struct wlan_dfs *dfs, e->total_gain = rs.agc_total_gain; e->mb_gain = rs.agc_mb_gain; e->relpwr_db = rsfr.relpwr_db; + e->pulse_delta_peak = rs.delta_peak; + e->pulse_delta_diff = rs.delta_diff; dfs_debug(dfs, WLAN_DEBUG_DFS_PHYERR_SUM, "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", @@ -714,12 +716,14 @@ 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", + "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", 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); + rsfr.relpwr_db, + rs.delta_peak, + rs.delta_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 13d1900ceef0..2efccffa9544 100644 --- a/umac/dfs/core/src/filtering/dfs_process_phyerr.c +++ b/umac/dfs/core/src/filtering/dfs_process_phyerr.c @@ -809,6 +809,8 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen, event->re_total_gain = e.total_gain; event->re_mb_gain = e.mb_gain; event->re_relpwr_db = e.relpwr_db; + event->re_delta_diff = e.pulse_delta_diff; + event->re_delta_peak = e.pulse_delta_peak; /* Handle chirp flags. */ if (e.do_check_chirp) { event->re_flags |= DFS_EVENT_CHECKCHIRP; diff --git a/umac/dfs/core/src/filtering/dfs_process_radarevent.c b/umac/dfs/core/src/filtering/dfs_process_radarevent.c index aa8a75c695ef..c5e48a6ddc1f 100644 --- a/umac/dfs/core/src/filtering/dfs_process_radarevent.c +++ b/umac/dfs/core/src/filtering/dfs_process_radarevent.c @@ -31,6 +31,10 @@ #define DFS_MAX_FREQ_SPREAD (1375 * 1) #define DFS_LARGE_PRI_MULTIPLIER 4 #define DFS_W53_DEFAULT_PRI_MULTIPLIER 2 +#define DFS_INVALID_PRI_LIMIT 100 /* should we use 135? */ +#define DFS_BIG_SIDX 10000 + +#define FRAC_PRI_SCORE_ARRAY_SIZE 40 static char debug_dup[33]; static int debug_dup_cnt; @@ -104,7 +108,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", + "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", 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, @@ -114,7 +118,9 @@ static void dfs_print_radar_events(struct wlan_dfs *dfs) dfs->radar_log[i].peak_mag, dfs->radar_log[i].total_gain, dfs->radar_log[i].mb_gain, - dfs->radar_log[i].relpwr_db); + dfs->radar_log[i].relpwr_db, + dfs->radar_log[i].delta_diff, + dfs->radar_log[i].delta_peak); } dfs->dfs_event_log_count = 0; dfs->dfs_phyerr_count = 0; @@ -124,6 +130,163 @@ static void dfs_print_radar_events(struct wlan_dfs *dfs) dfs->dfs_phyerr_freq_max = 0; } +/** + * dfs_confirm_radar() - This function checks for fractional PRI and jitter in + * sidx index to determine if the radar is real or not. + * @dfs: Pointer to dfs structure. + * @rf: Pointer to dfs_filter structure. + * @ext_chan_flag: ext chan flags. + */ +static int dfs_confirm_radar(struct wlan_dfs *dfs, + struct dfs_filter *rf, + int ext_chan_flag) +{ + int i = 0; + int index; + struct dfs_delayline *dl = &rf->rf_dl; + struct dfs_delayelem *de; + uint64_t target_ts = 0; + struct dfs_pulseline *pl; + int start_index = 0, current_index, next_index; + unsigned char scores[FRAC_PRI_SCORE_ARRAY_SIZE]; + uint32_t pri_margin; + uint64_t this_diff_ts; + uint32_t search_bin; + + unsigned char max_score = 0; + int max_score_index = 0; + + pl = dfs->pulses; + + OS_MEMZERO(scores, sizeof(scores)); + scores[0] = rf->rf_threshold; + + pri_margin = dfs_get_pri_margin(dfs, ext_chan_flag, + (rf->rf_patterntype == 1)); + + /* + * Look for the entry that matches dl_seq_num_second. + * we need the time stamp and diff_ts from there. + */ + + for (i = 0; i < dl->dl_numelems; i++) { + index = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; + de = &dl->dl_elems[index]; + if (dl->dl_seq_num_second == de->de_seq_num) + target_ts = de->de_ts - de->de_time; + } + + if (dfs->dfs_debug_mask & WLAN_DEBUG_DFS2) { + dfs_print_delayline(dfs, &rf->rf_dl); + + /* print pulse line */ + dfs_debug(dfs, WLAN_DEBUG_DFS2, + "%s: Pulse Line\n", __func__); + for (i = 0; i < pl->pl_numelems; i++) { + 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", + 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); + } + } + + /* + * Walk through the pulse line and find pulse with target_ts. + * Then continue until we find entry with seq_number dl_seq_num_stop. + */ + + for (i = 0; i < pl->pl_numelems; i++) { + index = (pl->pl_firstelem + i) & DFS_MAX_PULSE_BUFFER_MASK; + if (pl->pl_elems[index].p_time == target_ts) { + dl->dl_seq_num_start = pl->pl_elems[index].p_seq_num; + start_index = index; /* save for future use */ + } + } + + dfs_debug(dfs, WLAN_DEBUG_DFS2, + "%s: target_ts=%llu, dl_seq_num_start=%d, dl_seq_num_second=%d, dl_seq_num_stop=%d\n", + __func__, target_ts, dl->dl_seq_num_start, + dl->dl_seq_num_second, dl->dl_seq_num_stop); + + current_index = start_index; + while (pl->pl_elems[current_index].p_seq_num < dl->dl_seq_num_stop) { + next_index = (current_index + 1) & DFS_MAX_PULSE_BUFFER_MASK; + this_diff_ts = pl->pl_elems[next_index].p_time - + pl->pl_elems[current_index].p_time; + + /* Now update the score for this diff_ts */ + for (i = 1; i < FRAC_PRI_SCORE_ARRAY_SIZE; i++) { + search_bin = dl->dl_search_pri / (i + 1); + + /* + * We do not give score to PRI that is lower then the + * limit. + */ + if (search_bin < DFS_INVALID_PRI_LIMIT) + break; + + /* + * Increment the score if this_diff_ts belongs to this + * search_bin +/- margin. + */ + if ((this_diff_ts >= (search_bin - pri_margin)) && + (this_diff_ts <= + (search_bin + pri_margin))) { + /*increment score */ + scores[i]++; + } + } + current_index = next_index; + } + + for (i = 0; i < FRAC_PRI_SCORE_ARRAY_SIZE; i++) + if (scores[i] > max_score) { + max_score = scores[i]; + max_score_index = i; + } + + if (max_score_index != 0) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "%s: Rejecting Radar since Fractional PRI detected: searchpri=%d, threshold=%d, fractional PRI=%d, Fractional PRI score=%d\n", + __func__, dl->dl_search_pri, scores[0], + dl->dl_search_pri/(max_score_index + 1), + max_score); + return 0; + } + + + /* Check for frequency spread */ + if (dl->dl_min_sidx > pl->pl_elems[start_index].p_sidx) + dl->dl_min_sidx = pl->pl_elems[start_index].p_sidx; + + if (dl->dl_max_sidx < pl->pl_elems[start_index].p_sidx) + dl->dl_max_sidx = pl->pl_elems[start_index].p_sidx; + + if ((dl->dl_max_sidx - dl->dl_min_sidx) > rf->rf_sidx_spread) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "%s: Rejecting Radar since frequency spread is too large : min_sidx=%d, max_sidx=%d, rf_sidx_spread=%d\n", + __func__, dl->dl_min_sidx, dl->dl_max_sidx, + rf->rf_sidx_spread); + return 0; + } + + if ((rf->rf_check_delta_peak) && + ((dl->dl_delta_peak_match_count) < + 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); + return 0; + } + + return 1; +} + /* * dfs_reject_on_pri() - Rejecting on individual filter based on min PRI . * @dfs: Pointer to wlan_dfs structure. @@ -182,11 +345,36 @@ static inline bool dfs_reject_on_pri( return 0; } +/** + * dfs_confirm_radar_check() - Do additioal check to conirm radar except for + * the staggered, chirp FCC Bin 5, frequency hopping indicated by + * rf_patterntype == 1. + * @dfs: Pointer to wlan_dfs structure. + * @rf: Pointer to dfs_filter structure. + * @ext_chan_event_flag: Extension channel event flag + * @found: Pointer to radar found flag (return value). + * @false_radar_found: Pointer to false radar found (return value). + */ + +static inline void dfs_confirm_radar_check( + struct wlan_dfs *dfs, + struct dfs_filter *rf, + int ext_chan_event_flag, + int *found, + int *false_radar_found) +{ + if (rf->rf_patterntype != 1) { + *found = dfs_confirm_radar(dfs, rf, ext_chan_event_flag); + *false_radar_found = (*found == 1) ? 0 : 1; + } +} + void __dfs_process_radarevent(struct wlan_dfs *dfs, struct dfs_filtertype *ft, struct dfs_event *re, uint64_t this_ts, - int *found) + int *found, + int *false_radar_found) { int p; uint64_t deltaT = 0; @@ -194,7 +382,7 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs, struct dfs_filter *rf = NULL; for (p = 0, *found = 0; (p < ft->ft_numfilters) && - (!(*found)); p++) { + (!(*found)) && !(*false_radar_found); p++) { rf = &(ft->ft_filters[p]); if ((re->re_dur >= rf->rf_mindur) && (re->re_dur <= rf->rf_maxdur)) { @@ -223,9 +411,18 @@ void __dfs_process_radarevent(struct wlan_dfs *dfs, *found = dfs_bin_check(dfs, rf, (uint32_t) deltaT, re->re_dur, ext_chan_event_flag); + + if (*found) + dfs_confirm_radar_check(dfs, + rf, ext_chan_event_flag, + found, + false_radar_found); } + if (dfs->dfs_debug_mask & WLAN_DEBUG_DFS2) - dfs_print_delayline(dfs, &rf->rf_dl); + if (rf->rf_patterntype != + WLAN_DFS_RF_PATTERN_TYPE_1) + dfs_print_delayline(dfs, &rf->rf_dl); rf->rf_dl.dl_last_ts = this_ts; } @@ -300,6 +497,7 @@ static inline void dfs_radarfound_reset_vars( 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; @@ -494,14 +692,17 @@ static inline void dfs_return_event_to_eventq( * @re: Pointer to dfs_event re * @this_ts: Current time stamp 64bit * @diff_ts: Difference between 2 timestamps 32bit + * @index: Index value. */ static inline void dfs_log_event( struct wlan_dfs *dfs, struct dfs_event *re, uint64_t this_ts, - uint32_t diff_ts) + uint32_t diff_ts, + uint32_t index) { uint8_t i; + struct dfs_pulseline *pl = dfs->pulses; if (dfs->dfs_event_log_on) { i = dfs->dfs_event_log_count % DFS_EVENT_LOG_SIZE; @@ -517,10 +718,15 @@ static inline void dfs_log_event( 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].delta_diff = (*re).re_delta_diff; + dfs->radar_log[i].delta_peak = (*re).re_delta_peak; dfs->radar_log[i].is_chirp = DFS_EVENT_NOTCHIRP(re) ? 0 : 1; dfs->dfs_event_log_count++; } + + dfs->dfs_seq_num++; + pl->pl_elems[index].p_seq_num = dfs->dfs_seq_num; } /** @@ -532,6 +738,7 @@ static inline void dfs_log_event( * @diff_ts: Difference between 2 timestamps 32bit * @found: Pointer to found. If radar found or not. * @retval: Pointer to retval(return value). + * @false_radar_found: Pointer to false_radar_found(return value). */ static inline void dfs_check_if_nonbin5( struct wlan_dfs *dfs, @@ -540,7 +747,8 @@ static inline void dfs_check_if_nonbin5( uint64_t this_ts, uint32_t diff_ts, int *found, - int *retval) + int *retval, + int *false_radar_found) { uint32_t tabledepth = 0; @@ -554,7 +762,7 @@ static inline void dfs_check_if_nonbin5( while ((tabledepth < DFS_MAX_RADAR_OVERLAP) && ((dfs->dfs_ftindextable[(*re).re_dur])[tabledepth] != - -1) && (!*retval)) { + -1) && (!*retval) && !(*false_radar_found)) { ft = dfs->dfs_radarf[((dfs->dfs_ftindextable[(*re).re_dur]) [tabledepth])]; dfs_debug(dfs, WLAN_DEBUG_DFS2, @@ -590,7 +798,8 @@ static inline void dfs_check_if_nonbin5( continue; } - __dfs_process_radarevent(dfs, ft, re, this_ts, found); + __dfs_process_radarevent(dfs, ft, re, this_ts, found, + false_radar_found); ft->ft_last_ts = this_ts; *retval |= *found; @@ -813,16 +1022,18 @@ static inline void dfs_calculate_timestamps( * 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) + * @this_ts: Pointer to this_ts (this timestamp) + * @diff_ts: Diff ts. + * @index: Pointer to get index value. */ 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 *diff_ts, + uint32_t *index) { - uint32_t index; struct dfs_pulseline *pl; /* @@ -854,7 +1065,7 @@ static inline void dfs_add_to_pulseline( pl = dfs->pulses; /* Save the pulse parameters in the pulse buffer(pulse line). */ - index = (pl->pl_lastelem + 1) & DFS_MAX_PULSE_BUFFER_MASK; + *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) & @@ -862,10 +1073,12 @@ static inline void dfs_add_to_pulseline( 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; + 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; + pl->pl_elems[*index].p_sidx = (*re).re_sidx; + pl->pl_elems[*index].p_delta_peak = (*re).re_delta_peak; *diff_ts = (uint32_t)*this_ts - *test_ts; *test_ts = (uint32_t)*this_ts; @@ -873,19 +1086,26 @@ static inline void dfs_add_to_pulseline( "ts%u %u %u diff %u pl->pl_lastelem.p_time=%llu", (uint32_t)*this_ts, (*re).re_dur, (*re).re_rssi, *diff_ts, - (uint64_t)pl->pl_elems[index].p_time); + (uint64_t)pl->pl_elems[*index].p_time); } /** * dfs_conditional_clear_delaylines - Clear delay lines to remove the * false pulses. * @dfs: Pointer to wlan_dfs structure. - * @diff_ts: diff between timerstamps + * @diff_ts: diff between timerstamps. + * @this_ts: this timestamp value. + * @re: Pointer to dfs_event structure. */ static inline void dfs_conditional_clear_delaylines( struct wlan_dfs *dfs, - uint32_t diff_ts) + uint32_t diff_ts, + uint64_t this_ts, + struct dfs_event re) { + struct dfs_pulseline *pl = dfs->pulses; + uint32_t index; + /* 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 @@ -894,15 +1114,39 @@ static inline void dfs_conditional_clear_delaylines( * false detects. */ - if (diff_ts < 100) { + if (diff_ts < DFS_INVALID_PRI_LIMIT) { + dfs->dfs_seq_num = 0; dfs_reset_alldelaylines(dfs); dfs_reset_radarq(dfs); + + 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; + pl->pl_elems[index].p_sidx = re.re_sidx; + pl->pl_elems[index].p_delta_peak = re.re_delta_peak; + dfs->dfs_seq_num++; + pl->pl_elems[index].p_seq_num = dfs->dfs_seq_num; } } + /** * dfs_process_each_radarevent - remove each event from the dfs radar queue * and process it. * @dfs: Pointer to wlan_dfs structure. + * @chan: Pointer to DFS current channel. + * @rs: Pointer to dfs_state structure. + * @seg_id: segment id. + * @retval: pointer to retval. + * @false_radar_found: pointer to false radar found. + * * Return: If radar found then return 1 else return 0. */ static inline int dfs_process_each_radarevent( @@ -910,18 +1154,21 @@ static inline int dfs_process_each_radarevent( struct dfs_ieee80211_channel *chan, struct dfs_state **rs, uint8_t *seg_id, - int *retval) + int *retval, + int *false_radar_found) { 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; + static uint32_t test_ts; + static uint32_t diff_ts; + uint32_t index; dfs_is_radarq_empty(dfs, &empty); - while ((!empty) && (!*retval) && (events_processed < MAX_EVENTS)) { + while ((!empty) && (!*retval) && !(*false_radar_found) && + (events_processed < MAX_EVENTS)) { dfs_remove_event_from_radarq(dfs, &event); if (!event) { empty = 1; @@ -943,11 +1190,12 @@ static inline int dfs_process_each_radarevent( re.re_dur = dfs_process_pulse_dur(dfs, re.re_dur); - dfs_add_to_pulseline(dfs, &re, &this_ts, &test_ts, &diff_ts); + dfs_add_to_pulseline(dfs, &re, &this_ts, &test_ts, &diff_ts, + &index); - dfs_log_event(dfs, &re, this_ts, diff_ts); + dfs_log_event(dfs, &re, this_ts, diff_ts, index); - dfs_conditional_clear_delaylines(dfs, diff_ts); + dfs_conditional_clear_delaylines(dfs, diff_ts, this_ts, re); found = 0; dfs_check_if_bin5(dfs, &re, this_ts, diff_ts, &found); @@ -957,7 +1205,7 @@ static inline int dfs_process_each_radarevent( } dfs_check_if_nonbin5(dfs, &re, rs, this_ts, diff_ts, &found, - retval); + retval, false_radar_found); dfs_is_radarq_empty(dfs, &empty); } @@ -965,6 +1213,22 @@ static inline int dfs_process_each_radarevent( return 0; } +/** + * dfs_false_radarfound_reset_vars () - Reset dfs variables after false radar + * found. + * @dfs: Pointer to wlan_dfs structure. + */ +static inline void dfs_false_radarfound_reset_vars( + struct wlan_dfs *dfs) +{ + dfs->dfs_seq_num = 0; + dfs_reset_radarq(dfs); + dfs_reset_alldelaylines(dfs); + dfs->dfs_phyerr_freq_min = 0x7fffffff; + dfs->dfs_phyerr_freq_max = 0; + dfs->dfs_phyerr_w53_counter = 0; +} + int dfs_process_radarevent( struct wlan_dfs *dfs, struct dfs_ieee80211_channel *chan) @@ -972,6 +1236,7 @@ int dfs_process_radarevent( struct dfs_state *rs = NULL; uint8_t seg_id = 0; int retval = 0; + int false_radar_found = 0; if (!dfs_radarevent_basic_sanity(dfs, chan)) return 0; @@ -985,11 +1250,15 @@ int dfs_process_radarevent( if (!dfs_handle_missing_pulses(dfs, chan)) return 0; - dfs_process_each_radarevent(dfs, chan, &rs, &seg_id, &retval); + dfs_process_each_radarevent(dfs, chan, &rs, &seg_id, &retval, + &false_radar_found); dfsfound: if (retval) dfs_radarfound_reset_vars(dfs, rs, chan, seg_id); + if (false_radar_found) + dfs_false_radarfound_reset_vars(dfs); + return retval; } diff --git a/umac/dfs/core/src/filtering/dfs_radar.c b/umac/dfs/core/src/filtering/dfs_radar.c index e6a5f8e65fef..398b77cd7be6 100644 --- a/umac/dfs/core/src/filtering/dfs_radar.c +++ b/umac/dfs/core/src/filtering/dfs_radar.c @@ -31,30 +31,30 @@ */ struct dfs_pulse dfs_fcc_radars[] = { /* FCC TYPE 1 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, - {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, + {18, 1, 700, 700, 0, 4, 5, 0, 1, 18, 0, 3, 1, 5, 0, 0}, + {18, 1, 350, 350, 0, 4, 5, 0, 1, 18, 0, 3, 0, 5, 0, 0}, /* FCC TYPE 6 */ - {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, + {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1000, 0, 1}, /* FCC TYPE 2 */ - {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2}, + {23, 5, 4347, 6666, 0, 4, 11, 0, 7, 22, 0, 3, 0, 5, 0, 2}, /* FCC TYPE 3 */ - {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5}, + {18, 10, 2000, 5000, 0, 4, 8, 6, 13, 22, 0, 3, 0, 5, 0, 5}, /* FCC TYPE 4 */ - {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11}, + {16, 15, 2000, 5000, 0, 4, 7, 11, 23, 22, 0, 3, 0, 5, 0, 11}, /* FCC NEW TYPE 1 */ /* 518us to 938us pulses (min 56 pulses) */ - {57, 1, 1066, 1930, 0, 6, 20, 0, 1, 22, 0, 3, 0, 21}, + {57, 1, 1066, 1930, 0, 4, 20, 0, 1, 22, 0, 3, 0, 5, 0, 21}, /* 938us to 2000 pulses (min 26 pulses) */ - {27, 1, 500, 1066, 0, 6, 13, 0, 1, 22, 0, 3, 0, 22}, + {27, 1, 500, 1066, 0, 4, 13, 0, 1, 22, 0, 3, 0, 5, 0, 22}, /* 2000 to 3067us pulses (min 17 pulses) */ - {18, 1, 325, 500, 0, 6, 9, 0, 1, 22, 0, 3, 0, 23}, + {18, 1, 325, 500, 0, 4, 9, 0, 1, 22, 0, 3, 0, 5, 0, 23}, }; /** @@ -64,31 +64,31 @@ struct dfs_pulse dfs_mkk4_radars[] = { /* following two filters are specific to Japan/MKK4 */ /* 1389 +/- 6 us */ - {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, + {18, 1, 720, 720, 0, 4, 6, 0, 1, 18, 0, 3, 0, 5, 0, 17}, /* 4000 +/- 6 us */ - {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, + {18, 4, 250, 250, 0, 4, 5, 1, 6, 18, 0, 3, 0, 5, 0, 18}, /* 3846 +/- 7 us */ - {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, + {18, 5, 260, 260, 0, 4, 6, 1, 6, 18, 0, 3, 1, 5, 0, 19}, /* following filters are common to both FCC and JAPAN */ /* FCC TYPE 1 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, - {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, + {18, 1, 700, 700, 0, 4, 5, 0, 1, 18, 0, 3, 1, 5, 0, 0}, + {18, 1, 350, 350, 0, 4, 5, 0, 1, 18, 0, 3, 0, 5, 0, 0}, /* FCC TYPE 6 */ - {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, + {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1000, 0, 1}, /* FCC TYPE 2 */ - {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2}, + {23, 5, 4347, 6666, 0, 4, 11, 0, 7, 22, 0, 3, 0, 5, 0, 2}, /* FCC TYPE 3 */ - {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5}, + {18, 10, 2000, 5000, 0, 4, 8, 6, 13, 22, 0, 3, 0, 5, 0, 5}, /* FCC TYPE 4 */ - {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11}, + {16, 15, 2000, 5000, 0, 4, 7, 11, 23, 22, 0, 3, 0, 5, 0, 11}, }; /** @@ -96,7 +96,7 @@ struct dfs_pulse dfs_mkk4_radars[] = { * chipsets. */ struct dfs_bin5pulse dfs_fcc_bin5pulses[] = { - {4, 28, 105, 12, 22, 5}, + {5, 28, 105, 12, 22, 5}, }; /** @@ -119,7 +119,7 @@ struct dfs_bin5pulse dfs_jpn_bin5pulses[] = { */ struct dfs_bin5pulse dfs_fcc_bin5pulses_ar900b[] = { - {4, 28, 105, 12, 20, 5}, + {5, 28, 105, 12, 20, 5}, }; /** @@ -141,7 +141,7 @@ struct dfs_bin5pulse dfs_jpn_bin5pulses_ar900b[] = { * raise the threshold. */ struct dfs_bin5pulse dfs_fcc_bin5pulses_qca9984[] = { - {4, 20, 105, 12, 20, 0}, + {5, 20, 105, 12, 20, 0}, }; /** @@ -160,30 +160,31 @@ struct dfs_pulse dfs_etsi_radars[] = { /* TYPE staggered pulse */ /* Type 5*/ /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ - {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, + {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 5, 0, 31}, /* Type 6 */ /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */ - {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, + {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 5, 0, 32}, /* constant PRF based */ /* Type 1 */ /* 0.8-5us, 200 300 PRF, 10 pulses */ - {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, - {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, - {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, - {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, + {10, 5, 200, 400, 0, 4, 5, 0, 8, 15, 0, 0, 2, 5, 0, 33}, + {10, 5, 400, 600, 0, 4, 5, 0, 8, 15, 0, 0, 2, 5, 0, 37}, + {10, 5, 600, 800, 0, 4, 5, 0, 8, 15, 0, 0, 2, 5, 0, 38}, + {10, 5, 800, 1000, 0, 4, 5, 0, 8, 15, 0, 0, 2, 5, 0, 39}, + /* {10, 5, 200, 1000, 0, 6, 5, 0, 8, 15, 0, 0, 2, 5, 33}, */ /* Type 2 */ /* 0.8-15us, 200-1600 PRF, 15 pulses */ - {15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 34}, + {15, 15, 200, 1600, 0, 4, 8, 0, 18, 24, 0, 0, 0, 5, 0, 34}, /* Type 3 */ /* 0.8-15us, 2300-4000 PRF, 25 pulses*/ - {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 35}, + {25, 15, 2300, 4000, 0, 4, 10, 0, 18, 24, 0, 0, 0, 5, 0, 35}, /* Type 4 */ /* 20-30us, 2000-4000 PRF, 20 pulses*/ - {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 36}, + {20, 30, 2000, 4000, 0, 4, 6, 19, 33, 24, 0, 0, 0, 24, 1, 36}, }; /** @@ -229,16 +230,16 @@ struct dfs_pulse dfs_china_radars[] = { */ struct dfs_pulse dfs_korea_radars[] = { /* Korea Type 1 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 40}, + {18, 1, 700, 700, 0, 4, 5, 0, 1, 18, 0, 3, 1, 5, 0, 40}, /* Korea Type 2 */ - {10, 1, 1800, 1800, 0, 6, 4, 0, 1, 18, 0, 3, 1, 41}, + {10, 1, 1800, 1800, 0, 4, 4, 0, 1, 18, 0, 3, 1, 5, 0, 41}, /* Korea Type 3 */ - {70, 1, 330, 330, 0, 6, 20, 0, 2, 18, 0, 3, 1, 42}, + {70, 1, 330, 330, 0, 4, 20, 0, 2, 18, 0, 3, 1, 5, 0, 42}, /* Korea Type 4 */ - {3, 1, 3003, 3003, 1, 7, 2, 0, 1, 18, 0, 0, 1, 43}, + {3, 1, 3003, 3003, 1, 7, 2, 0, 1, 18, 0, 0, 1, 1000, 0, 43}, }; #define RSSI_THERSH_AR900B 15 diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index b1d525294023..aacc8d95277f 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/umac/dfs/core/src/misc/dfs.c @@ -888,22 +888,25 @@ int dfs_control(struct wlan_dfs *dfs, for (i = 0; (i < DFS_EVENT_LOG_SIZE) && (i < dfs->dfs_event_log_count); i++) { +#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", - 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), - dfs->radar_log[i].peak_mag, - dfs->radar_log[i].total_gain, - dfs->radar_log[i].mb_gain, - dfs->radar_log[i].relpwr_db); + "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", + 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, + FREQ_OFFSET1, + FREQ_OFFSET2, + dfs->radar_log[i].peak_mag, + dfs->radar_log[i].total_gain, + 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->dfs_event_log_count = 0; dfs->dfs_phyerr_count = 0;