diff mbox

ath: support new FCC DFS Radar Type 1

Message ID 1424902634-18275-1-git-send-email-poh@qca.qualcomm.com (mailing list archive)
State Not Applicable
Delegated to: Kalle Valo
Headers show

Commit Message

Peter Oh Feb. 25, 2015, 10:17 p.m. UTC
Add support for new FCC DFS rules released on August 14, 2014.
FCC has added a new radar type named Radar Type 1 and original
Radar Type 1 is renamed to Radar Type 0 in consequence.
In fact, the type ID does nothing to functionalities.
In other words, even if we re-order the IDs, DFS detection will
work as well, but we give the ID with matching to FCC doc.

By adding this support, the drivers using this DFS function are
able to support both of old and new FCC DFS rules simultaneously
without any other changes.

Signed-off-by: Peter Oh <poh@qca.qualcomm.com>
---
 drivers/net/wireless/ath/dfs_pattern_detector.c | 23 ++++++++++----------
 drivers/net/wireless/ath/dfs_pattern_detector.h |  5 +++++
 drivers/net/wireless/ath/dfs_pri_detector.c     | 29 ++++++++++++++++++++++---
 drivers/net/wireless/ath/dfs_pri_detector.h     |  4 ++--
 4 files changed, 44 insertions(+), 17 deletions(-)

Comments

Zefir Kurtisi Feb. 27, 2015, 10:45 a.m. UTC | #1
On 02/25/2015 11:17 PM, Peter Oh wrote:
> Add support for new FCC DFS rules released on August 14, 2014.
> FCC has added a new radar type named Radar Type 1 and original
> Radar Type 1 is renamed to Radar Type 0 in consequence.
> In fact, the type ID does nothing to functionalities.
> In other words, even if we re-order the IDs, DFS detection will
> work as well, but we give the ID with matching to FCC doc.
> 
> By adding this support, the drivers using this DFS function are
> able to support both of old and new FCC DFS rules simultaneously
> without any other changes.
> 
> [...]

Peter,

while trying to solve detection of the special FCC type 1 radar pattern with the
pri_detector at hand is a valid approach, it is neither suitable nor effective.

It is not suitable because in the way you do, it will not reach the required
detection probability required to pass certification. This is because you take the
very first pri to configure its detector specs, which is way too optimistic. You
have to consider that the detector must be able to detect properly with only 50%
of the pulses seen. In this particular case, you would ignore a lot of type 1
patterns, since the resulting visibility gap causes temporary false PRIs that
won't be considered. You might want to have a look on my slides 15ff in [1] for an
idea what needs to be handled.

Generally, to reach the detection probability requirements, the design of the
PRI-detector at hand follows a full-coverage search with fast cancellation
approach. For that, it allows collecting potential pattern candidates and a
posteriori correction of initial assumptions. It is specifically targeting at
radar patterns defined through PRI-ranges, where constant PRI-ranges are supported
as special cases by setting the same values for pri_min and pri_max (as is done
for pattern 0). With support for PRI-ranges and unique PRIs, everything needed to
detect pattern 1 is there, but defining it as a PRI-range over all the unique 23
PRIs is the wrong way.

The correct approach is more simple, robust, and efficient: define all those 23
unique PRIs as sub-patterns for type 1 with individual specs. Would look like:

#define TYPE1_PPB(X) ((19 * 100000) / (36 * X))
static const struct radar_detector_specs fcc_radar_ref_types[] = {
	FCC_PATTERN(0, 0, 1, 1428, 1428, 1, 18, false),
	FCC_PATTERN(101, 0, 1, 518, 518, 1, TYPE1_PPB(518), false),
	FCC_PATTERN(102, 0, 1, ..., ..., 1, ..., false),
	[...],
	FCC_PATTERN(123, 0, 1, 3066, 3066, 1, TYPE1_PPB(3066), false),
	FCC_PATTERN(2, 0, 5, 150, 230, 1, 23, false),
	FCC_PATTERN(3, 6, 10, 200, 500, 1, 16, false),
	FCC_PATTERN(4, 11, 20, 200, 500, 1, 12, false),
	FCC_PATTERN(5, 50, 100, 1000, 2000, 1, 1, true),
	FCC_PATTERN(6, 0, 1, 333, 333, 1, 9, false),
};


