blob: ffcafff8ebfb2e1378d884dab7378be965283a13 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Anurag Chouhan50220ce2016-02-18 20:11:33 +05302 * Copyright (c) 2005-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*===========================================================================
29
30 dfs.h
31
32 OVERVIEW:
33
34 Source code borrowed from QCA_MAIN DFS module
35
36 DEPENDENCIES:
37
38 Are listed for each API below.
39
40 ===========================================================================*/
41
42#ifndef _DFS_H_
43#define _DFS_H_
44
45/*
46 *TO DO DFS- Need to include this file later on
47 *#include "ath_internal.h"
48 */
49/*DFS New Include Start*/
50
Anurag Chouhanc73697b2016-02-21 15:05:43 +053051#include <qdf_net_types.h> /* QDF_NBUF_EXEMPT_NO_EXEMPTION, etc. */
Nirav Shahcbc6d722016-03-01 16:24:53 +053052#include <qdf_nbuf.h> /* qdf_nbuf_t, etc. */
Anurag Chouhanc5548422016-02-24 18:33:27 +053053#include <qdf_util.h> /* qdf_assert */
Anurag Chouhana37b5b72016-02-21 14:53:42 +053054#include <qdf_lock.h> /* cdf_spinlock */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080055#include <cds_queue.h> /* TAILQ */
Anurag Chouhan50220ce2016-02-18 20:11:33 +053056#include <qdf_time.h>
Anurag Chouhan754fbd82016-02-19 17:00:08 +053057#include <qdf_timer.h>
Anurag Chouhan600c3a02016-03-01 10:33:54 +053058#include <qdf_mem.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059#include <osdep.h>
60/*DFS Utility Include END*/
61
62/* From wlan_modules/include/ */
63#include "ath_dfs_structs.h"
64/*DFS - Newly added File to interface cld UMAC and dfs data structures*/
65#include <wma_dfs_interface.h>
66/*
67 *TO DO DFS- Need to include this file later on
68 #include "ah.h"
69 */
70/* #include "ah_desc.h" */
71#include "dfs_ioctl.h"
72#include "dfs_ioctl_private.h"
73#include "dfs_interface.h"
74#include "cds_ieee80211_common.h"
75#include "cds_api.h"
76
77#define ATH_SUPPORT_DFS 1
78#define CHANNEL_TURBO 0x00010
79#define DFS_PRINTK(_fmt, ...) printk((_fmt), __VA_ARGS__)
80#define DFS_DPRINTK(dfs, _m, _fmt, ...) do { \
81 if (((dfs) == NULL) || \
82 ((dfs) != NULL && \
83 ((_m) & (dfs)->dfs_debug_mask))) { \
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053084 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080085 _fmt, __VA_ARGS__); \
86 } \
87} while (0)
88
89#define DFS_MIN(a, b) ((a) < (b) ? (a) : (b))
90#define DFS_MAX(a, b) ((a) > (b) ? (a) : (b))
91#define DFS_DIFF(a, b) (DFS_MAX(a, b) - DFS_MIN(a, b))
92/*
93 * Maximum number of radar events to be processed in a single iteration.
94 * Allows soft watchdog to run.
95 */
96#define MAX_EVENTS 100
97
98#define DFS_STATUS_SUCCESS 0
99#define DFS_STATUS_FAIL 1
100
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800101#define DFS_80P80_SEG0 0
102#define DFS_80P80_SEG1 1
103
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800104/*
105 * Constants to use for chirping detection.
106 *
107 * All are unconverted as HW reports them.
108 *
109 * XXX Are these constants with or without fast clock 5GHz operation?
110 * XXX Peregrine reports pulses in microseconds, not hardware clocks!
111 */
112#define MIN_BIN5_DUR 63 /* 50 * 1.25 */
113#define MIN_BIN5_DUR_MICROSEC 50
114#define MAYBE_BIN5_DUR 35 /* 28 * 1.25 */
115#define MAYBE_BIN5_DUR_MICROSEC 28
116/* #define MAX_BIN5_DUR 131 / * 105 * 1.25* / */
117/* use 145 for osprey conversion is already done using dfs->dur_multiplier */
118#define MAX_BIN5_DUR 145
119#define MAX_BIN5_DUR_MICROSEC 105
120
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800121#define DFS_BIN5_TIME_WINDOW_UNITS_MULTIPLIER 1000000
122
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800123#define DFS_MARGIN_EQUAL(a, b, margin) ((DFS_DIFF(a, b)) <= margin)
124#define DFS_MAX_STAGGERED_BURSTS 3
125
126/*
127 * All filter thresholds in the radar filter tables
128 * are effective at a 50% channel loading
129 */
130#define DFS_CHAN_LOADING_THRESH 50
131#define DFS_EXT_CHAN_LOADING_THRESH 30
132#define DFS_DEFAULT_PRI_MARGIN 6
133#define DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN 4
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530134#define ATH_DFSQ_LOCK(_dfs) qdf_spin_lock_bh((&(_dfs)->dfs_radarqlock))
135#define ATH_DFSQ_UNLOCK(_dfs) qdf_spin_unlock_bh((&(_dfs)->dfs_radarqlock))
136#define ATH_DFSQ_LOCK_INIT(_dfs) qdf_spinlock_create(&(_dfs)->dfs_radarqlock)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800137
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530138#define ATH_ARQ_LOCK(_dfs) qdf_spin_lock_bh((&(_dfs)->dfs_arqlock))
139#define ATH_ARQ_UNLOCK(_dfs) qdf_spin_unlock_bh((&(_dfs)->dfs_arqlock))
140#define ATH_ARQ_LOCK_INIT(_dfs) qdf_spinlock_create(&(_dfs)->dfs_arqlock)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800141
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530142#define ATH_DFSEVENTQ_LOCK(_dfs) qdf_spin_lock_bh((&(_dfs)->dfs_eventqlock))
143#define ATH_DFSEVENTQ_UNLOCK(_dfs) qdf_spin_unlock_bh((&(_dfs)->dfs_eventqlock))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800144#define ATH_DFSEVENTQ_LOCK_INIT(_dfs) \
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530145 qdf_spinlock_create((&(_dfs)->dfs_eventqlock))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800146/* Mask for time stamp from descriptor */
147#define DFS_TSMASK 0xFFFFFFFF
148/* Shift for time stamp from descriptor */
149#define DFS_TSSHIFT 32
150/* 64 bit TSF wrap value */
151#define DFS_TSF_WRAP 0xFFFFFFFFFFFFFFFFULL
152/* TS mask for 64 bit value */
153#define DFS_64BIT_TSFMASK 0x0000000000007FFFULL
154
155#define DFS_AR_RADAR_RSSI_THR 5 /* in dB */
156#define DFS_AR_RADAR_RESET_INT 1 /* in secs */
157#define DFS_AR_RADAR_MAX_HISTORY 500
158#define DFS_AR_REGION_WIDTH 128
159#define DFS_AR_RSSI_THRESH_STRONG_PKTS 17 /* in dB */
160#define DFS_AR_RSSI_DOUBLE_THRESHOLD 15 /* in dB */
161#define DFS_AR_MAX_NUM_ACK_REGIONS 9
162#define DFS_AR_ACK_DETECT_PAR_THRESH 20
163#define DFS_AR_PKT_COUNT_THRESH 20
164
165#define DFS_MAX_DL_SIZE 64
166#define DFS_MAX_DL_MASK 0x3F
167
168#define DFS_NOL_TIME DFS_NOL_TIMEOUT_US
169/* 30 minutes in usecs */
170
171#define DFS_WAIT_TIME (60 * 1000000) /* 1 minute in usecs */
172
173#define DFS_DISABLE_TIME (3 * 60 * 1000000) /* 3 minutes in usecs */
174
175#define DFS_MAX_B5_SIZE 128
176#define DFS_MAX_B5_MASK 0x0000007F /* 128 */
177
178#define DFS_MAX_RADAR_OVERLAP 16 /* Max number of overlapping filters */
179/* Max number of dfs events which can be q'd */
180#define DFS_MAX_EVENTS 1024
181
182#define DFS_RADAR_EN 0x80000000 /* Radar detect is capable */
183#define DFS_AR_EN 0x40000000 /* AR detect is capable */
184#define DFS_MAX_RSSI_VALUE 0x7fffffff /* Max rssi value */
185/* max num of pulses in a burst */
186#define DFS_BIN_MAX_PULSES 60
187#define DFS_BIN5_PRI_LOWER_LIMIT 990 /* us */
188
189/* to cover the single pusle burst case, change from 2010 us to 2010000 us */
190
191/*
192 * this is reverted back to 2010 as larger value causes false
193 * bin5 detect (EV76432, EV76320)
194 */
195#define DFS_BIN5_PRI_HIGHER_LIMIT 2010 /* us */
196
197#define DFS_BIN5_WIDTH_MARGIN 4 /* us */
198#define DFS_BIN5_RSSI_MARGIN 5 /* dBm */
199/*Following threshold is not specified but should be okay statistically*/
200#define DFS_BIN5_BRI_LOWER_LIMIT 300000 /* us */
201#define DFS_BIN5_BRI_UPPER_LIMIT 12000000 /* us */
202/* Max number of pulses kept in buffer */
203#define DFS_MAX_PULSE_BUFFER_SIZE 1024
204#define DFS_MAX_PULSE_BUFFER_MASK 0x3ff
205
206#define DFS_FAST_CLOCK_MULTIPLIER (800/11)
207#define DFS_NO_FAST_CLOCK_MULTIPLIER (80)
208
209#define DFS_WAR_PLUS_30_MHZ_SEPARATION 30
210#define DFS_WAR_MINUS_30_MHZ_SEPARATION -30
211#define DFS_WAR_PEAK_INDEX_ZERO 0
212#define DFS_TYPE4_WAR_PULSE_DURATION_LOWER_LIMIT 11
213#define DFS_TYPE4_WAR_PULSE_DURATION_UPPER_LIMIT 33
214#define DFS_TYPE4_WAR_PRI_LOWER_LIMIT 200
215#define DFS_TYPE4_WAR_PRI_UPPER_LIMIT 500
216#define DFS_TYPE4_WAR_VALID_PULSE_DURATION 12
217#define DFS_ETSI_TYPE2_TYPE3_WAR_PULSE_DUR_LOWER_LIMIT 15
218#define DFS_ETSI_TYPE2_TYPE3_WAR_PULSE_DUR_UPPER_LIMIT 33
219#define DFS_ETSI_TYPE2_WAR_PRI_LOWER_LIMIT 625
220#define DFS_ETSI_TYPE2_WAR_PRI_UPPER_LIMIT 5000
221#define DFS_ETSI_TYPE3_WAR_PRI_LOWER_LIMIT 250
222#define DFS_ETSI_TYPE3_WAR_PRI_UPPER_LIMIT 435
223#define DFS_ETSI_WAR_VALID_PULSE_DURATION 15
224
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530225typedef qdf_spinlock_t dfsq_lock_t;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800226
227#ifdef WIN32
228#pragma pack(push, dfs_pulseparams, 1)
229#endif
230struct dfs_pulseparams {
231 uint64_t p_time; /* time for start of pulse in usecs */
232 uint8_t p_dur; /* Duration of pulse in usecs */
233 uint8_t p_rssi; /* Duration of pulse in usecs */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530234} qdf_packed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800235#ifdef WIN32
236#pragma pack(pop, dfs_pulseparams)
237#endif
238
239#ifdef WIN32
240#pragma pack(push, dfs_pulseline, 1)
241#endif
242struct dfs_pulseline {
243 /* pl_elems - array of pulses in delay line */
244 struct dfs_pulseparams pl_elems[DFS_MAX_PULSE_BUFFER_SIZE];
245 uint32_t pl_firstelem; /* Index of the first element */
246 uint32_t pl_lastelem; /* Index of the last element */
247 uint32_t pl_numelems; /* Number of elements in the delay line */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530248} qdf_packed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800249#ifdef WIN32
250#pragma pack(pop, dfs_pulseline)
251#endif
252
253#ifdef WIN32
254#pragma pack(push, dfs_event, 1)
255#endif
256
257#define DFS_EVENT_CHECKCHIRP 0x01 /* Whether to check the chirp flag */
258#define DFS_EVENT_HW_CHIRP 0x02 /* hardware chirp */
259#define DFS_EVENT_SW_CHIRP 0x04 /* software chirp */
260
261/*
262 * Use this only if the event has CHECKCHIRP set.
263 */
264#define DFS_EVENT_ISCHIRP(e) \
265 ((e)->re_flags & (DFS_EVENT_HW_CHIRP | DFS_EVENT_SW_CHIRP))
266
267/*
268 * Check if the given event is to be rejected as not possibly
269 * a chirp. This means:
270 * (a) it's a hardware or software checked chirp, and
271 * (b) the HW/SW chirp bits are both 0.
272 */
273#define DFS_EVENT_NOTCHIRP(e) \
274 (((e)->re_flags & (DFS_EVENT_CHECKCHIRP)) && \
275 (!DFS_EVENT_ISCHIRP((e))))
276
277struct dfs_event {
278 uint64_t re_full_ts; /* 64-bit full timestamp from interrupt time */
279 uint32_t re_ts; /* Original 15 bit recv timestamp */
280 uint8_t re_rssi; /* rssi of radar event */
281 uint8_t re_dur; /* duration of radar pulse */
282 uint8_t re_chanindex; /* Channel of event */
283 uint8_t re_flags; /* Event flags */
284 uint32_t re_freq; /* Centre frequency of event, KHz */
285 uint32_t re_freq_lo; /* Lower bounds of frequency, KHz */
286 uint32_t re_freq_hi; /* Upper bounds of frequency, KHz */
287 int sidx; /* Pulse Index as in radar summary report */
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800288 int radar_80p80_segid; /* 80p80 segment ID as in radar sum report */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800289 STAILQ_ENTRY(dfs_event) re_list; /* List of radar events */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530290} qdf_packed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800291#ifdef WIN32
292#pragma pack(pop, dfs_event)
293#endif
294
295#define DFS_AR_MAX_ACK_RADAR_DUR 511
296#define DFS_AR_MAX_NUM_PEAKS 3
297#define DFS_AR_ARQ_SIZE 2048 /* 8K AR events for buffer size */
298#define DFS_AR_ARQ_SEQSIZE 2049 /* Sequence counter wrap for AR */
299
300#define DFS_RADARQ_SIZE 512 /* 1K radar events for buffer size */
301#define DFS_RADARQ_SEQSIZE 513 /* Sequence counter wrap for radar */
302/* Number of radar channels we keep state for */
303#define DFS_NUM_RADAR_STATES 64
304/* Max number radar filters for each type */
305#define DFS_MAX_NUM_RADAR_FILTERS 10
306/* Number of different radar types */
307#define DFS_MAX_RADAR_TYPES 32
308
309struct dfs_ar_state {
310 uint32_t ar_prevwidth;
311 uint32_t ar_phyerrcount[DFS_AR_MAX_ACK_RADAR_DUR];
312 uint32_t ar_acksum;
313 uint32_t ar_packetthreshold; /* Thresh to determine traffic load */
314 uint32_t ar_parthreshold; /* Thresh to determine peak */
315 uint32_t ar_radarrssi; /* Rssi threshold for AR event */
316 uint16_t ar_prevtimestamp;
317 uint16_t ar_peaklist[DFS_AR_MAX_NUM_PEAKS];
318};
319
320#ifdef WIN32
321#pragma pack(push, dfs_delayelem, 1)
322#endif
323struct dfs_delayelem {
324 /* Current "filter" time for start of pulse in usecs */
325 uint32_t de_time;
326 /* Duration of pulse in usecs */
327 uint8_t de_dur;
328 /* rssi of pulse in dB */
329 uint8_t de_rssi;
330 /* time stamp for this delay element */
331 uint64_t de_ts;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530332} qdf_packed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800333#ifdef WIN32
334#pragma pack(pop, dfs_delayelem)
335#endif
336
337/* NB: The first element in the circular buffer is the oldest element */
338
339#ifdef WIN32
340#pragma pack(push, dfs_delayline, 1)
341#endif
342struct dfs_delayline {
343 /* Array of pulses in delay line */
344 struct dfs_delayelem dl_elems[DFS_MAX_DL_SIZE];
345 /* Last timestamp the delay line was used (in usecs) */
346 uint64_t dl_last_ts;
347 /* Index of the first element */
348 uint32_t dl_firstelem;
349 /* Index of the last element */
350 uint32_t dl_lastelem;
351 /* Number of elements in the delay line */
352 uint32_t dl_numelems;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530353} qdf_packed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800354#ifdef WIN32
355#pragma pack(pop, dfs_delayline)
356#endif
357
358#ifdef WIN32
359#pragma pack(push, dfs_filter, 1)
360#endif
361struct dfs_filter {
362 /* Delay line of pulses for this filter */
363 struct dfs_delayline rf_dl;
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800364 /* Delay line of pulses for this filter in 80p80 */
365 struct dfs_delayline rf_dl_ext_seg;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800366 /* Number of pulses in the filter */
367 uint32_t rf_numpulses;
368 /* min pri to be considered for this filter */
369 uint32_t rf_minpri;
370 /* max pri to be considered for this filter */
371 uint32_t rf_maxpri;
372 /* match filter output threshold for radar detect */
373 uint32_t rf_threshold;
374 /* Length (in usecs) of the filter */
375 uint32_t rf_filterlen;
376 /* fixed or variable pattern type */
377 uint32_t rf_patterntype;
378 /* indicates if it is a fixed pri pulse */
379 uint32_t rf_fixed_pri_radar_pulse;
380 /* Min duration for this radar filter */
381 uint32_t rf_mindur;
382 /* Max duration for this radar filter */
383 uint32_t rf_maxdur;
384 uint32_t rf_ignore_pri_window;
385 /* Unique ID corresponding to the original filter ID */
386 uint32_t rf_pulseid;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530387} qdf_packed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388#ifdef WIN32
389#pragma pack(pop, dfs_filter)
390#endif
391
392struct dfs_filtertype {
393 struct dfs_filter ft_filters[DFS_MAX_NUM_RADAR_FILTERS];
394 /* Duration of pulse which specifies filter type */
395 uint32_t ft_filterdur;
396 /* Num filters of this type */
397 uint32_t ft_numfilters;
398 /* Last timestamp this filtertype was used(in usecs) */
399 uint64_t ft_last_ts;
400 /* min pulse duration to be considered for this filter type */
401 uint32_t ft_mindur;
402 /* max pulse duration to be considered for this filter type */
403 uint32_t ft_maxdur;
404 /* min rssi to be considered for this filter type */
405 uint32_t ft_rssithresh;
406 /* Num pulses in each filter of this type */
407 uint32_t ft_numpulses;
408 /* fixed or variable pattern type */
409 uint32_t ft_patterntype;
410 /* min pri to be considered for this type */
411 uint32_t ft_minpri;
412 /* rssi threshold margin. In Turbo Mode HW
413 * reports rssi 3dB lower than in non TURBO
414 * mode. This will offset that diff.
415 */
416 uint32_t ft_rssimargin;
417};
418
419struct dfs_state {
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +0530420 struct dfs_ieee80211_channel rs_chan; /* Channel info */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800421 uint8_t rs_chanindex; /* Channel index in radar structure */
422 uint32_t rs_numradarevents; /* Number of radar events */
423
424 struct ath_dfs_phyerr_param rs_param;
425};
426
427/* 30 minutes in seconds */
428#define DFS_NOL_TIMEOUT_S (30*60)
429/* 5 minutes in seconds - debugging */
430/* #define DFS_NOL_TIMEOUT_S (5*60) */
431#define DFS_NOL_TIMEOUT_MS (DFS_NOL_TIMEOUT_S * 1000)
432#define DFS_NOL_TIMEOUT_US (DFS_NOL_TIMEOUT_MS * 1000)
433
434#ifdef WIN32
435#pragma pack(push, dfs_nolelem, 1)
436#endif
437struct dfs_nolelem {
438 uint32_t nol_freq; /* centre frequency */
439 uint32_t nol_chwidth; /* event width (MHz) */
440 unsigned long nol_start_ticks; /* NOL start time in OS ticks */
441 uint32_t nol_timeout_ms; /* NOL timeout value in msec */
442 os_timer_t nol_timer; /* per element NOL timer */
443 struct dfs_nolelem *nol_next; /* next element pointer */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530444} qdf_packed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800445#ifdef WIN32
446#pragma pack(pop, dfs_nolelem)
447#endif
448
449/* Pass structure to DFS NOL timer */
450struct dfs_nol_timer_arg {
451 struct ath_dfs *dfs;
452 uint16_t delfreq;
453 uint16_t delchwidth;
454};
455
456#ifdef WIN32
457#pragma pack(push, dfs_info, 1)
458#endif
459struct dfs_info {
460 /* Use the NOL when radar found (default: true) */
461 int rn_use_nol;
462 /* Number of different types of radars */
463 uint32_t rn_numradars;
464 /* Last 64 bit timstamp from recv interrupt */
465 uint64_t rn_lastfull_ts;
466 /* last 15 bit ts from recv descriptor */
467 uint16_t rn_last_ts;
468 /* last unique 32 bit ts from recv descriptor */
469 uint32_t rn_last_unique_ts;
470 /* Prefix to prepend to 15 bit recv ts */
471 uint64_t rn_ts_prefix;
472 /* Number of bin5 radar pulses to search for */
473 uint32_t rn_numbin5radars;
474 /* Value of fast diversity gc limit from init file */
475 uint32_t rn_fastdivGCval;
476 /* Min rssi for all radar types */
477 int32_t rn_minrssithresh;
478 /* Max pulse width in TSF ticks */
479 uint32_t rn_maxpulsedur;
480
481 uint8_t dfs_ext_chan_busy;
482 uint64_t ext_chan_busy_ts;
483
484 uint64_t dfs_bin5_chirp_ts;
485 uint8_t dfs_last_bin5_dur;
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800486 uint8_t dfs_last_bin5_dur_ext_seg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530487} qdf_packed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800488#ifdef WIN32
489#pragma pack(pop, dfs_info)
490#endif
491
492struct dfs_bin5elem {
493 uint64_t be_ts; /* Timestamp for the bin5 element */
494 uint32_t be_rssi; /* Rssi for the bin5 element */
495 uint32_t be_dur; /* Duration of bin5 element */
496};
497
498struct dfs_bin5radars {
499 /* List of bin5 elems that fall within the time window */
500 struct dfs_bin5elem br_elems[DFS_MAX_B5_SIZE];
501 /* Index of the first element */
502 uint32_t br_firstelem;
503 /* Index of the last element */
504 uint32_t br_lastelem;
505 /* Number of elements in the delay line */
506 uint32_t br_numelems;
507 /* Original info about bin5 pulse */
508 struct dfs_bin5pulse br_pulse;
509};
510
511struct dfs_stats {
512 uint32_t num_radar_detects; /* total num. of radar detects */
513 uint32_t total_phy_errors;
514 uint32_t owl_phy_errors;
515 uint32_t pri_phy_errors;
516 uint32_t ext_phy_errors;
517 uint32_t dc_phy_errors;
518 uint32_t early_ext_phy_errors;
519 uint32_t bwinfo_errors;
520 uint32_t datalen_discards;
521 uint32_t rssi_discards;
522 uint64_t last_reset_tstamp;
523};
524
525/*
526 * This is for debuggin DFS as console log interferes with (helps)
527 * radar detection
528 */
529
530#define DFS_EVENT_LOG_SIZE 256
531struct dfs_event_log {
532 uint64_t ts; /* 64-bit full timestamp from interrupt time */
533 uint32_t diff_ts; /* diff timestamp */
534 uint8_t rssi; /* rssi of radar event */
535 uint8_t dur; /* duration of radar pulse */
536};
537
538#define ATH_DFS_RESET_TIME_S 7
539#define ATH_DFS_WAIT (60 + ATH_DFS_RESET_TIME_S) /* 60 seconds */
540#define ATH_DFS_WAIT_MS ((ATH_DFS_WAIT) * 1000) /*in MS */
541
542#define ATH_DFS_WEATHER_CHANNEL_WAIT_MIN 10 /*10 minutes */
543#define ATH_DFS_WEATHER_CHANNEL_WAIT_S (ATH_DFS_WEATHER_CHANNEL_WAIT_MIN * 60)
544#define ATH_DFS_WEATHER_CHANNEL_WAIT_MS \
545 ((ATH_DFS_WEATHER_CHANNEL_WAIT_S) * 1000) /*in MS */
546
547#define ATH_DFS_WAIT_POLL_PERIOD 2 /* 2 seconds */
548/*in MS */
549#define ATH_DFS_WAIT_POLL_PERIOD_MS ((ATH_DFS_WAIT_POLL_PERIOD) * 1000)
550#define ATH_DFS_TEST_RETURN_PERIOD 2 /* 2 seconds */
551/* n MS */
552#define ATH_DFS_TEST_RETURN_PERIOD_MS ((ATH_DFS_TEST_RETURN_PERIOD) * 1000)
553#define IS_CHANNEL_WEATHER_RADAR(chan) ((chan->ic_freq >= 5600) && \
554 (chan->ic_freq <= 5650))
555
556#define DFS_DEBUG_TIMEOUT_S 30 /* debug timeout is 30 seconds */
557#define DFS_DEBUG_TIMEOUT_MS (DFS_DEBUG_TIMEOUT_S * 1000)
558
559#define RSSI_POSSIBLY_FALSE 50
560#define SEARCH_FFT_REPORT_PEAK_MAG_THRSH 40
561
562struct ath_dfs {
563 uint32_t dfs_debug_mask; /* current debug bitmask */
564 int16_t dfs_curchan_radindex; /* cur. channel radar index */
565 int16_t dfs_extchan_radindex; /* extension channel radar index */
566 uint32_t dfsdomain; /* cur. DFS domain */
567 uint32_t dfs_proc_phyerr; /* Flags for Phy Errs to process */
568 struct ieee80211com *ic;
569 STAILQ_HEAD(, dfs_event) dfs_eventq; /* Q of free dfs event objects */
570 dfsq_lock_t dfs_eventqlock; /* Lock for free dfs event list */
571 STAILQ_HEAD(, dfs_event) dfs_radarq; /* Q of radar events */
572 dfsq_lock_t dfs_radarqlock; /* Lock for dfs q */
573 STAILQ_HEAD(, dfs_event) dfs_arq; /* Q of AR events */
574 dfsq_lock_t dfs_arqlock; /* Lock for AR q */
575
576 struct dfs_ar_state dfs_ar_state; /* AR state */
577
578 /* dfs_radar - Per-Channel Radar detector state */
579 struct dfs_state dfs_radar[DFS_NUM_RADAR_STATES];
580
581 /* dfs_radarf - One filter for each radar pulse type */
582 struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES];
583
584 struct dfs_info dfs_rinfo; /* State vars for radar processing */
585 struct dfs_bin5radars *dfs_b5radars; /* array of bin5 radar events */
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800586 /* array of bin5 radar events on extension segment in 80p80 */
587 struct dfs_bin5radars *dfs_b5radars_ext_seg;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800588 int8_t **dfs_radartable; /* map of radar durs to filter types */
589#ifndef ATH_DFS_RADAR_DETECTION_ONLY
590 struct dfs_nolelem *dfs_nol; /* Non occupancy list for radar */
591 int dfs_nol_count; /* How many items? */
592#endif
593 /* Default phy params per radar state */
594 struct ath_dfs_phyerr_param dfs_defaultparams;
595 struct dfs_stats ath_dfs_stats; /* DFS related stats */
596 struct dfs_pulseline *pulses; /* pulse history */
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800597 struct dfs_pulseline *pulses_ext_seg; /* pulse history ext 80p80 seg */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598 struct dfs_event *events; /* Events structure */
599
600 uint32_t ath_radar_tasksched:1, /* radar task is scheduled */
601 ath_dfswait:1, /* waiting on channel for radar detect */
602 ath_dfstest:1; /* Test timer in progress */
603 struct ath_dfs_caps dfs_caps;
604 /* IEEE chan num to return to after
605 * a dfs mute test
606 */
607 uint8_t ath_dfstest_ieeechan;
608#ifndef ATH_DFS_RADAR_DETECTION_ONLY
609 uint32_t ath_dfs_cac_time; /* CAC period */
610 uint32_t ath_dfstesttime; /* Time to stay off chan during dfs test */
611 os_timer_t ath_dfswaittimer; /* dfs wait timer */
612 os_timer_t ath_dfstesttimer; /* dfs mute test timer */
613 os_timer_t ath_dfs_debug_timer; /* dfs debug timer */
614 uint8_t dfs_bangradar;
615#endif
616 os_timer_t ath_dfs_task_timer; /* dfs wait timer */
617 int dur_multiplier;
618
619 uint16_t ath_dfs_isdfsregdomain; /* true when we are DFS domain */
620 int ath_dfs_false_rssi_thres;
621 int ath_dfs_peak_mag;
622
623 struct dfs_event_log radar_log[DFS_EVENT_LOG_SIZE];
624 int dfs_event_log_count;
625 int dfs_event_log_on;
626 int dfs_phyerr_count; /* same as number of PHY radar interrupts */
627 /*
628 * when TLV is supported, # of radar events ignored after TLV is parsed
629 */
630 int dfs_phyerr_reject_count;
631 /* number of radar events queued for matching the filters */
632 int dfs_phyerr_queued_count;
633 int dfs_phyerr_freq_min;
634 int dfs_phyerr_freq_max;
635 int dfs_phyerr_w53_counter;
636 /* allow pulse if they are within multiple of PRI for the radar type */
637 int dfs_pri_multiplier;
638 int ath_dfs_nol_timeout;
639 int dfs_pri_multiplier_ini; /* dfs pri configuration from ini */
640 /*
641 * Flag to indicate if DFS test mode is enabled and
642 * channel switch is disabled.
643 */
644 int8_t disable_dfs_ch_switch;
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800645 uint32_t test_ts; /* to capture timestamps on primary segment */
646 uint32_t test_ts_ext_seg; /* to capture timestamps on ext segment */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800647};
648
649/* This should match the table from if_ath.c */
650enum {
651 ATH_DEBUG_DFS = 0x00000100, /* Minimal DFS debug */
652 ATH_DEBUG_DFS1 = 0x00000200, /* Normal DFS debug */
653 ATH_DEBUG_DFS2 = 0x00000400, /* Maximal DFS debug */
654 ATH_DEBUG_DFS3 = 0x00000800, /* matched filterID display */
655
656 ATH_DEBUG_DFS_PHYERR = 0x00001000, /* phy error parsing */
657 ATH_DEBUG_DFS_NOL = 0x00002000, /* NOL related entries */
658 ATH_DEBUG_DFS_PHYERR_SUM = 0x00004000, /* PHY error summary */
659 ATH_DEBUG_DFS_PHYERR_PKT = 0x00008000, /* PHY error payload */
660
661 ATH_DEBUG_DFS_BIN5 = 0x00010000, /* bin5 checks */
662 ATH_DEBUG_DFS_BIN5_FFT = 0x00020000, /* bin5 FFT check */
663 ATH_DEBUG_DFS_BIN5_PULSE = 0x00040000, /* bin5 pulse check */
664};
665
666#define IS_CHAN_HT40(_c) IEEE80211_IS_CHAN_11N_HT40(_c)
667#define IS_CHAN_HT40_PLUS(_c) IEEE80211_IS_CHAN_11N_HT40PLUS(_c)
668#define IS_CHAN_HT40_MINUS(_c) IEEE80211_IS_CHAN_11N_HT40MINUS(_c)
669
670/*
671 * chirp notes!
672 *
673 * Pre-Sowl chips don't do FFT reports, so chirp pulses simply show up
674 * as long duration pulses.
675 *
676 * The bin5 checking code would simply look for a chirp pulse of the correct
677 * duration (within MIN_BIN5_DUR and MAX_BIN5_DUR) and add it to the "chirp"
678 * pattern.
679 *
680 * For Sowl and later, an FFT was done on longer duration frames. If those
681 * frames looked like a chirp, their duration was adjusted to fall within
682 * the chirp duration limits. If the pulse failed the chirp test (it had
683 * no FFT data or the FFT didn't meet the chirping requirements) then the
684 * pulse duration was adjusted to be greater than MAX_BIN5_DUR, so it
685 * would always fail chirp detection.
686 *
687 * This is pretty horrible.
688 *
689 * The eventual goal for chirp handling is thus:
690 *
691 * + In case someone ever wants to do chirp detection with this code on
692 * chips that don't support chirp detection, you can still do it based
693 * on pulse duration. That's your problem to solve.
694 *
695 * + For chips that do hardware chirp detection or FFT, the "do_check_chirp"
696 * bit should be set.
697 *
698 * + Then, either is_hw_chirp or is_sw_chirp is set, indicating that
699 * the hardware or software post-processing of the chirp event found
700 * that indeed it was a chirp.
701 *
702 * + Finally, the bin5 code should just check whether the chirp bits are
703 * set and behave appropriately, falling back onto the duration checks
704 * if someone wishes to use this on older hardware (or with disabled
705 * FFTs, for whatever reason.)
706 */
707/*
708 * XXX TODO:
709 *
710 * + add duration in uS and raw duration, so the PHY error parsing
711 * code is responsible for doing the duration calculation;
712 * + add ts in raw and corrected, so the PHY error parsing
713 * code is responsible for doing the offsetting, not the radar
714 * event code.
715 */
716struct dfs_phy_err {
717 uint64_t fulltsf; /* 64-bit TSF as read from MAC */
718
719 uint32_t is_pri:1, /* detected on primary channel */
720 is_ext:1, /* detected on extension channel */
721 is_dc:1, /* detected at DC */
722 is_early:1, /* early detect */
723 do_check_chirp:1, /* whether to check hw_chirp/sw_chirp */
724 is_hw_chirp:1, /* hardware-detected chirp */
725 is_sw_chirp:1; /* software detected chirp */
726
727 uint32_t rs_tstamp; /* 32 bit TSF from RX descriptor (event) */
728 uint32_t freq; /* Centre frequency of event - KHz */
729 uint32_t freq_lo; /* Lower bounds of frequency - KHz */
730 uint32_t freq_hi; /* Upper bounds of frequency - KHz */
731
732 uint8_t rssi; /* pulse RSSI */
733 uint8_t dur; /* pulse duration, raw (not uS) */
734 int sidx; /* Pulse Index as in radar summary report */
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800735 /*
736 * Indicates segment ID on which the phyerror is received
737 * when SAP is operating in 80p80 channel width.
738 */
739 int radar_80p80_segid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800740};
741
742/* Attach, detach, handle ioctl prototypes */
743
744int dfs_get_thresholds(struct ieee80211com *ic,
745 struct ath_dfs_phyerr_param *param);
746int dfs_set_thresholds(struct ieee80211com *ic,
747 const uint32_t threshtype, const uint32_t value);
748
749/* PHY error and radar event handling */
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +0530750int dfs_process_radarevent(struct ath_dfs *dfs,
751 struct dfs_ieee80211_channel *chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800752
753/* Non occupancy (NOL) handling prototypes */
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +0530754void dfs_nol_addchan(struct ath_dfs *dfs, struct dfs_ieee80211_channel *chan,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755 uint32_t dfs_nol_timeout);
756void dfs_get_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol,
757 int *nchan);
758void dfs_set_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol,
759 int nchan);
760void dfs_nol_update(struct ath_dfs *dfs);
761void dfs_nol_timer_cleanup(struct ath_dfs *dfs);
762
763/* FCC Bin5 detection prototypes */
764int dfs_bin5_check_pulse(struct ath_dfs *dfs, struct dfs_event *re,
765 struct dfs_bin5radars *br);
766int dfs_bin5_addpulse(struct ath_dfs *dfs, struct dfs_bin5radars *br,
767 struct dfs_event *re, uint64_t thists);
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800768int dfs_bin5_check(struct ath_dfs *dfs, int seg_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769int dfs_check_chirping(struct ath_dfs *dfs, void *buf,
770 uint16_t datalen, int is_ctl,
771 int is_ext, int *slope, int *is_dc);
772uint8_t dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, uint32_t diff_ts,
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800773 uint8_t old_dur, int seg_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774uint8_t dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, uint32_t diff_ts,
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800775 uint8_t old_dur, int seg_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800776int dfs_get_random_bin5_dur(struct ath_dfs *dfs, uint64_t tstamp);
777
778/* Debug prototypes */
779void dfs_print_delayline(struct ath_dfs *dfs, struct dfs_delayline *dl);
780void dfs_print_nol(struct ath_dfs *dfs);
781void dfs_print_filters(struct ath_dfs *dfs);
782void dfs_print_activity(struct ath_dfs *dfs);
783os_timer_func(dfs_debug_timeout);
784void dfs_print_filter(struct ath_dfs *dfs, struct dfs_filter *rf);
785
786/* Misc prototypes */
787uint32_t dfs_round(int32_t val);
788struct dfs_state *dfs_getchanstate(struct ath_dfs *dfs, uint8_t *index,
789 int ext_ch_flag);
790
791/* Reset and init data structures */
792
793int dfs_init_radar_filters(struct ieee80211com *ic,
794 struct ath_dfs_radar_tab_info *radar_info);
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800795void dfs_reset_alldelaylines(struct ath_dfs *dfs, int seg_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800796void dfs_reset_delayline(struct dfs_delayline *dl);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800797void dfs_reset_radarq(struct ath_dfs *dfs);
798
799/* Detection algorithm prototypes */
800void dfs_add_pulse(struct ath_dfs *dfs, struct dfs_filter *rf,
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800801 struct dfs_event *re, uint32_t deltaT, uint64_t this_ts,
802 int seg_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803
804int dfs_bin_fixedpattern_check(struct ath_dfs *dfs, struct dfs_filter *rf,
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800805 uint32_t dur, int ext_chan_flag, int seg_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800806int dfs_bin_check(struct ath_dfs *dfs, struct dfs_filter *rf,
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800807 uint32_t deltaT, uint32_t dur, int ext_chan_flag, int seg_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808
809int dfs_bin_pri_check(struct ath_dfs *dfs, struct dfs_filter *rf,
810 struct dfs_delayline *dl, uint32_t score,
811 uint32_t refpri, uint32_t refdur, int ext_chan_flag,
812 int fundamentalpri);
813int dfs_staggered_check(struct ath_dfs *dfs, struct dfs_filter *rf,
Rakesh Sunkif7f82e52015-12-14 15:09:40 -0800814 uint32_t deltaT, uint32_t width, int seg_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800815/* False detection reduction */
816int dfs_get_pri_margin(struct ath_dfs *dfs, int is_extchan_detect,
817 int is_fixed_pattern);
818int dfs_get_filter_threshold(struct ath_dfs *dfs, struct dfs_filter *rf,
819 int is_extchan_detect);
820
821/* AR related prototypes */
822
823/* Commenting out since all the ar functions are obsolete and
824 * the function definition has been removed as part of dfs_ar.c
825 * void dfs_process_ar_event(struct ath_dfs *dfs,
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +0530826 * struct dfs_ieee80211_channel *chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800827 */
828/* Commenting out since all the ar functions are obsolete and
829 * the function definition has been removed as part of dfs_ar.c
830 * void ath_ar_disable(struct ath_dfs *dfs);
831 */
832/* Commenting out since all the ar functions are obsolete and
833 * the function definition has been removed as part of dfs_ar.c
834 * void ath_ar_enable(struct ath_dfs *dfs);
835 */
836void dfs_reset_ar(struct ath_dfs *dfs);
837/* Commenting out since all the ar functions are obsolete and
838 * the function definition has been removed as part of dfs_ar.c
839 * void dfs_reset_arq(struct ath_dfs *dfs);
840 */
841
Chandrasekaran, Manishekar22a7e1e2015-11-05 10:38:49 +0530842struct dfs_ieee80211_channel *ieee80211_get_extchan(struct ieee80211com *ic);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800843
844#endif /* _DFS_H_ */