qcacmn: refactor DFS code Part-I

Reduced the max indentation level to five.
Spilt functions to several smaller functions.
Only a few functions were split
in this commit. Rest need to be done in future commits.

Change-Id: I1c9dcf3ae12edef6bcce37023f93d062705e0142
CRs-Fixed: 2098511
This commit is contained in:
Abhijit Pradhan
2017-08-20 11:49:35 +05:30
committed by snandini
parent 4d23cd7886
commit 382c50fff7
12 changed files with 1832 additions and 1096 deletions

View File

@@ -67,6 +67,8 @@
* XXX Peregrine reports pulses in microseconds, not hardware clocks!
*/
#define MAX_DUR_FOR_LOW_RSSI 4
/**
* Cascade has issue with reported duration especially when there is a
* crossover of chirp from one segment to another. It may report a value
@@ -231,7 +233,7 @@
* struct dfs_pulseparams - DFS pulse param structure.
* @p_time: Time for start of pulse in usecs.
* @p_dur: Duration of pulse in usecs.
* @p_rssi: Duration of pulse in usecs.
* @p_rssi: RSSI of pulse.
*/
struct dfs_pulseparams {
uint64_t p_time;
@@ -497,7 +499,7 @@ struct dfs_nolelem {
/**
* struct dfs_info - DFS Info.
* @rn_use_nol: Use the NOL when radar found (default: TRUE).
* @rn_numradars: Number of different types of radars.
* @rn_ftindex: Number of different types of radars.
* @rn_lastfull_ts: Last 64 bit timstamp from recv interrupt.
* @rn_last_ts: last 15 bit ts from recv descriptor.
* @rn_last_unique_ts: last unique 32 bit ts from recv descriptor.
@@ -513,7 +515,7 @@ struct dfs_nolelem {
*/
struct dfs_info {
int rn_use_nol;
uint32_t rn_numradars;
uint32_t rn_ftindex;
uint64_t rn_lastfull_ts;
uint16_t rn_last_ts;
uint32_t rn_last_unique_ts;
@@ -663,7 +665,7 @@ struct dfs_event_log {
* @dfs_radarf[]: dfs_radarf - One filter for each radar pulse type.
* @dfs_rinfo: State vars for radar processing.
* @dfs_b5radars: array of bin5 radar events.
* @dfs_radartable: map of radar durs to filter types.
* @dfs_ftindextable: map of radar durs to filter types.
* @dfs_nol: Non occupancy list for radar.
* @dfs_nol_count: How many items?
* @dfs_defaultparams: Default phy params per radar state.
@@ -752,7 +754,7 @@ struct wlan_dfs {
struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES];
struct dfs_info dfs_rinfo;
struct dfs_bin5radars *dfs_b5radars;
int8_t **dfs_radartable;
int8_t **dfs_ftindextable;
struct dfs_nolelem *dfs_nol;
int dfs_nol_count;
struct wlan_dfs_phyerr_param dfs_defaultparams;
@@ -1012,7 +1014,8 @@ void dfs_radar_found_action(struct wlan_dfs *dfs);
* and ext channels as being unavailable. This should be fixed for 802.11ac
* or we'll quickly run out of valid channels to use.
*
* Return: If a radar event is found, return 1. Otherwise, return 0.
* Return: If a radar event found on non-DFS channel return 0.
* Otherwise, return 1.
*/
int dfs_process_radarevent(struct wlan_dfs *dfs,
struct dfs_ieee80211_channel *chan);
@@ -1229,18 +1232,6 @@ void dfs_add_pulse(struct wlan_dfs *dfs,
uint32_t deltaT,
uint64_t this_ts);
/**
* dfs_bin_fixedpattern_check() - Checks the BIN pattern.
* @dfs: Pointer to wlan_dfs structure.
* @rf: Pointer to dfs_filter structure.
* @dur: Duration.
* ext_chan_flag : Ext channel flag.
*/
int dfs_bin_fixedpattern_check(struct wlan_dfs *dfs,
struct dfs_filter *rf,
uint32_t dur,
int ext_chan_flag);
/**
* dfs_bin_check() - BIN check
* @dfs: Pointer to wlan_dfs structure.
@@ -1845,7 +1836,6 @@ int dfs_process_phyerr_merlin(struct wlan_dfs *dfs,
* __dfs_process_radarevent() - Continuation of process a radar event function.
* @dfs: Pointer to wlan_dfs structure.
* @ft: Pointer to dfs_filtertype structure.
* @rf: Pointer to dfs_filter structure.
* @re: Pointer to dfs_event structure.
* @this_ts: Timestamp.
*
@@ -1858,7 +1848,6 @@ int dfs_process_phyerr_merlin(struct wlan_dfs *dfs,
*/
void __dfs_process_radarevent(struct wlan_dfs *dfs,
struct dfs_filtertype *ft,
struct dfs_filter *rf,
struct dfs_event *re,
uint64_t this_ts,
int *found);
@@ -1879,34 +1868,8 @@ void bin5_rules_check_internal(struct wlan_dfs *dfs,
uint32_t *numevents,
uint32_t prev,
uint32_t i,
uint32_t this);
/**
* count_the_other_delay_elements() - Counts the ther delay elements.
* @dfs: Pointer to wlan_dfs structure.
* @rf: Pointer to dfs_filter structure.
* @dl: Pointer to dfs_delayline structure.
* @i: Index value.
* @refpri: Current "filter" time for start of pulse in usecs.
* @refdur: Duration value.
* @primargin: Primary margin.
* @durmargin: Duration margin.
* @numpulses: Number of pulses.
* @prev_good_timestamp: Previous good timestamp.
* @fundamentalpri: Highest PRI.
*/
void count_the_other_delay_elements(struct wlan_dfs *dfs,
struct dfs_filter *rf,
struct dfs_delayline *dl,
uint32_t i,
uint32_t refpri,
uint32_t refdur,
uint32_t primargin,
uint32_t durmargin,
int *numpulses,
uint32_t *prev_good_timestamp,
int fundamentalpri
);
uint32_t this,
int *index);
/**
* dfs_main_timer_init() - Initialize dfs timers.

View File

@@ -25,102 +25,249 @@
#include "../dfs.h"
int dfs_bin_fixedpattern_check(struct wlan_dfs *dfs,
/**
* dfs_find_first_index_within_window() - Find first index within window
* @pl: Pointer to dfs_pulseline structure.
* @index: Index to dfs pulse elements.
* @start_ts: Start timestamp.
*
* Return: Returns index.
*/
static inline uint32_t dfs_find_first_index_within_window(
struct dfs_pulseline *pl,
uint32_t index,
uint64_t start_ts)
{
uint16_t i;
/* 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;
}
}
return index;
}
/**
* dfs_ts_within_window() - Calculate pulses for timestamp within window
* @dfs: Pointer to wlan_dfs structure.
* @pl: Pointer to dfs_pulseline structure.
* @index: Index to dfs pulse elements.
* @dur: Pulse duration/width
* @numpulses: Number of pulses
*
* Return: Returns 1 if pulse count is incremented else returns 0.
*/
static inline bool dfs_ts_within_window(
struct wlan_dfs *dfs,
struct dfs_pulseline *pl,
uint32_t *index,
uint32_t dur,
int *numpulses)
{
uint32_t deltadur;
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, WLAN_DEBUG_DFS2, "numpulses %u\n", *numpulses);
return 1;
}
return 0;
}
/**
* dfs_ts_eq_prevts() - Calculate pulses for timestamp equals to prev event
* @dfs: Pointer to wlan_dfs structure.
* @pl: Pointer to dfs_pulseline structure.
* @index: Index to dfs pulse elements.
* @dur: Pulse duration/width
* @numpulses: Number of pulses
*
* Return: Returns 1 if pulse count is incremented else returns 0.
*/
static inline bool dfs_ts_eq_prevts(
struct wlan_dfs *dfs,
struct dfs_pulseline *pl,
uint64_t next_event_ts,
uint64_t event_ts,
uint32_t refpri,
uint32_t *index,
uint32_t dur,
int *numpulses)
{
uint32_t deltadur;
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, WLAN_DEBUG_DFS2,
"zero PRI: numpulses %u\n", *numpulses);
return 1;
}
}
return 0;
}
/**
* dfs_pulses_within_window() - Calculate pulses within window
* @dfs: Pointer to wlan_dfs structure.
* @window_start: Start of the window.
* @window_end: End of the window.
* @index: Index to dfs pulse elements.
* @dur: Pulse duration/width.
* @refpri: reference PRI.
*
* Return: Returns 1 if pulse count is incremented else returns 0.
*/
static inline int dfs_pulses_within_window(
struct wlan_dfs *dfs,
uint64_t window_start,
uint64_t window_end,
uint32_t *index,
uint32_t dur,
uint32_t refpri)
{
int numpulses = 0;
uint32_t i;
struct dfs_pulseline *pl = dfs->pulses;
uint64_t event_ts, prev_event_ts, next_event_ts;
uint32_t next_index;
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, WLAN_DEBUG_DFS2, "ts %u\n",
(uint32_t)event_ts);
if ((event_ts <= window_end) && (event_ts >= window_start)) {
if (dfs_ts_within_window(dfs, pl, index, dur,
&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 (dfs_ts_eq_prevts(dfs, pl, next_event_ts, event_ts,
refpri, index, dur, &numpulses))
break;
}
}
return numpulses;
}
/**
* dfs_count_pulses() - Count pulses
* @dfs: Pointer to wlan_dfs structure.
* @rf: Pointer to dfs_filter structure.
* @dur: Pulse duration/width.
* @ext_chan_flag : Ext channel flag.
* @primargin: Primary margin.
* @index: Index to dfs pulse elements.
* @refpri: reference PRI.
* @start_ts: Start timestamp.
*
* Return: Returns number of pulses within window.
*/
static inline int dfs_count_pulses(
struct wlan_dfs *dfs,
struct dfs_filter *rf,
uint32_t dur,
int ext_chan_flag,
int primargin,
uint32_t index,
uint32_t refpri,
uint64_t start_ts)
{
uint32_t n;
int numpulses = 0;
uint64_t window_start, window_end;
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, WLAN_DEBUG_DFS2,
"window_start %u window_end %u\n",
(uint32_t)window_start, (uint32_t)window_end);
numpulses += dfs_pulses_within_window(dfs, window_start,
window_end, &index, dur, refpri);
}
return numpulses;
}
/**
* dfs_bin_fixedpattern_check() - Fixed pattern check
* @dfs: Pointer to wlan_dfs structure.
* @rf: Pointer to dfs_filter structure.
* @dur: Pulse duration/width.
* @ext_chan_flag : Ext channel flag.
*/
static int dfs_bin_fixedpattern_check(
struct wlan_dfs *dfs,
struct dfs_filter *rf,
uint32_t dur,
int ext_chan_flag)
{
struct dfs_pulseline *pl = dfs->pulses;
int i, n, refpri, primargin, numpulses = 0;
uint64_t start_ts, end_ts, event_ts, prev_event_ts;
uint64_t next_event_ts, window_start, window_end;
uint32_t index, next_index, deltadur;
/* For fixed pattern types, rf->rf_patterntype=1. */
primargin = dfs_get_pri_margin(dfs, ext_chan_flag,
(rf->rf_patterntype == 1));
int primargin, numpulses, fil_thresh;
uint64_t start_ts, end_ts;
uint32_t last_index, first_index;
uint32_t refpri;
refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
index = pl->pl_lastelem;
end_ts = pl->pl_elems[index].p_time;
last_index = pl->pl_lastelem;
end_ts = pl->pl_elems[last_index].p_time;
start_ts = end_ts - (refpri*rf->rf_numpulses);
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS3,
"lastelem ts=%llu start_ts=%llu, end_ts=%llu\n",
(unsigned long long)pl->pl_elems[index].p_time,
(unsigned long long)pl->pl_elems[last_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, WLAN_DEBUG_DFS2,
"window_start %u window_end %u\n",
(uint32_t)window_start, (uint32_t)window_end);
first_index = dfs_find_first_index_within_window(pl, last_index,
start_ts);
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, WLAN_DEBUG_DFS2, "ts %u\n",
(uint32_t)event_ts);
/* For fixed pattern types, rf->rf_patterntype=1. */
primargin = dfs_get_pri_margin(dfs, ext_chan_flag,
(rf->rf_patterntype == 1));
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, WLAN_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,
WLAN_DEBUG_DFS2,
"zero PRI: numpulses %u\n",
numpulses);
break;
}
}
}
}
}
if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) {
numpulses = dfs_count_pulses(dfs, rf, dur, ext_chan_flag, primargin,
first_index, refpri, start_ts);
fil_thresh = dfs_get_filter_threshold(dfs, rf, ext_chan_flag);
if (numpulses >= fil_thresh) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
"%s FOUND filterID=%u numpulses=%d unadj thresh=%d\n",
__func__, rf->rf_pulseid, numpulses, rf->rf_threshold);
return 1;
} else
} else {
return 0;
}
}
void dfs_add_pulse(struct wlan_dfs *dfs,
void dfs_add_pulse(
struct wlan_dfs *dfs,
struct dfs_filter *rf,
struct dfs_event *re,
uint32_t deltaT,
@@ -165,85 +312,107 @@ void dfs_add_pulse(struct wlan_dfs *dfs,
dl->dl_firstelem, dl->dl_lastelem);
}
int dfs_bin_check(struct wlan_dfs *dfs,
struct dfs_filter *rf,
uint32_t deltaT,
uint32_t width,
int ext_chan_flag)
/**
* dfs_find_lowestpri() - Find lowest PRI
* @dl: Pointer to dfs delayline.
* @lowpriindex: Low PRI index.
* @lowpri: Low PRI
*/
static inline void dfs_find_lowestpri(
struct dfs_delayline *dl,
uint32_t *lowpriindex,
uint32_t *lowpri)
{
struct dfs_delayline *dl;
uint32_t refpri, refdur, searchpri, deltapri, deltapri_2, deltapri_3;
uint32_t averagerefpri, n, i, primargin, durmargin, highscore;
uint32_t highscoreindex;
int score[DFS_MAX_DL_SIZE], delayindex, dindex, found = 0;
uint32_t scoreindex, lowpriindex = 0, lowpri = 0xffff;
int numpulses = 0;
int lowprichk = 3, pri_match = 0;
int delayindex;
uint32_t refpri;
uint32_t n;
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(dfs, 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(dfs, rf, width,
ext_chan_flag);
if (found)
dl->dl_numelems = 0;
return found;
}
qdf_mem_zero(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;
} else if (refpri < *lowpri) {
*lowpri = dl->dl_elems[delayindex].de_time;
*lowpriindex = n;
}
}
/* Find out the each delay element's pri score. */
}
/**
* dfs_calculate_score() - Calculate score for the score index
* if PRI match is found
* @dl: Pointer to dfs delayline.
* @rf: Pointer to dfs_filter structure.
* @score: score array.
* @refpri: reference PRI.
* @primargin: PRI margin.
* @score_index: Score index.
*/
static inline void dfs_calculate_score(
struct dfs_delayline *dl,
struct dfs_filter *rf,
int *score,
uint32_t refpri,
uint32_t primargin,
uint32_t score_index)
{
int pri_match = 0;
int dindex;
uint32_t searchpri, deltapri, deltapri_2, deltapri_3;
uint32_t i;
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[score_index]++;
}
}
/**
* dfs_find_priscores() - Find PRI score
* @dl: Pointer to dfs delayline.
* @rf: Pointer to dfs_filter structure.
* @score: score array.
* @primargin: PRI margin.
*/
static void dfs_find_priscores(
struct dfs_delayline *dl,
struct dfs_filter *rf,
int *score,
uint32_t primargin)
{
int delayindex;
uint32_t refpri;
uint32_t n;
qdf_mem_zero(score, sizeof(int)*DFS_MAX_DL_SIZE);
for (n = 0; n < dl->dl_numelems; n++) {
delayindex = (dl->dl_firstelem + n) &
DFS_MAX_DL_MASK;
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]++;
}
dfs_calculate_score(dl, rf, score, refpri, primargin,
n);
} else {
score[n] = 0;
}
if (score[n] > rf->rf_threshold) {
/*
* We got the most possible candidate,
@@ -252,67 +421,301 @@ int dfs_bin_check(struct wlan_dfs *dfs,
break;
}
}
}
/**
* dfs_find_highscore() - Find PRI high score
* @dl: Pointer to dfs delayline.
* @score: score array.
* @highscore: High score.
* @highscoreindex: High score index.
*/
static inline void dfs_find_highscore(
struct dfs_delayline *dl,
int *score,
uint32_t *highscore,
uint32_t *highscoreindex)
{
int delayindex, dindex;
uint32_t n;
*highscore = 0;
*highscoreindex = 0;
/* 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) {
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) &
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;
*highscoreindex = n;
}
}
}
/*
* Find the average pri of pulses around the pri of highscore
* or the pulses around the lowest pri.
*/
return;
}
/**
* dfs_get_durmargin() - Find duration margin
* @rf: Pointer to dfs_filter structure.
* @durmargin: Duration margin
*/
static inline void dfs_get_durmargin(
struct dfs_filter *rf,
uint32_t *durmargin)
{
#define DUR_THRESH 10
#define LOW_MARGIN 4
#define HIGH_MARGIN 6
if (rf->rf_maxdur < DUR_THRESH)
*durmargin = LOW_MARGIN;
else
*durmargin = HIGH_MARGIN;
#undef DUR_THRESH
#undef LOW_MARGIN
#undef HIGH_MARGIN
}
/**
* dfs_handle_fixedpattern() - Handle Fixed pattern radar
* @dfs: Pointer to wlan_dfs structure.
* @dl: Pointer to dfs delayline.
* @rf: Pointer to dfs_filter structure.
* @dur: Pulse duration/width
* @ext_chan_flag : Ext channel flag.
*/
static inline int dfs_handle_fixedpattern(
struct wlan_dfs *dfs,
struct dfs_delayline *dl,
struct dfs_filter *rf,
uint32_t dur,
int ext_chan_flag)
{
int found = 0;
found = dfs_bin_fixedpattern_check(dfs, rf, dur, ext_chan_flag);
if (found)
dl->dl_numelems = 0;
return found;
}
/**
* dfs_bin_basic_sanity() - Sanity check
* @dl: Pointer to dfs delayline.
* @rf: Pointer to dfs_filter structure.
* @deltaT: Delta time.
*/
static inline int dfs_bin_basic_sanity(
struct dfs_delayline *dl,
struct dfs_filter *rf,
uint32_t *deltaT)
{
if (dl->dl_numelems < (rf->rf_threshold-1))
return 0;
if (*deltaT > rf->rf_filterlen)
return 0;
return 1;
}
/**
* dfs_find_scoreindex() - Find score index
* @rf: Pointer to dfs_filter structure.
* @highscore: High score.
* @lowpriindex: Low PRI index.
* @highscoreindex: High score index.
* @scoreindex: score index.
*/
static inline void dfs_find_scoreindex(
struct dfs_filter *rf,
uint32_t highscore,
uint32_t lowpriindex,
uint32_t highscoreindex,
uint32_t *scoreindex)
{
int lowprichk = 3;
if (rf->rf_ignore_pri_window > 0)
lowprichk = (rf->rf_threshold >> 1)+1;
else
lowprichk = 3;
if (highscore < lowprichk)
scoreindex = lowpriindex;
*scoreindex = lowpriindex;
else
scoreindex = highscoreindex;
*scoreindex = highscoreindex;
}
/**
* dfs_find_refs() - Find reference values.
* @dl: Pointer to dfs delayline.
* @rf: Pointer to dfs_filter structure.
* @scoreindex: score index.
* @refdur: Duration value.
* @refpri: Current "filter" time for start of pulse in usecs.
*/
static inline void dfs_find_refs(
struct dfs_delayline *dl,
struct dfs_filter *rf,
uint32_t scoreindex,
uint32_t *refdur,
uint32_t *refpri)
{
int delayindex;
/* 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;
*refdur = dl->dl_elems[delayindex].de_dur;
*refpri = dl->dl_elems[delayindex].de_time;
if (rf->rf_fixed_pri_radar_pulse)
refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
*refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
}
numpulses = dfs_bin_pri_check(dfs, rf, dl, score[scoreindex], refpri,
refdur, ext_chan_flag, refpri);
if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) {
found = 1;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
/**
* dfs_bin_success_print() - Debug print
* @dfs: Pointer to wlan_dfs structure.
* @rf: Pointer to dfs_filter structure.
* @ext_chan_flag: Extension channel flag.
* @numpulses: Number of pulses.
* @refpri: Current "filter" time for start of pulse in usecs.
* @refdur: Duration value.
* @primargin: PRI margin.
*/
static inline void dfs_bin_success_print(
struct wlan_dfs *dfs,
struct dfs_filter *rf,
int ext_chan_flag,
int numpulses,
uint32_t refpri,
uint32_t refdur,
uint32_t primargin)
{
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
"ext_flag=%d MATCH filter=%u numpulses=%u thresh=%u refdur=%d refpri=%d primargin=%d\n",
ext_chan_flag, rf->rf_pulseid, numpulses,
rf->rf_threshold, refdur, refpri, primargin);
dfs_print_delayline(dfs, &rf->rf_dl);
dfs_print_filter(dfs, rf);
dfs_print_delayline(dfs, &rf->rf_dl);
dfs_print_filter(dfs, rf);
}
int dfs_bin_check(
struct wlan_dfs *dfs,
struct dfs_filter *rf,
uint32_t deltaT,
uint32_t width,
int ext_chan_flag)
{
struct dfs_delayline *dl;
uint32_t refpri, refdur;
uint32_t highscoreindex;
uint32_t primargin, highscore;
int score[DFS_MAX_DL_SIZE], found = 0;
uint32_t scoreindex, lowpriindex = 0, lowpri = 0xffff;
int numpulses = 0;
int fil_thresh;
dl = &rf->rf_dl;
if (!dfs_bin_basic_sanity(dl, rf, &deltaT))
return 0;
primargin = dfs_get_pri_margin(dfs, ext_chan_flag,
(rf->rf_patterntype == 1));
if (rf->rf_patterntype == 1)
return dfs_handle_fixedpattern(dfs, dl, rf, width,
ext_chan_flag);
dfs_find_lowestpri(dl, &lowpriindex, &lowpri);
/* Find out the each delay element's pri score. */
dfs_find_priscores(dl, rf, score, primargin);
/* Find out the high scorer. */
dfs_find_highscore(dl, score, &highscore, &highscoreindex);
/*
* Find the average pri of pulses around the pri of highscore
* or the pulses around the lowest pri.
*/
dfs_find_scoreindex(rf, highscore, lowpriindex, highscoreindex,
&scoreindex);
/* We got the possible pri, save its parameters as reference. */
dfs_find_refs(dl, rf, scoreindex, &refdur, &refpri);
numpulses = dfs_bin_pri_check(dfs, rf, dl, score[scoreindex], refpri,
refdur, ext_chan_flag, refpri);
fil_thresh = dfs_get_filter_threshold(dfs, rf, ext_chan_flag);
if (numpulses >= fil_thresh) {
found = 1;
dfs_bin_success_print(dfs, rf, ext_chan_flag, numpulses,
refpri, refdur, primargin);
}
return found;
}
void count_the_other_delay_elements(struct wlan_dfs *dfs,
/**
* dfs_check_pulses_for_delta_variance() - Check pulses for delta variance.
* @rf: Pointer to dfs_filter structure.
* @numpulsetochk: Number of pulses to check.
* @delta_time_stamps: Delta time stamp.
* @fundamentalpri: Highest PRI.
* @primargin: Primary margin.
* @numpulses: Number of pulses.
*/
static inline void dfs_check_pulses_for_delta_variance(
struct dfs_filter *rf,
int numpulsetochk,
uint32_t delta_time_stamps,
int fundamentalpri,
uint32_t primargin,
int *numpulses)
{
uint32_t delta_ts_variance, j;
for (j = 0; j < numpulsetochk; j++) {
delta_ts_variance = DFS_DIFF(delta_time_stamps,
((j + 1) * fundamentalpri));
if (delta_ts_variance < (2 * (j + 1) * primargin)) {
(*numpulses)++;
if (rf->rf_ignore_pri_window > 0)
break;
}
}
}
/**
* dfs_count_the_other_delay_elements() - Counts the ther delay elements.
* @dfs: Pointer to wlan_dfs structure.
* @rf: Pointer to dfs_filter structure.
* @dl: Pointer to dfs_delayline structure.
* @i: Index value.
* @refpri: Current "filter" time for start of pulse in usecs.
* @refdur: Duration value.
* @primargin: Primary margin.
* @durmargin: Duration margin.
* @numpulses: Number of pulses.
* @prev_good_timestamp: Previous good timestamp.
* @fundamentalpri: Highest PRI.
*/
static void dfs_count_the_other_delay_elements(
struct wlan_dfs *dfs,
struct dfs_filter *rf,
struct dfs_delayline *dl,
uint32_t i,
@@ -322,12 +725,11 @@ void count_the_other_delay_elements(struct wlan_dfs *dfs,
uint32_t durmargin,
int *numpulses,
uint32_t *prev_good_timestamp,
int fundamentalpri
)
int fundamentalpri)
{
int delayindex;
uint32_t searchpri, searchdur, deltadur, deltapri1, deltapri2;
uint32_t j = 0, delta_time_stamps, delta_ts_variance, deltapri;
uint32_t j = 0, delta_time_stamps, deltapri;
int dindex, primatch, numpulsetochk = 2;
delayindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
@@ -348,21 +750,16 @@ void count_the_other_delay_elements(struct wlan_dfs *dfs,
deltapri2 = DFS_DIFF(searchpri, 2 * refpri);
primatch = 0;
if ((rf->rf_ignore_pri_window > 0) &&
(rf->rf_patterntype != 2)) {
if ((rf->rf_ignore_pri_window > 0) && (rf->rf_patterntype != 2)) {
for (j = 0; j < rf->rf_numpulses; j++) {
deltapri1 = DFS_DIFF(searchpri,
(j + 1) * refpri);
deltapri1 = DFS_DIFF(searchpri, (j + 1) * refpri);
if (deltapri1 < (2 * primargin)) {
primatch = 1;
break;
}
}
} else {
if ((deltapri1 < primargin) ||
(deltapri2 < primargin)) {
primatch = 1;
}
} else if ((deltapri1 < primargin) || (deltapri2 < primargin)) {
primatch = 1;
}
if (primatch && (deltadur < durmargin)) {
@@ -380,16 +777,10 @@ void count_the_other_delay_elements(struct wlan_dfs *dfs,
} else {
numpulsetochk = 4;
}
for (j = 0; j < numpulsetochk; j++) {
delta_ts_variance = DFS_DIFF(delta_time_stamps,
((j + 1) * fundamentalpri));
if (delta_ts_variance <
(2 * (j + 1) * primargin)) {
(*numpulses)++;
if (rf->rf_ignore_pri_window > 0)
break;
}
}
dfs_check_pulses_for_delta_variance(rf, numpulsetochk,
delta_time_stamps, fundamentalpri,
primargin, numpulses);
}
*prev_good_timestamp = dl->dl_elems[delayindex].de_ts;
@@ -400,7 +791,8 @@ void count_the_other_delay_elements(struct wlan_dfs *dfs,
}
}
int dfs_bin_pri_check(struct wlan_dfs *dfs,
int dfs_bin_pri_check(
struct wlan_dfs *dfs,
struct dfs_filter *rf,
struct dfs_delayline *dl,
uint32_t score,
@@ -433,10 +825,7 @@ int dfs_bin_pri_check(struct wlan_dfs *dfs,
return numpulses;
}
if (rf->rf_maxdur < 10)
durmargin = 4;
else
durmargin = 6;
dfs_get_durmargin(rf, &durmargin);
if ((!rf->rf_fixed_pri_radar_pulse)) {
if (rf->rf_ignore_pri_window == 1)
@@ -481,9 +870,9 @@ int dfs_bin_pri_check(struct wlan_dfs *dfs,
* in the acceptable range from the reference one.
*/
for (i = 0; i < dl->dl_numelems; i++)
count_the_other_delay_elements(dfs, rf, dl, i, refpri, refdur,
primargin, durmargin, &numpulses, &prev_good_timestamp,
fundamentalpri);
dfs_count_the_other_delay_elements(dfs, rf, dl, i, refpri,
refdur, primargin, durmargin, &numpulses,
&prev_good_timestamp, fundamentalpri);
return numpulses;
}

View File

@@ -44,11 +44,33 @@ void dfs_print_filter(struct wlan_dfs *dfs, struct dfs_filter *rf)
rf->rf_maxdur);
}
/**
* dfs_print_filtertype() - Print the filtertype
* @dfs: Pointer to wlan_dfs structure.
* @ft: Pointer to dfs_filtertype structure.
*/
static void dfs_print_filtertype(
struct wlan_dfs *dfs,
struct dfs_filtertype *ft)
{
uint32_t j;
struct dfs_filter *rf;
for (j = 0; j < ft->ft_numfilters; j++) {
rf = &(ft->ft_filters[j]);
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
"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_filters(struct wlan_dfs *dfs)
{
struct dfs_filtertype *ft = NULL;
struct dfs_filter *rf;
int i, j;
uint8_t i;
if (dfs == NULL) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
@@ -64,21 +86,9 @@ void dfs_print_filters(struct wlan_dfs *dfs)
continue;
}
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
"===========ft->ft_numfilters = %u===========\n",
ft->ft_numfilters);
for (j = 0; j < ft->ft_numfilters; j++) {
rf = &(ft->ft_filters[j]);
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
"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);
}
"===========ft->ft_numfilters = %u===========\n",
ft->ft_numfilters);
dfs_print_filtertype(dfs, ft);
}
}
}

View File

@@ -127,17 +127,70 @@ int dfs_bin5_addpulse(struct wlan_dfs *dfs,
return 1;
}
/**
* dfs_calculate_bursts_for_same_rssi() - Calculate bursts for same rssi.
* @dfs: Pointer to wlan_dfs structure.
* @br: Pointer to dfs_bin5radars structure.
* @bursts: Bursts.
* @numevents: Number of events.
* @prev: prev index.
* @this: index to br_elems[].
* @index: index array.
*/
static inline void dfs_calculate_bursts_for_same_rssi(
struct wlan_dfs *dfs,
struct dfs_bin5radars *br,
uint32_t *bursts,
uint32_t *numevents,
uint32_t prev,
uint32_t this,
int *index)
{
uint32_t rssi_diff;
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, WLAN_DEBUG_DFS_BIN5,
"%s %d Bin5 rssi_diff=%d\n",
__func__, __LINE__, rssi_diff);
}
}
void bin5_rules_check_internal(struct wlan_dfs *dfs,
struct dfs_bin5radars *br,
uint32_t *bursts,
uint32_t *numevents,
uint32_t prev,
uint32_t i,
uint32_t this)
uint32_t this,
int *index)
{
uint64_t pri = 0;
uint32_t width_diff = 0, rssi_diff = 0;
int index[DFS_MAX_B5_SIZE];
uint32_t width_diff = 0;
/* Rule 1: 1000 <= PRI <= 2000 + some margin. */
if (br->br_elems[this].be_ts >= br->br_elems[prev].be_ts) {
@@ -168,42 +221,15 @@ void bin5_rules_check_internal(struct wlan_dfs *dfs,
width_diff = (br->br_elems[prev].be_dur
- br->br_elems[this].be_dur);
}
if (width_diff <= DFS_BIN5_WIDTH_MARGIN) {
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, WLAN_DEBUG_DFS_BIN5,
"%s %d Bin5 rssi_diff=%d\n",
__func__, __LINE__, rssi_diff);
} else
dfs_calculate_bursts_for_same_rssi(dfs, br, bursts,
numevents, prev, this, index);
else
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_BIN5,
"%s %d Bin5 width_diff=%d\n",
__func__, __LINE__, width_diff);
@@ -224,6 +250,7 @@ int dfs_bin5_check(struct wlan_dfs *dfs)
uint32_t n = 0, i = 0, i1 = 0, this = 0, prev = 0;
uint32_t bursts = 0, total_diff = 0, average_diff = 0;
uint32_t total_width = 0, average_width = 0, numevents = 0;
int index[DFS_MAX_B5_SIZE];
if (dfs == NULL) {
DFS_PRINTK("%s: dfs is NULL\n", __func__);
@@ -258,7 +285,7 @@ int dfs_bin5_check(struct wlan_dfs *dfs)
continue;
}
bin5_rules_check_internal(dfs, br, &bursts, &numevents,
prev, i, this);
prev, i, this, index);
prev = this;
}
@@ -272,12 +299,9 @@ int dfs_bin5_check(struct wlan_dfs *dfs)
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_BIN5,
"bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n",
bursts, numevents,
total_width, average_width,
bursts, numevents, total_width, average_width,
total_diff, average_diff);
DFS_PRINTK(
"bin 5 radar detected, bursts=%d\n",
bursts);
DFS_PRINTK("bin 5 radar detected, bursts=%d\n", bursts);
return 1;
}
}