Hope it helps, and sorry I didn't do myself, but so far we are only working in
ETSI domains and ignored FCC completely.


Cheers,
Zefir

[1]
http://linuxwireless.sipsolutions.net/attachments/en/developers/DFS/Vancouver2011-Slides-DFS.pdf
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Peter Oh March 3, 2015, 1:29 a.m. UTC | #2
On 02/27/2015 02:45 AM, Zefir Kurtisi wrote:
> On 02/25/2015 11:17 PM, Peter Oh wrote:
>> Add support for new FCC DFS rules released on August 14, 2014.
>> FCC has added a new radar type named Radar Type 1 and original
>> Radar Type 1 is renamed to Radar Type 0 in consequence.
>> In fact, the type ID does nothing to functionalities.
>> In other words, even if we re-order the IDs, DFS detection will
>> work as well, but we give the ID with matching to FCC doc.
>>
>> By adding this support, the drivers using this DFS function are
>> able to support both of old and new FCC DFS rules simultaneously
>> without any other changes.
>>
>> [...]
> Peter,
>
> while trying to solve detection of the special FCC type 1 radar pattern
> with the
> pri_detector at hand is a valid approach, it is neither suitable nor
> effective.
>
> It is not suitable because in the way you do, it will not reach the
> required
> detection probability required to pass certification. This is because you
> take the
> very first pri to configure its detector specs, which is way too
> optimistic. You
> have to consider that the detector must be able to detect properly with
> only 50%
> of the pulses seen. In this particular case, you would ignore a lot of
> type 1
> patterns, since the resulting visibility gap causes temporary false PRIs
> that
> won't be considered. You might want to have a look on my slides 15ff in
> [1] for an
> idea what needs to be handled.
>
> Generally, to reach the detection probability requirements, the design of
> the
> PRI-detector at hand follows a full-coverage search with fast cancellation
> approach. For that, it allows collecting potential pattern candidates and
> a
> posteriori correction of initial assumptions. It is specifically targeting
> at
> radar patterns defined through PRI-ranges, where constant PRI-ranges are
> supported
> as special cases by setting the same values for pri_min and pri_max (as is
> done
> for pattern 0). With support for PRI-ranges and unique PRIs, everything
> needed to
> detect pattern 1 is there, but defining it as a PRI-range over all the
> unique 23
> PRIs is the wrong way.
>
> The correct approach is more simple, robust, and efficient: define all
> those 23
> unique PRIs as sub-patterns for type 1 with individual specs. Would look
> like:
>
> #define TYPE1_PPB(X) ((19 * 100000) / (36 * X))
> static const struct radar_detector_specs fcc_radar_ref_types[] = {
> 	FCC_PATTERN(0, 0, 1, 1428, 1428, 1, 18, false),
> 	FCC_PATTERN(101, 0, 1, 518, 518, 1, TYPE1_PPB(518), false),
> 	FCC_PATTERN(102, 0, 1, ..., ..., 1, ..., false),
> 	[...],
> 	FCC_PATTERN(123, 0, 1, 3066, 3066, 1, TYPE1_PPB(3066), false),
> 	FCC_PATTERN(2, 0, 5, 150, 230, 1, 23, false),
> 	FCC_PATTERN(3, 6, 10, 200, 500, 1, 16, false),
> 	FCC_PATTERN(4, 11, 20, 200, 500, 1, 12, false),
> 	FCC_PATTERN(5, 50, 100, 1000, 2000, 1, 1, true),
> 	FCC_PATTERN(6, 0, 1, 333, 333, 1, 9, false),
> };
>
>
> Hope it helps, and sorry I didn't do myself, but so far we are only
> working in
> ETSI domains and ignored FCC completely.
Thank you Zefir for the advice and I'll review and update the code based 
on your comment.
>
> Cheers,
> Zefir
>
> [1]
> http://linuxwireless.sipsolutions.net/attachments/en/developers/DFS/Vancou
> ver2011-Slides-DFS.pdf
>
> _______________________________________________
> ath10k mailing list
> ath10k@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/ath10k
Thanks,
Peter
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c
index b1de8c6..65958ec 100644
--- a/drivers/net/wireless/ath/dfs_pattern_detector.c
+++ b/drivers/net/wireless/ath/dfs_pattern_detector.c
@@ -21,12 +21,6 @@ 
 #include "dfs_pri_detector.h"
 #include "ath.h"
 
