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
spectral_pwfactor_max(int16_t pwfactor1,int16_t pwfactor2)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
get_spectral_scale_rssi_corr(u_int8_t agc_total_gain_db,u_int8_t gen3_defmaxgain,u_int8_t gen2_maxgain,int16_t lowlevel_offset,int16_t inband_pwr,int16_t rssi_thr)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
spectral_scale_linear_to_gen2(u_int8_t gen3_binmag,u_int8_t gen2_maxgain,u_int8_t gen3_defmaxgain,int16_t lowlevel_offset,int16_t inband_pwr,int16_t rssi_thr,u_int8_t agc_total_gain_db,int16_t highlevel_offset,u_int8_t gen2_bin_scale,u_int8_t gen3_bin_scale)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