View File

@@ -23,13 +23,32 @@
#include "../dfs.h"
#include "wlan_dfs_lmac_api.h"
/**
* dfs_reset_filtertype() - Reset filtertype.
* @ft: Pointer to dfs_filtertype structure.
*/
static inline void dfs_reset_filtertype(
struct dfs_filtertype *ft)
{
int j;
struct dfs_filter *rf;
struct dfs_delayline *dl;
for (j = 0; j < ft->ft_numfilters; j++) {
rf = &(ft->ft_filters[j]);
dl = &(rf->rf_dl);
if (dl != NULL) {
qdf_mem_zero(dl, sizeof(*dl));
dl->dl_lastelem = (0xFFFFFFFF) & DFS_MAX_DL_MASK;
}
}
}
void dfs_reset_alldelaylines(struct wlan_dfs *dfs)
{
struct dfs_filtertype *ft = NULL;
struct dfs_filter *rf;
struct dfs_delayline *dl;
struct dfs_pulseline *pl;
int i, j;
int i;
if (dfs == NULL) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
@@ -57,16 +76,7 @@ void dfs_reset_alldelaylines(struct wlan_dfs *dfs)
for (i = 0; i < DFS_MAX_RADAR_TYPES; i++) {
if (dfs->dfs_radarf[i] != NULL) {
ft = dfs->dfs_radarf[i];
for (j = 0; j < ft->ft_numfilters; j++) {
rf = &(ft->ft_filters[j]);
dl = &(rf->rf_dl);
if (dl != NULL) {
qdf_mem_zero(dl,
sizeof(struct dfs_delayline));
dl->dl_lastelem =
(0xFFFFFFFF) & DFS_MAX_DL_MASK;
}
}
dfs_reset_filtertype(ft);
}
}
@@ -119,6 +129,93 @@ void dfs_reset_radarq(struct wlan_dfs *dfs)
WLAN_DFSQ_UNLOCK(dfs);
}
/**
* dfs_fill_ft_index_table() - DFS fill ft index table.
* @dfs: Pointer to wlan_dfs structure.
* @i: Duration used as an index.
*
* Return: 1 if too many overlapping radar filters else 0.
*/
static inline bool dfs_fill_ft_index_table(
struct wlan_dfs *dfs,
int i)
{
uint32_t stop = 0, tableindex = 0;
while ((tableindex < DFS_MAX_RADAR_OVERLAP) && (!stop)) {
if ((dfs->dfs_ftindextable[i])[tableindex] == -1)
stop = 1;
else
tableindex++;
}
if (stop) {
(dfs->dfs_ftindextable[i])[tableindex] =
(int8_t)(dfs->dfs_rinfo.rn_ftindex);
} else {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
"%s: Too many overlapping radar filters\n",
__func__);
return 1;
}
return 0;
}
/**
* dfs_fill_filter_type() - DFS fill filter type.
* @dfs: Pointer to wlan_dfs structure.
* @ft: Double pointer to dfs_filtertype structure.
* @dfs_radars: Pointer to dfs_pulse structure.
* @min_rssithresh: Minimum RSSI threshold.
* @max_pulsedur: Maximum RSSI threshold.
* @p: Index to dfs_pulse structure.
*
* Return: 1 if too many overlapping radar filters else 0.
*/
static inline bool dfs_fill_filter_type(
struct wlan_dfs *dfs,
struct dfs_filtertype **ft,
struct dfs_pulse *dfs_radars,
int32_t *min_rssithresh,
uint32_t *max_pulsedur,
int p)
{
int i;
/* No filter of the appropriate dur was found. */
if ((dfs->dfs_rinfo.rn_ftindex + 1) > DFS_MAX_RADAR_TYPES) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
"%s: Too many filter types\n", __func__);
return 1;
}
(*ft) = dfs->dfs_radarf[dfs->dfs_rinfo.rn_ftindex];
(*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 = 1000000;
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++) {
if (dfs_fill_ft_index_table(dfs, i))
return 1;
}
dfs->dfs_rinfo.rn_ftindex++;
return 0;
}
int dfs_init_radar_filters(struct wlan_dfs *dfs,
struct wlan_dfs_radar_tab_info *radar_info)
{
@@ -131,6 +228,7 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
uint32_t max_pulsedur = 0;
int numpulses, p, n, i;
int numradars = 0, numb5radars = 0;
int retval;
if (dfs == NULL) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS, "dfs is NULL %s", __func__);
@@ -167,17 +265,17 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
dfs->dfs_defaultparams = radar_info->dfs_defaultparams;
dfs->wlan_dfs_isdfsregdomain = 1;
dfs->dfs_rinfo.rn_numradars = 0;
dfs->dfs_rinfo.rn_ftindex = 0;
/* Clear filter type table. */
for (n = 0; n < 256; n++) {
for (i = 0; i < DFS_MAX_RADAR_OVERLAP; i++)
(dfs->dfs_radartable[n])[i] = -1;
(dfs->dfs_ftindextable[n])[i] = -1;
}
/* Now, initialize the radar filters. */
for (p = 0; p < numradars; p++) {
ft = NULL;
for (n = 0; n < dfs->dfs_rinfo.rn_numradars; n++) {
for (n = 0; n < dfs->dfs_rinfo.rn_ftindex; n++) {
if ((dfs_radars[p].rp_pulsedur ==
dfs->dfs_radarf[n]->ft_filterdur) &&
(dfs_radars[p].rp_numpulses ==
@@ -190,57 +288,14 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
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, WLAN_DEBUG_DFS,
"%s: Too many filter types\n",
__func__);
retval = dfs_fill_filter_type(dfs, &ft, dfs_radars,
&min_rssithresh, &max_pulsedur, p);
if (retval == 1)
goto bad4;
}
ft = dfs->dfs_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 = 1000000;
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++) {
uint32_t stop = 0, tableindex = 0;
while ((tableindex < DFS_MAX_RADAR_OVERLAP) &&
(!stop)) {
if ((dfs->dfs_radartable[i])[tableindex]
== -1)
stop = 1;
else
tableindex++;
}
if (stop) {
(dfs->dfs_radartable[i])[tableindex] =
(int8_t)
(dfs->dfs_rinfo.rn_numradars);
} else {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
"%s: Too many overlapping radar filters\n",
__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;
@@ -254,21 +309,19 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
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)));
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)));
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;
rf->rf_fixed_pri_radar_pulse = (
dfs_radars[p].rp_max_pulsefreq ==
dfs_radars[p].rp_pulsefreq) ? 1 : 0;
rf->rf_threshold = dfs_radars[p].rp_threshold;
rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses;
@@ -307,10 +360,8 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
min_rssithresh =
dfs->dfs_b5radars[n].br_pulse.b5_rssithresh;
if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur
> max_pulsedur)
max_pulsedur =
dfs->dfs_b5radars[n].br_pulse.b5_maxdur;
if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur > max_pulsedur)
max_pulsedur = dfs->dfs_b5radars[n].br_pulse.b5_maxdur;
}
dfs_reset_alldelaylines(dfs);
dfs_reset_radarq(dfs);
@@ -325,15 +376,12 @@ int dfs_init_radar_filters(struct wlan_dfs *dfs,
* Relax the max pulse duration a little bit due to inaccuracy
* caused by chirping.
*/
dfs->dfs_rinfo.rn_maxpulsedur =
dfs->dfs_rinfo.rn_maxpulsedur + 20;
dfs->dfs_rinfo.rn_maxpulsedur = dfs->dfs_rinfo.rn_maxpulsedur + 20;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
"DFS min filter rssiThresh = %d\n",
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS, "DFS min filter rssiThresh = %d\n",
min_rssithresh);
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
"DFS max pulse dur = %d ticks\n",
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS, "DFS max pulse dur = %d ticks\n",
dfs->dfs_rinfo.rn_maxpulsedur);
return 0;