-/*
- * tolerated deviation of radar time stamp in usecs on both sides
- * TODO: this might need to be HW-dependent
- */
-#define PRI_TOLERANCE	16
-
 /**
  * struct radar_types - contains array of patterns defined for one DFS domain
  * @domain: DFS regulatory domain
@@ -81,13 +75,18 @@  static const struct radar_types etsi_radar_types_v15 = {
 	PPB_THRESH(PPB), PRI_TOLERANCE,	CHIRP			\
 }
 
+/* radar types released on August 14, 2014
+ * type 1 PRI values randomly selected within the range of PMIN and PMAX,
+ * hence leave its PPB as 0 to be calculated on the fly.
+ */
 static const struct radar_detector_specs fcc_radar_ref_types[] = {
 	FCC_PATTERN(0, 0, 1, 1428, 1428, 1, 18, false),
-	FCC_PATTERN(1, 0, 5, 150, 230, 1, 23, false),
-	FCC_PATTERN(2, 6, 10, 200, 500, 1, 16, false),
-	FCC_PATTERN(3, 11, 20, 200, 500, 1, 12, false),
-	FCC_PATTERN(4, 50, 100, 1000, 2000, 1, 1, true),
-	FCC_PATTERN(5, 0, 1, 333, 333, 1, 9, false),
+	FCC_PATTERN(1, 0, 1, 518, 3066, 1, 0, false),
+	FCC_PATTERN(2, 0, 5, 150, 230, 1, 23, false),
+	FCC_PATTERN(3, 6, 10, 200, 500, 1, 16, false),
+	FCC_PATTERN(4, 11, 20, 200, 500, 1, 12, false),
+	FCC_PATTERN(5, 50, 100, 1000, 2000, 1, 1, true),
+	FCC_PATTERN(6, 0, 1, 333, 333, 1, 9, false),
 };
 
 static const struct radar_types fcc_radar_types = {
@@ -199,7 +198,7 @@  channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq)
 		goto fail;
 
 	for (i = 0; i < dpd->num_radar_types; i++) {
-		const struct radar_detector_specs *rs = &dpd->radar_spec[i];
+		struct radar_detector_specs *rs = &dpd->radar_spec[i];
 		struct pri_detector *de = pri_detector_init(rs);
 		if (de == NULL)
 			goto fail;
diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.h b/drivers/net/wireless/ath/dfs_pattern_detector.h
index 25a43d6..92be353 100644
--- a/drivers/net/wireless/ath/dfs_pattern_detector.h
+++ b/drivers/net/wireless/ath/dfs_pattern_detector.h
@@ -21,6 +21,11 @@ 
 #include <linux/list.h>
 #include <linux/nl80211.h>
 
+/* tolerated deviation of radar time stamp in usecs on both sides
+ * TODO: this might need to be HW-dependent
+ */
+#define PRI_TOLERANCE	16
+
 /**
  * struct ath_dfs_pool_stats - DFS Statistics for global pools
  */
diff --git a/drivers/net/wireless/ath/dfs_pri_detector.c b/drivers/net/wireless/ath/dfs_pri_detector.c
index 1b5ad19..a234329 100644
--- a/drivers/net/wireless/ath/dfs_pri_detector.c
+++ b/drivers/net/wireless/ath/dfs_pri_detector.c
@@ -21,6 +21,13 @@ 
 #include "dfs_pattern_detector.h"
 #include "dfs_pri_detector.h"
 
+#define FCC_TYPE1_MIN_PRI (518)
+#define FCC_TYPE1_MAX_PRI (3066)
+#define FCC_TYPE1_MIN_PPB (18)
+#define FCC_TYPE1_MAX_PPB (106)
+/* round up of ((1 / 360) * (19 * 1M)) */
+#define FCC_TYPE1_PPB_CONSTANT (52778)
+
 struct ath_dfs_pool_stats global_dfs_pool_stats = {};
 
 #define DFS_POOL_STAT_INC(c) (global_dfs_pool_stats.c++)
@@ -244,6 +251,13 @@  static bool pseq_handler_create_sequences(struct pri_detector *pde,
 		ps.first_ts = p->ts;
 		ps.last_ts = ts;
 		ps.pri = ts - p->ts;
+		if (pde->rs->ppb == 0) {
+			/* runtime calculation of ppb and ppb threshold for
+			 * pri in variable range. ppb threshold is half of ppb.
+			 */
+			pde->rs->ppb = FCC_TYPE1_PPB_CONSTANT / ps.pri;
+			pde->rs->ppb_thresh = (pde->rs->ppb / 2) + 1;
+		}
 		ps.dur = ps.pri * (pde->rs->ppb - 1)
 				+ 2 * pde->rs->max_pri_tolerance;
 
@@ -366,6 +380,14 @@  static void pri_detector_reset(struct pri_detector *pde, u64 ts)
 	}
 	pde->count = 0;
 	pde->last_ts = ts;
+	/* reset FCC type 1 ppb and threshold to be calculated again */
+	if (pde->rs->type_id == 1) {
+		if ((pde->rs->pri_min == FCC_TYPE1_MIN_PRI - PRI_TOLERANCE) &&
+		    (pde->rs->pri_max == FCC_TYPE1_MAX_PRI + PRI_TOLERANCE)) {
+			pde->rs->ppb = 0;
+			pde->rs->ppb_thresh = 0;
+		}
+	}
 }
 
 static void pri_detector_exit(struct pri_detector *de)
