summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 ) )