View File

@@ -71,6 +71,30 @@ static int dfs_adjust_thresh_per_chan_busy(int ext_chan_busy, int thresh)
return adjust_thresh;
}
/**
* dfs_get_cached_ext_chan_busy() - Get cached ext chan busy.
* @dfs: Pointer to wlan_dfs structure.
* @ext_chan_busy: Extension channel PRI.
*/
static inline void dfs_get_cached_ext_chan_busy(
struct wlan_dfs *dfs,
int *ext_chan_busy)
{
*ext_chan_busy = 0;
/* Check to see if the cached value of ext_chan_busy can be used. */
if (dfs->dfs_rinfo.dfs_ext_chan_busy &&
(dfs->dfs_rinfo.rn_lastfull_ts <
dfs->dfs_rinfo.ext_chan_busy_ts)) {
*ext_chan_busy = dfs->dfs_rinfo.dfs_ext_chan_busy;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
"Use cached copy of ext_chan_busy extchanbusy=%d rn_lastfull_ts=%llu ext_chan_busy_ts=%llu\n",
*ext_chan_busy,
(uint64_t)dfs->dfs_rinfo.rn_lastfull_ts,
(uint64_t)dfs->dfs_rinfo.ext_chan_busy_ts);
}
}
int dfs_get_pri_margin(struct wlan_dfs *dfs,
int is_extchan_detect,
int is_fixed_pattern)
@@ -90,21 +114,7 @@ int dfs_get_pri_margin(struct wlan_dfs *dfs,
lmac_get_tsf64(dfs->dfs_pdev_obj);
dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
} else {
/*
* Check to see if the cached value of ext_chan_busy
* can be used.
*/
ext_chan_busy = 0;
if (dfs->dfs_rinfo.dfs_ext_chan_busy) {
if (dfs->dfs_rinfo.rn_lastfull_ts <
dfs->dfs_rinfo.ext_chan_busy_ts) {
ext_chan_busy =
dfs->dfs_rinfo.dfs_ext_chan_busy;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
"PRI Use cached copy of ext_chan_busy extchanbusy=%d\n",
ext_chan_busy);
}
}
dfs_get_cached_ext_chan_busy(dfs, &ext_chan_busy);
}
adjust_pri = dfs_adjust_pri_per_chan_busy(ext_chan_busy,
pri_margin);
@@ -130,26 +140,7 @@ int dfs_get_filter_threshold(struct wlan_dfs *dfs,
lmac_get_tsf64(dfs->dfs_pdev_obj);
dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
} else {
/*
* Check to see if the cached value of ext_chan_busy
* can be used.
*/
ext_chan_busy = 0;
if (dfs->dfs_rinfo.dfs_ext_chan_busy) {
if (dfs->dfs_rinfo.rn_lastfull_ts <
dfs->dfs_rinfo.ext_chan_busy_ts) {
ext_chan_busy =
dfs->dfs_rinfo.dfs_ext_chan_busy;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
"THRESH Use cached copy of ext_chan_busy extchanbusy=%d rn_lastfull_ts=%llu ext_chan_busy_ts=%llu\n",
ext_chan_busy,
(uint64_t)
dfs->dfs_rinfo.rn_lastfull_ts,
(uint64_t)
dfs->dfs_rinfo.ext_chan_busy_ts
);
}
}
dfs_get_cached_ext_chan_busy(dfs, &ext_chan_busy);
}
adjust_thresh =

