aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch')
-rw-r--r--package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch211
1 files changed, 0 insertions, 211 deletions
diff --git a/package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch b/package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch
deleted file mode 100644
index 3437f139f7..0000000000
--- a/package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
-Date: Tue, 16 Jun 2015 12:52:16 +0200
-Subject: [PATCH] ath9k: DFS - add pulse chirp detection for FCC
-
-FCC long pulse radar (type 5) requires pulses to be
-checked for chirping. This patch implements chirp
-detection based on the FFT data provided for long
-pulses.
-
-A chirp is detected when a set of criteria defined
-by FCC pulse characteristics is met, including
-* have at least 4 FFT samples
-* max_bin index moves equidistantly between samples
-* the gradient is within defined range
-
-The chirp detection has been tested with reference
-radar generating devices and proved to work reliably.
-
-Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/dfs.c
-+++ b/drivers/net/wireless/ath/ath9k/dfs.c
-@@ -30,6 +30,157 @@ struct ath_radar_data {
- u8 pulse_length_pri;
- };
-
-+/**** begin: CHIRP ************************************************************/
-+
-+/* min and max gradients for defined FCC chirping pulses, given by
-+ * - 20MHz chirp width over a pulse width of 50us
-+ * - 5MHz chirp width over a pulse width of 100us
-+ */
-+static const int BIN_DELTA_MIN = 1;
-+static const int BIN_DELTA_MAX = 10;
-+
-+/* we need at least 3 deltas / 4 samples for a reliable chirp detection */
-+#define NUM_DIFFS 3
-+static const int FFT_NUM_SAMPLES = (NUM_DIFFS + 1);
-+
-+/* Threshold for difference of delta peaks */
-+static const int MAX_DIFF = 2;
-+
-+/* width range to be checked for chirping */
-+static const int MIN_CHIRP_PULSE_WIDTH = 20;
-+static const int MAX_CHIRP_PULSE_WIDTH = 110;
-+
-+struct ath9k_dfs_fft_20 {
-+ u8 bin[28];
-+ u8 lower_bins[3];
-+} __packed;
-+struct ath9k_dfs_fft_40 {
-+ u8 bin[64];
-+ u8 lower_bins[3];
-+ u8 upper_bins[3];
-+} __packed;
-+
-+static inline int fft_max_index(u8 *bins)
-+{
-+ return (bins[2] & 0xfc) >> 2;
-+}
-+static inline int fft_max_magnitude(u8 *bins)
-+{
-+ return (bins[0] & 0xc0) >> 6 | bins[1] << 2 | (bins[2] & 0x03) << 10;
-+}
-+static inline u8 fft_bitmap_weight(u8 *bins)
-+{
-+ return bins[0] & 0x3f;
-+}
-+
-+static int ath9k_get_max_index_ht40(struct ath9k_dfs_fft_40 *fft,
-+ bool is_ctl, bool is_ext)
-+{
-+ const int DFS_UPPER_BIN_OFFSET = 64;
-+ /* if detected radar on both channels, select the significant one */
-+ if (is_ctl && is_ext) {
-+ /* first check wether channels have 'strong' bins */
-+ is_ctl = fft_bitmap_weight(fft->lower_bins) != 0;
-+ is_ext = fft_bitmap_weight(fft->upper_bins) != 0;
-+
-+ /* if still unclear, take higher magnitude */
-+ if (is_ctl && is_ext) {
-+ int mag_lower = fft_max_magnitude(fft->lower_bins);
-+ int mag_upper = fft_max_magnitude(fft->upper_bins);
-+ if (mag_upper > mag_lower)
-+ is_ctl = false;
-+ else
-+ is_ext = false;
-+ }
-+ }
-+ if (is_ctl)
-+ return fft_max_index(fft->lower_bins);
-+ return fft_max_index(fft->upper_bins) + DFS_UPPER_BIN_OFFSET;
-+}
-+static bool ath9k_check_chirping(struct ath_softc *sc, u8 *data,
-+ int datalen, bool is_ctl, bool is_ext)
-+{
-+ int i;
-+ int max_bin[FFT_NUM_SAMPLES];
-+ struct ath_hw *ah = sc->sc_ah;
-+ struct ath_common *common = ath9k_hw_common(ah);
-+ int prev_delta;
-+
-+ if (IS_CHAN_HT40(ah->curchan)) {
-+ struct ath9k_dfs_fft_40 *fft = (struct ath9k_dfs_fft_40 *) data;
-+ int num_fft_packets = datalen / sizeof(*fft);
-+ if (num_fft_packets == 0)
-+ return false;
-+
-+ ath_dbg(common, DFS, "HT40: datalen=%d, num_fft_packets=%d\n",
-+ datalen, num_fft_packets);
-+ if (num_fft_packets < (FFT_NUM_SAMPLES)) {
-+ ath_dbg(common, DFS, "not enough packets for chirp\n");
-+ return false;
-+ }
-+ /* HW sometimes adds 2 garbage bytes in front of FFT samples */
-+ if ((datalen % sizeof(*fft)) == 2) {
-+ fft = (struct ath9k_dfs_fft_40 *) (data + 2);
-+ ath_dbg(common, DFS, "fixing datalen by 2\n");
-+ }
-+ if (IS_CHAN_HT40MINUS(ah->curchan)) {
-+ int temp = is_ctl;
-+ is_ctl = is_ext;
-+ is_ext = temp;
-+ }
-+ for (i = 0; i < FFT_NUM_SAMPLES; i++)
-+ max_bin[i] = ath9k_get_max_index_ht40(fft + i, is_ctl,
-+ is_ext);
-+ } else {
-+ struct ath9k_dfs_fft_20 *fft = (struct ath9k_dfs_fft_20 *) data;
-+ int num_fft_packets = datalen / sizeof(*fft);
-+ if (num_fft_packets == 0)
-+ return false;
-+ ath_dbg(common, DFS, "HT20: datalen=%d, num_fft_packets=%d\n",
-+ datalen, num_fft_packets);
-+ if (num_fft_packets < (FFT_NUM_SAMPLES)) {
-+ ath_dbg(common, DFS, "not enough packets for chirp\n");
-+ return false;
-+ }
-+ /* in ht20, this is a 6-bit signed number => shift it to 0 */
-+ for (i = 0; i < FFT_NUM_SAMPLES; i++)
-+ max_bin[i] = fft_max_index(fft[i].lower_bins) ^ 0x20;
-+ }
-+ ath_dbg(common, DFS, "bin_max = [%d, %d, %d, %d]\n",
-+ max_bin[0], max_bin[1], max_bin[2], max_bin[3]);
-+
-+ /* Check for chirp attributes within specs
-+ * a) delta of adjacent max_bins is within range
-+ * b) delta of adjacent deltas are within tolerance
-+ */
-+ prev_delta = 0;
-+ for (i = 0; i < NUM_DIFFS; i++) {
-+ int ddelta = -1;
-+ int delta = max_bin[i + 1] - max_bin[i];
-+
-+ /* ensure gradient is within valid range */
-+ if (abs(delta) < BIN_DELTA_MIN || abs(delta) > BIN_DELTA_MAX) {
-+ ath_dbg(common, DFS, "CHIRP: invalid delta %d "
-+ "in sample %d\n", delta, i);
-+ return false;
-+ }
-+ if (i == 0)
-+ goto done;
-+ ddelta = delta - prev_delta;
-+ if (abs(ddelta) > MAX_DIFF) {
-+ ath_dbg(common, DFS, "CHIRP: ddelta %d too high\n",
-+ ddelta);
-+ return false;
-+ }
-+done:
-+ ath_dbg(common, DFS, "CHIRP - %d: delta=%d, ddelta=%d\n",
-+ i, delta, ddelta);
-+ prev_delta = delta;
-+ }
-+ return true;
-+}
-+/**** end: CHIRP **************************************************************/
-+
- /* convert pulse duration to usecs, considering clock mode */
- static u32 dur_to_usecs(struct ath_hw *ah, u32 dur)
- {
-@@ -113,12 +264,6 @@ ath9k_postprocess_radar_event(struct ath
- return false;
- }
-
-- /*
-- * TODO: check chirping pulses
-- * checks for chirping are dependent on the DFS regulatory domain
-- * used, which is yet TBD
-- */
--
- /* convert duration to usecs */
- pe->width = dur_to_usecs(sc->sc_ah, dur);
- pe->rssi = rssi;
-@@ -190,6 +335,16 @@ void ath9k_dfs_process_phyerr(struct ath
- if (!ath9k_postprocess_radar_event(sc, &ard, &pe))
- return;
-
-+ if (pe.width > MIN_CHIRP_PULSE_WIDTH &&
-+ pe.width < MAX_CHIRP_PULSE_WIDTH) {
-+ bool is_ctl = !!(ard.pulse_bw_info & PRI_CH_RADAR_FOUND);
-+ bool is_ext = !!(ard.pulse_bw_info & EXT_CH_RADAR_FOUND);
-+ int clen = datalen - 3;
-+ pe.chirp = ath9k_check_chirping(sc, data, clen, is_ctl, is_ext);
-+ } else {
-+ pe.chirp = false;
-+ }
-+
- ath_dbg(common, DFS,
- "ath9k_dfs_process_phyerr: type=%d, freq=%d, ts=%llu, "
- "width=%d, rssi=%d, delta_ts=%llu\n",