1 /* 2 * Copyright (c) 2011,2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * 6 * Permission to use, copy, modify, and/or distribute this software for 7 * any purpose with or without fee is hereby granted, provided that the 8 * above copyright notice and this permission notice appear in all 9 * copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 12 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 14 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 17 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 18 * PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <qdf_types.h> 22 #include "wlan_dfs_ioctl.h" 23 #include <spectral_ioctl.h> 24 25 #ifndef __KERNEL__ 26 #include <math.h> 27 #endif /* __KERNEL__ */ 28 29 #ifndef _WLAN_SPECTRAL_PUBLIC_STRUCTS_H_ 30 #define _WLAN_SPECTRAL_PUBLIC_STRUCTS_H_ 31 32 #ifndef AH_MAX_CHAINS 33 #define AH_MAX_CHAINS 3 34 #endif 35 36 #define MAX_NUM_CHANNELS 255 37 #define SPECTRAL_PHYERR_PARAM_NOVAL 65535 38 39 #ifdef SPECTRAL_USE_EMU_DEFAULTS 40 /* Use defaults from emulation */ 41 #define SPECTRAL_SCAN_ACTIVE_DEFAULT (0x0) 42 #define SPECTRAL_SCAN_ENABLE_DEFAULT (0x0) 43 #define SPECTRAL_SCAN_COUNT_DEFAULT (0x0) 44 #define SPECTRAL_SCAN_PERIOD_DEFAULT (250) 45 #define SPECTRAL_SCAN_PRIORITY_DEFAULT (0x1) 46 #define SPECTRAL_SCAN_FFT_SIZE_DEFAULT (0x7) 47 #define SPECTRAL_SCAN_GC_ENA_DEFAULT (0x1) 48 #define SPECTRAL_SCAN_RESTART_ENA_DEFAULT (0x0) 49 #define SPECTRAL_SCAN_NOISE_FLOOR_REF_DEFAULT (0xa0) 50 #define SPECTRAL_SCAN_INIT_DELAY_DEFAULT (0x50) 51 #define SPECTRAL_SCAN_NB_TONE_THR_DEFAULT (0xc) 52 #define SPECTRAL_SCAN_STR_BIN_THR_DEFAULT (0x7) 53 #define SPECTRAL_SCAN_WB_RPT_MODE_DEFAULT (0x0) 54 #define SPECTRAL_SCAN_RSSI_RPT_MODE_DEFAULT (0x1) 55 #define SPECTRAL_SCAN_RSSI_THR_DEFAULT (0xf) 56 #define SPECTRAL_SCAN_PWR_FORMAT_DEFAULT (0x1) 57 #define SPECTRAL_SCAN_RPT_MODE_DEFAULT (0x2) 58 #define SPECTRAL_SCAN_BIN_SCALE_DEFAULT (0x1) 59 #define SPECTRAL_SCAN_DBM_ADJ_DEFAULT (0x0) 60 #define SPECTRAL_SCAN_CHN_MASK_DEFAULT (0x1) 61 #else 62 /* 63 * Static default values for spectral state and configuration. 64 * These definitions should be treated as temporary. Ideally, 65 * we should get the defaults from firmware - this will be discussed. 66 * 67 * Use defaults from Spectral Hardware Micro-Architecture 68 * document (v1.0) 69 */ 70 #define SPECTRAL_SCAN_ACTIVE_DEFAULT (0) 71 #define SPECTRAL_SCAN_ENABLE_DEFAULT (0) 72 #define SPECTRAL_SCAN_COUNT_DEFAULT (0) 73 #define SPECTRAL_SCAN_PERIOD_GEN_I_DEFAULT (35) 74 #define SPECTRAL_SCAN_PERIOD_GEN_II_DEFAULT (35) 75 #define SPECTRAL_SCAN_PERIOD_GEN_III_DEFAULT (224) 76 #define SPECTRAL_SCAN_PRIORITY_DEFAULT (1) 77 #define SPECTRAL_SCAN_FFT_SIZE_DEFAULT (7) 78 #define SPECTRAL_SCAN_GC_ENA_DEFAULT (1) 79 #define SPECTRAL_SCAN_RESTART_ENA_DEFAULT (0) 80 #define SPECTRAL_SCAN_NOISE_FLOOR_REF_DEFAULT (-96) 81 #define SPECTRAL_SCAN_INIT_DELAY_DEFAULT (80) 82 #define SPECTRAL_SCAN_NB_TONE_THR_DEFAULT (12) 83 #define SPECTRAL_SCAN_STR_BIN_THR_DEFAULT (8) 84 #define SPECTRAL_SCAN_WB_RPT_MODE_DEFAULT (0) 85 #define SPECTRAL_SCAN_RSSI_RPT_MODE_DEFAULT (0) 86 #define SPECTRAL_SCAN_RSSI_THR_DEFAULT (0xf0) 87 #define SPECTRAL_SCAN_PWR_FORMAT_DEFAULT (0) 88 #define SPECTRAL_SCAN_RPT_MODE_DEFAULT (2) 89 #define SPECTRAL_SCAN_BIN_SCALE_DEFAULT (1) 90 #define SPECTRAL_SCAN_DBM_ADJ_DEFAULT (1) 91 #define SPECTRAL_SCAN_CHN_MASK_DEFAULT (1) 92 #define SPECTRAL_SCAN_FREQUENCY_DEFAULT (0) 93 #define SPECTRAL_FFT_RECAPTURE_DEFAULT (0) 94 #endif /* SPECTRAL_USE_EMU_DEFAULTS */ 95 96 /* The below two definitions apply only to pre-11ac chipsets */ 97 #define SPECTRAL_SCAN_SHORT_REPORT_DEFAULT (1) 98 #define SPECTRAL_SCAN_FFT_PERIOD_DEFAULT (1) 99 100 /* 101 * Definitions to help in scaling of gen3 linear format Spectral bins to values 102 * similar to those from gen2 chipsets. 103 */ 104 105 /* 106 * Max gain for QCA9984. Since this chipset is a prime representative of gen2 107 * chipsets, it is chosen for this value. 108 */ 109 #define SPECTRAL_QCA9984_MAX_GAIN (78) 110 111 /* Temporary section for hard-coded values. These need to come from FW. */ 112 113 /* Max gain for IPQ8074 */ 114 #define SPECTRAL_IPQ8074_DEFAULT_MAX_GAIN_HARDCODE (62) 115 116 /* 117 * Section for values needing tuning per customer platform. These too may need 118 * to come from FW. To be considered as hard-coded for now. 119 */ 120 121 /* 122 * If customers have a different gain line up than QCA reference designs for 123 * IPQ8074 and/or QCA9984, they may have to tune the low level threshold and 124 * the RSSI threshold. 125 */ 126 #define SPECTRAL_SCALING_LOW_LEVEL_OFFSET (7) 127 #define SPECTRAL_SCALING_RSSI_THRESH (5) 128 129 /* 130 * If customers set the AGC backoff differently, they may have to tune the high 131 * level threshold. 132 */ 133 #define SPECTRAL_SCALING_HIGH_LEVEL_OFFSET (5) 134 135 /* End of section for values needing fine tuning. */ 136 /* End of temporary section for hard-coded values */ 137 138 /** 139 * enum spectral_msg_buf_type - Spectral message buffer type 140 * @SPECTRAL_MSG_BUF_NEW: Allocate new buffer 141 * @SPECTRAL_MSG_BUF_SAVED: Reuse last buffer, used for secondary segment report 142 * in case of 160 MHz. 143 * @SPECTRAL_MSG_BUF_TYPE_MAX: Max enumeration 144 */ 145 enum spectral_msg_buf_type { 146 SPECTRAL_MSG_BUF_NEW, 147 SPECTRAL_MSG_BUF_SAVED, 148 SPECTRAL_MSG_BUF_TYPE_MAX, 149 }; 150 151 /** 152 * enum spectral_msg_type - Spectral SAMP message type 153 * @SPECTRAL_MSG_NORMAL_MODE: Normal mode Spectral SAMP message 154 * @SPECTRAL_MSG_AGILE_MODE: Agile mode Spectral SAMP message 155 * @SPECTRAL_MSG_INTERFERENCE_NOTIFICATION: Interference notification to 156 * external auto channel selection 157 * entity 158 * @SPECTRAL_MSG_TYPE_MAX: Spectral SAMP message type max 159 */ 160 enum spectral_msg_type { 161 SPECTRAL_MSG_NORMAL_MODE, 162 SPECTRAL_MSG_AGILE_MODE, 163 SPECTRAL_MSG_INTERFERENCE_NOTIFICATION, 164 SPECTRAL_MSG_TYPE_MAX, 165 }; 166 167 /** 168 * enum spectral_debug - Spectral debug level 169 * @DEBUG_SPECTRAL: Minimal SPECTRAL debug 170 * @DEBUG_SPECTRAL1: Normal SPECTRAL debug 171 * @DEBUG_SPECTRAL2: Maximal SPECTRAL debug 172 * @DEBUG_SPECTRAL3: Matched filterID display 173 * @DEBUG_SPECTRAL4: One time dump of FFT report 174 */ 175 enum spectral_debug { 176 DEBUG_SPECTRAL = 0x00000100, 177 DEBUG_SPECTRAL1 = 0x00000200, 178 DEBUG_SPECTRAL2 = 0x00000400, 179 DEBUG_SPECTRAL3 = 0x00000800, 180 DEBUG_SPECTRAL4 = 0x00001000, 181 }; 182 183 /** 184 * enum spectral_capability_type - Spectral capability type 185 * @SPECTRAL_CAP_PHYDIAG: Phydiag capability 186 * @SPECTRAL_CAP_RADAR: Radar detection capability 187 * @SPECTRAL_CAP_SPECTRAL_SCAN: Spectral capability 188 * @SPECTRAL_CAP_ADVNCD_SPECTRAL_SCAN: Advanced spectral capability 189 */ 190 enum spectral_capability_type { 191 SPECTRAL_CAP_PHYDIAG, 192 SPECTRAL_CAP_RADAR, 193 SPECTRAL_CAP_SPECTRAL_SCAN, 194 SPECTRAL_CAP_ADVNCD_SPECTRAL_SCAN, 195 }; 196 197 /** 198 * enum spectral_cp_error_code - Spectral control path response code 199 * @SPECTRAL_SCAN_ERR_INVALID: Invalid error identifier 200 * @SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED: parameter unsupported 201 * @SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED: mode unsupported 202 * @SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE: invalid parameter value 203 * @SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED: parameter uninitialized 204 */ 205 enum spectral_cp_error_code { 206 SPECTRAL_SCAN_ERR_INVALID, 207 SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED, 208 SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED, 209 SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE, 210 SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED, 211 }; 212 213 /** 214 * enum spectral_dma_debug - Spectral DMA debug 215 * @SPECTRAL_DMA_RING_DEBUG: Spectral DMA ring debug 216 * @SPECTRAL_DMA_BUFFER_DEBUG: Spectral DMA buffer debug 217 */ 218 enum spectral_dma_debug { 219 SPECTRAL_DMA_RING_DEBUG, 220 SPECTRAL_DMA_BUFFER_DEBUG, 221 }; 222 223 struct wiphy; 224 struct wlan_objmgr_pdev; 225 struct wlan_objmgr_vdev; 226 /** 227 * struct spectral_cfg80211_vendor_cmd_handlers - Spectral vendor command 228 * handlers 229 * @wlan_cfg80211_spectral_scan_start: start scan handler 230 * @wlan_cfg80211_spectral_scan_stop: stop scan handler 231 * @wlan_cfg80211_spectral_scan_get_config: get config handler 232 * @wlan_cfg80211_spectral_scan_get_diag_stats: get diag stats handler 233 * @wlan_cfg80211_spectral_scan_get_cap: get capability handler 234 * @wlan_cfg80211_spectral_scan_get_status: get status handler 235 */ 236 struct spectral_cfg80211_vendor_cmd_handlers { 237 int (*wlan_cfg80211_spectral_scan_start)(struct wiphy *wiphy, 238 struct wlan_objmgr_pdev *pdev, 239 struct wlan_objmgr_vdev *vdev, 240 const void *data, 241 int data_len); 242 int (*wlan_cfg80211_spectral_scan_stop)(struct wiphy *wiphy, 243 struct wlan_objmgr_pdev *pdev, 244 struct wlan_objmgr_vdev *vdev, 245 const void *data, 246 int data_len); 247 int (*wlan_cfg80211_spectral_scan_get_config)( 248 struct wiphy *wiphy, 249 struct wlan_objmgr_pdev *pdev, 250 struct wlan_objmgr_vdev *vdev, 251 const void *data, 252 int data_len); 253 int (*wlan_cfg80211_spectral_scan_get_diag_stats)( 254 struct wiphy *wiphy, 255 struct wlan_objmgr_pdev *pdev, 256 struct wlan_objmgr_vdev *vdev, 257 const void *data, 258 int data_len); 259 int (*wlan_cfg80211_spectral_scan_get_cap)( 260 struct wiphy *wiphy, 261 struct wlan_objmgr_pdev *pdev, 262 struct wlan_objmgr_vdev *vdev, 263 const void *data, 264 int data_len); 265 int (*wlan_cfg80211_spectral_scan_get_status)( 266 struct wiphy *wiphy, 267 struct wlan_objmgr_pdev *pdev, 268 struct wlan_objmgr_vdev *vdev, 269 const void *data, 270 int data_len); 271 }; 272 273 /** 274 * struct spectral_cp_param - Spectral control path data structure which 275 * contains parameter and its value 276 * @id: Parameter ID 277 * @value: Single parameter value 278 * @freq: Spectral scan frequency 279 */ 280 struct spectral_cp_param { 281 uint32_t id; 282 union { 283 uint32_t value; 284 struct spectral_config_frequency freq; 285 }; 286 }; 287 288 /** 289 * struct spectral_chan_stats - channel status info 290 * @cycle_count: Cycle count 291 * @channel_load: Channel load 292 * @per: Period 293 * @noisefloor: Noise floor 294 * @comp_usablity: Computed usability 295 * @maxregpower: Maximum allowed regulatory power 296 * @comp_usablity_sec80: Computed usability of secondary 80 Mhz 297 * @maxregpower_sec80: Max regulatory power of secondary 80 Mhz 298 */ 299 struct spectral_chan_stats { 300 int cycle_count; 301 int channel_load; 302 int per; 303 int noisefloor; 304 uint16_t comp_usablity; 305 int8_t maxregpower; 306 uint16_t comp_usablity_sec80; 307 int8_t maxregpower_sec80; 308 }; 309 310 /** 311 * struct spectral_diag_stats - spectral diag stats 312 * @spectral_mismatch: Spectral TLV signature mismatches 313 * @spectral_sec80_sfft_insufflen: Insufficient length when parsing for 314 * Secondary 80 Search FFT report 315 * @spectral_no_sec80_sfft: Secondary 80 Search FFT report 316 * TLV not found 317 * @spectral_vhtseg1id_mismatch: VHT Operation Segment 1 ID 318 * mismatches in Search FFT report 319 * @spectral_vhtseg2id_mismatch: VHT Operation Segment 2 ID 320 * mismatches in Search FFT report 321 * @spectral_invalid_detector_id: Invalid detector id 322 */ 323 struct spectral_diag_stats { 324 uint64_t spectral_mismatch; 325 uint64_t spectral_sec80_sfft_insufflen; 326 uint64_t spectral_no_sec80_sfft; 327 uint64_t spectral_vhtseg1id_mismatch; 328 uint64_t spectral_vhtseg2id_mismatch; 329 uint64_t spectral_invalid_detector_id; 330 }; 331 332 /** 333 * struct spectral_scan_state - State of spectral scan 334 * @is_active: Is spectral scan active 335 * @is_enabled: Is spectral scan enabled 336 */ 337 struct spectral_scan_state { 338 uint8_t is_active; 339 uint8_t is_enabled; 340 }; 341 342 /* Forward declarations */ 343 struct wlan_objmgr_pdev; 344 345 /** 346 * struct spectral_nl_cb - Spectral Netlink callbacks 347 * @get_sbuff: Get the socket buffer to send the data to the application 348 * @send_nl_bcast: Send data to the application using netlink broadcast 349 * @send_nl_unicast: Send data to the application using netlink unicast 350 * @free_sbuff: Free the socket buffer for a particular message type 351 * @convert_to_nl_ch_width: 352 * @convert_to_phy_ch_width: 353 */ 354 struct spectral_nl_cb { 355 void *(*get_sbuff)(struct wlan_objmgr_pdev *pdev, 356 enum spectral_msg_type smsg_type, 357 enum spectral_msg_buf_type buf_type); 358 int (*send_nl_bcast)(struct wlan_objmgr_pdev *pdev, 359 enum spectral_msg_type smsg_type); 360 int (*send_nl_unicast)(struct wlan_objmgr_pdev *pdev, 361 enum spectral_msg_type smsg_type); 362 void (*free_sbuff)(struct wlan_objmgr_pdev *pdev, 363 enum spectral_msg_type smsg_type); 364 int (*convert_to_nl_ch_width)(uint8_t phy_chwidth); 365 uint8_t (*convert_to_phy_ch_width)(uint8_t nl_chwidth); 366 }; 367 368 /** 369 * struct spectral_scan_config_request - Config request 370 * @sscan_config: Spectral parameters 371 * @sscan_err_code: Spectral scan error code 372 */ 373 struct spectral_scan_config_request { 374 struct spectral_config sscan_config; 375 enum spectral_cp_error_code sscan_err_code; 376 }; 377 378 /** 379 * struct spectral_scan_action_request - Action request 380 * @sscan_err_code: Spectral scan error code 381 */ 382 struct spectral_scan_action_request { 383 enum spectral_cp_error_code sscan_err_code; 384 }; 385 386 /** 387 * struct spectral_scan_get_caps_request - Get caps request 388 * @sscan_caps: Spectral capabilities 389 * @sscan_err_code: Spectral scan error code 390 */ 391 struct spectral_scan_get_caps_request { 392 struct spectral_caps sscan_caps; 393 enum spectral_cp_error_code sscan_err_code; 394 }; 395 396 /** 397 * struct spectral_scan_get_diag_request - Get diag request 398 * @sscan_diag: Spectral diag stats 399 * @sscan_err_code: Spectral scan error code 400 */ 401 struct spectral_scan_get_diag_request { 402 struct spectral_diag_stats sscan_diag; 403 enum spectral_cp_error_code sscan_err_code; 404 }; 405 406 /** 407 * struct spectral_scan_get_chan_width_request - Get channel width request 408 * @chan_width: Channel width 409 * @sscan_err_code: Spectral scan error code 410 */ 411 struct spectral_scan_get_chan_width_request { 412 uint32_t chan_width; 413 enum spectral_cp_error_code sscan_err_code; 414 }; 415 416 /** 417 * struct spectral_scan_get_status_request - Get status request 418 * @is_active: is Spectral scan active 419 * @is_enabled: is Spectral scan enabled 420 * @sscan_err_code: Spectral scan error code 421 */ 422 struct spectral_scan_get_status_request { 423 bool is_active; 424 bool is_enabled; 425 enum spectral_cp_error_code sscan_err_code; 426 }; 427 428 /** 429 * struct spectral_scan_debug_request - Get/set debug level request 430 * @spectral_dbg_level: Spectral debug level 431 * @sscan_err_code: Spectral scan error code 432 */ 433 struct spectral_scan_debug_request { 434 uint32_t spectral_dbg_level; 435 enum spectral_cp_error_code sscan_err_code; 436 }; 437 438 /** 439 * struct spectral_scan_dma_debug_request - DMA debug request 440 * @dma_debug_enable: Enable/disable @dma_debug_type 441 * @dma_debug_type: Type of Spectral DMA debug i.e., ring or buffer debug 442 * @sscan_err_code: Spectral scan error code 443 */ 444 struct spectral_scan_dma_debug_request { 445 bool dma_debug_enable; 446 enum spectral_dma_debug dma_debug_type; 447 enum spectral_cp_error_code sscan_err_code; 448 }; 449 450 /** 451 * struct spectral_cp_request - Spectral control path request 452 * Creating request and extracting response has to 453 * be atomic. 454 * @ss_mode: Spectral scan mode 455 * @req_id: Request identifier 456 * @vdev_id: VDEV id 457 * @config_req: Spectral scan config request 458 * @action_req: Spectral scan action request 459 * @caps_req: Spectral scan get caps request 460 * @diag_req: Spectral scan get diag request 461 * @chan_width_req:Spectral scan get chan width request 462 * @status_req: Spectral scan get status request 463 * @debug_req: Spectral scan debug request 464 * @dma_debug_req: Spectral DMA debug request 465 */ 466 struct spectral_cp_request { 467 enum spectral_scan_mode ss_mode; 468 uint8_t req_id; 469 uint8_t vdev_id; 470 union { 471 struct spectral_scan_config_request config_req; 472 struct spectral_scan_action_request action_req; 473 struct spectral_scan_get_caps_request caps_req; 474 struct spectral_scan_get_diag_request diag_req; 475 struct spectral_scan_get_chan_width_request chan_width_req; 476 struct spectral_scan_get_status_request status_req; 477 struct spectral_scan_debug_request debug_req; 478 struct spectral_scan_dma_debug_request dma_debug_req; 479 }; 480 }; 481 482 /** 483 * struct spectral_data_stats - Spectral data stats 484 * @spectral_rx_events: Number of Spectral rx events 485 * @consume_spectral_calls: Number of consume_spectral_report() invocations 486 * @fill_samp_msg_calls: Number of fill_samp_msg() invocations 487 * @msgs_ready_for_user: Number of SAMP messages that are ready to be sent to 488 * user-space 489 * @msgs_queued_to_user: Number of SAMP messages queued to the user-space 490 */ 491 struct spectral_data_stats { 492 uint32_t spectral_rx_events; 493 uint32_t consume_spectral_calls; 494 uint32_t fill_samp_msg_calls; 495 uint32_t msgs_ready_for_user; 496 uint32_t msgs_queued_to_user; 497 }; 498 499 #ifndef __KERNEL__ 500 501 static inline int16_t 502 spectral_pwfactor_max(int16_t pwfactor1, 503 int16_t pwfactor2) 504 { 505 return ((pwfactor1 > pwfactor2) ? pwfactor1 : pwfactor2); 506 } 507 508 /** 509 * get_spectral_scale_rssi_corr() - Compute RSSI correction factor for scaling 510 * @agc_total_gain_db: AGC total gain in dB steps 511 * @gen3_defmaxgain: Default max gain value of the gen III chipset 512 * @gen2_maxgain: Max gain value used by the reference gen II chipset 513 * @lowlevel_offset: Low level offset for scaling 514 * @inband_pwr: In band power in dB steps 515 * @rssi_thr: RSSI threshold for scaling 516 * 517 * Helper function to compute RSSI correction factor for Gen III linear format 518 * Spectral scaling. It is the responsibility of the caller to ensure that 519 * correct values are passed. 520 * 521 * Return: RSSI correction factor 522 */ 523 static inline int16_t 524 get_spectral_scale_rssi_corr(u_int8_t agc_total_gain_db, 525 u_int8_t gen3_defmaxgain, u_int8_t gen2_maxgain, 526 int16_t lowlevel_offset, int16_t inband_pwr, 527 int16_t rssi_thr) 528 { 529 return ((agc_total_gain_db < gen3_defmaxgain) ? 530 (gen2_maxgain - gen3_defmaxgain + lowlevel_offset) : 531 spectral_pwfactor_max((inband_pwr - rssi_thr), 0)); 532 } 533 534 /** 535 * spectral_scale_linear_to_gen2() - Scale linear bin value to gen II equivalent 536 * @gen3_binmag: Captured FFT bin value from the Spectral Search FFT report 537 * generated by the Gen III chipset 538 * @gen2_maxgain: Max gain value used by the reference gen II chipset 539 * @gen3_defmaxgain: Default max gain value of the gen III chipset 540 * @lowlevel_offset: Low level offset for scaling 541 * @inband_pwr: In band power in dB steps 542 * @rssi_thr: RSSI threshold for scaling 543 * @agc_total_gain_db: AGC total gain in dB steps 544 * @highlevel_offset: High level offset for scaling 545 * @gen2_bin_scale: Bin scale value used on reference gen II chipset 546 * @gen3_bin_scale: Bin scale value used on gen III chipset 547 * 548 * Helper function to scale a given gen III linear format bin value into an 549 * approximately equivalent gen II value. The scaled value can possibly be 550 * higher than 8 bits. If the caller is incapable of handling values larger 551 * than 8 bits, the caller can saturate the value at 255. This function does not 552 * carry out this saturation for the sake of flexibility so that callers 553 * interested in the larger values can avail of this. Also note it is the 554 * responsibility of the caller to ensure that correct values are passed. 555 * 556 * Return: Scaled bin value 557 */ 558 static inline u_int32_t 559 spectral_scale_linear_to_gen2(u_int8_t gen3_binmag, 560 u_int8_t gen2_maxgain, u_int8_t gen3_defmaxgain, 561 int16_t lowlevel_offset, int16_t inband_pwr, 562 int16_t rssi_thr, u_int8_t agc_total_gain_db, 563 int16_t highlevel_offset, u_int8_t gen2_bin_scale, 564 u_int8_t gen3_bin_scale) 565 { 566 return (gen3_binmag * 567 sqrt(pow(10, (((double)spectral_pwfactor_max(gen2_maxgain - 568 gen3_defmaxgain + lowlevel_offset - 569 get_spectral_scale_rssi_corr(agc_total_gain_db, 570 gen3_defmaxgain, 571 gen2_maxgain, 572 lowlevel_offset, 573 inband_pwr, 574 rssi_thr), 575 (agc_total_gain_db < gen3_defmaxgain) * 576 highlevel_offset)) / 10))) * 577 pow(2, (gen3_bin_scale - gen2_bin_scale))); 578 } 579 580 #endif /* __KERNEL__ */ 581 582 #endif /* _WLAN_SPECTRAL_PUBLIC_STRUCTS_H_ */ 583