View File

@@ -255,6 +255,52 @@ static void dfs_radar_fft_search_report_parse(struct wlan_dfs *dfs,
}
}
/**
* dfs_check_for_false_detection() - Check for possible false detection on
* beeliner this may also work for Cascade but parameters
* (e.g. AGC_MB_GAIN_THRESH1) may be different for Cascade.
* @dfs: pointer to wlan_dfs structure.
* @rs: pointer to rx_radar_status structure.
* @false_detect: Pointer to save false detect value.
* @rssi: RSSI.
*/
static inline void dfs_check_for_false_detection(
struct wlan_dfs *dfs,
struct rx_radar_status *rs,
bool *false_detect,
uint8_t rssi)
{
bool is_ht160 = false;
bool is_false_detect = false;
is_ht160 = dfs->dfs_caps.wlan_chip_is_ht160;
is_false_detect = dfs->dfs_caps.wlan_chip_is_false_detect;
if ((dfs->dfs_caps.wlan_chip_is_over_sampled == 0) &&
(is_ht160 == 0 && is_false_detect)) {
if ((rs->agc_mb_gain > AGC_MB_GAIN_THRESH1) &&
((rs->agc_total_gain - rs->agc_mb_gain) <
AGC_OTHER_GAIN_THRESH1)) {
*false_detect = true;
}
if ((rs->agc_mb_gain > AGC_MB_GAIN_THRESH2) &&
((rs->agc_total_gain - rs->agc_mb_gain) >
AGC_OTHER_GAIN_THRESH2) &&
(rssi > AGC_GAIN_RSSI_THRESH)) {
*false_detect = true;
}
}
if (*false_detect)
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"%s: setting false_detect to TRUE because of mb/total_gain/rssi, agc_mb_gain=%d, agc_total_gain=%d, rssi=%d\n",
__func__,
rs->agc_mb_gain,
rs->agc_total_gain,
rssi);
}
/**
* dfs_tlv_parse_frame () - Parse a Peregrine BB TLV frame.
* @dfs: pointer to wlan_dfs structure.
@@ -282,8 +328,6 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
uint32_t tlv_hdr[1];
bool first_tlv = true;
bool false_detect = false;
bool is_ht160 = false;
bool is_false_detect = false;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"%s: total length = %zu bytes\n",
@@ -335,47 +379,8 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs,
dfs_radar_summary_parse(dfs, buf + i,
MS(tlv_hdr[TLV_REG], TLV_LEN), rs);
/*
* Check for possible false detection on
* beeliner this may also work for Cascade but
* parameters (e.g. AGC_MB_GAIN_THRESH1) may
* be different for Cascade.
*/
is_ht160 = dfs->dfs_caps.wlan_chip_is_ht160;
is_false_detect =
dfs->dfs_caps.wlan_chip_is_false_detect;
if ((dfs->dfs_caps.wlan_chip_is_over_sampled == 0) &&
(is_ht160 == 0 && is_false_detect)
) {
if ((rs->agc_mb_gain > AGC_MB_GAIN_THRESH1) &&
((rs->agc_total_gain - rs->agc_mb_gain)
< AGC_OTHER_GAIN_THRESH1)) {
false_detect = true;
DFS_DPRINTK(dfs,
WLAN_DEBUG_DFS_PHYERR,
"%s: setting false_detect to TRUE because of mb/total_gain, agc_mb_gain=%d, agc_total_gain=%d, rssi=%d\n",
__func__,
rs->agc_mb_gain,
rs->agc_total_gain,
rssi);
}
if ((rs->agc_mb_gain > AGC_MB_GAIN_THRESH2) &&
((rs->agc_total_gain - rs->agc_mb_gain)
> AGC_OTHER_GAIN_THRESH2) &&
(rssi > AGC_GAIN_RSSI_THRESH)
) {
false_detect = true;
DFS_DPRINTK(dfs,
WLAN_DEBUG_DFS_PHYERR,
"%s: setting false_detect to TRUE because of mb/total_gain/rssi, agc_mb_gain=%d, agc_total_gain=%d, rssi=%d\n",
__func__,
rs->agc_mb_gain,
rs->agc_total_gain,
rssi);
}
}
dfs_check_for_false_detection(dfs, rs, &false_detect,
rssi);
break;
case TAG_ID_SEARCH_FFT_REPORT:
dfs_radar_fft_search_report_parse(dfs, buf + i,
@@ -722,33 +727,20 @@ int dfs_process_phyerr_bb_tlv(struct wlan_dfs *dfs,
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR_SUM,
"%s: fbin=%d, freq=%d.%d MHz, raw tsf=%u, offset=%d, cooked tsf=%u, rssi=%d, dur=%d, is_chirp=%d, fulltsf=%llu, freq=%d.%d MHz, freq_lo=%d.%dMHz, freq_hi=%d.%d MHz\n",
__func__, rs.sidx,
(int) (rs.freq_offset / 1000),
(int) abs(rs.freq_offset % 1000),
rs.raw_tsf, rs.tsf_offset,
e->rs_tstamp, rs.rssi,
rs.pulse_duration,
(int)rs.is_chirp,
(unsigned long long) fulltsf,
(int)e->freq / 1000,
(int) abs(e->freq) % 1000,
(int)e->freq_lo / 1000,
(int) abs(e->freq_lo) % 1000,
(int)e->freq_hi / 1000,
__func__, rs.sidx, (int) (rs.freq_offset / 1000),
(int) abs(rs.freq_offset % 1000), rs.raw_tsf, rs.tsf_offset,
e->rs_tstamp, rs.rssi, rs.pulse_duration, (int)rs.is_chirp,
(unsigned long long) fulltsf, (int)e->freq / 1000,
(int) abs(e->freq) % 1000, (int)e->freq_lo / 1000,
(int) abs(e->freq_lo) % 1000, (int)e->freq_hi / 1000,
(int) abs(e->freq_hi) % 1000);
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_FALSE_DET,
"ts=%u, dur=%d, rssi=%d, freq_offset=%d.%dMHz, is_chirp=%d, seg_id=%d, peak_mag=%d, total_gain=%d, mb_gain=%d, relpwr_db=%d\n",
e->rs_tstamp,
rs.pulse_duration,
rs.rssi,
e->rs_tstamp, rs.pulse_duration, rs.rssi,
(int)e->freq_offset_khz / 1000,
(int)abs(e->freq_offset_khz) % 1000,
(int)rs.is_chirp,
rsfr.seg_id,
rsfr.peak_mag,
rs.agc_total_gain,
rs.agc_mb_gain,
(int)abs(e->freq_offset_khz) % 1000, (int)rs.is_chirp,
rsfr.seg_id, rsfr.peak_mag, rs.agc_total_gain, rs.agc_mb_gain,
rsfr.relpwr_db);
return 1;

