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