summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKapil Gupta <kapgupta@qti.qualcomm.com>2016-07-08 18:05:27 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-07-28 14:36:58 +0530
commit7015e35e17d8196c36fe098f580b950e63d0ca2b (patch)
tree665dd6a3e96e44b672fb6c4eca30f924a3caa555
parent374acff684621da082d7df176e2b1bd9b41e49f2 (diff)
qcacld-2.0: WAR for dfs false detection
Hardware sometimes get phyerrors in presence of third party devices which may be identified as radar pulses. Add following workaround to skip these pulses on basis of their characteristics: 1. Add new filters for pulses coming on DC position 2. Increased min threshold for filter 5 3. Flush other DC queue once we get pulse belonging to one queue 4. Add extra workaround for FCC filter 31 and 32 to reset the queues based on deviation from mean. 5. Remove rejection of pulses based on max pri(channel load optimization) CRs-Fixed: 1039381 Change-Id: I9b3fea04fa2f6a9cc85dde4fd9eaab8b6b490fd8
-rw-r--r--CORE/SERVICES/DFS/inc/dfs.h7
-rw-r--r--CORE/SERVICES/DFS/src/dfs.c92
-rw-r--r--CORE/SERVICES/DFS/src/dfs_debug.c23
-rw-r--r--CORE/SERVICES/DFS/src/dfs_init.c125
-rw-r--r--CORE/SERVICES/DFS/src/dfs_process_radarevent.c199
-rw-r--r--CORE/VOSS/inc/vos_types.h6
6 files changed, 441 insertions, 11 deletions
diff --git a/CORE/SERVICES/DFS/inc/dfs.h b/CORE/SERVICES/DFS/inc/dfs.h
index 632636296b08..52ae15f1dea4 100644
--- a/CORE/SERVICES/DFS/inc/dfs.h
+++ b/CORE/SERVICES/DFS/inc/dfs.h
@@ -89,6 +89,7 @@
#include "dfs_interface.h"
#include "_ieee80211_common.h"
#include "vos_api.h"
+#include "sirDebug.h"
#define ATH_SUPPORT_DFS 1
#define CHANNEL_TURBO 0x00010
@@ -128,6 +129,7 @@
//#define MAX_BIN5_DUR 131 /* 105 * 1.25*/
#define MAX_BIN5_DUR 145 /* use 145 for osprey */ //conversion is already done using dfs->dur_multiplier//
#define MAX_BIN5_DUR_MICROSEC 105
+#define MAX_DFS_RADAR_TYPE 256
#define DFS_MARGIN_EQUAL(a, b, margin) ((DFS_DIFF(a,b)) <= margin)
#define DFS_MAX_STAGGERED_BURSTS 3
@@ -265,6 +267,7 @@ struct dfs_pulseline {
#define DFS_EVENT_HW_CHIRP 0x02 /* hardware chirp */
#define DFS_EVENT_SW_CHIRP 0x04 /* software chirp */
+
/*
* Use this only if the event has CHECKCHIRP set.
*/
@@ -298,6 +301,7 @@ struct dfs_event {
#pragma pack(pop, dfs_event)
#endif
+#define DFS_FILTER_DEFAULT_PRI 1000000
#define DFS_AR_MAX_ACK_RADAR_DUR 511
#define DFS_AR_MAX_NUM_PEAKS 3
#define DFS_AR_ARQ_SIZE 2048 /* 8K AR events for buffer size */
@@ -569,10 +573,13 @@ struct ath_dfs {
/* dfs_radarf - One filter for each radar pulse type */
struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES];
+ struct dfs_filtertype *dfs_dc_radarf[DFS_MAX_RADAR_TYPES];
struct dfs_info dfs_rinfo; /* State vars for radar processing */
struct dfs_bin5radars *dfs_b5radars;/* array of bin5 radar events */
int8_t **dfs_radartable; /* map of radar durs to filter types */
+ /* map of dc radar durs to filter types */
+ int8_t **dfs_dc_radartable;
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
struct dfs_nolelem *dfs_nol; /* Non occupancy list for radar */
int dfs_nol_count; /* How many items? */
diff --git a/CORE/SERVICES/DFS/src/dfs.c b/CORE/SERVICES/DFS/src/dfs.c
index 5a918ff6660a..57b51b19a384 100644
--- a/CORE/SERVICES/DFS/src/dfs.c
+++ b/CORE/SERVICES/DFS/src/dfs.c
@@ -362,7 +362,7 @@ dfs_attach(struct ieee80211com *ic)
dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
- /* Allocate memory for radar filters */
+ /* Allocate memory for radar filters */
for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
dfs->dfs_radarf[n] = (struct dfs_filtertype *)OS_MALLOC(NULL, sizeof(struct dfs_filtertype),GFP_ATOMIC);
if (dfs->dfs_radarf[n] == NULL) {
@@ -375,12 +375,28 @@ dfs_attach(struct ieee80211com *ic)
goto bad1;
}
}
- /* Allocate memory for radar table */
+
+ /* Allocate memory for dc radar filters */
+ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+ dfs->dfs_dc_radarf[n] =
+ (struct dfs_filtertype *)OS_MALLOC(NULL,
+ sizeof(struct dfs_filtertype), GFP_ATOMIC);
+ if (!(dfs->dfs_dc_radarf[n])) {
+ DFS_PRINTK("%s: cannot allocate memory for dc radar filter types\n",
+ __func__);
+ goto bad1;
+ }
+ vos_mem_zero(dfs->dfs_dc_radarf[n], sizeof(struct dfs_filtertype));
+ if (0 != dfs_alloc_mem_filter(dfs->dfs_dc_radarf[n]))
+ goto bad4;
+ }
+
+ /* Allocate memory for radar table */
dfs->dfs_radartable = (int8_t **)OS_MALLOC(NULL, 256*sizeof(int8_t *), GFP_ATOMIC);
if (dfs->dfs_radartable == NULL) {
DFS_PRINTK("%s: cannot allocate memory for radar table\n",
__func__);
- goto bad1;
+ goto bad4;
}
for (n=0; n<256; n++) {
dfs->dfs_radartable[n] = OS_MALLOC(NULL, DFS_MAX_RADAR_OVERLAP*sizeof(int8_t),
@@ -392,6 +408,26 @@ dfs_attach(struct ieee80211com *ic)
}
}
+ /* Allocate memory for dc radar table */
+ dfs->dfs_dc_radartable = (int8_t **)OS_MALLOC(NULL,
+ MAX_DFS_RADAR_TYPE * sizeof(int8_t *),
+ GFP_ATOMIC);
+ if (!dfs->dfs_dc_radartable) {
+ DFS_PRINTK("%s: cannot allocate memory for radar table\n",
+ __func__);
+ goto bad2;
+ }
+ for (n = 0; n < MAX_DFS_RADAR_TYPE; n++) {
+ dfs->dfs_dc_radartable[n] = OS_MALLOC(NULL,
+ DFS_MAX_RADAR_OVERLAP * sizeof(int8_t),
+ GFP_ATOMIC);
+ if (!(dfs->dfs_dc_radartable[n])) {
+ DFS_PRINTK("%s: cannot allocate memory for dc radar table entry\n",
+ __func__);
+ goto bad3;
+ }
+ }
+
if (usenol == 0)
DFS_PRINTK("%s: NOL disabled\n", __func__);
else if (usenol == 2)
@@ -429,9 +465,36 @@ dfs_attach(struct ieee80211com *ic)
dfs->ath_dfs_nol_timeout = DFS_NOL_TIMEOUT_S;
return 0;
+bad3:
+ if (!(dfs->dfs_dc_radartable)) {
+ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+ if (!(dfs->dfs_dc_radartable[n])) {
+ OS_FREE(dfs->dfs_dc_radartable[n]);
+ dfs->dfs_dc_radartable[n] = NULL;
+ }
+ }
+ OS_FREE(dfs->dfs_dc_radartable);
+ dfs->dfs_dc_radartable = NULL;
+ }
bad2:
- OS_FREE(dfs->dfs_radartable);
- dfs->dfs_radartable = NULL;
+ if (dfs->dfs_radartable != NULL) {
+ for (n=0; n < DFS_MAX_RADAR_TYPES; n++) {
+ if (dfs->dfs_radartable[n] != NULL) {
+ OS_FREE(dfs->dfs_radartable[n]);
+ dfs->dfs_radartable[n] = NULL;
+ }
+ }
+ OS_FREE(dfs->dfs_radartable);
+ dfs->dfs_radartable = NULL;
+ }
+bad4:
+ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+ if (!(dfs->dfs_dc_radarf[n])) {
+ dfs_free_filter(dfs->dfs_dc_radarf[n]);
+ OS_FREE(dfs->dfs_dc_radarf[n]);
+ dfs->dfs_dc_radarf[n] = NULL;
+ }
+ }
bad1:
for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
if (dfs->dfs_radarf[n] != NULL) {
@@ -520,6 +583,14 @@ dfs_detach(struct ieee80211com *ic)
dfs->dfs_radarf[n] = NULL;
}
}
+ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+ if (!(dfs->dfs_dc_radarf[n])) {
+ dfs_free_filter(dfs->dfs_dc_radarf[n]);
+ OS_FREE(dfs->dfs_dc_radarf[n]);
+ dfs->dfs_dc_radarf[n] = NULL;
+ }
+ }
+
if (dfs->dfs_radartable != NULL) {
@@ -536,6 +607,17 @@ dfs_detach(struct ieee80211com *ic)
#endif
}
+ if (!(dfs->dfs_dc_radartable)) {
+ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+ if (!(dfs->dfs_dc_radartable[n])) {
+ OS_FREE(dfs->dfs_dc_radartable[n]);
+ dfs->dfs_dc_radartable[n] = NULL;
+ }
+ }
+ OS_FREE(dfs->dfs_dc_radartable);
+ dfs->dfs_dc_radartable = NULL;
+ }
+
if (dfs->dfs_b5radars != NULL) {
OS_FREE(dfs->dfs_b5radars);
dfs->dfs_b5radars=NULL;
diff --git a/CORE/SERVICES/DFS/src/dfs_debug.c b/CORE/SERVICES/DFS/src/dfs_debug.c
index 534d09d54add..efe88520852a 100644
--- a/CORE/SERVICES/DFS/src/dfs_debug.c
+++ b/CORE/SERVICES/DFS/src/dfs_debug.c
@@ -109,7 +109,8 @@ dfs_print_filters(struct ath_dfs *dfs)
ft = dfs->dfs_radarf[i];
if((ft->ft_numfilters > DFS_MAX_NUM_RADAR_FILTERS) || (!ft->ft_numfilters))
continue;
- DFS_PRINTK("===========ft->ft_numfilters=%u===========\n", ft->ft_numfilters);
+ DFS_PRINTK("===========ft->ft_numfilters=%u===========\n",
+ ft->ft_numfilters);
for (j=0; j<ft->ft_numfilters; j++) {
rf = ft->ft_filters[j];
DFS_PRINTK("filter[%d] filterID = %d rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n",j, rf->rf_pulseid,
@@ -117,6 +118,26 @@ dfs_print_filters(struct ath_dfs *dfs)
}
}
}
+
+ for (i=0; i < DFS_MAX_RADAR_TYPES; i++) {
+ if (dfs->dfs_dc_radarf[i])
+ continue;
+
+ ft = dfs->dfs_dc_radarf[i];
+ if ((ft->ft_numfilters > DFS_MAX_NUM_RADAR_FILTERS) ||
+ (!ft->ft_numfilters))
+ continue;
+ DFS_PRINTK("===========DC ft->ft_numfilters=%u===========\n",
+ ft->ft_numfilters);
+ for (j = 0; j < ft->ft_numfilters; j++) {
+ rf = ft->ft_filters[j];
+ DFS_PRINTK("DC filter[%d] filterID = %d rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n",
+ j, rf->rf_pulseid, rf->rf_numpulses, rf->rf_minpri,
+ rf->rf_maxpri, rf->rf_threshold, rf->rf_filterlen,
+ rf->rf_mindur, rf->rf_maxdur);
+ }
+ }
+
}
void dfs_print_activity(struct ath_dfs *dfs)
diff --git a/CORE/SERVICES/DFS/src/dfs_init.c b/CORE/SERVICES/DFS/src/dfs_init.c
index afa03e94d800..b85b5a8a29a4 100644
--- a/CORE/SERVICES/DFS/src/dfs_init.c
+++ b/CORE/SERVICES/DFS/src/dfs_init.c
@@ -115,6 +115,22 @@ void dfs_reset_alldelaylines(struct ath_dfs *dfs)
}
}
}
+ for (i = 0; i < DFS_MAX_RADAR_TYPES; i++) {
+ if (dfs->dfs_dc_radarf[i] == NULL)
+ continue;
+
+ ft = dfs->dfs_dc_radarf[i];
+ for (j = 0; j < ft->ft_numfilters; j++) {
+ rf = ft->ft_filters[j];
+ dl = &(rf->rf_dl);
+ if (dl == NULL)
+ continue;
+
+ OS_MEMZERO(dl, sizeof(struct dfs_delayline));
+ dl->dl_lastelem = (0xFFFFFFFF) & DFS_MAX_DL_MASK;
+ }
+ }
+
for (i = 0; i < dfs->dfs_rinfo.rn_numbin5radars; i++) {
OS_MEMZERO(&(dfs->dfs_b5radars[i].br_elems[0]), sizeof(struct dfs_bin5elem)*DFS_MAX_B5_SIZE);
dfs->dfs_b5radars[i].br_firstelem = 0;
@@ -230,6 +246,12 @@ int dfs_init_radar_filters(struct ieee80211com *ic,
for (i=0;i<DFS_MAX_RADAR_OVERLAP; i++)
(dfs->dfs_radartable[n])[i] = -1;
}
+ /* Clear dc filter type table */
+ for (n = 0; n < 256; n++) {
+ for (i = 0;i < DFS_MAX_RADAR_OVERLAP; i++)
+ (dfs->dfs_dc_radartable[n])[i] = -1;
+ }
+
/* Now, initialize the radar filters */
for (p=0; p<numradars; p++) {
ft = NULL;
@@ -319,8 +341,109 @@ int dfs_init_radar_filters(struct ieee80211com *ic,
}
+ /* Initialize dc radar filters */
+ for (p = 0; p < numradars; p++) {
+ ft = NULL;
+ for (n = 0; n < dfs->dfs_rinfo.rn_numradars; n++) {
+ if ((dfs_radars[p].rp_pulsedur ==
+ dfs->dfs_dc_radarf[n]->ft_filterdur) &&
+ (dfs_radars[p].rp_numpulses ==
+ dfs->dfs_dc_radarf[n]->ft_numpulses) &&
+ (dfs_radars[p].rp_mindur == dfs->dfs_dc_radarf[n]->ft_mindur) &&
+ (dfs_radars[p].rp_maxdur == dfs->dfs_dc_radarf[n]->ft_maxdur)) {
+
+ ft = dfs->dfs_dc_radarf[n];
+ break;
+ }
+ }
+ if (ft == NULL) {
+ /* No filter of the appropriate dur was found */
+ if ((dfs->dfs_rinfo.rn_numradars+1) > DFS_MAX_RADAR_TYPES) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Too many filter types",
+ __func__);
+ goto bad4;
+ }
+ ft = dfs->dfs_dc_radarf[dfs->dfs_rinfo.rn_numradars];
+ ft->ft_numfilters = 0;
+ ft->ft_numpulses = dfs_radars[p].rp_numpulses;
+ ft->ft_patterntype = dfs_radars[p].rp_patterntype;
+ ft->ft_mindur = dfs_radars[p].rp_mindur;
+ ft->ft_maxdur = dfs_radars[p].rp_maxdur;
+ ft->ft_filterdur = dfs_radars[p].rp_pulsedur;
+ ft->ft_rssithresh = dfs_radars[p].rp_rssithresh;
+ ft->ft_rssimargin = dfs_radars[p].rp_rssimargin;
+ ft->ft_minpri = DFS_FILTER_DEFAULT_PRI;
+
+ if (ft->ft_rssithresh < min_rssithresh)
+ min_rssithresh = ft->ft_rssithresh;
+ if (ft->ft_maxdur > max_pulsedur)
+ max_pulsedur = ft->ft_maxdur;
+ for (i = ft->ft_mindur; i <= ft->ft_maxdur; i++) {
+ u_int32_t stop = 0, tableindex = 0;
+
+ while ((tableindex < DFS_MAX_RADAR_OVERLAP) && (!stop)) {
+ if ((dfs->dfs_dc_radartable[i])[tableindex] == -1)
+ stop = 1;
+ else
+ tableindex++;
+ }
+ if (stop) {
+ (dfs->dfs_dc_radartable[i])[tableindex] =
+ (int8_t) (dfs->dfs_rinfo.rn_numradars);
+ } else {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
+ "%s: Too many overlapping dc radar filters",
+ __func__);
+ goto bad4;
+ }
+ }
+ dfs->dfs_rinfo.rn_numradars++;
+ }
+ rf = ft->ft_filters[ft->ft_numfilters++];
+ dfs_reset_delayline(&rf->rf_dl);
+ numpulses = dfs_radars[p].rp_numpulses;
+
+ rf->rf_numpulses = numpulses;
+ rf->rf_patterntype = dfs_radars[p].rp_patterntype;
+ rf->rf_pulseid = dfs_radars[p].rp_pulseid;
+ rf->rf_mindur = dfs_radars[p].rp_mindur;
+ rf->rf_maxdur = dfs_radars[p].rp_maxdur;
+ rf->rf_numpulses = dfs_radars[p].rp_numpulses;
+ rf->rf_ignore_pri_window = dfs_radars[p].rp_ignore_pri_window;
+ T = (100000000/dfs_radars[p].rp_max_pulsefreq) -
+ 100*(dfs_radars[p].rp_meanoffset);
+ rf->rf_minpri =
+ dfs_round((int32_t)T - (100*(dfs_radars[p].rp_pulsevar)));
+ Tmax = (100000000/dfs_radars[p].rp_pulsefreq) -
+ 100*(dfs_radars[p].rp_meanoffset);
+ rf->rf_maxpri =
+ dfs_round((int32_t)Tmax + (100*(dfs_radars[p].rp_pulsevar)));
+
+ if(rf->rf_minpri < ft->ft_minpri)
+ ft->ft_minpri = rf->rf_minpri;
+
+ rf->rf_fixed_pri_radar_pulse =
+ (dfs_radars[p].rp_max_pulsefreq ==
+ dfs_radars[p].rp_pulsefreq) ? 1 : 0;
+ /* for pulseid 5, increase threshould by 1 */
+ if (dfs_radars[p].rp_pulseid == 5)
+ rf->rf_threshold = dfs_radars[p].rp_threshold + 1;
+ else
+ rf->rf_threshold = dfs_radars[p].rp_threshold;
+
+ rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses;
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]: minprf = %d maxprf = %d pulsevar = %d thresh=%d",
+ __func__, __LINE__, dfs_radars[p].rp_pulsefreq,
+ dfs_radars[p].rp_max_pulsefreq, dfs_radars[p].rp_pulsevar,
+ rf->rf_threshold);
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:minpri = %d maxpri = %d filterlen = %d filterID = %d",
+ __func__, __LINE__, rf->rf_minpri, rf->rf_maxpri,
+ rf->rf_filterlen, rf->rf_pulseid);
+
+ }
#ifdef DFS_DEBUG
- dfs_print_filters(ic);
+ dfs_print_filters(dfs);
#endif
dfs->dfs_rinfo.rn_numbin5radars = numb5radars;
if (dfs->dfs_b5radars != NULL)
diff --git a/CORE/SERVICES/DFS/src/dfs_process_radarevent.c b/CORE/SERVICES/DFS/src/dfs_process_radarevent.c
index 156a229dd0cd..45176f5706d0 100644
--- a/CORE/SERVICES/DFS/src/dfs_process_radarevent.c
+++ b/CORE/SERVICES/DFS/src/dfs_process_radarevent.c
@@ -108,6 +108,175 @@ dfs_process_pulse_dur(struct ath_dfs *dfs, u_int8_t re_dur)
}
/*
+ * dfs_process_dc_pulse: process dc pulses
+ * @dfs: pointer to dfs structure
+ * @event: dfs event
+ * @retval: current found status
+ * @this_ts: event's ts
+ *
+ * Return: None
+ */
+static void dfs_process_dc_pulse(struct ath_dfs *dfs, struct dfs_event *event,
+ int *retval, int this_ts)
+{
+ struct dfs_event re;
+ struct dfs_state *rs=NULL;
+ struct dfs_filtertype *ft;
+ struct dfs_filter *rf;
+ int found, p, empty;
+ int min_pri, miss_pulse_number = 0, deviation = 0;
+ u_int32_t tabledepth = 0;
+ u_int64_t deltaT;
+ int ext_chan_event_flag = 0;
+ int i;
+
+ OS_MEMCPY(&re, event, sizeof(*event));
+ if (re.re_chanindex < DFS_NUM_RADAR_STATES)
+ rs = &dfs->dfs_radar[re.re_chanindex];
+
+ while ((tabledepth < DFS_MAX_RADAR_OVERLAP) &&
+ ((dfs->dfs_dc_radartable[re.re_dur])[tabledepth] != -1) &&
+ (!*retval)) {
+ ft = dfs->dfs_dc_radarf[((dfs->dfs_dc_radartable
+ [re.re_dur])[tabledepth])];
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("** RD (%d): ts %x dur %u rssi %u"),
+ rs->rs_chan.ic_freq,
+ re.re_ts, re.re_dur, re.re_rssi);
+
+ deltaT = this_ts - ft->ft_last_ts;
+ if (re.re_rssi < ft->ft_rssithresh && re.re_dur > 4) {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("Rejecting on rssi rssi=%u thresh=%u depth=%d"),
+ re.re_rssi, ft->ft_rssithresh,
+ tabledepth);
+ tabledepth++;
+ dfs_reset_filter_delaylines(ft);
+ ATH_DFSQ_LOCK(dfs);
+ empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
+ ATH_DFSQ_UNLOCK(dfs);
+ continue;
+ }
+ if ((deltaT < ft->ft_minpri) && (deltaT !=0)) {
+ /* This check is for the whole filter type. Individual filters
+ * will check this again. This is first line of filtering. */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("Rejecting on pri pri=%lld minpri=%u depth=%d"),
+ (unsigned long long)deltaT,
+ ft->ft_minpri, tabledepth);
+ dfs_reset_filter_delaylines(ft);
+ tabledepth++;
+ continue;
+ }
+ for (p = 0, found = 0; (p < ft->ft_numfilters) && (!found); p++) {
+ rf = ft->ft_filters[p];
+ if ((re.re_dur >= rf->rf_mindur) &&
+ (re.re_dur <= rf->rf_maxdur)) {
+ deltaT = (this_ts < rf->rf_dl.dl_last_ts) ?
+ (int64_t) ((DFS_TSF_WRAP - rf->rf_dl.dl_last_ts) +
+ this_ts + 1) :
+ this_ts - rf->rf_dl.dl_last_ts;
+
+ if ((deltaT < rf->rf_minpri) && (deltaT != 0)) {
+ /* Second line of PRI filtering. */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("filterID=%d :: Rejected and cleared individual filter min PRI deltaT=%lld rf->rf_minpri=%u"),
+ rf->rf_pulseid,
+ (unsigned long long)deltaT, rf->rf_minpri);
+ dfs_reset_delayline(&rf->rf_dl);
+ rf->rf_dl.dl_last_ts = this_ts;
+ continue;
+ }
+
+ if (rf->rf_ignore_pri_window > 0) {
+ if (deltaT < rf->rf_minpri) {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("filterID=%d :: Rejected and cleared on individual filter max PRI deltaT=%lld rf->rf_minpri=%u"),
+ rf->rf_pulseid,
+ (unsigned long long)deltaT, rf->rf_minpri);
+ dfs_reset_delayline(&rf->rf_dl);
+ rf->rf_dl.dl_last_ts = this_ts;
+ continue;
+ }
+ } else {
+ if (deltaT < rf->rf_minpri) {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("filterID=%d :: Rejected and cleared on individual filter max PRI deltaT=%lld rf->rf_minpri=%u"),
+ rf->rf_pulseid,
+ (unsigned long long)deltaT, rf->rf_minpri);
+ dfs_reset_delayline(&rf->rf_dl);
+ rf->rf_dl.dl_last_ts = this_ts;
+ continue;
+ }
+ }
+ dfs_add_pulse(dfs, rf, &re, deltaT, this_ts);
+
+ /* extra WAR */
+ if ((dfs->dfsdomain == DFS_FCC_DOMAIN &&
+ dfs->dfsdomain == DFS_MKK4_DOMAIN) &&
+ ((rf->rf_pulseid != 31) && (rf->rf_pulseid != 32))) {
+
+ min_pri = 0xffff;
+ for (i = 0; i < rf->rf_dl.dl_numelems; i++) {
+ if (rf->rf_dl.dl_elems[i].de_time < min_pri)
+ min_pri = rf->rf_dl.dl_elems[i].de_time;
+ }
+
+ for (i=0; i < rf->rf_dl.dl_numelems; i++) {
+ miss_pulse_number = vos_round_div(
+ (rf->rf_dl.dl_elems[i].de_time), min_pri);
+ deviation = __adf_os_abs(min_pri *
+ miss_pulse_number -
+ rf->rf_dl.dl_elems[i].de_time);
+ if (deviation > miss_pulse_number*3) {
+ dfs_reset_delayline(&rf->rf_dl);
+ VOS_TRACE(VOS_MODULE_ID_SAP,
+ VOS_TRACE_LEVEL_INFO,
+ FL("filterID=%d :: cleared individual deleyline min_pri =%d miss_pulse_number =%d deviation =%d"),
+ rf->rf_pulseid,
+ min_pri, miss_pulse_number, deviation);
+ }
+ }
+ }
+
+ /* If this is an extension channel event,
+ * flag it for false alarm reduction */
+ if (re.re_chanindex == dfs->dfs_extchan_radindex)
+ ext_chan_event_flag = 1;
+
+ if (rf->rf_patterntype == 2)
+ found = dfs_staggered_check(dfs, rf, (uint32_t)deltaT,
+ re.re_dur);
+ else
+ found = dfs_bin_check(dfs, rf, (uint32_t) deltaT,
+ re.re_dur, ext_chan_event_flag);
+
+ if (dfs->dfs_debug_mask & ATH_DEBUG_DFS2)
+ dfs_print_delayline(dfs, &rf->rf_dl);
+
+ rf->rf_dl.dl_last_ts = this_ts;
+ } else {
+ /* if we are rejecting this, clear the queue */
+ dfs_reset_delayline(&rf->rf_dl);
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("filterID= %d :: cleared individual deleyline"),
+ rf->rf_pulseid);
+ }
+ }
+ ft->ft_last_ts = this_ts;
+ *retval |= found;
+ if (found) {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL(":## Radar Found minDur=%d, filterId=%d ##"),
+ ft->ft_mindur,
+ rf != NULL ? rf->rf_pulseid : -1);
+ }
+ tabledepth++;
+ }
+}
+
+/*
* Process a radar event.
*
* If a radar event is found, return 1. Otherwise, return 0.
@@ -381,9 +550,11 @@ dfs_process_radarevent(struct ath_dfs *dfs, struct ieee80211_channel *chan)
dfs->radar_log[i].dur = re.re_dur;
dfs->dfs_event_log_count++;
}
- VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u pl->pl_lastelem.p_time=%llu xxxxx",__func__,__LINE__,(u_int32_t)this_ts, re.re_dur, re.re_rssi, diff_ts, (unsigned long long)pl->pl_elems[index].p_time);
-
-
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u sidx = %u flags = %x pl->pl_lastelem.p_time=%llu xxxxx",
+ __func__, __LINE__, (u_int32_t)this_ts,
+ re.re_dur, re.re_rssi, diff_ts, re.sidx, re.re_flags,
+ (unsigned long long)pl->pl_elems[index].p_time);
/* If diff_ts is very small, we might be getting false pulse detects
* due to heavy interference. We might be getting spectral splatter
@@ -527,7 +698,26 @@ dfs_process_radarevent(struct ath_dfs *dfs, struct ieee80211_channel *chan)
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1," *** chan freq (%d): ts %llu dur %u rssi %u",
rs->rs_chan.ic_freq, (unsigned long long)this_ts, re.re_dur, re.re_rssi);
- while ((tabledepth < DFS_MAX_RADAR_OVERLAP) &&
+
+ /*
+ * DC pulses processing will be done in this seperate block since some
+ * device may generate pulse which may cause false detection.
+ * This processing is similar kind as of normal pulse processing with
+ * some exception such as:
+ * 1. Clear the queue if pulse doesn't belong to it
+ * 2. Remove chan load optimization(can cause some valid pulses to drop)
+ * 3. Drop pulses on basis of mean deviation for some filters
+ */
+ if (((re.sidx == 0) && DFS_EVENT_NOTCHIRP(&re)) &&
+ ((dfs->dfsdomain == DFS_FCC_DOMAIN) ||
+ (dfs->dfsdomain == DFS_MKK4_DOMAIN) ||
+ (dfs->dfsdomain == DFS_ETSI_DOMAIN && re.re_dur < 18))) {
+ dfs_process_dc_pulse(dfs, &re, &retval, this_ts);
+ }
+
+ /* Pulse not at DC position */
+ else {
+ while ((tabledepth < DFS_MAX_RADAR_OVERLAP) &&
((dfs->dfs_radartable[re.re_dur])[tabledepth] != -1) &&
(!retval)) {
ft = dfs->dfs_radarf[((dfs->dfs_radartable[re.re_dur])[tabledepth])];
@@ -631,6 +821,7 @@ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:filterID= %d :: Rejec
rf != NULL ? rf->rf_pulseid : -1);
}
tabledepth++;
+ }
}
ATH_DFSQ_LOCK(dfs);
empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
diff --git a/CORE/VOSS/inc/vos_types.h b/CORE/VOSS/inc/vos_types.h
index 960226fa75ce..a9198201600a 100644
--- a/CORE/VOSS/inc/vos_types.h
+++ b/CORE/VOSS/inc/vos_types.h
@@ -58,6 +58,12 @@
// macro to return the floor of an integer division operation
#define VOS_FLOOR_DIV( _a, _b ) ( ( (_a) - ( (_a) % (_b) ) ) / (_b) )
+static inline unsigned int vos_round_div(unsigned int dividend,
+ unsigned int divisor)
+{
+ return (dividend + (divisor / 2)) / divisor;
+}
+
#define VOS_SWAP_U16(_x) \
( ( ( (_x) << 8 ) & 0xFF00 ) | ( ( (_x) >> 8 ) & 0x00FF ) )