View File

@@ -162,11 +162,7 @@ int dfs_process_phyerr_owl(struct wlan_dfs *dfs,
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR_SUM,
"%s: rssi=%u dur=%u, freq=%d MHz, freq_lo=%d MHz, freq_hi=%d MHz\n",
__func__,
rssi,
dur,
e->freq/1000,
e->freq_lo/1000,
__func__, rssi, dur, e->freq/1000, e->freq_lo/1000,
e->freq_hi / 1000);
return 1;
@@ -266,8 +262,7 @@ int dfs_process_phyerr_sowl(struct wlan_dfs *dfs,
if (!pulse_bw_info) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"ERROR channel dur=%u rssi=%u pulse_bw_info=0x%x datalen MOD 4 = %d\n",
dur, rssi, pulse_bw_info,
(datalen & 0x3));
dur, rssi, pulse_bw_info, (datalen & 0x3));
/*
* Bogus bandwidth info received in descriptor, so
* ignore this PHY error.
@@ -305,15 +300,8 @@ int dfs_process_phyerr_sowl(struct wlan_dfs *dfs,
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR_SUM,
"%s: pulse_bw_info=0x%x pulse_length_ext=%u pulse_length_pri=%u rssi=%u ext_rssi=%u, freq=%d MHz, freq_lo=%d MHz, freq_hi=%d MHz\n",
__func__,
pulse_bw_info,
pulse_length_ext,
pulse_length_pri,
rssi,
ext_rssi,
e->freq/1000,
e->freq_lo/1000,
e->freq_hi/1000);
__func__, pulse_bw_info, pulse_length_ext, pulse_length_pri,
rssi, ext_rssi, e->freq/1000, e->freq_lo/1000, e->freq_hi/1000);
#undef EXT_CH_RADAR_FOUND
#undef PRI_CH_RADAR_FOUND
#undef EXT_CH_RADAR_EARLY_FOUND
@@ -354,8 +342,7 @@ int dfs_process_phyerr_merlin(struct wlan_dfs *dfs,
case 0x01:
/* Radar in ctrl channel */
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"RAW RSSI: rssi=%u ext_rssi=%u\n",
rssi, ext_rssi);
"RAW RSSI: rssi=%u ext_rssi=%u\n", rssi, ext_rssi);
if (ext_rssi >= (rssi + 3)) {
/*
* Cannot use ctrl channel RSSI if extension channel is
@@ -367,8 +354,7 @@ int dfs_process_phyerr_merlin(struct wlan_dfs *dfs,
case 0x02:
/* Radar in extension channel */
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"RAW RSSI: rssi=%u ext_rssi=%u\n",
rssi, ext_rssi);
"RAW RSSI: rssi=%u ext_rssi=%u\n", rssi, ext_rssi);
if (rssi >= (ext_rssi + 12)) {
/*
* Cannot use extension channel RSSI if control channel
@@ -435,6 +421,111 @@ static void dfs_dump_phyerr_contents(const char *d, int len)
DFS_PRINTK("%s: %s\n", __func__, buf);
}
/**
* dfs_bump_up_bin5_pulse_dur() - Bump up to a random BIN 5 pulse duration.
* @dfs: Pointer to wlan_dfs structure.
* @e: Pointer to dfs_phy_err structure.
* @slope: Slope value.
*/
static inline void dfs_bump_up_bin5_pulse_dur(
struct wlan_dfs *dfs,
struct dfs_phy_err *e,
int slope)
{
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR, "old dur %d slope =%d\n",
e->dur, slope);
e->is_sw_chirp = 1;
/* bump up to a random bin5 pulse duration */
if (e->dur < MIN_BIN5_DUR)
e->dur = dfs_get_random_bin5_dur(dfs, e->fulltsf);
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR, "new dur %d\n", e->dur);
}
/**
* dfs_filter_short_pulses() - Filter short pulses.
* @dfs: Pointer to wlan_dfs structure.
* @e: Pointer to dfs_phy_err structure.
* @retval: Return value
*
* Rssi is not accurate for short pulses, so donot filter based on that for
* short duration pulses.
*/
static inline void dfs_filter_short_pulses(
struct wlan_dfs *dfs,
struct dfs_phy_err *e,
int *retval)
{
if (dfs->dfs_caps.wlan_dfs_ext_chan_ok) {
if ((e->rssi < dfs->dfs_rinfo.rn_minrssithresh &&
(e->dur > MAX_DUR_FOR_LOW_RSSI)) ||
e->dur > (dfs->dfs_rinfo.rn_maxpulsedur)) {
dfs->wlan_dfs_stats.rssi_discards++;
*retval = 1;
}
} else if (e->rssi < dfs->dfs_rinfo.rn_minrssithresh ||
e->dur > dfs->dfs_rinfo.rn_maxpulsedur) {
dfs->wlan_dfs_stats.rssi_discards++;
*retval = 1;
}
if (*retval) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
"%s pulse is discarded: dur=%d, maxpulsedur=%d, rssi=%d, minrssi=%d\n",
(dfs->dfs_caps.wlan_dfs_ext_chan_ok) ?
"Extension channel" : "",
e->dur, dfs->dfs_rinfo.rn_maxpulsedur,
e->rssi, dfs->dfs_rinfo.rn_minrssithresh);
}
}
/**
* dfs_is_second_seg_radar_disabled() - Check for second segment radar disabled.
* @dfs: Pointer to wlan_dfs structure.
* @seg_id: Segment id.
*
* Return: true if the second segment RADAR is enabled else false.
*/
static inline bool dfs_is_second_seg_radar_disabled(
struct wlan_dfs *dfs,
int seg_id)
{
if ((seg_id == SEG_ID_SECONDARY) &&
!(dfs->dfs_proc_phyerr &
DFS_SECOND_SEGMENT_RADAR_EN)) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS3,
"%s: Do not process PHY error data from Second segment, DFS_SECOND_SEGMENT_RADAR_EN is not enabled\n",
__func__);
return true;
}
return false;
}
/**
* dfs_set_chan_index() - Set channel index.
* @dfs: Pointer to wlan_dfs structure.
* @e: Pointer to dfs_phy_err structure.
* @event: Pointer to dfs_event structure.
*/
static inline void dfs_set_chan_index(
struct wlan_dfs *dfs,
struct dfs_phy_err *e,
struct dfs_event *event)
{
if (e->is_pri) {
event->re_chanindex = dfs->dfs_curchan_radindex;
} else {
event->re_chanindex = dfs->dfs_extchan_radindex;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"%s %s New extension channel event is added to queue\n",
__func__,
(event->re_chanindex == -1) ?
"- phyerr on ext channel\n" : "");
}
}
void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
uint8_t r_rssi, uint8_t r_ext_rssi, uint32_t r_rs_tstamp,
uint64_t r_fulltsf)
@@ -595,16 +686,7 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
(e.is_pri ? 1 : 0),
(e.is_ext ? 1 : 0), &slope, &dc_found);
if (add_dur) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"old dur %d slope =%d\n", e.dur, slope);
e.is_sw_chirp = 1;
/* bump up to a random bin5 pulse duration */
if (e.dur < MIN_BIN5_DUR) {
e.dur = dfs_get_random_bin5_dur(dfs,
e.fulltsf);
}
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"new dur %d\n", e.dur);
dfs_bump_up_bin5_pulse_dur(dfs, &e, slope);
} else {
/* Set the duration so that it is rejected. */
e.is_sw_chirp = 0;
@@ -616,7 +698,7 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
} else {
/*
* We have a pulse that is either bigger than
* MAX_BIN5_DUR or * less than MAYBE_BIN5_DUR
* MAX_BIN5_DUR or less than MAYBE_BIN5_DUR
*/
if ((dfs->dfsdomain == DFS_FCC_DOMAIN) ||
(dfs->dfsdomain == DFS_MKK4_DOMAIN)) {
@@ -654,8 +736,7 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
if ((dfs->dfs_curchan->dfs_ch_flags & CHANNEL_108G) == CHANNEL_108G) {
if (!(dfs->dfs_proc_phyerr & DFS_AR_EN)) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS2,
"%s: DFS_AR_EN not enabled\n",
__func__);
"%s: DFS_AR_EN not enabled\n", __func__);
return;
}
WLAN_DFSEVENTQ_LOCK(dfs);
@@ -663,8 +744,7 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
if (event == NULL) {
WLAN_DFSEVENTQ_UNLOCK(dfs);
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS,
"%s: no more events space left\n",
__func__);
"%s: no more events space left\n", __func__);
return;
}
STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list);
@@ -694,54 +774,22 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
IEEE80211_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) &&
IEEE80211_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan))) ||
(dfs_is_precac_timer_running(dfs))) {
int retval = 0;
if (!(dfs->dfs_proc_phyerr & DFS_RADAR_EN)) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS3,
"%s: DFS_RADAR_EN not enabled\n",
__func__);
return;
}
/*
* Rssi is not accurate for short pulses, so donot
* filter based on that for short duration pulses.
*/
if (dfs->dfs_caps.wlan_dfs_ext_chan_ok) {
if ((e.rssi < dfs->dfs_rinfo.rn_minrssithresh &&
(e.dur > 4)) || e.dur >
(dfs->dfs_rinfo.rn_maxpulsedur)) {
dfs->wlan_dfs_stats.rssi_discards++;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
"Extension channel pulse is discarded: dur=%d, maxpulsedur=%d, rssi=%d, minrssi=%d\n",
e.dur,
dfs->dfs_rinfo.rn_maxpulsedur,
e.rssi,
dfs->dfs_rinfo.rn_minrssithresh
);
return;
}
} else {
if (e.rssi < dfs->dfs_rinfo.rn_minrssithresh ||
e.dur >
dfs->dfs_rinfo.rn_maxpulsedur) {
dfs->wlan_dfs_stats.rssi_discards++;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS1,
"Pulse is discarded: dur=%d, maxpulsedur=%d, rssi=%d, minrssi=%d\n",
e.dur,
dfs->dfs_rinfo.rn_maxpulsedur,
e.rssi,
dfs->dfs_rinfo.rn_minrssithresh
);
return;
}
}
if ((e.seg_id == SEG_ID_SECONDARY) &&
!(dfs->dfs_proc_phyerr &
DFS_SECOND_SEGMENT_RADAR_EN)){
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS3,
"%s: Do not process PHY error data from Second segment, DFS_SECOND_SEGMENT_RADAR_EN is not enabled\n",
__func__);
dfs_filter_short_pulses(dfs, &e, &retval);
if (retval)
return;
if (dfs_is_second_seg_radar_disabled(dfs, e.seg_id))
return;
}
/* Add the event to the list, if there's space. */
WLAN_DFSEVENTQ_LOCK(dfs);
@@ -781,19 +829,8 @@ void dfs_process_phyerr(struct wlan_dfs *dfs, void *buf, uint16_t datalen,
}
/* Correctly set which channel is being reported on */
if (e.is_pri) {
event->re_chanindex = dfs->dfs_curchan_radindex;
} else {
if (dfs->dfs_extchan_radindex == -1) {
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"%s - phyerr on ext channel\n",
__func__);
}
event->re_chanindex = dfs->dfs_extchan_radindex;
DFS_DPRINTK(dfs, WLAN_DEBUG_DFS_PHYERR,
"%s New extension channel event is added to queue\n",
__func__);
}
dfs_set_chan_index(dfs, &e, event);
WLAN_DFSQ_LOCK(dfs);
STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list);
WLAN_DFSQ_UNLOCK(dfs);

