1 /* 2 * Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. 3 * 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <qdf_types.h> 21 #include "wlan_dfs_ioctl.h" 22 #include <spectral_ioctl.h> 23 24 #ifndef __KERNEL__ 25 #include <math.h> 26 #endif /* __KERNEL__ */ 27 28 #ifndef _WLAN_SPECTRAL_PUBLIC_STRUCTS_H_ 29 #define _WLAN_SPECTRAL_PUBLIC_STRUCTS_H_ 30 31 #ifndef AH_MAX_CHAINS 32 #define AH_MAX_CHAINS 3 33 #endif 34 35 #define MAX_NUM_CHANNELS 255 36 #define SPECTRAL_PHYERR_PARAM_NOVAL 65535 37 38 #ifdef SPECTRAL_USE_EMU_DEFAULTS 39 /* Use defaults from emulation */ 40 #define SPECTRAL_SCAN_ACTIVE_DEFAULT (0x0) 41 #define SPECTRAL_SCAN_ENABLE_DEFAULT (0x0) 42 #define SPECTRAL_SCAN_COUNT_DEFAULT (0x0) 43 #define SPECTRAL_SCAN_PERIOD_DEFAULT (250) 44 #define SPECTRAL_SCAN_PRIORITY_DEFAULT (0x1) 45 #define SPECTRAL_SCAN_FFT_SIZE_DEFAULT (0x7) 46 #define SPECTRAL_SCAN_GC_ENA_DEFAULT (0x1) 47 #define SPECTRAL_SCAN_RESTART_ENA_DEFAULT (0x0) 48 #define SPECTRAL_SCAN_NOISE_FLOOR_REF_DEFAULT (0xa0) 49 #define SPECTRAL_SCAN_INIT_DELAY_DEFAULT (0x50) 50 #define SPECTRAL_SCAN_NB_TONE_THR_DEFAULT (0xc) 51 #define SPECTRAL_SCAN_STR_BIN_THR_DEFAULT (0x7) 52 #define SPECTRAL_SCAN_WB_RPT_MODE_DEFAULT (0x0) 53 #define SPECTRAL_SCAN_RSSI_RPT_MODE_DEFAULT (0x1) 54 #define SPECTRAL_SCAN_RSSI_THR_DEFAULT (0xf) 55 #define SPECTRAL_SCAN_PWR_FORMAT_DEFAULT (0x1) 56 #define SPECTRAL_SCAN_RPT_MODE_DEFAULT (0x2) 57 #define SPECTRAL_SCAN_BIN_SCALE_DEFAULT (0x1) 58 #define SPECTRAL_SCAN_DBM_ADJ_DEFAULT (0x0) 59 #define SPECTRAL_SCAN_CHN_MASK_DEFAULT (0x1) 60 #else 61 /* 62 * Static default values for spectral state and configuration. 63 * These definitions should be treated as temporary. Ideally, 64 * we should get the defaults from firmware - this will be discussed. 65 * 66 * Use defaults from Spectral Hardware Micro-Architecture 67 * document (v1.0) 68 */ 69 #define SPECTRAL_SCAN_ACTIVE_DEFAULT (0) 70 #define SPECTRAL_SCAN_ENABLE_DEFAULT (0) 71 #define SPECTRAL_SCAN_COUNT_DEFAULT (0) 72 #define SPECTRAL_SCAN_PERIOD_GEN_I_DEFAULT (35) 73 #define SPECTRAL_SCAN_PERIOD_GEN_II_DEFAULT (35) 74 #define SPECTRAL_SCAN_PERIOD_GEN_III_DEFAULT (224) 75 #define SPECTRAL_SCAN_PRIORITY_DEFAULT (1) 76 #define SPECTRAL_SCAN_FFT_SIZE_DEFAULT (7) 77 #define SPECTRAL_SCAN_GC_ENA_DEFAULT (1) 78 #define SPECTRAL_SCAN_RESTART_ENA_DEFAULT (0) 79 #define SPECTRAL_SCAN_NOISE_FLOOR_REF_DEFAULT (-96) 80 #define SPECTRAL_SCAN_INIT_DELAY_DEFAULT (80) 81 #define SPECTRAL_SCAN_NB_TONE_THR_DEFAULT (12) 82 #define SPECTRAL_SCAN_STR_BIN_THR_DEFAULT (8) 83 #define SPECTRAL_SCAN_WB_RPT_MODE_DEFAULT (0) 84 #define SPECTRAL_SCAN_RSSI_RPT_MODE_DEFAULT (0) 85 #define SPECTRAL_SCAN_RSSI_THR_DEFAULT (0xf0) 86 #define SPECTRAL_SCAN_PWR_FORMAT_DEFAULT (0) 87 #define SPECTRAL_SCAN_RPT_MODE_DEFAULT (2) 88 #define SPECTRAL_SCAN_BIN_SCALE_DEFAULT (1) 89 #define SPECTRAL_SCAN_DBM_ADJ_DEFAULT (1) 90 #define SPECTRAL_SCAN_CHN_MASK_DEFAULT (1) 91 #endif /* SPECTRAL_USE_EMU_DEFAULTS */ 92 93 /* The below two definitions apply only to pre-11ac chipsets */ 94 #define SPECTRAL_SCAN_SHORT_REPORT_DEFAULT (1) 95 #define SPECTRAL_SCAN_FFT_PERIOD_DEFAULT (1) 96 97 /* 98 * Definitions to help in scaling of gen3 linear format Spectral bins to values 99 * similar to those from gen2 chipsets. 100 */ 101 102 /* 103 * Max gain for QCA9984. Since this chipset is a prime representative of gen2 104 * chipsets, it is chosen for this value. 105 */ 106 #define SPECTRAL_QCA9984_MAX_GAIN (78) 107 108 /* Temporary section for hard-coded values. These need to come from FW. */ 109 110 /* Max gain for IPQ8074 */ 111 #define SPECTRAL_IPQ8074_DEFAULT_MAX_GAIN_HARDCODE (62) 112 113 /* 114 * Section for values needing tuning per customer platform. These too may need 115 * to come from FW. To be considered as hard-coded for now. 116 */ 117 118 /* 119 * If customers have a different gain line up than QCA reference designs for 120 * IPQ8074 and/or QCA9984, they may have to tune the low level threshold and 121 * the RSSI threshold. 122 */ 123 #define SPECTRAL_SCALING_LOW_LEVEL_OFFSET (7) 124 #define SPECTRAL_SCALING_RSSI_THRESH (5) 125 126 /* 127 * If customers set the AGC backoff differently, they may have to tune the high 128 * level threshold. 129 */ 130 #define SPECTRAL_SCALING_HIGH_LEVEL_OFFSET (5) 131 132 /* End of section for values needing fine tuning. */ 133 /* End of temporary section for hard-coded values */ 134 135 /** 136 * enum wlan_cfg80211_spectral_vendorcmd_handler_idx - Indices to cfg80211 137 * spectral vendor command handlers 138 * @SPECTRAL_SCAN_START_HANDLER_IDX: Index to SPECTRAL_SCAN_START handler 139 * @SPECTRAL_SCAN_STOP_HANDLER_IDX: Index to SPECTRAL_SCAN_STOP handler 140 * @SPECTRAL_SCAN_GET_CONFIG_HANDLER_IDX: Index to SPECTRAL_SCAN_GET_CONFIG 141 * handler 142 * @SPECTRAL_SCAN_GET_DIAG_STATS_HANDLER_IDX: Index to 143 * SPECTRAL_SCAN_GET_DIAG_STATS handler 144 * @SPECTRAL_SCAN_GET_CAP_HANDLER_IDX: Index to SPECTRAL_SCAN_GET_CAP handler 145 * @SPECTRAL_SCAN_GET_STATUS_HANDLER_IDX: Index to SPECTRAL_SCAN_GET_STATUS 146 * handler 147 * @SPECTRAL_SCAN_VENDOR_CMD_HANDLER_MAX: Number of cfg80211 spectral 148 * vendor command handlers supported 149 */ 150 enum wlan_cfg80211_spectral_vendorcmd_handler_idx { 151 SPECTRAL_SCAN_START_HANDLER_IDX, 152 SPECTRAL_SCAN_STOP_HANDLER_IDX, 153 SPECTRAL_SCAN_GET_CONFIG_HANDLER_IDX, 154 SPECTRAL_SCAN_GET_DIAG_STATS_HANDLER_IDX, 155 SPECTRAL_SCAN_GET_CAP_HANDLER_IDX, 156 SPECTRAL_SCAN_GET_STATUS_HANDLER_IDX, 157 SPECTRAL_SCAN_VENDOR_CMD_HANDLER_MAX, 158 }; 159 160 /** 161 * enum spectral_debug - Spectral debug level 162 * @DEBUG_SPECTRAL: Minimal SPECTRAL debug 163 * @DEBUG_SPECTRAL1: Normal SPECTRAL debug 164 * @DEBUG_SPECTRAL2: Maximal SPECTRAL debug 165 * @DEBUG_SPECTRAL3: Matched filterID display 166 * @DEBUG_SPECTRAL4: One time dump of FFT report 167 */ 168 enum spectral_debug { 169 DEBUG_SPECTRAL = 0x00000100, 170 DEBUG_SPECTRAL1 = 0x00000200, 171 DEBUG_SPECTRAL2 = 0x00000400, 172 DEBUG_SPECTRAL3 = 0x00000800, 173 DEBUG_SPECTRAL4 = 0x00001000, 174 }; 175 176 /** 177 * enum spectral_capability_type - Spectral capability type 178 * @SPECTRAL_CAP_PHYDIAG: Phydiag capability 179 * @SPECTRAL_CAP_RADAR: Radar detection capability 180 * @SPECTRAL_CAP_SPECTRAL_SCAN: Spectral capability 181 * @SPECTRAL_CAP_ADVNCD_SPECTRAL_SCAN: Advanced spectral capability 182 */ 183 enum spectral_capability_type { 184 SPECTRAL_CAP_PHYDIAG, 185 SPECTRAL_CAP_RADAR, 186 SPECTRAL_CAP_SPECTRAL_SCAN, 187 SPECTRAL_CAP_ADVNCD_SPECTRAL_SCAN, 188 }; 189 190 /** 191 * struct spectral_chan_stats - channel status info 192 * @cycle_count: Cycle count 193 * @channel_load: Channel load 194 * @per: Period 195 * @noisefloor: Noise floor 196 * @comp_usablity: Computed usability 197 * @maxregpower: Maximum allowed regulatory power 198 * @comp_usablity_sec80: Computed usability of secondary 80 Mhz 199 * @maxregpower_sec80: Max regulatory power of secondary 80 Mhz 200 */ 201 struct spectral_chan_stats { 202 int cycle_count; 203 int channel_load; 204 int per; 205 int noisefloor; 206 uint16_t comp_usablity; 207 int8_t maxregpower; 208 uint16_t comp_usablity_sec80; 209 int8_t maxregpower_sec80; 210 }; 211 212 /** 213 * struct spectral_diag_stats - spectral diag stats 214 * @spectral_mismatch: Spectral TLV signature mismatches 215 * @spectral_sec80_sfft_insufflen: Insufficient length when parsing for 216 * Secondary 80 Search FFT report 217 * @spectral_no_sec80_sfft: Secondary 80 Search FFT report 218 * TLV not found 219 * @spectral_vhtseg1id_mismatch: VHT Operation Segment 1 ID 220 * mismatches in Search FFT report 221 * @spectral_vhtseg2id_mismatch: VHT Operation Segment 2 ID 222 * mismatches in Search FFT report 223 * @spectral_invalid_detector_id: Invalid detector id 224 */ 225 struct spectral_diag_stats { 226 uint64_t spectral_mismatch; 227 uint64_t spectral_sec80_sfft_insufflen; 228 uint64_t spectral_no_sec80_sfft; 229 uint64_t spectral_vhtseg1id_mismatch; 230 uint64_t spectral_vhtseg2id_mismatch; 231 uint64_t spectral_invalid_detector_id; 232 }; 233 234 /** 235 * struct spectral_scan_state - State of spectral scan 236 * @is_active: Is spectral scan active 237 * @is_enabled: Is spectral scan enabled 238 */ 239 struct spectral_scan_state { 240 uint8_t is_active; 241 uint8_t is_enabled; 242 }; 243 244 /* Forward declarations */ 245 struct wlan_objmgr_pdev; 246 247 /** 248 * struct spectral_nl_cb - Spectral Netlink callbacks 249 * @get_nbuff: Get the socket buffer to send the data to the application 250 * @send_nl_bcast: Send data to the application using netlink broadcast 251 * @send_nl_unicast: Send data to the application using netlink unicast 252 */ 253 struct spectral_nl_cb { 254 void *(*get_nbuff)(struct wlan_objmgr_pdev *pdev); 255 int (*send_nl_bcast)(struct wlan_objmgr_pdev *pdev); 256 int (*send_nl_unicast)(struct wlan_objmgr_pdev *pdev); 257 void (*free_nbuff)(struct wlan_objmgr_pdev *pdev); 258 }; 259 260 #ifndef __KERNEL__ 261 262 static inline int16_t 263 spectral_pwfactor_max(int16_t pwfactor1, 264 int16_t pwfactor2) 265 { 266 return ((pwfactor1 > pwfactor2) ? pwfactor1 : pwfactor2); 267 } 268 269 /** 270 * get_spectral_scale_rssi_corr() - Compute RSSI correction factor for scaling 271 * @agc_total_gain_db: AGC total gain in dB steps 272 * @gen3_defmaxgain: Default max gain value of the gen III chipset 273 * @gen2_maxgain: Max gain value used by the reference gen II chipset 274 * @lowlevel_offset: Low level offset for scaling 275 * @inband_pwr: In band power in dB steps 276 * @rssi_thr: RSSI threshold for scaling 277 * 278 * Helper function to compute RSSI correction factor for Gen III linear format 279 * Spectral scaling. It is the responsibility of the caller to ensure that 280 * correct values are passed. 281 * 282 * Return: RSSI correction factor 283 */ 284 static inline int16_t 285 get_spectral_scale_rssi_corr(u_int8_t agc_total_gain_db, 286 u_int8_t gen3_defmaxgain, u_int8_t gen2_maxgain, 287 int16_t lowlevel_offset, int16_t inband_pwr, 288 int16_t rssi_thr) 289 { 290 return ((agc_total_gain_db < gen3_defmaxgain) ? 291 (gen2_maxgain - gen3_defmaxgain + lowlevel_offset) : 292 spectral_pwfactor_max((inband_pwr - rssi_thr), 0)); 293 } 294 295 /** 296 * spectral_scale_linear_to_gen2() - Scale linear bin value to gen II equivalent 297 * @gen3_binmag: Captured FFT bin value from the Spectral Search FFT report 298 * generated by the Gen III chipset 299 * @gen2_maxgain: Max gain value used by the reference gen II chipset 300 * @gen3_defmaxgain: Default max gain value of the gen III chipset 301 * @lowlevel_offset: Low level offset for scaling 302 * @inband_pwr: In band power in dB steps 303 * @rssi_thr: RSSI threshold for scaling 304 * @agc_total_gain_db: AGC total gain in dB steps 305 * @highlevel_offset: High level offset for scaling 306 * @gen2_bin_scale: Bin scale value used on reference gen II chipset 307 * @gen3_bin_scale: Bin scale value used on gen III chipset 308 * 309 * Helper function to scale a given gen III linear format bin value into an 310 * approximately equivalent gen II value. The scaled value can possibly be 311 * higher than 8 bits. If the caller is incapable of handling values larger 312 * than 8 bits, the caller can saturate the value at 255. This function does not 313 * carry out this saturation for the sake of flexibility so that callers 314 * interested in the larger values can avail of this. Also note it is the 315 * responsibility of the caller to ensure that correct values are passed. 316 * 317 * Return: Scaled bin value 318 */ 319 static inline u_int32_t 320 spectral_scale_linear_to_gen2(u_int8_t gen3_binmag, 321 u_int8_t gen2_maxgain, u_int8_t gen3_defmaxgain, 322 int16_t lowlevel_offset, int16_t inband_pwr, 323 int16_t rssi_thr, u_int8_t agc_total_gain_db, 324 int16_t highlevel_offset, u_int8_t gen2_bin_scale, 325 u_int8_t gen3_bin_scale) 326 { 327 return (gen3_binmag * 328 sqrt(pow(10, (((double)spectral_pwfactor_max(gen2_maxgain - 329 gen3_defmaxgain + lowlevel_offset - 330 get_spectral_scale_rssi_corr(agc_total_gain_db, 331 gen3_defmaxgain, 332 gen2_maxgain, 333 lowlevel_offset, 334 inband_pwr, 335 rssi_thr), 336 (agc_total_gain_db < gen3_defmaxgain) * 337 highlevel_offset)) / 10))) * 338 pow(2, (gen3_bin_scale - gen2_bin_scale))); 339 } 340 341 #endif /* __KERNEL__ */ 342 343 #endif /* _WLAN_SPECTRAL_PUBLIC_STRUCTS_H_ */ 344