diff options
| -rw-r--r-- | CORE/SERVICES/DFS/inc/dfs.h | 7 | ||||
| -rw-r--r-- | CORE/SERVICES/DFS/src/dfs.c | 92 | ||||
| -rw-r--r-- | CORE/SERVICES/DFS/src/dfs_debug.c | 23 | ||||
| -rw-r--r-- | CORE/SERVICES/DFS/src/dfs_init.c | 125 | ||||
| -rw-r--r-- | CORE/SERVICES/DFS/src/dfs_process_radarevent.c | 199 | ||||
| -rw-r--r-- | CORE/VOSS/inc/vos_types.h | 6 |
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 ) ) |