File diff suppressed because it is too large Load Diff

View File

@@ -247,6 +247,32 @@ struct dfs_pulse dfs_korea_radars[] = {
#define TARGET_TYPE_QCA9888 12
#define RSSI_THERSH_AR900B 15
/**
* dfs_assign_fcc_pulse_table() - Assign FCC pulse table
* @rinfo: Pointer to wlan_dfs_radar_tab_info structure.
* @target_type: Target type.
*/
static inline void dfs_assign_fcc_pulse_table(
struct wlan_dfs_radar_tab_info *rinfo,
uint32_t target_type)
{
rinfo->dfs_radars = dfs_fcc_radars;
rinfo->numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
if (target_type == TARGET_TYPE_AR900B ||
target_type == TARGET_TYPE_IPQ4019) {
rinfo->b5pulses = dfs_fcc_bin5pulses_ar900b;
rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_ar900b);
} else if (target_type == TARGET_TYPE_QCA9984 ||
target_type == TARGET_TYPE_QCA9888) {
rinfo->b5pulses = dfs_fcc_bin5pulses_qca9984;
rinfo->numb5radars =
QDF_ARRAY_SIZE(dfs_fcc_bin5pulses_qca9984);
} else {
rinfo->b5pulses = dfs_fcc_bin5pulses;
rinfo->numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
}
}
void ol_if_dfs_configure(struct wlan_dfs *dfs)
{
struct wlan_dfs_radar_tab_info rinfo;
@@ -284,24 +310,7 @@ void ol_if_dfs_configure(struct wlan_dfs *dfs)
rinfo.b5pulses = NULL;
rinfo.numb5radars = 0;
} else {
rinfo.dfs_radars = dfs_fcc_radars;
rinfo.numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
if (target_type == TARGET_TYPE_AR900B ||
target_type == TARGET_TYPE_IPQ4019) {
rinfo.b5pulses = dfs_fcc_bin5pulses_ar900b;
rinfo.numb5radars = QDF_ARRAY_SIZE(
dfs_fcc_bin5pulses_ar900b);
} else if (target_type == TARGET_TYPE_QCA9984 ||
target_type == TARGET_TYPE_QCA9888) {
rinfo.b5pulses = dfs_fcc_bin5pulses_qca9984;
rinfo.numb5radars = QDF_ARRAY_SIZE(
dfs_fcc_bin5pulses_qca9984);
} else {
rinfo.b5pulses = dfs_fcc_bin5pulses;
rinfo.numb5radars =
QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
}
dfs_assign_fcc_pulse_table(&rinfo, target_type);
}
break;

