Example #1
0
void dfs_process_ar_event(struct ath_softc *sc, HAL_CHANNEL *chan)
{
	struct ath_dfs *dfs=sc->sc_dfs;
	struct dfs_ar_state *ar;
	struct dfs_event *re=NULL;
	u_int32_t sumpeak=0,numpeaks,rssi,width,origregionsum=0, i;
	u_int16_t thistimestamp;
	int empty;

	if (dfs == NULL) {
		DFS_DPRINTK(sc, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n",
			__func__);
		return;
	}
	ar = (struct dfs_ar_state *) &(dfs->dfs_ar_state);
	ATH_ARQ_LOCK(dfs);
	empty = STAILQ_EMPTY(&(dfs->dfs_arq));
	ATH_ARQ_UNLOCK(dfs);
	while (!empty) {
		ATH_ARQ_LOCK(dfs);
		re = STAILQ_FIRST(&(dfs->dfs_arq));
		if (re != NULL)
			STAILQ_REMOVE_HEAD(&(dfs->dfs_arq), re_list);
		ATH_ARQ_UNLOCK(dfs);
		if (re == NULL)
			return;

		thistimestamp = re->re_ts;
		rssi = re->re_rssi;
		width = re->re_dur;

		/* Return the dfs event to the free event list */
		OS_MEMZERO(re, sizeof(struct dfs_event));
		ATH_DFSEVENTQ_LOCK(dfs);
		STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), re, re_list);
		ATH_DFSEVENTQ_UNLOCK(dfs);

		/* determine if current radar is an extension of previous radar */
		if (ar->ar_prevwidth == 255) {
			/* tag on previous width for consideraion of low data rate ACKs */
			ar->ar_prevwidth += width;
			width = (width == 255) ? 255 : ar->ar_prevwidth;
		} else if ((width == 255) &&
			   (ar->ar_prevwidth == 510 ||
			    ar->ar_prevwidth == 765 ||
			    ar->ar_prevwidth == 1020)) {
			/* Aggregate up to 5 consecuate max radar widths
			 * to consider 11Mbps long preamble 1500-byte pkts
			 */
			ar->ar_prevwidth += width;
		} else if (ar->ar_prevwidth == 1275 && width != 255) {
			/* Found 5th consecute maxed out radar, reset history */
			width += ar->ar_prevwidth;
			ar->ar_prevwidth = 0;
		} else if (ar->ar_prevwidth > 255) {
			/* Ignore if there are less than 5 consecutive maxed out radars */
			ar->ar_prevwidth = width;
			width = 255;
		} else {
			ar->ar_prevwidth = width;
		}
		/* For ignoring noises with radar duration in ranges of 3-30: AP4x */
		if ((width >= 257 && width <= 278) ||	/* Region 7 - 5.5Mbps (long pre) ACK = 270 = 216 us */
		    (width >= 295 && width <= 325) ||	/* Region 8 - 2Mbps (long pre) ACKC = 320 = 256us */
		    (width >= 1280 && width <= 1300)) {
			u_int16_t wraparoundadj=0;
			u_int16_t base = (width >= 1280) ? 1275 : 255;
			if (thistimestamp < ar->ar_prevtimestamp) {
				wraparoundadj = 32768;
			}
			if ((thistimestamp + wraparoundadj - ar->ar_prevtimestamp) !=
			    (width - base)) {
				width = 1;
			}
		}
		if (width <= 10) {
			ATH_ARQ_LOCK(dfs);
			empty = STAILQ_EMPTY(&(dfs->dfs_arq));
			ATH_ARQ_UNLOCK(dfs);
			continue;
		}
		/*
		 * Overloading the width=2 in: Store a count of radars w/max duration
		 * and high RSSI (not noise)
		 */
		if ((width == 255) && (rssi > DFS_AR_RSSI_THRESH_STRONG_PKTS))
			width = 2;
		/*
		 * Overloading the width=3 bin:
		 *   Double and store a count of rdars of durtaion that matches 11Mbps (long preamble)
		 *   TCP ACKs or 1500-byte data packets
		 */
		if ((width >= 1280 && width <= 1300) ||
		    (width >= 318 && width <= 325)) {
			width = 3;
			ar->ar_phyerrcount[3] += 2;
			ar->ar_acksum += 2;
		}
		/* build histogram of radar duration */
		if (width > 0 && width <= 510)
			ar->ar_phyerrcount[width]++;
		else {
			/* invalid radar width, throw it away */
			ATH_ARQ_LOCK(dfs);
			empty = STAILQ_EMPTY(&(dfs->dfs_arq));
			ATH_ARQ_UNLOCK(dfs);
			continue;
		}
		/* Received radar of interest (i.e., signature match), proceed to check if
		 * there is enough neighboring traffic to drop out of Turbo 
		 */
		if ((width >= 33 && width <= 38) ||          /* Region 0: 24Mbps ACK = 35 = 28us */
		    (width >= 39 && width <= 44) ||          /* Region 1: 12Mbps ACK = 40 = 32us */
		    (width >= 53 && width <= 58) ||          /* Region 2:  6Mbps ACK = 55 = 44us */
		    (width >= 126 && width <= 140) ||        /* Region 3: 11Mbps ACK = 135 = 108us */
		    (width >= 141 && width <= 160) ||        /* Region 4: 5.5Mbps ACK = 150 = 120us */
		    (width >= 189 && width <= 210) ||        /* Region 5:  2Mbps ACK = 200 = 160us */
		    (width >= 360 && width <= 380) ||        /* Region 6   1Mbps ACK = 400 = 320us */
		    (width >= 257 && width <= 270) ||        /* Region 7   5.5Mbps (Long Pre) ACK = 270 = 216us */
		    (width >= 295 && width <= 302) ||        /* Region 8   2Mbps (Long Pre) ACK = 320 = 256us */
		    /* Ignoring Region 9 due to overlap with 255 which is same as board noise */
		    /* Region 9  11Mbps (Long Pre) ACK = 255 = 204us */            
		    (width == 3)) {
			ar->ar_acksum++;
			/* double the count for strong radars that match one of the ACK signatures */
			if (rssi > DFS_AR_RSSI_DOUBLE_THRESHOLD) {
				ar->ar_phyerrcount[width]++;
				ar->ar_acksum++;
			}
			UPDATE_TOP_THREE_PEAKS(ar->ar_phyerrcount,
					       ar->ar_peaklist, width);
			/* sum the counts of these peaks */
			numpeaks = DFS_AR_MAX_NUM_PEAKS;
			origregionsum = ar->ar_acksum;
			for (i = 0; i < DFS_AR_MAX_NUM_PEAKS; i++) {
				if (ar->ar_peaklist[i] > 0) {
					if ((i==0) &&
					    (ar->ar_peaklist[i] == 3) &&
					    (ar->ar_phyerrcount[3] <
					     ar->ar_phyerrcount[2]) &&
					    (ar->ar_phyerrcount[3] > 6)) {
						/*
						 * If the top peak is one that
						 * maches the 11Mbps long
						 * preamble TCP Ack/1500-byte
						 * data, include the count for
						 * radars that hav emax
						 * duration and high rssi
						 * (width = 2) to boost the
						 * sum for the PAR test that
						 * follows */
						sumpeak += (ar->ar_phyerrcount[2]
							    + ar->ar_phyerrcount[3]);
						ar->ar_acksum += (ar->ar_phyerrcount[2]
								  + ar->ar_phyerrcount[3]);
					} else {
						sumpeak += ar->ar_phyerrcount[ar->ar_peaklist[i]];
					}
				} else 
					numpeaks--;
			}
			/*
			 * If sum of patterns matches exceeds packet threshold,
			 * perform comparison between peak-to-avg ratio against parThreshold
			 */
			if ((ar->ar_acksum > ar->ar_packetthreshold) &&
			    ((sumpeak * DFS_AR_REGION_WIDTH) > (ar->ar_parthreshold * numpeaks *
								ar->ar_acksum))) {
				/* neighboring traffic detected, get out of Turbo */
				chan->priv_flags |= CHANNEL_INTERFERENCE;
				OS_MEMZERO(ar->ar_peaklist, sizeof(ar->ar_peaklist));
				ar->ar_acksum = 0;
				OS_MEMZERO(ar->ar_phyerrcount, sizeof(ar->ar_phyerrcount));
			} else {
				/*
				 * reset sum of matches to discount the count of
				 * strong radars with max duration
				 */
				ar->ar_acksum = origregionsum;
			}
		}
		ar->ar_prevtimestamp = thistimestamp;
		ATH_ARQ_LOCK(dfs);
		empty = STAILQ_EMPTY(&(dfs->dfs_arq));
		ATH_ARQ_UNLOCK(dfs);
	}
}
Example #2
0
static void
ath_AR_event(struct net_device *dev, const struct ath_desc *ds,
             struct sk_buff *skb)
{
    struct ath_softc *sc = dev->priv;
    struct ath_phyerr_state *pe;
    u_int32_t sumPeak=0,numPeaks,rssi,width,origRegionSum=0, i;
    u_int16_t thisTimeStamp;

