int is_unique_pri(u_int32_t highestpri , u_int32_t midpri, u_int32_t lowestpri , u_int32_t refpri ) { #define DFS_STAGGERED_PRI_MARGIN_MIN 20 #define DFS_STAGGERED_PRI_MARGIN_MAX 400 if ((DFS_DIFF(lowestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) && (DFS_DIFF(midpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) && (DFS_DIFF(highestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN)) { return 1; } else { if ((is_pri_multiple(refpri, highestpri)) || (is_pri_multiple(refpri, lowestpri)) || (is_pri_multiple(refpri, midpri))) return 0; } return 0; #undef DFS_STAGGERED_PRI_MARGIN_MIN #undef DFS_STAGGERED_PRI_MARGIN_MAX }
int dfs_bin_pri_check(struct ath_dfs_host *dfs, struct dfs_filter *rf, struct dfs_delayline *dl, u_int32_t score, u_int32_t refpri, u_int32_t refdur, int ext_chan_flag, u_int32_t ext_chan_busy) { u_int32_t searchpri, searchdur, searchrssi, deltapri, deltadur, averagerefpri=0; int primultiples[6]; int delayindex, dindex; u_int32_t i, j, primargin, durmargin, highscore=score, highscoreindex=0; int numpulses=1; /*first pulse in the burst is most likely being filtered out based on maxfilterlen */ /*Use the adjusted PRI margin to reduce false alarms */ /* For non fixed pattern types, rf->rf_patterntype=0*/ primargin = dfs_get_pri_margin(ext_chan_flag, (rf->rf_patterntype==1), dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy); if(rf->rf_maxdur < 10) { durmargin = 4; } else { durmargin = 6; } if( score > 1) { for (i=0;i<dl->dl_numelems; i++) { dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; searchpri = dl->dl_elems[dindex].de_time; deltapri = DFS_DIFF(searchpri, refpri); if( deltapri < primargin) averagerefpri += searchpri; } refpri = (averagerefpri/score); /*average */ } /* Note: Following primultiple calculation should be done once per filter * during initialization stage (dfs_attach) and stored in its array * atleast for fixed frequency types like FCC Bin1 to save some CPU cycles. * multiplication, devide operators in the following code are left as it is * for readability hoping the complier will use left/right shifts wherever possible */ if( refpri > rf->rf_maxpri) { primultiples[0] = (refpri - refdur)/2; primultiples[1] = refpri; primultiples[2] = refpri + primultiples[0]; primultiples[3] = (refpri - refdur)*2; primultiples[4] = primultiples[3] + primultiples[0]; primultiples[5] = primultiples[3] + refpri; } else { primultiples[0] = refpri; primultiples[1] = refpri + primultiples[0]; primultiples[2] = refpri + primultiples[1]; primultiples[3] = refpri + primultiples[2]; primultiples[4] = refpri + primultiples[3]; primultiples[5] = refpri + primultiples[4]; } DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "pri0 = %d pri1 = %d pri2 = %d pri3 = %d pri4 = %d pri5 = %d\n", primultiples[0], primultiples[1], primultiples[2], primultiples[3], primultiples[4], primultiples[5]); DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "refpri = %d high score = %d index = %d numpulses = %d\n", refpri, highscore, highscoreindex, numpulses); /* Count the other delay elements that have pri and dur with in the * acceptable range from the reference one */ for (i=0; i<dl->dl_numelems; i++) { delayindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; searchpri = dl->dl_elems[delayindex].de_time; if( searchpri == 0) { /* This events PRI is zero, take it as a * valid pulse but decrement next event's PRI by refpri */ dindex = (delayindex+1)& DFS_MAX_DL_MASK; dl->dl_elems[dindex].de_time -= refpri; searchpri = refpri; } searchdur = dl->dl_elems[delayindex].de_dur; searchrssi = dl->dl_elems[delayindex].de_rssi; deltadur = DFS_DIFF(searchdur, refdur); for(j=0; j<6; j++) { deltapri = DFS_DIFF(searchpri, primultiples[j]); /* May need to revisit this as this increases the primargin by 5*/ /* if( deltapri < (primargin+j)) { */ if( deltapri < (primargin)) { if( deltadur < durmargin) { if( (refdur < 8) || ((refdur >=8)&& (searchrssi < 250))) { numpulses++; DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "rf->minpri=%d rf->maxpri=%d searchpri = %d index = %d numpulses = %d deltapri=%d j=%d\n", rf->rf_minpri, rf->rf_maxpri, searchpri, i, numpulses, deltapri, j); } } break; } } } return numpulses; }
int dfs_bin_fixedpattern_check(struct ath_dfs_host *dfs, struct dfs_filter *rf, u_int32_t dur, int ext_chan_flag, u_int32_t ext_chan_busy) { struct dfs_pulseline *pl = dfs->pulses; int i, n, refpri, primargin, numpulses=0; u_int64_t start_ts, end_ts, event_ts, prev_event_ts, next_event_ts, window_start, window_end; u_int32_t index, next_index, deltadur; /* For fixed pattern types, rf->rf_patterntype=1*/ primargin = dfs_get_pri_margin(ext_chan_flag, (rf->rf_patterntype==1),dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy); refpri = (rf->rf_minpri + rf->rf_maxpri)/2; index = pl->pl_lastelem; end_ts = pl->pl_elems[index].p_time; start_ts = end_ts - (refpri*rf->rf_numpulses); DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, "lastelem ts=%llu start_ts=%llu, end_ts=%llu\n", (unsigned long long)pl->pl_elems[index].p_time, (unsigned long long)start_ts, (unsigned long long)end_ts); /* find the index of first element in our window of interest */ for(i=0;i<pl->pl_numelems;i++) { index = (index-1) & DFS_MAX_PULSE_BUFFER_MASK; if(pl->pl_elems[index].p_time >= start_ts ) continue; else { index = (index) & DFS_MAX_PULSE_BUFFER_MASK; break; } } for (n=0;n<=rf->rf_numpulses; n++) { window_start = (start_ts + (refpri*n))-(primargin+n); window_end = window_start + 2*(primargin+n); DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "window_start %u window_end %u \n", (u_int32_t)window_start, (u_int32_t)window_end); for(i=0;i<pl->pl_numelems;i++) { prev_event_ts = pl->pl_elems[index].p_time; index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK; event_ts = pl->pl_elems[index].p_time; next_index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK; next_event_ts = pl->pl_elems[next_index].p_time; DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "ts %u \n", (u_int32_t)event_ts); if( (event_ts <= window_end) && (event_ts >= window_start)){ deltadur = DFS_DIFF(pl->pl_elems[index].p_dur, dur); if( (pl->pl_elems[index].p_dur == 1) || ((dur != 1) && (deltadur <= 2))) { numpulses++; DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "numpulses %u \n", numpulses); break; } } else if( event_ts > window_end) { index = (index-1) & DFS_MAX_PULSE_BUFFER_MASK; break; } else if( event_ts == prev_event_ts) { if( ((next_event_ts - event_ts) > refpri) || ((next_event_ts - event_ts) == 0)) { deltadur = DFS_DIFF(pl->pl_elems[index].p_dur, dur); if( (pl->pl_elems[index].p_dur == 1) || ((pl->pl_elems[index].p_dur != 1) && (deltadur <= 2))) { numpulses++; DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "zero PRI: numpulses %u \n", numpulses); break; } } } } } if (numpulses >= dfs_get_filter_threshold(rf, ext_chan_flag, dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy)) { DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s FOUND filterID=%u numpulses=%d unadj thresh=%d\n", __func__, rf->rf_pulseid, numpulses, rf->rf_threshold); return 1; } else return 0; }
int dfs_bin_check(struct ath_dfs_host *dfs, struct dfs_filter *rf, u_int32_t deltaT, u_int32_t width, int ext_chan_flag, u_int32_t ext_chan_busy) { u_int32_t refpri, refdur, searchpri, deltapri, averagerefpri; u_int32_t n, i, primargin, durmargin, highscore, highscoreindex; int score[DFS_MAX_DL_SIZE], delayindex, dindex, found=0; struct dfs_delayline *dl; u_int32_t scoreindex, lowpriindex= 0, lowpri = 0xffff; int numpulses=0; dl = &rf->rf_dl; if( dl->dl_numelems < (rf->rf_threshold-1)) { return 0; } if( deltaT > rf->rf_filterlen) return 0; primargin = dfs_get_pri_margin(ext_chan_flag, (rf->rf_patterntype==1), dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy); if(rf->rf_maxdur < 10) { durmargin = 4; } else { durmargin = 6; } if( rf->rf_patterntype == 1 ){ found = dfs_bin_fixedpattern_check(dfs, rf, width, ext_chan_flag, ext_chan_busy); if(found) { dl->dl_numelems = 0; } return found; } OS_MEMZERO(score, sizeof(int)*DFS_MAX_DL_SIZE); /* find out the lowest pri */ for (n=0;n<dl->dl_numelems; n++) { delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; refpri = dl->dl_elems[delayindex].de_time; if( refpri == 0) continue; else if(refpri < lowpri) { lowpri = dl->dl_elems[delayindex].de_time; lowpriindex = n; } } /* find out the each delay element's pri score */ for (n=0;n<dl->dl_numelems; n++) { delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; refpri = dl->dl_elems[delayindex].de_time; if( refpri == 0) continue; for (i=0;i<dl->dl_numelems; i++) { dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; searchpri = dl->dl_elems[dindex].de_time; deltapri = DFS_DIFF(searchpri, refpri); if( deltapri < primargin) score[n]++; } if( score[n] > rf->rf_threshold) { /* we got the most possible candidate, * no need to continue further */ break; } } /* find out the high scorer */ highscore = 0; highscoreindex = 0; for (n=0;n<dl->dl_numelems; n++) { if( score[n] > highscore) { highscore = score[n]; highscoreindex = n; } else if( score[n] == highscore ) { /*more than one pri has highscore take the least pri */ delayindex = (dl->dl_firstelem + highscoreindex) & DFS_MAX_DL_MASK; dindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; if( dl->dl_elems[dindex].de_time <= dl->dl_elems[delayindex].de_time ) { highscoreindex = n; } } } /* find the average pri of pulses around the pri of highscore or * the pulses around the lowest pri */ if( highscore < 3) { scoreindex = lowpriindex; } else { scoreindex = highscoreindex; } /* We got the possible pri, save its parameters as reference */ delayindex = (dl->dl_firstelem + scoreindex) & DFS_MAX_DL_MASK; refdur = dl->dl_elems[delayindex].de_dur; refpri = dl->dl_elems[delayindex].de_time; averagerefpri = 0; numpulses = dfs_bin_pri_check(dfs, rf, dl, score[scoreindex], refpri, refdur, ext_chan_flag, ext_chan_busy); if (numpulses >= dfs_get_filter_threshold(rf, ext_chan_flag, dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy)) { found = 1; DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "ext_flag=%d MATCH filter=%u numpulses=%u thresh=%u refpri=%d primargin=%d\n", ext_chan_flag, rf->rf_pulseid, numpulses,rf->rf_threshold, refpri, primargin); dfs_print_delayline(dfs, &rf->rf_dl); dfs_print_filter(dfs, rf); } return found; }
int dfs_staggered_check(struct ath_dfs_host *dfs, struct dfs_filter *rf, u_int32_t deltaT, u_int32_t width, u_int32_t ext_chan_busy) { u_int32_t refpri, refdur, searchpri=0, deltapri;/*, averagerefpri; */ u_int32_t n, i, primargin, durmargin; int score[DFS_MAX_DL_SIZE], delayindex, dindex, found=0; struct dfs_delayline *dl; u_int32_t scoreindex, lowpriindex= 0, lowpri = 0xffff; int numpulses=0, higherthan, lowerthan, numscores; u_int32_t lowestscore=0, lowestscoreindex=0, lowestpri=0; u_int32_t midscore=0, midscoreindex=0, midpri=0; u_int32_t highestscore=0, highestscoreindex=0, highestpri=0; dl = &rf->rf_dl; if( dl->dl_numelems < (rf->rf_threshold-1)) { DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "numelems %d < threshold for filter %d\n", dl->dl_numelems, rf->rf_pulseid); return 0; } if( deltaT > rf->rf_filterlen) { DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "numelems %d < threshold for filter %d\n", dl->dl_numelems, rf->rf_pulseid); return 0; } primargin = 10; if(rf->rf_maxdur < 10) { durmargin = 4; } else { durmargin = 6; } OS_MEMZERO(score, sizeof(int)*DFS_MAX_DL_SIZE); /* find out the lowest pri */ for (n=0;n<dl->dl_numelems; n++) { delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; refpri = dl->dl_elems[delayindex].de_time; if( refpri == 0) continue; else if(refpri < lowpri) { lowpri = dl->dl_elems[delayindex].de_time; lowpriindex = n; } } /* find out the each delay element's pri score */ for (n=0;n<dl->dl_numelems; n++) { delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; refpri = dl->dl_elems[delayindex].de_time; if( refpri == 0) continue; for (i=0;i<dl->dl_numelems; i++) { dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; searchpri = dl->dl_elems[dindex].de_time; deltapri = DFS_DIFF(searchpri, refpri); if( deltapri < primargin) score[n]++; } if( score[n] > rf->rf_threshold) { /* we got the most possible candidate, * no need to continue further */ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "THRESH score[%d]=%d pri=%d\n", n, score[n], searchpri); break; } } for (n=0;n<dl->dl_numelems; n++) { delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; refdur = dl->dl_elems[delayindex].de_time; DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "score[%d]=%d pri=%d\n", n, score[n], refdur); } /* find out the 2 or 3 highest scorers */ scoreindex = 0; highestscore=0; highestscoreindex=0; highestpri=0; numscores=0; lowestscore=0; for (n=0;n<dl->dl_numelems; n++) { higherthan=0; lowerthan=0; delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; refpri = dl->dl_elems[delayindex].de_time; if ((score[n] >= highestscore) && (is_unique_pri(highestpri, midpri, lowestpri, refpri))) { lowestscore = midscore; lowestpri = midpri; lowestscoreindex = midscoreindex; midscore = highestscore; midpri = highestpri; midscoreindex = highestscoreindex; highestscore = score[n]; highestpri = refpri; highestscoreindex = n; } else { if ((score[n] >= midscore) && (is_unique_pri(highestpri, midpri, lowestpri, refpri))) { lowestscore = midscore; lowestpri = midpri; lowestscoreindex = midscoreindex; midscore = score[n]; midpri = refpri; midscoreindex = n; } else if ((score[n] >= lowestscore) && (is_unique_pri(highestpri, midpri, lowestpri, refpri))) { lowestscore = score[n]; lowestpri = refpri; lowestscoreindex = n; } } } DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "FINAL highestscore=%d highestscoreindex=%d highestpri=%d\n", highestscore, highestscoreindex, highestpri); DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "FINAL lowestscore=%d lowestscoreindex=%d lowpri=%d\n", lowestscore, lowestscoreindex, lowestpri); DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "FINAL midscore=%d midscoreindex=%d midpri=%d\n", midscore, midscoreindex, midpri); delayindex = (dl->dl_firstelem + highestscoreindex) & DFS_MAX_DL_MASK; refdur = dl->dl_elems[delayindex].de_dur; refpri = dl->dl_elems[delayindex].de_time; DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "highscoreindex=%d refdur=%d refpri=%d\n", highestscoreindex, refdur, refpri); numpulses += dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur, 0, ext_chan_busy); ; delayindex = (dl->dl_firstelem + midscoreindex) & DFS_MAX_DL_MASK; refdur = dl->dl_elems[delayindex].de_dur; refpri = dl->dl_elems[delayindex].de_time; DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "midscoreindex=%d refdur=%d refpri=%d\n", midscoreindex, refdur, refpri); numpulses += dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur, 0, ext_chan_busy); ; delayindex = (dl->dl_firstelem + lowestscoreindex) & DFS_MAX_DL_MASK; refdur = dl->dl_elems[delayindex].de_dur; refpri = dl->dl_elems[delayindex].de_time; DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "lowestscoreindex=%d refdur=%d refpri=%d\n", lowestscoreindex, refdur, refpri); numpulses += dfs_bin_pri_check(dfs, rf, dl, lowestscore, refpri, refdur, 0, ext_chan_busy); DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "numpulses=%d\n",numpulses); if (numpulses >= rf->rf_threshold) { found = 1; DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "MATCH filter=%u numpulses=%u thresh=%u\n", rf->rf_pulseid, numpulses,rf->rf_threshold); } return found; }
int dfs_bin_check(struct ath_softc *sc, struct dfs_filter *rf, u_int32_t deltaT, u_int32_t width, int ext_chan_flag) { u_int32_t refpri, refdur, searchpri, deltapri,deltapri_2,deltapri_3, averagerefpri; u_int32_t n, i, primargin, durmargin, highscore, highscoreindex; int score[DFS_MAX_DL_SIZE], delayindex, dindex, found=0; struct dfs_delayline *dl; u_int32_t scoreindex, lowpriindex= 0, lowpri = 0xffff; int numpulses=0; int lowprichk=3,pri_match=0; dl = &rf->rf_dl; if( dl->dl_numelems < (rf->rf_threshold-1)) { return 0; } if( deltaT > rf->rf_filterlen) return 0; primargin = dfs_get_pri_margin(sc, ext_chan_flag, (rf->rf_patterntype==1)); if(rf->rf_maxdur < 10) { durmargin = 4; } else { durmargin = 6; } if( rf->rf_patterntype == 1 ){ found = dfs_bin_fixedpattern_check(sc, rf, width, ext_chan_flag); if(found) { dl->dl_numelems = 0; } return found; } OS_MEMZERO(score, sizeof(int)*DFS_MAX_DL_SIZE); /* find out the lowest pri */ for (n=0;n<dl->dl_numelems; n++) { delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; refpri = dl->dl_elems[delayindex].de_time; if( refpri == 0) continue; else if(refpri < lowpri) { lowpri = dl->dl_elems[delayindex].de_time; lowpriindex = n; } } /* find out the each delay element's pri score */ for (n=0;n<dl->dl_numelems; n++) { delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; refpri = dl->dl_elems[delayindex].de_time; if( refpri == 0) continue; if (refpri < rf->rf_maxpri) { // use only valid PRI range for high score for (i=0;i<dl->dl_numelems; i++) { dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; searchpri = dl->dl_elems[dindex].de_time; deltapri = DFS_DIFF(searchpri, refpri); deltapri_2 = DFS_DIFF(searchpri, 2*refpri); deltapri_3 = DFS_DIFF(searchpri, 3*refpri); if (rf->rf_ignore_pri_window==2) { pri_match = ((deltapri < primargin) || (deltapri_2 < primargin) || (deltapri_3 < primargin)); } else { pri_match = (deltapri < primargin); } if (pri_match) score[n]++; } } else { score[n] = 0; } if( score[n] > rf->rf_threshold) { /* we got the most possible candidate, * no need to continue further */ break; } } /* find out the high scorer */ highscore = 0; highscoreindex = 0; for (n=0;n<dl->dl_numelems; n++) { if( score[n] > highscore) { highscore = score[n]; highscoreindex = n; } else if( score[n] == highscore ) { /*more than one pri has highscore take the least pri */ delayindex = (dl->dl_firstelem + highscoreindex) & DFS_MAX_DL_MASK; dindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; if( dl->dl_elems[dindex].de_time <= dl->dl_elems[delayindex].de_time ) { highscoreindex = n; } } } /* find the average pri of pulses around the pri of highscore or * the pulses around the lowest pri */ if (rf->rf_ignore_pri_window > 0) { lowprichk = (rf->rf_threshold >> 1)+1; } else {
int dfs_bin5_check(struct ath_dfs_host *dfs) { struct dfs_bin5radars *br; int index[DFS_MAX_B5_SIZE]; u_int32_t n, i, this, prev, rssi_diff, width_diff, bursts= 0; u_int32_t total_diff=0, average_diff, total_width=0, average_width, numevents=0; u_int64_t pri; if (dfs == NULL) { A_PRINTF("%s: sc_dfs is NULL\n", __func__); return 1; } for (n=0;n<dfs->dfs_rinfo.rn_numbin5radars; n++) { br = &(dfs->dfs_b5radars[n]); DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "Num elems = %d\n", br->br_numelems); prev = br->br_firstelem; for(i=0;i<br->br_numelems;i++){ this = ((br->br_firstelem +i) & DFS_MAX_B5_MASK); /* Rule 1: 1000 <= PRI <= 2000 + some margin */ if( br->br_elems[this].be_ts >= br->br_elems[prev].be_ts ) { pri = br->br_elems[this].be_ts - br->br_elems[prev].be_ts; } else {//roll over case //pri = (0xffffffffffffffff - br->br_elems[prev].be_ts) + br->br_elems[this].be_ts; pri = br->br_elems[this].be_ts; } DFS_DPRINTK(dfs, ATH_DEBUG_DFS2," pri=%llu this.ts=%llu prev.ts=%llu\n", pri, br->br_elems[this].be_ts, br->br_elems[prev].be_ts); if(( (pri >= DFS_BIN5_PRI_LOWER_LIMIT) && (pri <= DFS_BIN5_PRI_HIGHER_LIMIT))) { //pri: pulse repitition interval in us /* Rule 2: pulse width of the pulses in the burst should be same (+/- margin) */ if( br->br_elems[this].be_dur >= br->br_elems[prev].be_dur) { width_diff = br->br_elems[this].be_dur - br->br_elems[prev].be_dur; } else { width_diff = br->br_elems[prev].be_dur - br->br_elems[this].be_dur; } if( width_diff <= DFS_BIN5_WIDTH_MARGIN ) { /* Rule 3: RSSI of the pulses in the burst should be same (+/- margin) */ if( br->br_elems[this].be_rssi >= br->br_elems[prev].be_rssi) { rssi_diff = br->br_elems[this].be_rssi - br->br_elems[prev].be_rssi; } else { rssi_diff = br->br_elems[prev].be_rssi - br->br_elems[this].be_rssi; } if( rssi_diff <= DFS_BIN5_RSSI_MARGIN ) { bursts++; /* Save the indexes of this pair for later width variance check */ if( numevents >= 2 ) { /* make sure the event is not duplicated, * possible in a 3 pulse burst */ if( index[numevents-1] != prev) { index[numevents++] = prev; } } else { index[numevents++] = prev; } index[numevents++] = this; } else { DFS_DPRINTK(dfs,ATH_DEBUG_DFS2,"%s %d Bin5 rssi_diff=%d\n", __func__, __LINE__, rssi_diff); } } else { DFS_DPRINTK(dfs,ATH_DEBUG_DFS2,"%s %d Bin5 width_diff=%d\n", __func__, __LINE__, width_diff); } } else { DFS_DPRINTK(dfs,ATH_DEBUG_DFS2,"%s %d Bin5 PRI check fail pri=%llu\n", __func__, __LINE__,pri); } prev = this; } DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "bursts=%u numevents=%u\n", bursts, numevents); if ( bursts >= br->br_pulse.b5_threshold) { if( (br->br_elems[br->br_lastelem].be_ts - br->br_elems[br->br_firstelem].be_ts) < 3000000 ) { return 0; } else { for (i=0; i<numevents; i++){ total_width += br->br_elems[index[i]].be_dur; } average_width = total_width/numevents; for (i=0; i<numevents; i++){ total_diff += DFS_DIFF(br->br_elems[index[i]].be_dur, average_width); } average_diff = total_diff/numevents; if( average_diff > DFS_BIN5_WIDTH_MARGIN ) { return 1; } else { DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n", bursts, numevents, total_width, average_width, total_diff, average_diff); } } } } return 0; }