View File

@@ -164,8 +164,13 @@ int dfs_staggered_check(struct wlan_dfs *dfs, struct dfs_filter *rf,
delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
refpri = dl->dl_elems[delayindex].de_time;
if ((score[n] >= highestscore) && (dfs_is_unique_pri(highestpri,
midpri, lowestpri, refpri))) {
if (!dfs_is_unique_pri(highestpri,
midpri,
lowestpri,
refpri))
continue;
if (score[n] >= highestscore) {
lowestscore = midscore;
lowestpri = midpri;
lowestscoreindex = midscoreindex;
@@ -175,25 +180,17 @@ int dfs_staggered_check(struct wlan_dfs *dfs, struct dfs_filter *rf,
highestscore = score[n];
highestpri = refpri;
highestscoreindex = n;
} else {
if ((score[n] >= midscore) &&
(dfs_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) &&
(dfs_is_unique_pri(highestpri, midpri,
lowestpri, refpri))
) {
lowestscore = score[n];
lowestpri = refpri;
lowestscoreindex = n;
}
} else if (score[n] >= midscore) {
lowestscore = midscore;
lowestpri = midpri;
lowestscoreindex = midscoreindex;
midscore = score[n];
midpri = refpri;
midscoreindex = n;
} else if (score[n] >= lowestscore) {
lowestscore = score[n];
lowestpri = refpri;
lowestscoreindex = n;
}
}

View File

@@ -233,17 +233,17 @@ int dfs_main_attach(struct wlan_dfs *dfs)
}
/* Allocate memory for radar table. */
dfs->dfs_radartable = (int8_t **)qdf_mem_malloc(256*sizeof(int8_t *));
if (dfs->dfs_radartable == NULL) {
dfs->dfs_ftindextable = (int8_t **)qdf_mem_malloc(256*sizeof(int8_t *));
if (dfs->dfs_ftindextable == NULL) {
DFS_PRINTK(
"%s: Cannot allocate memory for radar table\n",
__func__);
goto bad1;
}
for (n = 0; n < 256; n++) {
dfs->dfs_radartable[n] = qdf_mem_malloc(
dfs->dfs_ftindextable[n] = qdf_mem_malloc(
DFS_MAX_RADAR_OVERLAP*sizeof(int8_t));
if (dfs->dfs_radartable[n] == NULL) {
if (dfs->dfs_ftindextable[n] == NULL) {
DFS_PRINTK(
"%s: cannot allocate memory for radar table entry\n",
__func__);
@@ -290,8 +290,8 @@ int dfs_main_attach(struct wlan_dfs *dfs)
return 0;
bad2:
qdf_mem_free(dfs->dfs_radartable);
dfs->dfs_radartable = NULL;
qdf_mem_free(dfs->dfs_ftindextable);
dfs->dfs_ftindextable = NULL;
bad1:
for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
if (dfs->dfs_radarf[n] != NULL) {
@@ -391,15 +391,15 @@ void dfs_main_detach(struct wlan_dfs *dfs)
}
}
if (dfs->dfs_radartable != NULL) {
if (dfs->dfs_ftindextable != NULL) {
for (n = 0; n < 256; n++) {
if (dfs->dfs_radartable[n] != NULL) {
qdf_mem_free(dfs->dfs_radartable[n]);
dfs->dfs_radartable[n] = NULL;
if (dfs->dfs_ftindextable[n] != NULL) {
qdf_mem_free(dfs->dfs_ftindextable[n]);
dfs->dfs_ftindextable[n] = NULL;
}
}
qdf_mem_free(dfs->dfs_radartable);
dfs->dfs_radartable = NULL;
qdf_mem_free(dfs->dfs_ftindextable);
dfs->dfs_ftindextable = NULL;
dfs->wlan_dfs_isdfsregdomain = 0;
}