diff --git a/core/sap/dfs/inc/ath_dfs_structs.h b/core/sap/dfs/inc/ath_dfs_structs.h deleted file mode 100644 index 83c0655262ca..000000000000 --- a/core/sap/dfs/inc/ath_dfs_structs.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - ath_dfs_structs.h - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#ifndef _DFS__STRUCTS_H_ -#define _DFS__STRUCTS_H_ -#include - -#ifdef ANDROID -#include -#endif - -/* - * For the dfs_nol_clist_update() method - this is the - * update command. - */ -enum { - DFS_NOL_CLIST_CMD_NONE = 0x0, - DFS_NOL_CLIST_CMD_UPDATE = 0x1, -}; - -struct ath_dfs_caps { - uint32_t ath_dfs_ext_chan_ok:1, - /* Can radar be detected on the extension chan? */ - ath_dfs_combined_rssi_ok:1, - /* Can use combined radar RSSI? - * the following flag is used to indicate if radar detection - * scheme should use enhanced chirping detection algorithm. - * This flag also determines if certain radar data should be - * discarded to minimize false detection of radar. - */ - ath_dfs_use_enhancement:1, - ath_strong_signal_diversiry:1, - ath_chip_is_bb_tlv:1; - - /* - * goes with ath_strong_signal_diversiry: - * If we have fast diversity capability, read off - * Strong Signal fast diversity count set in the ini - * file, and store so we can restore the value when - * radar is disabled - */ - uint32_t ath_fastdiv_val; -}; - -/* - * These are defined in the HAL for now, and must be migrated outside - * of there in order to be used by the new partial offload data path. - */ - -struct dfs_pulse { - uint32_t rp_numpulses; /* Num of pulses in radar burst */ - uint32_t rp_pulsedur; /* Duration of each pulse in usecs */ - uint32_t rp_pulsefreq; /* Frequency of pulses in burst */ - uint32_t rp_max_pulsefreq; /* Frequency of pulses in burst */ - uint32_t rp_patterntype; /* fixed or variable pattern type */ - uint32_t rp_pulsevar; /* Time variation of pulse duration for - matched filter (single-sided) in usecs */ - uint32_t rp_threshold; /* Threshold for MF output to indicateC - radar match */ - uint32_t rp_mindur; /* Min pulse duration to be considered for - this pulse type */ - uint32_t rp_maxdur; /* Max pusle duration to be considered for - this pulse type */ - uint32_t rp_rssithresh; /* Min rssi to be considered a radar pulse */ - uint32_t rp_meanoffset; /* Offset for timing adjustment */ - int32_t rp_rssimargin; /* rssi threshold margin. In Turbo Mode HW - * reports rssi 3dBm lower than in non TURBO - * mode. This will be used to offset that - * diff. - */ - uint32_t rp_ignore_pri_window; - uint32_t rp_pulseid; /* Unique ID for identifying filter */ -}; - -struct dfs_staggered_pulse { - uint32_t rp_numpulses; /* Num of pulses in radar burst */ - uint32_t rp_pulsedur; /* Duration of each pulse in usecs */ - uint32_t rp_min_pulsefreq; /* Frequency of pulses in burst */ - uint32_t rp_max_pulsefreq; /* Frequency of pulses in burst */ - uint32_t rp_patterntype; /* fixed or variable pattern type */ - uint32_t rp_pulsevar; /* Time variation of pulse duration for - matched filter (single-sided) in usecs */ - uint32_t rp_threshold; /* Thershold for MF output to indicateC - radar match */ - uint32_t rp_mindur; /* Min pulse duration to be considered for - this pulse type */ - uint32_t rp_maxdur; /* Max pusle duration to be considered for - this pulse type */ - uint32_t rp_rssithresh; /* Min rssi to be considered a radar pulse */ - uint32_t rp_meanoffset; /* Offset for timing adjustment */ - int32_t rp_rssimargin; /* rssi threshold margin. In Turbo Mode HW - reports rssi 3dBm lower than in non TURBO - mode. This will be used to offset that - diff. */ - uint32_t rp_pulseid; /* Unique ID for identifying filter */ -}; - -struct dfs_bin5pulse { - uint32_t b5_threshold; /* Num of bin5 pulses to indicate detection */ - uint32_t b5_mindur; /* Min duration for a bin5 pulse */ - uint32_t b5_maxdur; /* Max duration for a bin5 pulse */ - uint32_t b5_timewindow; /* Window over which to count bin5 pulses */ - uint32_t b5_rssithresh; /* Min rssi to be considered a pulse */ - uint32_t b5_rssimargin; /* rssi threshold margin. In Turbo Mode HW - * reports rssi 3dB - */ -}; - -/* - * DFS NOL representation. - * - * This is used to represent the DFS NOL information between the - * NOL code in lmac/dfs/dfs_nol.c and any driver layer wishing - * to use it. - */ -struct dfs_nol_chan_entry { - uint32_t nol_chfreq; /* Centre frequency, MHz */ - uint32_t nol_chwidth; /* Width, MHz */ - unsigned long nol_start_ticks; /* start ticks, OS specific */ - uint32_t nol_timeout_ms; /* timeout, mS */ -}; - -/* HAL_PHYERR_PARAM; */ - -/* - * This represents the general case of the radar PHY configuration, - * across all chips. - * - * It's then up to each chip layer to translate to/from this - * (eg to HAL_PHYERR_PARAM for the HAL case.) - */ - -#define ATH_DFS_PHYERR_PARAM_NOVAL 0xFFFF -#define ATH_DFS_PHYERR_PARAM_ENABLE 0x8000 - -struct ath_dfs_phyerr_param { - int32_t pe_firpwr; /* FIR pwr out threshold */ - int32_t pe_rrssi; /* Radar rssi thresh */ - int32_t pe_height; /* Pulse height thresh */ - int32_t pe_prssi; /* Pulse rssi thresh */ - int32_t pe_inband; /* Inband thresh */ - - /* The following params are only for AR5413 and later */ - /* - * Relative power threshold in 0.5dB steps - */ - uint32_t pe_relpwr; - - /* - * Pulse Relative step threshold in 0.5dB steps - */ - uint32_t pe_relstep; - - /* - * Max length of radar sign in 0.8us units - */ - uint32_t pe_maxlen; - - /* - * Use the average in-band power measured over 128 cycles - */ - bool pe_usefir128; - - /* - * Enable to block radar check if pkt detect is done via OFDM - * weak signal detect or pkt is detected immediately after tx - * to rx transition - */ - bool pe_blockradar; - - /* - * Enable to use the max rssi instead of the last rssi during - * fine gain changes for radar detection - */ - bool pe_enmaxrssi; -}; - -static inline void ath_dfs_phyerr_param_copy(struct ath_dfs_phyerr_param *dst, - struct ath_dfs_phyerr_param *src) -{ - qdf_mem_copy(dst, src, sizeof(*dst)); -} - -static inline void ath_dfs_phyerr_init_noval(struct ath_dfs_phyerr_param *pe) -{ - pe->pe_firpwr = ATH_DFS_PHYERR_PARAM_NOVAL; - pe->pe_rrssi = ATH_DFS_PHYERR_PARAM_NOVAL; - pe->pe_height = ATH_DFS_PHYERR_PARAM_NOVAL; - pe->pe_prssi = ATH_DFS_PHYERR_PARAM_NOVAL; - pe->pe_inband = ATH_DFS_PHYERR_PARAM_NOVAL; - pe->pe_relpwr = ATH_DFS_PHYERR_PARAM_NOVAL; - pe->pe_relstep = ATH_DFS_PHYERR_PARAM_NOVAL; - pe->pe_maxlen = ATH_DFS_PHYERR_PARAM_NOVAL; - - /* XXX what about usefir128, blockradar, enmaxrssi? */ -} - -struct ath_dfs_radar_tab_info { - uint32_t dfsdomain; - int numradars; - struct dfs_pulse *dfs_radars; - int numb5radars; - struct dfs_bin5pulse *b5pulses; - struct ath_dfs_phyerr_param dfs_defaultparams; - int dfs_pri_multiplier; -}; -#endif /* _DFS__STRUCTS_H_ */ diff --git a/core/sap/dfs/inc/dfs.h b/core/sap/dfs/inc/dfs.h deleted file mode 100644 index 291ae6798cc0..000000000000 --- a/core/sap/dfs/inc/dfs.h +++ /dev/null @@ -1,927 +0,0 @@ -/* - * Copyright (c) 2005-2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs.h - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -#ifndef _DFS_H_ -#define _DFS_H_ - -/* - *TO DO DFS- Need to include this file later on - *#include "ath_internal.h" - */ -/*DFS New Include Start*/ - -#include /* QDF_NBUF_EXEMPT_NO_EXEMPTION, etc. */ -#include /* qdf_nbuf_t, etc. */ -#include /* qdf_assert */ -#include /* qdf_spinlock */ -#include /* TAILQ */ -#include -#include -#include -#include -/*DFS Utility Include END*/ - -/* From wlan_modules/include/ */ -#include "ath_dfs_structs.h" -/*DFS - Newly added File to interface cld UMAC and dfs data structures*/ -#include "wlan_reg_services_api.h" -#include "wma_dfs_interface.h" -/* - *TO DO DFS- Need to include this file later on - #include "ah.h" - */ -/* #include "ah_desc.h" */ -#include "dfs_ioctl.h" -#include "dfs_ioctl_private.h" -#include "dfs_interface.h" -#include "cds_ieee80211_common.h" -#include "cds_api.h" - -#define ATH_SUPPORT_DFS 1 -#define CHANNEL_TURBO 0x00010 -#define DFS_PRINTK(_fmt, ...) printk((_fmt), __VA_ARGS__) -#define DFS_DPRINTK(dfs, _m, _fmt, ...) do { \ - if (((dfs) == NULL) || \ - ((dfs) != NULL && \ - ((_m) & (dfs)->dfs_debug_mask))) { \ - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, \ - _fmt, __VA_ARGS__); \ - } \ -} while (0) - -#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 - -#define DFS_STATUS_SUCCESS 0 -#define DFS_STATUS_FAIL 1 - -#define DFS_80P80_SEG0 0 -#define DFS_80P80_SEG1 1 - -/** - * @DFS_RADAR_SUMMARY_REPORT_VERSION_2: DFS-2 radar summary report - * @DFS_RADAR_SUMMARY_REPORT_VERSION_3: DFS-3 radar summary report - */ -enum { - DFS_RADAR_SUMMARY_REPORT_VERSION_2 = 1, - DFS_RADAR_SUMMARY_REPORT_VERSION_3 = 2, -}; - - -/* - * 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 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 -/* #define MAX_BIN5_DUR 131 / * 105 * 1.25* / */ -/* use 145 for osprey conversion is already done using dfs->dur_multiplier */ -#define MAX_BIN5_DUR 145 -#define MAX_BIN5_DUR_MICROSEC 105 -#define MAX_DFS_RADAR_TABLE_TYPE 256 - -#define DFS_BIN5_TIME_WINDOW_UNITS_MULTIPLIER 1000000 - -#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 ATH_DFSQ_LOCK(_dfs) qdf_spin_lock_bh((&(_dfs)->dfs_radarqlock)) -#define ATH_DFSQ_UNLOCK(_dfs) qdf_spin_unlock_bh((&(_dfs)->dfs_radarqlock)) -#define ATH_DFSQ_LOCK_INIT(_dfs) qdf_spinlock_create(&(_dfs)->dfs_radarqlock) -#define ATH_DFSQ_LOCK_DEINIT(_dfs) qdf_spinlock_destroy(&(_dfs)->dfs_radarqlock) - -#define ATH_ARQ_LOCK(_dfs) qdf_spin_lock_bh((&(_dfs)->dfs_arqlock)) -#define ATH_ARQ_UNLOCK(_dfs) qdf_spin_unlock_bh((&(_dfs)->dfs_arqlock)) -#define ATH_ARQ_LOCK_INIT(_dfs) qdf_spinlock_create(&(_dfs)->dfs_arqlock) -#define ATH_ARQ_LOCK_DEINIT(_dfs) qdf_spinlock_destroy(&(_dfs)->dfs_arqlock) - -#define ATH_DFSEVENTQ_LOCK(_dfs) qdf_spin_lock_bh((&(_dfs)->dfs_eventqlock)) -#define ATH_DFSEVENTQ_UNLOCK(_dfs) qdf_spin_unlock_bh((&(_dfs)->dfs_eventqlock)) -#define ATH_DFSEVENTQ_LOCK_INIT(_dfs) \ - qdf_spinlock_create((&(_dfs)->dfs_eventqlock)) -#define ATH_DFSEVENTQ_LOCK_DEINIT(_dfs) \ - qdf_spinlock_destroy((&(_dfs)->dfs_eventqlock)) -/* 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 */ - -#define DFS_MAX_RADAR_OVERLAP 16 /* Max number of overlapping filters */ -/* 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 */ -#define DFS_MAX_RSSI_VALUE 0x7fffffff /* Max rssi value */ -/* max num of pulses in a burst */ -#define DFS_BIN_MAX_PULSES 60 -#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_WAR_PLUS_30_MHZ_SEPARATION 30 -#define DFS_WAR_MINUS_30_MHZ_SEPARATION -30 -#define DFS_WAR_PEAK_INDEX_ZERO 0 -#define DFS_TYPE4_WAR_PULSE_DURATION_LOWER_LIMIT 11 -#define DFS_TYPE4_WAR_PULSE_DURATION_UPPER_LIMIT 33 -#define DFS_TYPE4_WAR_PRI_LOWER_LIMIT 200 -#define DFS_TYPE4_WAR_PRI_UPPER_LIMIT 500 -#define DFS_TYPE4_WAR_VALID_PULSE_DURATION 12 -#define DFS_ETSI_TYPE2_TYPE3_WAR_PULSE_DUR_LOWER_LIMIT 15 -#define DFS_ETSI_TYPE2_TYPE3_WAR_PULSE_DUR_UPPER_LIMIT 33 -#define DFS_ETSI_TYPE2_WAR_PRI_LOWER_LIMIT 625 -#define DFS_ETSI_TYPE2_WAR_PRI_UPPER_LIMIT 5000 -#define DFS_ETSI_TYPE3_WAR_PRI_LOWER_LIMIT 250 -#define DFS_ETSI_TYPE3_WAR_PRI_UPPER_LIMIT 435 -#define DFS_ETSI_WAR_VALID_PULSE_DURATION 15 - -typedef qdf_spinlock_t dfsq_lock_t; - -#ifdef WIN32 -#pragma pack(push, dfs_pulseparams, 1) -#endif -struct dfs_pulseparams { - uint64_t p_time; /* time for start of pulse in usecs */ - uint8_t p_dur; /* Duration of pulse in usecs */ - uint8_t p_rssi; /* Duration of pulse in usecs */ -} qdf_packed; -#ifdef WIN32 -#pragma pack(pop, dfs_pulseparams) -#endif - -#ifdef WIN32 -#pragma pack(push, dfs_pulseline, 1) -#endif -struct dfs_pulseline { - /* pl_elems - array of pulses in delay line */ - struct dfs_pulseparams pl_elems[DFS_MAX_PULSE_BUFFER_SIZE]; - uint32_t pl_firstelem; /* Index of the first element */ - uint32_t pl_lastelem; /* Index of the last element */ - uint32_t pl_numelems; /* Number of elements in the delay line */ -} qdf_packed; -#ifdef WIN32 -#pragma pack(pop, dfs_pulseline) -#endif - -#ifdef WIN32 -#pragma pack(push, dfs_event, 1) -#endif - -#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 - to hold dfs events - * @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 - * @sidx: Pulse Index as in radar summary report - * @radar_80p80_segid: 80p80 segment ID as in radar sum report - * @delta_peak: delta peak reported in radar summary - * @delta_diff: delta diff reported in radar summary - * @agc_total_gain: agc total gain reported in radar summary - * @agc_mb_gain: agc mb gain reported in radar summary - * @radar_subchan_mask: subchan mask reported in radar summary - * @pulse_height: pulse height reported in radar summary - * @triggering_agc_event: triggering agc reported in radar summary - * @pulse_rssi: rssi of phyerr reported in radar summary - * @radar_fft_pri80_inband_power: Pri80MHz pwr reported in summary - * @radar_fft_ext80_inband_power: Ext80MHz pwr reported in summary - * @rsu_version: Radar summary report version - * @dfs_phyerr_eventq_serial_num: phyerr seq num queued for pattern matching - * @peak_mag: Peak mag reported in radar search FFT report - * @re_list: List of radar events - * - * To Process 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; - int sidx; - int radar_80p80_segid; - uint8_t delta_peak; - uint8_t delta_diff; - uint8_t agc_total_gain; - uint8_t agc_mb_gain; - uint8_t radar_subchan_mask; - uint8_t pulse_height; - uint8_t triggering_agc_event; - uint8_t pulse_rssi; - uint8_t radar_fft_pri80_inband_power; - uint8_t radar_fft_ext80_inband_power; - uint8_t rsu_version; - uint8_t dfs_phyerr_eventq_serial_num; - uint8_t peak_mag; - STAILQ_ENTRY(dfs_event) re_list; -}; -#ifdef WIN32 -#pragma pack(pop, dfs_event) -#endif - -#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 - -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; /* Thresh to determine traffic load */ - uint32_t ar_parthreshold; /* Thresh to determine peak */ - uint32_t ar_radarrssi; /* Rssi threshold for AR event */ - uint16_t ar_prevtimestamp; - uint16_t ar_peaklist[DFS_AR_MAX_NUM_PEAKS]; -}; - -#ifdef WIN32 -#pragma pack(push, dfs_delayelem, 1) -#endif -struct dfs_delayelem { - /* Current "filter" time for start of pulse in usecs */ - uint32_t de_time; - /* Duration of pulse in usecs */ - uint8_t de_dur; - /* rssi of pulse in dB */ - uint8_t de_rssi; - /* time stamp for this delay element */ - uint64_t de_ts; -} qdf_packed; -#ifdef WIN32 -#pragma pack(pop, dfs_delayelem) -#endif - -/* NB: The first element in the circular buffer is the oldest element */ - -#ifdef WIN32 -#pragma pack(push, dfs_delayline, 1) -#endif -struct dfs_delayline { - /* Array of pulses in delay line */ - struct dfs_delayelem dl_elems[DFS_MAX_DL_SIZE]; - /* Last timestamp the delay line was used (in usecs) */ - uint64_t dl_last_ts; - /* Index of the first element */ - uint32_t dl_firstelem; - /* Index of the last element */ - uint32_t dl_lastelem; - /* Number of elements in the delay line */ - uint32_t dl_numelems; -} qdf_packed; -#ifdef WIN32 -#pragma pack(pop, dfs_delayline) -#endif - -#ifdef WIN32 -#pragma pack(push, dfs_filter, 1) -#endif -struct dfs_filter { - /* Delay line of pulses for this filter */ - struct dfs_delayline rf_dl; - /* Delay line of pulses for this filter in 80p80 */ - struct dfs_delayline rf_dl_ext_seg; - /* Number of pulses in the filter */ - uint32_t rf_numpulses; - /* min pri to be considered for this filter */ - uint32_t rf_minpri; - /* max pri to be considered for this filter */ - uint32_t rf_maxpri; - /* match filter output threshold for radar detect */ - uint32_t rf_threshold; - /* Length (in usecs) of the filter */ - uint32_t rf_filterlen; - /* fixed or variable pattern type */ - uint32_t rf_patterntype; - /* indicates if it is a fixed pri pulse */ - uint32_t rf_fixed_pri_radar_pulse; - /* Min duration for this radar filter */ - uint32_t rf_mindur; - /* Max duration for this radar filter */ - uint32_t rf_maxdur; - uint32_t rf_ignore_pri_window; - /* Unique ID corresponding to the original filter ID */ - uint32_t rf_pulseid; -} qdf_packed; -#ifdef WIN32 -#pragma pack(pop, dfs_filter) -#endif - -struct dfs_filtertype { - struct dfs_filter *ft_filters[DFS_MAX_NUM_RADAR_FILTERS]; - /* Duration of pulse which specifies filter type */ - uint32_t ft_filterdur; - /* Num filters of this type */ - uint32_t ft_numfilters; - /* Last timestamp this filtertype was used(in usecs) */ - uint64_t ft_last_ts; - /* min pulse duration to be considered for this filter type */ - uint32_t ft_mindur; - /* max pulse duration to be considered for this filter type */ - uint32_t ft_maxdur; - /* min rssi to be considered for this filter type */ - uint32_t ft_rssithresh; - /* Num pulses in each filter of this type */ - uint32_t ft_numpulses; - /* fixed or variable pattern type */ - uint32_t ft_patterntype; - /* min pri to be considered for this type */ - uint32_t ft_minpri; - /* rssi threshold margin. In Turbo Mode HW - * reports rssi 3dB lower than in non TURBO - * mode. This will offset that diff. - */ - uint32_t ft_rssimargin; -}; - -struct dfs_state { - struct dfs_ieee80211_channel rs_chan; /* Channel info */ - uint8_t rs_chanindex; /* Channel index in radar structure */ - uint32_t rs_numradarevents; /* Number of radar events */ - - struct ath_dfs_phyerr_param rs_param; -}; - -/* 30 minutes in seconds */ -#define DFS_NOL_TIMEOUT_S (30*60) -/* 5 minutes in seconds - debugging */ -/* #define DFS_NOL_TIMEOUT_S (5*60) */ -#define DFS_NOL_TIMEOUT_MS (DFS_NOL_TIMEOUT_S * 1000) -#define DFS_NOL_TIMEOUT_US (DFS_NOL_TIMEOUT_MS * 1000) - -#ifdef WIN32 -#pragma pack(push, dfs_nolelem, 1) -#endif -struct dfs_nolelem { - uint32_t nol_freq; /* centre frequency */ - uint32_t nol_chwidth; /* event width (MHz) */ - unsigned long nol_start_ticks; /* NOL start time in OS ticks */ - uint32_t nol_timeout_ms; /* NOL timeout value in msec */ - os_timer_t nol_timer; /* per element NOL timer */ - struct dfs_nolelem *nol_next; /* next element pointer */ -}; -#ifdef WIN32 -#pragma pack(pop, dfs_nolelem) -#endif - -/* Pass structure to DFS NOL timer */ -struct dfs_nol_timer_arg { - struct ath_dfs *dfs; - uint16_t delfreq; - uint16_t delchwidth; -}; - -#ifdef WIN32 -#pragma pack(push, dfs_info, 1) -#endif -struct dfs_info { - /* Use the NOL when radar found (default: true) */ - int rn_use_nol; - /* Number of different types of radars */ - uint32_t rn_numradars; - /* Last 64 bit timstamp from recv interrupt */ - uint64_t rn_lastfull_ts; - /* last 15 bit ts from recv descriptor */ - uint16_t rn_last_ts; - /* last unique 32 bit ts from recv descriptor */ - uint32_t rn_last_unique_ts; - /* Prefix to prepend to 15 bit recv ts */ - uint64_t rn_ts_prefix; - /* Number of bin5 radar pulses to search for */ - uint32_t rn_numbin5radars; - /* Value of fast diversity gc limit from init file */ - uint32_t rn_fastdivGCval; - /* Min rssi for all radar types */ - int32_t rn_minrssithresh; - /* Max pulse width in TSF ticks */ - 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; - uint8_t dfs_last_bin5_dur_ext_seg; -} qdf_packed; -#ifdef WIN32 -#pragma pack(pop, dfs_info) -#endif - -struct dfs_bin5elem { - uint64_t be_ts; /* Timestamp for the bin5 element */ - uint32_t be_rssi; /* Rssi for the bin5 element */ - uint32_t be_dur; /* Duration of bin5 element */ -}; - -struct dfs_bin5radars { - /* List of bin5 elems that fall within the time window */ - struct dfs_bin5elem br_elems[DFS_MAX_B5_SIZE]; - /* Index of the first element */ - uint32_t br_firstelem; - /* Index of the last element */ - uint32_t br_lastelem; - /* Number of elements in the delay line */ - uint32_t br_numelems; - /* Original info about bin5 pulse */ - struct dfs_bin5pulse br_pulse; -}; - -struct dfs_stats { - uint32_t num_radar_detects; /* total num. of 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; -}; - -/* - * This is for debuggin DFS as console log interferes with (helps) - * radar detection - */ - -#define DFS_EVENT_LOG_SIZE 256 -struct dfs_event_log { - uint64_t ts; /* 64-bit full timestamp from interrupt time */ - uint32_t diff_ts; /* diff timestamp */ - uint8_t rssi; /* rssi of radar event */ - uint8_t dur; /* duration of radar pulse */ -}; - -#define ATH_DFS_RESET_TIME_S 7 -#define ATH_DFS_WAIT (60 + ATH_DFS_RESET_TIME_S) /* 60 seconds */ -#define ATH_DFS_WAIT_MS ((ATH_DFS_WAIT) * 1000) /*in MS */ - -#define ATH_DFS_WEATHER_CHANNEL_WAIT_MIN 10 /*10 minutes */ -#define ATH_DFS_WEATHER_CHANNEL_WAIT_S (ATH_DFS_WEATHER_CHANNEL_WAIT_MIN * 60) -#define ATH_DFS_WEATHER_CHANNEL_WAIT_MS \ - ((ATH_DFS_WEATHER_CHANNEL_WAIT_S) * 1000) /*in MS */ - -#define ATH_DFS_WAIT_POLL_PERIOD 2 /* 2 seconds */ -/*in MS */ -#define ATH_DFS_WAIT_POLL_PERIOD_MS ((ATH_DFS_WAIT_POLL_PERIOD) * 1000) -#define ATH_DFS_TEST_RETURN_PERIOD 2 /* 2 seconds */ -/* n MS */ -#define ATH_DFS_TEST_RETURN_PERIOD_MS ((ATH_DFS_TEST_RETURN_PERIOD) * 1000) -#define IS_CHANNEL_WEATHER_RADAR(chan) ((chan->ic_freq >= 5600) && \ - (chan->ic_freq <= 5650)) - -#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 ath_dfs { - uint32_t dfs_debug_mask; /* current debug bitmask */ - int16_t dfs_curchan_radindex; /* cur. channel radar index */ - int16_t dfs_extchan_radindex; /* extension channel radar index */ - uint32_t dfsdomain; /* cur. DFS domain */ - uint32_t dfs_proc_phyerr; /* Flags for Phy Errs to process */ - struct ieee80211com *ic; - STAILQ_HEAD(, dfs_event) dfs_eventq; /* Q of free dfs event objects */ - dfsq_lock_t dfs_eventqlock; /* Lock for free dfs event list */ - STAILQ_HEAD(, dfs_event) dfs_radarq; /* Q of radar events */ - dfsq_lock_t dfs_radarqlock; /* Lock for dfs q */ - STAILQ_HEAD(, dfs_event) dfs_arq; /* Q of AR events */ - dfsq_lock_t dfs_arqlock; /* Lock for AR q */ - - struct dfs_ar_state dfs_ar_state; /* AR state */ - - /* dfs_radar - Per-Channel Radar detector state */ - struct dfs_state dfs_radar[DFS_NUM_RADAR_STATES]; - - /* dfs_radarf - One filter for each radar pulse type */ - struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES]; - - struct dfs_info dfs_rinfo; /* State vars for radar processing */ - struct dfs_bin5radars *dfs_b5radars; /* array of bin5 radar events */ - /* array of bin5 radar events on extension segment in 80p80 */ - struct dfs_bin5radars *dfs_b5radars_ext_seg; - int8_t **dfs_radartable; /* map of radar durs to filter types */ -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - struct dfs_nolelem *dfs_nol; /* Non occupancy list for radar */ - int dfs_nol_count; /* How many items? */ -#endif - /* Default phy params per radar state */ - struct ath_dfs_phyerr_param dfs_defaultparams; - struct dfs_stats ath_dfs_stats; /* DFS related stats */ - struct dfs_pulseline *pulses; /* pulse history */ - struct dfs_pulseline *pulses_ext_seg; /* pulse history ext 80p80 seg */ - struct dfs_event *events; /* Events structure */ - - uint32_t ath_radar_tasksched:1, /* radar task is scheduled */ - ath_dfswait:1, /* waiting on channel for radar detect */ - ath_dfstest:1; /* Test timer in progress */ - struct ath_dfs_caps dfs_caps; - /* IEEE chan num to return to after - * a dfs mute test - */ - uint8_t ath_dfstest_ieeechan; -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - uint32_t ath_dfs_cac_time; /* CAC period */ - uint32_t ath_dfstesttime; /* Time to stay off chan during dfs test */ - os_timer_t ath_dfswaittimer; /* dfs wait timer */ - os_timer_t ath_dfstesttimer; /* dfs mute test timer */ - os_timer_t ath_dfs_debug_timer; /* dfs debug timer */ - uint8_t dfs_bangradar; -#endif - os_timer_t ath_dfs_task_timer; /* dfs wait timer */ - int dur_multiplier; - - uint16_t ath_dfs_isdfsregdomain; /* true when we are DFS domain */ - int ath_dfs_false_rssi_thres; - int ath_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; /* same as number of PHY radar interrupts */ - /* - * when TLV is supported, # of radar events ignored after TLV is parsed - */ - int dfs_phyerr_reject_count; - /* number of radar events queued for matching the filters */ - int dfs_phyerr_queued_count; - int dfs_phyerr_freq_min; - int dfs_phyerr_freq_max; - int dfs_phyerr_w53_counter; - /* allow pulse if they are within multiple of PRI for the radar type */ - int dfs_pri_multiplier; - int ath_dfs_nol_timeout; - int dfs_pri_multiplier_ini; /* dfs pri configuration from ini */ - /* - * Flag to indicate if DFS test mode is enabled and - * channel switch is disabled. - */ - int8_t disable_dfs_ch_switch; - uint32_t test_ts; /* to capture timestamps on primary segment */ - uint32_t test_ts_ext_seg; /* to capture timestamps on ext segment */ -}; - -/* This should match the table from if_ath.c */ -enum { - ATH_DEBUG_DFS = 0x00000100, /* Minimal DFS debug */ - ATH_DEBUG_DFS1 = 0x00000200, /* Normal DFS debug */ - ATH_DEBUG_DFS2 = 0x00000400, /* Maximal DFS debug */ - ATH_DEBUG_DFS3 = 0x00000800, /* matched filterID display */ - - ATH_DEBUG_DFS_PHYERR = 0x00001000, /* phy error parsing */ - ATH_DEBUG_DFS_NOL = 0x00002000, /* NOL related entries */ - ATH_DEBUG_DFS_PHYERR_SUM = 0x00004000, /* PHY error summary */ - ATH_DEBUG_DFS_PHYERR_PKT = 0x00008000, /* PHY error payload */ - - ATH_DEBUG_DFS_BIN5 = 0x00010000, /* bin5 checks */ - ATH_DEBUG_DFS_BIN5_FFT = 0x00020000, /* bin5 FFT check */ - ATH_DEBUG_DFS_BIN5_PULSE = 0x00040000, /* bin5 pulse check */ -}; - -#define IS_CHAN_HT40(_c) IEEE80211_IS_CHAN_11N_HT40(_c) -#define IS_CHAN_HT40_PLUS(_c) IEEE80211_IS_CHAN_11N_HT40PLUS(_c) -#define IS_CHAN_HT40_MINUS(_c) IEEE80211_IS_CHAN_11N_HT40MINUS(_c) - -/* - * 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: - * - * + 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. - * - * + For chips that do hardware chirp detection or FFT, the "do_check_chirp" - * bit should be set. - * - * + 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. - * - * + 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: - * - * + add duration in uS and raw duration, so the PHY error parsing - * code is responsible for doing the duration calculation; - * + 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; /* 64-bit TSF as read from MAC */ - - uint32_t is_pri:1, /* detected on primary channel */ - is_ext:1, /* detected on extension channel */ - is_dc:1, /* detected at DC */ - is_early:1, /* early detect */ - do_check_chirp:1, /* whether to check hw_chirp/sw_chirp */ - is_hw_chirp:1, /* hardware-detected chirp */ - is_sw_chirp:1; /* software detected chirp */ - - uint32_t rs_tstamp; /* 32 bit TSF from RX descriptor (event) */ - uint32_t freq; /* Centre frequency of event - KHz */ - uint32_t freq_lo; /* Lower bounds of frequency - KHz */ - uint32_t freq_hi; /* Upper bounds of frequency - KHz */ - - uint8_t rssi; /* pulse RSSI */ - uint8_t dur; /* pulse duration, raw (not uS) */ - int sidx; /* Pulse Index as in radar summary report */ - /* - * Indicates segment ID on which the phyerror is received - * when SAP is operating in 80p80 channel width. - */ - int radar_80p80_segid; - /* delta peak reported in radar summary */ - int delta_peak; - /* delta diff reported in radar summary */ - int delta_diff; - /* agc total gain reported in radar summary */ - int agc_total_gain; - /* agc mb gain reported in radar summary */ - int agc_mb_gain; - /* subchan mask reported in radar summary */ - int radar_subchan_mask; - /* pulse height reported in radar summary */ - int pulse_height; - /* triggering agc reported in radar summary */ - int triggering_agc_event; - /* rssi of phyerr reported in radar summary */ - int pulse_rssi; - /* Pri80MHz pwr reported in summary */ - int radar_fft_pri80_inband_power; - /* Ext80MHz pwr reported in summary */ - int radar_fft_ext80_inband_power; - /* Peak mag reported in radar search FFT report */ - int peak_mag; - /* Radar summary report version */ - int rsu_version; -}; - -/* Attach, detach, handle ioctl prototypes */ - -int dfs_get_thresholds(struct ieee80211com *ic, - struct ath_dfs_phyerr_param *param); -int dfs_set_thresholds(struct ieee80211com *ic, - const uint32_t threshtype, const uint32_t value); - -/* PHY error and radar event handling */ -int dfs_process_radarevent(struct ath_dfs *dfs, - struct dfs_ieee80211_channel *chan); - -/* Non occupancy (NOL) handling prototypes */ -void dfs_nol_addchan(struct ath_dfs *dfs, struct dfs_ieee80211_channel *chan, - uint32_t dfs_nol_timeout); -void dfs_get_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, - int *nchan); -void dfs_set_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, - int nchan); -void dfs_nol_update(struct ath_dfs *dfs); -void dfs_nol_timer_cleanup(struct ath_dfs *dfs); - -/* FCC Bin5 detection prototypes */ -int dfs_bin5_check_pulse(struct ath_dfs *dfs, struct dfs_event *re, - struct dfs_bin5radars *br); -int dfs_bin5_addpulse(struct ath_dfs *dfs, struct dfs_bin5radars *br, - struct dfs_event *re, uint64_t thists); -int dfs_bin5_check(struct ath_dfs *dfs, int seg_id); -int dfs_check_chirping(struct ath_dfs *dfs, void *buf, - uint16_t datalen, int is_ctl, - int is_ext, int *slope, int *is_dc); -uint8_t dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, uint32_t diff_ts, - uint8_t old_dur, int seg_id); -uint8_t dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, uint32_t diff_ts, - uint8_t old_dur, int seg_id); -int dfs_get_random_bin5_dur(struct ath_dfs *dfs, uint64_t tstamp); - -/* Debug prototypes */ -void dfs_print_delayline(struct ath_dfs *dfs, struct dfs_delayline *dl); -void dfs_print_nol(struct ath_dfs *dfs); -void dfs_print_filters(struct ath_dfs *dfs); -void dfs_print_activity(struct ath_dfs *dfs); -os_timer_func(dfs_debug_timeout); -void dfs_print_filter(struct ath_dfs *dfs, struct dfs_filter *rf); - -/* Misc prototypes */ -uint32_t dfs_round(int32_t val); -struct dfs_state *dfs_getchanstate(struct ath_dfs *dfs, uint8_t *index, - int ext_ch_flag); - -/* Reset and init data structures */ - -int dfs_init_radar_filters(struct ieee80211com *ic, - struct ath_dfs_radar_tab_info *radar_info); -void dfs_reset_alldelaylines(struct ath_dfs *dfs, int seg_id); -void dfs_reset_delayline(struct dfs_delayline *dl); -void dfs_reset_radarq(struct ath_dfs *dfs); - -/* Detection algorithm prototypes */ -void dfs_add_pulse(struct ath_dfs *dfs, struct dfs_filter *rf, - struct dfs_event *re, uint32_t deltaT, uint64_t this_ts, - int seg_id); - -int dfs_bin_fixedpattern_check(struct ath_dfs *dfs, struct dfs_filter *rf, - uint32_t dur, int ext_chan_flag, int seg_id); -int dfs_bin_check(struct ath_dfs *dfs, struct dfs_filter *rf, - uint32_t deltaT, uint32_t dur, int ext_chan_flag, int seg_id); - -int dfs_bin_pri_check(struct ath_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); -int dfs_staggered_check(struct ath_dfs *dfs, struct dfs_filter *rf, - uint32_t deltaT, uint32_t width, int seg_id); -/* False detection reduction */ -int dfs_get_pri_margin(struct ath_dfs *dfs, int is_extchan_detect, - int is_fixed_pattern); -int dfs_get_filter_threshold(struct ath_dfs *dfs, struct dfs_filter *rf, - int is_extchan_detect); - -/* AR related prototypes */ - -/* Commenting out since all the ar functions are obsolete and - * the function definition has been removed as part of dfs_ar.c - * void dfs_process_ar_event(struct ath_dfs *dfs, - * struct dfs_ieee80211_channel *chan); - */ -/* Commenting out since all the ar functions are obsolete and - * the function definition has been removed as part of dfs_ar.c - * void ath_ar_disable(struct ath_dfs *dfs); - */ -/* Commenting out since all the ar functions are obsolete and - * the function definition has been removed as part of dfs_ar.c - * void ath_ar_enable(struct ath_dfs *dfs); - */ -void dfs_reset_ar(struct ath_dfs *dfs); -/* Commenting out since all the ar functions are obsolete and - * the function definition has been removed as part of dfs_ar.c - * void dfs_reset_arq(struct ath_dfs *dfs); - */ - -struct dfs_ieee80211_channel *ieee80211_get_extchan(struct ieee80211com *ic); - -#endif /* _DFS_H_ */ diff --git a/core/sap/dfs/inc/dfs_interface.h b/core/sap/dfs/inc/dfs_interface.h deleted file mode 100644 index e0bbf90bf285..000000000000 --- a/core/sap/dfs/inc/dfs_interface.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_interface.h - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -#ifndef _DFS__INTERFACE_H_ -#define _DFS__INTERFACE_H_ - -/* - * These are the only functions exported to the upper (device) layer. - */ - -/* - * EXPORT_SYMBOL(dfs_attach); - * EXPORT_SYMBOL(dfs_detach); - * EXPORT_SYMBOL(dfs_radar_enable); - * EXPORT_SYMBOL(dfs_process_phyerr); - * EXPORT_SYMBOL(dfs_control); - * EXPORT_SYMBOL(dfs_clear_stats); - * EXPORT_SYMBOL(dfs_usenol); - * EXPORT_SYMBOL(dfs_isdfsregdomain); - */ - -/* - * These are exported but not currently defined here; these should be - * evaluated. - * - * EXPORT_SYMBOL(dfs_process_ar_event); -- legacy adaptive radio processing - * EXPORT_SYMBOL(ath_ar_disable); - * EXPORT_SYMBOL(ath_ar_enable); - * EXPORT_SYMBOL(dfs_get_thresholds); - * EXPORT_SYMBOL(dfs_init_radar_filters); - * EXPORT_SYMBOL(dfs_getchanstate); - */ -uint16_t dfs_usenol(struct ieee80211com *ic); -uint16_t dfs_isdfsregdomain(struct ieee80211com *ic); -int dfs_attach(struct ieee80211com *ic); -void dfs_detach(struct ieee80211com *ic); -int dfs_radar_enable(struct ieee80211com *ic, - struct ath_dfs_radar_tab_info *ri); -int dfs_radar_disable(struct ieee80211com *ic); -extern void dfs_process_phyerr(struct ieee80211com *ic, void *buf, - uint16_t datalen, uint8_t rssi, uint8_t ext_rssi, - uint32_t rs_tstamp, uint64_t fulltsf, - bool enable_log); -int dfs_control(struct ieee80211com *ic, u_int id, void *indata, - uint32_t insize, void *outdata, uint32_t *outsize); -void dfs_clear_stats(struct ieee80211com *ic); -#if 0 -/* The following are for FCC Bin 1-4 pulses */ -struct dfs_pulse dfs_fcc_radars[] = { - /* FCC TYPE 1 */ - /* {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, - {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, - - /* FCC TYPE 6 */ - /* {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us */ - {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, - - /* FCC TYPE 2 */ - {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2}, - - /* FCC TYPE 3 */ - {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5}, - - /* FCC TYPE 4 */ - {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11}, -}; - -struct dfs_pulse dfs_mkk4_radars[] = { - /* following two filters are specific to Japan/MKK4 */ -/* {18, 1, 720, 720, 1, 6, 6, 0, 1, 18, 0, 3, 17}, // 1389 +/- 6 us */ -/* {18, 4, 250, 250, 1, 10, 5, 1, 6, 18, 0, 3, 18}, // 4000 +/- 6 us */ -/* {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 19}, // 3846 +/- 7 us */ - {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, /* 1389 +/- 6 us */ - {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, /* 4000 +/- 6 us */ - {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, /* 3846 +/- 7 us */ - - /* following filters are common to both FCC and JAPAN */ - - /* FCC TYPE 1 */ - /* {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, - {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, - - /* FCC TYPE 6 */ - /* {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us */ - {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, - - /* FCC TYPE 2 */ - {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2}, - - /* FCC TYPE 3 */ - {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5}, - - /* FCC TYPE 4 */ - {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11}, -}; - -struct dfs_bin5pulse dfs_fcc_bin5pulses[] = { - {4, 28, 105, 12, 22, 5}, -}; - -struct dfs_bin5pulse dfs_jpn_bin5pulses[] = { - {5, 28, 105, 12, 22, 5}, -}; - -struct dfs_pulse dfs_etsi_radars[] = { - - /* TYPE staggered pulse */ - /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ - {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, /* Type 5 */ - /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */ - {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, /* Type 6 */ - - /* constant PRF based */ - /* 0.8-5us, 200 300 PRF, 10 pulses */ - {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, /* Type 1 */ - {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, /* Type 1 */ - {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, /* Type 1 */ - {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, /* Type 1 */ -/* {10, 5, 200, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, */ - - /* 0.8-15us, 200-1600 PRF, 15 pulses */ - {15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 34}, /* Type 2 */ - - /* 0.8-15us, 2300-4000 PRF, 25 pulses */ - {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 35}, /* Type 3 */ - - /* 20-30us, 2000-4000 PRF, 20 pulses */ - {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 36}, /* Type 4 */ -}; -#endif -#endif /* _DFS__INTERFACE_H_ */ diff --git a/core/sap/dfs/inc/radar_filters.h b/core/sap/dfs/inc/radar_filters.h deleted file mode 100644 index 0d1b6563ea50..000000000000 --- a/core/sap/dfs/inc/radar_filters.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - radar_filters.h - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -struct dfs_pulse dfs_fcc_radars[] = { - /* FCC NEW TYPE 0 */ - /* {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, - {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, - - /* FCC TYPE 6 */ - /* {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us */ - {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, - - /* FCC TYPE 2 */ - {23, 5, 4347, 6666, 0, 18, 8, 0, 7, 22, 0, 3, 0, 2}, - - /* FCC TYPE 3 */ - {18, 10, 2000, 5000, 0, 23, 6, 6, 13, 22, 0, 3, 0, 5}, - - /* FCC TYPE 4 */ - {16, 15, 2000, 5000, 0, 25, 5, 11, 23, 22, 0, 3, 0, 11}, - - /* - * FCC NEW TYPE 1 - * 518us to 938us pulses (min 56 pulses) - */ - {57, 1, 1066, 1930, 0, 6, 20, 0, 1, 22, 0, 3, 0, 21}, - - /* - * FCC NEW TYPE 1 - * 938us to 2000 pulses (min 26 pulses) - */ - {27, 1, 500, 1066, 0, 6, 13, 0, 1, 22, 0, 3, 0, 22}, - - /* - * FCC NEW TYPE 1 - * 2000 to 3067us pulses (min 17 pulses) - */ - {18, 1, 325, 500, 0, 6, 9, 0, 1, 22, 0, 3, 0, 23}, -}; - -struct dfs_pulse dfs_mkk4_radars[] = { - /* following two filters are specific to Japan/MKK4 */ -/* {18, 1, 720, 720, 1, 6, 6, 0, 1, 18, 0, 3, 17}, // 1389 +/- 6 us */ -/* {18, 4, 250, 250, 1, 10, 5, 1, 6, 18, 0, 3, 18}, // 4000 +/- 6 us */ -/* {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 19}, // 3846 +/- 7 us */ - {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, /* 1389 +/- 6 us */ - {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, /* 4000 +/- 6 us */ - {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, /* 3846 +/- 7 us */ - - /* following filters are common to both FCC and JAPAN */ - - /* FCC TYPE 1 */ - /* {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, - {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, - - /* FCC TYPE 6 */ - /* {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us */ - {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, - - /* FCC TYPE 2 */ - {23, 5, 4347, 6666, 0, 18, 8, 0, 7, 22, 0, 3, 0, 2}, - - /* FCC TYPE 3 */ - {18, 10, 2000, 5000, 0, 23, 6, 6, 13, 22, 0, 3, 0, 5}, - - /* FCC TYPE 4 */ - {16, 15, 2000, 5000, 0, 25, 5, 11, 23, 22, 0, 3, 0, 11}, -}; - -struct dfs_bin5pulse dfs_fcc_bin5pulses[] = { - {4, 28, 105, 12, 17, 5}, -}; - -struct dfs_bin5pulse dfs_jpn_bin5pulses[] = { - {5, 28, 105, 12, 22, 5}, -}; - -struct dfs_pulse dfs_etsi_radars[] = { - - /* TYPE staggered pulse */ - /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ - {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, /* Type 5 */ - /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */ - {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, /* Type 6 */ - - /* constant PRF based */ - /* 0.8-5us, 200 300 PRF, 10 pulses */ - {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, /* Type 1 */ - {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, /* Type 1 */ - {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, /* Type 1 */ - {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, /* Type 1 */ -/* {10, 5, 200, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, */ - - /* 0.8-15us, 200-1600 PRF, 15 pulses */ - {15, 15, 200, 1600, 0, 24, 8, 0, 18, 22, 0, 0, 0, 34}, /* Type 2 */ - - /* 0.8-15us, 2300-4000 PRF, 25 pulses */ - {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 22, 0, 0, 0, 35}, /* Type 3 */ - - /* 20-30us, 2000-4000 PRF, 20 pulses */ - {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 36}, /* Type 4 */ -}; - -struct dfs_pulse dfs_korea_radars[] = { - /* Korea Type 1 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 40}, - - /* Korea Type 2 */ - {10, 1, 1800, 1800, 0, 6, 4, 0, 1, 18, 0, 3, 1, 41}, - - /* Korea Type 3 */ - {70, 1, 330, 330, 0, 6, 20, 0, 2, 18, 0, 3, 1, 42}, - - /* Korea Type 4 */ - {3, 1, 3003, 3003, 1, 7, 2, 0, 1, 18, 0, 0, 1, 43}, -}; - -struct dfs_pulse dfs_china_radars[] = { - /* FCC NEW TYPE 0 */ - {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, - {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, - - /* FCC TYPE 6 */ - { 9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, - - /* FCC TYPE 2 */ - {23, 5, 4347, 6666, 0, 18, 8, 0, 7, 22, 0, 3, 0, 2}, - - /* FCC TYPE 3 */ - {18, 10, 2000, 5000, 0, 23, 6, 6, 13, 22, 0, 3, 0, 5}, - - /* FCC TYPE 4 */ - {16, 15, 2000, 5000, 0, 25, 5, 11, 23, 22, 0, 3, 0, 11}, - - /* - * FCC NEW TYPE 1 - * 518us to 938us pulses (min 56 pulses) - */ - {57, 1, 1066, 1930, 0, 6, 20, 0, 1, 22, 0, 3, 0, 21}, - - /* - * FCC NEW TYPE 1 - * 938us to 2000 pulses (min 26 pulses) - */ - {27, 1, 500, 1066, 0, 6, 13, 0, 1, 22, 0, 3, 0, 22}, - - /* - * FCC NEW TYPE 1 - * 2000 to 3067us pulses (min 17 pulses) - */ - {18, 1, 325, 500, 0, 6, 9, 0, 1, 22, 0, 3, 0, 23}, - - /* CN TYPE 1 */ - {20, 1, 1000, 1000, 0, 6, 5, 0, 1, 18, 0, 3, 1, 24}, -}; diff --git a/core/sap/dfs/sources b/core/sap/dfs/sources deleted file mode 100644 index 3899f4156c92..000000000000 --- a/core/sap/dfs/sources +++ /dev/null @@ -1,62 +0,0 @@ -# -# sources file for DFS module -# -LMAC=.. -TOP=$(LMAC)\.. -INC=$(TOP)\include -HAL=$(TOP)\hal -ATH=$(LMAC)\ath_dev - -!IFDEF BUILD_UMAC -MP=$(TOP)\os\win_nwf -INC_MP=$(MP)\include -IF_ATH=$(TOP)\umac\if_lmac -!ELSE -MP=$(TOP)\winvista -INC_MP=$(INC)\winvista -IF_ATH=$(TOP)\if_ath_net80211 -!ENDIF - -!include $(INC_MP)\sources.inc - -TARGETNAME=ath_dfs -TARGETPATH=$(TOP)\lib -TARGETTYPE=LIBRARY - -!IFDEF BUILD_HTC -# Put htc include dirs at the head of the list. -# This ensures that the htc/cdf header files will preempt any -# header files of the same names from the regular cdf directories. -INCLUDES= $(INCLUDES) \ - $(TOP)\htc\inc; \ - $(TOP)\htc\adf\include; \ - $(TOP)\htc\adf\winvista\nbuf; \ - $(TOP)\htc\adf\winvista\include; -!ENDIF - -INCLUDES= $(INCLUDES) \ - $(TOP); \ - $(ATH); \ - $(ATH_DFS); \ - $(TOP)\ath\winvista; \ - $(TOP)\ath\winvista; \ - $(HAL); \ - $(HAL)\winvista; \ - $(IF_ATH); \ - $(INC); \ - $(INC_MP); \ - $(SDXROOT)\net\inc; \ - $(DDK_INC_PATH) - -SOURCES=$(SOURCES) \ - dfs_staggered.c \ - dfs_bindetects.c \ - dfs_misc.c \ - dfs_debug.c \ - dfs_process_radarevent.c \ - dfs_process_phyerr.c \ - dfs_nol.c \ - dfs_ar.c \ - dfs_fcc_bin5.c \ - dfs_init.c \ - dfs.c diff --git a/core/sap/dfs/src/dfs.c b/core/sap/dfs/src/dfs.c deleted file mode 100644 index aa2506b5f1d7..000000000000 --- a/core/sap/dfs/src/dfs.c +++ /dev/null @@ -1,1124 +0,0 @@ -/* - * Copyright (c) 2002-2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs.c - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#include - -#ifndef ATH_SUPPORT_DFS -#define ATH_SUPPORT_DFS 1 - -/* #include "if_athioctl.h" */ -/* #include "if_athvar.h" */ -#include "dfs_ioctl.h" -#include "dfs.h" - -int domainoverride = DFS_UNINIT_REG; - -/* -** channel switch announcement (CSA) -** usenol=1 (default) make CSA and switch to a new channel on radar detect -** usenol=0, make CSA with next channel same as current on radar detect -** usenol=2, no CSA and stay on the same channel on radar detect -**/ - -int usenol = 1; -uint32_t dfs_debug_level = ATH_DEBUG_DFS; - -#if 0 /* the code to call this is curently commented-out below */ -/* - * Mark a channel as having interference detected upon it. - * - * This adds the interference marker to both the primary and - * extension channel. - * - * XXX TODO: make the NOL and channel interference logic a bit smarter - * so only the channel with the radar event is marked, rather than - * both the primary and extension. - */ -static void -dfs_channel_mark_radar(struct ath_dfs *dfs, struct dfs_ieee80211_channel *chan) -{ - struct ieee80211_channel_list chan_info; - int i; - - /* chan->ic_flagext |= CHANNEL_INTERFERENCE; */ - - /* - * If radar is detected in 40MHz mode, add both the primary and the - * extension channels to the NOL. chan is the channel data we return - * to the ath_dev layer which passes it on to the 80211 layer. - * As we want the AP to change channels and send out a CSA, - * we always pass back the primary channel data to the ath_dev layer. - */ - if ((dfs->dfs_rinfo.rn_use_nol == 1) && - (dfs->ic->ic_opmode == IEEE80211_M_HOSTAP || - dfs->ic->ic_opmode == IEEE80211_M_IBSS)) { - chan_info.cl_nchans = 0; - dfs->ic->ic_get_ext_chan_info(dfs->ic, &chan_info); - - for (i = 0; i < chan_info.cl_nchans; i++) { - if (chan_info.cl_channels[i] == NULL) { - DFS_PRINTK("%s: NULL channel\n", __func__); - } else { - chan_info.cl_channels[i]->ic_flagext |= - CHANNEL_INTERFERENCE; - dfs_nol_addchan(dfs, chan_info.cl_channels[i], - dfs->ath_dfs_nol_timeout); - } - } - - /* - * Update the umac/driver channels with the new NOL information. - */ - dfs_nol_update(dfs); - } -} -#endif /* #if 0 */ - -static os_timer_func(dfs_task) -{ - struct ieee80211com *ic; - struct ath_dfs *dfs = NULL; - - OS_GET_TIMER_ARG(ic, struct ieee80211com *); - dfs = (struct ath_dfs *)ic->ic_dfs; - /* - * XXX no locking?! - */ - if (dfs_process_radarevent(dfs, ic->ic_curchan)) { -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - - /* - * 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. - */ - - if (dfs->dfs_rinfo.rn_use_nol == 1) { - /* dfs_channel_mark_radar(dfs, ic->ic_curchan); */ - } -#endif /* ATH_DFS_RADAR_DETECTION_ONLY */ - - /* - * This calls into the umac DFS code, which sets the umac related - * radar flags and begins the channel change machinery. - * - * XXX TODO: the umac NOL code isn't used, but IEEE80211_CHAN_RADAR - * still gets set. Since the umac NOL code isn't used, that flag - * is never cleared. This needs to be fixed. See EV 105776. - */ - if (dfs->dfs_rinfo.rn_use_nol == 1) { - ic->ic_dfs_notify_radar(ic, ic->ic_curchan); - } else if (dfs->dfs_rinfo.rn_use_nol == 0) { - /* - * For the test mode, don't do a CSA here; but setup the - * test timer so we get a CSA _back_ to the original channel. - */ - OS_CANCEL_TIMER(&dfs->ath_dfstesttimer); - dfs->ath_dfstest = 1; - qdf_spin_lock_bh(&ic->chan_lock); - dfs->ath_dfstest_ieeechan = ic->ic_curchan->ic_ieee; - qdf_spin_unlock_bh(&ic->chan_lock); - dfs->ath_dfstesttime = 1; /* 1ms */ - OS_SET_TIMER(&dfs->ath_dfstesttimer, - dfs->ath_dfstesttime); - } - } - dfs->ath_radar_tasksched = 0; -} - -static os_timer_func(dfs_testtimer_task) -{ - struct ieee80211com *ic; - struct ath_dfs *dfs = NULL; - - OS_GET_TIMER_ARG(ic, struct ieee80211com *); - dfs = (struct ath_dfs *)ic->ic_dfs; - - /* XXX no locking? */ - dfs->ath_dfstest = 0; - - /* - * Flip the channel back to the original channel. - * Make sure this is done properly with a CSA. - */ - DFS_PRINTK("%s: go back to channel %d\n", - __func__, dfs->ath_dfstest_ieeechan); - - /* - * XXX The mere existence of this method indirection - * to a umac function means this code belongs in - * the driver, _not_ here. Please fix this! - */ - ic->ic_start_csa(ic, dfs->ath_dfstest_ieeechan); -} - -static int dfs_get_debug_info(struct ieee80211com *ic, int type, void *data) -{ - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - - if (data) { - *(uint32_t *) data = dfs->dfs_proc_phyerr; - } - return (int)dfs->dfs_proc_phyerr; -} - -/** - * dfs_alloc_mem_filter() - allocate memory for dfs ft_filters - * @radarf: pointer holding ft_filters - * - * Return: 0-success and 1-failure -*/ -static int dfs_alloc_mem_filter(struct dfs_filtertype *radarf) -{ - int status = 0, n, i; - - for (i = 0; i < DFS_MAX_NUM_RADAR_FILTERS; i++) { - radarf->ft_filters[i] = qdf_mem_malloc(sizeof(struct - dfs_filter)); - if (NULL == radarf->ft_filters[i]) { - DFS_PRINTK("%s[%d]: mem alloc failed\n", - __func__, __LINE__); - status = 1; - goto error; - } - } - - return status; - -error: - /* free up allocated memory */ - for (n = 0; n < i; n++) { - if (radarf->ft_filters[n]) { - qdf_mem_free(radarf->ft_filters[n]); - radarf->ft_filters[i] = NULL; - } - } - - DFS_PRINTK("%s[%d]: cannot allocate memory for radar filter types\n", - __func__, __LINE__); - - return status; -} - -/** - * dfs_free_filter() - free memory allocated for dfs ft_filters - * @radarf: pointer holding ft_filters - * - * Return: NA -*/ -static void dfs_free_filter(struct dfs_filtertype *radarf) -{ - int i; - - for (i = 0; i < DFS_MAX_NUM_RADAR_FILTERS; i++) { - if (radarf->ft_filters[i]) { - qdf_mem_free(radarf->ft_filters[i]); - radarf->ft_filters[i] = NULL; - } - } -} - -int dfs_attach(struct ieee80211com *ic) -{ - int i, n; - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - struct ath_dfs_radar_tab_info radar_info; - - if (dfs != NULL) { - /*DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "%s: ic_dfs was not NULL\n", - __func__); - */ - return 1; - } - - dfs = (struct ath_dfs *)os_malloc(NULL, sizeof(struct ath_dfs), - GFP_ATOMIC); - - if (dfs == NULL) { - /*DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "%s: ath_dfs allocation failed\n", __func__); */ - return 1; - } - - OS_MEMZERO(dfs, sizeof(struct ath_dfs)); - - ic->ic_dfs = (void *)dfs; - - dfs->ic = ic; - - ic->ic_dfs_debug = dfs_get_debug_info; -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - dfs->dfs_nol = NULL; -#endif - - /* - * Zero out radar_info. It's possible that the attach function won't - * fetch an initial regulatory configuration; you really do want to - * ensure that the contents indicates there aren't any filters. - */ - OS_MEMZERO(&radar_info, sizeof(radar_info)); - ic->ic_dfs_attach(ic, &dfs->dfs_caps, &radar_info); - dfs_clear_stats(ic); - dfs->dfs_event_log_on = 0; - OS_INIT_TIMER(NULL, &(dfs->ath_dfs_task_timer), dfs_task, (void *)(ic), - QDF_TIMER_TYPE_SW); -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - OS_INIT_TIMER(NULL, &(dfs->ath_dfstesttimer), dfs_testtimer_task, - (void *)ic, QDF_TIMER_TYPE_SW); - dfs->ath_dfs_cac_time = ATH_DFS_WAIT_MS; - dfs->ath_dfstesttime = ATH_DFS_TEST_RETURN_PERIOD_MS; -#endif - ATH_DFSQ_LOCK_INIT(dfs); - STAILQ_INIT(&dfs->dfs_radarq); - ATH_ARQ_LOCK_INIT(dfs); - STAILQ_INIT(&dfs->dfs_arq); - STAILQ_INIT(&(dfs->dfs_eventq)); - ATH_DFSEVENTQ_LOCK_INIT(dfs); - dfs->events = (struct dfs_event *)os_malloc(NULL, - sizeof(struct dfs_event) * - DFS_MAX_EVENTS, GFP_ATOMIC); - if (dfs->events == NULL) { - OS_FREE(dfs); - ic->ic_dfs = NULL; - DFS_PRINTK("%s: events allocation failed\n", __func__); - return 1; - } - for (i = 0; i < DFS_MAX_EVENTS; i++) { - STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), &dfs->events[i], - re_list); - } - - dfs->pulses = - (struct dfs_pulseline *)os_malloc(NULL, - sizeof(struct dfs_pulseline), - GFP_ATOMIC); - if (dfs->pulses == NULL) { - OS_FREE(dfs->events); - dfs->events = NULL; - OS_FREE(dfs); - ic->ic_dfs = NULL; - DFS_PRINTK("%s: pulse buffer allocation failed\n", __func__); - return 1; - } - - /* - * If the chip supports DFS-3 then allocate - * memory for pulses for extension segment. - */ - if (ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) { - dfs->pulses_ext_seg = (struct dfs_pulseline *) - os_malloc(NULL, - sizeof(struct dfs_pulseline), - GFP_ATOMIC); - if (dfs->pulses_ext_seg == NULL) { - OS_FREE(dfs->events); - dfs->events = NULL; - OS_FREE(dfs); - ic->ic_dfs = NULL; - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s[%d]: pulse buffer allocation failed", - __func__, __LINE__); - return 1; - } - dfs->pulses_ext_seg->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK; - } - - dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK; - - /* Allocate memory for radar filters */ - for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) { - dfs->dfs_radarf[n] = (struct dfs_filtertype *) - os_malloc(NULL, sizeof(struct dfs_filtertype), - GFP_ATOMIC); - if (dfs->dfs_radarf[n] == NULL) { - DFS_PRINTK - ("%s: cannot allocate memory for radar filter types\n", - __func__); - goto bad1; - } else { - qdf_mem_zero(dfs->dfs_radarf[n], - sizeof(struct dfs_filtertype)); - if (0 != dfs_alloc_mem_filter(dfs->dfs_radarf[n])) - goto bad1; - } - } - /* Allocate memory for radar table */ - dfs->dfs_radartable = - (int8_t **) os_malloc(NULL, - MAX_DFS_RADAR_TABLE_TYPE * sizeof(int8_t *), GFP_ATOMIC); - if (dfs->dfs_radartable == NULL) { - DFS_PRINTK("%s: cannot allocate memory for radar table\n", - __func__); - goto bad1; - } - for (n = 0; n < MAX_DFS_RADAR_TABLE_TYPE; n++) { - dfs->dfs_radartable[n] = - os_malloc(NULL, DFS_MAX_RADAR_OVERLAP * sizeof(int8_t), - GFP_ATOMIC); - if (dfs->dfs_radartable[n] == NULL) { - DFS_PRINTK - ("%s: cannot allocate memory for radar table entry\n", - __func__); - goto bad2; - } - } - - if (usenol == 0) - DFS_PRINTK("%s: NOL disabled\n", __func__); - else if (usenol == 2) - DFS_PRINTK("%s: NOL disabled; no CSA\n", __func__); - - dfs->dfs_rinfo.rn_use_nol = usenol; - - /* Init the cached extension channel busy for false alarm reduction */ - dfs->dfs_rinfo.ext_chan_busy_ts = ic->ic_get_TSF64(ic); - dfs->dfs_rinfo.dfs_ext_chan_busy = 0; - /* Init the Bin5 chirping related data */ - dfs->dfs_rinfo.dfs_bin5_chirp_ts = dfs->dfs_rinfo.ext_chan_busy_ts; - dfs->dfs_rinfo.dfs_last_bin5_dur = MAX_BIN5_DUR; - dfs->dfs_b5radars = NULL; - if (ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) { - dfs->dfs_rinfo.dfs_last_bin5_dur_ext_seg = MAX_BIN5_DUR; - dfs->dfs_b5radars_ext_seg = NULL; - } - - /* - * If dfs_init_radar_filters() fails, we can abort here and - * reconfigure when the first valid channel + radar config - * is available. - */ - if (dfs_init_radar_filters(ic, &radar_info)) { - DFS_PRINTK(" %s: Radar Filter Intialization Failed\n", - __func__); - return 1; - } - - dfs->ath_dfs_false_rssi_thres = RSSI_POSSIBLY_FALSE; - dfs->ath_dfs_peak_mag = SEARCH_FFT_REPORT_PEAK_MAG_THRSH; - dfs->dfs_phyerr_freq_min = 0x7fffffff; - dfs->dfs_phyerr_freq_max = 0; - dfs->dfs_phyerr_queued_count = 0; - dfs->dfs_phyerr_w53_counter = 0; - dfs->dfs_pri_multiplier = 2; - - dfs->ath_dfs_nol_timeout = DFS_NOL_TIMEOUT_S; - return 0; - -bad2: - for (n = 0; n < MAX_DFS_RADAR_TABLE_TYPE; n++) { - if (dfs->dfs_radartable[n] != NULL) { - OS_FREE(dfs->dfs_radartable[n]); - dfs->dfs_radartable[n] = NULL; - } - } - OS_FREE(dfs->dfs_radartable); - dfs->dfs_radartable = NULL; -bad1: - for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) { - if (dfs->dfs_radarf[n] != NULL) { - dfs_free_filter(dfs->dfs_radarf[n]); - OS_FREE(dfs->dfs_radarf[n]); - dfs->dfs_radarf[n] = NULL; - } - } - if (dfs->pulses) { - OS_FREE(dfs->pulses); - dfs->pulses = NULL; - } - if (dfs->pulses_ext_seg && - ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) { - OS_FREE(dfs->pulses_ext_seg); - dfs->pulses_ext_seg = NULL; - } - if (dfs->events) { - OS_FREE(dfs->events); - dfs->events = NULL; - } - - if (ic->ic_dfs) { - OS_FREE(ic->ic_dfs); - ic->ic_dfs = NULL; - } - return 1; -#undef N -} - -void dfs_detach(struct ieee80211com *ic) -{ - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - int n, empty; - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s: ic_dfs is NULL\n", - __func__); - return; - } - - /* Bug 29099 make sure all outstanding timers are cancelled */ - - if (dfs->ath_radar_tasksched) { - OS_CANCEL_TIMER(&dfs->ath_dfs_task_timer); - dfs->ath_radar_tasksched = 0; - } - - if (dfs->ath_dfstest) { - OS_CANCEL_TIMER(&dfs->ath_dfstesttimer); - dfs->ath_dfstest = 0; - } -#if 0 -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - if (dfs->ic_dfswait) { - OS_CANCEL_TIMER(&dfs->ic_dfswaittimer); - dfs->ath_dfswait = 0; - } - - OS_CANCEL_TIMER(&dfs->sc_dfs_war_timer); - if (dfs->dfs_nol != NULL) { - struct dfs_nolelem *nol, *next; - - nol = dfs->dfs_nol; - /* Bug 29099 - each NOL element has its own timer, cancel it and - free the element */ - while (nol != NULL) { - OS_CANCEL_TIMER(&nol->nol_timer); - next = nol->nol_next; - OS_FREE(nol); - nol = next; - } - dfs->dfs_nol = NULL; - } -#endif -#endif - - /* Return radar events to free q */ - dfs_reset_radarq(dfs); - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG0); - if (ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG1); - - /* Free up pulse log */ - if (dfs->pulses != NULL) { - OS_FREE(dfs->pulses); - dfs->pulses = NULL; - } - - if (dfs->pulses_ext_seg != NULL) { - OS_FREE(dfs->pulses_ext_seg); - dfs->pulses_ext_seg = NULL; - } - - for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) { - if (dfs->dfs_radarf[n] != NULL) { - dfs_free_filter(dfs->dfs_radarf[n]); - OS_FREE(dfs->dfs_radarf[n]); - dfs->dfs_radarf[n] = NULL; - } - } - - if (dfs->dfs_radartable != NULL) { - for (n = 0; n < MAX_DFS_RADAR_TABLE_TYPE; n++) { - if (dfs->dfs_radartable[n] != NULL) { - OS_FREE(dfs->dfs_radartable[n]); - dfs->dfs_radartable[n] = NULL; - } - } - OS_FREE(dfs->dfs_radartable); - dfs->dfs_radartable = NULL; -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - dfs->ath_dfs_isdfsregdomain = 0; -#endif - } - - if (dfs->dfs_b5radars != NULL) { - OS_FREE(dfs->dfs_b5radars); - dfs->dfs_b5radars = NULL; - } - if (dfs->dfs_b5radars_ext_seg != NULL) { - OS_FREE(dfs->dfs_b5radars_ext_seg); - dfs->dfs_b5radars_ext_seg = NULL; - } - -/* Commenting out since all the ar functions are obsolete and - * the function definition has been removed as part of dfs_ar.c - * dfs_reset_ar(dfs); - */ - ATH_ARQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_arq)); - ATH_ARQ_UNLOCK(dfs); - if (!empty) { -/* - * Commenting out since all the ar functions are obsolete and - * the function definition has been removed as part of dfs_ar.c - * - * dfs_reset_arq(dfs); - */ - } - if (dfs->events != NULL) { - OS_FREE(dfs->events); - dfs->events = NULL; - } - dfs_nol_timer_cleanup(dfs); - OS_FREE(dfs); - - ATH_DFSQ_LOCK_DEINIT(dfs); - ATH_ARQ_LOCK_DEINIT(dfs); - ATH_DFSEVENTQ_LOCK_DEINIT(dfs); - /* XXX? */ - ic->ic_dfs = NULL; -} - -/* - * This is called each time a channel change occurs, to (potentially) enable - * the radar code. - */ -int dfs_radar_disable(struct ieee80211com *ic) -{ - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; -#ifdef ATH_ENABLE_AR - dfs->dfs_proc_phyerr &= ~DFS_AR_EN; -#endif - dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN; - return 0; -} - -/* - * This is called each time a channel change occurs, to (potentially) enable - * the radar code. - */ -int dfs_radar_enable(struct ieee80211com *ic, - struct ath_dfs_radar_tab_info *radar_info) -{ - int is_ext_ch; - int is_fastclk = 0; - int radar_filters_init_status = 0; - struct ath_dfs *dfs; - struct dfs_state *rs_pri, *rs_ext; - struct dfs_ieee80211_channel *chan = ic->ic_curchan, *ext_ch = NULL; - - is_ext_ch = IEEE80211_IS_CHAN_11N_HT40(ic->ic_curchan); - dfs = (struct ath_dfs *)ic->ic_dfs; - rs_pri = NULL; - rs_ext = NULL; - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: ic_dfs is NULL\n", - __func__); - - return -EIO; - } - ic->ic_dfs_disable(ic); - - /* - * Setting country code might change the DFS domain - * so initialize the DFS Radar filters - */ - radar_filters_init_status = dfs_init_radar_filters(ic, radar_info); - - /* - * dfs_init_radar_filters() returns 1 on failure and - * 0 on success. - */ - if (DFS_STATUS_FAIL == radar_filters_init_status) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s[%d]: DFS Radar Filters Initialization Failed", - __func__, __LINE__); - return -EIO; - } - - if ((ic->ic_opmode == IEEE80211_M_HOSTAP - || ic->ic_opmode == IEEE80211_M_IBSS)) { - - if (IEEE80211_IS_CHAN_DFS(chan)) { - - uint8_t index_pri, index_ext; -#ifdef ATH_ENABLE_AR - dfs->dfs_proc_phyerr |= DFS_AR_EN; -#endif - dfs->dfs_proc_phyerr |= DFS_RADAR_EN; - - if (is_ext_ch) { - ext_ch = ieee80211_get_extchan(ic); - } - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG0); - /* - * Extension segment delaylines will be - * enabled only when SAP operates in 80p80 - * and both the channels are DFS. - */ - if (chan->ic_80p80_both_dfs) - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG1); - - rs_pri = dfs_getchanstate(dfs, &index_pri, 0); - if (ext_ch) { - rs_ext = dfs_getchanstate(dfs, &index_ext, 1); - } - if (rs_pri != NULL - && ((ext_ch == NULL) || (rs_ext != NULL))) { - struct ath_dfs_phyerr_param pe; - - OS_MEMSET(&pe, '\0', sizeof(pe)); - - if (index_pri != dfs->dfs_curchan_radindex) { - dfs_reset_alldelaylines(dfs, - DFS_80P80_SEG0); - /* - * Reset only when ext segment is - * present - */ - if (chan->ic_80p80_both_dfs) - dfs_reset_alldelaylines(dfs, - DFS_80P80_SEG1); - } - dfs->dfs_curchan_radindex = (int16_t) index_pri; - dfs->dfs_pri_multiplier_ini = - radar_info->dfs_pri_multiplier; - - if (rs_ext) - dfs->dfs_extchan_radindex = - (int16_t) index_ext; - - ath_dfs_phyerr_param_copy(&pe, - &rs_pri->rs_param); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, - "%s: firpwr=%d, rssi=%d, height=%d, " - "prssi=%d, inband=%d, relpwr=%d, " - "relstep=%d, maxlen=%d\n", - __func__, - pe.pe_firpwr, - pe.pe_rrssi, - pe.pe_height, - pe.pe_prssi, - pe.pe_inband, - pe.pe_relpwr, - pe.pe_relstep, pe.pe_maxlen); - - ic->ic_dfs_enable(ic, &is_fastclk, &pe); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "Enabled radar detection on channel %d\n", - chan->ic_freq); - dfs->dur_multiplier = - is_fastclk ? DFS_FAST_CLOCK_MULTIPLIER : - DFS_NO_FAST_CLOCK_MULTIPLIER; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, - "%s: duration multiplier is %d\n", - __func__, dfs->dur_multiplier); - } else - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "%s: No more radar states left\n", - __func__); - } - } - - return DFS_STATUS_SUCCESS; -} - -int -dfs_control(struct ieee80211com *ic, u_int id, - void *indata, uint32_t insize, void *outdata, uint32_t *outsize) -{ - int error = 0; - struct ath_dfs_phyerr_param peout; - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - struct dfs_ioctl_params *dfsparams; - uint32_t val = 0; -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - struct dfsreq_nolinfo *nol; - uint32_t *data = NULL; -#endif /* ATH_DFS_RADAR_DETECTION_ONLY */ - int i; - - if (dfs == NULL) { - error = -EINVAL; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s DFS is null\n", __func__); - goto bad; - } - - switch (id) { - case DFS_SET_THRESH: - if (insize < sizeof(struct dfs_ioctl_params) || !indata) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "%s: insize=%d, expected=%zu bytes, indata=%pK\n", - __func__, insize, - sizeof(struct dfs_ioctl_params), indata); - error = -EINVAL; - break; - } - dfsparams = (struct dfs_ioctl_params *)indata; - if (!dfs_set_thresholds - (ic, DFS_PARAM_FIRPWR, dfsparams->dfs_firpwr)) - error = -EINVAL; - if (!dfs_set_thresholds - (ic, DFS_PARAM_RRSSI, dfsparams->dfs_rrssi)) - error = -EINVAL; - if (!dfs_set_thresholds - (ic, DFS_PARAM_HEIGHT, dfsparams->dfs_height)) - error = -EINVAL; - if (!dfs_set_thresholds - (ic, DFS_PARAM_PRSSI, dfsparams->dfs_prssi)) - error = -EINVAL; - if (!dfs_set_thresholds - (ic, DFS_PARAM_INBAND, dfsparams->dfs_inband)) - error = -EINVAL; - /* 5413 speicfic */ - if (!dfs_set_thresholds - (ic, DFS_PARAM_RELPWR, dfsparams->dfs_relpwr)) - error = -EINVAL; - if (!dfs_set_thresholds - (ic, DFS_PARAM_RELSTEP, dfsparams->dfs_relstep)) - error = -EINVAL; - if (!dfs_set_thresholds - (ic, DFS_PARAM_MAXLEN, dfsparams->dfs_maxlen)) - error = -EINVAL; - break; - case DFS_GET_THRESH: - if (!outdata || !outsize - || *outsize < sizeof(struct dfs_ioctl_params)) { - error = -EINVAL; - break; - } - *outsize = sizeof(struct dfs_ioctl_params); - dfsparams = (struct dfs_ioctl_params *)outdata; - - /* - * Fetch the DFS thresholds using the internal representation. - */ - (void)dfs_get_thresholds(ic, &peout); - - /* - * Convert them to the dfs IOCTL representation. - */ - ath_dfs_dfsparam_to_ioctlparam(&peout, dfsparams); - break; - case DFS_RADARDETECTS: - if (!outdata || !outsize || *outsize < sizeof(uint32_t)) { - error = -EINVAL; - break; - } - *outsize = sizeof(uint32_t); - *((uint32_t *) outdata) = dfs->ath_dfs_stats.num_radar_detects; - break; - case DFS_DISABLE_DETECT: - dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN; - dfs->ic->ic_dfs_state.ignore_dfs = 1; - DFS_PRINTK("%s enable detects, ignore_dfs %d\n", - __func__, dfs->ic->ic_dfs_state.ignore_dfs); - break; - case DFS_ENABLE_DETECT: - dfs->dfs_proc_phyerr |= DFS_RADAR_EN; - dfs->ic->ic_dfs_state.ignore_dfs = 0; - DFS_PRINTK("%s enable detects, ignore_dfs %d\n", - __func__, dfs->ic->ic_dfs_state.ignore_dfs); - break; - case DFS_DISABLE_FFT: - /* UMACDFS: TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, false); */ - DFS_PRINTK("%s TODO disable FFT val=0x%x\n", __func__, val); - break; - case DFS_ENABLE_FFT: - /* UMACDFS TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, true); */ - DFS_PRINTK("%s TODO enable FFT val=0x%x\n", __func__, val); - break; - case DFS_SET_DEBUG_LEVEL: - if (insize < sizeof(uint32_t) || !indata) { - error = -EINVAL; - break; - } - dfs->dfs_debug_mask = *(uint32_t *) indata; - DFS_PRINTK("%s debug level now = 0x%x\n", - __func__, dfs->dfs_debug_mask); - if (dfs->dfs_debug_mask & ATH_DEBUG_DFS3) { - /* Enable debug Radar Event */ - dfs->dfs_event_log_on = 1; - } else { - dfs->dfs_event_log_on = 0; - } - break; - case DFS_SET_FALSE_RSSI_THRES: - if (insize < sizeof(uint32_t) || !indata) { - error = -EINVAL; - break; - } - dfs->ath_dfs_false_rssi_thres = *(uint32_t *) indata; - DFS_PRINTK("%s false RSSI threshold now = 0x%x\n", - __func__, dfs->ath_dfs_false_rssi_thres); - break; - case DFS_SET_PEAK_MAG: - if (insize < sizeof(uint32_t) || !indata) { - error = -EINVAL; - break; - } - dfs->ath_dfs_peak_mag = *(uint32_t *) indata; - DFS_PRINTK("%s peak_mag now = 0x%x\n", - __func__, dfs->ath_dfs_peak_mag); - break; - case DFS_IGNORE_CAC: - if (insize < sizeof(uint32_t) || !indata) { - error = -EINVAL; - break; - } - if (*(uint32_t *) indata) { - dfs->ic->ic_dfs_state.ignore_cac = 1; - } else { - dfs->ic->ic_dfs_state.ignore_cac = 0; - } - DFS_PRINTK("%s ignore cac = 0x%x\n", - __func__, dfs->ic->ic_dfs_state.ignore_cac); - break; - case DFS_SET_NOL_TIMEOUT: - if (insize < sizeof(uint32_t) || !indata) { - error = -EINVAL; - break; - } - if (*(int *)indata) { - dfs->ath_dfs_nol_timeout = *(int *)indata; - } else { - dfs->ath_dfs_nol_timeout = DFS_NOL_TIMEOUT_S; - } - DFS_PRINTK("%s nol timeout = %d sec\n", - __func__, dfs->ath_dfs_nol_timeout); - break; -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - case DFS_MUTE_TIME: - if (insize < sizeof(uint32_t) || !indata) { - error = -EINVAL; - break; - } - data = (uint32_t *) indata; - dfs->ath_dfstesttime = *data; - dfs->ath_dfstesttime *= (1000); /* convert sec into ms */ - break; - case DFS_GET_USENOL: - if (!outdata || !outsize || *outsize < sizeof(uint32_t)) { - error = -EINVAL; - break; - } - *outsize = sizeof(uint32_t); - *((uint32_t *) outdata) = dfs->dfs_rinfo.rn_use_nol; - - for (i = 0; - (i < DFS_EVENT_LOG_SIZE) && (i < dfs->dfs_event_log_count); - i++) { - /* DFS_DPRINTK(sc, ATH_DEBUG_DFS,"ts=%llu diff_ts=%u rssi=%u dur=%u\n", dfs->radar_log[i].ts, dfs->radar_log[i].diff_ts, dfs->radar_log[i].rssi, dfs->radar_log[i].dur); */ - - } - dfs->dfs_event_log_count = 0; - dfs->dfs_phyerr_count = 0; - dfs->dfs_phyerr_reject_count = 0; - dfs->dfs_phyerr_queued_count = 0; - dfs->dfs_phyerr_freq_min = 0x7fffffff; - dfs->dfs_phyerr_freq_max = 0; - break; - case DFS_SET_USENOL: - if (insize < sizeof(uint32_t) || !indata) { - error = -EINVAL; - break; - } - dfs->dfs_rinfo.rn_use_nol = *(uint32_t *) indata; - /* iwpriv markdfs in linux can do the same thing... */ - break; - case DFS_GET_NOL: - if (!outdata || !outsize - || *outsize < sizeof(struct dfsreq_nolinfo)) { - error = -EINVAL; - break; - } - *outsize = sizeof(struct dfsreq_nolinfo); - nol = (struct dfsreq_nolinfo *)outdata; - dfs_get_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, - &nol->ic_nchans); - dfs_print_nol(dfs); - break; - case DFS_SET_NOL: - if (insize < sizeof(struct dfsreq_nolinfo) || !indata) { - error = -EINVAL; - break; - } - nol = (struct dfsreq_nolinfo *)indata; - dfs_set_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, - nol->ic_nchans); - break; - - case DFS_SHOW_NOL: - dfs_print_nol(dfs); - break; - case DFS_BANGRADAR: -#if 0 /* MERGE_TBD */ - if (sc->sc_nostabeacons) { - printk("No radar detection Enabled\n"); - break; - } -#endif - dfs->dfs_bangradar = 1; - dfs->ath_radar_tasksched = 1; - OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0); - break; -#endif /* ATH_DFS_RADAR_DETECTION_ONLY */ - default: - error = -EINVAL; - } -bad: - return error; -} - -int -dfs_set_thresholds(struct ieee80211com *ic, const uint32_t threshtype, - const uint32_t value) -{ - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - int16_t chanindex; - struct dfs_state *rs; - struct ath_dfs_phyerr_param pe; - int is_fastclk = 0; /* XXX throw-away */ - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s: ic_dfs is NULL\n", - __func__); - return 0; - } - - chanindex = dfs->dfs_curchan_radindex; - if ((chanindex < 0) || (chanindex >= DFS_NUM_RADAR_STATES)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "%s: chanindex = %d, DFS_NUM_RADAR_STATES=%d\n", - __func__, chanindex, DFS_NUM_RADAR_STATES); - return 0; - } - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "%s: threshtype=%d, value=%d\n", __func__, threshtype, - value); - - ath_dfs_phyerr_init_noval(&pe); - - rs = &(dfs->dfs_radar[chanindex]); - switch (threshtype) { - case DFS_PARAM_FIRPWR: - rs->rs_param.pe_firpwr = (int32_t) value; - pe.pe_firpwr = value; - break; - case DFS_PARAM_RRSSI: - rs->rs_param.pe_rrssi = value; - pe.pe_rrssi = value; - break; - case DFS_PARAM_HEIGHT: - rs->rs_param.pe_height = value; - pe.pe_height = value; - break; - case DFS_PARAM_PRSSI: - rs->rs_param.pe_prssi = value; - pe.pe_prssi = value; - break; - case DFS_PARAM_INBAND: - rs->rs_param.pe_inband = value; - pe.pe_inband = value; - break; - /* 5413 specific */ - case DFS_PARAM_RELPWR: - rs->rs_param.pe_relpwr = value; - pe.pe_relpwr = value; - break; - case DFS_PARAM_RELSTEP: - rs->rs_param.pe_relstep = value; - pe.pe_relstep = value; - break; - case DFS_PARAM_MAXLEN: - rs->rs_param.pe_maxlen = value; - pe.pe_maxlen = value; - break; - default: - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "%s: unknown threshtype (%d)\n", - __func__, threshtype); - break; - } - - /* - * The driver layer dfs_enable routine is tasked with translating - * values from the global format to the per-device (HAL, offload) - * format. - */ - ic->ic_dfs_enable(ic, &is_fastclk, &pe); - return 1; -} - -int -dfs_get_thresholds(struct ieee80211com *ic, struct ath_dfs_phyerr_param *param) -{ - /* UMACDFS : TODO:ath_hal_getdfsthresh(sc->sc_ah, param); */ - - OS_MEMZERO(param, sizeof(*param)); - - (void)ic->ic_dfs_get_thresholds(ic, param); - - return 1; -} - -uint16_t dfs_usenol(struct ieee80211com *ic) -{ - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - - return dfs ? (uint16_t) dfs->dfs_rinfo.rn_use_nol : 0; -} - -uint16_t dfs_isdfsregdomain(struct ieee80211com *ic) -{ - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - - return dfs ? dfs->dfsdomain : 0; -} - -#endif /* ATH_UPPORT_DFS */ diff --git a/core/sap/dfs/src/dfs_bindetects.c b/core/sap/dfs/src/dfs_bindetects.c deleted file mode 100644 index b5c45a4aea7a..000000000000 --- a/core/sap/dfs/src/dfs_bindetects.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (c) 2002-2014, 2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_bindetects.c - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#include "dfs.h" -/*TO DO DFS removing - #include - */ -#ifdef ATH_SUPPORT_DFS - -int -dfs_bin_fixedpattern_check(struct ath_dfs *dfs, struct dfs_filter *rf, - uint32_t dur, int ext_chan_flag, int seg_id) -{ - struct dfs_pulseline *pl; - int i, n, refpri, primargin, numpulses = 0; - uint64_t start_ts, end_ts, event_ts, prev_event_ts, next_event_ts, - window_start, window_end; - uint32_t index, next_index, deltadur; - - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - pl = (seg_id == 0) ? dfs->pulses : dfs->pulses_ext_seg; - else - pl = dfs->pulses; - - /* For fixed pattern types, rf->rf_patterntype=1 */ - primargin = - dfs_get_pri_margin(dfs, ext_chan_flag, (rf->rf_patterntype == 1)); - - refpri = (rf->rf_minpri + rf->rf_maxpri) / 2; - index = pl->pl_lastelem; - end_ts = pl->pl_elems[index].p_time; - start_ts = end_ts - (refpri * rf->rf_numpulses); - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, - "lastelem ts=%llu start_ts=%llu, end_ts=%llu\n", - (unsigned long long)pl->pl_elems[index].p_time, - (unsigned long long)start_ts, (unsigned long long)end_ts); - - /* find the index of first element in our window of interest */ - for (i = 0; i < pl->pl_numelems; i++) { - index = (index - 1) & DFS_MAX_PULSE_BUFFER_MASK; - if (pl->pl_elems[index].p_time >= start_ts) - continue; - else { - index = (index) & DFS_MAX_PULSE_BUFFER_MASK; - break; - } - } - for (n = 0; n <= rf->rf_numpulses; n++) { - window_start = (start_ts + (refpri * n)) - (primargin + n); - window_end = window_start + 2 * (primargin + n); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "window_start %u window_end %u\n", - (uint32_t) window_start, (uint32_t) window_end); - for (i = 0; i < pl->pl_numelems; i++) { - prev_event_ts = pl->pl_elems[index].p_time; - index = (index + 1) & DFS_MAX_PULSE_BUFFER_MASK; - event_ts = pl->pl_elems[index].p_time; - next_index = (index + 1) & DFS_MAX_PULSE_BUFFER_MASK; - next_event_ts = pl->pl_elems[next_index].p_time; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "ts %u\n", (uint32_t) event_ts); - if ((event_ts <= window_end) - && (event_ts >= window_start)) { - deltadur = - DFS_DIFF(pl->pl_elems[index].p_dur, dur); - if ((pl->pl_elems[index].p_dur == 1) - || ((dur != 1) && (deltadur <= 2))) { - numpulses++; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "numpulses %u\n", - numpulses); - break; - } - } else if (event_ts > window_end) { - index = (index - 1) & DFS_MAX_PULSE_BUFFER_MASK; - break; - } else if (event_ts == prev_event_ts) { - if (((next_event_ts - event_ts) > refpri) || - ((next_event_ts - event_ts) == 0)) { - deltadur = - DFS_DIFF(pl->pl_elems[index].p_dur, - dur); - if ((pl->pl_elems[index].p_dur == 1) - || ((pl->pl_elems[index].p_dur != 1) - && (deltadur <= 2))) { - numpulses++; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "zero PRI: numpulses %u\n", - numpulses); - break; - } - } - } - } - } - if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "%s FOUND filterID=%u numpulses=%d unadj thresh=%d\n", - __func__, rf->rf_pulseid, numpulses, - rf->rf_threshold); - return 1; - } else - return 0; -} - -void -dfs_add_pulse(struct ath_dfs *dfs, struct dfs_filter *rf, struct dfs_event *re, - uint32_t deltaT, uint64_t this_ts, int seg_id) -{ - uint32_t index, n, window; - struct dfs_delayline *dl; - - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - dl = (seg_id == 0) ? &rf->rf_dl : &rf->rf_dl_ext_seg; - else - dl = &rf->rf_dl; - /* Circular buffer of size 2^n */ - index = (dl->dl_lastelem + 1) & DFS_MAX_DL_MASK; - /* if ((dl->dl_numelems+1) == DFS_MAX_DL_SIZE) */ - if ((dl->dl_numelems) == DFS_MAX_DL_SIZE) - dl->dl_firstelem = (dl->dl_firstelem + 1) & DFS_MAX_DL_MASK; - else - dl->dl_numelems++; - dl->dl_lastelem = index; - dl->dl_elems[index].de_time = deltaT; - dl->dl_elems[index].de_ts = this_ts; - window = deltaT; - dl->dl_elems[index].de_dur = re->re_dur; - dl->dl_elems[index].de_rssi = re->re_rssi; - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "%s: adding: filter id %d, dur=%d, rssi=%d, ts=%llu\n", - __func__, - rf->rf_pulseid, - re->re_dur, re->re_rssi, (unsigned long long int)this_ts); - - for (n = 0; n < dl->dl_numelems - 1; n++) { - index = (index - 1) & DFS_MAX_DL_MASK; - /* - * calculate window based on full time stamp instead of deltaT - * deltaT (de_time) may result in incorrect window value - */ - window = (uint32_t) (this_ts - dl->dl_elems[index].de_ts); - - if (window > rf->rf_filterlen) { - dl->dl_firstelem = (index + 1) & DFS_MAX_DL_MASK; - dl->dl_numelems = n + 1; - } - } - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "dl firstElem = %d lastElem = %d\n", dl->dl_firstelem, - dl->dl_lastelem); -} - -int -dfs_bin_check(struct ath_dfs *dfs, struct dfs_filter *rf, uint32_t deltaT, - uint32_t width, int ext_chan_flag, int seg_id) -{ - uint32_t refpri, refdur, searchpri, deltapri, deltapri_2, deltapri_3, - averagerefpri; - uint32_t n, i, primargin, durmargin, highscore, highscoreindex; - int score[DFS_MAX_DL_SIZE], delayindex, dindex, found = 0; - struct dfs_delayline *dl; - uint32_t scoreindex, lowpriindex = 0, lowpri = 0xffff; - int numpulses = 0; - int lowprichk = 3, pri_match = 0; - - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - dl = (seg_id == 0) ? &rf->rf_dl : &rf->rf_dl_ext_seg; - else - dl = &rf->rf_dl; - - if (dl->dl_numelems < (rf->rf_threshold - 1)) { - return 0; - } - if (deltaT > rf->rf_filterlen) - return 0; - - primargin = - dfs_get_pri_margin(dfs, ext_chan_flag, (rf->rf_patterntype == 1)); - - if (rf->rf_maxdur < 10) { - durmargin = 4; - } else { - durmargin = 6; - } - - if (rf->rf_patterntype == 1) { - found = - dfs_bin_fixedpattern_check(dfs, rf, width, - ext_chan_flag, seg_id); - if (found) { - dl->dl_numelems = 0; - } - return found; - } - - OS_MEMZERO(score, sizeof(int) * DFS_MAX_DL_SIZE); - /* find out the lowest pri */ - for (n = 0; n < dl->dl_numelems; n++) { - delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; - refpri = dl->dl_elems[delayindex].de_time; - if (refpri == 0) - continue; - else if (refpri < lowpri) { - lowpri = dl->dl_elems[delayindex].de_time; - lowpriindex = n; - } - } - /* find out the each delay element's pri score */ - for (n = 0; n < dl->dl_numelems; n++) { - delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; - refpri = dl->dl_elems[delayindex].de_time; - if (refpri == 0) - continue; - if (refpri < rf->rf_maxpri) { /* use only valid PRI range for high score */ - for (i = 0; i < dl->dl_numelems; i++) { - dindex = - (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; - searchpri = dl->dl_elems[dindex].de_time; - deltapri = DFS_DIFF(searchpri, refpri); - deltapri_2 = DFS_DIFF(searchpri, 2 * refpri); - deltapri_3 = DFS_DIFF(searchpri, 3 * refpri); - if (rf->rf_ignore_pri_window == 2) { - pri_match = ((deltapri < primargin) - || (deltapri_2 < primargin) - || (deltapri_3 < - primargin)); - } else { - pri_match = (deltapri < primargin); - } - - if (pri_match) - score[n]++; - } - } else { - score[n] = 0; - } - if (score[n] > rf->rf_threshold) { - /* we got the most possible candidate, - * no need to continue further */ - break; - } - } - /* find out the high scorer */ - highscore = 0; - highscoreindex = 0; - for (n = 0; n < dl->dl_numelems; n++) { - if (score[n] > highscore) { - highscore = score[n]; - highscoreindex = n; - } else if (score[n] == highscore) { - /*more than one pri has highscore take the least pri */ - delayindex = - (dl->dl_firstelem + - highscoreindex) & DFS_MAX_DL_MASK; - dindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; - if (dl->dl_elems[dindex].de_time <= - dl->dl_elems[delayindex].de_time) { - highscoreindex = n; - } - } - } - /* find the average pri of pulses around the pri of highscore or - * the pulses around the lowest pri */ - if (rf->rf_ignore_pri_window > 0) { - lowprichk = (rf->rf_threshold >> 1) + 1; - } else { - lowprichk = 3; - } - - if (highscore < lowprichk) { - scoreindex = lowpriindex; - } else { - scoreindex = highscoreindex; - } - /* We got the possible pri, save its parameters as reference */ - delayindex = (dl->dl_firstelem + scoreindex) & DFS_MAX_DL_MASK; - refdur = dl->dl_elems[delayindex].de_dur; - refpri = dl->dl_elems[delayindex].de_time; - averagerefpri = 0; - - if (rf->rf_fixed_pri_radar_pulse) { - refpri = (rf->rf_minpri + rf->rf_maxpri) / 2; - } - - numpulses = dfs_bin_pri_check(dfs, rf, dl, score[scoreindex], refpri, - refdur, ext_chan_flag, refpri); - if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) { - found = 1; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "ext_flag=%d MATCH filter=%u numpulses=%u thresh=%u refdur=%d refpri=%d primargin=%d\n", - ext_chan_flag, rf->rf_pulseid, numpulses, - rf->rf_threshold, refdur, refpri, primargin); - - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - dfs_print_delayline(dfs, - (seg_id == 0) ? &rf->rf_dl : &rf->rf_dl_ext_seg); - else - dfs_print_delayline(dfs, &rf->rf_dl); - - dfs_print_filter(dfs, rf); - } - return found; -} - -int -dfs_bin_pri_check(struct ath_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) -{ - uint32_t searchpri, searchdur, searchrssi, deltapri = 0, deltapri1 = - 0, deltapri2 = 0, deltadur, averagerefpri = 0, MatchCount = 0; - uint32_t delta_ts_variance, delta_time_stamps, prev_good_timestamp = 0; - int delayindex, dindex; - uint32_t i, j = 0, primargin, durmargin, highscore = - score, highscoreindex = 0; - int numpulses = 1; /* first pulse in the burst is most likely being filtered out based on maxfilterlen */ - int priscorechk = 1, numpulsetochk = 2, primatch = 0; - - /* Use the adjusted PRI margin to reduce false alarms */ - /* For non fixed pattern types, rf->rf_patterntype=0 */ - primargin = - dfs_get_pri_margin(dfs, ext_chan_flag, (rf->rf_patterntype == 1)); - - if ((refpri > rf->rf_maxpri) || (refpri < rf->rf_minpri)) { - numpulses = 0; - return numpulses; - } - - if (rf->rf_maxdur < 10) { - durmargin = 4; - } else { - durmargin = 6; - } - - if ((!rf->rf_fixed_pri_radar_pulse)) { - if (rf->rf_ignore_pri_window == 1) { - priscorechk = (rf->rf_threshold >> 1); - } else { - priscorechk = 1; - } - - MatchCount = 0; - if (score > priscorechk) { - for (i = 0; i < dl->dl_numelems; i++) { - dindex = - (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; - searchpri = dl->dl_elems[dindex].de_time; - deltapri = DFS_DIFF(searchpri, refpri); - if (deltapri < primargin) { - averagerefpri += searchpri; - MatchCount++; - } - } - if (rf->rf_patterntype != 2) { - if (MatchCount > 0) - refpri = (averagerefpri / MatchCount); /* average */ - } else { - refpri = (averagerefpri / score); - } - } - } - /* Note: Following primultiple calculation should be done once per filter - * during initialization stage (dfs_attach) and stored in its array - * atleast for fixed frequency types like FCC Bin1 to save some CPU cycles. - * multiplication, devide operators in the following code are left as it is - * for readability hoping the complier will use left/right shifts wherever possible - */ - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "refpri = %d high score = %d index = %d numpulses = %d\n", - refpri, highscore, highscoreindex, numpulses); - /* Count the other delay elements that have pri and dur with in the - * acceptable range from the reference one */ - for (i = 0; i < dl->dl_numelems; i++) { - delayindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; - searchpri = dl->dl_elems[delayindex].de_time; - if (searchpri == 0) { - /* This events PRI is zero, take it as a - * valid pulse but decrement next event's PRI by refpri - */ - dindex = (delayindex + 1) & DFS_MAX_DL_MASK; - dl->dl_elems[dindex].de_time -= refpri; - searchpri = refpri; - } - searchdur = dl->dl_elems[delayindex].de_dur; - searchrssi = dl->dl_elems[delayindex].de_rssi; - deltadur = DFS_DIFF(searchdur, refdur); - deltapri = DFS_DIFF(searchpri, refpri); - - /* deltapri3 = DFS_DIFF(searchpri, 3 * refpri); */ - primatch = 0; - - if ((rf->rf_ignore_pri_window > 0) && (rf->rf_patterntype != 2)) { - for (j = 0; j < rf->rf_numpulses; j++) { - deltapri1 = - DFS_DIFF(searchpri, (j + 1) * refpri); - if (deltapri1 < (2 * primargin)) { - primatch = 1; - break; - } - } - } else { - if ((deltapri1 < primargin) || (deltapri2 < primargin)) { - primatch = 1; - } - } - - if (primatch && (deltadur < durmargin)) { - if (numpulses == 1) { - numpulses++; - } else { - delta_time_stamps = - dl->dl_elems[delayindex].de_ts - - prev_good_timestamp; - if ((rf->rf_ignore_pri_window > 0)) { - numpulsetochk = rf->rf_numpulses; - - if ((rf->rf_patterntype == 2) - && (fundamentalpri < - refpri + 100)) { - numpulsetochk = 4; - } - } else { - numpulsetochk = 4; - } - for (j = 0; j < numpulsetochk; j++) { - delta_ts_variance = - DFS_DIFF(delta_time_stamps, - ((j + - 1) * fundamentalpri)); - if (delta_ts_variance < - (2 * (j + 1) * primargin)) { - numpulses++; - if (rf->rf_ignore_pri_window > - 0) { - break; - } - } - } - } - prev_good_timestamp = dl->dl_elems[delayindex].de_ts; - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "rf->minpri=%d rf->maxpri=%d searchpri = %d index = %d numpulses = %d deltapri=%d j=%d\n", - rf->rf_minpri, rf->rf_maxpri, searchpri, i, - numpulses, deltapri, j); - } - - } - return numpulses; -} -#endif /* ATH_SUPPORT_DFS */ diff --git a/core/sap/dfs/src/dfs_debug.c b/core/sap/dfs/src/dfs_debug.c deleted file mode 100644 index 1a5aa2be2e98..000000000000 --- a/core/sap/dfs/src/dfs_debug.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2002-2014 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_debug.c - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#include "dfs.h" -/* TO DO DFS - #include - */ -#ifdef ATH_SUPPORT_DFS - -void dfs_print_delayline(struct ath_dfs *dfs, struct dfs_delayline *dl) -{ - int i = 0, index; - struct dfs_delayelem *de; - - index = dl->dl_lastelem; - for (i = 0; i < dl->dl_numelems; i++) { - de = &dl->dl_elems[index]; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "Elem %d: ts = %u (0x%x) dur=%u\n", i, - de->de_time, de->de_time, de->de_dur); - index = (index - 1) & DFS_MAX_DL_MASK; - } -} - -void dfs_print_filter(struct ath_dfs *dfs, struct dfs_filter *rf) -{ - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "filterID[%d] rf_numpulses=%u; rf->rf_minpri=%u; " - "rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; " - "rf->rf_mindur=%u; rf->rf_maxdur=%u\n", - rf->rf_pulseid, - rf->rf_numpulses, - rf->rf_minpri, - rf->rf_maxpri, - rf->rf_threshold, - rf->rf_filterlen, rf->rf_mindur, rf->rf_maxdur); -} - -void dfs_print_filters(struct ath_dfs *dfs) -{ - struct dfs_filtertype *ft = NULL; - struct dfs_filter *rf; - int i, j; - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n", - __func__); - return; - } - for (i = 0; i < DFS_MAX_RADAR_TYPES; i++) { - if (dfs->dfs_radarf[i] != NULL) { - ft = dfs->dfs_radarf[i]; - if ((ft->ft_numfilters > DFS_MAX_NUM_RADAR_FILTERS) - || (!ft->ft_numfilters)) - continue; - DFS_PRINTK - ("===========ft->ft_numfilters=%u===========\n", - ft->ft_numfilters); - for (j = 0; j < ft->ft_numfilters; j++) { - rf = ft->ft_filters[j]; - DFS_PRINTK - ("filter[%d] filterID = %d rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n", - j, rf->rf_pulseid, rf->rf_numpulses, - rf->rf_minpri, rf->rf_maxpri, - rf->rf_threshold, rf->rf_filterlen, - rf->rf_mindur, rf->rf_maxdur); - } - } - } -} - -void dfs_print_activity(struct ath_dfs *dfs) -{ - int chan_busy = 0, ext_chan_busy = 0; - uint32_t rxclear = 0, rxframe = 0, txframe = 0, cycles = 0; - - cycles = - dfs->ic->ic_get_mib_cycle_counts_pct(dfs->ic, &rxclear, &rxframe, - &txframe); - chan_busy = cycles; - - ext_chan_busy = dfs->ic->ic_get_ext_busy(dfs->ic); - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "cycles=%d rxclear=%d rxframe=%d" - " txframe=%d extchanbusy=%d\n", cycles, rxclear, - rxframe, txframe, ext_chan_busy); - return; -} - -/* - * XXX migrate this to use ath_dfs as the arg, not ieee80211com! - */ -#ifndef ATH_DFS_RADAR_DETECTION_ONLY -os_timer_func(dfs_debug_timeout) -{ - struct ieee80211com *ic; - struct ath_dfs *dfs; - - OS_GET_TIMER_ARG(ic, struct ieee80211com *); - - dfs = (struct ath_dfs *)ic->ic_dfs; - - dfs_print_activity(dfs); - - OS_SET_TIMER(&dfs->ath_dfs_debug_timer, DFS_DEBUG_TIMEOUT_MS); -} -#endif - -#endif /* ATH_SUPPORT_DFS */ diff --git a/core/sap/dfs/src/dfs_fcc_bin5.c b/core/sap/dfs/src/dfs_fcc_bin5.c deleted file mode 100644 index ca8e1c15e2e3..000000000000 --- a/core/sap/dfs/src/dfs_fcc_bin5.c +++ /dev/null @@ -1,894 +0,0 @@ -/* - * Copyright (c) 2002-2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_fcc_bin5.c - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#include "dfs.h" -/* TO DO DFS - #include - */ -#ifdef ATH_SUPPORT_DFS - -/* - * Reject the pulse if: - * + It's outside the RSSI threshold; - * + It's outside the pulse duration; - * + It's been verified by HW/SW chirp checking - * and neither of those found a chirp. - */ -int -dfs_bin5_check_pulse(struct ath_dfs *dfs, struct dfs_event *re, - struct dfs_bin5radars *br) -{ - int b5_rssithresh = br->br_pulse.b5_rssithresh; - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_PULSE, - "%s: re_dur=%d, rssi=%d, check_chirp=%d, " - "hw_chirp=%d, sw_chirp=%d\n", - __func__, - (int)re->re_dur, - (int)re->re_rssi, - !!(re->re_flags & DFS_EVENT_CHECKCHIRP), - !!(re->re_flags & DFS_EVENT_HW_CHIRP), - !!(re->re_flags & DFS_EVENT_SW_CHIRP)); - - /* - * If the sw/hw chirp detection says to fail the pulse, - * do so. - */ - if (DFS_EVENT_NOTCHIRP(re)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, - "%s: rejecting chirp: ts=%llu, dur=%d, rssi=%d " - "checkchirp=%d, hwchirp=%d, swchirp=%d\n", - __func__, - (unsigned long long)re->re_full_ts, - (int)re->re_dur, - (int)re->re_rssi, - !!(re->re_flags & DFS_EVENT_CHECKCHIRP), - !!(re->re_flags & DFS_EVENT_HW_CHIRP), - !!(re->re_flags & DFS_EVENT_SW_CHIRP)); - return 0; - } - - /* Adjust the filter threshold for rssi in non TURBO mode */ - qdf_spin_lock_bh(&dfs->ic->chan_lock); - if (!(dfs->ic->ic_curchan->ic_flags & CHANNEL_TURBO)) - b5_rssithresh += br->br_pulse.b5_rssimargin; - - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - - /* - * Check if the pulse is within duration and rssi - * thresholds. - */ - if ((re->re_dur >= br->br_pulse.b5_mindur) && - (re->re_dur <= br->br_pulse.b5_maxdur) && - (re->re_rssi >= b5_rssithresh)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, - "%s: dur=%d, rssi=%d - adding!\n", - __func__, (int)re->re_dur, (int)re->re_rssi); - return 1; - } - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, - "%s: too low to be Bin5 pulse tsf=%llu, dur=%d, rssi=%d\n", - __func__, - (unsigned long long)re->re_full_ts, - (int)re->re_dur, (int)re->re_rssi); - - return 0; -} - -int dfs_bin5_addpulse(struct ath_dfs *dfs, struct dfs_bin5radars *br, - struct dfs_event *re, uint64_t thists) -{ - uint32_t index, stop; - uint64_t tsDelta; - - /* Check if this pulse is a valid pulse in terms of repetition, - * if not, return without adding it to the queue. - * PRI : Pulse Repitetion Interval - * BRI : Burst Repitetion Interval */ - if (br->br_numelems != 0) { - index = br->br_lastelem; - tsDelta = thists - br->br_elems[index].be_ts; - if ((tsDelta < DFS_BIN5_PRI_LOWER_LIMIT) || - ((tsDelta > DFS_BIN5_PRI_HIGHER_LIMIT) && - (tsDelta < DFS_BIN5_BRI_LOWER_LIMIT))) { - return 0; - } - } - /* Circular buffer of size 2^n */ - index = (br->br_lastelem + 1) & DFS_MAX_B5_MASK; - br->br_lastelem = index; - if (br->br_numelems == DFS_MAX_B5_SIZE) - br->br_firstelem = (br->br_firstelem + 1) & DFS_MAX_B5_MASK; - else - br->br_numelems++; - br->br_elems[index].be_ts = thists; - br->br_elems[index].be_rssi = re->re_rssi; - br->br_elems[index].be_dur = re->re_dur; /* please note that this is in u-sec */ - stop = 0; - index = br->br_firstelem; - while ((!stop) && (br->br_numelems - 1) > 0) { - if ((thists - br->br_elems[index].be_ts) > - ((uint64_t) br->br_pulse.b5_timewindow)) { - br->br_numelems--; - br->br_firstelem = - (br->br_firstelem + 1) & DFS_MAX_B5_MASK; - index = br->br_firstelem; - } else - stop = 1; - } - return 1; -} - -/* - * 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 ath_dfs *dfs, int seg_id) -{ - struct dfs_bin5radars *br; - int index[DFS_MAX_B5_SIZE]; - uint32_t n = 0, i = 0, i1 = 0, this = 0, prev = 0, rssi_diff = - 0, width_diff = 0, bursts = 0; - uint32_t total_diff = 0, average_diff = 0, total_width = - 0, average_width = 0, numevents = 0; - uint64_t pri; - - if (dfs == NULL) { - DFS_PRINTK("%s: ic_dfs is NULL\n", __func__); - return 1; - } - for (n = 0; n < dfs->dfs_rinfo.rn_numbin5radars; n++) { - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - br = (seg_id == 0) ? &(dfs->dfs_b5radars[n]) : - &(dfs->dfs_b5radars_ext_seg[n]); - else - br = &(dfs->dfs_b5radars[n]); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, - "Num elems = %d\n", br->br_numelems); - - /* find a valid bin 5 pulse and use it as reference */ - for (i1 = 0; i1 < br->br_numelems; i1++) { - this = ((br->br_firstelem + i1) & DFS_MAX_B5_MASK); - if ((br->br_elems[this].be_dur >= MIN_BIN5_DUR_MICROSEC) - && (br->br_elems[this].be_dur <= - MAX_BIN5_DUR_MICROSEC)) { - break; - } - } - - prev = this; - for (i = i1 + 1; i < br->br_numelems; i++) { - this = ((br->br_firstelem + i) & DFS_MAX_B5_MASK); - - /* first make sure it is a bin 5 pulse by checking the duration */ - if ((br->br_elems[this].be_dur < MIN_BIN5_DUR_MICROSEC) - || (br->br_elems[this].be_dur > - MAX_BIN5_DUR_MICROSEC)) { - continue; - } - - /* Rule 1: 1000 <= PRI <= 2000 + some margin */ - if (br->br_elems[this].be_ts >= - br->br_elems[prev].be_ts) { - pri = - br->br_elems[this].be_ts - - br->br_elems[prev].be_ts; - } else { /* roll over case */ - /* pri = (0xffffffffffffffff - br->br_elems[prev].be_ts) + br->br_elems[this].be_ts; */ - pri = br->br_elems[this].be_ts; - } - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, - " pri=%llu this.ts=%llu this.dur=%d this.rssi=%d prev.ts=%llu\n", - (unsigned long long)pri, - (unsigned long long)br->br_elems[this]. - be_ts, (int)br->br_elems[this].be_dur, - (int)br->br_elems[this].be_rssi, - (unsigned long long)br->br_elems[prev]. - be_ts); - if (((pri >= DFS_BIN5_PRI_LOWER_LIMIT) && (pri <= DFS_BIN5_PRI_HIGHER_LIMIT))) { /* pri: pulse repitition interval in us */ - /* Rule 2: pulse width of the pulses in the burst should be same (+/- margin) */ - if (br->br_elems[this].be_dur >= - br->br_elems[prev].be_dur) { - width_diff = - br->br_elems[this].be_dur - - br->br_elems[prev].be_dur; - } else { - width_diff = - br->br_elems[prev].be_dur - - br->br_elems[this].be_dur; - } - if (width_diff <= DFS_BIN5_WIDTH_MARGIN) { - /* Rule 3: RSSI of the pulses in the burst should be same (+/- margin) */ - if (br->br_elems[this].be_rssi >= - br->br_elems[prev].be_rssi) { - rssi_diff = - br->br_elems[this].be_rssi - - br->br_elems[prev].be_rssi; - } else { - rssi_diff = - br->br_elems[prev].be_rssi - - br->br_elems[this].be_rssi; - } - if (rssi_diff <= DFS_BIN5_RSSI_MARGIN) { - bursts++; - /* Save the indexes of this pair for later width variance check */ - if (numevents >= 2) { - /* make sure the event is not duplicated, - * possible in a 3 pulse burst */ - if (index[numevents - 1] - != prev) { - index - [numevents++] - = prev; - } - } else { - index[numevents++] = - prev; - } - index[numevents++] = this; - } else { - DFS_DPRINTK(dfs, - ATH_DEBUG_DFS_BIN5, - "%s %d Bin5 rssi_diff=%d\n", - __func__, __LINE__, - rssi_diff); - } - } else { - DFS_DPRINTK(dfs, - ATH_DEBUG_DFS_BIN5, - "%s %d Bin5 width_diff=%d\n", - __func__, __LINE__, - width_diff); - } - } else if ((pri >= DFS_BIN5_BRI_LOWER_LIMIT) && - (pri <= DFS_BIN5_BRI_UPPER_LIMIT)) { - /* check pulse width to make sure it is in range of bin 5 */ - /* if ((br->br_elems[this].be_dur >= MIN_BIN5_DUR_MICROSEC) && (br->br_elems[this].be_dur <= MAX_BIN5_DUR_MICROSEC)) { */ - bursts++; - /* } */ - } else { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, - "%s %d Bin5 PRI check fail pri=%llu\n", - __func__, __LINE__, - (unsigned long long)pri); - } - prev = this; - } - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u\n", - bursts, numevents); - if (bursts >= br->br_pulse.b5_threshold) { - if ((br->br_elems[br->br_lastelem].be_ts - - br->br_elems[br->br_firstelem].be_ts) < 3000000) { - return 0; - } else { - /* - * don't do this check since not all the cases have this kind of burst width variation. - * - for (i=0; ibr_elems[index[i]].be_dur; - } - average_width = total_width/bursts; - for (i=0; ibr_elems[index[i]].be_dur, average_width); - } - average_diff = total_diff/bursts; - if( average_diff > DFS_BIN5_WIDTH_MARGIN ) { - return 1; - } else { - - DFS_DPRINTK(ic, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n", bursts, numevents, total_width, average_width, total_diff, average_diff); - - } - */ - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, - "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n", - bursts, numevents, total_width, - average_width, total_diff, - average_diff); - DFS_PRINTK("bin 5 radar detected, bursts=%d\n", - bursts); - return 1; - } - } - } - - return 0; -} - -/* Return true if chirping pulse, false if not. - Decision is made based on processing the FFT data included with the PHY error. - Calculate the slope using the maximum bin index reported in the FFT data. - Calculate slope between FFT packet 0 and packet n-1. Also calculate slope between - packet 1 and packet n. - If a pulse is chirping, a slope of 5 and greater is seen. - Non-chirping pulses have slopes of 0, 1, 2 or 3. - */ - -/* - * Chirp detection for Sowl/Howl. - */ -static int -dfs_check_chirping_sowl(struct ath_dfs *dfs, void *buf, - uint16_t datalen, int is_ctl, int is_ext, int *slope, - int *is_dc) -{ -#define FFT_LEN 70 -#define FFT_LOWER_BIN_MAX_INDEX_BYTE 66 -#define FFT_UPPER_BIN_MAX_INDEX_BYTE 69 -#define MIN_CHIRPING_SLOPE 4 - int is_chirp = 0; - int p, num_fft_packets = 0; - int ctl_slope = 0, ext_slope = 0; - int ctl_high0, ctl_low0, ctl_slope0 = - 0, ext_high0, ext_low0, ext_slope0 = 0; - int ctl_high1, ctl_low1, ctl_slope1 = - 0, ext_high1, ext_low1, ext_slope1 = 0; - uint8_t *fft_data_ptr; - - *slope = 0; - *is_dc = 0; - - num_fft_packets = datalen / FFT_LEN; - fft_data_ptr = ((uint8_t *) buf); - - /* DEBUG - Print relevant portions of the FFT data */ - for (p = 0; p < num_fft_packets; p++) { - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "fft_data_ptr=0x%pK\t", - fft_data_ptr); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "[66]=%d [69]=%d\n", - *(fft_data_ptr + FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2, - *(fft_data_ptr + - FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2); - - fft_data_ptr += FFT_LEN; - } - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, - "datalen=%d num_fft_packets=%d\n", datalen, - num_fft_packets); - - /* There is not enough FFT data to figure out whether the pulse is chirping or not */ - if (num_fft_packets < 4) { - return 0; - } - - fft_data_ptr = ((uint8_t *) buf); - - if (is_ctl) { - - fft_data_ptr = ((uint8_t *) buf); - ctl_low0 = *(fft_data_ptr + FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2; - fft_data_ptr += FFT_LEN; - ctl_low1 = *(fft_data_ptr + FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2; - - /* last packet with first packet */ - fft_data_ptr = - ((uint8_t *) buf) + (FFT_LEN * (num_fft_packets - 1)); - ctl_high1 = *(fft_data_ptr + FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2; - - /* second last packet with 0th packet */ - fft_data_ptr = - ((uint8_t *) buf) + (FFT_LEN * (num_fft_packets - 2)); - ctl_high0 = *(fft_data_ptr + FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2; - - ctl_slope0 = ctl_high0 - ctl_low0; - if (ctl_slope0 < 0) - ctl_slope0 *= (-1); - - ctl_slope1 = ctl_high1 - ctl_low1; - if (ctl_slope1 < 0) - ctl_slope1 *= (-1); - - ctl_slope = - ((ctl_slope0 > ctl_slope1) ? ctl_slope0 : ctl_slope1); - *slope = ctl_slope; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, - "ctl_slope0=%d ctl_slope1=%d ctl_slope=%d\n", - ctl_slope0, ctl_slope1, ctl_slope); - - } else if (is_ext) { - - fft_data_ptr = ((uint8_t *) buf); - ext_low0 = *(fft_data_ptr + FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2; - - fft_data_ptr += FFT_LEN; - ext_low1 = *(fft_data_ptr + FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2; - - fft_data_ptr = - ((uint8_t *) buf) + (FFT_LEN * (num_fft_packets - 1)); - ext_high1 = *(fft_data_ptr + FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2; - fft_data_ptr = - ((uint8_t *) buf) + (FFT_LEN * (num_fft_packets - 2)); - ext_high0 = *(fft_data_ptr + FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2; - - ext_slope0 = ext_high0 - ext_low0; - if (ext_slope0 < 0) - ext_slope0 *= (-1); - - ext_slope1 = ext_high1 - ext_low1; - if (ext_slope1 < 0) - ext_slope1 *= (-1); - - ext_slope = - ((ext_slope0 > ext_slope1) ? ext_slope0 : ext_slope1); - *slope = ext_slope; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT | ATH_DEBUG_DFS_BIN5, - "ext_slope0=%d ext_slope1=%d ext_slope=%d\n", - ext_slope0, ext_slope1, ext_slope); - } else - return 0; - - if ((ctl_slope >= MIN_CHIRPING_SLOPE) - || (ext_slope >= MIN_CHIRPING_SLOPE)) { - is_chirp = 1; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5 | ATH_DEBUG_DFS_BIN5_FFT | - ATH_DEBUG_DFS_PHYERR_SUM, - "is_chirp=%d is_dc=%d\n", is_chirp, *is_dc); - } - return is_chirp; - -#undef FFT_LEN -#undef FFT_LOWER_BIN_MAX_INDEX_BYTE -#undef FFT_UPPER_BIN_MAX_INDEX_BYTE -#undef MIN_CHIRPING_SLOPE -} - -/* - * Merlin (and Osprey, etc) chirp radar chirp detection. - */ -static int -dfs_check_chirping_merlin(struct ath_dfs *dfs, void *buf, uint16_t datalen, - int is_ctl, int is_ext, int *slope, int *is_dc) -{ -#define ABS_DIFF(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x) -#define ABS(_x) ((int)_x > 0 ? (int)_x : -(int)_x) - -#define DELTA_STEP 1 /* This should be between 1 and 3. Default is 1. */ -#define NUM_DIFFS 3 /* Number of Diffs to compute. valid range is 2-4 */ -#define MAX_DIFF 2 /* Threshold for difference of delta peaks */ -#define BIN_COUNT_MAX 6 /* Max. number of strong bins for narrow band */ - -/* - * Dynamic 20/40 mode FFT packet format related definition - */ - -#define NUM_FFT_BYTES_HT40 70 -#define NUM_BIN_BYTES_HT40 64 -#define NUM_SUBCHAN_BINS_HT40 64 -#define LOWER_INDEX_BYTE_HT40 66 -#define UPPER_INDEX_BYTE_HT40 69 -#define LOWER_WEIGHT_BYTE_HT40 64 -#define UPPER_WEIGHT_BYTE_HT40 67 -#define LOWER_MAG_BYTE_HT40 65 -#define UPPER_MAG_BYTE_HT40 68 - -/* - * Static 20 mode FFT packet format related definition - */ - -#define NUM_FFT_BYTES_HT20 31 -#define NUM_BIN_BYTES_HT20 28 -#define NUM_SUBCHAN_BINS_HT20 56 -#define LOWER_INDEX_BYTE_HT20 30 -#define UPPER_INDEX_BYTE_HT20 30 -#define LOWER_WEIGHT_BYTE_HT20 28 -#define UPPER_WEIGHT_BYTE_HT20 28 -#define LOWER_MAG_BYTE_HT20 29 -#define UPPER_MAG_BYTE_HT20 29 - - int num_fft_packets; /* number of FFT packets reported to software */ - int num_fft_bytes; - int num_bin_bytes; - int num_subchan_bins; - int lower_index_byte; - int upper_index_byte; - int lower_weight_byte; - int upper_weight_byte; - int lower_mag_byte; - int upper_mag_byte; - - int max_index_lower[DELTA_STEP + NUM_DIFFS]; - int max_index_upper[DELTA_STEP + NUM_DIFFS]; - int max_mag_lower[DELTA_STEP + NUM_DIFFS]; - int max_mag_upper[DELTA_STEP + NUM_DIFFS]; - int bin_wt_lower[DELTA_STEP + NUM_DIFFS]; - int bin_wt_upper[DELTA_STEP + NUM_DIFFS]; - int max_mag_sel[DELTA_STEP + NUM_DIFFS]; - int max_mag[DELTA_STEP + NUM_DIFFS]; - int max_index[DELTA_STEP + NUM_DIFFS]; - - int max_d[] = { 10, 19, 28 }; - int min_d[] = { 1, 2, 3 }; - - uint8_t *ptr; /* pointer to FFT data */ - int i; - int fft_start; - int chirp_found; - int delta_peak[NUM_DIFFS]; - int j; - int bin_count; - int bw_mask; - int delta_diff; - int same_sign; - int temp; - - qdf_spin_lock_bh(&dfs->ic->chan_lock); - if (IS_CHAN_HT40(dfs->ic->ic_curchan)) { - num_fft_bytes = NUM_FFT_BYTES_HT40; - num_bin_bytes = NUM_BIN_BYTES_HT40; - num_subchan_bins = NUM_SUBCHAN_BINS_HT40; - lower_index_byte = LOWER_INDEX_BYTE_HT40; - upper_index_byte = UPPER_INDEX_BYTE_HT40; - lower_weight_byte = LOWER_WEIGHT_BYTE_HT40; - upper_weight_byte = UPPER_WEIGHT_BYTE_HT40; - lower_mag_byte = LOWER_MAG_BYTE_HT40; - upper_mag_byte = UPPER_MAG_BYTE_HT40; - - /* if we are in HT40MINUS then swap primary and extension */ - if (IS_CHAN_HT40_MINUS(dfs->ic->ic_curchan)) { - temp = is_ctl; - is_ctl = is_ext; - is_ext = temp; - } - - } else { - num_fft_bytes = NUM_FFT_BYTES_HT20; - num_bin_bytes = NUM_BIN_BYTES_HT20; - num_subchan_bins = NUM_SUBCHAN_BINS_HT20; - lower_index_byte = LOWER_INDEX_BYTE_HT20; - upper_index_byte = UPPER_INDEX_BYTE_HT20; - lower_weight_byte = LOWER_WEIGHT_BYTE_HT20; - upper_weight_byte = UPPER_WEIGHT_BYTE_HT20; - lower_mag_byte = LOWER_MAG_BYTE_HT20; - upper_mag_byte = UPPER_MAG_BYTE_HT20; - } - - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - ptr = (uint8_t *) buf; - /* - * sanity check for FFT buffer - */ - - if ((ptr == NULL) || (datalen == 0)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, - "%s: FFT buffer pointer is null or size is 0\n", - __func__); - return 0; - } - - num_fft_packets = (datalen - 3) / num_fft_bytes; - if (num_fft_packets < (NUM_DIFFS + DELTA_STEP)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, - "datalen = %d, num_fft_packets = %d, too few packets... (exiting)\n", - datalen, num_fft_packets); - return 0; - } - - if ((((datalen - 3) % num_fft_bytes) == 2) && (datalen > num_fft_bytes)) { - /* FIXME !!! */ - ptr += 2; - datalen -= 2; - } - - for (i = 0; i < (NUM_DIFFS + DELTA_STEP); i++) { - fft_start = i * num_fft_bytes; - bin_wt_lower[i] = ptr[fft_start + lower_weight_byte] & 0x3f; - bin_wt_upper[i] = ptr[fft_start + upper_weight_byte] & 0x3f; - - max_index_lower[i] = ptr[fft_start + lower_index_byte] >> 2; - max_index_upper[i] = - (ptr[fft_start + upper_index_byte] >> 2) + num_subchan_bins; - - qdf_spin_lock_bh(&dfs->ic->chan_lock); - if (!IS_CHAN_HT40(dfs->ic->ic_curchan)) { - /* - * for HT20 mode indices are 6 bit signed number - */ - max_index_lower[i] ^= 0x20; - max_index_upper[i] = 0; - } - - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - /* - * Reconstruct the maximum magnitude for each sub-channel. Also select - * and flag the max overall magnitude between the two sub-channels. - */ - - max_mag_lower[i] = - ((ptr[fft_start + lower_index_byte] & 0x03) << 8) + - ptr[fft_start + lower_mag_byte]; - max_mag_upper[i] = - ((ptr[fft_start + upper_index_byte] & 0x03) << 8) + - ptr[fft_start + upper_mag_byte]; - bw_mask = - ((bin_wt_lower[i] == - 0) ? 0 : is_ctl) + (((bin_wt_upper[i] == - 0) ? 0 : is_ext) << 1); - - /* - * Limit the max bin based on channel bandwidth - * If the upper sub-channel max index is stuck at '1', the signal is dominated - * by residual DC (or carrier leak) and should be ignored. - */ - - if (bw_mask == 1) { - max_mag_sel[i] = 0; - max_mag[i] = max_mag_lower[i]; - max_index[i] = max_index_lower[i]; - } else if (bw_mask == 2) { - max_mag_sel[i] = 1; - max_mag[i] = max_mag_upper[i]; - max_index[i] = max_index_upper[i]; - } else if (max_index_upper[i] == num_subchan_bins) { - max_mag_sel[i] = 0; /* Ignore DC bin. */ - max_mag[i] = max_mag_lower[i]; - max_index[i] = max_index_lower[i]; - } else { - if (max_mag_upper[i] > max_mag_lower[i]) { - max_mag_sel[i] = 1; - max_mag[i] = max_mag_upper[i]; - max_index[i] = max_index_upper[i]; - } else { - max_mag_sel[i] = 0; - max_mag[i] = max_mag_lower[i]; - max_index[i] = max_index_lower[i]; - } - } - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, - "i=%d, max_index[i]=%d, max_index_lower[i]=%d, " - "max_index_upper[i]=%d\n", - i, max_index[i], max_index_lower[i], - max_index_upper[i]); - } - - chirp_found = 1; - delta_diff = 0; - same_sign = 1; - - /* - delta_diff computation -- look for movement in peak. - make sure that the chirp direction (i.e. sign) is always the same, - i.e. sign of the two peaks should be same. - */ - for (i = 0; i < NUM_DIFFS; i++) { - delta_peak[i] = max_index[i + DELTA_STEP] - max_index[i]; - if (i > 0) { - delta_diff = delta_peak[i] - delta_peak[i - 1]; - same_sign = - !((delta_peak[i] & 0x80) ^ - (delta_peak[i - 1] & 0x80)); - } - chirp_found &= (ABS(delta_peak[i]) >= min_d[DELTA_STEP - 1]) && - (ABS(delta_peak[i]) <= max_d[DELTA_STEP - 1]) && - same_sign && (ABS(delta_diff) <= MAX_DIFF); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, - "i=%d, delta_peak[i]=%d, delta_diff=%d\n", - i, delta_peak[i], delta_diff); - } - - if (chirp_found) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, - "%s: CHIRPING_BEFORE_STRONGBIN_YES\n", __func__); - } else { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, - "%s: CHIRPING_BEFORE_STRONGBIN_NO\n", __func__); - } - - /* - Work around for potential hardware data corruption bug. Check for - wide band signal by counting strong bins indicated by bitmap flags. - This check is done if chirp_found is true. We do this as a final check - to weed out corrupt FFTs bytes. This looks expensive but in most cases it - will exit early. - */ - - for (i = 0; (i < (NUM_DIFFS + DELTA_STEP)) && (chirp_found == 1); i++) { - bin_count = 0; - /* point to the start of the 1st byte of the selected sub-channel. */ - fft_start = - (i * num_fft_bytes) + - (max_mag_sel[i] ? (num_subchan_bins >> 1) : 0); - for (j = 0; j < (num_subchan_bins >> 1); j++) { - /* - * If either bin is flagged "strong", accumulate the bin_count. - * It's not accurate, but good enough... - */ - bin_count += (ptr[fft_start + j] & 0x88) ? 1 : 0; - } - chirp_found &= (bin_count > BIN_COUNT_MAX) ? 0 : 1; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, - "i=%d, computed bin_count=%d\n", i, bin_count); - } - - if (chirp_found) { - DFS_DPRINTK(dfs, - ATH_DEBUG_DFS_BIN5_FFT | ATH_DEBUG_DFS_PHYERR_SUM, - "%s: CHIRPING_YES\n", __func__); - } else { - DFS_DPRINTK(dfs, - ATH_DEBUG_DFS_BIN5_FFT | ATH_DEBUG_DFS_PHYERR_SUM, - "%s: CHIRPING_NO\n", __func__); - } - return chirp_found; - -#undef ABS_DIFF -#undef ABS -#undef DELTA_STEP -#undef NUM_DIFFS -#undef MAX_DIFF -#undef BIN_COUNT_MAX - -#undef NUM_FFT_BYTES_HT40 -#undef NUM_BIN_BYTES_HT40 -#undef NUM_SUBCHAN_BINS_HT40 -#undef LOWER_INDEX_BYTE_HT40 -#undef UPPER_INDEX_BYTE_HT40 -#undef LOWER_WEIGHT_BYTE_HT40 -#undef UPPER_WEIGHT_BYTE_HT40 -#undef LOWER_MAG_BYTE_HT40 -#undef UPPER_MAG_BYTE_HT40 - -#undef NUM_FFT_BYTES_HT40 -#undef NUM_BIN_BYTES_HT40 -#undef NUM_SUBCHAN_BINS_HT40 -#undef LOWER_INDEX_BYTE_HT40 -#undef UPPER_INDEX_BYTE_HT40 -#undef LOWER_WEIGHT_BYTE_HT40 -#undef UPPER_WEIGHT_BYTE_HT40 -#undef LOWER_MAG_BYTE_HT40 -#undef UPPER_MAG_BYTE_HT40 -} - -int -dfs_check_chirping(struct ath_dfs *dfs, void *buf, - uint16_t datalen, int is_ctl, int is_ext, int *slope, - int *is_dc) -{ - - if (dfs->dfs_caps.ath_dfs_use_enhancement) - return dfs_check_chirping_merlin(dfs, buf, datalen, is_ctl, - is_ext, slope, is_dc); - else - return dfs_check_chirping_sowl(dfs, buf, datalen, is_ctl, - is_ext, slope, is_dc); -} - -uint8_t -dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, uint32_t diff_ts, - uint8_t old_dur, int seg_id) -{ - - u_int8_t dfs_last_bin5_dur; - - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - dfs_last_bin5_dur = (seg_id == 0) ? - dfs->dfs_rinfo.dfs_last_bin5_dur : - dfs->dfs_rinfo.dfs_last_bin5_dur_ext_seg; - else - dfs_last_bin5_dur = dfs->dfs_rinfo.dfs_last_bin5_dur; - - /* - * Pulses may get split into 2 during chirping, this print is only - * to show that it happened, we do not handle this condition if we - * cannot detect the chirping. - */ - /* - * SPLIT pulses will have a time stamp difference of < 50 - */ - if (diff_ts < 50) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, - "%s SPLIT pulse diffTs=%u dur=%d (old_dur=%d)\n", - __func__, diff_ts, - dfs_last_bin5_dur, old_dur); - } - /* - * Check if this is the 2nd or 3rd pulse in the same burst, - * PRI will be between 1000 and 2000 us - */ - if (((diff_ts >= DFS_BIN5_PRI_LOWER_LIMIT) && - (diff_ts <= DFS_BIN5_PRI_HIGHER_LIMIT))) { - /* - * This pulse belongs to the same burst as the pulse before, - * so return the same random duration for it - */ - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, - "%s this pulse belongs to the same burst as before, give " - "it same dur=%d (old_dur=%d)\n", - __func__, dfs_last_bin5_dur, old_dur); - - return dfs_last_bin5_dur; - } - /* - * This pulse does not belong to this burst, return unchanged - * duration. - */ - return old_dur; -} - -/* - * 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 - * ath_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. - * - * XXX This function doesn't take into account whether the hardware - * is operating in 5GHz fast clock mode or not. - * - * XXX And this function doesn't take into account whether the hardware - * is peregrine or not. Grr. - */ -int dfs_get_random_bin5_dur(struct ath_dfs *dfs, uint64_t tstamp) -{ - uint8_t new_dur = MIN_BIN5_DUR; - int range; - - get_random_bytes(&new_dur, sizeof(uint8_t)); - - range = (MAX_BIN5_DUR - MIN_BIN5_DUR + 1); - - new_dur %= range; - - new_dur += MIN_BIN5_DUR; - - return new_dur; -} - -#endif /* ATH_SUPPORT_DFS */ diff --git a/core/sap/dfs/src/dfs_init.c b/core/sap/dfs/src/dfs_init.c deleted file mode 100644 index 12cb49b9caa3..000000000000 --- a/core/sap/dfs/src/dfs_init.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright (c) 2002-2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_init.c - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#include "dfs.h" -/* TO DO DFS - #include - */ -#ifdef ATH_SUPPORT_DFS - -extern int domainoverride; - -/* - * Clear all delay lines for all filter types - * - * This may be called before any radar pulses are configured - * (eg on a non-DFS channel, with radar PHY errors still showing up.) - * In that case, just drop out early. - */ -void dfs_reset_alldelaylines(struct ath_dfs *dfs, int seg_id) -{ - struct dfs_filtertype *ft = NULL; - struct dfs_filter *rf; - struct dfs_delayline *dl; - struct dfs_pulseline *pl; - int i, j; - - if (dfs == NULL) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s[%d]: sc_dfs is NULL", __func__, __LINE__); - return; - } - - if (dfs->ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) - pl = (seg_id == 0) ? dfs->pulses : dfs->pulses_ext_seg; - else - pl = dfs->pulses; - - if (pl == NULL) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s[%d]: pl==NULL, dfs=%pK", __func__, __LINE__, dfs); - return; - } - - if (dfs->ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) { - if (((seg_id == 0) ? - dfs->dfs_b5radars : dfs->dfs_b5radars_ext_seg) == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "%s: pl==NULL, b5radars=%pK\n", - __func__, - (seg_id == 0) ? dfs->dfs_b5radars : - dfs->dfs_b5radars_ext_seg); - return; - } - } else { - if (dfs->dfs_b5radars == NULL) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s[%d]: pl==NULL, b5radars=%pK", __func__, __LINE__, - dfs->dfs_b5radars); - return; - } - } - /* reset the pulse log */ - pl->pl_firstelem = pl->pl_numelems = 0; - pl->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK; - - for (i = 0; i < DFS_MAX_RADAR_TYPES; i++) { - if (dfs->dfs_radarf[i] != NULL) { - ft = dfs->dfs_radarf[i]; - if (NULL != ft) { - for (j = 0; j < ft->ft_numfilters; j++) { - rf = ft->ft_filters[j]; - if (dfs->ic->dfs_hw_bd_id != - DFS_HWBD_QCA6174) - dl = (seg_id == 0) ? - &(rf->rf_dl) : - &(rf->rf_dl_ext_seg); - else - dl = &(rf->rf_dl); - if (dl != NULL) { - OS_MEMZERO(dl, - sizeof(struct - dfs_delayline)); - dl->dl_lastelem = - (0xFFFFFFFF) & - DFS_MAX_DL_MASK; - } - } - } - } - } - for (i = 0; i < dfs->dfs_rinfo.rn_numbin5radars; i++) { - if (dfs->ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) { - if (seg_id == DFS_80P80_SEG0) { - OS_MEMZERO(&(dfs->dfs_b5radars[i].br_elems[0]), - sizeof(struct dfs_bin5elem) * - DFS_MAX_B5_SIZE); - dfs->dfs_b5radars[i].br_firstelem = 0; - dfs->dfs_b5radars[i].br_numelems = 0; - dfs->dfs_b5radars[i].br_lastelem = - (0xFFFFFFFF) & DFS_MAX_B5_MASK; - } else { - OS_MEMZERO( - &(dfs->dfs_b5radars_ext_seg[i].br_elems[0]), - sizeof(struct dfs_bin5elem)* - DFS_MAX_B5_SIZE); - dfs->dfs_b5radars_ext_seg[i].br_firstelem = 0; - dfs->dfs_b5radars_ext_seg[i].br_numelems = 0; - dfs->dfs_b5radars_ext_seg[i].br_lastelem = - (0xFFFFFFFF)&DFS_MAX_B5_MASK; - } - - } else { - OS_MEMZERO(&(dfs->dfs_b5radars[i].br_elems[0]), - sizeof(struct dfs_bin5elem) * DFS_MAX_B5_SIZE); - dfs->dfs_b5radars[i].br_firstelem = 0; - dfs->dfs_b5radars[i].br_numelems = 0; - dfs->dfs_b5radars[i].br_lastelem = - (0xFFFFFFFF) & DFS_MAX_B5_MASK; - } - } -} - -/* - * Clear only a single delay line - */ - -void dfs_reset_delayline(struct dfs_delayline *dl) -{ - OS_MEMZERO(&(dl->dl_elems[0]), sizeof(dl->dl_elems)); - dl->dl_lastelem = (0xFFFFFFFF) & DFS_MAX_DL_MASK; -} - -void dfs_reset_radarq(struct ath_dfs *dfs) -{ - struct dfs_event *event; - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL", __func__); - return; - } - ATH_DFSQ_LOCK(dfs); - ATH_DFSEVENTQ_LOCK(dfs); - while (!STAILQ_EMPTY(&(dfs->dfs_radarq))) { - event = STAILQ_FIRST(&(dfs->dfs_radarq)); - STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list); - OS_MEMZERO(event, sizeof(struct dfs_event)); - STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list); - } - ATH_DFSEVENTQ_UNLOCK(dfs); - ATH_DFSQ_UNLOCK(dfs); -} - -/* This function Initialize the radar filter tables - * if the ath dfs domain is uninitalized or - * ath dfs domain is different from hal dfs domain - */ -int dfs_init_radar_filters(struct ieee80211com *ic, - struct ath_dfs_radar_tab_info *radar_info) -{ - uint32_t T, Tmax; - int numpulses, p, n, i; - int numradars = 0, numb5radars = 0; - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - struct dfs_filtertype *ft = NULL; - struct dfs_filter *rf = NULL; - struct dfs_pulse *dfs_radars; - struct dfs_bin5pulse *b5pulses = NULL; - int32_t min_rssithresh = DFS_MAX_RSSI_VALUE; - uint32_t max_pulsedur = 0; - uint32_t b5_rssithresh; - uint32_t b5_maxdur; - - if (dfs == NULL) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s[%d]: dfs is NULL", __func__, __LINE__); - return DFS_STATUS_FAIL; - } - /* clear up the dfs domain flag first */ -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - dfs->ath_dfs_isdfsregdomain = 0; -#endif - - /* - * If radar_info is NULL or dfsdomain is NULL, treat - * the rest of the radar configuration as suspect. - */ - if (radar_info == NULL || radar_info->dfsdomain == 0) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s[%d]: Unknown dfs domain %d ", - __func__, __LINE__, dfs->dfsdomain); - /* Disable radar detection since we don't have a radar domain */ - dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN; - /* Returning success though we are not completing init. A failure - * will fail dfs_attach also. - */ - return DFS_STATUS_SUCCESS; - } - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s[%d]:dfsdomain=%d, numradars=%d, numb5radars=%d", - __func__, __LINE__, radar_info->dfsdomain, - radar_info->numradars, radar_info->numb5radars); - dfs->dfsdomain = radar_info->dfsdomain; - dfs_radars = radar_info->dfs_radars; - numradars = radar_info->numradars; - b5pulses = radar_info->b5pulses; - numb5radars = radar_info->numb5radars; - - /* XXX this should be an explicit copy of some sort! */ - dfs->dfs_defaultparams = radar_info->dfs_defaultparams; - -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - dfs->ath_dfs_isdfsregdomain = 1; -#endif - - dfs->dfs_rinfo.rn_numradars = 0; - /* Clear filter type table */ - for (n = 0; n < 256; n++) { - for (i = 0; i < DFS_MAX_RADAR_OVERLAP; i++) - (dfs->dfs_radartable[n])[i] = -1; - } - /* Now, initialize the radar filters */ - for (p = 0; p < numradars; p++) { - ft = NULL; - for (n = 0; n < dfs->dfs_rinfo.rn_numradars; n++) { - if ((dfs_radars[p].rp_pulsedur == - dfs->dfs_radarf[n]->ft_filterdur) - && (dfs_radars[p].rp_numpulses == - dfs->dfs_radarf[n]->ft_numpulses) - && (dfs_radars[p].rp_mindur == - dfs->dfs_radarf[n]->ft_mindur) - && (dfs_radars[p].rp_maxdur == - dfs->dfs_radarf[n]->ft_maxdur)) { - ft = dfs->dfs_radarf[n]; - break; - } - } - if (ft == NULL) { - /* No filter of the appropriate dur was found */ - if ((dfs->dfs_rinfo.rn_numradars + 1) > - DFS_MAX_RADAR_TYPES) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "%s: Too many filter types", - __func__); - goto bad4; - } - ft = dfs->dfs_radarf[dfs->dfs_rinfo.rn_numradars]; - ft->ft_numfilters = 0; - ft->ft_numpulses = dfs_radars[p].rp_numpulses; - ft->ft_patterntype = dfs_radars[p].rp_patterntype; - ft->ft_mindur = dfs_radars[p].rp_mindur; - ft->ft_maxdur = dfs_radars[p].rp_maxdur; - ft->ft_filterdur = dfs_radars[p].rp_pulsedur; - ft->ft_rssithresh = dfs_radars[p].rp_rssithresh; - ft->ft_rssimargin = dfs_radars[p].rp_rssimargin; - ft->ft_minpri = 1000000; - - if (ft->ft_rssithresh < min_rssithresh) - min_rssithresh = ft->ft_rssithresh; - if (ft->ft_maxdur > max_pulsedur) - max_pulsedur = ft->ft_maxdur; - for (i = ft->ft_mindur; i <= ft->ft_maxdur; i++) { - uint32_t stop = 0, tableindex = 0; - - while ((tableindex < DFS_MAX_RADAR_OVERLAP) - && (!stop)) { - if ((dfs-> - dfs_radartable[i])[tableindex] == - -1) - stop = 1; - else - tableindex++; - } - if (stop) { - (dfs->dfs_radartable[i])[tableindex] = - (int8_t) (dfs->dfs_rinfo. - rn_numradars); - } else { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "%s: Too many overlapping radar filters", - __func__); - goto bad4; - } - } - dfs->dfs_rinfo.rn_numradars++; - } - rf = ft->ft_filters[ft->ft_numfilters++]; - dfs_reset_delayline(&rf->rf_dl); - - if (ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) - dfs_reset_delayline(&rf->rf_dl_ext_seg); - - numpulses = dfs_radars[p].rp_numpulses; - - rf->rf_numpulses = numpulses; - rf->rf_patterntype = dfs_radars[p].rp_patterntype; - rf->rf_pulseid = dfs_radars[p].rp_pulseid; - rf->rf_mindur = dfs_radars[p].rp_mindur; - rf->rf_maxdur = dfs_radars[p].rp_maxdur; - rf->rf_numpulses = dfs_radars[p].rp_numpulses; - rf->rf_ignore_pri_window = dfs_radars[p].rp_ignore_pri_window; - T = (100000000 / dfs_radars[p].rp_max_pulsefreq) - - 100 * (dfs_radars[p].rp_meanoffset); - rf->rf_minpri = - dfs_round((int32_t) T - - (100 * (dfs_radars[p].rp_pulsevar))); - Tmax = - (100000000 / dfs_radars[p].rp_pulsefreq) - - 100 * (dfs_radars[p].rp_meanoffset); - rf->rf_maxpri = - dfs_round((int32_t) Tmax + - (100 * (dfs_radars[p].rp_pulsevar))); - - if (rf->rf_minpri < ft->ft_minpri) - ft->ft_minpri = rf->rf_minpri; - - rf->rf_fixed_pri_radar_pulse = - (dfs_radars[p].rp_max_pulsefreq == - dfs_radars[p].rp_pulsefreq) ? 1 : 0; - rf->rf_threshold = dfs_radars[p].rp_threshold; - rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses; - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s[%d]: minprf = %d maxprf = %d pulsevar = %d thresh=%d", - __func__, __LINE__, dfs_radars[p].rp_pulsefreq, - dfs_radars[p].rp_max_pulsefreq, - dfs_radars[p].rp_pulsevar, rf->rf_threshold); - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s[%d]:minpri = %d maxpri = %d filterlen = %d filterID = %d", - __func__, __LINE__, rf->rf_minpri, rf->rf_maxpri, - rf->rf_filterlen, rf->rf_pulseid); - - } - -#ifdef DFS_DEBUG - dfs_print_filters(ic); -#endif - dfs->dfs_rinfo.rn_numbin5radars = numb5radars; - if (dfs->dfs_b5radars != NULL) { - OS_FREE(dfs->dfs_b5radars); - dfs->dfs_b5radars = NULL; - } - - if (dfs->dfs_b5radars_ext_seg != NULL) { - OS_FREE(dfs->dfs_b5radars_ext_seg); - dfs->dfs_b5radars_ext_seg = NULL; - } - - if (numb5radars) { - dfs->dfs_b5radars = (struct dfs_bin5radars *)os_malloc(NULL, - numb5radars * - sizeof(struct dfs_bin5radars), - GFP_KERNEL); - if (dfs->dfs_b5radars == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "%s: cannot allocate memory for bin5 radars", - __func__); - goto bad4; - } - - if (ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) { - dfs->dfs_b5radars_ext_seg = - (struct dfs_bin5radars *)os_malloc(NULL, - numb5radars * - sizeof(struct dfs_bin5radars), - GFP_KERNEL); - if (dfs->dfs_b5radars_ext_seg == NULL) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_ERROR, - "%s:Fail allocate memory for ext bin5 radars", - __func__); - goto bad4; - } - } - - for (n = 0; n < numb5radars; n++) { - dfs->dfs_b5radars[n].br_pulse = b5pulses[n]; - dfs->dfs_b5radars[n].br_pulse.b5_timewindow *= - DFS_BIN5_TIME_WINDOW_UNITS_MULTIPLIER; - if (dfs->dfs_b5radars[n].br_pulse.b5_rssithresh < - min_rssithresh) - min_rssithresh = - dfs->dfs_b5radars[n].br_pulse.b5_rssithresh; - - if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur > - max_pulsedur) - max_pulsedur = - dfs->dfs_b5radars[n].br_pulse.b5_maxdur; - } - - if (ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) { - for (n = 0; n < numb5radars; n++) { - dfs->dfs_b5radars_ext_seg[n].br_pulse = - b5pulses[n]; - dfs->dfs_b5radars_ext_seg[n].br_pulse.b5_timewindow *= - DFS_BIN5_TIME_WINDOW_UNITS_MULTIPLIER; - b5_rssithresh = - dfs->dfs_b5radars_ext_seg[n].br_pulse.b5_rssithresh; - - if (b5_rssithresh < min_rssithresh) - min_rssithresh = b5_rssithresh; - - b5_maxdur = - dfs->dfs_b5radars_ext_seg[n].br_pulse.b5_maxdur; - if (b5_maxdur > max_pulsedur) - max_pulsedur = b5_maxdur; - - } - } - } - - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG0); - - if (ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG1); - - dfs_reset_radarq(dfs); - dfs->dfs_curchan_radindex = -1; - dfs->dfs_extchan_radindex = -1; - dfs->dfs_rinfo.rn_minrssithresh = min_rssithresh; - /* Convert durations to TSF ticks */ - dfs->dfs_rinfo.rn_maxpulsedur = - dfs_round((int32_t) ((max_pulsedur * 100 / 80) * 100)); - /* relax the max pulse duration a little bit due to inaccuracy caused by chirping. */ - dfs->dfs_rinfo.rn_maxpulsedur = dfs->dfs_rinfo.rn_maxpulsedur + 20; - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s[%d]: DFS min filter rssiThresh = %d", - __func__, __LINE__, min_rssithresh); - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s[%d]:DFS max pulse dur = %d ticks", - __func__, __LINE__, dfs->dfs_rinfo.rn_maxpulsedur); - return DFS_STATUS_SUCCESS; - -bad4: - return DFS_STATUS_FAIL; -} - -void dfs_clear_stats(struct ieee80211com *ic) -{ - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - - if (dfs == NULL) - return; - OS_MEMZERO(&dfs->ath_dfs_stats, sizeof(struct dfs_stats)); - dfs->ath_dfs_stats.last_reset_tstamp = ic->ic_get_TSF64(ic); -} - -#endif /* ATH_SUPPORT_DFS */ diff --git a/core/sap/dfs/src/dfs_ioctl.h b/core/sap/dfs/src/dfs_ioctl.h deleted file mode 100644 index abe6c0c8c75e..000000000000 --- a/core/sap/dfs/src/dfs_ioctl.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2010-2015 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_ioctl.h - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/* - * ioctl defines - */ - -#ifndef _DFS_IOCTL_H_ -#define _DFS_IOCTL_H_ - -#define DFS_MUTE_TIME 1 -#define DFS_SET_THRESH 2 -#define DFS_GET_THRESH 3 -#define DFS_GET_USENOL 4 -#define DFS_SET_USENOL 5 -#define DFS_RADARDETECTS 6 -#define DFS_BANGRADAR 7 -#define DFS_SHOW_NOL 8 -#define DFS_DISABLE_DETECT 9 -#define DFS_ENABLE_DETECT 10 -#define DFS_DISABLE_FFT 11 -#define DFS_ENABLE_FFT 12 -#define DFS_SET_DEBUG_LEVEL 13 -#define DFS_GET_NOL 14 -#define DFS_SET_NOL 15 - -#define DFS_SET_FALSE_RSSI_THRES 16 -#define DFS_SET_PEAK_MAG 17 -#define DFS_IGNORE_CAC 18 -#define DFS_SET_NOL_TIMEOUT 19 -#define DFS_LAST_IOCTL 20 -#ifndef IEEE80211_CHAN_MAX -#define IEEE80211_CHAN_MAX 255 -#endif - -struct dfsreq_nolelem { - uint16_t nol_freq; /* NOL channel frequency */ - uint16_t nol_chwidth; - unsigned long nol_start_ticks; /* OS ticks when the NOL timer started */ - uint32_t nol_timeout_ms; /* Nol timeout value in msec */ -}; - -struct dfsreq_nolinfo { - uint32_t ic_nchans; - struct dfsreq_nolelem dfs_nol[IEEE80211_CHAN_MAX]; -}; - -/* - * ioctl parameter types - */ - -#define DFS_PARAM_FIRPWR 1 -#define DFS_PARAM_RRSSI 2 -#define DFS_PARAM_HEIGHT 3 -#define DFS_PARAM_PRSSI 4 -#define DFS_PARAM_INBAND 5 -/* 5413 specific parameters */ -#define DFS_PARAM_RELPWR 7 -#define DFS_PARAM_RELSTEP 8 -#define DFS_PARAM_MAXLEN 9 - -struct dfs_ioctl_params { - int32_t dfs_firpwr; /* FIR pwr out threshold */ - int32_t dfs_rrssi; /* Radar rssi thresh */ - int32_t dfs_height; /* Pulse height thresh */ - int32_t dfs_prssi; /* Pulse rssi thresh */ - int32_t dfs_inband; /* Inband thresh */ - int32_t dfs_relpwr; /* pulse relative pwr thresh */ - int32_t dfs_relstep; /* pulse relative step thresh */ - int32_t dfs_maxlen; /* pulse max duration */ -}; - -/* - * XXX keep these in sync with ath_dfs_phyerr_param! - */ -#define DFS_IOCTL_PARAM_NOVAL 65535 -#define DFS_IOCTL_PARAM_ENABLE 0x8000 - -#endif /* _DFS_IOCTL_H_ */ diff --git a/core/sap/dfs/src/dfs_ioctl_private.h b/core/sap/dfs/src/dfs_ioctl_private.h deleted file mode 100644 index 6b268b713e86..000000000000 --- a/core/sap/dfs/src/dfs_ioctl_private.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010-2015 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_ioctl_private.h - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/* - * ioctl defines - */ - -#ifndef _DFS_IOCTL_PRIVATE_H_ -#define _DFS_IOCTL_PRIVATE_H_ - -/* - * Assert that the NOVAL values match. - */ -#if (ATH_DFS_PHYERR_PARAM_NOVAL != DFS_IOCTL_PARAM_NOVAL) -#error "ATH_DFS_PHYERR_PARAM_NOVAL != DFS_IOCTL_PARAM_NOVAL" -#endif - -/* - * Assert that the ENABLE values match. - */ -#if (ATH_DFS_PHYERR_PARAM_ENABLE != DFS_IOCTL_PARAM_ENABLE) -#error "ATH_DFS_PHYERR_PARAM_ENABLE != DFS_IOCTL_PARAM_ENABLE" -#endif - -/* - * These two methods are used by the lmac glue to copy between - * the DFS and HAL PHY configuration. - * - * I'm "cheating" here and assuming that the ENABLE and NOVAL - * values match - see the above macros. - */ -static inline void -ath_dfs_ioctlparam_to_dfsparam(const struct dfs_ioctl_params *src, - struct ath_dfs_phyerr_param *dst) -{ - - dst->pe_firpwr = src->dfs_firpwr; - dst->pe_rrssi = src->dfs_rrssi; - dst->pe_height = src->dfs_height; - dst->pe_prssi = src->dfs_prssi; - dst->pe_inband = src->dfs_inband; - dst->pe_relpwr = src->dfs_relpwr; - dst->pe_relstep = src->dfs_relstep; - dst->pe_maxlen = src->dfs_maxlen; -} - -static inline void -ath_dfs_dfsparam_to_ioctlparam(struct ath_dfs_phyerr_param *src, - struct dfs_ioctl_params *dst) -{ - - dst->dfs_firpwr = src->pe_firpwr; - dst->dfs_rrssi = src->pe_rrssi; - dst->dfs_height = src->pe_height; - dst->dfs_prssi = src->pe_prssi; - dst->dfs_inband = src->pe_inband; - dst->dfs_relpwr = src->pe_relpwr; - dst->dfs_relstep = src->pe_relstep; - dst->dfs_maxlen = src->pe_maxlen; -} - -#endif /* _DFS_IOCTL_PRIVATE_H_ */ diff --git a/core/sap/dfs/src/dfs_misc.c b/core/sap/dfs/src/dfs_misc.c deleted file mode 100644 index 37b78bdf4e45..000000000000 --- a/core/sap/dfs/src/dfs_misc.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2002-2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_misc.c - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#include "dfs.h" -/* TO DO DFS - #include - */ -#ifndef UNINET -/* TO DO DFS - #include - */ -#endif -#ifdef ATH_SUPPORT_DFS - -static int adjust_pri_per_chan_busy(int ext_chan_busy, int pri_margin) -{ - int adjust_pri = 0; - - if (ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) { - - adjust_pri = - (ext_chan_busy - - DFS_EXT_CHAN_LOADING_THRESH) * (pri_margin); - adjust_pri /= 100; - - } - return adjust_pri; -} - -static int adjust_thresh_per_chan_busy(int ext_chan_busy, int thresh) -{ - int adjust_thresh = 0; - - if (ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) { - - adjust_thresh = - (ext_chan_busy - DFS_EXT_CHAN_LOADING_THRESH) * thresh; - adjust_thresh /= 100; - - } - return adjust_thresh; -} - -/* 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.*/ - -int -dfs_get_pri_margin(struct ath_dfs *dfs, int is_extchan_detect, - int is_fixed_pattern) -{ - - int adjust_pri = 0, ext_chan_busy = 0; - int pri_margin; - - if (is_fixed_pattern) - pri_margin = DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN; - else - pri_margin = DFS_DEFAULT_PRI_MARGIN; - - qdf_spin_lock_bh(&dfs->ic->chan_lock); - if (IS_CHAN_HT40(dfs->ic->ic_curchan)) { - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - ext_chan_busy = dfs->ic->ic_get_ext_busy(dfs->ic); - if (ext_chan_busy >= 0) { - dfs->dfs_rinfo.ext_chan_busy_ts = - dfs->ic->ic_get_TSF64(dfs->ic); - dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy; - } else { - /* Check to see if the cached value of ext_chan_busy can be used */ - ext_chan_busy = 0; - if (dfs->dfs_rinfo.dfs_ext_chan_busy) { - if (dfs->dfs_rinfo.rn_lastfull_ts < - dfs->dfs_rinfo.ext_chan_busy_ts) { - ext_chan_busy = - dfs->dfs_rinfo.dfs_ext_chan_busy; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - " PRI Use cached copy of ext_chan_busy extchanbusy=%d\n", - ext_chan_busy); - } - } - } - adjust_pri = - adjust_pri_per_chan_busy(ext_chan_busy, pri_margin); - - pri_margin -= adjust_pri; - } else { - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - } - return pri_margin; -} - -/* 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.*/ - -int dfs_get_filter_threshold(struct ath_dfs *dfs, struct dfs_filter *rf, - int is_extchan_detect) -{ - int ext_chan_busy = 0; - int thresh, adjust_thresh = 0; - - thresh = rf->rf_threshold; - - qdf_spin_lock_bh(&dfs->ic->chan_lock); - if (IS_CHAN_HT40(dfs->ic->ic_curchan)) { - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - ext_chan_busy = dfs->ic->ic_get_ext_busy(dfs->ic); - if (ext_chan_busy >= 0) { - dfs->dfs_rinfo.ext_chan_busy_ts = - dfs->ic->ic_get_TSF64(dfs->ic); - dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy; - } else { - /* Check to see if the cached value of ext_chan_busy can be used */ - ext_chan_busy = 0; - if (dfs->dfs_rinfo.dfs_ext_chan_busy) { - if (dfs->dfs_rinfo.rn_lastfull_ts < - dfs->dfs_rinfo.ext_chan_busy_ts) { - ext_chan_busy = - dfs->dfs_rinfo.dfs_ext_chan_busy; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - " THRESH Use cached copy of ext_chan_busy extchanbusy=%d rn_lastfull_ts=%llu ext_chan_busy_ts=%llu\n", - ext_chan_busy, - (unsigned long long)dfs-> - dfs_rinfo.rn_lastfull_ts, - (unsigned long long)dfs-> - dfs_rinfo.ext_chan_busy_ts); - } - } - } - - adjust_thresh = - adjust_thresh_per_chan_busy(ext_chan_busy, thresh); - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - " filterID=%d extchanbusy=%d adjust_thresh=%d\n", - rf->rf_pulseid, ext_chan_busy, adjust_thresh); - - thresh += adjust_thresh; - } else { - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - } - return thresh; -} - -uint32_t dfs_round(int32_t val) -{ - uint32_t ival, rem; - - if (val < 0) - return 0; - ival = val / 100; - rem = val - (ival * 100); - if (rem < 50) - return ival; - else - return ival + 1; -} - -struct dfs_ieee80211_channel *ieee80211_get_extchan(struct ieee80211com *ic) -{ - int chan_offset = 0; - - if (IEEE80211_IS_CHAN_HT40PLUS_CAPABLE(ic->ic_curchan)) { - chan_offset = 20; - } else if (IEEE80211_IS_CHAN_HT40MINUS_CAPABLE(ic->ic_curchan)) { - chan_offset = -20; - } else { - return NULL; - } - return (ic-> - ic_find_channel(ic, ic->ic_curchan->ic_freq + chan_offset, - IEEE80211_CHAN_11NA_HT20)); -} - -/* - * Finds the radar state entry that matches the current channel - */ -struct dfs_state *dfs_getchanstate(struct ath_dfs *dfs, uint8_t *index, - int ext_chan_flag) -{ - struct dfs_state *rs = NULL; - int i; - struct dfs_ieee80211_channel *cmp_ch; - - if (dfs == NULL) { - printk("%s[%d]: sc_dfs is NULL\n", __func__, __LINE__); - /* DFS_DPRINTK(dfs, ATH_DEBUG_DFS,"%s: sc_dfs is NULL\n",__func__); */ - return NULL; - } - - if (ext_chan_flag) { - cmp_ch = ieee80211_get_extchan(dfs->ic); - if (cmp_ch) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "Extension channel freq = %u flags=0x%x\n", - cmp_ch->ic_freq, cmp_ch->ic_flagext); - } else { - return NULL; - } - - } else { - cmp_ch = dfs->ic->ic_curchan; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "Primary channel freq = %u flags=0x%x\n", - cmp_ch->ic_freq, cmp_ch->ic_flagext); - } - for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { - if ((dfs->dfs_radar[i].rs_chan.ic_freq == cmp_ch->ic_freq) && - (dfs->dfs_radar[i].rs_chan.ic_flags == cmp_ch->ic_flags)) { - if (index != NULL) - *index = (uint8_t) i; - return &(dfs->dfs_radar[i]); - } - } - /* No existing channel found, look for first free channel state entry */ - for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { - if (dfs->dfs_radar[i].rs_chan.ic_freq == 0) { - rs = &(dfs->dfs_radar[i]); - /* Found one, set channel info and default thresholds */ - rs->rs_chan = *cmp_ch; - - /* Copy the parameters from the default set */ - ath_dfs_phyerr_param_copy(&rs->rs_param, - &dfs->dfs_defaultparams); - - if (index != NULL) - *index = (uint8_t) i; - return rs; - } - } - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "%s: No more radar states left.\n", - __func__); - return NULL; -} - -#endif /* ATH_SUPPORT_DFS */ diff --git a/core/sap/dfs/src/dfs_nol.c b/core/sap/dfs/src/dfs_nol.c deleted file mode 100644 index 85810bcd2b05..000000000000 --- a/core/sap/dfs/src/dfs_nol.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (c) 2002-2016 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_nol.c - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#include "dfs.h" -/* TO DO DFS - #include - */ -#ifndef UNINET -/*TO DO DFS - #include - */ -#endif -#if defined(ATH_SUPPORT_DFS) && !defined(ATH_DFS_RADAR_DETECTION_ONLY) -#include "dfs_ioctl.h" -#include "dfs_ioctl_private.h" -#include "qdf_time.h" /* qdf_time_t, qdf_system_time_after */ - -static void -dfs_nol_delete(struct ath_dfs *dfs, uint16_t delfreq, uint16_t delchwidth); - -static os_timer_func(dfs_remove_from_nol) -{ - struct dfs_nol_timer_arg *nol_arg; - struct ath_dfs *dfs; - struct ieee80211com *ic; - uint16_t delfreq; - uint16_t delchwidth; - - OS_GET_TIMER_ARG(nol_arg, struct dfs_nol_timer_arg *); - - dfs = nol_arg->dfs; - ic = dfs->ic; - delfreq = nol_arg->delfreq; - delchwidth = nol_arg->delchwidth; - - /* Only operate in HOSTAP/IBSS */ - if (ic->ic_opmode != IEEE80211_M_HOSTAP && - ic->ic_opmode != IEEE80211_M_IBSS) - goto done; - - /* Delete the given NOL entry */ - dfs_nol_delete(dfs, delfreq, delchwidth); - - /* Update the wireless stack with the new NOL */ - dfs_nol_update(dfs); - -done: - OS_FREE(nol_arg); - return; -} - -void dfs_print_nol(struct ath_dfs *dfs) -{ - struct dfs_nolelem *nol; - uint32_t diff_ms, remaining_sec; - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL", - __func__); - return; - } - nol = dfs->dfs_nol; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: NOL", __func__); - while (nol != NULL) { - diff_ms = - qdf_system_ticks_to_msecs(qdf_system_ticks() - - nol->nol_start_ticks); - diff_ms = (nol->nol_timeout_ms - diff_ms); - remaining_sec = diff_ms / 1000; /* convert to seconds */ - nol = nol->nol_next; - } -} - -void -dfs_get_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int *nchan) -{ - struct dfs_nolelem *nol; - - *nchan = 0; - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL", - __func__); - return; - } - - nol = dfs->dfs_nol; - while (nol != NULL) { - dfs_nol[*nchan].nol_freq = nol->nol_freq; - dfs_nol[*nchan].nol_chwidth = nol->nol_chwidth; - dfs_nol[*nchan].nol_start_ticks = nol->nol_start_ticks; - dfs_nol[*nchan].nol_timeout_ms = nol->nol_timeout_ms; - ++(*nchan); - nol = nol->nol_next; - } -} - -void dfs_set_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int nchan) -{ -#define TIME_IN_MS 1000 - uint32_t nol_time_left_ms; - struct dfs_ieee80211_channel chan; - int i; - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL", - __func__); - return; - } - - for (i = 0; i < nchan; i++) { - nol_time_left_ms = - qdf_system_ticks_to_msecs(qdf_system_ticks() - - dfs_nol[i].nol_start_ticks); - if (nol_time_left_ms < dfs_nol[i].nol_timeout_ms) { - chan.ic_freq = dfs_nol[i].nol_freq; - chan.ic_flags = 0; - chan.ic_flagext = 0; - nol_time_left_ms = - (dfs_nol[i].nol_timeout_ms - nol_time_left_ms); - dfs_nol_addchan(dfs, &chan, - (nol_time_left_ms / TIME_IN_MS)); - } - } -#undef TIME_IN_MS - dfs_nol_update(dfs); -} - -void -dfs_nol_addchan(struct ath_dfs *dfs, struct dfs_ieee80211_channel *chan, - uint32_t dfs_nol_timeout) -{ -#define TIME_IN_MS 1000 -#define TIME_IN_US (TIME_IN_MS * 1000) - struct dfs_nolelem *nol, *elem, *prev; - struct dfs_nol_timer_arg *dfs_nol_arg; - /* XXX for now, assume all events are 20MHz wide */ - int ch_width = 20; - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL", - __func__); - return; - } - nol = dfs->dfs_nol; - prev = dfs->dfs_nol; - elem = NULL; - while (nol != NULL) { - if ((nol->nol_freq == chan->ic_freq) && - (nol->nol_chwidth == ch_width)) { - nol->nol_start_ticks = qdf_system_ticks(); - nol->nol_timeout_ms = dfs_nol_timeout * TIME_IN_MS; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, - "%s: Update OS Ticks for NOL %d MHz / %d MHz", - __func__, nol->nol_freq, nol->nol_chwidth); - OS_CANCEL_TIMER(&nol->nol_timer); - OS_SET_TIMER(&nol->nol_timer, - dfs_nol_timeout * TIME_IN_MS); - return; - } - prev = nol; - nol = nol->nol_next; - } - /* Add a new element to the NOL */ - elem = - (struct dfs_nolelem *)os_malloc(NULL, sizeof(struct dfs_nolelem), - GFP_ATOMIC); - if (elem == NULL) { - goto bad; - } - dfs_nol_arg = (struct dfs_nol_timer_arg *)os_malloc(NULL, - sizeof(struct - dfs_nol_timer_arg), - GFP_ATOMIC); - if (dfs_nol_arg == NULL) { - OS_FREE(elem); - goto bad; - } - elem->nol_freq = chan->ic_freq; - elem->nol_chwidth = ch_width; - elem->nol_start_ticks = qdf_system_ticks(); - elem->nol_timeout_ms = dfs_nol_timeout * TIME_IN_MS; - elem->nol_next = NULL; - if (prev) { - prev->nol_next = elem; - } else { - /* This is the first element in the NOL */ - dfs->dfs_nol = elem; - } - dfs_nol_arg->dfs = dfs; - dfs_nol_arg->delfreq = elem->nol_freq; - dfs_nol_arg->delchwidth = elem->nol_chwidth; - - OS_INIT_TIMER(NULL, &elem->nol_timer, dfs_remove_from_nol, - dfs_nol_arg, QDF_TIMER_TYPE_SW); - OS_SET_TIMER(&elem->nol_timer, dfs_nol_timeout * TIME_IN_MS); - - /* Update the NOL counter */ - dfs->dfs_nol_count++; - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, - "%s: new NOL channel %d MHz / %d MHz", - __func__, elem->nol_freq, elem->nol_chwidth); - return; - -bad: - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL | ATH_DEBUG_DFS, - "%s: failed to allocate memory for nol entry", __func__); - -#undef TIME_IN_MS -#undef TIME_IN_US -} - -/* - * Delete the given frequency/chwidth from the NOL. - */ -static void -dfs_nol_delete(struct ath_dfs *dfs, uint16_t delfreq, uint16_t delchwidth) -{ - struct dfs_nolelem *nol, **prev_next; - - if (dfs == NULL) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL", __func__); - return; - } - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, - "%s: remove channel=%d/%d MHz from NOL", - __func__, delfreq, delchwidth); - prev_next = &(dfs->dfs_nol); - nol = dfs->dfs_nol; - while (nol != NULL) { - if (nol->nol_freq == delfreq && nol->nol_chwidth == delchwidth) { - *prev_next = nol->nol_next; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, - "%s removing channel %d/%dMHz from NOL tstamp=%d", - __func__, nol->nol_freq, nol->nol_chwidth, - (qdf_system_ticks_to_msecs - (qdf_system_ticks()) / 1000)); - OS_CANCEL_TIMER(&nol->nol_timer); - OS_FREE(nol); - nol = NULL; - nol = *prev_next; - - /* Update the NOL counter */ - dfs->dfs_nol_count--; - - /* Be paranoid! */ - if (dfs->dfs_nol_count < 0) { - DFS_PRINTK("%s: dfs_nol_count < 0; eek!", - __func__); - dfs->dfs_nol_count = 0; - } - - } else { - prev_next = &(nol->nol_next); - nol = nol->nol_next; - } - } -} - -/* - * notify the driver/umac that it should update the channel radar/NOL - * flags based on the current NOL list. - */ -void dfs_nol_update(struct ath_dfs *dfs) -{ - struct ieee80211com *ic = dfs->ic; - struct dfs_nol_chan_entry *dfs_nol; - struct dfs_nolelem *nol; - int nlen; - - /* - * Allocate enough entries to store the NOL. - * - * At least on Linux (don't ask why), if you allocate a 0 entry - * array, the returned pointer is 0x10. Make sure you're - * aware of this when you start debugging. - */ - dfs_nol = (struct dfs_nol_chan_entry *)os_malloc(NULL, - sizeof(struct - dfs_nol_chan_entry) - * dfs->dfs_nol_count, - GFP_ATOMIC); - - if (dfs_nol == NULL) { - /* - * XXX TODO: if this fails, just schedule a task to retry - * updating the NOL at a later stage. That way the NOL - * update _DOES_ happen - hopefully the failure was just - * temporary. - */ - DFS_PRINTK("%s: failed to allocate NOL update memory!", - __func__); - return; - } - - /* populate the nol array */ - nlen = 0; - - nol = dfs->dfs_nol; - while (nol != NULL && nlen < dfs->dfs_nol_count) { - dfs_nol[nlen].nol_chfreq = nol->nol_freq; - dfs_nol[nlen].nol_chwidth = nol->nol_chwidth; - dfs_nol[nlen].nol_start_ticks = nol->nol_start_ticks; - dfs_nol[nlen].nol_timeout_ms = nol->nol_timeout_ms; - nlen++; - nol = nol->nol_next; - } - - /* Be suitably paranoid for now */ - if (nlen != dfs->dfs_nol_count) - DFS_PRINTK("%s: nlen (%d) != dfs->dfs_nol_count (%d)!", - __func__, nlen, dfs->dfs_nol_count); - - /* - * Call the driver layer to have it recalculate the NOL flags for - * each driver/umac channel. - * - * If the list is empty, pass NULL instead of dfs_nol. - * - * The operating system may have some special representation for - * "malloc a 0 byte memory region" - for example, - * Linux 2.6.38-13 (ubuntu) returns 0x10 rather than a valid - * allocation (and is likely not NULL so the pointer doesn't - * match NULL checks in any later code. - */ - ic->ic_dfs_clist_update(ic, DFS_NOL_CLIST_CMD_UPDATE, - (nlen > 0) ? dfs_nol : NULL, nlen); - - /* - * .. and we're done. - */ - OS_FREE(dfs_nol); -} - -void dfs_nol_timer_cleanup(struct ath_dfs *dfs) -{ - struct dfs_nolelem *nol = dfs->dfs_nol, *prev; - - /* First Cancel timer */ - while (nol) { - OS_CANCEL_TIMER(&nol->nol_timer); - nol = nol->nol_next; - } - /* Free NOL elem, don't mix this while loop with above loop */ - nol = dfs->dfs_nol; - while (nol) { - prev = nol; - nol = nol->nol_next; - OS_FREE(prev); - } - return; -} -#endif /* defined(ATH_SUPPORT_DFS) && !defined(ATH_DFS_RADAR_DETECTION_ONLY) */ diff --git a/core/sap/dfs/src/dfs_phyerr.h b/core/sap/dfs/src/dfs_phyerr.h deleted file mode 100644 index 22a900f2e060..000000000000 --- a/core/sap/dfs/src/dfs_phyerr.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/* - * dfs_phyerr.h - * - * OVERVIEW: - * - * Source code borrowed from QCA_MAIN DFS module - * - * DEPENDENCIES: - * - * Are listed for each API below. - */ - - -#ifndef __DFS_PHYERR_H__ -#define __DFS_PHYERR_H__ - -extern int dfs_process_phyerr_bb_tlv(struct ath_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, - bool enable_log); - -#endif /* __DFS_PHYERR_H__ */ diff --git a/core/sap/dfs/src/dfs_phyerr_tlv.c b/core/sap/dfs/src/dfs_phyerr_tlv.c deleted file mode 100644 index 0f50a9e6126e..000000000000 --- a/core/sap/dfs/src/dfs_phyerr_tlv.c +++ /dev/null @@ -1,946 +0,0 @@ -/* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -#include "dfs.h" -/* TO DO DFS - #include - */ -/* TO DO DFS - #include - */ -#include "dfs_phyerr.h" -#include "dfs_phyerr_tlv.h" - -/* - * Parsed radar status - */ -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; - /*Parsed only for DFS-3*/ - int radar_subchan_mask; - int rsu_version; - /* - * The parameters below are present only in - * DFS-3 radar summary report and need to be - * parsed only for DFS-3. - */ - /* DFS-3 Only */ - int pulse_height; - /* DFS-3 Only */ - int triggering_agc_event; - /* DFS-3 Only */ - int pulse_rssi; - /* DFS-3 Only */ - int radar_fft_pri80_inband_power; - /* DFS-3 Only */ - int radar_fft_ext80_inband_power; - /* DFS-3 Only */ - int radar_80p80_segid; -}; - -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; -}; - -/* - * XXX until "fastclk" is stored in the DFS configuration.. - */ -#define PERE_IS_OVERSAMPLING(_dfs) (1) - -/* - * XXX there _has_ to be a better way of doing this! - * -adrian - */ -static int32_t sign_extend_32(uint32_t v, int nb) -{ - uint32_t m = 1U << (nb - 1); - - /* Chop off high bits, just in case */ - v &= v & ((1U << nb) - 1); - - /* Extend */ - return (v ^ m) - m; -} - -/* - * Calculate the frequency offset from the given signed bin index - * from the radar summary report. - * - * This takes the oversampling mode into account. - * - * For oversampling, each bin has resolution 44MHz/128. - * For non-oversampling, each bin has resolution 40MHz/128. - * - * It returns kHz - ie, 1000th's of MHz. - */ -static int calc_freq_offset(int sindex, int is_oversampling) -{ - - if (is_oversampling) - return sindex * (44000 / 128); - else - return sindex * (40000 / 128); -} - -static void -radar_summary_print(struct ath_dfs *dfs, - struct rx_radar_status *rsu, - bool enable_log) -{ - int is_chip_oversampling; - - if (!enable_log) - return; - - /* - * Oversampling needs to be turned on for - * older chipsets that support DFS-2. - * it needs to be turned off for chips - * that support DFS-3. - */ - if (dfs->ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) - is_chip_oversampling = 0; - else - is_chip_oversampling = PERE_IS_OVERSAMPLING(dfs); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "\n ############ Radar Summary ############\n"); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Radar Summary - pulsedur = %d micro seconds\n", __func__, - rsu->pulse_duration); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Radar Summary - rssi = %d dbm\n", __func__, - rsu->rssi); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Radar Summary - ischirp = %d\n", __func__, - rsu->is_chirp); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Radar Summary - sidx = %d\n", __func__, - rsu->sidx); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Radar Summary - delta_peak = %d\n", __func__, - rsu->delta_peak); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Radar Summary - delta_diff = %d\n", __func__, - rsu->delta_diff); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Radar Summary - raw tsf = %d\n", __func__, - rsu->raw_tsf); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Radar Summary - tsf_offset = %d micro seconds\n", - __func__, rsu->tsf_offset); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Radar Summary - cooked tsf = %d\n", __func__, - (rsu->raw_tsf - rsu->tsf_offset)); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: frequency offset = %d.%d MHz (oversampling = %d)\n", - __func__, (int) (rsu->freq_offset / 1000), - (int) abs(rsu->freq_offset % 1000), - is_chip_oversampling); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "\n ###################################\n"); -} - -/* - * Parse the radar summary frame. - * - * The frame contents _minus_ the TLV are passed in. - */ -static void -radar_summary_parse(struct ath_dfs *dfs, const char *buf, size_t len, - struct rx_radar_status *rsu) -{ - uint32_t rs[2]; - uint32_t dfs3_rs[5]; - int freq_centre, freq; - int is_chip_oversampling; - - /* - * Drop out if we have < 2 DWORDs available for DFS-2 - * and drop out if we have < 5 DWORDS available for DFS-3 - */ - if ((dfs->ic->dfs_hw_bd_id == DFS_HWBD_QCA6174) && - (len < sizeof(rs))) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s: DFS-2 radar summary len = (%zu) wrong, expected = (%zu)", - __func__, len, sizeof(rs)); - } else if ((dfs->ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) && - (len < sizeof(dfs3_rs))) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s: DFS-3 radar summary len = (%zu) wrong, expected = (%zu)", - __func__, len, sizeof(dfs3_rs)); - } - - /* - * If the length of TLV is equal to - * DFS3_RADAR_PULSE_SUMMARY_TLV_LENGTH - * then it means the radar summary report - * has 5 DWORDS and we need to parse the - * report accordingly. - * Else if the length is equal to - * DFS2_RADAR_PULSE_SUMMARY_TLV_LENGTH then - * it the radar summary report will have only - * two DWORDS so we parse for only two DWORDS. - */ - if (len == DFS3_RADAR_PULSE_SUMMARY_TLV_LENGTH) { - /* - * Since the TLVs may be unaligned for some reason - * we take a private copy into aligned memory. - * This enables us to use the HAL-like accessor macros - * into the DWORDs to access sub-DWORD fields. - */ - OS_MEMCPY(dfs3_rs, buf, sizeof(dfs3_rs)); - - /* - * Oversampling is only needed to be - * turned on for older chips that support - * DFS-2. It needs to be turned off for chips - * that support DFS-3. - */ - is_chip_oversampling = 0; - - /* - * populate the version of the radar summary report - * based on the TLV length to differentiate between - * DFS-2 and DFS-3 radar summary report. - */ - rsu->rsu_version = DFS_RADAR_SUMMARY_REPORT_VERSION_3; - - /* Populate the fields from the summary report */ - rsu->tsf_offset = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_2], - RADAR_REPORT_PULSE_TSF_OFFSET); - rsu->pulse_duration = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_2], - RADAR_REPORT_PULSE_DUR); - rsu->is_chirp = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_PULSE_IS_CHIRP); - rsu->sidx = sign_extend_32(MS(dfs3_rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_PULSE_SIDX), 10); - rsu->freq_offset = calc_freq_offset(rsu->sidx, - is_chip_oversampling); - /* These are only relevant if the pulse is a chirp */ - rsu->delta_peak = sign_extend_32( - MS(dfs3_rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_PULSE_DELTA_PEAK), - 6); - rsu->delta_diff = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_PULSE_DELTA_DIFF); - /* For false detection Debug */ - rsu->agc_total_gain = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_AGC_TOTAL_GAIN); - rsu->agc_mb_gain = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_2], - RADAR_REPORT_PULSE_AGC_MB_GAIN); - /* - * radar_subchan_mask will be used in the future to identify the - * sub channel that encoutered radar pulses and block those - * channels in NOL accordingly. - */ - rsu->radar_subchan_mask = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_2], - RADAR_REPORT_PULSE_SUBCHAN_MASK); - - rsu->pulse_height = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_3], - RADAR_REPORT_PULSE_HEIGHT); - rsu->triggering_agc_event = - MS(dfs3_rs[RADAR_REPORT_PULSE_REG_4], - RADAR_REPORT_TRIGGERING_AGC_EVENT); - rsu->pulse_rssi = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_4], - RADAR_REPORT_PULSE_RSSI); - rsu->radar_fft_pri80_inband_power = - MS(dfs3_rs[RADAR_REPORT_PULSE_REG_5], - RADAR_REPORT_FFT_PRI80_INBAND_POWER); - rsu->radar_fft_ext80_inband_power = - MS(dfs3_rs[RADAR_REPORT_PULSE_REG_5], - RADAR_REPORT_FFT_EXT80_INBAND_POWER); - rsu->radar_80p80_segid = MS(dfs3_rs[RADAR_REPORT_PULSE_REG_5], - RADAR_REPORT_80P80_SEGID); - } else { - /* - * Since the TLVs may be unaligned for some reason - * we take a private copy into aligned memory. - * This enables us to use the HAL-like accessor macros - * into the DWORDs to access sub-DWORD fields. - */ - OS_MEMCPY(rs, buf, sizeof(rs)); - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s: two 32 bit values are: %08x %08x", __func__, rs[0], - rs[1]); - /* - * DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s (p=%pK):", __func__, buf); - */ - - is_chip_oversampling = PERE_IS_OVERSAMPLING(dfs); - /* - * populate the version of the radar summary report - * based on the TLV length to differentiate between - * DFS-2 and DFS-3 radar summary report. - */ - rsu->rsu_version = DFS_RADAR_SUMMARY_REPORT_VERSION_2; - - /* Populate the fields from the summary report */ - rsu->tsf_offset = - MS(rs[RADAR_REPORT_PULSE_REG_2], - RADAR_REPORT_PULSE_TSF_OFFSET); - rsu->pulse_duration = - MS(rs[RADAR_REPORT_PULSE_REG_2], - RADAR_REPORT_PULSE_DUR); - rsu->is_chirp = - MS(rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_PULSE_IS_CHIRP); - rsu->sidx = - sign_extend_32(MS(rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_PULSE_SIDX), 10); - rsu->freq_offset = - calc_freq_offset(rsu->sidx, is_chip_oversampling); - - /* These are only relevant if the pulse is a chirp */ - rsu->delta_peak = - sign_extend_32(MS(rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_PULSE_DELTA_PEAK), 6); - rsu->delta_diff = - MS(rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_PULSE_DELTA_DIFF); - - /* For false detection Debug */ - rsu->agc_total_gain = - MS(rs[RADAR_REPORT_PULSE_REG_1], - RADAR_REPORT_AGC_TOTAL_GAIN); - rsu->agc_mb_gain = - MS(rs[RADAR_REPORT_PULSE_REG_2], - RADAR_REPORT_PULSE_AGC_MB_GAIN); - - } - - /* WAR for FCC Type 4 */ - /* - * HW is giving longer pulse duration (in case of VHT80, with traffic) - * which fails to detect FCC type4 radar pulses. Added a work around to - * fix the pulse duration and duration delta. - * - * IF VHT80 - * && (primary_channel==30MHz || primary_channel== -30MHz) - * && -4 <= pulse_index <= 4 - * && !chirp - * && pulse duration > 20 us - * THEN - * Set pulse duration to 20 us - */ - - qdf_spin_lock_bh(&dfs->ic->chan_lock); - freq = ieee80211_chan2freq(dfs->ic, dfs->ic->ic_curchan); - freq_centre = dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1; - - if ((IEEE80211_IS_CHAN_11AC_VHT80(dfs->ic->ic_curchan) && - (abs(freq - freq_centre) == 30) && - !rsu->is_chirp && - abs(rsu->sidx) <= 4 && rsu->pulse_duration > 20)) { - rsu->pulse_duration = 20; - } - - qdf_spin_unlock_bh(&dfs->ic->chan_lock); -} - -static void -radar_fft_search_report_parse(struct ath_dfs *dfs, const char *buf, size_t len, - struct rx_search_fft_report *rsfr) -{ - uint32_t rs[2]; - - /* Drop out if we have < 2 DWORDs available */ - if (len < sizeof(rs)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | - ATH_DEBUG_DFS_PHYERR_SUM, - "%s: len (%zu) < expected (%zu)!", - __func__, len, sizeof(rs)); - } - - /* - * Since the TLVs may be unaligned for some reason - * we take a private copy into aligned memory. - * This enables us to use the HAL-like accessor macros - * into the DWORDs to access sub-DWORD fields. - */ - OS_MEMCPY(rs, buf, sizeof(rs)); - rsfr->total_gain_db = - MS(rs[SEARCH_FFT_REPORT_REG_1], - SEARCH_FFT_REPORT_TOTAL_GAIN_DB); - rsfr->base_pwr_db = - MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_BASE_PWR_DB); - rsfr->fft_chn_idx = - MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_FFT_CHN_IDX); - rsfr->peak_sidx = - sign_extend_32(MS - (rs[SEARCH_FFT_REPORT_REG_1], - SEARCH_FFT_REPORT_PEAK_SIDX), 12); - rsfr->relpwr_db = - MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_RELPWR_DB); - rsfr->avgpwr_db = - MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_AVGPWR_DB); - rsfr->peak_mag = - MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_PEAK_MAG); - rsfr->num_str_bins_ib = - MS(rs[SEARCH_FFT_REPORT_REG_2], - SEARCH_FFT_REPORT_NUM_STR_BINS_IB); - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s: two 32 bit values are: %08x %08x", __func__, rs[0], - rs[1]); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->total_gain_db = %d", - __func__, rsfr->total_gain_db); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->base_pwr_db = %d", - __func__, rsfr->base_pwr_db); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->fft_chn_idx = %d", - __func__, rsfr->fft_chn_idx); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->peak_sidx = %d", - __func__, rsfr->peak_sidx); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->relpwr_db = %d", - __func__, rsfr->relpwr_db); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->avgpwr_db = %d", - __func__, rsfr->avgpwr_db); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->peak_mag = %d", - __func__, rsfr->peak_mag); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: rsfr->num_str_bins_ib = %d", - __func__, rsfr->num_str_bins_ib); -} - -/* - * Parse a Peregrine BB TLV frame. - * - * This routine parses each TLV, prints out what's going on and - * calls an appropriate sub-function. - * - * Since the TLV format doesn't _specify_ all TLV components are - * DWORD aligned, we must treat them as not and access the fields - * appropriately. - */ -static int -tlv_parse_frame(struct ath_dfs *dfs, struct rx_radar_status *rs, - struct rx_search_fft_report *rsfr, const char *buf, size_t len, - uint8_t rssi) -{ - int i = 0; - uint32_t tlv_hdr[1]; - bool first_tlv = true; - bool false_detect = false; - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s: total length = %zu bytes", __func__, len); - while ((i < len) && (false_detect == false)) { - /* Ensure we at least have four bytes */ - if ((len - i) < sizeof(tlv_hdr)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | - ATH_DEBUG_DFS_PHYERR_SUM, - "%s: ran out of bytes, len=%zu, i=%d", - __func__, len, i); - return 0; - } - - /* - * Copy the offset into the header, - * so the DWORD style access macros - * can be used. - */ - OS_MEMCPY(&tlv_hdr, buf + i, sizeof(tlv_hdr)); - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s: HDR: TLV SIG=0x%x, TAG=0x%x, LEN=%d bytes", - __func__, - MS(tlv_hdr[TLV_REG], TLV_SIG), - MS(tlv_hdr[TLV_REG], TLV_TAG), - MS(tlv_hdr[TLV_REG], TLV_LEN)); - - /* - * Sanity check the length field is available in - * the remaining frame. Drop out if this isn't - * the case - we can't trust the rest of the TLV - * entries. - */ - if (MS(tlv_hdr[TLV_REG], TLV_LEN) + i >= len) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s: TLV oversize: LEN=%d, avail=%zu, i=%d", - __func__, - MS(tlv_hdr[TLV_REG], TLV_LEN), len, i); - break; - } - - /* Skip the TLV header - one DWORD */ - i += sizeof(tlv_hdr); - - /* Handle the payload */ - /* XXX TODO! */ - switch (MS(tlv_hdr[TLV_REG], TLV_SIG)) { - case TAG_ID_RADAR_PULSE_SUMMARY: /* Radar pulse summary */ - /* XXX TODO verify return value */ - /* XXX TODO validate only seeing one of these */ - radar_summary_parse(dfs, buf + i, - MS(tlv_hdr[TLV_REG], TLV_LEN), rs); - break; - case TAG_ID_SEARCH_FFT_REPORT: - radar_fft_search_report_parse(dfs, buf + i, - MS(tlv_hdr[TLV_REG], - TLV_LEN), rsfr); - /* - * we examine search FFT report and make the following - * assumption as per algorithms group's input: - * (1) There may be multiple TLV - * (2) We make false detection decison solely based on - * the first TLV - * (3) If the first TLV is a serch FFT report then we - * check the peak_mag value. When RSSI is equal to - * dfs->ath_dfs_false_rssI_thres (default 50) and - * peak_mag is less than 2 * dfs->ath_dfs_peak_mag - * (default 40) we treat it as false detect. - * Please note that 50 is not a true RSSI estimate, - * but value indicated by HW for RF saturation event. - */ - - if ((first_tlv == true) && - (rssi == dfs->ath_dfs_false_rssi_thres) && - (rsfr->peak_mag < (2 * dfs->ath_dfs_peak_mag))) { - false_detect = true; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s: setting false_detect to true", - __func__); - } - - break; - default: - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s: unknown entry, SIG=0x%02x", - __func__, MS(tlv_hdr[TLV_REG], TLV_SIG)); - } - - /* Skip the payload */ - i += MS(tlv_hdr[TLV_REG], TLV_LEN); - first_tlv = false; - } - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: done", __func__); - - return false_detect ? 0 : 1; -} - -/* - * Calculate the channel centre in MHz. - */ -static int tlv_calc_freq_info(struct ath_dfs *dfs, struct rx_radar_status *rs) -{ - uint32_t chan_centre; - uint32_t chan_width; - int chan_offset; - - /* - * For now, just handle up to VHT80 correctly. - */ - if (dfs->ic == NULL || dfs->ic->ic_curchan == NULL) { - DFS_PRINTK("%s: dfs->ic=%pK, that or curchan is null?", - __func__, dfs->ic); - return 0; - } - - qdf_spin_lock_bh(&dfs->ic->chan_lock); - /* - * calculate the channel center frequency for - * 160MHz and 80p80 MHz including the legacy - * channel widths. - */ - if (IEEE80211_IS_CHAN_11AC_VHT160(dfs->ic->ic_curchan)) { - chan_centre = dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1; - } else if (IEEE80211_IS_CHAN_11AC_VHT80P80(dfs->ic->ic_curchan)) { - if (rs->radar_80p80_segid == DFS_80P80_SEG0) - chan_centre = - dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1; - else - chan_centre = - dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg2; - } else if (IEEE80211_IS_CHAN_11AC_VHT80(dfs->ic->ic_curchan)) { - /* 11AC, so cfreq1/cfreq2 are setup */ - chan_centre = dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1; - } else { - /* HT20/HT40 */ - - /* - * XXX this is hard-coded - it should be 5 or 10 for - * half/quarter appropriately. - */ - chan_width = 20; - - /* Grab default channel centre */ - chan_centre = ieee80211_chan2freq(dfs->ic, dfs->ic->ic_curchan); - - /* Calculate offset based on HT40U/HT40D and VHT40U/VHT40D */ - if (IEEE80211_IS_CHAN_11N_HT40PLUS(dfs->ic->ic_curchan) || - dfs->ic->ic_curchan->ic_flags & IEEE80211_CHAN_VHT40PLUS) - chan_offset = chan_width; - else if (IEEE80211_IS_CHAN_11N_HT40MINUS(dfs->ic->ic_curchan) || - dfs->ic->ic_curchan-> - ic_flags & IEEE80211_CHAN_VHT40MINUS) - chan_offset = -chan_width; - else - chan_offset = 0; - - /* Calculate new _real_ channel centre */ - chan_centre += (chan_offset / 2); - } - - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - /* - * XXX half/quarter rate support! - */ - - /* Return ev_chan_centre in MHz */ - return chan_centre; -} - -/* - * Calculate the centre frequency and low/high range for a radar pulse event. - * - * XXX TODO: Handle half/quarter rates correctly! - * XXX TODO: handle VHT160 correctly! - * XXX TODO: handle VHT80+80 correctly! - */ -static int -tlv_calc_event_freq_pulse(struct ath_dfs *dfs, struct rx_radar_status *rs, - uint32_t *freq_centre, uint32_t *freq_lo, - uint32_t *freq_hi) -{ - int chan_width; - int chan_centre; - int is_chip_oversampling; - - /* - * Oversampling needs to be turned on for - * older chipsets that support DFS-2. - * it needs to be turned off for chips - * that support DFS-3. - */ - if (dfs->ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) - is_chip_oversampling = 0; - else - is_chip_oversampling = PERE_IS_OVERSAMPLING(dfs); - - /* Fetch the channel centre frequency in MHz */ - chan_centre = tlv_calc_freq_info(dfs, rs); - - /* Convert to KHz */ - chan_centre *= 1000; - - /* - * XXX hard-code event width to be 2 * bin size for now; - * XXX this needs to take into account the core clock speed - * XXX for half/quarter rate mode. - */ - if (is_chip_oversampling) - chan_width = (44000 * 2 / 128); - else - chan_width = (40000 * 2 / 128); - - /* XXX adjust chan_width for half/quarter rate! */ - - /* - * Now we can do the math to figure out the correct channel range. - */ - (*freq_centre) = (uint32_t) (chan_centre + rs->freq_offset); - (*freq_lo) = (uint32_t) ((chan_centre + rs->freq_offset) - - chan_width); - (*freq_hi) = (uint32_t) ((chan_centre + rs->freq_offset) - + chan_width); - - return 1; -} - -/* - * The chirp bandwidth in KHz is defined as: - * - * totalBW(KHz) = delta_peak(mean) - * * [ (bin resolution in KHz) / (radar_fft_long_period in uS) ] - * * pulse_duration (us) - * - * The bin resolution depends upon oversampling. - * - * For now, we treat the radar_fft_long_period as a hard-coded 8uS. - */ -static int -tlv_calc_event_freq_chirp(struct ath_dfs *dfs, struct rx_radar_status *rs, - uint32_t *freq_centre, uint32_t *freq_lo, - uint32_t *freq_hi) -{ - int32_t bin_resolution; /* KHz * 100 */ - int32_t radar_fft_long_period = 8; /* microseconds */ - int32_t delta_peak; - int32_t pulse_duration; - int32_t total_bw; - int32_t chan_centre; - int32_t freq_1, freq_2; - int is_chip_oversampling; - - /* - * Oversampling needs to be turned on for - * older chipsets that support DFS-2. - * it needs to be turned off for chips - * that support DFS-3. - */ - if (dfs->ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) - is_chip_oversampling = 0; - else - is_chip_oversampling = PERE_IS_OVERSAMPLING(dfs); - - /* - * KHz isn't enough resolution here! - * So treat it as deci-hertz (10Hz) and convert back to KHz - * later. - */ - if (is_chip_oversampling) - bin_resolution = (44000 * 100) / 128; - else - bin_resolution = (40000 * 100) / 128; - - delta_peak = rs->delta_peak; - pulse_duration = rs->pulse_duration; - - total_bw = delta_peak * (bin_resolution / radar_fft_long_period) * - pulse_duration; - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | ATH_DEBUG_DFS_PHYERR_SUM, - "%s: delta_peak=%d, pulse_duration=%d, bin_resolution=%d.%dKHz, " - "radar_fft_long_period=%d, total_bw=%d.%dKHz", - __func__, - delta_peak, - pulse_duration, - bin_resolution / 1000, - bin_resolution % 1000, - radar_fft_long_period, - total_bw / 100, - (int)abs(total_bw % 100)); - - total_bw /= 100; /* back to KHz */ - - /* Grab the channel centre frequency in MHz */ - chan_centre = tlv_calc_freq_info(dfs, rs); - - /* Early abort! */ - if (chan_centre == 0) { - (*freq_centre) = 0; - return 0; - } - - /* Convert to KHz */ - chan_centre *= 1000; - - /* - * sidx is the starting frequency; total_bw is a signed value and - * for negative chirps (ie, moving down in frequency rather than up) - * the end frequency may be less than the start frequency. - */ - if (total_bw > 0) { - freq_1 = chan_centre + rs->freq_offset; - freq_2 = chan_centre + rs->freq_offset + total_bw; - } else { - freq_1 = chan_centre + rs->freq_offset + total_bw; - freq_2 = chan_centre + rs->freq_offset; - } - - (*freq_lo) = (uint32_t) (freq_1); - (*freq_hi) = (uint32_t) (freq_2); - (*freq_centre) = (uint32_t) (freq_1 + (abs(total_bw) / 2)); - - return 1; -} - -/* - * Calculate the centre and band edge frequencies of the given radar - * event. - */ -static int -tlv_calc_event_freq(struct ath_dfs *dfs, struct rx_radar_status *rs, - uint32_t *freq_centre, uint32_t *freq_lo, - uint32_t *freq_hi) -{ - if (rs->is_chirp) - return tlv_calc_event_freq_chirp(dfs, rs, freq_centre, - freq_lo, freq_hi); - else - return tlv_calc_event_freq_pulse(dfs, rs, freq_centre, - freq_lo, freq_hi); -} - -/* - * This is the public facing function which parses the PHY error - * and populates the dfs_phy_err struct. - */ -int -dfs_process_phyerr_bb_tlv(struct ath_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, - bool enable_log) -{ - struct rx_radar_status rs; - struct rx_search_fft_report rsfr; - static int invalid_phyerr_count; - - OS_MEMZERO(&rs, sizeof(rs)); - - /* - * Add the ppdu_start/ppdu_end fields given to us by the upper - * layers. The firmware gives us a summary set of parameters rather - * than the whole PPDU_START/PPDU_END descriptor contenst. - */ - rs.rssi = rssi; - rs.raw_tsf = rs_tstamp; - /* - * Try parsing the TLV set. - */ - qdf_mem_zero(&rsfr, sizeof(rsfr)); - if (!tlv_parse_frame(dfs, &rs, &rsfr, buf, datalen, rssi)) { - invalid_phyerr_count++; - /* - * Print only at every 2 power times - * to avoid flushing of the kernel - * logs, since the frequency of - * invalid phyerrors is very high - * in noisy environments. - */ - if (!(invalid_phyerr_count & 0xFF)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s[%d]:parse failed invalid phyerror cnt = %d", - __func__, __LINE__, invalid_phyerr_count); - } - return 0; - } - /* For debugging, print what we have parsed */ - radar_summary_print(dfs, &rs, enable_log); - - /* Populate dfs_phy_err from rs */ - OS_MEMSET(e, 0, sizeof(*e)); - e->rssi = rs.rssi; - e->dur = rs.pulse_duration; - e->sidx = rs.sidx; - e->is_pri = 1; /* XXX always PRI for now */ - e->is_ext = 0; - e->is_dc = 0; - e->is_early = 0; - - /* - * Copy the segment ID from the radar summary report - * only when radar summary report version is DFS-3. - */ - if (rs.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) { - e->radar_80p80_segid = rs.radar_80p80_segid; - e->delta_peak = rs.delta_peak; - e->delta_diff = rs.delta_diff; - e->agc_total_gain = rs.agc_total_gain; - e->agc_mb_gain = rs.agc_mb_gain; - e->radar_subchan_mask = rs.radar_subchan_mask; - e->pulse_height = rs.pulse_height; - e->triggering_agc_event = rs.triggering_agc_event; - e->pulse_rssi = rs.pulse_rssi; - e->radar_fft_pri80_inband_power = - rs.radar_fft_pri80_inband_power; - e->radar_fft_ext80_inband_power = - rs.radar_fft_ext80_inband_power; - e->rsu_version = rs.rsu_version; - e->peak_mag = rsfr.peak_mag; - - /* - * RSSI_COMB is not reliable indicator of RSSI - * for extension80 when operating in 80p80 - * non-contiguous mode due to existing hardware - * bug. Added workaround in software to use - * pulse_rssi instead of RSSI_COMB. - */ - - if ((dfs->ic->ic_curchan->ic_flags & - IEEE80211_CHAN_VHT80P80) && - (rs.radar_80p80_segid == DFS_80P80_SEG1)) - e->rssi = rs.pulse_rssi; - } - /* - * XXX TODO: add a "chirp detection enabled" capability or config - * bit somewhere, in case for some reason the hardware chirp - * detection AND FFTs are disabled. - */ - /* For now, assume this hardware always does chirp detection */ - e->do_check_chirp = 1; - e->is_hw_chirp = !!(rs.is_chirp); - e->is_sw_chirp = 0; /* We don't yet do software chirp checking */ - - e->fulltsf = fulltsf; - e->rs_tstamp = rs.raw_tsf - rs.tsf_offset; - - /* XXX error check */ - (void)tlv_calc_event_freq(dfs, &rs, &e->freq, &e->freq_lo, &e->freq_hi); - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM, - "%s: fbin=%d, freq=%d.%d MHz, raw tsf=%u, offset=%d, " - "cooked tsf=%u, rssi=%d, dur=%d, is_chirp=%d, fulltsf=%llu, " - "freq=%d.%d MHz, freq_lo=%d.%dMHz, freq_hi=%d.%d MHz", - __func__, - rs.sidx, - (int)(rs.freq_offset / 1000), - (int)abs(rs.freq_offset % 1000), - rs.raw_tsf, - rs.tsf_offset, - e->rs_tstamp, - rs.rssi, - rs.pulse_duration, - (int)rs.is_chirp, - (unsigned long long)fulltsf, - (int)e->freq / 1000, - (int)abs(e->freq) % 1000, - (int)e->freq_lo / 1000, - (int)abs(e->freq_lo) % 1000, - (int)e->freq_hi / 1000, (int)abs(e->freq_hi) % 1000); - - return 1; -} diff --git a/core/sap/dfs/src/dfs_phyerr_tlv.h b/core/sap/dfs/src/dfs_phyerr_tlv.h deleted file mode 100644 index 3e9932e98f8a..000000000000 --- a/core/sap/dfs/src/dfs_phyerr_tlv.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_phyerr_tlv.h - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -#ifndef __DFS_PHYERR_PEREGRINE_H__ -#define __DFS_PHYERR_PEREGRINE_H__ - -/* - * Register manipulation macros that expect bit field defines - * to follow the convention that an _S suffix is appended for - * a shift count, while the field mask has no suffix. - */ -#undef SM -#undef MS -#define SM(_v, _f) (((_v) << _f ## _S) & _f) -#define MS(_v, _f) (((_v) & _f) >> _f ## _S) - -/* - * The TLV dword is at the beginning of each TLV section. - */ -#define TLV_REG 0x00 - -#define TLV_LEN 0x0000FFFF -#define TLV_LEN_S 0 - -#define TLV_SIG 0x00FF0000 -#define TLV_SIG_S 16 - -#define TLV_TAG 0xFF000000 -#define TLV_TAG_S 24 - -#define TAG_ID_SEARCH_FFT_REPORT 0xFB -#define TAG_ID_RADAR_PULSE_SUMMARY 0xF8 - -/* DFS-2 Radar pulse summary Length */ -#define DFS2_RADAR_PULSE_SUMMARY_TLV_LENGTH 8 - -/* DFS-3 Radar pulse summary length */ -#define DFS3_RADAR_PULSE_SUMMARY_TLV_LENGTH 20 - -/* - * Radar pulse summary - * - * + TYPE=0xF8 (Radar pulse summary reprot) - * + SIG=0xBB (baseband PHY generated TLV components) - */ - -#define RADAR_REPORT_PULSE_REG_1 0x00 - -#define RADAR_REPORT_PULSE_IS_CHIRP 0x80000000 -#define RADAR_REPORT_PULSE_IS_CHIRP_S 31 - -#define RADAR_REPORT_PULSE_IS_MAX_WIDTH 0x40000000 -#define RADAR_REPORT_PULSE_IS_MAX_WIDTH_S 30 - -#define RADAR_REPORT_AGC_TOTAL_GAIN 0x3FF00000 -#define RADAR_REPORT_AGC_TOTAL_GAIN_S 20 - -#define RADAR_REPORT_PULSE_DELTA_DIFF 0x000F0000 -#define RADAR_REPORT_PULSE_DELTA_DIFF_S 16 - -#define RADAR_REPORT_PULSE_DELTA_PEAK 0x0000FC00 -#define RADAR_REPORT_PULSE_DELTA_PEAK_S 10 - -#define RADAR_REPORT_PULSE_SIDX 0x000003FF -#define RADAR_REPORT_PULSE_SIDX_S 0x0 - -#define RADAR_REPORT_PULSE_REG_2 0x01 - -#define RADAR_REPORT_PULSE_SRCH_FFT_A_VALID 0x80000000 -#define RADAR_REPORT_PULSE_SRCH_FFT_A_VALID_S 31 - -#define RADAR_REPORT_PULSE_AGC_MB_GAIN 0x7F000000 -#define RADAR_REPORT_PULSE_AGC_MB_GAIN_S 24 - -#define RADAR_REPORT_PULSE_SUBCHAN_MASK 0x00FF0000 -#define RADAR_REPORT_PULSE_SUBCHAN_MASK_S 16 - -#define RADAR_REPORT_PULSE_TSF_OFFSET 0x0000FF00 -#define RADAR_REPORT_PULSE_TSF_OFFSET_S 8 - -#define RADAR_REPORT_PULSE_DUR 0x000000FF -#define RADAR_REPORT_PULSE_DUR_S 0 - -/* - * These are the new TLV's in the DFS-3 - * radar summary report. Three new DWORDS - * have been added to radar summary report - * as part of DFS-3 as defined below. - */ - -#define RADAR_REPORT_PULSE_REG_3 0x02 - -#define RADAR_REPORT_PULSE_HEIGHT 0x000003FF -#define RADAR_REPORT_PULSE_HEIGHT_S 0 - -#define RADAR_REPORT_PULSE_REG_4 0x03 - -#define RADAR_REPORT_TRIGGERING_AGC_EVENT 0xC0000000 -#define RADAR_REPORT_TRIGGERING_AGC_EVENT_S 30 - -#define RADAR_REPORT_PULSE_RSSI 0X3FFC0000 -#define RADAR_REPORT_PULSE_RSSI_S 18 - -#define RADAR_REPORT_PULSE_REG_5 0x04 - -#define RADAR_REPORT_FFT_PRI80_INBAND_POWER 0x1FFF8000 -#define RADAR_REPORT_FFT_PRI80_INBAND_POWER_S 15 - -#define RADAR_REPORT_FFT_EXT80_INBAND_POWER 0x00007FFE -#define RADAR_REPORT_FFT_EXT80_INBAND_POWER_S 1 - -#define RADAR_REPORT_80P80_SEGID 0x00000001 -#define RADAR_REPORT_80P80_SEGID_S 0 - -#define SEARCH_FFT_REPORT_REG_1 0x00 - -#define SEARCH_FFT_REPORT_TOTAL_GAIN_DB 0xFF800000 -#define SEARCH_FFT_REPORT_TOTAL_GAIN_DB_S 23 - -#define SEARCH_FFT_REPORT_BASE_PWR_DB 0x007FC000 -#define SEARCH_FFT_REPORT_BASE_PWR_DB_S 14 - -#define SEARCH_FFT_REPORT_FFT_CHN_IDX 0x00003000 -#define SEARCH_FFT_REPORT_FFT_CHN_IDX_S 12 - -#define SEARCH_FFT_REPORT_PEAK_SIDX 0x00000FFF -#define SEARCH_FFT_REPORT_PEAK_SIDX_S 0 - -#define SEARCH_FFT_REPORT_REG_2 0x01 - -#define SEARCH_FFT_REPORT_RELPWR_DB 0xFC000000 -#define SEARCH_FFT_REPORT_RELPWR_DB_S 26 - -#define SEARCH_FFT_REPORT_AVGPWR_DB 0x03FC0000 -#define SEARCH_FFT_REPORT_AVGPWR_DB_S 18 - -#define SEARCH_FFT_REPORT_PEAK_MAG 0x0003FF00 -#define SEARCH_FFT_REPORT_PEAK_MAG_S 8 - -#define SEARCH_FFT_REPORT_NUM_STR_BINS_IB 0x000000FF -#define SEARCH_FFT_REPORT_NUM_STR_BINS_IB_S 0 - -/* - * Although this code is now not parsing the whole frame (descriptor - * and all), the relevant fields are still useful information - * for anyone who is working on the PHY error part of DFS pattern - * matching. - * - * However, to understand _where_ these descriptors start, you - * should do some digging into the peregrine descriptor format. - * The 30 second version: each RX ring has a bitmap listing which - * descriptors are to be included, and then a set of offsets - * into the RX buffer for where each descriptor will be written. - * It's not like the 802.11n generation hardware which has - * a fixed descriptor format. - */ - -/* - * RX_PPDU_START - */ -#define RX_PPDU_START_LEN (10*4) - -#define RX_PPDU_START_REG_4 0x0004 -#define RX_PPDU_START_RSSI_COMB 0x000000FF -#define RX_PPDU_START_RSSI_COMB_S 0 - -/* - * RX_PPDU_END - */ -#define RX_PPDU_END_LEN (21*4) - -#define RX_PPDU_END_REG_16 16 -#define RX_PPDU_END_TSF_TIMESTAMP 0xFFFFFFFF -#define RX_PPDU_END_TSF_TIMESTAMP_S 0 - -#define RX_PPDU_END_REG_18 18 -#define RX_PPDU_END_PHY_ERR_CODE 0x0000FF00 -#define RX_PPDU_END_PHY_ERR_CODE_S 8 -#define RX_PPDU_END_PHY_ERR 0x00010000 -#define RX_PPDU_END_PHY_ERR_S 16 - -/* - * The RSSI values can have "special meanings". - * - * If rssi=50, it means that the peak detector triggered. - */ -#define RSSI_PEAK_DETECTOR_SAT 50 - -/* - * - * If rssi=25, it means that the ADC was saturated, but that only is - * valid when there is one ADC gain change. For short pulses this - * is true - you won't have time to do a gain change before the pulse - * goes away. But for longer pulses, ADC gain changes can occur, so - * you'll get a more accurate RSSI figure. - * - * For short pulses (and the definition of "short" still isn't clear - * at the time of writing) there isn't any real time to do a gain change - * (or two, or three..) in order to get an accurate estimation of signal - * sizing. Thus, RSSI will not be very accurate for short duration pulses. - * All you can really say for certain is that yes, there's a pulse that - * met the requirements of the pulse detector. - * - * For more information, see the 802.11ac Microarchitecture guide. - * (TODO: add a twiki reference.) - */ - -#endif /* __DFS_PHYERR_PEREGRINE_H__ */ diff --git a/core/sap/dfs/src/dfs_process_phyerr.c b/core/sap/dfs/src/dfs_process_phyerr.c deleted file mode 100644 index bc46cda0052d..000000000000 --- a/core/sap/dfs/src/dfs_process_phyerr.c +++ /dev/null @@ -1,943 +0,0 @@ -/* - * Copyright (c) 2002-2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -#include "dfs.h" -#include "dfs_phyerr.h" /* For chip-specific phyerr func declarations */ -/* TO DO DFS - #include - */ -#ifndef UNINET -/* TO DO DFS - #include - */ -#endif -#ifdef ATH_SUPPORT_DFS - -/* - * Return the frequency width for the current operating channel. - * - * This isn't the channel width - it's how wide the reported event - * may be. For HT20 this is 20MHz. For HT40 on Howl and later it'll - * still be 20MHz - the hardware returns either pri or ext channel. - */ -static inline int dfs_get_event_freqwidth(struct ath_dfs *dfs) -{ - - /* Handle edge cases during startup/transition, shouldn't happen! */ - if (dfs == NULL) - return 0; - if (dfs->ic == NULL || dfs->ic->ic_curchan == NULL) - return 0; - - /* - * XXX For now, assume 20MHz wide - but this is incorrect when - * operating in half/quarter mode! - */ - return 20; -} - -/* - * Return the centre frequency for the current operating channel and - * event. - * - * This is for post-Owl 11n chips which report pri/extension channel - * events. - */ -static inline uint16_t -dfs_get_event_freqcentre(struct ath_dfs *dfs, int is_pri, int is_ext, int is_dc) -{ - struct ieee80211com *ic; - int chan_offset = 0, chan_width; - uint16_t freq; - - /* Handle edge cases during startup/transition, shouldn't happen! */ - if (dfs == NULL) - return 0; - if (dfs->ic == NULL || dfs->ic->ic_curchan == NULL) - return 0; - - ic = dfs->ic; - - /* - * - * For wide channels, DC and ext frequencies need a bit of hand-holding - * based on whether it's an upper or lower channel. - */ - chan_width = dfs_get_event_freqwidth(dfs); - qdf_spin_lock_bh(&ic->chan_lock); - if (IEEE80211_IS_CHAN_11N_HT40PLUS(ic->ic_curchan)) - chan_offset = chan_width; - else if (IEEE80211_IS_CHAN_11N_HT40MINUS(ic->ic_curchan)) - chan_offset = -chan_width; - else - chan_offset = 0; - - qdf_spin_unlock_bh(&ic->chan_lock); - - /* - * Check for DC events first - the sowl code may just set all - * the bits together.. - */ - if (is_dc) { - /* - * XXX TODO: Should DC events be considered 40MHz wide here? - */ - qdf_spin_lock_bh(&ic->chan_lock); - freq = ieee80211_chan2freq(ic, ic->ic_curchan) + - (chan_offset / 2); - qdf_spin_unlock_bh(&ic->chan_lock); - return freq; - } - - /* - * For non-wide channels, the centre frequency is just ic_freq. - * The centre frequency for pri events is still ic_freq. - */ - if (is_pri) { - qdf_spin_lock_bh(&ic->chan_lock); - freq = ieee80211_chan2freq(ic, ic->ic_curchan); - qdf_spin_unlock_bh(&ic->chan_lock); - return freq; - } - - if (is_ext) { - qdf_spin_lock_bh(&ic->chan_lock); - freq = ieee80211_chan2freq(ic, ic->ic_curchan) + chan_width; - qdf_spin_unlock_bh(&ic->chan_lock); - return freq; - } - - /* XXX shouldn't get here */ - qdf_spin_lock_bh(&ic->chan_lock); - freq = ieee80211_chan2freq(ic, ic->ic_curchan); - qdf_spin_unlock_bh(&ic->chan_lock); - return freq; -} - -/* - * Process an Owl-style phy error. - * - * Return 1 on success or 0 on failure. - */ -static int -dfs_process_phyerr_owl(struct ath_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) -{ - const char *cbuf = (const char *)buf; - uint8_t dur; - int event_width; - - /* XXX this shouldn't be kept count here */ - dfs->ath_dfs_stats.owl_phy_errors++; - - /* - * HW cannot detect extension channel radar so it only passes us - * primary channel radar data - */ - if (datalen == 0) - dur = 0; - else - dur = ((uint8_t *) cbuf)[0]; - - /* - * This is a spurious event; toss. - */ - if (rssi == 0 && dur == 0) - dfs->ath_dfs_stats.datalen_discards++; - return 0; - - /* - * Fill out dfs_phy_err with the information we have - * at hand. - */ - OS_MEMSET(e, 0, sizeof(*e)); - e->rssi = rssi; - e->dur = dur; - e->is_pri = 1; - e->is_ext = 0; - e->is_dc = 0; - e->is_early = 1; - e->fulltsf = fulltsf; - e->rs_tstamp = rs_tstamp; - - /* - * Owl only ever reports events on the primary channel; - * it doesn't even see events on the secondary channel. - */ - event_width = dfs_get_event_freqwidth(dfs); - e->freq = dfs_get_event_freqcentre(dfs, 1, 0, 0) * 1000; - e->freq_lo = e->freq - (event_width / 2) * 1000; - e->freq_hi = e->freq + (event_width / 2) * 1000; - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM, - "%s: rssi=%u dur=%u,freq=%dMHz, freq_lo=%dMHz, freq_hi=%dMHz\n", - __func__, rssi, dur, e->freq / 1000, e->freq_lo / 1000, - e->freq_hi / 1000); - - return 1; -} - -/* - * Process a Sowl/Howl style phy error. - */ -static int -dfs_process_phyerr_sowl(struct ath_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) -{ -#define EXT_CH_RADAR_FOUND 0x02 -#define PRI_CH_RADAR_FOUND 0x01 -#define EXT_CH_RADAR_EARLY_FOUND 0x04 - const char *cbuf = (const char *)buf; - uint8_t dur = 0; - uint8_t pulse_bw_info, pulse_length_ext, pulse_length_pri; - int pri_found = 0, ext_found = 0; - int early_ext = 0; - int event_width; - - /* - * If radar can be detected on the extension channel, datalen zero - * pulses are bogus, discard them. - */ - if (!datalen) { - dfs->ath_dfs_stats.datalen_discards++; - return 0; - } - - /* Ensure that we have at least three bytes of payload */ - if (datalen < 3) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "%s: short error frame (%d bytes)\n", - __func__, datalen); - dfs->ath_dfs_stats.datalen_discards++; - return 0; - } - - /* - * Fetch the payload directly - the compiler will happily generate - * byte-read instructions with a const char * cbuf pointer. - */ - pulse_length_pri = cbuf[datalen - 3]; - pulse_length_ext = cbuf[datalen - 2]; - pulse_bw_info = cbuf[datalen - 1]; - - /* - * Only the last 3 bits of the BW info are relevant, they indicate - * which channel the radar was detected in. - */ - pulse_bw_info &= 0x07; - - /* - * If pulse on DC, both primary and extension flags will be set - */ - if (((pulse_bw_info & EXT_CH_RADAR_FOUND) && - (pulse_bw_info & PRI_CH_RADAR_FOUND))) { - /* - * Conducted testing, when pulse is on DC, both - * pri and ext durations are reported to be same. - * - * Radiated testing, when pulse is on DC, different - * pri and ext durations are reported, so take the - * larger of the two - */ - if (pulse_length_ext >= pulse_length_pri) { - dur = pulse_length_ext; - ext_found = 1; - } else { - dur = pulse_length_pri; - pri_found = 1; - } - dfs->ath_dfs_stats.dc_phy_errors++; - } else { - if (pulse_bw_info & EXT_CH_RADAR_FOUND) { - dur = pulse_length_ext; - pri_found = 0; - ext_found = 1; - dfs->ath_dfs_stats.ext_phy_errors++; - } - if (pulse_bw_info & PRI_CH_RADAR_FOUND) { - dur = pulse_length_pri; - pri_found = 1; - ext_found = 0; - dfs->ath_dfs_stats.pri_phy_errors++; - } - if (pulse_bw_info & EXT_CH_RADAR_EARLY_FOUND) { - dur = pulse_length_ext; - pri_found = 0; - ext_found = 1; - early_ext = 1; - dfs->ath_dfs_stats.early_ext_phy_errors++; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "EARLY ext channel dur=%u rssi=%u datalen=%d\n", - dur, rssi, datalen); - } - if (!pulse_bw_info) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "dur=%u rssi=%u bw_info=0x%x datalen = %d\n", - dur, rssi, pulse_bw_info, (datalen & 0x3)); - /* - * Bogus bandwidth info received in descriptor, - * so ignore this PHY error - */ - dfs->ath_dfs_stats.bwinfo_errors++; - return 0; - } - } - - /* - * Always use combined RSSI reported, unless RSSI reported on - * extension is stronger - */ - if ((ext_rssi > rssi) && (ext_rssi < 128)) - rssi = ext_rssi; - - /* - * Fill out the rssi/duration fields from above. - */ - OS_MEMSET(e, 0, sizeof(*e)); - e->rssi = rssi; - e->dur = dur; - e->is_pri = pri_found; - e->is_ext = ext_found; - e->is_dc = !!(((pulse_bw_info & EXT_CH_RADAR_FOUND) && - (pulse_bw_info & PRI_CH_RADAR_FOUND))); - e->is_early = early_ext; - e->fulltsf = fulltsf; - e->rs_tstamp = rs_tstamp; - - /* - * Sowl and later can report pri/ext events. - */ - event_width = dfs_get_event_freqwidth(dfs); - e->freq = dfs_get_event_freqcentre(dfs, e->is_pri, e->is_ext, e->is_dc) - * 1000; - e->freq_lo = e->freq - (event_width / 2) * 1000; - e->freq_hi = e->freq + (event_width / 2) * 1000; - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM, - "%s: pulse_bw_info=0x%x pulse_length_ext=%u pulse_length_pri=%u " - "rssi=%u ext_rssi=%u, freq=%d MHz, freq_lo=%d MHz, " - "freq_hi=%d MHz\n", - __func__, - pulse_bw_info, - pulse_length_ext, - pulse_length_pri, - rssi, - ext_rssi, - e->freq / 1000, e->freq_lo / 1000, e->freq_hi / 1000); - - return 1; -} - -/* - * Process a Merlin/Osprey style phy error. - */ -static int -dfs_process_phyerr_merlin(struct ath_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) -{ - const char *cbuf = (const char *)buf; - uint8_t pulse_bw_info = 0; - - /* - * Process using the sowl code - */ - if (!dfs_process_phyerr_sowl(dfs, buf, datalen, rssi, ext_rssi, - rs_tstamp, fulltsf, e)) { - return 0; - } - - /* - * For osprey (and Merlin) bw_info has implication for selecting - * RSSI value. So re-fetch the bw_info field so the RSSI values - * can be appropriately overridden. - */ - pulse_bw_info = cbuf[datalen - 1]; - - switch (pulse_bw_info & 0x03) { - case 0x00: - /* No radar in ctrl or ext channel */ - rssi = 0; - break; - case 0x01: - /* radar in ctrl channel */ - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "RAW RSSI: rssi=%u ext_rssi=%u\n", rssi, ext_rssi); - if (ext_rssi >= (rssi + 3)) { - /* - * cannot use ctrl channel RSSI if - * extension channel is stronger - */ - rssi = 0; - } - break; - case 0x02: - /* radar in extension channel */ - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "RAW RSSI: rssi=%u ext_rssi=%u\n", rssi, ext_rssi); - if (rssi >= (ext_rssi + 12)) { - /* - * cannot use extension channel RSSI if control channel - * is stronger - */ - rssi = 0; - } else { - rssi = ext_rssi; - } - break; - case 0x03: - /* when both are present use stronger one */ - if (rssi < ext_rssi) - rssi = ext_rssi; - break; - } - - /* - * Override the rssi decision made by the sowl code. - * The rest of the fields (duration, timestamp, etc) - * are left untouched. - */ - e->rssi = rssi; - - return 1; -} - -static void dump_phyerr_contents(const char *d, int len) -{ -#ifdef CONFIG_ENABLE_DUMP_PHYERR_CONTENTS - int i, n, bufsize = 64; - - /* - * This is statically sized for a 4-digit address + 16 * 2 digit - * data string. - * - * It's done so the printk() passed to the kernel is an entire - * line, so the kernel logging code will atomically print it. - * Otherwise we'll end up with interleaved lines with output - * from other kernel threads. - */ - char buf[64]; - - /* Initial conditions */ - buf[0] = '\n'; - n = 0; - - for (i = 0; i < len; i++) { - if (i % 16 == 0) - n += snprintf(buf + n, bufsize - n, "%04x: ", i); - n += snprintf(buf + n, bufsize - n, "%02x ", d[i] & 0xff); - if (i % 16 == 15) { - n = 0; - buf[0] = '\0'; - } - } - - /* - * Print the final line if we didn't print it above. - */ - if (n != 0) - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, "%s: %s", - __func__, buf); -#endif /* def CONFIG_ENABLE_DUMP_PHYERR_CONTENTS */ -} - -void -dfs_process_phyerr(struct ieee80211com *ic, void *buf, uint16_t datalen, - uint8_t r_rssi, uint8_t r_ext_rssi, uint32_t r_rs_tstamp, - uint64_t r_fulltsf, bool enable_log) -{ - struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; - struct dfs_ieee80211_channel *chan = ic->ic_curchan; - struct dfs_event *event; - struct dfs_phy_err e; - int empty; - - if (dfs == NULL) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s: sc_dfs is NULL", __func__); - return; - } - - dfs->dfs_phyerr_count++; - dump_phyerr_contents(buf, datalen); - /* - * XXX The combined_rssi_ok support has been removed. - * This was only clear for Owl. - * - * XXX TODO: re-add this; it requires passing in the ctl/ext - * RSSI set from the RX status descriptor. - * - * XXX TODO TODO: this may be done for us from the legacy - * phy error path in ath_dev; please review that code. - */ - - /* - * At this time we have a radar pulse that we need to examine and - * queue. But if dfs_process_radarevent already detected radar and set - * CHANNEL_INTERFERENCE flag then do not queue any more radar data. - * When we are in a new channel this flag will be clear and we will - * start queueing data for new channel. (EV74162) - */ - if (dfs->dfs_debug_mask & ATH_DEBUG_DFS_PHYERR_PKT) - dump_phyerr_contents(buf, datalen); - - if (chan == NULL) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: chan is NULL", __func__); - return; - } - - qdf_spin_lock_bh(&ic->chan_lock); - if (IEEE80211_IS_CHAN_RADAR(chan)) { - qdf_spin_unlock_bh(&ic->chan_lock); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "%s: Radar already found in the channel, " - " do not queue radar data\n", __func__); - return; - } - - qdf_spin_unlock_bh(&ic->chan_lock); - dfs->ath_dfs_stats.total_phy_errors++; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "%s[%d] phyerr %d len %d\n", - __func__, __LINE__, - dfs->ath_dfs_stats.total_phy_errors, datalen); - - /* - * hardware stores this as 8 bit signed value. - * we will cap it at 0 if it is a negative number - */ - if (r_rssi & 0x80) - r_rssi = 0; - - if (r_ext_rssi & 0x80) - r_ext_rssi = 0; - - OS_MEMSET(&e, 0, sizeof(e)); - - /* - * This is a bit evil - instead of just passing in - * the chip version, the existing code uses a set - * of HAL capability bits to determine what is - * possible. - * - * The way I'm decoding it is thus: - * - * + DFS enhancement? Merlin or later - * + DFS extension channel? Sowl or later. (Howl?) - * + otherwise, Owl (and legacy.) - */ - if (dfs->dfs_caps.ath_chip_is_bb_tlv) { - if (dfs_process_phyerr_bb_tlv(dfs, buf, datalen, r_rssi, - r_ext_rssi, r_rs_tstamp, - r_fulltsf, &e, - enable_log) == 0) { - dfs->dfs_phyerr_reject_count++; - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s:Rejected phyerr count after parsing=%d", - __func__, dfs->dfs_phyerr_reject_count); - return; - } else { - if (dfs->dfs_phyerr_freq_min > e.freq) - dfs->dfs_phyerr_freq_min = e.freq; - - if (dfs->dfs_phyerr_freq_max < e.freq) - dfs->dfs_phyerr_freq_max = e.freq; - } - } else if (dfs->dfs_caps.ath_dfs_use_enhancement) { - if (dfs_process_phyerr_merlin(dfs, buf, datalen, r_rssi, - r_ext_rssi, r_rs_tstamp, - r_fulltsf, &e) == 0) { - return; - } - } else if (dfs->dfs_caps.ath_dfs_ext_chan_ok) { - if (dfs_process_phyerr_sowl(dfs, buf, datalen, r_rssi, - r_ext_rssi, r_rs_tstamp, r_fulltsf, - &e) == 0) { - return; - } - } else { - if (dfs_process_phyerr_owl(dfs, buf, datalen, r_rssi, - r_ext_rssi, r_rs_tstamp, r_fulltsf, - &e) == 0) { - return; - } - } - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Frequency at which the phyerror was injected = %d", - __func__, e.freq); - /* - * If the hardware supports radar reporting on the extension channel - * it will supply FFT data for longer radar pulses. - * - * TLV chips don't go through this software check - the hardware - * check should be enough. If we want to do software checking - * later on then someone will have to craft an FFT parser - * suitable for the TLV FFT data format. - */ - if ((!dfs->dfs_caps.ath_chip_is_bb_tlv) && - dfs->dfs_caps.ath_dfs_ext_chan_ok) { - /* - * HW has a known issue with chirping pulses injected at or - * around DC in 40MHz mode. Such pulses are reported with - * much lower durations and SW then discards them because - * they do not fit the minimum bin5 pulse duration. - * - * To work around this issue, if a pulse is within a 10us - * range of the bin5 min duration, check if the pulse is - * chirping. If the pulse is chirping, bump up the duration - * to the minimum bin5 duration. - * - * This makes sure that a valid chirping pulse will not be - * discarded because of incorrect low duration. - * - * TBD - Is it possible to calculate the 'real' duration of - * the pulse using the slope of the FFT data? - * - * TBD - Use FFT data to differentiate between radar pulses - * and false PHY errors. - * This will let us reduce the number of false alarms seen. - * - * BIN 5 chirping pulses are only for FCC or Japan MMK4 domain - */ - if (((dfs->dfsdomain == DFS_FCC_REG) || - (dfs->dfsdomain == DFS_MKK_REG)) && - (e.dur >= MAYBE_BIN5_DUR) && (e.dur < MAX_BIN5_DUR)) { - int add_dur; - int slope = 0, dc_found = 0; - - /* - * Set the event chirping flags; as we're doing - * an actual chirp check. - */ - e.do_check_chirp = 1; - e.is_hw_chirp = 0; - e.is_sw_chirp = 0; - - /* - * dfs_check_chirping() expects is_pri and is_ext - * to be '1' for true and '0' for false for now, - * as the function itself uses these values in - * constructing things rather than testing them - * for 'true' or 'false'. - */ - add_dur = dfs_check_chirping(dfs, buf, datalen, - (e.is_pri ? 1 : 0), - (e.is_ext ? 1 : 0), - &slope, &dc_found); - if (add_dur) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "old dur %d slope =%d\n", e.dur, - slope); - e.is_sw_chirp = 1; - /* bump up to a random bin5 pulse duration */ - if (e.dur < MIN_BIN5_DUR) { - e.dur = dfs_get_random_bin5_dur(dfs, - e.fulltsf); - } - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "new dur %d\n", e.dur); - } else { - /* set the duration so that it is rejected */ - e.is_sw_chirp = 0; - e.dur = MAX_BIN5_DUR + 100; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "is_chirping = %d dur=%d\n", - add_dur, e.dur); - } - } else { - /* - * We have a pulse that is either bigger than - * MAX_BIN5_DUR or * less than MAYBE_BIN5_DUR - */ - if ((dfs->dfsdomain == DFS_FCC_REG) || - (dfs->dfsdomain == DFS_MKK_REG)) { - /* - * XXX Would this result in very large pulses - * wrapping around to become short pulses? - */ - if (e.dur >= MAX_BIN5_DUR) { - /* - * set the duration so that it is - * rejected - */ - e.dur = MAX_BIN5_DUR + 50; - } - } - } - } - - /* - * Add the parsed, checked and filtered entry to the radar pulse - * event list. This is then checked by dfs_radar_processevent(). - * - * XXX TODO: some filtering is still done below this point - fix - * XXX this! - */ - ATH_DFSEVENTQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_eventq)); - ATH_DFSEVENTQ_UNLOCK(dfs); - if (empty) { - return; - } - - /* - * If the channel is a turbo G channel, then the event is - * for the adaptive radio (AR) pattern matching rather than - * radar detection. - */ - qdf_spin_lock_bh(&ic->chan_lock); - if ((chan->ic_flags & CHANNEL_108G) == CHANNEL_108G) { - qdf_spin_unlock_bh(&ic->chan_lock); - if (!(dfs->dfs_proc_phyerr & DFS_AR_EN)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "%s: DFS_AR_EN not enabled\n", __func__); - return; - } - ATH_DFSEVENTQ_LOCK(dfs); - event = STAILQ_FIRST(&(dfs->dfs_eventq)); - if (event == NULL) { - ATH_DFSEVENTQ_UNLOCK(dfs); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "%s: no more events space left\n", - __func__); - return; - } - STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list); - ATH_DFSEVENTQ_UNLOCK(dfs); - event->re_rssi = e.rssi; - event->re_dur = e.dur; - event->re_full_ts = e.fulltsf; - event->re_ts = (e.rs_tstamp) & DFS_TSMASK; - event->re_chanindex = dfs->dfs_curchan_radindex; - event->re_flags = 0; - event->sidx = e.sidx; - if (e.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) { - event->delta_peak = e.delta_peak; - event->delta_diff = e.delta_diff; - event->agc_total_gain = e.agc_total_gain; - event->agc_mb_gain = e.agc_mb_gain; - event->radar_subchan_mask = e.radar_subchan_mask; - event->pulse_height = e.pulse_height; - event->triggering_agc_event = e.triggering_agc_event; - event->pulse_rssi = e.pulse_rssi; - event->radar_fft_pri80_inband_power = - e.radar_fft_pri80_inband_power; - event->radar_fft_ext80_inband_power = - e.radar_fft_ext80_inband_power; - event->rsu_version = e.rsu_version; - event->peak_mag = e.peak_mag; - } - /* - * Copy the segment ID of the phyerror - * from the radar summary report only - * if SAP is operating in 80p80 mode - * and both primary and extension segments - * are DFS. - */ - if (chan->ic_80p80_both_dfs) - event->radar_80p80_segid = e.radar_80p80_segid; - - /* - * Handle chirp flags. - */ - if (e.do_check_chirp) { - event->re_flags |= DFS_EVENT_CHECKCHIRP; - if (e.is_hw_chirp) - event->re_flags |= DFS_EVENT_HW_CHIRP; - if (e.is_sw_chirp) - event->re_flags |= DFS_EVENT_SW_CHIRP; - } - - ATH_ARQ_LOCK(dfs); - STAILQ_INSERT_TAIL(&(dfs->dfs_arq), event, re_list); - ATH_ARQ_UNLOCK(dfs); - } else { - if (IEEE80211_IS_CHAN_DFS(chan)) { - qdf_spin_unlock_bh(&ic->chan_lock); - if (!(dfs->dfs_proc_phyerr & DFS_RADAR_EN)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, - "%s: DFS_RADAR_EN not enabled\n", - __func__); - return; - } - /* - * rssi is not accurate for short pulses, so do - * not filter based on that for short duration pulses - * - * XXX do this filtering above? - */ - if (dfs->dfs_caps.ath_dfs_ext_chan_ok) { - if ((e.rssi < dfs->dfs_rinfo.rn_minrssithresh && - (e.dur > 4)) || - e.dur > (dfs->dfs_rinfo.rn_maxpulsedur)) { - dfs->ath_dfs_stats.rssi_discards++; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "Extension channel pulse is " - "discarded: dur=%d, " - "maxpulsedur=%d, rssi=%d, " - "minrssi=%d\n", - e.dur, - dfs->dfs_rinfo. - rn_maxpulsedur, e.rssi, - dfs->dfs_rinfo. - rn_minrssithresh); - return; - } - } else if (e.rssi < dfs->dfs_rinfo.rn_minrssithresh || - e.dur > dfs->dfs_rinfo.rn_maxpulsedur) { - - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO, - "%s [%d] : Rejecting: dur = %d maxpulsedur = %d, rssi = %d minrssithresh = %d", - __func__, __LINE__, - e.dur, dfs->dfs_rinfo.rn_maxpulsedur, - e.rssi, - dfs->dfs_rinfo.rn_minrssithresh); - - dfs->ath_dfs_stats.rssi_discards++; - return; - } - - /* - * Add the event to the list, if there's space. - */ - ATH_DFSEVENTQ_LOCK(dfs); - event = STAILQ_FIRST(&(dfs->dfs_eventq)); - if (event == NULL) { - ATH_DFSEVENTQ_UNLOCK(dfs); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, - "%s: no more events space left\n", - __func__); - return; - } - STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list); - ATH_DFSEVENTQ_UNLOCK(dfs); - - dfs->dfs_phyerr_queued_count++; - dfs->dfs_phyerr_w53_counter++; - - event->re_dur = e.dur; - event->re_full_ts = e.fulltsf; - event->re_ts = (e.rs_tstamp) & DFS_TSMASK; - event->re_rssi = e.rssi; - event->sidx = e.sidx; - if (e.rsu_version == - DFS_RADAR_SUMMARY_REPORT_VERSION_3) { - event->delta_peak = e.delta_peak; - event->delta_diff = e.delta_diff; - event->agc_total_gain = e.agc_total_gain; - event->agc_mb_gain = e.agc_mb_gain; - event->radar_subchan_mask = e.radar_subchan_mask; - event->pulse_height = e.pulse_height; - event->triggering_agc_event = - e.triggering_agc_event; - event->pulse_rssi = e.pulse_rssi; - event->radar_fft_pri80_inband_power = - e.radar_fft_pri80_inband_power; - event->radar_fft_ext80_inband_power = - e.radar_fft_ext80_inband_power; - event->rsu_version = e.rsu_version; - event->dfs_phyerr_eventq_serial_num = - dfs->dfs_phyerr_queued_count; - event->peak_mag = e.peak_mag; - } - /* - * Copy the segment ID of the phyerror - * from the radar summary report only - * if SAP is operating in 80p80 mode - * and both primary and extension segments - * are DFS. - */ - if (chan->ic_80p80_both_dfs) - event->radar_80p80_segid = e.radar_80p80_segid; - - /* - * Handle chirp flags. - */ - if (e.do_check_chirp) { - event->re_flags |= DFS_EVENT_CHECKCHIRP; - if (e.is_hw_chirp) - event->re_flags |= DFS_EVENT_HW_CHIRP; - if (e.is_sw_chirp) - event->re_flags |= DFS_EVENT_SW_CHIRP; - } - - /* - * Correctly set which channel is being reported on - */ - if (e.is_pri) { - event->re_chanindex = dfs->dfs_curchan_radindex; - } else { - if (dfs->dfs_extchan_radindex == -1) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s - phyerr on ext channel\n", - __func__); - } - event->re_chanindex = dfs->dfs_extchan_radindex; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, - "%s New extension channel event is added " - "to queue\n", __func__); - } - ATH_DFSQ_LOCK(dfs); - STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list); - ATH_DFSQ_UNLOCK(dfs); - } else { - qdf_spin_unlock_bh(&ic->chan_lock); - } - } - - /* - * Schedule the radar/AR task as appropriate. - * - * XXX isn't a lock needed for ath_radar_tasksched? - */ - -/* - * Commenting out the dfs_process_ar_event() since the function is never - * called at run time as dfs_arq will be empty and the function - * dfs_process_ar_event is obsolete and function definition is removed - * as part of dfs_ar.c file - * - * if (!STAILQ_EMPTY(&dfs->dfs_arq)) - * // XXX shouldn't this be a task/timer too? - * dfs_process_ar_event(dfs, ic->ic_curchan); - */ - - if (!STAILQ_EMPTY(&dfs->dfs_radarq) && !dfs->ath_radar_tasksched) { - dfs->ath_radar_tasksched = 1; - OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0); - } -#undef EXT_CH_RADAR_FOUND -#undef PRI_CH_RADAR_FOUND -#undef EXT_CH_RADAR_EARLY_FOUND -} -#endif /* ATH_SUPPORT_DFS */ diff --git a/core/sap/dfs/src/dfs_process_radarevent.c b/core/sap/dfs/src/dfs_process_radarevent.c deleted file mode 100644 index 56d4a5841732..000000000000 --- a/core/sap/dfs/src/dfs_process_radarevent.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * Copyright (c) 2002-2017 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_radarevent.c - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#include "dfs.h" -/* TO DO DFS - #include - */ -#ifdef ATH_SUPPORT_DFS - -#define FREQ_5500_MHZ 5500 -#define FREQ_5500_MHZ 5500 - -#define DFS_MAX_FREQ_SPREAD 1375 * 1 - -static char debug_dup[33]; -static int debug_dup_cnt; - -/* - * Convert the hardware provided duration to TSF ticks (usecs) - * taking the clock (fast or normal) into account. - * - * Legacy (pre-11n, Owl, Sowl, Howl) operate 5GHz using a 40MHz - * clock. Later 11n chips (Merlin, Osprey, etc) operate 5GHz using - * a 44MHz clock, so the reported pulse durations are different. - * - * Peregrine reports the pulse duration in microseconds regardless - * of the operating mode. (XXX TODO: verify this, obviously.) - */ -static inline uint8_t dfs_process_pulse_dur(struct ath_dfs *dfs, uint8_t re_dur) -{ - /* - * Short pulses are sometimes returned as having a duration of 0, - * so round those up to 1. - * - * XXX This holds true for BB TLV chips too, right? - */ - if (re_dur == 0) - return 1; - - /* - * For BB TLV chips, the hardware always returns microsecond - * pulse durations. - */ - if (dfs->dfs_caps.ath_chip_is_bb_tlv) - return re_dur; - - /* - * This is for 11n and legacy chips, which may or may not - * use the 5GHz fast clock mode. - */ - /* Convert 0.8us durations to TSF ticks (usecs) */ - return (uint8_t) dfs_round((int32_t) ((dfs->dur_multiplier) * re_dur)); -} - -/* - * Process a radar event. - * - * If a radar event is found, return 1. Otherwise, return 0. - * - * There is currently no way to specify that a radar event has occured 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. - */ -int dfs_process_radarevent(struct ath_dfs *dfs, - struct dfs_ieee80211_channel *chan) -{ - struct dfs_event re, *event; - struct dfs_state *rs = NULL; - struct dfs_filtertype *ft; - struct dfs_filter *rf; - int found, retval = 0, p, empty; - int events_processed = 0; - uint32_t tabledepth, index; - uint64_t deltafull_ts = 0, this_ts, deltaT; - struct dfs_ieee80211_channel *thischan; - struct dfs_pulseline *pl; - static uint32_t diff_ts; - int ext_chan_event_flag = 0; - int is_hw_chirp = 0; - int i; - int seg_id = DFS_80P80_SEG0; - struct dfs_delayline *dl; - - if (dfs == NULL) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s[%d]: dfs is NULL", __func__, __LINE__); - return 0; - } - qdf_spin_lock_bh(&dfs->ic->chan_lock); - if (!(IEEE80211_IS_CHAN_DFS(dfs->ic->ic_curchan))) { - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "%s: radar event on non-DFS chan", __func__); - dfs_reset_radarq(dfs); - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG0); - - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG1); - - return 0; - } - - qdf_spin_unlock_bh(&dfs->ic->chan_lock); -#ifndef ATH_DFS_RADAR_DETECTION_ONLY - /* TEST : Simulate radar bang, make sure we add the channel to NOL (bug 29968) */ - if (dfs->dfs_bangradar) { - /* bangradar will always simulate radar found on the primary channel */ - rs = &dfs->dfs_radar[dfs->dfs_curchan_radindex]; - dfs->dfs_bangradar = 0; /* reset */ - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: bangradar", __func__); - retval = 1; - goto dfsfound; - } -#endif - - /* - The HW may miss some pulses especially with high channel loading. - This is true for Japan W53 where channel loaoding is 50%. Also - for ETSI where channel loading is 30% this can be an issue too. - To take care of missing pulses, we introduce pri_margin multiplie. - This is normally 2 but can be higher for W53. - */ - - if ((dfs->dfsdomain == DFS_MKK_REG) && - (dfs->dfs_caps.ath_chip_is_bb_tlv) && - (chan->ic_freq < FREQ_5500_MHZ)) { - - dfs->dfs_pri_multiplier = dfs->dfs_pri_multiplier_ini; - - /* do not process W53 pulses, - unless we have a minimum number of them - */ - if (dfs->dfs_phyerr_w53_counter >= 5) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "%s: w53_counter=%d, freq_max=%d, " - "freq_min=%d, pri_multiplier=%d", - __func__, - dfs->dfs_phyerr_w53_counter, - dfs->dfs_phyerr_freq_max, - dfs->dfs_phyerr_freq_min, - dfs->dfs_pri_multiplier); - dfs->dfs_phyerr_freq_min = 0x7fffffff; - dfs->dfs_phyerr_freq_max = 0; - } else { - return 0; - } - } - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "%s: pri_multiplier=%d", __func__, dfs->dfs_pri_multiplier); - - ATH_DFSQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); - ATH_DFSQ_UNLOCK(dfs); - - while ((!empty) && (!retval) && (events_processed < MAX_EVENTS)) { - ATH_DFSQ_LOCK(dfs); - event = STAILQ_FIRST(&(dfs->dfs_radarq)); - if (event != NULL) - STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list); - ATH_DFSQ_UNLOCK(dfs); - - if (event == NULL) { - empty = 1; - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s[%d]: event is NULL ", __func__, __LINE__); - break; - } - events_processed++; - re = *event; - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - seg_id = re.radar_80p80_segid; - else - seg_id = DFS_80P80_SEG0; - - pl = (seg_id == 0) ? dfs->pulses : dfs->pulses_ext_seg; - - OS_MEMZERO(event, sizeof(struct dfs_event)); - ATH_DFSEVENTQ_LOCK(dfs); - STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list); - ATH_DFSEVENTQ_UNLOCK(dfs); - - found = 0; - qdf_spin_lock_bh(&dfs->ic->chan_lock); - if (dfs->ic->disable_phy_err_processing) { - ATH_DFSQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); - ATH_DFSQ_UNLOCK(dfs); - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - continue; - } - - qdf_spin_unlock_bh(&dfs->ic->chan_lock); - if (re.re_chanindex < DFS_NUM_RADAR_STATES) - rs = &dfs->dfs_radar[re.re_chanindex]; - else { - ATH_DFSQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); - ATH_DFSQ_UNLOCK(dfs); - continue; - } - if (rs->rs_chan.ic_flagext & CHANNEL_INTERFERENCE) { - ATH_DFSQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); - ATH_DFSQ_UNLOCK(dfs); - continue; - } - - if (dfs->dfs_rinfo.rn_lastfull_ts == 0) { - /* - * Either not started, or 64-bit rollover exactly to zero - * Just prepend zeros to the 15-bit ts - */ - dfs->dfs_rinfo.rn_ts_prefix = 0; - } else { - /* WAR 23031- patch duplicate ts on very short pulses */ - /* This pacth has two problems in linux environment. - * 1)The time stamp created and hence PRI depends entirely on the latency. - * If the latency is high, it possibly can split two consecutive - * pulses in the same burst so far away (the same amount of latency) - * that make them look like they are from differenct bursts. It is - * observed to happen too often. It sure makes the detection fail. - * 2)Even if the latency is not that bad, it simply shifts the duplicate - * timestamps to a new duplicate timestamp based on how they are processed. - * This is not worse but not good either. - * - * Take this pulse as a good one and create a probable PRI later - */ - if (re.re_dur == 0 - && re.re_ts == dfs->dfs_rinfo.rn_last_unique_ts) { - debug_dup[debug_dup_cnt++] = '1'; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - " %s deltaT is 0 ", __func__); - } else { - dfs->dfs_rinfo.rn_last_unique_ts = re.re_ts; - debug_dup[debug_dup_cnt++] = '0'; - } - if (debug_dup_cnt >= 32) { - debug_dup_cnt = 0; - } - - if (re.re_ts <= dfs->dfs_rinfo.rn_last_ts) { - dfs->dfs_rinfo.rn_ts_prefix += - (((uint64_t) 1) << DFS_TSSHIFT); - /* Now, see if it's been more than 1 wrap */ - deltafull_ts = - re.re_full_ts - - dfs->dfs_rinfo.rn_lastfull_ts; - if (deltafull_ts > - ((uint64_t) - ((DFS_TSMASK - dfs->dfs_rinfo.rn_last_ts) + - 1 + re.re_ts))) - deltafull_ts -= - (DFS_TSMASK - - dfs->dfs_rinfo.rn_last_ts) + 1 + - re.re_ts; - deltafull_ts = deltafull_ts >> DFS_TSSHIFT; - if (deltafull_ts > 1) { - dfs->dfs_rinfo.rn_ts_prefix += - ((deltafull_ts - 1) << DFS_TSSHIFT); - } - } else { - deltafull_ts = - re.re_full_ts - - dfs->dfs_rinfo.rn_lastfull_ts; - if (deltafull_ts > (uint64_t) DFS_TSMASK) { - deltafull_ts = - deltafull_ts >> DFS_TSSHIFT; - dfs->dfs_rinfo.rn_ts_prefix += - ((deltafull_ts - 1) << DFS_TSSHIFT); - } - } - } - /* - * At this stage rn_ts_prefix has either been blanked or - * calculated, so it's safe to use. - */ - this_ts = dfs->dfs_rinfo.rn_ts_prefix | ((uint64_t) re.re_ts); - dfs->dfs_rinfo.rn_lastfull_ts = re.re_full_ts; - dfs->dfs_rinfo.rn_last_ts = re.re_ts; - - /* - * The hardware returns the duration in a variety of formats, - * so it's converted from the hardware format to TSF (usec) - * values here. - * - * XXX TODO: this should really be done when the PHY error - * is processed, rather than way out here.. - */ - re.re_dur = dfs_process_pulse_dur(dfs, re.re_dur); - - /* - * Calculate the start of the radar pulse. - * - * The TSF is stamped by the MAC upon reception of the - * event, which is (typically?) at the end of the event. - * But the pattern matching code expects the event timestamps - * to be at the start of the event. So to fake it, we - * subtract the pulse duration from the given TSF. - * - * This is done after the 64-bit timestamp has been calculated - * so long pulses correctly under-wrap the counter. Ie, if - * this was done on the 32 (or 15!) bit TSF when the TSF - * value is closed to 0, it will underflow to 0xfffffXX, which - * would mess up the logical "OR" operation done above. - * - * This isn't valid for Peregrine as the hardware gives us - * the actual TSF offset of the radar event, not just the MAC - * TSF of the completed receive. - * - * XXX TODO: ensure that the TLV PHY error processing - * code will correctly calculate the TSF to be the start - * of the radar pulse. - * - * XXX TODO TODO: modify the TLV parsing code to subtract - * the duration from the TSF, based on the current fast clock - * value. - */ - if ((!dfs->dfs_caps.ath_chip_is_bb_tlv) && re.re_dur != 1) { - this_ts -= re.re_dur; - } - - /* Save the pulse parameters in the pulse buffer(pulse line) */ - index = (pl->pl_lastelem + 1) & DFS_MAX_PULSE_BUFFER_MASK; - if (pl->pl_numelems == DFS_MAX_PULSE_BUFFER_SIZE) - pl->pl_firstelem = - (pl->pl_firstelem + 1) & DFS_MAX_PULSE_BUFFER_MASK; - else - pl->pl_numelems++; - pl->pl_lastelem = index; - pl->pl_elems[index].p_time = this_ts; - pl->pl_elems[index].p_dur = re.re_dur; - pl->pl_elems[index].p_rssi = re.re_rssi; - if (seg_id == 0) { - diff_ts = (uint32_t) this_ts - dfs->test_ts; - dfs->test_ts = (uint32_t) this_ts; - } else { - diff_ts = (u_int32_t)this_ts - dfs->test_ts_ext_seg; - dfs->test_ts_ext_seg = (u_int32_t)this_ts; - } - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "ts%u %u %u diff %u pl->pl_lastelem.p_time=%llu", - (uint32_t) this_ts, re.re_dur, re.re_rssi, diff_ts, - (unsigned long long)pl->pl_elems[index].p_time); - if (dfs->dfs_event_log_on) { - i = dfs->dfs_event_log_count % DFS_EVENT_LOG_SIZE; - dfs->radar_log[i].ts = this_ts; - dfs->radar_log[i].diff_ts = diff_ts; - dfs->radar_log[i].rssi = re.re_rssi; - dfs->radar_log[i].dur = re.re_dur; - dfs->dfs_event_log_count++; - } - if (re.rsu_version == DFS_RADAR_SUMMARY_REPORT_VERSION_3) { - if ((re.re_flags & DFS_EVENT_HW_CHIRP) == - DFS_EVENT_HW_CHIRP) - is_hw_chirp = 1; - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "\n %s[%d]:PHYERR# = %d ts = %u diff_ts = %u ppdu_rssi = %u dur = %u is_hw_chirp = %d segid = %d sidx = %d peak_mag = %d delta_peak = %d delta_diff = %d agc_total_gain = %d agc_mb_gain = %d radar_subchan_mask = 0x%x pulse_height = %d triggering_agc_event = %d rs_pulse_rssi = %d pri80_inband_power = %d ext80_inband_power = %d\n", - __func__, __LINE__, - re.dfs_phyerr_eventq_serial_num, - (uint32_t) this_ts, - diff_ts, re.re_rssi, re.re_dur, is_hw_chirp, - re.radar_80p80_segid, re.sidx, re.peak_mag, - re.delta_peak, re.delta_diff, - re.agc_total_gain, re.agc_mb_gain, - re.radar_subchan_mask, re.pulse_height, - re.triggering_agc_event, re.pulse_rssi, - re.radar_fft_pri80_inband_power, - re.radar_fft_ext80_inband_power); - } else { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u pl->pl_lastelem.p_time=%llu xxxxx", - __func__, __LINE__, (uint32_t) this_ts, re.re_dur, - re.re_rssi, diff_ts, - (unsigned long long)pl->pl_elems[index].p_time); - } - - /* If diff_ts is very small, we might be getting false pulse detects - * due to heavy interference. We might be getting spectral splatter - * from adjacent channel. In order to prevent false alarms we - * clear the delay-lines. This might impact positive detections under - * harsh environments, but helps with false detects. */ - - if (diff_ts < 100) { - dfs_reset_alldelaylines(dfs, seg_id); - dfs_reset_radarq(dfs); - } - found = 0; - - /* - * Use this fix only when device is not in test mode, as - * it drops some valid phyerrors. - * In FCC or JAPAN domain,if the follwing signature matches - * its likely that this is a false radar pulse pattern - * so process the next pulse in the queue. - */ - if ((dfs->disable_dfs_ch_switch == false) && - (DFS_FCC_REG == dfs->dfsdomain || - DFS_MKK_REG == dfs->dfsdomain) && - (re.re_dur >= 11 && re.re_dur <= 20) && - (diff_ts > 500 || diff_ts <= 305) && - (re.sidx == -4)) { - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "\n%s: Rejecting on Peak Index = %d,re.re_dur = %d,diff_ts = %d\n", - __func__, re.sidx, re.re_dur, diff_ts); - - ATH_DFSQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); - ATH_DFSQ_UNLOCK(dfs); - continue; - } - - /* - * Modifying the pulse duration for FCC Type 4 - * or JAPAN W56 Type 6 radar pulses when the - * following condition is reported in radar - * summary report. - */ - if ((DFS_FCC_REG == dfs->dfsdomain || - DFS_MKK_REG == dfs->dfsdomain) && - ((chan->ic_flags & IEEE80211_CHAN_VHT80) == - IEEE80211_CHAN_VHT80) && - (chan->ic_pri_freq_center_freq_mhz_separation == - DFS_WAR_PLUS_30_MHZ_SEPARATION || - chan->ic_pri_freq_center_freq_mhz_separation == - DFS_WAR_MINUS_30_MHZ_SEPARATION) && - (re.sidx == DFS_WAR_PEAK_INDEX_ZERO) && - (re.re_dur > DFS_TYPE4_WAR_PULSE_DURATION_LOWER_LIMIT && - re.re_dur < DFS_TYPE4_WAR_PULSE_DURATION_UPPER_LIMIT) && - (diff_ts > DFS_TYPE4_WAR_PRI_LOWER_LIMIT && - diff_ts < DFS_TYPE4_WAR_PRI_UPPER_LIMIT)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s:chan->ic_flags=0x%x, MHz separation=%d\n", - __func__, chan->ic_flags, - chan->ic_pri_freq_center_freq_mhz_separation); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: Peak Idx =%d,re.re_dur =%d,diff_ts =%d\n", - __func__, re.sidx, re.re_dur, diff_ts); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "\n%s: Modify pulse dur to fit valid range\n", - __func__); - - re.re_dur = DFS_TYPE4_WAR_VALID_PULSE_DURATION; - } - - /* - * Modifying the pulse duration for ETSI Type 2 - * and ETSI type 3 radar pulses when the following - * condition is reported in radar summary report. - */ - if ((DFS_ETSI_REG == dfs->dfsdomain) && - ((chan->ic_flags & IEEE80211_CHAN_VHT80) == - IEEE80211_CHAN_VHT80) && - (chan->ic_pri_freq_center_freq_mhz_separation == - DFS_WAR_PLUS_30_MHZ_SEPARATION || - chan->ic_pri_freq_center_freq_mhz_separation == - DFS_WAR_MINUS_30_MHZ_SEPARATION) && - (re.sidx == DFS_WAR_PEAK_INDEX_ZERO) && - (re.re_dur > - DFS_ETSI_TYPE2_TYPE3_WAR_PULSE_DUR_LOWER_LIMIT && - re.re_dur < - DFS_ETSI_TYPE2_TYPE3_WAR_PULSE_DUR_UPPER_LIMIT) && - ((diff_ts > DFS_ETSI_TYPE2_WAR_PRI_LOWER_LIMIT && - diff_ts < DFS_ETSI_TYPE2_WAR_PRI_UPPER_LIMIT) || - (diff_ts > DFS_ETSI_TYPE3_WAR_PRI_LOWER_LIMIT && - diff_ts < DFS_ETSI_TYPE3_WAR_PRI_UPPER_LIMIT))) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "\n%s:chan->ic_flags=0x%x,MHz Separation=%d\n", - __func__, chan->ic_flags, - chan->ic_pri_freq_center_freq_mhz_separation); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s:Peak Index =%d,re.re_dur =%d,diff_ts =%d\n", - __func__, re.sidx, re.re_dur, diff_ts); - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s:Modify ETSI pulse dur to valid range\n", - __func__); - - re.re_dur = DFS_ETSI_WAR_VALID_PULSE_DURATION; - } - - /* BIN5 pulses are FCC and Japan specific */ - - if ((dfs->dfsdomain == DFS_FCC_REG) - || (dfs->dfsdomain == DFS_MKK_REG)) { - for (p = 0; - (p < dfs->dfs_rinfo.rn_numbin5radars) && (!found); - p++) { - struct dfs_bin5radars *br; - - br = (seg_id == 0) ? - &(dfs->dfs_b5radars[p]) : - &(dfs->dfs_b5radars_ext_seg[p]); - - if (dfs_bin5_check_pulse(dfs, &re, br)) { - /* - * This is a valid Bin5 pulse, - * check if it belongs to a burst - */ - re.re_dur = - dfs_retain_bin5_burst_pattern(dfs, - diff_ts, re.re_dur, seg_id); - /* - * Remember our computed duration for - * the next pulse in the burst - * (if needed) - */ - if (seg_id == 0) - dfs->dfs_rinfo. - dfs_last_bin5_dur = - re.re_dur; - else - dfs->dfs_rinfo. - dfs_last_bin5_dur_ext_seg = - re.re_dur; - - if (dfs_bin5_addpulse - (dfs, br, &re, this_ts)) { - found |= dfs_bin5_check(dfs, - seg_id); - } - } else { - DFS_DPRINTK(dfs, - ATH_DEBUG_DFS_BIN5_PULSE, - "%s not a BIN5 pulse (dur=%d)", - __func__, re.re_dur); - } - } - } - - if (found) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Found bin5 radar", - __func__); - retval |= found; - goto dfsfound; - } - - tabledepth = 0; - rf = NULL; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - " *** chan freq (%d): ts %llu dur %u rssi %u", - rs->rs_chan.ic_freq, (unsigned long long)this_ts, - re.re_dur, re.re_rssi); - - while ((tabledepth < DFS_MAX_RADAR_OVERLAP) && - ((dfs->dfs_radartable[re.re_dur])[tabledepth] != -1) && - (!retval)) { - ft = dfs-> - dfs_radarf[((dfs-> - dfs_radartable[re. - re_dur])[tabledepth])]; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - " ** RD (%d): ts %x dur %u rssi %u", - rs->rs_chan.ic_freq, re.re_ts, re.re_dur, - re.re_rssi); - - if (re.re_rssi < ft->ft_rssithresh && re.re_dur > 4) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "%s : Rejecting on rssi rssi=%u thresh=%u", - __func__, re.re_rssi, - ft->ft_rssithresh); - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO, - "%s[%d]: Rejecting on rssi rssi=%u thresh=%u", - __func__, __LINE__, re.re_rssi, - ft->ft_rssithresh); - tabledepth++; - ATH_DFSQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); - ATH_DFSQ_UNLOCK(dfs); - continue; - } - deltaT = this_ts - ft->ft_last_ts; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "deltaT = %lld (ts: 0x%llx) (last ts: 0x%llx)", - (unsigned long long)deltaT, - (unsigned long long)this_ts, - (unsigned long long)ft->ft_last_ts); - if ((deltaT < ft->ft_minpri) && (deltaT != 0)) { - /* This check is for the whole filter type. Individual filters - will check this again. This is first line of filtering. */ - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "%s: Rejecting on pri pri=%lld minpri=%u", - __func__, - (unsigned long long)deltaT, - ft->ft_minpri); - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO, - "%s[%d]:Rejecting on pri pri=%lld minpri=%u", - __func__, __LINE__, - (unsigned long long)deltaT, - ft->ft_minpri); - tabledepth++; - continue; - } - for (p = 0, found = 0; - (p < ft->ft_numfilters) && (!found); p++) { - rf = ft->ft_filters[p]; - dl = (seg_id == 0) ? &rf->rf_dl : - &rf->rf_dl_ext_seg; - if ((re.re_dur >= rf->rf_mindur) - && (re.re_dur <= rf->rf_maxdur)) { - /* The above check is probably not necessary */ - deltaT = - (this_ts < dl->dl_last_ts) ? - (int64_t) - ((DFS_TSF_WRAP - - dl->dl_last_ts) + - this_ts + 1) : - this_ts - dl->dl_last_ts; - - if ((deltaT < rf->rf_minpri) - && (deltaT != 0)) { - /* Second line of PRI filtering. */ - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "filterID %d : Rejecting on individual filter min PRI deltaT=%lld rf->rf_minpri=%u", - rf->rf_pulseid, - (unsigned long long) - deltaT, - rf->rf_minpri); - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO, - "%s[%d]:filterID= %d::Rejecting on individual filter min PRI deltaT=%lld rf->rf_minpri=%u", - __func__, __LINE__, - rf->rf_pulseid, - (unsigned long long) - deltaT, - rf->rf_minpri); - continue; - } - - if (rf->rf_ignore_pri_window > 0) { - if (deltaT < rf->rf_minpri) { - DFS_DPRINTK(dfs, - ATH_DEBUG_DFS2, - "filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u", - rf-> - rf_pulseid, - (unsigned - long long) - deltaT, - rf-> - rf_minpri); - QDF_TRACE - (QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO, - "%s[%d]:filterID= %d :: Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u", - __func__, __LINE__, - rf->rf_pulseid, - (unsigned long - long)deltaT, - rf->rf_minpri); - /* But update the last time stamp */ - dl->dl_last_ts = - this_ts; - continue; - } - } else { - - /* - The HW may miss some pulses especially with high channel loading. - This is true for Japan W53 where channel loaoding is 50%. Also - for ETSI where channel loading is 30% this can be an issue too. - To take care of missing pulses, we introduce pri_margin multiplie. - This is normally 2 but can be higher for W53. - */ - - if ((deltaT > - ((u_int64_t)dfs-> - dfs_pri_multiplier * - rf->rf_maxpri)) - || (deltaT < - rf->rf_minpri)) { - DFS_DPRINTK(dfs, - ATH_DEBUG_DFS2, - "filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u", - rf-> - rf_pulseid, - (unsigned - long long) - deltaT, - rf-> - rf_minpri); - QDF_TRACE - (QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO, - "%s[%d]:filterID= %d :: Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u", - __func__, __LINE__, - rf->rf_pulseid, - (unsigned long - long)deltaT, - rf->rf_minpri); - /* But update the last time stamp */ - dl->dl_last_ts = - this_ts; - continue; - } - } - dfs_add_pulse(dfs, rf, &re, deltaT, - this_ts, seg_id); - - /* If this is an extension channel event, flag it for false alarm reduction */ - if (re.re_chanindex == - dfs->dfs_extchan_radindex) { - ext_chan_event_flag = 1; - } - if (rf->rf_patterntype == 2) { - found = - dfs_staggered_check(dfs, - rf, - (uint32_t)deltaT, - re.re_dur, seg_id); - } else { - found = - dfs_bin_check(dfs, rf, - (uint32_t)deltaT, - re.re_dur, - ext_chan_event_flag, - seg_id); - } - if (dfs-> - dfs_debug_mask & ATH_DEBUG_DFS2) { - dfs_print_delayline(dfs, dl); - } - dl->dl_last_ts = this_ts; - } - } - ft->ft_last_ts = this_ts; - retval |= found; - if (found) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, - "Found on channel minDur = %d, filterId = %d", - ft->ft_mindur, - rf != NULL ? rf->rf_pulseid : -1); - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s[%d]:### Found on channel minDur = %d, filterId = %d seg_id = %d ###", - __func__, __LINE__, ft->ft_mindur, - rf != NULL ? rf->rf_pulseid : -1, - seg_id); - } - tabledepth++; - } - ATH_DFSQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); - ATH_DFSQ_UNLOCK(dfs); - } -dfsfound: - if (retval) { - /* Collect stats */ - dfs->ath_dfs_stats.num_radar_detects++; - thischan = &rs->rs_chan; - - /* - * Since we support 80p80 mode, indicate the - * segment on which the radar has been detected. - * only if both segments are dfs in 80p80 mode - * and the radar is found on ext the segment - * ic_radar_found_segid is to 1, in all other - * cases it is set to 0. - */ - dfs->ic->ic_curchan->ic_radar_found_segid = seg_id; - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s[%d]:### RADAR FOUND ON CHANNEL %d (%d MHz),seg_id=%d ###", - __func__, __LINE__, thischan->ic_ieee, - thischan->ic_freq, seg_id); - DFS_PRINTK("Radar found on channel %d (%d MHz)", - thischan->ic_ieee, thischan->ic_freq); - -#if 0 /* UMACDFS : TODO */ - /* Disable radar for now */ - rfilt = ath_hal_getrxfilter(ah); - rfilt &= ~HAL_RX_FILTER_PHYRADAR; - ath_hal_setrxfilter(ah, rfilt); -#endif - dfs_reset_radarq(dfs); - - /* - * For now reset both segments - * until we have changes for us - * to do sub-channel marking which - * enables SAP to continue to use the 80 - * segment where radar was not detected - * and as a result CAC can be avoided on - * that segment. Currently we do not support - * sub-channel marking. - */ - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG0); - - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - dfs_reset_alldelaylines(dfs, DFS_80P80_SEG1); - - /* XXX Should we really enable again? Maybe not... */ -/* No reason to re-enable so far - Ajay*/ -#if 0 - pe.pe_firpwr = rs->rs_firpwr; - pe.pe_rrssi = rs->rs_radarrssi; - pe.pe_height = rs->rs_height; - pe.pe_prssi = rs->rs_pulserssi; - pe.pe_inband = rs->rs_inband; - /* 5413 specific */ - pe.pe_relpwr = rs->rs_relpwr; - pe.pe_relstep = rs->rs_relstep; - pe.pe_maxlen = rs->rs_maxlen; - - ath_hal_enabledfs(ah, &pe); - rfilt |= HAL_RX_FILTER_PHYRADAR; - ath_hal_setrxfilter(ah, rfilt); -#endif - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "Primary channel freq = %u flags=0x%x, " - "Ext channel freq = %u flags=0x%x", - chan->ic_freq, chan->ic_flagext, - thischan->ic_freq, thischan->ic_flagext); - - dfs->dfs_phyerr_freq_min = 0x7fffffff; - dfs->dfs_phyerr_freq_max = 0; - dfs->dfs_phyerr_w53_counter = 0; - } - /* QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, "IN FUNC %s[%d]: retval = %d ",__func__,__LINE__,retval); */ - return retval; -/* #endif */ -/* return 1; */ -} - -#endif /* ATH_SUPPORT_DFS */ diff --git a/core/sap/dfs/src/dfs_staggered.c b/core/sap/dfs/src/dfs_staggered.c deleted file mode 100644 index cf00e741d1ad..000000000000 --- a/core/sap/dfs/src/dfs_staggered.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) 2002-2014 The Linux Foundation. All rights reserved. - * - * Previously licensed under the ISC license by Qualcomm Atheros, 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. - */ - -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - -/*=========================================================================== - - dfs_staggered.c - - OVERVIEW: - - Source code borrowed from QCA_MAIN DFS module - - DEPENDENCIES: - - Are listed for each API below. - - ===========================================================================*/ - -/*=========================================================================== - - EDIT HISTORY FOR FILE - - This section contains comments describing changes made to the module. - Notice that changes are listed in reverse chronological order. - - when who what, where, why - ---------- --- -------------------------------------------------------- - - ===========================================================================*/ - -#include "dfs.h" -/* TO DO DFS - #include - */ -#ifdef ATH_SUPPORT_DFS - -static int is_pri_multiple(uint32_t sample_pri, uint32_t refpri) -{ -#define MAX_ALLOWED_MISSED 3 - int i; - - if (sample_pri < refpri || (!refpri)) - return 0; - - for (i = 1; i <= MAX_ALLOWED_MISSED; i++) { - if ((sample_pri % (i * refpri) <= 5)) { - /* printk("sample_pri=%d is a multiple of refpri=%d\n", sample_pri, refpri); */ - return 1; - } - } - return 0; -#undef MAX_ALLOWED_MISSED -} - -static int is_unique_pri(uint32_t highestpri, uint32_t midpri, - uint32_t lowestpri, uint32_t refpri) -{ -#define DFS_STAGGERED_PRI_MARGIN_MIN 20 -#define DFS_STAGGERED_PRI_MARGIN_MAX 400 - if ((DFS_DIFF(lowestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) && - (DFS_DIFF(midpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) && - (DFS_DIFF(highestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN)) { - return 1; - } else { - if ((is_pri_multiple(refpri, highestpri)) - || (is_pri_multiple(refpri, lowestpri)) - || (is_pri_multiple(refpri, midpri))) - return 0; - } - return 0; -#undef DFS_STAGGERED_PRI_MARGIN_MIN -#undef DFS_STAGGERED_PRI_MARGIN_MAX -} - -int dfs_staggered_check(struct ath_dfs *dfs, struct dfs_filter *rf, - uint32_t deltaT, uint32_t width, int seg_id) -{ - uint32_t refpri, refdur, searchpri = 0, deltapri; /* , averagerefpri; */ - uint32_t n, i, primargin, durmargin; - int score[DFS_MAX_DL_SIZE], delayindex, dindex, found = 0; - struct dfs_delayline *dl; - uint32_t scoreindex, lowpriindex = 0, lowpri = 0xffff; -#if 0 - int numpulses = 0; -#endif - int higherthan, lowerthan, numscores; - int numpulseshigh = 0, numpulsesmid = 0, numpulsestemp = 0; - uint32_t lowestscore = 0, lowestscoreindex = 0, lowestpri = 0; - uint32_t midscore = 0, midscoreindex = 0, midpri = 0; - uint32_t highestscore = 0, highestscoreindex = 0, highestpri = 0; - - if (dfs->ic->ic_curchan->ic_80p80_both_dfs) - dl = (seg_id == 0) ? &rf->rf_dl : &rf->rf_dl_ext_seg; - else - dl = &rf->rf_dl; - - if (dl->dl_numelems < (rf->rf_threshold - 1)) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "numelems %d < threshold for filter %d\n", - dl->dl_numelems, rf->rf_pulseid); - return 0; - } - if (deltaT > rf->rf_filterlen) { - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "numelems %d < threshold for filter %d\n", - dl->dl_numelems, rf->rf_pulseid); - return 0; - } - primargin = 6; - if (rf->rf_maxdur < 10) { - durmargin = 4; - } else { - durmargin = 6; - } - - OS_MEMZERO(score, sizeof(int) * DFS_MAX_DL_SIZE); - /* find out the lowest pri */ - for (n = 0; n < dl->dl_numelems; n++) { - delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; - refpri = dl->dl_elems[delayindex].de_time; - if (refpri == 0) - continue; - else if (refpri < lowpri) { - lowpri = dl->dl_elems[delayindex].de_time; - lowpriindex = n; - } - } - /* find out the each delay element's pri score */ - for (n = 0; n < dl->dl_numelems; n++) { - delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; - refpri = dl->dl_elems[delayindex].de_time; - if (refpri == 0) { - continue; - } - - if ((refpri > rf->rf_maxpri) || (refpri < rf->rf_minpri)) { - score[n] = 0; - continue; - } - - for (i = 0; i < dl->dl_numelems; i++) { - dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; - searchpri = dl->dl_elems[dindex].de_time; - deltapri = DFS_DIFF(searchpri, refpri); - if (deltapri < primargin) - score[n]++; - } - } - for (n = 0; n < dl->dl_numelems; n++) { - delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; - refdur = dl->dl_elems[delayindex].de_time; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "score[%d]=%d pri=%d\n", n, - score[n], refdur); - } - - /* find out the 2 or 3 highest scorers */ - scoreindex = 0; - highestscore = 0; - highestscoreindex = 0; - highestpri = 0; - numscores = 0; - lowestscore = 0; - - for (n = 0; n < dl->dl_numelems; n++) { - higherthan = 0; - lowerthan = 0; - delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; - refpri = dl->dl_elems[delayindex].de_time; - - if ((score[n] >= highestscore) && - (is_unique_pri(highestpri, midpri, lowestpri, refpri))) { - lowestscore = midscore; - lowestpri = midpri; - lowestscoreindex = midscoreindex; - midscore = highestscore; - midpri = highestpri; - midscoreindex = highestscoreindex; - highestscore = score[n]; - highestpri = refpri; - highestscoreindex = n; - } else { - if ((score[n] >= midscore) && - (is_unique_pri - (highestpri, midpri, lowestpri, refpri))) { - lowestscore = midscore; - lowestpri = midpri; - lowestscoreindex = midscoreindex; - midscore = score[n]; - midpri = refpri; - midscoreindex = n; - } else if ((score[n] >= lowestscore) && - (is_unique_pri - (highestpri, midpri, lowestpri, refpri))) { - lowestscore = score[n]; - lowestpri = refpri; - lowestscoreindex = n; - } - } - - } - - if (midscore == 0) { - /* This means we have only 1 pulse type. It can not be staggered! */ - return 0; - } - - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "FINAL highestscore=%d highestscoreindex=%d highestpri=%d\n", - highestscore, highestscoreindex, highestpri); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "FINAL lowestscore=%d lowestscoreindex=%d lowpri=%d\n", - lowestscore, lowestscoreindex, lowestpri); - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "FINAL midscore=%d midscoreindex=%d midpri=%d\n", - midscore, midscoreindex, midpri); - - delayindex = (dl->dl_firstelem + highestscoreindex) & DFS_MAX_DL_MASK; - refdur = dl->dl_elems[delayindex].de_dur; - refpri = dl->dl_elems[delayindex].de_time; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "highscoreindex=%d refdur=%d refpri=%d\n", - highestscoreindex, refdur, refpri); - - numpulsestemp = - dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur, 0, - highestpri); - numpulseshigh = numpulsestemp; - numpulsestemp = - dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur, 0, - highestpri + midpri); - if (numpulsestemp > numpulseshigh) { - numpulseshigh = numpulsestemp; - } - numpulsestemp = - dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur, 0, - highestpri + midpri + lowestpri); - if (numpulsestemp > numpulseshigh) { - numpulseshigh = numpulsestemp; - } - - delayindex = (dl->dl_firstelem + midscoreindex) & DFS_MAX_DL_MASK; - refdur = dl->dl_elems[delayindex].de_dur; - refpri = dl->dl_elems[delayindex].de_time; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, - "midscoreindex=%d refdur=%d refpri=%d\n", - midscoreindex, refdur, refpri); - - /* numpulsesmid = dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur,0, 1); */ - numpulsestemp = - dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur, 0, midpri); - numpulsesmid = numpulsestemp; - numpulsestemp = - dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur, 0, - highestpri + midpri); - if (numpulsestemp > numpulsesmid) { - numpulsesmid = numpulsestemp; - } - numpulsestemp = - dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur, 0, - highestpri + midpri + lowestpri); - if (numpulsestemp > numpulsesmid) { - numpulsesmid = numpulsestemp; - } - - /*delayindex = (dl->dl_firstelem + lowestscoreindex) & DFS_MAX_DL_MASK; - refdur = dl->dl_elems[delayindex].de_dur; - refpri = dl->dl_elems[delayindex].de_time; - DFS_DPRINTK(ic, ATH_DEBUG_DFS1, "lowestscoreindex=%d refdur=%d refpri=%d\n", lowestscoreindex, refdur, refpri); - - numpulseslow = dfs_bin_pri_check(dfs, rf, dl, lowestscore, refpri, refdur,0, 1); - */ - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "numpulseshigh=%d, numpulsesmid=%d\n", - numpulseshigh, numpulsesmid); -/* printf("numpulseshigh=%d, numpulsesmid=%d, numpulseslow %d\n",numpulseshigh, numpulsesmid, numpulseslow); */ - - if ((numpulseshigh >= rf->rf_threshold) - && (numpulsesmid >= rf->rf_threshold)) { - /*if (numpulses >= rf->rf_threshold) { */ - found = 1; - DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, - "MATCH filter=%u numpulseshigh=%u numpulsesmid= %u thresh=%u\n", - rf->rf_pulseid, numpulseshigh, numpulsesmid, - rf->rf_threshold); - } - return found; -} - -#endif /* ATH_SUPPORT_DFS */