@@ -411,7 +433,7 @@  static struct pri_sequence *pri_detector_add_pulse(struct pri_detector *de,
 	return ps;
 }
 
-struct pri_detector *pri_detector_init(const struct radar_detector_specs *rs)
+struct pri_detector *pri_detector_init(struct radar_detector_specs *rs)
 {
 	struct pri_detector *de;
 
@@ -424,8 +446,9 @@  struct pri_detector *pri_detector_init(const struct radar_detector_specs *rs)
 
 	INIT_LIST_HEAD(&de->sequences);
 	INIT_LIST_HEAD(&de->pulses);
-	de->window_size = rs->pri_max * rs->ppb * rs->num_pri;
-	de->max_count = rs->ppb * 2;
+	de->window_size = rs->pri_max *
+		(rs->ppb ? rs->ppb : FCC_TYPE1_MIN_PPB) * rs->num_pri;
+	de->max_count = (rs->ppb ? rs->ppb : FCC_TYPE1_MAX_PPB) * 2;
 	de->rs = rs;
 
 	pool_register_ref();
diff --git a/drivers/net/wireless/ath/dfs_pri_detector.h b/drivers/net/wireless/ath/dfs_pri_detector.h
index 79f0fff..f460b46 100644
--- a/drivers/net/wireless/ath/dfs_pri_detector.h
+++ b/drivers/net/wireless/ath/dfs_pri_detector.h
@@ -63,7 +63,7 @@  struct pri_detector {
 	void (*reset)    (struct pri_detector *de, u64 ts);
 
 /* private: internal use only */
-	const struct radar_detector_specs *rs;
+	struct radar_detector_specs *rs;
 	u64 last_ts;
 	struct list_head sequences;
 	struct list_head pulses;
@@ -72,6 +72,6 @@  struct pri_detector {
 	u32 window_size;
 };
 
-struct pri_detector *pri_detector_init(const struct radar_detector_specs *rs);
+struct pri_detector *pri_detector_init(struct radar_detector_specs *rs);
 
 #endif /* DFS_PRI_DETECTOR_H */