    KASSERT(sc->sc_phyerr_state != NULL,
            ("NULL phyerr_state"));
    pe = (struct ath_phyerr_state *) sc->sc_phyerr_state;
    thisTimeStamp =(u_int16_t) ds->ds_rxstat.rs_tstamp;
    rssi = ds->ds_rxstat.rs_rssi;
    width = ds->ds_rxstat.rs_datalen ?
            (u_int32_t)(*((u_int8_t *) skb->data)) : 0;
    width &= 0xff;	/* Only lower 8 bits are valid */

    /* determine if current radar is an extension of previous radar */
    if (pe->pe_arState.ar_prevWidth == 255) {
        /* tag on previous width for consideraion of low data rate ACKs */
        pe->pe_arState.ar_prevWidth += width;
        width = (width == 255) ? 255 : pe->pe_arState.ar_prevWidth;
    } else if ((width == 255) &&
               (pe->pe_arState.ar_prevWidth == 510 ||
                pe->pe_arState.ar_prevWidth == 765 ||
                pe->pe_arState.ar_prevWidth == 1020)) {
        /* Aggregate up to 5 consecuate max radar widths
         * to consider 11Mbps long preamble 1500-byte pkts
         */
        pe->pe_arState.ar_prevWidth += width;
    } else if (pe->pe_arState.ar_prevWidth == 1275 && width != 255) {
        /* Found 5th consecute maxed out radar, reset history */
        width += pe->pe_arState.ar_prevWidth;
        pe->pe_arState.ar_prevWidth = 0;
    } else if (pe->pe_arState.ar_prevWidth > 255) {
        /* Ignore if there are less than 5 consecutive maxed out radars */
        pe->pe_arState.ar_prevWidth = width;
        width = 255;
    } else {
        pe->pe_arState.ar_prevWidth = width;
    }
    /* For ignoring noises with radar duration in ranges of 3-30: AP4x */
    if ((width >= 257 && width <= 278) ||	/* Region 7 - 5.5Mbps (long pre) ACK = 270 = 216 us */
            (width >= 295 && width <= 325) ||	/* Region 8 - 2Mbps (long pre) ACKC = 320 = 256us */
            (width >= 1280 && width <= 1300)) {
        u_int16_t wrapAroundAdj=0;
        u_int16_t base = (width >= 1280) ? 1275 : 255;
        if (thisTimeStamp < pe->pe_arState.ar_prevTimeStamp) {
            wrapAroundAdj = 32768;
        }
        if ((thisTimeStamp + wrapAroundAdj - pe->pe_arState.ar_prevTimeStamp) !=
                (width - base)) {
            width = 1;
        }
    }
    if (width <= 10)
        return;

