|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
|
|
|
+ * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
|
|
|
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
|
|
*
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
@@ -322,6 +322,7 @@ void dfs_add_pulse(
|
|
|
dl->dl_numelems = n+1;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
dfs_debug(dfs, WLAN_DEBUG_DFS2, "dl firstElem = %d lastElem = %d",
|
|
|
dl->dl_firstelem, dl->dl_lastelem);
|
|
|
}
|
|
@@ -544,6 +545,55 @@ static inline int dfs_bin_basic_sanity(
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * dfs_pick_lowpri() - Pick lowpri as refpri
|
|
|
+ * @dfs: Pointer to wlan_dfs structure.
|
|
|
+ * @dl: Pointer to dfs delayline.
|
|
|
+ * @rf: Pointer to dfs_filter structure.
|
|
|
+ * @lowpriindex: Low PRI index.
|
|
|
+ * @scoreindex: score index.
|
|
|
+ * @primargin: PRI margin.
|
|
|
+ */
|
|
|
+#ifdef DFS_PRI_MULTIPLIER
|
|
|
+static inline void dfs_pick_lowpri(struct wlan_dfs *dfs,
|
|
|
+ struct dfs_delayline *dl,
|
|
|
+ struct dfs_filter *rf,
|
|
|
+ uint32_t lowpriindex,
|
|
|
+ uint32_t *scoreindex,
|
|
|
+ uint32_t primargin)
|
|
|
+{
|
|
|
+ uint32_t candidate_refpri, deltapri, lowpri;
|
|
|
+ uint32_t dindex_candidate, dindex_lowpri;
|
|
|
+ uint32_t i;
|
|
|
+
|
|
|
+ dindex_candidate = (dl->dl_firstelem + *scoreindex) & DFS_MAX_DL_MASK;
|
|
|
+ dindex_lowpri = (dl->dl_firstelem + lowpriindex) & DFS_MAX_DL_MASK;
|
|
|
+
|
|
|
+ candidate_refpri = dl->dl_elems[dindex_candidate].de_time;
|
|
|
+ lowpri = dl->dl_elems[dindex_lowpri].de_time;
|
|
|
+
|
|
|
+ if (rf->rf_ignore_pri_window == 0 &&
|
|
|
+ candidate_refpri != lowpri) {
|
|
|
+ for (i = 1; i <= dfs->dfs_pri_multiplier; i++) {
|
|
|
+ deltapri = DFS_DIFF(candidate_refpri, i * lowpri);
|
|
|
+ if (deltapri < primargin) {
|
|
|
+ *scoreindex = lowpriindex;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline void dfs_pick_lowpri(struct wlan_dfs *dfs,
|
|
|
+ struct dfs_delayline *dl,
|
|
|
+ struct dfs_filter *rf,
|
|
|
+ uint32_t lowpriindex,
|
|
|
+ uint32_t *scoreindex,
|
|
|
+ uint32_t primargin)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/**
|
|
|
* dfs_find_scoreindex() - Find score index
|
|
|
* @rf: Pointer to dfs_filter structure.
|
|
@@ -667,6 +717,18 @@ int dfs_bin_check(
|
|
|
dfs_find_scoreindex(rf, highscore, lowpriindex, highscoreindex,
|
|
|
&scoreindex);
|
|
|
|
|
|
+ /*
|
|
|
+ * Observed ETSI type2 while channel loading 31% with pulse pri:
|
|
|
+ * 1489, 2978, 2978, 2978, 1489, 2978, 1489 us. With above logic,
|
|
|
+ * the highscore will be 4 (2978), scoreindex is 5. In this case,
|
|
|
+ * index 0, 4, 6 pulses will be not matched later in
|
|
|
+ * dfs_count_the_other_delay_elements(), which leads to the radar was
|
|
|
+ * not detected. The fix is: compare the highscore pri with lowpri,
|
|
|
+ * if they have relationship, within primargin of
|
|
|
+ * [1, dfs_pri_multiplier] times of lowpri, choose lowpri as refpri.
|
|
|
+ */
|
|
|
+ dfs_pick_lowpri(dfs, dl, rf, lowpriindex, &scoreindex, primargin);
|
|
|
+
|
|
|
/* We got the possible pri, save its parameters as reference. */
|
|
|
dfs_find_refs(dl, rf, scoreindex, &refdur, &refpri);
|
|
|
|
|
@@ -802,8 +864,8 @@ static void dfs_count_the_other_delay_elements(
|
|
|
int fundamentalpri)
|
|
|
{
|
|
|
int delayindex;
|
|
|
- uint32_t searchpri, searchdur, deltadur, deltapri1, deltapri2;
|
|
|
- uint32_t j = 0, delta_time_stamps, deltapri;
|
|
|
+ uint32_t searchpri, searchdur, deltadur;
|
|
|
+ uint32_t j = 0, delta_time_stamps, deltapri, k;
|
|
|
int dindex, primatch, numpulsetochk = 2;
|
|
|
int32_t sidx_min = DFS_BIG_SIDX;
|
|
|
int32_t sidx_max = -DFS_BIG_SIDX;
|
|
@@ -819,23 +881,28 @@ static void dfs_count_the_other_delay_elements(
|
|
|
dl->dl_elems[dindex].de_time -= refpri;
|
|
|
searchpri = refpri;
|
|
|
}
|
|
|
+
|
|
|
searchdur = dl->dl_elems[delayindex].de_dur;
|
|
|
deltadur = DFS_DIFF(searchdur, refdur);
|
|
|
deltapri = DFS_DIFF(searchpri, refpri);
|
|
|
- deltapri1 = DFS_DIFF(searchpri, refpri);
|
|
|
- deltapri2 = DFS_DIFF(searchpri, 2 * refpri);
|
|
|
primatch = 0;
|
|
|
|
|
|
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);
|
|
|
- if (deltapri1 < (2 * primargin)) {
|
|
|
+ deltapri = DFS_DIFF(searchpri, (j + 1) * refpri);
|
|
|
+ if (deltapri < (2 * primargin)) {
|
|
|
+ primatch = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ for (k = 1; k <= dfs->dfs_pri_multiplier; k++) {
|
|
|
+ deltapri = DFS_DIFF(searchpri, k * refpri);
|
|
|
+ if (deltapri < primargin) {
|
|
|
primatch = 1;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- } else if ((deltapri1 < primargin) || (deltapri2 < primargin)) {
|
|
|
- primatch = 1;
|
|
|
}
|
|
|
|
|
|
if (primatch && (deltadur < durmargin)) {
|