📄 if_ath_radar.c.svn-base
字号:
int32_t a_max_misses, HAL_BOOL a_match_midpoint, int32_t b_matched, int32_t b_missed, int32_t b_mean_period, int32_t b_noise, int32_t b_min_evts, int32_t b_max_evts, int32_t b_min_rep_int, int32_t b_max_rep_int, int32_t b_min_pulse, int32_t b_max_misses, HAL_BOOL b_match_midpoint ){ /* Intermediate calculations */ int32_t a_total = a_matched + a_missed; int32_t b_total = b_matched + b_missed; int32_t a_excess_total = MAX((int32_t)(a_total - (int32_t)a_max_evts), 0); int32_t b_excess_total = MAX((int32_t)(b_total - (int32_t)b_max_evts), 0); u_int64_t a_duration = a_total * a_mean_period; u_int64_t b_duration = b_total * b_mean_period; u_int64_t a_excess_duration = a_excess_total * a_mean_period; u_int64_t b_excess_duration = b_excess_total * b_mean_period; u_int64_t a_dist_from_pri_mid = labs(a_mean_period - (a_min_rep_int + ((a_max_rep_int - a_min_rep_int) / 2))); u_int64_t b_dist_from_pri_mid = labs(b_mean_period - (b_min_rep_int + ((b_max_rep_int - b_min_rep_int) / 2))); /* Did one radar have fewer excess total pulse intervals than the * other? */ if (a_excess_total != b_excess_total) return ((a_excess_total < b_excess_total) ? 1 : -1) * CR_EXCESS_INTERVALS; /* Was one pulse longer chronologically, even though totals matched? */ else if (a_excess_duration != b_excess_duration) return ((a_excess_duration < b_excess_duration) ? 1 : -1) * CR_EXCESS_DURATION; /* Did one get more matches? */ if (a_matched != b_matched) return (a_matched > b_matched ? 1 : -1) * CR_PULSES; /* Both waveforms are the same length, same total. * Did one get more misses? */ if (a_missed != b_missed) return (a_missed < b_missed ? 1 : -1) * CR_MISSES; /* Did one get more noise? */ if (a_noise != b_noise) return (a_noise < b_noise ? 1 : -1) * CR_NOISE; /* If both waveforms were not too long in terms of intervals */ if (0 == (a_excess_total+b_excess_total)) { /* Did one waveform have to match more events than the other? */ if (a_total != b_total) return ((a_total > b_total) ? 1 : -1) * CR_INTERVALS; /* Was one waveform longer than the other */ if (a_duration != b_duration) return ((a_duration > b_duration) ? 1 : -1) * CR_DURATION; } /* both durations are legal, but one is closer to the original PRF/PRI */ if (a_dist_from_pri_mid != b_dist_from_pri_mid) { if (a_match_midpoint && b_match_midpoint) { /* Which pattern is closer to midpoint? */ return ((a_dist_from_pri_mid < b_dist_from_pri_mid) ? 1 : -1) * CR_MIDPOINT_A; } else if (a_match_midpoint) { /* If not within spitting distance of midpoint, reject */ return ((a_dist_from_pri_mid < 3) ? 1 : -1) * CR_MIDPOINT_B; } else if (b_match_midpoint) { /* If not within spitting distance of midpoint, reject */ return ((b_dist_from_pri_mid >= 3) ? 1 : -1) * CR_MIDPOINT_C; } } return -CR_FALLTHROUGH;}#ifdef ATH_RADAR_LONG_PULSEstruct lp_burst { u_int32_t lpb_num_pulses; u_int32_t lpb_num_noise; u_int32_t lpb_tsf_delta; u_int64_t lpb_tsf_rel; u_int64_t lpb_min_possible_tsf; /* noise vs real pulses */ u_int64_t lpb_max_possible_tsf; /* noise vs real pulses */};static const u_int32_t LP_MIN_BC = 8;static const u_int32_t LP_MAX_BC = 20;static const u_int32_t LP_NUM_BC = 13; /* (LP_MAX_BC - LP_MIN_BC + 1); */static const u_int64_t LP_TSF_FUZZ_US = 32768; /* (1<<15) because rs_tstamp * rollover errors */static const u_int32_t LP_MIN_PRI = 1000;static const u_int32_t LP_MAX_PRI = 2000;static void rp_analyze_long_pulse_bscan( struct ath_softc *sc, struct ath_rp *last_pulse, u_int32_t *num_bursts, size_t bursts_buflen, struct lp_burst *bursts){ int i = 0; struct ath_rp *newer = NULL; struct ath_rp *cur = last_pulse; struct ath_rp *older = pulse_prev(last_pulse); u_int32_t waveform_num_bursts = 0; if (num_bursts) *num_bursts = 0; for (;;) { /* check if we are at the end of the list */ if (&cur->list == &sc->sc_rp_head) break; if (!cur->rp_allocated) break; if (NULL != newer) { u_int64_t tsf_delta = 0; u_int64_t tsf_adjustment = 0; /* Figure out TSF delta, taking into account * up to one multiple of (1<<15) of clock jitter * due to interrupt latency */ tsf_delta = newer->rp_tsf - cur->rp_tsf; if ((tsf_delta - LP_TSF_FUZZ_US) >= LP_MIN_PRI && (tsf_delta - LP_TSF_FUZZ_US) <= LP_MAX_PRI) { tsf_adjustment = LP_TSF_FUZZ_US; tsf_delta -= tsf_adjustment; } /* If we are in range for pulse, assume it is a pulse. */ if ((tsf_delta >= LP_MIN_PRI) && (tsf_delta <= LP_MAX_PRI)) { bursts[waveform_num_bursts].lpb_num_pulses++; bursts[waveform_num_bursts].lpb_min_possible_tsf = cur->rp_tsf - tsf_adjustment; } else if (tsf_delta < LP_MIN_PRI) { bursts[waveform_num_bursts].lpb_num_noise++; /* It may have been THE pulse after all... */ bursts[waveform_num_bursts].lpb_min_possible_tsf = cur->rp_tsf - tsf_adjustment; } else /* tsf_delta > LP_MAX_PRI */ { bursts[waveform_num_bursts].lpb_num_pulses++; bursts[waveform_num_bursts].lpb_min_possible_tsf = cur->rp_tsf; /* Do not overrun bursts_buflen */ if ((waveform_num_bursts+1) >= bursts_buflen) { break; } waveform_num_bursts++; bursts[waveform_num_bursts].lpb_tsf_delta = tsf_delta; bursts[waveform_num_bursts].lpb_min_possible_tsf = cur->rp_tsf; bursts[waveform_num_bursts].lpb_max_possible_tsf = cur->rp_tsf; } } else { bursts[waveform_num_bursts].lpb_max_possible_tsf = cur->rp_tsf; } /* advance to next pulse */ newer = cur; cur = pulse_prev(cur); older = pulse_prev(cur); } if (num_bursts) { bursts[waveform_num_bursts].lpb_num_pulses++; waveform_num_bursts++; *num_bursts = waveform_num_bursts; } for (i = 0; i < waveform_num_bursts; i++) bursts[i].lpb_tsf_rel = bursts[i].lpb_max_possible_tsf - bursts[waveform_num_bursts-1].lpb_min_possible_tsf;}static HAL_BOOL rp_analyze_long_pulse( struct ath_softc *sc, struct ath_rp *last_pulse, u_int32_t *bc, u_int32_t *matched, u_int32_t *missed, u_int32_t *noise, u_int32_t *pulses) { int i; int32_t found_radar = 0; int32_t found_burst_count = 0; int32_t matching_burst_count = 0; u_int32_t best_bc = 0; u_int32_t best_matched = 0; u_int32_t best_missed = 0; u_int32_t best_noise = 0; u_int32_t best_pulses = 0; struct lp_burst bursts[LP_MAX_BC]; memset(&bursts, 0, sizeof(bursts)); if (bc) *bc = 0; if (matched) *matched = 0; if (missed) *missed = 0; if (noise) *noise = 0; rp_analyze_long_pulse_bscan(sc, last_pulse, &found_burst_count, LP_MAX_BC, &bursts[0]); /* Find the matches */ for (matching_burst_count = LP_MAX_BC; matching_burst_count >= LP_MIN_BC; matching_burst_count--) { int32_t first_matched_index = -1; int32_t last_matched_index = -1; int32_t match_burst_index = 0; int32_t found_burst_index = 0; int32_t burst_period = (12000000 / matching_burst_count); int32_t waveform_offset = 0; int32_t total_big_gaps = 0; int32_t matched_span = 0; int32_t missed_bursts = 0; int32_t matched_bursts = 0; for (i = 0; i < matching_burst_count; i++) { int32_t d = bursts[i].lpb_tsf_delta; while (d >= burst_period) d -= burst_period; total_big_gaps += d; waveform_offset = MAX(waveform_offset, d); } waveform_offset *= -1; found_burst_index = 0; for (match_burst_index = 0; match_burst_index < matching_burst_count; match_burst_index++) { int64_t limit_high = (burst_period * (matching_burst_count - 1 - match_burst_index + 1)) + (2 * LP_TSF_FUZZ_US); int64_t limit_low = (burst_period * (matching_burst_count - 1 - match_burst_index)) - (2 * LP_TSF_FUZZ_US); /* If the burst is too old, skip it... it's noise too... */ while ((((int64_t)bursts[found_burst_index].lpb_tsf_rel + waveform_offset) > limit_high)) { if (found_burst_index < (found_burst_count - 1)) found_burst_index++; else break; } if ((((int64_t)bursts[found_burst_index].lpb_tsf_rel + waveform_offset) <= limit_high) && (((int64_t)bursts[found_burst_index].lpb_tsf_rel + waveform_offset) >= limit_low)) { if (-1 == first_matched_index) { first_matched_index = match_burst_index; matched_span = 1; } if (last_matched_index < match_burst_index) { last_matched_index = match_burst_index; } DPRINTF(sc, ATH_DEBUG_DOTHFILT, "LP %2dp] [%2d/%2d] %10lld " "in {%lld:%lld}] PASS\n", matching_burst_count, found_burst_index, match_burst_index, (int64_t)bursts[found_burst_index].lpb_tsf_rel - waveform_offset, limit_low, limit_high); matched_bursts++; found_burst_index++; } else { DPRINTF(sc, ATH_DEBUG_DOTHFILT, "LP %2dp] [%2d/%2d] %10lld " "in {%lld:%lld}] MISSED\n", matching_burst_count, match_burst_index, found_burst_index, (int64_t)bursts[found_burst_index].lpb_tsf_rel - waveform_offset, limit_low, limit_high); missed_bursts++; } } matched_span = last_matched_index - first_matched_index; DPRINTF(sc, ATH_DEBUG_DOTHFILT, "LP %2dp] burst_period=%10d, " "waveform_offset=%10d, matches=%2d/%2d, " "result=%s\n", matching_burst_count, burst_period, waveform_offset, matched_span, matching_burst_count, (matching_burst_count == matched_span) ? "MATCH" : "MISMATCH" ); /* XXX - Add comparison logic rather than taking first/last * match based upon ATH_DEBUG_DOTHFILTNOSC? */ if (matched_span >= (matching_burst_count - 4)) { found_radar++; best_bc = matching_burst_count; best_matched = matched_bursts; best_missed = missed_bursts; best_noise = 0; best_pulses = 0; for (i = 0; i <= found_burst_index; i++) { best_noise += bursts[match_burst_index].lpb_num_noise; best_pulses += bursts[match_burst_index].lpb_num_pulses; } if (!DFLAG_ISSET(sc, ATH_DEBUG_DOTHFILTNOSC)) break; } } if (bc) *bc = best_bc; if (matched) *matched = best_matched; if (missed) *missed = best_missed; if (noise) *noise = best_noise; if (pulses) *pulses = best_pulses; return found_radar ? AH_TRUE : AH_FALSE;}#endif /* #ifdef ATH_RADAR_LONG_PULSE */static HAL_BOOL rp_analyze_short_pulse( struct ath_softc *sc, struct ath_rp *last_pulse, u_int32_t *index, u_int32_t *pri, u_int32_t *matching_pulses, u_int32_t *missed_pulses, u_int32_t *noise_pulses){ int i; int best_index = -1; unsigned int best_matched = 0; unsigned int best_noise = 0; unsigned int best_missed = 0; unsigned int best_pri = 0; unsigned int best_cr = 0; u_int64_t t0_min, t0_max, t1, t_min, t_max; u_int32_t noise = 0, matched = 0, missed = 0, partial_miss = 0; struct ath_rp *pulse; u_int32_t pulse_count_minimum = 0; struct radar_pattern_specification *pattern = NULL; struct radar_pattern_specification *best_pattern = NULL; u_int32_t new_period = 0; u_int64_t last_tsf = 0; u_int32_t last_seen_period = 0; u_int32_t sum_periods = 0; u_int32_t mean_period = 0; u_int32_t adjusted_max_rep_int = 0; u_int32_t adjusted_min_rep_int = 0; if (index) *index = 0; if (pri) *pri = 0; if (noise_pulses) *noise_pulses = 0; if (matching_pulses) *matching_pulses = 0; if (missed_pulses) *missed_pulses = 0; /* we need at least sc_rp_min (>2 pulses) */ pulse_count_minimum = sc->sc_rp_min; if ((sc->sc_rp_num < pulse_count_minimum) || (sc->sc_rp_num < 2)) return 0; /* Search algorithm: * * - since we have a limited and known number of radar patterns, we * loop on all possible radar pulse period * * - we start the search from the last timestamp (t1), going * backward in time, up to the point for the first possible radar * pulse, ie t0_min - PERIOD * BURST_MAX * * - on this timescale, we matched the number of hit/missed using T - * PERIOD * n taking into account the 2% error margin (using * min_rep_int, max_rep_int) * * At the end, we have a number of pulse hit for each PRF * * TSF will roll over after just over 584,542 years of operation * without restart. * * This exceeds all known Atheros MTBF so, forget about TSF roll over. */ /* t1 is the timestamp of the last radar pulse */ t1 = (u_int64_t)last_pulse->rp_tsf; /* loop through all patterns */ for (i = 0; i < sizetab(radar_patterns); i++) { pattern = &radar_patterns[i]; /* underflow */ if ((pattern->min_rep_int * (pattern->min_evts - 1)) >= t1) { DPRINTF(sc, ATH_DEBUG_DOTHFILTVBSE, "%s: %s skipped (last pulse isn't old enough to" " match this pattern). %10llu >= %10llu.\n", SC_DEV_NAME(sc), pattern->name, (u_int64_t)( pattern->min_rep_int * pattern->min_evts), (u_int64_t)t1); continue; } /* this min formula is to check for underflow. It's the * minimum needed duration to gather specified number of * matches, assuming minimum match interval. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -