/* * Copyright (c) 2013, 2016-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2005-2006 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /** * DOC: This file has main dfs structures. */ #ifndef _DFS_H_ #define _DFS_H_ #include /* QDF_NBUF_EXEMPT_NO_EXEMPTION, etc. */ #include /* QDF_NBUF_EXEMPT_NO_EXEMPTION, etc. */ #include /* qdf_nbuf_t, etc. */ #include /* qdf_assert */ #include /* qdf_spinlock */ #include #include #include #include "dfs_structs.h" #include "dfs_channel.h" #include "dfs_ioctl_private.h" #include /* For qdf_packed*/ #include /* For STAILQ_ENTRY */ #include #include #include /* File Line and Submodule String */ #define FLSM(x, str) #str " : " FL(x) /* Cast to dfs type */ #define DC(x) ((struct wlan_dfs *)(x)) /** * dfs_log: dfs logging using submodule MASKs and * QDF trace level. * The logging is controlled by two bitmasks: * 1) submodule bitmask: sm * 2) trace level masks: level * * @dfs: The dfs object pointer or NULL if dfs is not defined. * @sm: Submodule BITMASK. * @level: QDF trace level. * @args...: Variable argument list. * * The submodule(sm) cannot be empty even if argument dfs is NULL. * Else the macro will create a compilation error. * One may provide WLAN_DEBUG_DFS_ALWAYS when the argument dfs is NULL. * Example:- * dfs_log(NULL, WLAN_DEBUG_DFS_ALWAYS, QDF_TRACE_LEVEL_INFO,"Error pulse"); * * Why DC(x) is required? * Since NULL is defined as ((void *)(0)), if the argument "dfs" * in a call to the macro "dfs_log" is NULL * then during compilation (NULL)->dfs_debug_mask will dereference * a (void *) type, which is illegal. Therefore, we need * the cast: (DC(dfs))->dfs_debug_mask. * Example:- * dfs_log(NULL, WLAN_DEBUG_DFS, QDF_TRACE_LEVEL_INFO,"dfs is NULL"); */ #define dfs_log(dfs, sm, level, args...) do { \ if (((dfs) == NULL) || \ ((sm) == WLAN_DEBUG_DFS_ALWAYS) || \ ((sm) & ((DC(dfs))->dfs_debug_mask))) { \ QDF_TRACE(QDF_MODULE_ID_DFS, level, ## args); \ } \ } while (0) #define dfs_logfl(dfs, level, sm, format, args...) \ dfs_log(dfs, sm, level, FLSM(format, sm), ## args) #define dfs_alert(dfs, sm, format, args...) \ dfs_logfl(dfs, QDF_TRACE_LEVEL_FATAL, sm, format, ## args) #define dfs_err(dfs, sm, format, args...) \ dfs_logfl(dfs, QDF_TRACE_LEVEL_ERROR, sm, format, ## args) #define dfs_warn(dfs, sm, format, args...) \ dfs_logfl(dfs, QDF_TRACE_LEVEL_WARN, sm, format, ## args) #define dfs_info(dfs, sm, format, args...) \ dfs_logfl(dfs, QDF_TRACE_LEVEL_INFO, sm, format, ## args) #define dfs_debug(dfs, sm, format, args...) \ dfs_logfl(dfs, QDF_TRACE_LEVEL_DEBUG, sm, format, ## args) #define DFS_MIN(a, b) ((a) < (b)?(a):(b)) #define DFS_MAX(a, b) ((a) > (b)?(a) : (b)) #define DFS_DIFF(a, b)(DFS_MAX(a, b) - DFS_MIN(a, b)) /** * Maximum number of radar events to be processed in a single iteration. * Allows soft watchdog to run. */ #define MAX_EVENTS 100 /** * Constants to use for chirping detection. * * All are unconverted as HW reports them. * * XXX Are these constants with or without fast clock 5GHz operation? * 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 * of duration that is well below 50us for a valid FCC type 5 chirping * pulse. For now changing minimum duration as a work around. This will * affect all chips but since we detect chirp with Merlin+, we may be OK * for now. We need a more robust solution for this. */ #define MIN_BIN5_DUR_CAS 25 /* 50 * 1.25*/ #define MIN_BIN5_DUR_MICROSEC_CAS 20 #define MIN_BIN5_DUR 63 /* 50 * 1.25*/ #define MIN_BIN5_DUR_MICROSEC 50 #define MAYBE_BIN5_DUR 35 /* 28 * 1.25*/ #define MAYBE_BIN5_DUR_MICROSEC 28 /* Conversion is already done using dfs->dur_multiplier */ #define MAX_BIN5_DUR 145 /* use 145 for osprey */ #define MAX_BIN5_DUR_MICROSEC 105 #define DFS_MARGIN_EQUAL(a, b, margin) ((DFS_DIFF(a, b)) <= margin) #define DFS_MAX_STAGGERED_BURSTS 3 /** * All filter thresholds in the radar filter tables are effective at a 50% * channel loading. */ #define DFS_CHAN_LOADING_THRESH 50 #define DFS_EXT_CHAN_LOADING_THRESH 30 #define DFS_DEFAULT_PRI_MARGIN 6 #define DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN 4 #define WLAN_DFSQ_LOCK(_dfs) qdf_spin_lock(&(_dfs)->dfs_radarqlock) #define WLAN_DFSQ_UNLOCK(_dfs) qdf_spin_unlock(&(_dfs)->dfs_radarqlock) #define WLAN_DFSQ_LOCK_CREATE(_dfs) qdf_spinlock_create( \ &(_dfs)->dfs_radarqlock) #define WLAN_DFSQ_LOCK_DESTROY(_dfs) qdf_spinlock_destroy( \ &(_dfs)->dfs_radarqlock) #define WLAN_ARQ_LOCK(_dfs) qdf_spin_lock(&(_dfs)->dfs_arqlock) #define WLAN_ARQ_UNLOCK(_dfs) qdf_spin_unlock(&(_dfs)->dfs_arqlock) #define WLAN_ARQ_LOCK_CREATE(_dfs) qdf_spinlock_create(&(_dfs)->dfs_arqlock) #define WLAN_ARQ_LOCK_DESTROY(_dfs) qdf_spinlock_destroy(&(_dfs)->dfs_arqlock) #define WLAN_DFSEVENTQ_LOCK(_dfs) qdf_spin_lock(&(_dfs)->dfs_eventqlock) #define WLAN_DFSEVENTQ_UNLOCK(_dfs) qdf_spin_unlock( \ &(_dfs)->dfs_eventqlock) #define WLAN_DFSEVENTQ_LOCK_CREATE(_dfs) qdf_spinlock_create( \ &(_dfs)->dfs_eventqlock) #define WLAN_DFSEVENTQ_LOCK_DESTROY(_dfs) qdf_spinlock_destroy( \ &(_dfs)->dfs_eventqlock) #define WLAN_DFSNOL_LOCK(_dfs) qdf_spin_lock_bh(&(_dfs)->dfs_nol_lock) #define WLAN_DFSNOL_UNLOCK(_dfs) qdf_spin_unlock_bh(&(_dfs)->dfs_nol_lock) #define WLAN_DFSNOL_LOCK_CREATE(_dfs) qdf_spinlock_create( \ &(_dfs)->dfs_nol_lock) #define WLAN_DFSNOL_LOCK_DESTROY(_dfs) qdf_spinlock_destroy( \ &(_dfs)->dfs_nol_lock) #define PRECAC_LIST_LOCK(_dfs) qdf_spin_lock_irqsave( \ &(_dfs)->dfs_precac_lock) #define PRECAC_LIST_UNLOCK(_dfs) qdf_spin_unlock_irqrestore( \ &(_dfs)->dfs_precac_lock) #define PRECAC_LIST_LOCK_CREATE(_dfs) qdf_spinlock_create( \ &(_dfs)->dfs_precac_lock) #define PRECAC_LIST_LOCK_DESTROY(_dfs) qdf_spinlock_destroy( \ &(_dfs)->dfs_precac_lock) /* Mask for time stamp from descriptor */ #define DFS_TSMASK 0xFFFFFFFF /* Shift for time stamp from descriptor */ #define DFS_TSSHIFT 32 /* 64 bit TSF wrap value */ #define DFS_TSF_WRAP 0xFFFFFFFFFFFFFFFFULL /* TS mask for 64 bit value */ #define DFS_64BIT_TSFMASK 0x0000000000007FFFULL #define DFS_AR_RADAR_RSSI_THR 5 /* in dB */ #define DFS_AR_RADAR_RESET_INT 1 /* in secs */ #define DFS_AR_RADAR_MAX_HISTORY 500 #define DFS_AR_REGION_WIDTH 128 #define DFS_AR_RSSI_THRESH_STRONG_PKTS 17 /* in dB */ #define DFS_AR_RSSI_DOUBLE_THRESHOLD 15 /* in dB */ #define DFS_AR_MAX_NUM_ACK_REGIONS 9 #define DFS_AR_ACK_DETECT_PAR_THRESH 20 #define DFS_AR_PKT_COUNT_THRESH 20 #define DFS_MAX_DL_SIZE 64 #define DFS_MAX_DL_MASK 0x3F #define DFS_NOL_TIME DFS_NOL_TIMEOUT_US /* 30 minutes in usecs */ #define DFS_WAIT_TIME (60*1000000) /* 1 minute in usecs */ #define DFS_DISABLE_TIME (3*60*1000000) /* 3 minutes in usecs */ #define DFS_MAX_B5_SIZE 128 #define DFS_MAX_B5_MASK 0x0000007F /* 128 */ /* Max number of overlapping filters */ #define DFS_MAX_RADAR_OVERLAP 16 /* Max number of dfs events which can be q'd */ #define DFS_MAX_EVENTS 1024 #define DFS_RADAR_EN 0x80000000 /* Radar detect is capable */ #define DFS_AR_EN 0x40000000 /* AR detect is capable */ /* Radar detect in second segment is capable */ #define DFS_SECOND_SEGMENT_RADAR_EN 0x20000000 #define DFS_MAX_RSSI_VALUE 0x7fffffff /* Max rssi value */ #define DFS_BIN_MAX_PULSES 60 /* max num of pulses in a burst */ #define DFS_BIN5_PRI_LOWER_LIMIT 990 /* us */ /** * To cover the single pusle burst case, change from 2010 us to * 2010000 us. */ /** * This is reverted back to 2010 as larger value causes false * bin5 detect (EV76432, EV76320) */ #define DFS_BIN5_PRI_HIGHER_LIMIT 2010 /* us */ #define DFS_BIN5_WIDTH_MARGIN 4 /* us */ #define DFS_BIN5_RSSI_MARGIN 5 /* dBm */ /** * Following threshold is not specified but should be * okay statistically. */ #define DFS_BIN5_BRI_LOWER_LIMIT 300000 /* us */ #define DFS_BIN5_BRI_UPPER_LIMIT 12000000 /* us */ /* Max number of pulses kept in buffer */ #define DFS_MAX_PULSE_BUFFER_SIZE 1024 #define DFS_MAX_PULSE_BUFFER_MASK 0x3ff #define DFS_FAST_CLOCK_MULTIPLIER (800/11) #define DFS_NO_FAST_CLOCK_MULTIPLIER (80) #define DFS_BIG_SIDX 10000 /** * Software use: channel interference used for as AR as well as RADAR * interference detection. */ #define CHANNEL_INTERFERENCE 0x01 #define CHANNEL_2GHZ 0x00080 /* 2 GHz spectrum channel. */ #define CHANNEL_OFDM 0x00040 /* OFDM channel */ #define CHANNEL_TURBO 0x00010 /* Turbo Channel */ #define CHANNEL_108G (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO) /* qdf_packed - denotes structure is packed. */ #define qdf_packed __qdf_packed #define SEG_ID_PRIMARY 0 #define SEG_ID_SECONDARY 1 /* MIN and MAX width for different regions */ #define REG0_MIN_WIDTH 33 #define REG0_MAX_WIDTH 38 #define REG1_MIN_WIDTH 39 #define REG1_MAX_WIDTH 44 #define REG2_MIN_WIDTH 53 #define REG2_MAX_WIDTH 58 #define REG3_MIN_WIDTH 126 #define REG3_MAX_WIDTH 140 #define REG4_MIN_WIDTH 141 #define REG4_MAX_WIDTH 160 #define REG5_MIN_WIDTH 189 #define REG5_MAX_WIDTH 210 #define REG6_MIN_WIDTH 360 #define REG6_MAX_WIDTH 380 #define REG7_MIN_WIDTH 257 #define REG7_MAX_WIDTH 270 #define REG8_MIN_WIDTH 295 #define REG8_MAX_WIDTH 302 #define OVER_SAMPLING_FREQ 44000 #define SAMPLING_FREQ 40000 #define HUNDRED 100 #define NUM_BINS 128 #define THOUSAND 1000 /* Check if the dfs current channel is 5.8GHz */ #define DFS_CURCHAN_IS_58GHz(freq) \ ((((freq) >= 5745) && ((freq) <= 5865)) ? true : false) /* ETSI11_WORLD regdmn pair id */ #define ETSI11_WORLD_REGDMN_PAIR_ID 0x26 /* Array offset to ETSI legacy pulse */ #define ETSI_LEGACY_PULSE_ARR_OFFSET 2 #define DFS_NOL_ADD_CHAN_LOCKED(dfs, freq, timeout) \ do { \ WLAN_DFSNOL_LOCK(dfs); \ dfs_nol_addchan(dfs, freq, timeout); \ WLAN_DFSNOL_UNLOCK(dfs); \ } while (0) #define DFS_NOL_DELETE_CHAN_LOCKED(dfs, freq, chwidth) \ do { \ WLAN_DFSNOL_LOCK(dfs); \ dfs_nol_delete(dfs, freq, chwidth); \ WLAN_DFSNOL_UNLOCK(dfs); \ } while (0) #define DFS_GET_NOL_LOCKED(dfs, dfs_nol, nchan) \ do { \ WLAN_DFSNOL_LOCK(dfs); \ dfs_get_nol(dfs, dfs_nol, nchan); \ WLAN_DFSNOL_UNLOCK(dfs); \ } while (0) #define DFS_PRINT_NOL_LOCKED(dfs) \ do { \ WLAN_DFSNOL_LOCK(dfs); \ dfs_print_nol(dfs); \ WLAN_DFSNOL_UNLOCK(dfs); \ } while (0) #define DFS_NOL_FREE_LIST_LOCKED(dfs) \ do { \ WLAN_DFSNOL_LOCK(dfs); \ dfs_nol_free_list(dfs); \ WLAN_DFSNOL_UNLOCK(dfs); \ } while (0) /** * 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: RSSI of pulse. * @p_seg_id: Segment id. * @p_sidx: Sidx value. * @p_delta_peak: Delta peak value. * @p_seq_num: Sequence number. */ struct dfs_pulseparams { uint64_t p_time; uint8_t p_dur; uint8_t p_rssi; uint8_t p_seg_id; int16_t p_sidx; int8_t p_delta_peak; uint32_t p_seq_num; } qdf_packed; /** * struct dfs_pulseline - Pulseline structure. * @pl_elems[]: array of pulses in delay line. * @pl_firstelem: Index of the first element. * @pl_lastelem: Index of the last element. * @pl_numelems: Number of elements in the delay line. */ struct dfs_pulseline { struct dfs_pulseparams pl_elems[DFS_MAX_PULSE_BUFFER_SIZE]; uint32_t pl_firstelem; uint32_t pl_lastelem; uint32_t pl_numelems; } qdf_packed; #define DFS_EVENT_CHECKCHIRP 0x01 /* Whether to check the chirp flag */ #define DFS_EVENT_HW_CHIRP 0x02 /* hardware chirp */ #define DFS_EVENT_SW_CHIRP 0x04 /* software chirp */ /* Use this only if the event has CHECKCHIRP set. */ #define DFS_EVENT_ISCHIRP(e) \ ((e)->re_flags & (DFS_EVENT_HW_CHIRP | DFS_EVENT_SW_CHIRP)) /** * Check if the given event is to be rejected as not possibly * a chirp. This means: * (a) it's a hardware or software checked chirp, and * (b) the HW/SW chirp bits are both 0. */ #define DFS_EVENT_NOTCHIRP(e) \ (((e)->re_flags & (DFS_EVENT_CHECKCHIRP)) && (!DFS_EVENT_ISCHIRP((e)))) /** * struct dfs_event - DFS event structure. * @re_full_ts: 64-bit full timestamp from interrupt time. * @re_ts: Original 15 bit recv timestamp. * @re_rssi: Rssi of radar event. * @re_dur: Duration of radar pulse. * @re_chanindex: Channel of event. * @re_flags: Event flags. * @re_freq: Centre frequency of event, KHz. * @re_freq_lo: Lower bounds of frequency, KHz. * @re_freq_hi: Upper bounds of frequency, KHz. * @re_seg_id: HT80_80/HT160 use. * @re_sidx: Seg index. * @re_freq_offset_khz: Freq offset in KHz * @re_peak_mag: Peak mag. * @re_total_gain: Total gain. * @re_mb_gain: Mb gain. * @re_relpwr_db: Relpower in db. * @re_delta_diff: Delta diff. * @re_delta_peak: Delta peak. * @re_list: List of radar events. */ struct dfs_event { uint64_t re_full_ts; uint32_t re_ts; uint8_t re_rssi; uint8_t re_dur; uint8_t re_chanindex; uint8_t re_flags; uint32_t re_freq; uint32_t re_freq_lo; uint32_t re_freq_hi; uint8_t re_seg_id; int re_sidx; u_int re_freq_offset_khz; int re_peak_mag; int re_total_gain; int re_mb_gain; int re_relpwr_db; uint8_t re_delta_diff; int8_t re_delta_peak; STAILQ_ENTRY(dfs_event) re_list; } qdf_packed; #define DFS_AR_MAX_ACK_RADAR_DUR 511 #define DFS_AR_MAX_NUM_PEAKS 3 #define DFS_AR_ARQ_SIZE 2048 /* 8K AR events for buffer size */ #define DFS_AR_ARQ_SEQSIZE 2049 /* Sequence counter wrap for AR */ #define DFS_RADARQ_SIZE 512 /* 1K radar events for buffer size */ #define DFS_RADARQ_SEQSIZE 513 /* Sequence counter wrap for radar */ /* Number of radar channels we keep state for */ #define DFS_NUM_RADAR_STATES 64 /* Max number radar filters for each type */ #define DFS_MAX_NUM_RADAR_FILTERS 10 /* Number of different radar types */ #define DFS_MAX_RADAR_TYPES 32 /* RADAR filter pattern type 1*/ #define WLAN_DFS_RF_PATTERN_TYPE_1 1 /** * struct dfs_ar_state - DFS AR state structure. * @ar_prevwidth: Previous width. * @ar_phyerrcount[]: Phy error count. * @ar_acksum: Acksum. * @ar_packetthreshold: Thresh to determine traffic load. * @ar_parthreshold: Thresh to determine peak. * @ar_radarrssi: Rssi threshold for AR event. * @ar_prevtimestamp: Prev time stamp. * @ar_peaklist[]: Peak list. */ struct dfs_ar_state { uint32_t ar_prevwidth; uint32_t ar_phyerrcount[DFS_AR_MAX_ACK_RADAR_DUR]; uint32_t ar_acksum; uint32_t ar_packetthreshold; uint32_t ar_parthreshold; uint32_t ar_radarrssi; uint16_t ar_prevtimestamp; uint16_t ar_peaklist[DFS_AR_MAX_NUM_PEAKS]; }; /** * struct dfs_delayelem - Delay Element. * @de_time: Current "filter" time for start of pulse in usecs. * @de_dur: Duration of pulse in usecs. * @de_rssi: Rssi of pulse in dB. * @de_ts: Time stamp for this delay element. * @de_seg_id: Segment id for HT80_80/HT160 use. * @de_sidx: Sidx value. * @de_delta_peak: Delta peak. * @de_seq_num: Sequence number. */ struct dfs_delayelem { uint32_t de_time; uint8_t de_dur; uint8_t de_rssi; uint64_t de_ts; uint8_t de_seg_id; int16_t de_sidx; int8_t de_delta_peak; uint32_t de_seq_num; } qdf_packed; /** * struct dfs_delayline - DFS Delay Line. * @dl_elems[]: Array of pulses in delay line. * @dl_last_ts: Last timestamp the delay line was used (in usecs). * @dl_firstelem: Index of the first element. * @dl_lastelem: Index of the last element. * @dl_numelems: Number of elements in the delay line. * The following is to handle fractional PRI pulses that can cause false * detection. * @dl_seq_num_start: Sequence number of first pulse that was part of * threshold match. * @dl_seq_num_stop: Sequence number of last pulse that was part of threshold * match. * The following is required because the first pulse may or may not be in the * delay line but we will find it iin the pulse line using dl_seq_num_second's * diff_ts value. * @dl_seq_num_second: Sequence number of second pulse that was part of * threshold match. * @dl_search_pri: We need final search PRI to identify possible fractional * PRI issue. * @dl_min_sidx: Minimum sidx value of pulses used to match thershold. * Used for sidx spread check. * @dl_max_sidx: Maximum sidx value of pulses used to match thershold. * Used for sidx spread check. * @dl_delta_peak_match_count: Number of pulse in the delay line that had valid * delta peak value. */ struct dfs_delayline { struct dfs_delayelem dl_elems[DFS_MAX_DL_SIZE]; uint64_t dl_last_ts; uint32_t dl_firstelem; uint32_t dl_lastelem; uint32_t dl_numelems; uint32_t dl_seq_num_start; uint32_t dl_seq_num_stop; uint32_t dl_seq_num_second; uint32_t dl_search_pri; int16_t dl_min_sidx; int8_t dl_max_sidx; uint8_t dl_delta_peak_match_count; } qdf_packed; /** * struct dfs_filter - Dfs filter. * @rf_dl: Delay line of pulses for this filter. * @rf_numpulses: Number of pulses in the filter. * @rf_minpri: Min pri to be considered for this filter. * @rf_maxpri: Max pri to be considered for this filter. * @rf_threshold: Match filter output threshold for radar detect. * @rf_filterlen: Length (in usecs) of the filter. * @rf_patterntype: Fixed or variable pattern type. * @rf_fixed_pri_radar_pulse: indicates if it is a fixed pri pulse. * @rf_mindur: Min duration for this radar filter. * @rf_maxdur: Max duration for this radar filter. * @rf_ignore_pri_window: Ignore pri window. * @rf_pulseid: Unique ID corresponding to the original filter ID. * To reduce false detection, look at frequency spread. For now we will use * sidx spread. But for HT160 frequency spread will be a better measure. * @rf_sidx_spread: Maximum SIDX value spread in a matched sequence * excluding FCC Bin 5. * @rf_check_delta_peak: Minimum allowed delta_peak value for a pulse to be * considetred for this filter's match. */ struct dfs_filter { struct dfs_delayline rf_dl; uint32_t rf_numpulses; uint32_t rf_minpri; uint32_t rf_maxpri; uint32_t rf_threshold; uint32_t rf_filterlen; uint32_t rf_patterntype; uint32_t rf_fixed_pri_radar_pulse; uint32_t rf_mindur; uint32_t rf_maxdur; uint32_t rf_ignore_pri_window; uint32_t rf_pulseid; uint16_t rf_sidx_spread; int8_t rf_check_delta_peak; } qdf_packed; /** * struct dfs_filtertype - DFS Filter type. * @ft_filterdur[]: Filter array. * @ft_filterdur: Duration of pulse which specifies filter type. * @ft_numfilters: Num filters of this type. * @ft_last_ts: Last timestamp this filtertype was used (in usecs). * @ft_mindur: Min pulse duration to be considered for this filter type. * @ft_maxdur: Max pulse duration to be considered for this filter type. * @ft_rssithresh: Min rssi to be considered for this filter type. * @ft_numpulses: Num pulses in each filter of this type. * @ft_patterntype: Fixed or variable pattern type. * @ft_minpri: Min pri to be considered for this type. * @ft_rssimargin: Rssi threshold margin. In Turbo Mode HW reports rssi 3dB * lower than in non TURBO mode. This will offset that diff. */ struct dfs_filtertype { struct dfs_filter ft_filters[DFS_MAX_NUM_RADAR_FILTERS]; uint32_t ft_filterdur; uint32_t ft_numfilters; uint64_t ft_last_ts; uint32_t ft_mindur; uint32_t ft_maxdur; uint32_t ft_rssithresh; uint32_t ft_numpulses; uint32_t ft_patterntype; uint32_t ft_minpri; uint32_t ft_rssimargin; }; /** * struct dfs_channel - Channel structure for dfs component. * @dfs_ch_freq: Frequency in Mhz. * @dfs_ch_flags: Channel flags. * @dfs_ch_flagext: Extended channel flags. * @dfs_ch_ieee: IEEE channel number. * @dfs_ch_vhtop_ch_freq_seg1: Channel Center frequency. * @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency applicable for 80+80MHz * mode of operation. */ struct dfs_channel { uint16_t dfs_ch_freq; uint64_t dfs_ch_flags; uint16_t dfs_ch_flagext; uint8_t dfs_ch_ieee; uint8_t dfs_ch_vhtop_ch_freq_seg1; uint8_t dfs_ch_vhtop_ch_freq_seg2; }; /** * struct dfs_state - DFS state. * @rs_chan: Channel info. * @rs_chanindex: Channel index in radar structure. * @rs_numradarevents: Number of radar events. * @rs_param: Phy param. */ struct dfs_state { struct dfs_channel rs_chan; uint8_t rs_chanindex; uint32_t rs_numradarevents; struct wlan_dfs_phyerr_param rs_param; }; #define DFS_NOL_TIMEOUT_S (30*60) /* 30 minutes in seconds */ #define DFS_NOL_TIMEOUT_MS (DFS_NOL_TIMEOUT_S * 1000) #define DFS_NOL_TIMEOUT_US (DFS_NOL_TIMEOUT_MS * 1000) /** * struct dfs_nolelem - DFS NOL element. * @nol_dfs Back pointer to dfs object. * @nol_freq: Centre frequency. * @nol_chwidth: Event width (MHz). * @nol_start_ticks: NOL start time in OS ticks. * @nol_timeout_ms: NOL timeout value in msec. * @nol_timer: Per element NOL timer. * @nol_next: Next element pointer. */ struct dfs_nolelem { TAILQ_ENTRY(dfs_nolelem) nolelem_list; struct wlan_dfs *nol_dfs; uint32_t nol_freq; uint32_t nol_chwidth; unsigned long nol_start_ticks; uint32_t nol_timeout_ms; os_timer_t nol_timer; struct dfs_nolelem *nol_next; } qdf_packed; /** * struct dfs_info - DFS Info. * @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. * @rn_ts_prefix: Prefix to prepend to 15 bit recv ts. * @rn_numbin5radars: Number of bin5 radar pulses to search for. * @rn_fastdivGCval: Value of fast diversity gc limit from init file. * @rn_minrssithresh: Min rssi for all radar types. * @rn_maxpulsedur: Max pulse width in TSF ticks. * @dfs_ext_chan_busy: Ext chan busy. * @ext_chan_busy_ts: Ext chan busy time. * @dfs_bin5_chirp_ts: Ext bin5 chrip time. * @dfs_last_bin5_dur: Last bin5 during. */ struct dfs_info { uint32_t rn_ftindex; uint64_t rn_lastfull_ts; uint16_t rn_last_ts; uint32_t rn_last_unique_ts; uint64_t rn_ts_prefix; uint32_t rn_numbin5radars; uint32_t rn_fastdivGCval; int32_t rn_minrssithresh; uint32_t rn_maxpulsedur; uint8_t dfs_ext_chan_busy; uint64_t ext_chan_busy_ts; uint64_t dfs_bin5_chirp_ts; uint8_t dfs_last_bin5_dur; } qdf_packed; /** * struct dfs_bin5elem - BIN5 elements. * @be_ts: Timestamp for the bin5 element. * @be_rssi: Rssi for the bin5 element. * @be_dur: Duration of bin5 element. */ struct dfs_bin5elem { uint64_t be_ts; uint32_t be_rssi; uint32_t be_dur; }; /** * struct dfs_bin5radars - BIN5 radars. * @br_elems[]: List of bin5 elems that fall within the time window. * @br_firstelem: Index of the first element. * @br_lastelem: Index of the last element. * @br_numelems: Number of elements in the delay line. * @br_pulse: Original info about bin5 pulse. */ struct dfs_bin5radars { struct dfs_bin5elem br_elems[DFS_MAX_B5_SIZE]; uint32_t br_firstelem; uint32_t br_lastelem; uint32_t br_numelems; struct dfs_bin5pulse br_pulse; }; /** * struct dfs_stats - DFS stats. * @num_radar_detects: Total num. of radar detects. * @num_seg_two_radar_detects: Total num. of radar detected in secondary segment * @total_phy_errors: Total PHY errors. * @owl_phy_errors: OWL PHY errors. * @pri_phy_errors: Primary channel phy errors. * @ext_phy_errors: Extension channel phy errors. * @dc_phy_errors: DC PHY errors. * @early_ext_phy_errors: Extension channel early radar found error. * @bwinfo_errors: Bogus bandwidth info received in descriptor. * @datalen_discards: data length at least three bytes of payload. * @rssi_discards: RSSI is not accurate. * @last_reset_tstamp: Last reset timestamp. */ struct dfs_stats { uint32_t num_radar_detects; uint32_t num_seg_two_radar_detects; uint32_t total_phy_errors; uint32_t owl_phy_errors; uint32_t pri_phy_errors; uint32_t ext_phy_errors; uint32_t dc_phy_errors; uint32_t early_ext_phy_errors; uint32_t bwinfo_errors; uint32_t datalen_discards; uint32_t rssi_discards; uint64_t last_reset_tstamp; }; #define DFS_EVENT_LOG_SIZE 256 /** * struct dfs_event_log - DFS event log. * @ts: 64-bit full timestamp from interrupt time. * @diff_ts: Diff timestamp. * @rssi: Rssi of radar event. * @dur: Duration of radar pulse. * @is_chirp: Chirp flag. * @seg_id: HT80_80/HT160 use. * @sidx: Seg index. * @freq_offset_khz: Freq offset in KHz * @peak_mag: Peak mag. * @total_gain: Total gain. * @mb_gain: Mb gain. * @relpwr_db: Relpower in db. * @delta_diff: Delta diff. * @delta_peak: Delta peak. */ struct dfs_event_log { uint64_t ts; uint32_t diff_ts; uint8_t rssi; uint8_t dur; int is_chirp; uint8_t seg_id; int sidx; u_int freq_offset_khz; int peak_mag; int total_gain; int mb_gain; int relpwr_db; uint8_t delta_diff; int8_t delta_peak; }; #define WLAN_DFS_RESET_TIME_S 7 #define WLAN_DFS_WAIT (60 + WLAN_DFS_RESET_TIME_S) /* 60 seconds */ #define WLAN_DFS_WAIT_MS ((WLAN_DFS_WAIT) * 1000) /*in MS*/ #define WLAN_DFS_WEATHER_CHANNEL_WAIT_MIN 10 /*10 minutes*/ #define WLAN_DFS_WEATHER_CHANNEL_WAIT_S (WLAN_DFS_WEATHER_CHANNEL_WAIT_MIN * 60) #define WLAN_DFS_WEATHER_CHANNEL_WAIT_MS \ ((WLAN_DFS_WEATHER_CHANNEL_WAIT_S) * 1000) /*in MS*/ #define WLAN_DFS_WAIT_POLL_PERIOD 2 /* 2 seconds */ #define WLAN_DFS_WAIT_POLL_PERIOD_MS \ ((WLAN_DFS_WAIT_POLL_PERIOD) * 1000) /*in MS*/ #define DFS_DEBUG_TIMEOUT_S 30 /* debug timeout is 30 seconds */ #define DFS_DEBUG_TIMEOUT_MS (DFS_DEBUG_TIMEOUT_S * 1000) #define RSSI_POSSIBLY_FALSE 50 #define SEARCH_FFT_REPORT_PEAK_MAG_THRSH 40 /** * struct wlan_dfs - The main dfs structure. * @dfs_debug_mask: Current debug bitmask. * @dfs_curchan_radindex: Current channel radar index. * @dfs_extchan_radindex: Extension channel radar index. * @dfsdomain: Current DFS domain. * @dfs_proc_phyerr: Flags for Phy Errs to process. * @dfs_eventq: Q of free dfs event objects. * @dfs_eventqlock: Lock for free dfs event list. * @dfs_radarq: Q of radar events. * @dfs_radarqlock: Lock for dfs q. * @dfs_arq: Q of AR events. * @dfs_arqlock: Lock for AR q. * @dfs_ar_state: AR state. * @dfs_radar[]: Per-Channel Radar detector state. * @dfs_radarf[]: One filter for each radar pulse type. * @dfs_rinfo: State vars for radar processing. * @dfs_b5radars: Array of bin5 radar events. * @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. * @wlan_dfs_stats: DFS related stats. * @pulses: Pulse history. * @events: Events structure. * @wlan_radar_tasksched: Radar task is scheduled. * @wlan_dfswait: Waiting on channel for radar detect. * @wlan_dfstest: Test timer in progress. * @dfs_caps: Object of wlan_dfs_caps structure. * @wlan_dfstest_ieeechan: IEEE chan num to return to after a dfs mute * test. * @wlan_dfs_cac_time: CAC period. * @wlan_dfstesttime: Time to stay off chan during dfs test. * @wlan_dfswaittimer: Dfs wait timer. * @wlan_dfstesttimer: Dfs mute test timer. * @wlan_dfs_debug_timer: Dfs debug timer. * @dfs_second_segment_bangradar: Bangaradar on second segment of * VHT80_80/160. * @is_radar_found_on_secondary_seg: Radar on second segment. * @is_radar_during_precac: Radar found during precac. * @dfs_precac_lock: Lock to protect precac lists. * @dfs_precac_enable: Enable the precac. * @dfs_precac_secondary_freq: Second segment freq for precac. * @dfs_precac_primary_freq: Primary freq. * @dfs_precac_timer_running: Precac timer running. * @dfs_defer_precac_channel_change: Defer precac channel change. * @dfs_pre_cac_timeout_channel_change: Channel change due to precac timeout. * @wlan_dfs_task_timer: Dfs wait timer. * @dur_multiplier: Duration multiplier. * @wlan_dfs_isdfsregdomain: True when AP is in DFS domain * @wlan_dfs_false_rssi_thres: False RSSI Threshold. * @wlan_dfs_peak_mag: Peak mag. * @radar_log[]: Radar log. * @dfs_event_log_count: Event log count. * @dfs_event_log_on: Event log on. * @dfs_phyerr_count: Same as number of PHY radar interrupts. * @dfs_phyerr_reject_count: When TLV is supported, # of radar events * ignored after TLV is parsed. * @dfs_phyerr_queued_count: Number of radar events queued for matching * the filters. * @dfs_phyerr_freq_min: Phyerr min freq. * @dfs_phyerr_freq_max: Phyerr max freq. * @dfs_phyerr_w53_counter: Phyerr w53 counter. * @dfs_pri_multiplier: Allow pulse if they are within multiple of * PRI for the radar type. * @wlan_dfs_nol_timeout: NOL timeout. * @update_nol: Update NOL. * @dfs_seq_num: Sequence number. * @dfs_nol_event[]: NOL event. * @dfs_nol_timer: NOL list processing. * @dfs_nol_free_list: NOL free list. * @dfs_nol_elem_free_work: The work queue to free an NOL element. * @dfs_cac_timer: CAC timer. * @dfs_cac_valid_timer: Ignore CAC when this timer is running. * @dfs_cac_timeout_override: Overridden cac timeout. * @dfs_enable: DFS Enable. * @dfs_cac_timer_running: DFS CAC timer running. * @dfs_ignore_dfs: Ignore DFS. * @dfs_ignore_cac: Ignore CAC. * @dfs_cac_valid: DFS CAC valid. * @dfs_cac_valid_time: Time for which CAC will be valid and will * not be re-done. * @dfs_precac_timer: PRECAC timer. * @dfs_precac_timeout_override: Overridden precac timeout. * @dfs_num_precac_freqs: Number of PreCAC VHT80 frequencies. * @dfs_precac_required_list: PreCAC required list. * @dfs_precac_done_list: PreCAC done list. * @dfs_precac_nol_list: PreCAC NOL List. * @dfs_is_offload_enabled: Set if DFS offload enabled. * @dfs_use_nol: Use the NOL when radar found(default: TRUE) * @dfs_nol_lock: Lock to protect nol list. * @tx_leakage_threshold: Tx leakage threshold for dfs. * @dfs_use_nol_subchannel_marking: Use subchannel marking logic to add only * radar affected subchannel instead of all * bonding channels. */ struct wlan_dfs { uint32_t dfs_debug_mask; int16_t dfs_curchan_radindex; int16_t dfs_extchan_radindex; uint32_t dfsdomain; uint32_t dfs_proc_phyerr; STAILQ_HEAD(, dfs_event) dfs_eventq; qdf_spinlock_t dfs_eventqlock; STAILQ_HEAD(, dfs_event) dfs_radarq; qdf_spinlock_t dfs_radarqlock; STAILQ_HEAD(, dfs_event) dfs_arq; qdf_spinlock_t dfs_arqlock; struct dfs_ar_state dfs_ar_state; struct dfs_state dfs_radar[DFS_NUM_RADAR_STATES]; struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES]; struct dfs_info dfs_rinfo; struct dfs_bin5radars *dfs_b5radars; int8_t **dfs_ftindextable; struct dfs_nolelem *dfs_nol; int dfs_nol_count; struct wlan_dfs_phyerr_param dfs_defaultparams; struct dfs_stats wlan_dfs_stats; struct dfs_pulseline *pulses; struct dfs_event *events; uint32_t wlan_radar_tasksched:1, wlan_dfswait:1, wlan_dfstest:1; struct wlan_dfs_caps dfs_caps; uint8_t wlan_dfstest_ieeechan; uint32_t wlan_dfs_cac_time; uint32_t wlan_dfstesttime; os_timer_t wlan_dfswaittimer; os_timer_t wlan_dfstesttimer; os_timer_t wlan_dfs_debug_timer; uint8_t dfs_bangradar; bool dfs_second_segment_bangradar; bool is_radar_found_on_secondary_seg; bool is_radar_during_precac; qdf_spinlock_t dfs_precac_lock; bool dfs_precac_enable; uint8_t dfs_precac_secondary_freq; uint8_t dfs_precac_primary_freq; uint8_t dfs_precac_timer_running; uint8_t dfs_defer_precac_channel_change; uint8_t dfs_pre_cac_timeout_channel_change:1; os_timer_t wlan_dfs_task_timer; int dur_multiplier; uint16_t wlan_dfs_isdfsregdomain; int wlan_dfs_false_rssi_thres; int wlan_dfs_peak_mag; struct dfs_event_log radar_log[DFS_EVENT_LOG_SIZE]; int dfs_event_log_count; int dfs_event_log_on; int dfs_phyerr_count; int dfs_phyerr_reject_count; int dfs_phyerr_queued_count; int dfs_phyerr_freq_min; int dfs_phyerr_freq_max; int dfs_phyerr_w53_counter; int dfs_pri_multiplier; int wlan_dfs_nol_timeout; bool update_nol; uint32_t dfs_seq_num; int dfs_nol_event[DFS_CHAN_MAX]; os_timer_t dfs_nol_timer; TAILQ_HEAD(, dfs_nolelem) dfs_nol_free_list; qdf_work_t dfs_nol_elem_free_work; os_timer_t dfs_cac_timer; os_timer_t dfs_cac_valid_timer; int dfs_cac_timeout_override; uint8_t dfs_enable:1, dfs_cac_timer_running:1, dfs_ignore_dfs:1, dfs_ignore_cac:1, dfs_cac_valid:1; uint32_t dfs_cac_valid_time; os_timer_t dfs_precac_timer; int dfs_precac_timeout_override; uint8_t dfs_num_precac_freqs; TAILQ_HEAD(, dfs_precac_entry) dfs_precac_required_list; TAILQ_HEAD(, dfs_precac_entry) dfs_precac_done_list; TAILQ_HEAD(, dfs_precac_entry) dfs_precac_nol_list; struct dfs_channel *dfs_curchan; struct wlan_objmgr_pdev *dfs_pdev_obj; bool dfs_is_offload_enabled; int dfs_use_nol; qdf_spinlock_t dfs_nol_lock; uint16_t tx_leakage_threshold; bool dfs_use_nol_subchannel_marking; }; /** * struct dfs_soc_priv_obj - dfs private data * @psoc: pointer to PSOC object information * @pdev: pointer to PDEV object information * @dfs_is_phyerr_filter_offload: For some chip like Rome indicates too many * phyerr packets in a short time, which causes * OS hang. If this feild is configured as true, * FW will do the pre-check, filter out some * kinds of invalid phyerrors and indicate * radar detection related information to host. */ struct dfs_soc_priv_obj { struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_pdev *pdev; bool dfs_is_phyerr_filter_offload; }; /** * enum DFS debug - This should match the table from if_ath.c. * @WLAN_DEBUG_DFS: Minimal DFS debug. * @WLAN_DEBUG_DFS1: Normal DFS debug. * @WLAN_DEBUG_DFS2: Maximal DFS debug. * @WLAN_DEBUG_DFS3: Matched filterID display. * @WLAN_DEBUG_DFS_PHYERR: Phy error parsing. * @WLAN_DEBUG_DFS_NOL: NOL related entries. * @WLAN_DEBUG_DFS_PHYERR_SUM: PHY error summary. * @WLAN_DEBUG_DFS_PHYERR_PKT: PHY error payload. * @WLAN_DEBUG_DFS_BIN5: BIN5 checks. * @WLAN_DEBUG_DFS_BIN5_FFT: BIN5 FFT check. * @WLAN_DEBUG_DFS_BIN5_PULSE: BIN5 pulse check. * @WLAN_DEBUG_DFS_FALSE_DET: False detection debug related prints. * @WLAN_DEBUG_DFS_FALSE_DET2: Second level check to confirm poisitive * detection. * @WLAN_DEBUG_DFS_RANDOM_CHAN: Random channel selection. */ enum { WLAN_DEBUG_DFS = 0x00000100, WLAN_DEBUG_DFS1 = 0x00000200, WLAN_DEBUG_DFS2 = 0x00000400, WLAN_DEBUG_DFS3 = 0x00000800, WLAN_DEBUG_DFS_PHYERR = 0x00001000, WLAN_DEBUG_DFS_NOL = 0x00002000, WLAN_DEBUG_DFS_PHYERR_SUM = 0x00004000, WLAN_DEBUG_DFS_PHYERR_PKT = 0x00008000, WLAN_DEBUG_DFS_BIN5 = 0x00010000, WLAN_DEBUG_DFS_BIN5_FFT = 0x00020000, WLAN_DEBUG_DFS_BIN5_PULSE = 0x00040000, WLAN_DEBUG_DFS_FALSE_DET = 0x00080000, WLAN_DEBUG_DFS_FALSE_DET2 = 0x00100000, WLAN_DEBUG_DFS_RANDOM_CHAN = 0x00200000, WLAN_DEBUG_DFS_MAX = 0x80000000, WLAN_DEBUG_DFS_ALWAYS = WLAN_DEBUG_DFS_MAX }; /** * struct dfs_phy_err - DFS phy error. * @fulltsf: 64-bit TSF as read from MAC. * @is_pri: Detected on primary channel. * @is_ext: Detected on extension channel. * @is_dc: Detected at DC. * @is_early: Early detect. * @do_check_chirp: Whether to check hw_chirp/sw_chirp. * @is_hw_chirp: Hardware-detected chirp. * @is_sw_chirp: Software detected chirp. * @rs_tstamp: 32 bit TSF from RX descriptor (event). * @freq: Centre frequency of event - KHz. * @freq_lo: Lower bounds of frequency - KHz. * @freq_hi: Upper bounds of frequency - KHz. * @rssi: Pulse RSSI. * @dur: Pulse duration, raw (not uS). * @seg_id: HT80_80/HT160 use. * @sidx: Seg index. * @freq_offset_khz: Freq offset in KHz. * @peak_mag: Peak mag. * @total_gain: Total gain. * @mb_gain: Mb gain. * @relpwr_db: Relpower in DB. * @pulse_delta_diff: Pulse delta diff. * @pulse_delta_peak: Pulse delta peak. * * Chirp notes! * * Pre-Sowl chips don't do FFT reports, so chirp pulses simply show up * as long duration pulses. * * The bin5 checking code would simply look for a chirp pulse of the correct * duration (within MIN_BIN5_DUR and MAX_BIN5_DUR) and add it to the "chirp" * pattern. * * For Sowl and later, an FFT was done on longer duration frames. If those * frames looked like a chirp, their duration was adjusted to fall within * the chirp duration limits. If the pulse failed the chirp test (it had * no FFT data or the FFT didn't meet the chirping requirements) then the * pulse duration was adjusted to be greater than MAX_BIN5_DUR, so it * would always fail chirp detection. * * This is pretty horrible. * * The eventual goal for chirp handling is thus: * * 1)In case someone ever wants to do chirp detection with this code on * chips that don't support chirp detection, you can still do it based * on pulse duration. That's your problem to solve. * * 2)For chips that do hardware chirp detection or FFT, the "do_check_chirp" * bit should be set. * * 3)Then, either is_hw_chirp or is_sw_chirp is set, indicating that * the hardware or software post-processing of the chirp event found * that indeed it was a chirp. * * 4)Finally, the bin5 code should just check whether the chirp bits are * set and behave appropriately, falling back onto the duration checks * if someone wishes to use this on older hardware (or with disabled * FFTs, for whatever reason.) * * XXX TODO: * * 1)add duration in uS and raw duration, so the PHY error parsing * code is responsible for doing the duration calculation; * 2)add ts in raw and corrected, so the PHY error parsing * code is responsible for doing the offsetting, not the radar * event code. */ struct dfs_phy_err { uint64_t fulltsf; uint32_t is_pri:1, is_ext:1, is_dc:1, is_early:1, do_check_chirp:1, is_hw_chirp:1, is_sw_chirp:1; uint32_t rs_tstamp; uint32_t freq; uint32_t freq_lo; uint32_t freq_hi; uint8_t rssi; uint8_t dur; uint8_t seg_id; int sidx; u_int freq_offset_khz; int peak_mag; int total_gain; int mb_gain; int relpwr_db; uint8_t pulse_delta_diff; int8_t pulse_delta_peak; }; /** * struct rx_radar_status - Parsed radar status * @raw_tsf: Raw tsf * @tsf_offset: TSF offset. * @rssi: RSSI. * @pulse_duration: Pulse duration. * @is_chirp: Is chirp. * @delta_peak: Delta peak. * @delta_diff: Delta diff. * @sidx: Starting frequency. * @freq_offset: Frequency offset. * @agc_total_gain: AGC total gain. * @agc_mb_gain: AGC MB gain. */ struct rx_radar_status { uint32_t raw_tsf; uint32_t tsf_offset; int rssi; int pulse_duration; int is_chirp:1; int delta_peak; int delta_diff; int sidx; int freq_offset; /* in KHz */ int agc_total_gain; int agc_mb_gain; }; /** * struct rx_search_fft_report - FFT report. * @total_gain_db: Total gain in Db. * @base_pwr_db: Base power in Db. * @fft_chn_idx: FFT channel index. * @peak_sidx: Peak sidx. * @relpwr_db: Real power in Db. * @avgpwr_db: Average power in Db. * @peak_mag: Peak Mag. * @num_str_bins_ib: Num dtr BINs IB * @seg_id: Segment ID */ struct rx_search_fft_report { uint32_t total_gain_db; uint32_t base_pwr_db; int fft_chn_idx; int peak_sidx; int relpwr_db; int avgpwr_db; int peak_mag; int num_str_bins_ib; int seg_id; }; /** * dfs_process_radarevent() - process the radar event generated for a pulse. * @dfs: Pointer to wlan_dfs structure. * @chan: Current channel. * * There is currently no way to specify that a radar event has occurred on * a specific channel, so the current methodology is to mark both the pri * and ext channels as being unavailable. This should be fixed for 802.11ac * or we'll quickly run out of valid channels to use. * * If Radar found, this marks the channel (and the extension channel, if HT40) * as having seen a radar event. It marks CHAN_INTERFERENCE and will add it to * the local NOL implementation. This is only done for 'usenol=1', as the other * two modes don't do radar notification or CAC/CSA/NOL; it just notes there * was a radar. */ void dfs_process_radarevent(struct wlan_dfs *dfs, struct dfs_channel *chan); /** * dfs_nol_addchan() - Add channel to NOL. * @dfs: Pointer to wlan_dfs structure. * @freq: frequency to add to NOL. * @dfs_nol_timeout: NOL timeout. */ void dfs_nol_addchan(struct wlan_dfs *dfs, uint16_t freq, uint32_t dfs_nol_timeout); /** * dfs_get_nol() - Get NOL. * @dfs: Pointer to wlan_dfs structure. * @dfs_nol: Pointer to dfsreq_nolelem structure to save the channels from NOL. * @nchan: Number of channels. */ void dfs_get_nol(struct wlan_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int *nchan); /** * dfs_set_nol() - Set NOL. * @dfs: Pointer to wlan_dfs structure. * @dfs_nol: Pointer to dfsreq_nolelem structure. * @nchan: Number of channels. */ void dfs_set_nol(struct wlan_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int nchan); /** * dfs_nol_update() - NOL update * @dfs: Pointer to wlan_dfs structure. * * Notify the driver/umac that it should update the channel radar/NOL flags * based on the current NOL list. */ void dfs_nol_update(struct wlan_dfs *dfs); /** * dfs_nol_timer_cleanup() - NOL timer cleanup. * @dfs: Pointer to wlan_dfs structure. * * Cancels the NOL timer and frees the NOL elements. */ void dfs_nol_timer_cleanup(struct wlan_dfs *dfs); /** * dfs_nol_workqueue_cleanup() - Flushes NOL workqueue. * @dfs: Pointer to wlan_dfs structure. * * Flushes the NOL workqueue. */ void dfs_nol_workqueue_cleanup(struct wlan_dfs *dfs); /** * dfs_retain_bin5_burst_pattern() - Retain the BIN5 burst pattern. * @dfs: Pointer to wlan_dfs structure. * @diff_ts: Timestamp diff. * @old_dur: Old duration. */ uint8_t dfs_retain_bin5_burst_pattern(struct wlan_dfs *dfs, uint32_t diff_ts, uint8_t old_dur); /** * dfs_bin5_check_pulse() - BIN5 check pulse. * @dfs: Pointer to wlan_dfs structure. * @re: Pointer to dfs_event structure. * @br: Pointer to dfs_bin5radars structure. * * Reject the pulse if: * 1) It's outside the RSSI threshold; * 2) It's outside the pulse duration; * 3) It's been verified by HW/SW chirp checking * and neither of those found a chirp. */ int dfs_bin5_check_pulse(struct wlan_dfs *dfs, struct dfs_event *re, struct dfs_bin5radars *br); /** * dfs_bin5_addpulse() - BIN5 add pulse. * @dfs: Pointer to wlan_dfs structure. * @br: Pointer to dfs_bin5radars structure. * @re: Pointer to dfs_event structure. * @thists: Timestamp. */ int dfs_bin5_addpulse(struct wlan_dfs *dfs, struct dfs_bin5radars *br, struct dfs_event *re, uint64_t thists); /** * dfs_bin5_check() - BIN5 check. * @dfs: Pointer to wlan_dfs structure. * * If the dfs structure is NULL (which should be illegal if everyting is working * properly, then signify that a bin5 radar was found. */ int dfs_bin5_check(struct wlan_dfs *dfs); /** * dfs_check_chirping() - Check chirping. * @dfs: Pointer to wlan_dfs structure. * @buf: Phyerr buffer * @datalen: Phyerr buf length * @is_ctl: detected on primary channel. * @is_ext: detected on extension channel. * @slope: Slope * @is_dc: DC found * * This examines the FFT data contained in the PHY error information to figure * out whether the pulse is moving across frequencies. */ int dfs_check_chirping(struct wlan_dfs *dfs, void *buf, uint16_t datalen, int is_ctl, int is_ext, int *slope, int *is_dc); /** * dfs_get_random_bin5_dur() - Get random BIN5 duration. * @dfs: Pointer to wlan_dfs structure. * @tstamp: Timestamp. * * Chirping pulses may get cut off at DC and report lower durations. * This function will compute a suitable random duration for each pulse. * Duration must be between 50 and 100 us, but remember that in * wlan_process_phyerr() which calls this function, we are dealing with the * HW reported duration (unconverted). dfs_process_radarevent() will * actually convert the duration into the correct value. * This function doesn't take into account whether the hardware * is operating in 5GHz fast clock mode or not. * And this function doesn't take into account whether the hardware * is peregrine or not. */ int dfs_get_random_bin5_dur(struct wlan_dfs *dfs, uint64_t tstamp); /** * dfs_print_delayline() - Prints delayline. * @dfs: Pointer to wlan_dfs structure. * @dl: Pointer to dfs_delayline structure. */ void dfs_print_delayline(struct wlan_dfs *dfs, struct dfs_delayline *dl); /** * dfs_print_nol() - Print NOL elements. * @dfs: Pointer to wlan_dfs structure. */ void dfs_print_nol(struct wlan_dfs *dfs); /** * dfs_print_filter() - Prints the filter. * @dfs: Pointer to wlan_dfs structure. * @rf: Pointer to dfs_filter structure. */ void dfs_print_filter(struct wlan_dfs *dfs, struct dfs_filter *rf); /** * dfs_getchanstate() - Get chan state. * @dfs: Pointer to wlan_dfs structure. * @index: To save the index of dfs_radar[] * @ext_chan_flag: Extension channel flag; */ struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index, int ext_ch_flag); /** * dfs_round() - DFS found. * @val: Convert durations to TSF ticks. * * Return: TSF ticks. */ uint32_t dfs_round(int32_t val); /** * dfs_reset_alldelaylines() - Reset alldelaylines. * @dfs: Pointer to wlan_dfs structure. */ void dfs_reset_alldelaylines(struct wlan_dfs *dfs); /** * dfs_reset_delayline() - Clear only a single delay line. * @dl: Pointer to dfs_delayline structure. */ void dfs_reset_delayline(struct dfs_delayline *dl); /** * dfs_reset_filter_delaylines() - Reset filter delaylines. * @dft: Pointer to dfs_filtertype structure. */ void dfs_reset_filter_delaylines(struct dfs_filtertype *dft); /** * dfs_reset_radarq() - Reset radar queue. * @dfs: Pointer to wlan_dfs structure. */ void dfs_reset_radarq(struct wlan_dfs *dfs); /** * dfs_add_pulse() - Adds pulse to the queue. * @dfs: Pointer to wlan_dfs structure. * @rf: Pointer to dfs_filter structure. * @re: Pointer to dfs_event structure. * @deltaT: deltaT value. * @this_ts: Last time stamp. */ void dfs_add_pulse(struct wlan_dfs *dfs, struct dfs_filter *rf, struct dfs_event *re, uint32_t deltaT, uint64_t this_ts); /** * dfs_bin_check() - BIN check * @dfs: Pointer to wlan_dfs structure. * @rf: Pointer to dfs_filter structure. * @deltaT: deltaT value. * @width: Width * @ext_chan_flag: Extension channel flag. */ int dfs_bin_check(struct wlan_dfs *dfs, struct dfs_filter *rf, uint32_t deltaT, uint32_t dur, int ext_chan_flag); /** * dfs_bin_pri_check() - BIN PRI check * @dfs: Pointer to wlan_dfs structure. * @rf: Pointer to dfs_filter structure. * @dl: Pointer to dfs_delayline structure. * @score: Primary score. * @refpri: Current "filter" time for start of pulse in usecs. * @refdur: Duration value. * @ext_chan_flag: Extension channel flag. * @fundamentalpri: Highest PRI. */ int dfs_bin_pri_check(struct wlan_dfs *dfs, struct dfs_filter *rf, struct dfs_delayline *dl, uint32_t score, uint32_t refpri, uint32_t refdur, int ext_chan_flag, int fundamentalpri); /** * dfs_staggered_check() - Detection implementation for staggered PRIs. * @dfs: Pointer to wlan_dfs structure. * @rf: Pointer to dfs_filter structure. * @deltaT: Delta of the Timestamp. * @width: Duration of radar pulse. * * Return: 1 on success and 0 on failure. */ int dfs_staggered_check(struct wlan_dfs *dfs, struct dfs_filter *rf, uint32_t deltaT, uint32_t width); /** * dfs_get_pri_margin() - Get Primary margin. * @dfs: Pointer to wlan_dfs structure. * @is_extchan_detect: Extension channel detect. * @is_fixed_pattern: Fixed pattern. * * For the extension channel, if legacy traffic is present, we see a lot of * false alarms, so make the PRI margin narrower depending on the busy % for * the extension channel. * * Return: Returns pri_margin. */ int dfs_get_pri_margin(struct wlan_dfs *dfs, int is_extchan_detect, int is_fixed_pattern); /** * dfs_get_filter_threshold() - Get filter threshold. * @dfs: Pointer to wlan_dfs structure. * @rf: Pointer to dfs_filter structure. * @is_extchan_detect: Extension channel detect. * * For the extension channel, if legacy traffic is present, we see a lot of * false alarms, so make the thresholds higher depending on the busy % for the * extension channel. * * Return: Returns threshold. */ int dfs_get_filter_threshold(struct wlan_dfs *dfs, struct dfs_filter *rf, int is_extchan_detect); /** * dfs_process_ar_event() - Process the ar event. * @dfs: Pointer to wlan_dfs structure. * @chan: Current channel structure. */ void dfs_process_ar_event(struct wlan_dfs *dfs, struct dfs_channel *chan); /** * dfs_reset_ar() - resets the ar state. * @dfs: pointer to wlan_dfs structure. */ void dfs_reset_ar(struct wlan_dfs *dfs); /** * dfs_reset_arq() - resets the ar queue. * @dfs: pointer to wlan_dfs structure. */ void dfs_reset_arq(struct wlan_dfs *dfs); /** * dfs_process_phyerr_bb_tlv() - Parses the PHY error and populates the * dfs_phy_err struct. * @dfs: Pointer to wlan_dfs structure. * @buf: Phyerr buffer * @datalen: Phyerr buf len * @rssi: RSSI * @ext_rssi: Extension RSSI. * @rs_tstamp: Time stamp. * @fulltsf: TSF64. * @e: Pointer to dfs_phy_err structure. * * Return: Returns 1. */ int dfs_process_phyerr_bb_tlv(struct wlan_dfs *dfs, void *buf, uint16_t datalen, uint8_t rssi, uint8_t ext_rssi, uint32_t rs_tstamp, uint64_t fulltsf, struct dfs_phy_err *e); /** * dfs_reset() - DFS reset * @dfs: Pointer to wlan_dfs structure. */ void dfs_reset(struct wlan_dfs *dfs); /** * dfs_radar_enable() - Enables the radar. * @dfs: Pointer to wlan_dfs structure. * @no_cac: If no_cac is 0, it cancels the CAC. */ void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode); /** * dfs_process_phyerr() - Process phyerr. * @dfs: Pointer to wlan_dfs structure. * @buf: Phyerr buffer. * @datalen: phyerr buffer length. * @r_rssi: RSSI. * @r_ext_rssi: Extension channel RSSI. * @r_rs_tstamp: Timestamp. * @r_fulltsf: TSF64. */ 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); #ifdef QCA_MCL_DFS_SUPPORT /** * dfs_process_phyerr_filter_offload() - Process radar event. * @dfs: Pointer to wlan_dfs structure. * @wlan_radar_event: Pointer to radar_event_info structure. * * Return: None */ void dfs_process_phyerr_filter_offload(struct wlan_dfs *dfs, struct radar_event_info *wlan_radar_event); #endif /** * dfs_is_precac_timer_running() - Check whether precac timer is running. * @dfs: Pointer to wlan_dfs structure. */ bool dfs_is_precac_timer_running(struct wlan_dfs *dfs); /** * dfs_get_radars() - Based on the chipset, calls init radar table functions. * @dfs: Pointer to wlan_dfs structure. */ void dfs_get_radars(struct wlan_dfs *dfs); /** * dfs_attach() - Wrapper function to allocate memory for wlan_dfs members. * @dfs: Pointer to wlan_dfs structure. */ int dfs_attach(struct wlan_dfs *dfs); /** * dfs_main_attach() - Allocates memory for wlan_dfs members. * @dfs: Pointer to wlan_dfs structure. */ int dfs_main_attach(struct wlan_dfs *dfs); /** * dfs_create_object() - Creates DFS object. * @dfs: Pointer to wlan_dfs structure. */ int dfs_create_object(struct wlan_dfs **dfs); /** * dfs_destroy_object() - Destroys the DFS object. * @dfs: Pointer to wlan_dfs structure. */ void dfs_destroy_object(struct wlan_dfs *dfs); /** * dfs_detach() - Wrapper function to free dfs variables. * @dfs: Pointer to wlan_dfs structure. */ void dfs_detach(struct wlan_dfs *dfs); /** * dfs_main_detach() - Free dfs variables. * @dfs: Pointer to wlan_dfs structure. */ void dfs_main_detach(struct wlan_dfs *dfs); /** * dfs_cac_valid_reset() - Cancels the dfs_cac_valid_timer timer. * @dfs: Pointer to wlan_dfs structure. * @prevchan_ieee: Prevchan number. * @prevchan_flags: Prevchan flags. */ void dfs_cac_valid_reset(struct wlan_dfs *dfs, uint8_t prevchan_ieee, uint32_t prevchan_flags); /** * dfs_cac_stop() - Clear the AP CAC timer. * @dfs: Pointer to wlan_dfs structure. */ void dfs_cac_stop(struct wlan_dfs *dfs); /** * dfs_cancel_cac_timer() - Cancels the CAC timer. * @dfs: Pointer to wlan_dfs structure. */ void dfs_cancel_cac_timer(struct wlan_dfs *dfs); /** * dfs_start_cac_timer() - Starts the CAC timer. * @dfs: Pointer to wlan_dfs structure. */ void dfs_start_cac_timer(struct wlan_dfs *dfs); /** * dfs_set_update_nol_flag() - Sets update_nol flag. * @dfs: Pointer to wlan_dfs structure. * @val: update_nol flag. */ void dfs_set_update_nol_flag(struct wlan_dfs *dfs, bool val); /** * dfs_get_update_nol_flag() - Returns update_nol flag. * @dfs: Pointer to wlan_dfs structure. */ bool dfs_get_update_nol_flag(struct wlan_dfs *dfs); /** * dfs_get_use_nol() - Get usenol. * @dfs: Pointer to wlan_dfs structure. */ int dfs_get_use_nol(struct wlan_dfs *dfs); /** * dfs_get_nol_timeout() - Get NOL timeout. * @dfs: Pointer to wlan_dfs structure. */ int dfs_get_nol_timeout(struct wlan_dfs *dfs); /** * dfs_is_ap_cac_timer_running() - Returns the dfs cac timer. * @dfs: Pointer to wlan_dfs structure. */ int dfs_is_ap_cac_timer_running(struct wlan_dfs *dfs); /** * dfs_control()- Used to process ioctls related to DFS. * @dfs: Pointer to wlan_dfs structure. * @id: Command type. * @indata: Input buffer. * @insize: size of the input buffer. * @outdata: A buffer for the results. * @outsize: Size of the output buffer. */ int dfs_control(struct wlan_dfs *dfs, u_int id, void *indata, uint32_t insize, void *outdata, uint32_t *outsize); /** * dfs_getnol() - Wrapper function for dfs_get_nol() * @dfs: Pointer to wlan_dfs structure. * @dfs_nolinfo: Pointer to dfsreq_nolinfo structure. */ void dfs_getnol(struct wlan_dfs *dfs, void *dfs_nolinfo); /** * dfs_get_override_cac_timeout() - Get override CAC timeout value. * @dfs: Pointer to DFS object. * @cac_timeout: Pointer to save the CAC timeout value. */ int dfs_get_override_cac_timeout(struct wlan_dfs *dfs, int *cac_timeout); /** * dfs_override_cac_timeout() - Override the default CAC timeout. * @dfs: Pointer to DFS object. * @cac_timeout: CAC timeout value. */ int dfs_override_cac_timeout(struct wlan_dfs *dfs, int cac_timeout); /** * dfs_clear_nolhistory() - unmarks WLAN_CHAN_CLR_HISTORY_RADAR flag for * all the channels in dfs_ch_channels. * @dfs: Pointer to wlan_dfs structure. */ void dfs_clear_nolhistory(struct wlan_dfs *dfs); /** * ol_if_dfs_configure() - Initialize the RADAR table for offload chipsets. * @dfs: Pointer to wlan_dfs structure. * * This is called during a channel change or regulatory domain * reset; in order to fetch the new configuration information and * program the DFS pattern matching module. * * Eventually this should be split into "fetch config" (which can * happen at regdomain selection time) and "configure DFS" (which * can happen at channel config time) so as to minimise overheads * when doing channel changes. However, this'll do for now. */ void ol_if_dfs_configure(struct wlan_dfs *dfs); /** * dfs_init_radar_filters() - Init Radar filters. * @dfs: Pointer to wlan_dfs structure. * @radar_info: Pointer to wlan_dfs_radar_tab_info structure. */ int dfs_init_radar_filters(struct wlan_dfs *dfs, struct wlan_dfs_radar_tab_info *radar_info); /** * dfs_get_radars_for_ar5212() - Initialize radar table for AR5212 chipsets. * @dfs: Pointer to wlan_dfs structure. */ void dfs_get_radars_for_ar5212(struct wlan_dfs *dfs); /** * dfs_get_radars_for_ar5416() - Initialize radar table for AR5416 chipsets. * @dfs: Pointer to wlan_dfs structure. */ void dfs_get_radars_for_ar5416(struct wlan_dfs *dfs); /** * dfs_get_radars_for_ar9300() - Initialize radar table for AR9300 chipsets. * @dfs: Pointer to wlan_dfs structure. */ void dfs_get_radars_for_ar9300(struct wlan_dfs *dfs); /** * dfs_print_filters() - Print the filters. * @dfs: Pointer to wlan_dfs structure. */ void dfs_print_filters(struct wlan_dfs *dfs); /** * dfs_clear_stats() - Clear stats. * @dfs: Pointer to wlan_dfs structure. */ void dfs_clear_stats(struct wlan_dfs *dfs); /** * dfs_radar_disable() - Disables the radar. * @dfs: Pointer to wlan_dfs structure. */ int dfs_radar_disable(struct wlan_dfs *dfs); /** * dfs_mark_precac_dfs() - Mark the precac channel as radar. * @dfs: Pointer to wlan_dfs structure. */ void dfs_mark_precac_dfs(struct wlan_dfs *dfs, uint8_t is_radar_found_on_secondary_seg); /** * dfs_get_debug_info() - Get debug info. * @dfs: Pointer to wlan_dfs structure. * @data: void pointer to the data to save dfs_proc_phyerr. */ int dfs_get_debug_info(struct wlan_dfs *dfs, void *data); /** * dfs_cac_timer_init() - Initialize cac timers. * @dfs: Pointer to wlan_dfs structure. */ void dfs_cac_timer_init(struct wlan_dfs *dfs); /** * dfs_cac_attach() - Initialize dfs cac variables. * @dfs: Pointer to wlan_dfs structure. */ void dfs_cac_attach(struct wlan_dfs *dfs); /** * dfs_cac_timer_reset() - Cancel dfs cac timers. * @dfs: Pointer to wlan_dfs structure. */ void dfs_cac_timer_reset(struct wlan_dfs *dfs); /** * dfs_nol_timer_init() - Initialize NOL timers. * @dfs: Pointer to wlan_dfs structure. */ void dfs_nol_timer_init(struct wlan_dfs *dfs); /** * dfs_nol_attach() - Initialize NOL variables. * @dfs: Pointer to wlan_dfs structure. */ void dfs_nol_attach(struct wlan_dfs *dfs); /** * dfs_nol_detach() - Detach NOL variables. * @dfs: Pointer to wlan_dfs structure. */ void dfs_nol_detach(struct wlan_dfs *dfs); /** * dfs_print_nolhistory() - Print NOL history. * @dfs: Pointer to wlan_dfs structure. */ void dfs_print_nolhistory(struct wlan_dfs *dfs); /** * dfs_stacac_stop() - Clear the STA CAC timer. * @dfs: Pointer to wlan_dfs structure. */ void dfs_stacac_stop(struct wlan_dfs *dfs); /** * dfs_find_precac_secondary_vht80_chan() - Get a VHT80 channel with the * precac primary center frequency. * @dfs: Pointer to wlan_dfs structure. * @chan: Pointer to dfs channel structure. */ void dfs_find_precac_secondary_vht80_chan(struct wlan_dfs *dfs, struct dfs_channel *chan); /** * dfs_phyerr_param_copy() - Function to copy src buf to dest buf. * @dst: dest buf. * @src: src buf. */ void dfs_phyerr_param_copy(struct wlan_dfs_phyerr_param *dst, struct wlan_dfs_phyerr_param *src); /** * dfs_get_thresholds() - Get the threshold value. * @dfs: Pointer to wlan_dfs structure. * @param: Pointer to wlan_dfs_phyerr_param structure. */ int dfs_get_thresholds(struct wlan_dfs *dfs, struct wlan_dfs_phyerr_param *param); /** * dfs_set_thresholds() - Sets the threshold value. * @dfs: Pointer to wlan_dfs structure. * @threshtype: DFS ioctl param type. * @value: Threshold value. */ int dfs_set_thresholds(struct wlan_dfs *dfs, const uint32_t threshtype, const uint32_t value); /** * dfs_set_current_channel() - Set DFS current channel. * @dfs: Pointer to wlan_dfs structure. * @dfs_ch_freq: Frequency in Mhz. * @dfs_ch_flags: Channel flags. * @dfs_ch_flagext: Extended channel flags. * @dfs_ch_ieee: IEEE channel number. * @dfs_ch_vhtop_ch_freq_seg1: Channel Center frequency1. * @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency2. */ void dfs_set_current_channel(struct wlan_dfs *dfs, uint16_t dfs_ch_freq, uint64_t dfs_ch_flags, uint16_t dfs_ch_flagext, uint8_t dfs_ch_ieee, uint8_t dfs_ch_vhtop_ch_freq_seg1, uint8_t dfs_ch_vhtop_ch_freq_seg2); /** * dfs_second_segment_radar_disable() - Disables the second segment radar. * @dfs: Pointer to wlan_dfs structure. * * This is called when AP detects the radar, to (potentially) disable * the radar code. * * Return: returns 0. */ int dfs_second_segment_radar_disable(struct wlan_dfs *dfs); /** * dfs_get_nol_chfreq_and_chwidth() - Get channel freq and width from NOL list. * @dfs_nol: Pointer to NOL channel entry. * @nol_chfreq: Pointer to save channel frequency. * @nol_chwidth: Pointer to save channel width. * @index: Index to dfs_nol list. */ void dfs_get_nol_chfreq_and_chwidth(struct dfsreq_nolelem *dfs_nol, uint32_t *nol_chfreq, uint32_t *nol_chwidth, int index); /** * dfs_process_phyerr_owl() - Process an Owl-style phy error. * @dfs: Pointer to wlan_dfs structure. * @buf: Phyerr buffer * @datalen: Phyerr buf len * @rssi: RSSI * @ext_rssi: Extension RSSI. * @rs_tstamp: Time stamp. * @fulltsf: TSF64. * @e: Pointer to dfs_phy_err structure. * * Return: Returns 1. */ int dfs_process_phyerr_owl(struct wlan_dfs *dfs, void *buf, uint16_t datalen, uint8_t rssi, uint8_t ext_rssi, uint32_t rs_tstamp, uint64_t fulltsf, struct dfs_phy_err *e); /** * dfs_process_phyerr_sowl() -Process a Sowl/Howl style phy error. * @dfs: Pointer to wlan_dfs structure. * @buf: Phyerr buffer * @datalen: Phyerr buf len * @rssi: RSSI * @ext_rssi: Extension RSSI. * @rs_tstamp: Time stamp. * @fulltsf: TSF64. * @e: Pointer to dfs_phy_err structure. * * Return: Returns 1. */ int dfs_process_phyerr_sowl(struct wlan_dfs *dfs, void *buf, uint16_t datalen, uint8_t rssi, uint8_t ext_rssi, uint32_t rs_tstamp, uint64_t fulltsf, struct dfs_phy_err *e); /** * dfs_process_phyerr_merlin() - Process a Merlin/Osprey style phy error. * dfs_phy_err struct. * @dfs: Pointer to wlan_dfs structure. * @buf: Phyerr buffer * @datalen: Phyerr buf len * @rssi: RSSI * @ext_rssi: Extension RSSI. * @rs_tstamp: Time stamp. * @fulltsf: TSF64. * @e: Pointer to dfs_phy_err structure. * * Return: Returns 1. */ int dfs_process_phyerr_merlin(struct wlan_dfs *dfs, void *buf, uint16_t datalen, uint8_t rssi, uint8_t ext_rssi, uint32_t rs_tstamp, uint64_t fulltsf, struct dfs_phy_err *e); /* * __dfs_process_radarevent() - Continuation of process a radar event function. * @dfs: Pointer to wlan_dfs structure. * @ft: Pointer to dfs_filtertype structure. * @re: Pointer to dfs_event structure. * @this_ts: Timestamp. * * There is currently no way to specify that a radar event has occurred on * a specific channel, so the current methodology is to mark both the pri * 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. */ void __dfs_process_radarevent(struct wlan_dfs *dfs, struct dfs_filtertype *ft, struct dfs_event *re, uint64_t this_ts, int *found, int *false_radar_found); /** * bin5_rules_check_internal() - This is a extension of dfs_bin5_check(). * @dfs: Pointer to wlan_dfs structure. * @br: Pointer to dfs_bin5radars structure. * @bursts: Bursts. * @numevents: Number of events. * @prev: prev index. * @i: Index. * @this: index to br_elems[] */ 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, int *index); /** * dfs_main_task_timer_init() - Initialize dfs task timer. * @dfs: Pointer to wlan_dfs structure. */ void dfs_main_task_timer_init(struct wlan_dfs *dfs); /** * dfs_main_task_testtimer_init() - Initialize dfs task testtimer. * @dfs: Pointer to wlan_dfs structure. */ void dfs_main_task_testtimer_init(struct wlan_dfs *dfs); /** * dfs_main_timer_reset() - Stop dfs timers. * @dfs: Pointer to wlan_dfs structure. */ void dfs_main_timer_reset(struct wlan_dfs *dfs); /** * dfs_stop() - Clear dfs timers. * @dfs: Pointer to wlan_dfs structure. */ void dfs_stop(struct wlan_dfs *dfs); /** * dfs_update_cur_chan_flags() - Update DFS channel flag and flagext. * @dfs: Pointer to wlan_dfs structure. * @flags: New channel flags * @flagext: New Extended flags */ void dfs_update_cur_chan_flags(struct wlan_dfs *dfs, uint64_t flags, uint16_t flagext); /** * dfs_send_csa_to_current_chan() - Send CSA to current channel * @dfs: Pointer to wlan_dfs structure. * * For the test mode(usenol = 0), don't do a CSA; but setup the test timer so * we get a CSA _back_ to the current operating channel. */ void dfs_send_csa_to_current_chan(struct wlan_dfs *dfs); /** * dfs_radarevent_basic_sanity() - Check basic sanity of the radar event * @dfs: Pointer to wlan_dfs structure. * @chan: Current channel. * * Return: If a radar event found on NON-DFS channel return 0. Otherwise, * return 1. */ int dfs_radarevent_basic_sanity(struct wlan_dfs *dfs, struct dfs_channel *chan); /** * wlan_psoc_get_dfs_txops() - Get dfs_tx_ops pointer * @psoc: Pointer to psoc structure. * * Return: Pointer to dfs_tx_ops. */ struct wlan_lmac_if_dfs_tx_ops * wlan_psoc_get_dfs_txops(struct wlan_objmgr_psoc *psoc); /** * dfs_nol_free_list() - Free NOL elements. * @dfs: Pointer to wlan_dfs structure. */ void dfs_nol_free_list(struct wlan_dfs *dfs); /** * dfs_set_phyerr_filter_offload - config phyerr filter offload. * @dfs: Pointer to wlan_dfs structure. * * Return: None */ void dfs_set_phyerr_filter_offload(struct wlan_dfs *dfs); #endif /* _DFS_H_ */