    /*
     * Overloading the width=2 in: Store a count of radars w/max duration
     * and high RSSI (not noise)
     */
    if ((width == 255) && (rssi > ATH_AR_RSSI_THRESH_STRONG_PKTS))
        width = 2;

    /*
     * Overloading the width=3 bin:
     *   Double and store a count of rdars of durtaion that matches 11Mbps (long preamble)
     *   TCP ACKs or 1500-byte data packets
     */
    if ((width >= 1280 && width <= 1300) ||
            (width >= 318 && width <= 325)) {
        width = 3;
        pe->pe_arState.ar_phyErrCount[3] += 2;
        pe->pe_arState.ar_ackSum += 2;
    }

    /* build histogram of radar duration */
    if (width > 0 && width <= 510)
        pe->pe_arState.ar_phyErrCount[width]++;
    else
        /* invalid radar width, throw it away */
        return;
    /* Received radar of interest (i.e., signature match), proceed to check if
     * there is enough neighboring traffic to drop out of Turbo
     */
    if ((width >= 33 && width <= 38) ||          /* Region 0: 24Mbps ACK = 35 = 28us */
            (width >= 39 && width <= 44) ||          /* Region 1: 12Mbps ACK = 40 = 32us */
            (width >= 53 && width <= 58) ||          /* Region 2:  6Mbps ACK = 55 = 44us */
            (width >= 126 && width <= 140) ||        /* Region 3: 11Mbps ACK = 135 = 108us */
            (width >= 141 && width <= 160) ||        /* Region 4: 5.5Mbps ACK = 150 = 120us */
            (width >= 189 && width <= 210) ||        /* Region 5:  2Mbps ACK = 200 = 160us */
            (width >= 360 && width <= 380) ||        /* Region 6   1Mbps ACK = 400 = 320us */
            (width >= 257 && width <= 270) ||        /* Region 7   5.5Mbps (Long Pre) ACK = 270 = 216us */
            (width >= 295 && width <= 302) ||        /* Region 8   2Mbps (Long Pre) ACK = 320 = 256us */
            /* Ignoring Region 9 due to overlap with 255 which is same as board noise */
            /* Region 9  11Mbps (Long Pre) ACK = 255 = 204us */
            (width == 3)) {
        pe->pe_arState.ar_ackSum++;

        /* double the count for strong radars that match one of the ACK signatures */
        if (rssi > ATH_AR_RSSI_DOUBLE_THRESHOLD) {
            pe->pe_arState.ar_phyErrCount[width]++;
            pe->pe_arState.ar_ackSum++;
        }
        UPDATE_TOP_THREE_PEAKS(pe->pe_arState.ar_phyErrCount,
                               pe->pe_arState.ar_peakList, width);
        /* sum the counts of these peaks */
        numPeaks = ATH_MAX_NUM_PEAKS;
        origRegionSum = pe->pe_arState.ar_ackSum;
        for (i=0; i<= ATH_MAX_NUM_PEAKS; i++) {
            if (pe->pe_arState.ar_peakList[i] > 0) {
                if ((i==0) &&
                        (pe->pe_arState.ar_peakList[i] == 3) &&
                        (pe->pe_arState.ar_phyErrCount[3] <
                         pe->pe_arState.ar_phyErrCount[2]) &&
                        (pe->pe_arState.ar_phyErrCount[3] > 6)) {
                    /*
                     * If the top peak is one that
                     * maches the 11Mbps long
                     * preamble TCP Ack/1500-byte
                     * data, include the count for
                     * radars that hav emax
                     * duration and high rssi
                     * (width = 2) to boost the
                     * sum for the PAR test that
                     * follows */
                    sumPeak += (pe->pe_arState.ar_phyErrCount[2]
                                + pe->pe_arState.ar_phyErrCount[3]);
                    pe->pe_arState.ar_ackSum += (pe->pe_arState.ar_phyErrCount[2]
                                                 + pe->pe_arState.ar_phyErrCount[3]);
                } else {
                    sumPeak += pe->pe_arState.ar_phyErrCount[pe->pe_arState.ar_peakList[i]];
                }
            } else
                numPeaks--;
        }

        /*
         * If sum of patterns matches exceeds packet threshold,
         * perform comparison between peak-to-avg ratio against parThreshold
         */
        if ((pe->pe_arState.ar_ackSum > pe->pe_arState.ar_packetThreshold) &&
                ((sumPeak * ATH_AR_REGION_WIDTH) > (pe->pe_arState.ar_parThreshold * numPeaks *
                        pe->pe_arState.ar_ackSum))) {
            /* neighboring traffic detected, get out of Turbo */
            sc->sc_curchan.channelFlags |= CHANNEL_AR;

            memset(pe->pe_arState.ar_peakList, 0,
                   sizeof(pe->pe_arState.ar_peakList));
            pe->pe_arState.ar_ackSum = 0;
            memset(pe->pe_arState.ar_phyErrCount, 0,
                   sizeof(pe->pe_arState.ar_phyErrCount));
        } else {
            /*
             * reset sum of matches to discount the count of
             * strong radars with max duration
             */
            pe->pe_arState.ar_ackSum = origRegionSum;
        }
    }
    pe->pe_arState.ar_prevTimeStamp = thisTimeStamp;
}