Example #1
0
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;
}
Example #5
0
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;
}
Example #6
0
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 {
Example #7
0
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;
}