1  /*
2   * Copyright (c) 2011,2017-2021 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
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  #ifndef _TARGET_IF_SPECTRAL_H_
21  #define _TARGET_IF_SPECTRAL_H_
22  
23  #include <wlan_objmgr_cmn.h>
24  #include <wlan_objmgr_psoc_obj.h>
25  #include <wlan_objmgr_pdev_obj.h>
26  #include <wlan_objmgr_vdev_obj.h>
27  #include <wlan_reg_services_api.h>
28  #include <qdf_lock.h>
29  #include <wlan_spectral_public_structs.h>
30  #include <reg_services_public_struct.h>
31  #ifdef DIRECT_BUF_RX_ENABLE
32  #include <target_if_direct_buf_rx_api.h>
33  #endif
34  #ifdef WIN32
35  #pragma pack(push, target_if_spectral, 1)
36  #define __ATTRIB_PACK
37  #else
38  #ifndef __ATTRIB_PACK
39  #define __ATTRIB_PACK __attribute__ ((packed))
40  #endif
41  #endif
42  
43  #include <spectral_defs_i.h>
44  #include <wmi_unified_param.h>
45  
46  #define FREQ_OFFSET_10MHZ (10)
47  #define FREQ_OFFSET_40MHZ (40)
48  #define FREQ_OFFSET_80MHZ (80)
49  #define FREQ_OFFSET_85MHZ (85)
50  #ifndef SPECTRAL_USE_NL_BCAST
51  #define SPECTRAL_USE_NL_BCAST  (0)
52  #endif
53  
54  #define STATUS_PASS       1
55  #define STATUS_FAIL       0
56  #undef spectral_dbg_line
57  #define spectral_dbg_line() \
58  	spectral_debug("----------------------------------------------------")
59  
60  #undef spectral_ops_not_registered
61  #define spectral_ops_not_registered(str) \
62  	spectral_info("SPECTRAL : %s not registered\n", (str))
63  #undef not_yet_implemented
64  #define not_yet_implemented() \
65  	spectral_info("SPECTRAL : %s : %d Not yet implemented\n", \
66  		      __func__, __LINE__)
67  
68  #define SPECTRAL_HT20_NUM_BINS               56
69  #define SPECTRAL_HT20_FFT_LEN                56
70  #define SPECTRAL_HT20_DC_INDEX               (SPECTRAL_HT20_FFT_LEN / 2)
71  #define SPECTRAL_HT20_DATA_LEN               60
72  #define SPECTRAL_HT20_TOTAL_DATA_LEN         (SPECTRAL_HT20_DATA_LEN + 3)
73  #define SPECTRAL_HT40_TOTAL_NUM_BINS         128
74  #define SPECTRAL_HT40_DATA_LEN               135
75  #define SPECTRAL_HT40_TOTAL_DATA_LEN         (SPECTRAL_HT40_DATA_LEN + 3)
76  #define SPECTRAL_HT40_FFT_LEN                128
77  #define SPECTRAL_HT40_DC_INDEX               (SPECTRAL_HT40_FFT_LEN / 2)
78  
79  /*
80   * Used for the SWAR to obtain approximate combined rssi
81   * in secondary 80Mhz segment
82   */
83  #define OFFSET_CH_WIDTH_20	65
84  #define OFFSET_CH_WIDTH_40	62
85  #define OFFSET_CH_WIDTH_80	56
86  #define OFFSET_CH_WIDTH_160	50
87  
88  /* Min and max for relevant Spectral params */
89  #define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2          (1)
90  #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2          (9)
91  #define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3          (5)
92  #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT  (9)
93  #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000  (10)
94  #define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3_BE       (5)
95  #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_BE       (11)
96  #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_BE_20MHZ (9)
97  #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_BE_40MHZ (10)
98  #define INVALID_FFT_SIZE                          (0xFFFF)
99  #define SPECTRAL_PARAM_RPT_MODE_MIN               (0)
100  #define SPECTRAL_PARAM_RPT_MODE_MAX               (3)
101  #define SPECTRAL_PARAM_SCAN_COUNT_MAX_GEN3        (4095)
102  #define SPECTRAL_PARAM_SCAN_COUNT_MAX_GEN3_BE     (4095)
103  #define SPECTRAL_DWORD_SIZE                       (4)
104  
105  #define MAX_FFTBIN_VALUE_LINEAR_MODE              (U8_MAX)
106  #define MAX_FFTBIN_VALUE_DBM_MODE                 (S8_MAX)
107  #define MIN_FFTBIN_VALUE_DBM_MODE                 (S8_MIN)
108  #define MAX_FFTBIN_VALUE                          (255)
109  
110  /* DBR ring debug size for Spectral */
111  #define SPECTRAL_DBR_RING_DEBUG_SIZE 512
112  
113  #ifdef BIG_ENDIAN_HOST
114  #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len)  do { \
115  	int j; \
116  	uint32_t *src, *dest; \
117  	src = (uint32_t *)(srcp); \
118  	dest = (uint32_t *)(destp); \
119  	for (j = 0; j < roundup((len), sizeof(uint32_t)) / 4; j++) { \
120  	*(dest + j) = qdf_le32_to_cpu(*(src + j)); \
121  	} \
122  	} while (0)
123  #else
124  #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) \
125  	OS_MEMCPY((destp), (srcp), (len));
126  #endif
127  
128  #define DUMMY_NF_VALUE          (-123)
129  /* 5 categories x (lower + upper) bands */
130  #define MAX_INTERF                   10
131  #define HOST_MAX_ANTENNA         3
132  /* Mask for time stamp from descriptor */
133  #define SPECTRAL_TSMASK              0xFFFFFFFF
134  #define SPECTRAL_SIGNATURE           0xdeadbeef
135  /* Signature to write onto spectral buffer and then later validate */
136  #define MEM_POISON_SIGNATURE (htobe32(0xdeadbeef))
137  
138  /* START of spectral GEN II HW specific details */
139  #define SPECTRAL_PHYERR_SIGNATURE_GEN2           0xbb
140  #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN2     0xF9
141  #define TLV_TAG_ADC_REPORT_GEN2                  0xFA
142  #define TLV_TAG_SEARCH_FFT_REPORT_GEN2           0xFB
143  
144  /*
145   * The Maximum number of detector information to be filled in the SAMP msg
146   * is 3, only for 165MHz case. For all other cases this value will be 1.
147   */
148  #define MAX_NUM_DEST_DETECTOR_INFO    (3)
149  #define MAX_DETECTORS_PER_PDEV        (3)
150  #define FFT_BIN_SIZE_1BYTE            (1)
151  
152  #ifdef OPTIMIZED_SAMP_MESSAGE
153  /**
154   * enum spectral_160mhz_report_delivery_state - 160 MHz state machine states
155   * @SPECTRAL_REPORT_WAIT_PRIMARY80:   Wait for primary80 report
156   * @SPECTRAL_REPORT_WAIT_SECONDARY80: Wait for secondory 80 report
157   */
158  enum spectral_160mhz_report_delivery_state {
159  	SPECTRAL_REPORT_WAIT_PRIMARY80,
160  	SPECTRAL_REPORT_WAIT_SECONDARY80,
161  };
162  #else
163  /**
164   * enum spectral_160mhz_report_delivery_state - 160 MHz state machine states
165   * @SPECTRAL_REPORT_WAIT_PRIMARY80:   Wait for primary80 report
166   * @SPECTRAL_REPORT_RX_PRIMARY80:     Receive primary 80 report
167   * @SPECTRAL_REPORT_WAIT_SECONDARY80: Wait for secondory 80 report
168   * @SPECTRAL_REPORT_RX_SECONDARY80:   Receive secondary 80 report
169   */
170  enum spectral_160mhz_report_delivery_state {
171  	SPECTRAL_REPORT_WAIT_PRIMARY80,
172  	SPECTRAL_REPORT_RX_PRIMARY80,
173  	SPECTRAL_REPORT_WAIT_SECONDARY80,
174  	SPECTRAL_REPORT_RX_SECONDARY80,
175  };
176  #endif /* OPTIMIZED_SAMP_MESSAGE */
177  
178  /**
179   * enum spectral_freq_span_id - Spectral frequency span id
180   * @SPECTRAL_FREQ_SPAN_ID_0: Frequency span 0
181   * @SPECTRAL_FREQ_SPAN_ID_1: Frequency span 1
182   * @SPECTRAL_FREQ_SPAN_ID_2: Frequency span 2
183   */
184  enum spectral_freq_span_id {
185  	SPECTRAL_FREQ_SPAN_ID_0,
186  	SPECTRAL_FREQ_SPAN_ID_1,
187  	SPECTRAL_FREQ_SPAN_ID_2,
188  };
189  
190  /**
191   * enum spectral_detector_id - Spectral detector id
192   * @SPECTRAL_DETECTOR_ID_0: Spectral detector 0
193   * @SPECTRAL_DETECTOR_ID_1: Spectral detector 1
194   * @SPECTRAL_DETECTOR_ID_2: Spectral detector 2
195   * @SPECTRAL_DETECTOR_ID_MAX: Max Spectral detector ID
196   * @SPECTRAL_DETECTOR_ID_INVALID: Invalid Spectral detector ID
197   */
198  enum spectral_detector_id {
199  	SPECTRAL_DETECTOR_ID_0,
200  	SPECTRAL_DETECTOR_ID_1,
201  	SPECTRAL_DETECTOR_ID_2,
202  	SPECTRAL_DETECTOR_ID_MAX,
203  	SPECTRAL_DETECTOR_ID_INVALID = 0xff,
204  };
205  
206  /**
207   * struct spectral_search_fft_info_gen2 - spectral search fft report for gen2
208   * @relpwr_db:       Total bin power in db
209   * @num_str_bins_ib: Number of strong bins
210   * @base_pwr:        Base power
211   * @total_gain_info: Total gain
212   * @fft_chn_idx:     FFT chain on which report is originated
213   * @avgpwr_db:       Average power in db
214   * @peak_mag:        Peak power seen in the bins
215   * @peak_inx:        Index of bin holding peak power
216   */
217  struct spectral_search_fft_info_gen2 {
218  	uint32_t relpwr_db;
219  	uint32_t num_str_bins_ib;
220  	uint32_t base_pwr;
221  	uint32_t total_gain_info;
222  	uint32_t fft_chn_idx;
223  	uint32_t avgpwr_db;
224  	uint32_t peak_mag;
225  	int16_t  peak_inx;
226  };
227  
228  /*
229   * XXX Check if we should be handling the endinness difference in some
230   * other way opaque to the host
231   */
232  #ifdef BIG_ENDIAN_HOST
233  
234  /**
235   * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for big endian host
236   * @signature: signature
237   * @tag:       tag
238   * @length:    length
239   */
240  struct spectral_phyerr_tlv_gen2 {
241  	uint8_t  signature;
242  	uint8_t  tag;
243  	uint16_t length;
244  } __ATTRIB_PACK;
245  
246  #else
247  
248  /**
249   * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for little endian host
250   * @length:    length
251   * @tag:       tag
252   * @signature: signature
253   */
254  struct spectral_phyerr_tlv_gen2 {
255  	uint16_t length;
256  	uint8_t  tag;
257  	uint8_t  signature;
258  } __ATTRIB_PACK;
259  
260  #endif /* BIG_ENDIAN_HOST */
261  
262  /**
263   * struct spectral_phyerr_hdr_gen2 - phyerr header for gen2 HW
264   * @hdr_a: Header[0:31]
265   * @hdr_b: Header[32:63]
266   */
267  struct spectral_phyerr_hdr_gen2 {
268  	uint32_t hdr_a;
269  	uint32_t hdr_b;
270  };
271  
272  /*
273   * Segment ID information for 80+80.
274   *
275   * If the HW micro-architecture specification extends this DWORD for other
276   * purposes, then redefine+rename accordingly. For now, the specification
277   * mentions only segment ID (though this doesn't require an entire DWORD)
278   * without mention of any generic terminology for the DWORD, or any reservation.
279   * We use nomenclature accordingly.
280   */
281  typedef uint32_t SPECTRAL_SEGID_INFO;
282  
283  /**
284   * struct spectral_phyerr_fft_gen2 - fft info in phyerr event
285   * @buf: fft report
286   */
287  struct spectral_phyerr_fft_gen2 {
288  	__QDF_DECLARE_FLEX_ARRAY(uint8_t, buf);
289  };
290  
291  /**
292   * struct spectral_process_phyerr_info_gen2 - Processed phyerr info structures
293   * needed to fill SAMP params for gen2
294   * @p_rfqual: Pointer to RF quality info
295   * @p_sfft: Pointer to Search fft report info
296   * @pfft: Pointer to FFT info in Phyerr event
297   * @acs_stats: Pointer to ACS stats struct
298   * @tsf64: 64 bit TSF value
299   * @seg_id: Segment ID
300   */
301  struct spectral_process_phyerr_info_gen2 {
302  	struct target_if_spectral_rfqual_info *p_rfqual;
303  	struct spectral_search_fft_info_gen2 *p_sfft;
304  	struct spectral_phyerr_fft_gen2 *pfft;
305  	struct target_if_spectral_acs_stats *acs_stats;
306  	uint64_t tsf64;
307  	uint8_t seg_id;
308  };
309  
310  /* END of spectral GEN II HW specific details */
311  
312  /* START of spectral GEN III HW specific details */
313  
314  #define get_bitfield(value, size, pos) \
315  	(((value) >> (pos)) & ((1 << (size)) - 1))
316  #define unsigned_to_signed(value, width) \
317  	(((value) >= (1 << ((width) - 1))) ? \
318  		(value - (1 << (width))) : (value))
319  
320  #define SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_POS_GEN3         (29)
321  #define SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_SIZE_GEN3        (2)
322  #define SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_POS_GEN3      (0)
323  #define SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_SIZE_GEN3     (8)
324  #define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_POS_GEN3       (18)
325  #define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_SIZE_GEN3      (10)
326  #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_POS_GEN3               (31)
327  #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_SIZE_GEN3              (1)
328  #define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3_V1       (30)
329  #define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3_V1      (1)
330  #define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_POS_GEN3_V2       (16)
331  #define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_SIZE_GEN3_V2      (1)
332  #define SSCAN_SUMMARY_REPORT_PAD_HDR_A_BLANKING_POS_GEN3_V2     (0)
333  #define SSCAN_SUMMARY_REPORT_PAD_HDR_A_BLANKING_SIZE_GEN3_V2    (32)
334  #define SSCAN_SUMMARY_REPORT_PAD_HDR_A_BLANKING_TAG_GEN3_V2     (0xc0debeaf)
335  #define SPECTRAL_REPORT_LTS_HDR_LENGTH_POS_GEN3                 (0)
336  #define SPECTRAL_REPORT_LTS_HDR_LENGTH_SIZE_GEN3                (16)
337  #define SPECTRAL_REPORT_LTS_TAG_POS_GEN3                        (16)
338  #define SPECTRAL_REPORT_LTS_TAG_SIZE_GEN3                       (8)
339  #define SPECTRAL_REPORT_LTS_SIGNATURE_POS_GEN3                  (24)
340  #define SPECTRAL_REPORT_LTS_SIGNATURE_SIZE_GEN3                 (8)
341  #define FFT_REPORT_HDR_A_DETECTOR_ID_POS_GEN3                   (0)
342  #define FFT_REPORT_HDR_A_DETECTOR_ID_SIZE_GEN3                  (2)
343  #define FFT_REPORT_HDR_A_FFT_NUM_POS_GEN3                       (2)
344  #define FFT_REPORT_HDR_A_FFT_NUM_SIZE_GEN3                      (3)
345  #define FFT_REPORT_HDR_A_RADAR_CHECK_POS_GEN3_V1                (5)
346  #define FFT_REPORT_HDR_A_RADAR_CHECK_SIZE_GEN3_V1               (12)
347  #define FFT_REPORT_HDR_A_RADAR_CHECK_POS_GEN3_V2                (5)
348  #define FFT_REPORT_HDR_A_RADAR_CHECK_SIZE_GEN3_V2               (14)
349  #define FFT_REPORT_HDR_A_PEAK_INDEX_POS_GEN3_V1                 (17)
350  #define FFT_REPORT_HDR_A_PEAK_INDEX_SIZE_GEN3_V1                (11)
351  #define FFT_REPORT_HDR_A_PEAK_INDEX_POS_GEN3_V2                 (19)
352  #define FFT_REPORT_HDR_A_PEAK_INDEX_SIZE_GEN3_V2                (11)
353  #define FFT_REPORT_HDR_A_CHAIN_INDEX_POS_GEN3_V1                (28)
354  #define FFT_REPORT_HDR_A_CHAIN_INDEX_SIZE_GEN3_V1               (3)
355  #define FFT_REPORT_HDR_B_CHAIN_INDEX_POS_GEN3_V2                (0)
356  #define FFT_REPORT_HDR_B_CHAIN_INDEX_SIZE_GEN3_V2               (3)
357  #define FFT_REPORT_HDR_B_BASE_PWR_POS_GEN3_V1                   (0)
358  #define FFT_REPORT_HDR_B_BASE_PWR_SIZE_GEN3_V1                  (9)
359  #define FFT_REPORT_HDR_B_BASE_PWR_POS_GEN3_V2                   (3)
360  #define FFT_REPORT_HDR_B_BASE_PWR_SIZE_GEN3_V2                  (9)
361  #define FFT_REPORT_HDR_B_TOTAL_GAIN_POS_GEN3_V1                 (9)
362  #define FFT_REPORT_HDR_B_TOTAL_GAIN_SIZE_GEN3_V1                (8)
363  #define FFT_REPORT_HDR_B_TOTAL_GAIN_POS_GEN3_V2                 (12)
364  #define FFT_REPORT_HDR_B_TOTAL_GAIN_SIZE_GEN3_V2                (8)
365  #define FFT_REPORT_HDR_C_NUM_STRONG_BINS_POS_GEN3               (0)
366  #define FFT_REPORT_HDR_C_NUM_STRONG_BINS_SIZE_GEN3              (8)
367  #define FFT_REPORT_HDR_C_PEAK_MAGNITUDE_POS_GEN3                (8)
368  #define FFT_REPORT_HDR_C_PEAK_MAGNITUDE_SIZE_GEN3               (10)
369  #define FFT_REPORT_HDR_C_AVG_PWR_POS_GEN3                       (18)
370  #define FFT_REPORT_HDR_C_AVG_PWR_SIZE_GEN3                      (7)
371  #define FFT_REPORT_HDR_C_RELATIVE_PWR_POS_GEN3                  (25)
372  #define FFT_REPORT_HDR_C_RELATIVE_PWR_SIZE_GEN3                 (7)
373  
374  #define SPECTRAL_PHYERR_SIGNATURE_GEN3                          (0xFA)
375  #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3                    (0x02)
376  #define TLV_TAG_SEARCH_FFT_REPORT_GEN3                          (0x03)
377  #define SPECTRAL_PHYERR_TLVSIZE_GEN3                            (4)
378  
379  #define NUM_SPECTRAL_DETECTORS_GEN3_V1                     (3)
380  #define NUM_SPECTRAL_DETECTORS_GEN3_V2                     (2)
381  #define FFT_REPORT_HEADER_LENGTH_GEN3_V2                   (24)
382  #define FFT_REPORT_HEADER_LENGTH_GEN3_V1                   (16)
383  #define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V1      (0)
384  #define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V2      (16)
385  
386  #define SPECTRAL_PHYERR_HDR_LTS_POS \
387  	(offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_lts))
388  #define SPECTRAL_FFT_BINS_POS \
389  	(offsetof(struct spectral_phyerr_fft_report_gen3, buf))
390  
391  /**
392   * struct phyerr_info - spectral search fft report for gen3
393   * @data:       handle to phyerror buffer
394   * @datalen:    length of phyerror buffer
395   * @p_rfqual:   rf quality matrices
396   * @p_chaninfo: pointer to chaninfo
397   * @tsf64:      64 bit TSF
398   * @acs_stats:  acs stats
399   */
400  struct phyerr_info {
401  	uint8_t *data;
402  	uint32_t datalen;
403  	struct target_if_spectral_rfqual_info *p_rfqual;
404  	struct target_if_spectral_chan_info *p_chaninfo;
405  	uint64_t tsf64;
406  	struct target_if_spectral_acs_stats *acs_stats;
407  };
408  
409  /**
410   * struct spectral_search_fft_info_gen3 - spectral search fft report for gen3
411   * @timestamp:           Timestamp at which fft report was generated
412   * @last_raw_timestamp:  Previous FFT report's raw timestamp
413   * @adjusted_timestamp:  Adjusted timestamp to account for target reset
414   * @fft_detector_id:     Which radio generated this report
415   * @fft_num:             The FFT count number. Set to 0 for short FFT.
416   * @fft_radar_check:     NA for spectral
417   * @fft_peak_sidx:       Index of bin with maximum power
418   * @fft_chn_idx:         Rx chain index
419   * @fft_base_pwr_db:     Base power in dB
420   * @fft_total_gain_db:   Total gain in dB
421   * @fft_num_str_bins_ib: Number of strong bins in the report
422   * @fft_peak_mag:        Peak magnitude
423   * @fft_avgpwr_db:       Average power in dB
424   * @fft_relpwr_db:       Relative power in dB
425   * @fft_bin_count:       Number of FFT bins in the FFT report
426   * @fft_bin_size:        Size of one FFT bin in bytes
427   * @bin_pwr_data:        Contains FFT bins extracted from the report
428   */
429  struct spectral_search_fft_info_gen3 {
430  	uint32_t timestamp;
431  	uint32_t last_raw_timestamp;
432  	uint32_t adjusted_timestamp;
433  	uint32_t fft_detector_id;
434  	uint32_t fft_num;
435  	uint32_t fft_radar_check;
436  	int32_t  fft_peak_sidx;
437  	uint32_t fft_chn_idx;
438  	uint32_t fft_base_pwr_db;
439  	uint32_t fft_total_gain_db;
440  	uint32_t fft_num_str_bins_ib;
441  	int32_t  fft_peak_mag;
442  	uint32_t fft_avgpwr_db;
443  	uint32_t fft_relpwr_db;
444  	uint32_t fft_bin_count;
445  	uint8_t  fft_bin_size;
446  	uint8_t  *bin_pwr_data;
447  };
448  
449  /**
450   * struct spectral_phyerr_fft_report_gen3 - fft info in phyerr event
451   * @fft_timestamp:  Timestamp at which fft report was generated
452   * @fft_hdr_lts:    length, tag, signature fields
453   * @hdr_a:          Header[0:31]
454   * @hdr_b:          Header[32:63]
455   * @hdr_c:          Header[64:95]
456   * @resv:           Header[96:127]
457   * @buf:            fft bins
458   */
459  struct spectral_phyerr_fft_report_gen3 {
460  	uint32_t fft_timestamp;
461  	uint32_t fft_hdr_lts;
462  	uint32_t hdr_a;
463  	uint32_t hdr_b;
464  	uint32_t hdr_c;
465  	uint32_t resv;
466  	uint8_t buf[];
467  } __ATTRIB_PACK;
468  
469  /**
470   * struct sscan_report_fields_gen3 - Fields of spectral report
471   * @sscan_agc_total_gain:  The AGC total gain in DB.
472   * @inband_pwr_db: The in-band power of the signal in 1/2 DB steps
473   * @sscan_gainchange: This bit is set to 1 if a gainchange occurred during
474   *                 the spectral scan FFT.  Software may choose to
475   *                 disregard the results.
476   * @sscan_pri80: This is set to 1 to indicate that the Spectral scan was
477   *                 performed on the pri80 segment. Software may choose to
478   *                 disregard the FFT sample if this is set to 1 but detector ID
479   *                 does not correspond to the ID for the pri80 segment.
480   * @sscan_detector_id: Detector ID in Spectral scan report
481   * @blanking_status: Indicates whether scan blanking was enabled during this
482   * spectral report capture. This field is applicable only when scan blanking
483   * feature is enabled. When scan blanking feature is disabled, this field
484   * will be set to zero.
485   */
486  struct sscan_report_fields_gen3 {
487  	uint8_t sscan_agc_total_gain;
488  	int16_t inband_pwr_db;
489  	uint8_t sscan_gainchange;
490  	uint8_t sscan_pri80;
491  	uint8_t sscan_detector_id;
492  	uint8_t blanking_status;
493  };
494  
495  /**
496   * struct spectral_sscan_summary_report_gen3 - Spectral summary report
497   * event
498   * @sscan_timestamp:  Timestamp at which fft report was generated
499   * @sscan_hdr_lts:    length, tag, signature fields
500   * @hdr_a:          Header[0:31]
501   * @res1:           Header[32:63]
502   * @hdr_b:          Header[64:95]
503   * @hdr_c:          Header[96:127]
504   */
505  struct spectral_sscan_summary_report_gen3 {
506  	u_int32_t sscan_timestamp;
507  	u_int32_t sscan_hdr_lts;
508  	u_int32_t hdr_a;
509  	u_int32_t res1;
510  	u_int32_t hdr_b;
511  	u_int32_t hdr_c;
512  } __ATTRIB_PACK;
513  
514  /**
515   * struct spectral_sscan_summary_report_padding_gen3_v2 - Spectral summary
516   * report padding region
517   * @hdr_a: Header[0:31]
518   * @hdr_b: Header[32:63]
519   * @hdr_c: Header[64:95]
520   * @hdr_d: Header[96:127]
521   */
522  struct spectral_sscan_summary_report_padding_gen3_v2 {
523  	u_int32_t hdr_a;
524  	u_int32_t hdr_b;
525  	u_int32_t hdr_c;
526  	u_int32_t hdr_d;
527  } __ATTRIB_PACK;
528  
529  #ifdef DIRECT_BUF_RX_ENABLE
530  /**
531   * struct spectral_report - spectral report
532   * @data: Report buffer
533   * @noisefloor: Noise floor values
534   * @reset_delay: Time taken for warm reset in us
535   * @cfreq1: center frequency 1
536   * @cfreq2: center frequency 2
537   * @ch_width: channel width
538   */
539  struct spectral_report {
540  	uint8_t *data;
541  	int32_t noisefloor[DBR_MAX_CHAINS];
542  	uint32_t reset_delay;
543  	uint32_t cfreq1;
544  	uint32_t cfreq2;
545  	uint32_t ch_width;
546  };
547  #endif
548  /* END of spectral GEN III HW specific details */
549  
550  typedef signed char pwr_dbm;
551  
552  /**
553   * enum spectral_gen - spectral hw generation
554   * @SPECTRAL_GEN1 : spectral hw gen 1
555   * @SPECTRAL_GEN2 : spectral hw gen 2
556   * @SPECTRAL_GEN3 : spectral hw gen 3
557   */
558  enum spectral_gen {
559  	SPECTRAL_GEN1,
560  	SPECTRAL_GEN2,
561  	SPECTRAL_GEN3,
562  };
563  
564  /**
565   * enum spectral_fftbin_size_war - spectral fft bin size war
566   * @SPECTRAL_FFTBIN_SIZE_NO_WAR: No WAR applicable for Spectral FFT bin size
567   * @SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE: Spectral FFT bin size: Retain only
568   *                                           least significant byte from 2 byte
569   *                                           FFT bin transferred by HW
570   * @SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE: Spectral FFT bin size: Retain only
571   *                                           least significant byte from 4 byte
572   *                                           FFT bin transferred by HW
573   */
574  enum spectral_fftbin_size_war {
575  	SPECTRAL_FFTBIN_SIZE_NO_WAR = 0,
576  	SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE = 1,
577  	SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE = 2,
578  };
579  
580  /**
581   * enum spectral_report_format_version - This represents the report format
582   * version number within each Spectral generation.
583   * @SPECTRAL_REPORT_FORMAT_VERSION_1 : version 1
584   * @SPECTRAL_REPORT_FORMAT_VERSION_2 : version 2
585   */
586  enum spectral_report_format_version {
587  	SPECTRAL_REPORT_FORMAT_VERSION_1,
588  	SPECTRAL_REPORT_FORMAT_VERSION_2,
589  };
590  
591  /**
592   * struct spectral_fft_bin_len_adj_swar - Encapsulate information required for
593   * Spectral FFT bin length adjusting software WARS.
594   * @inband_fftbin_size_adj: Whether to carry out FFT bin size adjustment for
595   * in-band report format. This would be required on some chipsets under the
596   * following circumstances: In report mode 2 only the in-band bins are DMA'ed.
597   * Scatter/gather is used. However, the HW generates all bins, not just in-band,
598   * and reports the number of bins accordingly. The subsystem arranging for the
599   * DMA cannot change this value. On such chipsets the adjustment required at the
600   * host driver is to check if report format is 2, and if so halve the number of
601   * bins reported to get the number actually DMA'ed.
602   * @null_fftbin_adj: Whether to remove NULL FFT bins for report mode (1) in
603   * which only summary of metrics for each completed FFT + spectral scan summary
604   * report are to be provided. This would be required on some chipsets under the
605   * following circumstances: In report mode 1, HW reports a length corresponding
606   * to all bins, and provides bins with value 0. This is because the subsystem
607   * arranging for the FFT information does not arrange for DMA of FFT bin values
608   * (as expected), but cannot arrange for a smaller length to be reported by HW.
609   * In these circumstances, the driver would have to disregard the NULL bins and
610   * report a bin count of 0 to higher layers.
611   * @packmode_fftbin_size_adj: Pack mode in HW refers to packing of each Spectral
612   * FFT bin into 2 bytes. But due to a bug HW reports 2 times the expected length
613   * when packmode is enabled. This SWAR compensates this bug by dividing the
614   * length with 2.
615   * @fftbin_size_war: Type of FFT bin size SWAR
616   */
617  struct spectral_fft_bin_len_adj_swar {
618  	u_int8_t inband_fftbin_size_adj;
619  	u_int8_t null_fftbin_adj;
620  	uint8_t packmode_fftbin_size_adj;
621  	enum spectral_fftbin_size_war fftbin_size_war;
622  };
623  
624  /**
625   * struct spectral_report_params - Parameters related to format of Spectral
626   * report.
627   * @version: This represents the report format version number within each
628   * Spectral generation.
629   * @ssummary_padding_bytes: Number of bytes of padding after Spectral summary
630   * report
631   * @fft_report_hdr_len: Number of bytes in the header of the FFT report. This
632   * has to be subtracted from the length field of FFT report to find the length
633   * of FFT bins.
634   * @fragmentation_160: This indicates whether Spectral reports in 160/80p80 is
635   * fragmented.
636   * @detid_mode_table: Detector ID to Spectral scan mode table
637   * @num_spectral_detectors: Total number of Spectral detectors
638   * @marker: Describes the boundaries of pri80, 5 MHz and sec80 bins
639   * @hw_fft_bin_width: FFT bin width reported by the HW
640   */
641  struct spectral_report_params {
642  	enum spectral_report_format_version version;
643  	uint8_t ssummary_padding_bytes;
644  	uint8_t fft_report_hdr_len;
645  	bool fragmentation_160[SPECTRAL_SCAN_MODE_MAX];
646  	enum spectral_scan_mode detid_mode_table[SPECTRAL_DETECTOR_ID_MAX];
647  	uint8_t num_spectral_detectors;
648  	struct spectral_fft_bin_markers_160_165mhz
649  				marker[SPECTRAL_SCAN_MODE_MAX];
650  	uint8_t hw_fft_bin_width;
651  };
652  
653  /**
654   * struct spectral_param_min_max - Spectral parameter minimum and maximum values
655   * @fft_size_min: Minimum value of fft_size
656   * @fft_size_max: Maximum value of fft_size for each BW
657   * @scan_count_max: Maximum value of scan count
658   */
659  struct spectral_param_min_max {
660  	uint16_t fft_size_min;
661  	uint16_t fft_size_max[CH_WIDTH_MAX];
662  	uint16_t scan_count_max;
663  };
664  
665  /**
666   * struct spectral_timestamp_war - Spectral time stamp WAR related parameters
667   * @timestamp_war_offset: Offset to be added to correct timestamp
668   * @target_reset_count: Number of times target exercised the reset routine
669   * @last_fft_timestamp: last fft report timestamp
670   */
671  struct spectral_timestamp_war {
672  	uint32_t timestamp_war_offset[SPECTRAL_SCAN_MODE_MAX];
673  	uint64_t target_reset_count;
674  	uint32_t last_fft_timestamp[SPECTRAL_SCAN_MODE_MAX];
675  };
676  
677  #if ATH_PERF_PWR_OFFLOAD
678  /**
679   * enum target_if_spectral_info - Enumerations for specifying which spectral
680   *                              information (among parameters and states)
681   *                              is desired.
682   * @TARGET_IF_SPECTRAL_INFO_ACTIVE:  Indicated whether spectral is active
683   * @TARGET_IF_SPECTRAL_INFO_ENABLED: Indicated whether spectral is enabled
684   * @TARGET_IF_SPECTRAL_INFO_PARAMS:  Config params
685   */
686  enum target_if_spectral_info {
687  	TARGET_IF_SPECTRAL_INFO_ACTIVE,
688  	TARGET_IF_SPECTRAL_INFO_ENABLED,
689  	TARGET_IF_SPECTRAL_INFO_PARAMS,
690  };
691  #endif /* ATH_PERF_PWR_OFFLOAD */
692  
693  /* forward declaration */
694  struct target_if_spectral;
695  
696  /**
697   * struct target_if_spectral_chan_info - Channel information
698   * @center_freq1: center frequency 1 in MHz
699   * @center_freq2: center frequency 2 in MHz -valid only for
700   *		 11ACVHT 80PLUS80 mode
701   * @chan_width:   channel width in MHz
702   */
703  struct target_if_spectral_chan_info {
704  	uint16_t    center_freq1;
705  	uint16_t    center_freq2;
706  	uint8_t     chan_width;
707  };
708  
709  /**
710   * struct target_if_spectral_acs_stats - EACS stats from spectral samples
711   * @nfc_ctl_rssi: Control chan rssi
712   * @nfc_ext_rssi: Extension chan rssi
713   * @ctrl_nf:      Control chan Noise Floor
714   * @ext_nf:       Extension chan Noise Floor
715   */
716  struct target_if_spectral_acs_stats {
717  	int8_t nfc_ctl_rssi;
718  	int8_t nfc_ext_rssi;
719  	int8_t ctrl_nf;
720  	int8_t ext_nf;
721  };
722  
723  /**
724   * struct target_if_spectral_perchain_rssi_info - per chain rssi info
725   * @rssi_pri20: Rssi of primary 20 Mhz
726   * @rssi_sec20: Rssi of secondary 20 Mhz
727   * @rssi_sec40: Rssi of secondary 40 Mhz
728   * @rssi_sec80: Rssi of secondary 80 Mhz
729   */
730  struct target_if_spectral_perchain_rssi_info {
731  	int8_t    rssi_pri20;
732  	int8_t    rssi_sec20;
733  	int8_t    rssi_sec40;
734  	int8_t    rssi_sec80;
735  };
736  
737  /**
738   * struct target_if_spectral_rfqual_info - RF measurement information
739   * @rssi_comb:    RSSI Information
740   * @pc_rssi_info: XXX : For now, we know we are getting information
741   *                for only 4 chains at max. For future extensions
742   *                use a define
743   * @noise_floor:  Noise floor information
744   */
745  struct target_if_spectral_rfqual_info {
746  	int8_t    rssi_comb;
747  	struct    target_if_spectral_perchain_rssi_info pc_rssi_info[4];
748  	int16_t   noise_floor[4];
749  };
750  
751  #define GET_TARGET_IF_SPECTRAL_OPS(spectral) \
752  	((struct target_if_spectral_ops *)(&((spectral)->spectral_ops)))
753  
754  /**
755   * struct target_if_spectral_ops - spectral low level ops table
756   * @get_tsf64:               Get 64 bit TSF value
757   * @get_capability:          Get capability info
758   * @set_rxfilter:            Set rx filter
759   * @get_rxfilter:            Get rx filter
760   * @is_spectral_active:      Check whether icm is active
761   * @is_spectral_enabled:     Check whether spectral is enabled
762   * @start_spectral_scan:     Start spectral scan
763   * @stop_spectral_scan:      Stop spectral scan
764   * @get_extension_channel:   Get extension channel
765   * @get_ctl_noisefloor:      Get control noise floor
766   * @get_ext_noisefloor:      Get extension noise floor
767   * @configure_spectral:      Set spectral configurations
768   * @get_spectral_config:     Get spectral configurations
769   * @get_ent_spectral_mask:   Get spectral mask
770   * @get_mac_address:         Get mac address
771   * @get_current_channel:     Get current channel
772   * @reset_hw:                Reset HW
773   * @get_chain_noise_floor:   Get Channel noise floor
774   * @spectral_process_phyerr: Process phyerr event
775   * @process_spectral_report: Process spectral report
776   * @byte_swap_headers:       Apply byte-swap on report headers
777   * @byte_swap_fft_bins:      Apply byte-swap on FFT bins
778   */
779  struct target_if_spectral_ops {
780  	uint64_t (*get_tsf64)(void *arg);
781  	uint32_t (*get_capability)(
782  		void *arg, enum spectral_capability_type type);
783  	uint32_t (*set_rxfilter)(void *arg, int rxfilter);
784  	uint32_t (*get_rxfilter)(void *arg);
785  	uint32_t (*is_spectral_active)(void *arg,
786  				       enum spectral_scan_mode smode);
787  	uint32_t (*is_spectral_enabled)(void *arg,
788  					enum spectral_scan_mode smode);
789  	uint32_t (*start_spectral_scan)(void *arg,
790  					enum spectral_scan_mode smode,
791  					enum spectral_cp_error_code *err);
792  	uint32_t (*stop_spectral_scan)(void *arg,
793  				       enum spectral_scan_mode smode);
794  	uint32_t (*get_extension_channel)(void *arg,
795  					  enum spectral_scan_mode smode);
796  	int8_t    (*get_ctl_noisefloor)(void *arg);
797  	int8_t    (*get_ext_noisefloor)(void *arg);
798  	uint32_t (*configure_spectral)(
799  			void *arg,
800  			struct spectral_config *params,
801  			enum spectral_scan_mode smode);
802  	uint32_t (*get_spectral_config)(
803  			void *arg,
804  			struct spectral_config *params,
805  			enum spectral_scan_mode smode);
806  	uint32_t (*get_ent_spectral_mask)(void *arg);
807  	uint32_t (*get_mac_address)(void *arg, char *addr);
808  	uint32_t (*get_current_channel)(void *arg,
809  					enum spectral_scan_mode smode);
810  	uint32_t (*reset_hw)(void *arg);
811  	uint32_t (*get_chain_noise_floor)(void *arg, int16_t *nf_buf);
812  	int (*spectral_process_phyerr)(struct target_if_spectral *spectral,
813  				       uint8_t *data, uint32_t datalen,
814  			struct target_if_spectral_rfqual_info *p_rfqual,
815  			struct target_if_spectral_chan_info *p_chaninfo,
816  			uint64_t tsf64,
817  			struct target_if_spectral_acs_stats *acs_stats);
818  	int (*process_spectral_report)(struct wlan_objmgr_pdev *pdev,
819  				       void *payload);
820  	QDF_STATUS (*byte_swap_headers)(
821  		struct target_if_spectral *spectral,
822  		void *data);
823  	QDF_STATUS (*byte_swap_fft_bins)(
824  		const struct spectral_report_params *rparams,
825  		void *bin_pwr_data, size_t num_fftbins);
826  };
827  
828  /**
829   * struct target_if_spectral_stats - spectral stats info
830   * @num_spectral_detects: Total num. of spectral detects
831   * @total_phy_errors:     Total number of phyerrors
832   * @owl_phy_errors:       Indicated phyerrors in old gen1 chipsets
833   * @pri_phy_errors:       Phyerrors in primary channel
834   * @ext_phy_errors:       Phyerrors in secondary channel
835   * @dc_phy_errors:        Phyerrors due to dc
836   * @early_ext_phy_errors: Early secondary channel phyerrors
837   * @bwinfo_errors:        Bandwidth info errors
838   * @datalen_discards:     Invalid data length errors, seen in gen1 chipsets
839   * @rssi_discards:        Indicates reports dropped due to RSSI threshold
840   * @last_reset_tstamp:    Last reset time stamp
841   */
842  struct target_if_spectral_stats {
843  	uint32_t    num_spectral_detects;
844  	uint32_t    total_phy_errors;
845  	uint32_t    owl_phy_errors;
846  	uint32_t    pri_phy_errors;
847  	uint32_t    ext_phy_errors;
848  	uint32_t    dc_phy_errors;
849  	uint32_t    early_ext_phy_errors;
850  	uint32_t    bwinfo_errors;
851  	uint32_t    datalen_discards;
852  	uint32_t    rssi_discards;
853  	uint64_t    last_reset_tstamp;
854  };
855  
856  /**
857   * struct target_if_spectral_event - spectral event structure
858   * @se_ts:        Original 15 bit recv timestamp
859   * @se_full_ts:   64-bit full timestamp from interrupt time
860   * @se_rssi:      Rssi of spectral event
861   * @se_bwinfo:    Rssi of spectral event
862   * @se_dur:       Duration of spectral pulse
863   * @se_chanindex: Channel of event
864   * @se_list:      List of spectral events
865   */
866  struct target_if_spectral_event {
867  	uint32_t                       se_ts;
868  	uint64_t                       se_full_ts;
869  	uint8_t                        se_rssi;
870  	uint8_t                        se_bwinfo;
871  	uint8_t                        se_dur;
872  	uint8_t                        se_chanindex;
873  
874  	STAILQ_ENTRY(spectral_event)    se_list;
875  };
876  
877  /**
878   * struct target_if_chain_noise_pwr_info - Noise power info for each channel
879   * @rptcount:        Count of reports in pwr array
880   * @un_cal_nf:       Uncalibrated noise floor
881   * @factory_cal_nf:  Noise floor as calibrated at the factory for module
882   * @median_pwr:      Median power (median of pwr array)
883   * @pwr:             Power reports
884   */
885  struct target_if_chain_noise_pwr_info {
886  	int        rptcount;
887  	pwr_dbm    un_cal_nf;
888  	pwr_dbm    factory_cal_nf;
889  	pwr_dbm    median_pwr;
890  	pwr_dbm    pwr[];
891  } __ATTRIB_PACK;
892  
893  /**
894   * struct target_if_spectral_chan_stats - Channel information
895   * @cycle_count:         Cycle count
896   * @channel_load:        Channel load
897   * @per:                 Period
898   * @noisefloor:          Noise floor
899   * @comp_usablity:       Computed usability
900   * @maxregpower:         Maximum allowed regulatary power
901   * @comp_usablity_sec80: Computed usability of secondary 80 Mhz
902   * @maxregpower_sec80:   Max regulatory power in secondary 80 Mhz
903   */
904  struct target_if_spectral_chan_stats {
905  	int          cycle_count;
906  	int          channel_load;
907  	int          per;
908  	int          noisefloor;
909  	uint16_t    comp_usablity;
910  	int8_t       maxregpower;
911  	uint16_t    comp_usablity_sec80;
912  	int8_t       maxregpower_sec80;
913  };
914  
915  #if ATH_PERF_PWR_OFFLOAD
916  
917  /**
918   * struct target_if_spectral_cache - Cache used to minimize WMI operations
919   *                             in offload architecture
920   * @osc_spectral_enabled: Whether Spectral is enabled
921   * @osc_spectral_active:  Whether spectral is active
922   *                        XXX: Ideally, we should NOT cache this
923   *                        since the hardware can self clear the bit,
924   *                        the firmware can possibly stop spectral due to
925   *                        intermittent off-channel activity, etc
926   *                        A WMI read command should be introduced to handle
927   *                        this This will be discussed.
928   * @osc_params:           Spectral parameters
929   * @osc_is_valid:         Whether the cache is valid
930   */
931  struct target_if_spectral_cache {
932  	uint8_t                  osc_spectral_enabled;
933  	uint8_t                  osc_spectral_active;
934  	struct spectral_config    osc_params;
935  	uint8_t                  osc_is_valid;
936  };
937  
938  /**
939   * struct target_if_spectral_param_state_info - Structure used to represent and
940   *                                        manage spectral information
941   *                                        (parameters and states)
942   * @osps_lock:  Lock to synchronize accesses to information
943   * @osps_cache: Cacheable' information
944   */
945  struct target_if_spectral_param_state_info {
946  	qdf_spinlock_t               osps_lock;
947  	struct target_if_spectral_cache    osps_cache;
948  	/* XXX - Non-cacheable information goes here, in the future */
949  };
950  #endif /* ATH_PERF_PWR_OFFLOAD */
951  
952  struct vdev_spectral_configure_params;
953  struct vdev_spectral_enable_params;
954  
955  /**
956   * struct spectral_wmi_ops - structure used holding the operations
957   * related to Spectral WMI
958   * @wmi_spectral_configure_cmd_send: Configure Spectral parameters
959   * @wmi_spectral_enable_cmd_send: Enable/Disable Spectral
960   * @wmi_spectral_crash_inject: Inject FW crash
961   * @wmi_extract_pdev_sscan_fw_cmd_fixed_param: Extract Fixed params from
962   * start scan response event
963   * @wmi_extract_pdev_sscan_fft_bin_index: Extract TLV which describes FFT
964   * bin indices from start scan response event
965   * @wmi_unified_register_event_handler: Register WMI event handler
966   * @wmi_unified_unregister_event_handler: Unregister WMI event handler
967   * @wmi_service_enabled: API to check whether a given WMI service is enabled
968   * @extract_pdev_spectral_session_chan_info: Extract Spectral scan session
969   * channel information
970   * @extract_pdev_spectral_session_detector_info: Extract Spectral scan session
971   * detector information
972   * @extract_spectral_caps_fixed_param: Extract fixed parameters from Spectral
973   * capabilities event
974   * @extract_spectral_scan_bw_caps: Extract bandwidth capabilities from Spectral
975   * capabilities event
976   * @extract_spectral_fft_size_caps: Extract fft size capabilities from Spectral
977   * capabilities event
978   */
979  struct spectral_wmi_ops {
980  	QDF_STATUS (*wmi_spectral_configure_cmd_send)(
981  		    wmi_unified_t wmi_hdl,
982  		    struct vdev_spectral_configure_params *param);
983  	QDF_STATUS (*wmi_spectral_enable_cmd_send)(
984  		    wmi_unified_t wmi_hdl,
985  		    struct vdev_spectral_enable_params *param);
986  	QDF_STATUS (*wmi_spectral_crash_inject)(
987  		wmi_unified_t wmi_handle, struct crash_inject *param);
988  	QDF_STATUS (*wmi_extract_pdev_sscan_fw_cmd_fixed_param)(
989  				wmi_unified_t wmi_handle, uint8_t *evt_buf,
990  				struct spectral_startscan_resp_params *param);
991  	QDF_STATUS (*wmi_extract_pdev_sscan_fft_bin_index)(
992  			wmi_unified_t wmi_handle, uint8_t *evt_buf,
993  			struct spectral_fft_bin_markers_160_165mhz *param);
994  	QDF_STATUS (*wmi_unified_register_event_handler)(
995  				wmi_unified_t wmi_handle,
996  				wmi_conv_event_id event_id,
997  				wmi_unified_event_handler handler_func,
998  				uint8_t rx_ctx);
999  	QDF_STATUS (*wmi_unified_unregister_event_handler)(
1000  				wmi_unified_t wmi_handle,
1001  				wmi_conv_event_id event_id);
1002  	bool (*wmi_service_enabled)(wmi_unified_t wmi_handle,
1003  				    uint32_t service_id);
1004  	QDF_STATUS (*extract_pdev_spectral_session_chan_info)(
1005  			wmi_unified_t wmi_handle, void *event,
1006  			struct spectral_session_chan_info *chan_info);
1007  	QDF_STATUS (*extract_pdev_spectral_session_detector_info)(
1008  		wmi_unified_t wmi_handle, void *event,
1009  		struct spectral_session_det_info *det_info,
1010  		uint8_t det_info_idx);
1011  	QDF_STATUS (*extract_spectral_caps_fixed_param)(
1012  		wmi_unified_t wmi_handle, void *event,
1013  		struct spectral_capabilities_event_params *param);
1014  	QDF_STATUS (*extract_spectral_scan_bw_caps)(
1015  		wmi_unified_t wmi_handle, void *event,
1016  		struct spectral_scan_bw_capabilities *bw_caps);
1017  	QDF_STATUS (*extract_spectral_fft_size_caps)(
1018  		wmi_unified_t wmi_handle, void *event,
1019  		struct spectral_fft_size_capabilities *fft_size_caps);
1020  };
1021  
1022  /**
1023   * struct spectral_tgt_ops - structure used holding the operations
1024   * related to target operations
1025   * @tgt_get_psoc_from_scn_hdl: Function to get psoc from scn
1026   */
1027  struct spectral_tgt_ops {
1028  	struct wlan_objmgr_psoc *(*tgt_get_psoc_from_scn_hdl)(void *scn_handle);
1029  };
1030  
1031  /**
1032   * struct spectral_param_properties - structure holding Spectral
1033   *                                    parameter properties
1034   * @supported: Parameter is supported or not
1035   * @common_all_modes: Parameter should be common for all modes or not
1036   */
1037  struct spectral_param_properties {
1038  	bool supported;
1039  	bool common_all_modes;
1040  };
1041  
1042  /**
1043   * struct target_if_finite_spectral_scan_params - Parameters related to finite
1044   * Spectral scan
1045   * @finite_spectral_scan: Indicates the Spectrl scan is finite/infinite
1046   * @num_reports_expected: Number of Spectral reports expected from target for a
1047   * finite Spectral scan
1048   */
1049  struct target_if_finite_spectral_scan_params {
1050  	bool finite_spectral_scan;
1051  	uint32_t num_reports_expected;
1052  };
1053  
1054  /**
1055   * struct per_session_dest_det_info - Per-session Detector information to be
1056   * filled to samp_detector_info
1057   * @freq_span_id: Contiguous frequency span ID within the SAMP message
1058   * @is_sec80: Indicates pri80/sec80 segment for 160/80p80 BW
1059   * @det_id: Detector ID within samp_freq_span_info corresponding to
1060   * freq_span_id
1061   * @dest_start_bin_idx: Start index of FFT bins within SAMP msg's bin_pwr array
1062   * @dest_end_bin_idx: End index of FFT bins within SAMP msg's bin_pwr array
1063   * @lb_extrabins_start_idx: Left band edge extra bins start index
1064   * @lb_extrabins_num: Number of left band edge extra bins
1065   * @rb_extrabins_start_idx: Right band edge extra bins start index
1066   * @rb_extrabins_num: Number of right band edge extra bins
1067   * @start_freq: Indicates start frequency per-detector (in MHz)
1068   * @end_freq: Indicates last frequency per-detector (in MHz)
1069   * @src_start_bin_idx: Start index within the Spectral report's bin_pwr array,
1070   * where the FFT bins corresponding to this dest_det_id start
1071   */
1072  struct per_session_dest_det_info {
1073  	uint8_t freq_span_id;
1074  	bool is_sec80;
1075  	uint8_t det_id;
1076  	uint16_t dest_start_bin_idx;
1077  	uint16_t dest_end_bin_idx;
1078  	uint16_t lb_extrabins_start_idx;
1079  	uint16_t lb_extrabins_num;
1080  	uint16_t rb_extrabins_start_idx;
1081  	uint16_t rb_extrabins_num;
1082  	uint32_t start_freq;
1083  	uint32_t end_freq;
1084  	uint16_t src_start_bin_idx;
1085  };
1086  
1087  /**
1088   * struct per_session_det_map - A map of per-session detector information,
1089   * keyed by the detector id obtained from the Spectral FFT report, mapping to
1090   * destination detector info in SAMP message.
1091   * @dest_det_info: Struct containing per-session detector information
1092   * @num_dest_det_info: Number of destination detectors to which information
1093   * of this detector is to be filled
1094   * @buf_type: Spectral message buffer type
1095   * @send_to_upper_layers: Indicates whether to send SAMP msg to upper layers
1096   * @det_map_valid: Indicates whether detector map is valid or not
1097   */
1098  struct per_session_det_map {
1099  	struct per_session_dest_det_info
1100  			dest_det_info[MAX_NUM_DEST_DETECTOR_INFO];
1101  	uint8_t num_dest_det_info;
1102  	enum spectral_msg_buf_type buf_type;
1103  	bool send_to_upper_layers;
1104  	bool det_map_valid[SPECTRAL_SCAN_MODE_MAX];
1105  };
1106  
1107  /**
1108   * struct per_session_report_info - Consists of per-session Spectral report
1109   * information to be filled at report level in SAMP message.
1110   * @pri20_freq: Primary 20MHz operating frequency in MHz
1111   * @cfreq1: Centre frequency of the frequency span for 20/40/80 MHz BW.
1112   * Segment 1 centre frequency in MHz for 80p80/160 BW.
1113   * @cfreq2: For 80p80, indicates segment 2 centre frequency in MHz. For 160MHz,
1114   * indicates the center frequency of 160MHz span.
1115   * @operating_bw: Device's operating bandwidth.Valid values = enum phy_ch_width
1116   * @sscan_cfreq1: Normal/Agile scan Centre frequency of the frequency span for
1117   * 20/40/80 MHz BW. Center frequency of Primary Segment in MHz for 80p80/160 BW
1118   * Based on Spectral scan mode.
1119   * @sscan_cfreq2: For 80p80, Normal/Agile scan Center frequency for Sec80
1120   * segment. For 160MHz, indicates the center frequency of 160MHz span. Based on
1121   * spectral scan mode
1122   * @sscan_bw: Normal/Agile Scan BW based on Spectral scan mode.
1123   * Valid values = enum phy_ch_width
1124   * @num_spans: Number of frequency spans
1125   * @valid: Indicated whether report info is valid
1126   */
1127  struct per_session_report_info {
1128  	uint32_t pri20_freq;
1129  	uint32_t cfreq1;
1130  	uint32_t cfreq2;
1131  	enum phy_ch_width operating_bw;
1132  	uint32_t sscan_cfreq1;
1133  	uint32_t sscan_cfreq2;
1134  	enum phy_ch_width sscan_bw;
1135  	uint8_t num_spans;
1136  	bool valid;
1137  };
1138  
1139  /**
1140   * struct sscan_detector_list - Spectral scan Detector list, for given Spectral
1141   * scan mode and operating BW
1142   * @detectors: List of detectors
1143   * @num_detectors: Number of detectors for given spectral scan mode, BW
1144   *                 and target type
1145   */
1146  struct sscan_detector_list {
1147  	uint8_t detectors[SPECTRAL_DETECTOR_ID_MAX];
1148  	uint8_t num_detectors;
1149  };
1150  
1151  /**
1152   * struct spectral_supported_bws - Supported sscan bandwidths
1153   * @supports_sscan_bw_5: 5 MHz bandwidth supported
1154   * @supports_sscan_bw_10: 10 MHz bandwidth supported
1155   * @supports_sscan_bw_20: 20 MHz bandwidth supported
1156   * @supports_sscan_bw_40: 40 MHz bandwidth supported
1157   * @supports_sscan_bw_80: 80 MHz bandwidth supported
1158   * @supports_sscan_bw_160: 160 MHz bandwidth supported
1159   * @supports_sscan_bw_80_80: 80+80 MHz bandwidth supported
1160   * @supports_sscan_bw_320: 320 MHz bandwidth supported
1161   * @reserved: reserved for future use
1162   * @bandwidths: bitmap of supported sscan bandwidths. Make sure to maintain this
1163   * bitmap in the increasing order of bandwidths.
1164   */
1165  struct spectral_supported_bws {
1166  	union {
1167  		struct {
1168  			uint32_t supports_sscan_bw_5:1,
1169  				 supports_sscan_bw_10:1,
1170  				 supports_sscan_bw_20:1,
1171  				 supports_sscan_bw_40:1,
1172  				 supports_sscan_bw_80:1,
1173  				 supports_sscan_bw_160:1,
1174  				 supports_sscan_bw_80_80:1,
1175  				 supports_sscan_bw_320:1,
1176  				 reserved:24;
1177  		};
1178  		uint32_t bandwidths;
1179  	};
1180  };
1181  
1182  /**
1183   * get_supported_sscan_bw_pos() - Get the position of a given sscan_bw inside
1184   * the supported sscan bandwidths bitmap
1185   * @sscan_bw: Spectral scan bandwidth
1186   *
1187   * Return: bit position for a valid sscan bandwidth, else -1
1188   */
1189  int get_supported_sscan_bw_pos(enum phy_ch_width sscan_bw);
1190  
1191  /**
1192   * struct target_if_spectral - main spectral structure
1193   * @pdev_obj: Pointer to pdev
1194   * @spectral_ops: Target if internal Spectral low level operations table
1195   * @capability: Spectral capabilities structure
1196   * @properties: Spectral parameter properties per mode
1197   * @spectral_lock: Lock used for internal Spectral operations
1198   * @vdev_id: VDEV id for all spectral modes
1199   * @spectral_curchan_radindex: Current channel spectral index
1200   * @spectral_extchan_radindex: Extension channel spectral index
1201   * @spectraldomain: Current Spectral domain
1202   * @spectral_proc_phyerr:  Flags to process for PHY errors
1203   * @spectral_defaultparams: Default PHY params per Spectral stat
1204   * @spectral_stats:  Spectral related stats
1205   * @events:   Events structure
1206   * @sc_spectral_ext_chan_ok:  Can spectral be detected on the extension channel?
1207   * @sc_spectral_combined_rssi_ok:  Can use combined spectral RSSI?
1208   * @sc_spectral_20_40_mode:  Is AP in 20-40 mode?
1209   * @sc_spectral_noise_pwr_cal:  Noise power cal required?
1210   * @sc_spectral_non_edma:  Is the spectral capable device Non-EDMA?
1211   * @upper_is_control: Upper segment is primary
1212   * @upper_is_extension: Upper segment is secondary
1213   * @lower_is_control: Lower segment is primary
1214   * @lower_is_extension: Lower segment is secondary
1215   * @sc_spectraltest_ieeechan:  IEEE channel number to return to after a spectral
1216   * mute test
1217   * @spectral_numbins: Number of bins
1218   * @spectral_fft_len: FFT length
1219   * @spectral_data_len: Total phyerror report length
1220   * @lb_edge_extrabins: Number of extra bins on left band edge
1221   * @rb_edge_extrabins: Number of extra bins on right band edge
1222   * @spectral_max_index_offset: Max FFT index offset (20 MHz mode)
1223   * @spectral_upper_max_index_offset: Upper max FFT index offset (20/40 MHz mode)
1224   * @spectral_lower_max_index_offset: Lower max FFT index offset (20/40 MHz mode)
1225   * @spectral_dc_index: At which index DC is present
1226   * @send_single_packet: Deprecated
1227   * @spectral_sent_msg: Indicates whether we send report to upper layers
1228   * @classify_scan:
1229   * @classify_timer:
1230   * @params: Spectral parameters
1231   * @params_valid:
1232   * @classifier_params:
1233   * @last_capture_time: Indicates timestamp of previous report
1234   * @num_spectral_data: Number of Spectral samples received in current session
1235   * @total_spectral_data: Total number of Spectral samples received
1236   * @max_rssi: Maximum RSSI
1237   * @detects_control_channel: NA
1238   * @detects_extension_channel: NA
1239   * @detects_below_dc: NA
1240   * @detects_above_dc: NA
1241   * @sc_scanning: Indicates active wifi scan
1242   * @sc_spectral_scan: Indicates active specral scan
1243   * @sc_spectral_full_scan: Deprecated
1244   * @scan_start_tstamp: Deprecated
1245   * @last_tstamp: Deprecated
1246   * @first_tstamp: Deprecated
1247   * @spectral_samp_count: Deprecated
1248   * @sc_spectral_samp_count: Deprecated
1249   * @noise_pwr_reports_reqd: Number of noise power reports required
1250   * @noise_pwr_reports_recv: Number of noise power reports received
1251   * @noise_pwr_reports_lock: Lock used for Noise power report processing
1252   * @noise_pwr_chain_ctl: Noise power report - control channel
1253   * @noise_pwr_chain_ext: Noise power report - extension channel
1254   * @tsf64: Latest TSF Value
1255   * @param_info: Offload architecture Spectral parameter cache information
1256   * @ch_width: Indicates Channel Width 20/40/80/160 MHz for each Spectral mode
1257   * @sscan_width_configured: Whether user has configured sscan bandwidth
1258   * @diag_stats: Diagnostic statistics
1259   * @is_160_format:  Indicates whether information provided by HW is in altered
1260   * format for 802.11ac 160/80+80 MHz support (QCA9984 onwards)
1261   * @is_lb_edge_extrabins_format:  Indicates whether information provided by
1262   * HW has 4 extra bins, at left band edge, for report mode 2
1263   * @is_rb_edge_extrabins_format:   Indicates whether information provided
1264   * by HW has 4 extra bins, at right band edge, for report mode 2
1265   * @is_sec80_rssi_war_required: Indicates whether the software workaround is
1266   * required to obtain approximate combined RSSI for secondary 80Mhz segment
1267   * @simctx: Spectral Simulation context
1268   * @spectral_gen: Spectral hardware generation
1269   * @hdr_sig_exp: Expected signature in PHYERR TLV header, for the given hardware
1270   * generation
1271   * @tag_sscan_summary_exp: Expected Spectral Scan Summary tag in PHYERR TLV
1272   * header, for the given hardware generation
1273   * @tag_sscan_fft_exp: Expected Spectral Scan FFT report tag in PHYERR TLV
1274   * header, for the given hardware generation
1275   * @tlvhdr_size: Expected PHYERR TLV header size, for the given hardware
1276   * generation
1277   * @nl_cb: Netlink callbacks
1278   * @use_nl_bcast: Whether to use Netlink broadcast/unicast
1279   * @send_phy_data: Send data to the application layer for a particular msg type
1280   * @len_adj_swar: Spectral fft bin length adjustment SWAR related info
1281   * @timestamp_war: Spectral time stamp WAR related info
1282   * @state_160mhz_delivery: Delivery state for each spectral scan mode
1283   * @dbr_ring_debug: Whether Spectral DBR ring debug is enabled
1284   * @dbr_buff_debug: Whether Spectral DBR buffer debug is enabled
1285   * @direct_dma_support: Whether Direct-DMA is supported on the current radio
1286   * @prev_tstamp: Timestamp of the previously received sample, which has to be
1287   * compared with the current tstamp to check descrepancy
1288   * @rparams: Parameters related to Spectral report structure
1289   * @param_min_max: Spectral parameter's minimum and maximum values
1290   * @finite_scan: Parameters for finite Spectral scan
1291   * @detector_list: Detector list for a given Spectral scan mode and channel
1292   * width, based on the target type.
1293   * @detector_list_lock: Lock to synchronize accesses to detector list
1294   * @det_map: Map of per-session detector information keyed by the Spectral HW
1295   * detector id.
1296   * @session_det_map_lock: Lock to synchronize accesses to session detector map
1297   * @report_info: Per session info to be filled at report level in SAMP message
1298   * @session_report_info_lock: Lock to synchronize access to session report info
1299   * @supported_bws: Supported sscan bandwidths for all sscan modes and
1300   * operating widths
1301   * @supported_sscan_bw_list: List of supported sscan widths for all sscan modes
1302   * @data_stats: stats in Spectral data path
1303   */
1304  struct target_if_spectral {
1305  	struct wlan_objmgr_pdev *pdev_obj;
1306  	struct target_if_spectral_ops                 spectral_ops;
1307  	struct spectral_caps                    capability;
1308  	struct spectral_param_properties
1309  			properties[SPECTRAL_SCAN_MODE_MAX][SPECTRAL_PARAM_MAX];
1310  	qdf_spinlock_t                          spectral_lock;
1311  	uint8_t                                 vdev_id[SPECTRAL_SCAN_MODE_MAX];
1312  	int16_t                                 spectral_curchan_radindex;
1313  	int16_t                                 spectral_extchan_radindex;
1314  	uint32_t                               spectraldomain;
1315  	uint32_t                               spectral_proc_phyerr;
1316  	struct spectral_config                  spectral_defaultparams;
1317  	struct target_if_spectral_stats         spectral_stats;
1318  	struct target_if_spectral_event *events;
1319  	unsigned int                            sc_spectral_ext_chan_ok:1,
1320  						sc_spectral_combined_rssi_ok:1,
1321  						sc_spectral_20_40_mode:1,
1322  						sc_spectral_noise_pwr_cal:1,
1323  						sc_spectral_non_edma:1;
1324  	int                                     upper_is_control;
1325  	int                                     upper_is_extension;
1326  	int                                     lower_is_control;
1327  	int                                     lower_is_extension;
1328  	uint8_t                                sc_spectraltest_ieeechan;
1329  	int                                     spectral_numbins;
1330  	int                                     spectral_fft_len;
1331  	int                                     spectral_data_len;
1332  
1333  	/*
1334  	 * For 11ac chipsets prior to AR900B version 2.0, a max of 512 bins are
1335  	 * delivered.  However, there can be additional bins reported for
1336  	 * AR900B version 2.0 and QCA9984 as described next:
1337  	 *
1338  	 * AR900B version 2.0: An additional tone is processed on the right
1339  	 * hand side in order to facilitate detection of radar pulses out to
1340  	 * the extreme band-edge of the channel frequency. Since the HW design
1341  	 * processes four tones at a time, this requires one additional Dword
1342  	 * to be added to the search FFT report.
1343  	 *
1344  	 * QCA9984: When spectral_scan_rpt_mode = 2, i.e 2-dword summary +
1345  	 * 1x-oversampled bins (in-band) per FFT, then 8 more bins
1346  	 * (4 more on left side and 4 more on right side)are added.
1347  	 */
1348  
1349  	int                                     lb_edge_extrabins;
1350  	int                                     rb_edge_extrabins;
1351  	int                                     spectral_max_index_offset;
1352  	int                                     spectral_upper_max_index_offset;
1353  	int                                     spectral_lower_max_index_offset;
1354  	int                                     spectral_dc_index;
1355  	int                                     send_single_packet;
1356  	int                                     spectral_sent_msg;
1357  	int                                     classify_scan;
1358  	qdf_timer_t                             classify_timer;
1359  	struct spectral_config params[SPECTRAL_SCAN_MODE_MAX];
1360  	bool params_valid[SPECTRAL_SCAN_MODE_MAX];
1361  	struct spectral_classifier_params       classifier_params;
1362  	int                                     last_capture_time;
1363  	int                                     num_spectral_data;
1364  	int                                     total_spectral_data;
1365  	int                                     max_rssi;
1366  	int                                     detects_control_channel;
1367  	int                                     detects_extension_channel;
1368  	int                                     detects_below_dc;
1369  	int                                     detects_above_dc;
1370  	int                                     sc_scanning;
1371  	int                                     sc_spectral_scan;
1372  	int                                     sc_spectral_full_scan;
1373  	uint64_t                               scan_start_tstamp;
1374  	uint32_t                               last_tstamp;
1375  	uint32_t                               first_tstamp;
1376  	uint32_t                               spectral_samp_count;
1377  	uint32_t                               sc_spectral_samp_count;
1378  	int                                     noise_pwr_reports_reqd;
1379  	int                                     noise_pwr_reports_recv;
1380  	qdf_spinlock_t                          noise_pwr_reports_lock;
1381  	struct target_if_chain_noise_pwr_info
1382  		*noise_pwr_chain_ctl[HOST_MAX_ANTENNA];
1383  	struct target_if_chain_noise_pwr_info
1384  		*noise_pwr_chain_ext[HOST_MAX_ANTENNA];
1385  	uint64_t                               tsf64;
1386  #if ATH_PERF_PWR_OFFLOAD
1387  	struct target_if_spectral_param_state_info
1388  					param_info[SPECTRAL_SCAN_MODE_MAX];
1389  #endif
1390  	enum phy_ch_width ch_width[SPECTRAL_SCAN_MODE_MAX];
1391  	bool sscan_width_configured[SPECTRAL_SCAN_MODE_MAX];
1392  	struct spectral_diag_stats              diag_stats;
1393  	bool                                    is_160_format;
1394  	bool                                    is_lb_edge_extrabins_format;
1395  	bool                                    is_rb_edge_extrabins_format;
1396  	bool                                    is_sec80_rssi_war_required;
1397  #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION
1398  	void                                    *simctx;
1399  #endif
1400  	enum spectral_gen                       spectral_gen;
1401  	uint8_t                                hdr_sig_exp;
1402  	uint8_t                                tag_sscan_summary_exp;
1403  	uint8_t                                tag_sscan_fft_exp;
1404  	uint8_t                                tlvhdr_size;
1405  	struct spectral_nl_cb nl_cb;
1406  	bool use_nl_bcast;
1407  	int (*send_phy_data)(struct wlan_objmgr_pdev *pdev,
1408  			     enum spectral_msg_type smsg_type);
1409  	struct spectral_fft_bin_len_adj_swar len_adj_swar;
1410  	struct spectral_timestamp_war timestamp_war;
1411  	enum spectral_160mhz_report_delivery_state
1412  			state_160mhz_delivery[SPECTRAL_SCAN_MODE_MAX];
1413  	bool dbr_ring_debug;
1414  	bool dbr_buff_debug;
1415  	bool direct_dma_support;
1416  #ifdef OPTIMIZED_SAMP_MESSAGE
1417  	uint32_t prev_tstamp[MAX_DETECTORS_PER_PDEV];
1418  #else
1419  	uint32_t prev_tstamp;
1420  #endif
1421  	struct spectral_report_params rparams;
1422  	struct spectral_param_min_max param_min_max;
1423  	struct target_if_finite_spectral_scan_params
1424  					finite_scan[SPECTRAL_SCAN_MODE_MAX];
1425  	struct sscan_detector_list
1426  			detector_list[SPECTRAL_SCAN_MODE_MAX][CH_WIDTH_MAX];
1427  	qdf_spinlock_t detector_list_lock;
1428  	struct per_session_det_map det_map[MAX_DETECTORS_PER_PDEV];
1429  	qdf_spinlock_t session_det_map_lock;
1430  	struct per_session_report_info report_info[SPECTRAL_SCAN_MODE_MAX];
1431  	qdf_spinlock_t session_report_info_lock;
1432  	struct spectral_supported_bws
1433  		supported_bws[SPECTRAL_SCAN_MODE_MAX][CH_WIDTH_MAX];
1434  	/* Whether a given sscan BW is supported on a given smode */
1435  	bool supported_sscan_bw_list[SPECTRAL_SCAN_MODE_MAX][CH_WIDTH_MAX];
1436  	struct spectral_data_stats data_stats;
1437  };
1438  
1439  /**
1440   * struct target_if_psoc_spectral - Target if psoc Spectral object
1441   * @psoc_obj:  psoc object
1442   * @wmi_ops:  Spectral WMI operations
1443   */
1444  struct target_if_psoc_spectral {
1445  	struct wlan_objmgr_psoc *psoc_obj;
1446  	struct spectral_wmi_ops wmi_ops;
1447  };
1448  
1449  #ifdef OPTIMIZED_SAMP_MESSAGE
1450  /**
1451   * struct target_if_samp_msg_params - Spectral Analysis Messaging Protocol
1452   * data format
1453   * @hw_detector_id: Spectral HW detector ID
1454   * @rssi: Spectral RSSI
1455   * @lower_rssi: RSSI of lower band
1456   * @upper_rssi: RSSI of upper band
1457   * @chain_ctl_rssi: RSSI for control channel, for all antennas
1458   * @chain_ext_rssi: RSSI for extension channel, for all antennas
1459   * @last_raw_timestamp: Previous FFT report's raw timestamp.
1460   * @raw_timestamp: FFT timestamp reported by HW on primary segment.
1461   * @timestamp: timestamp
1462   * @reset_delay: Time gap between the last spectral report before reset and the
1463   *               end of reset.
1464   * @max_mag: maximum magnitude
1465   * @max_index: index of max magnitude
1466   * @noise_floor: current noise floor
1467   * @agc_total_gain: AGC total gain on primary channel
1468   * @gainchange: Indicates a gainchange occurred during the spectral scan
1469   * @pri80ind: Indication from hardware that the sample was received on the
1470   *            primary 80 MHz segment. If this is set when smode =
1471   *            SPECTRAL_SCAN_MODE_AGILE, it indicates that Spectral was carried
1472   *            out on pri80 instead of the Agile frequency due to a channel
1473   *            switch - Software may choose to ignore the sample in this case.
1474   * @blanking_status: Indicates whether scan blanking was enabled during this
1475   * spectral report capture.
1476   * @bin_pwr_data: Contains FFT magnitudes
1477   */
1478  struct target_if_samp_msg_params {
1479  	uint8_t hw_detector_id;
1480  	int8_t rssi;
1481  	int8_t lower_rssi;
1482  	int8_t upper_rssi;
1483  	int8_t chain_ctl_rssi[HOST_MAX_ANTENNA];
1484  	int8_t chain_ext_rssi[HOST_MAX_ANTENNA];
1485  	uint32_t last_raw_timestamp;
1486  	uint32_t raw_timestamp;
1487  	uint32_t timestamp;
1488  	uint32_t reset_delay;
1489  	uint16_t max_mag;
1490  	uint16_t max_index;
1491  	int16_t noise_floor;
1492  	uint8_t agc_total_gain;
1493  	uint8_t gainchange;
1494  	uint8_t pri80ind;
1495  	uint8_t blanking_status;
1496  	uint8_t *bin_pwr_data;
1497  };
1498  
1499  #else
1500  /**
1501   * struct target_if_samp_msg_params - Spectral Analysis Messaging Protocol
1502   * data format
1503   * @rssi:  RSSI (except for secondary 80 segment)
1504   * @rssi_sec80:  RSSI for secondary 80 segment
1505   * @lower_rssi:  RSSI of lower band
1506   * @upper_rssi:  RSSI of upper band
1507   * @chain_ctl_rssi: RSSI for control channel, for all antennas
1508   * @chain_ext_rssi: RSSI for extension channel, for all antennas
1509   * @bwinfo:  bandwidth info
1510   * @datalen:  length of FFT data (except for secondary 80 segment)
1511   * @datalen_sec80:  length of FFT data for secondary 80 segment
1512   * @tstamp:  timestamp
1513   * @last_tstamp:  last time stamp
1514   * @max_mag:  maximum magnitude (except for secondary 80 segment)
1515   * @max_mag_sec80:  maximum magnitude for secondary 80 segment
1516   * @max_index:  index of max magnitude (except for secondary 80 segment)
1517   * @max_index_sec80:  index of max magnitude for secondary 80 segment
1518   * @max_exp:  max exp
1519   * @peak: peak frequency (obsolete)
1520   * @pwr_count:  number of FFT bins (except for secondary 80 segment)
1521   * @pwr_count_5mhz:  number of FFT bins in extra 5 MHz in
1522   *                   165 MHz/restricted 80p80 mode
1523   * @pwr_count_sec80:  number of FFT bins in secondary 80 segment
1524   * @nb_lower: This is deprecated
1525   * @nb_upper: This is deprecated
1526   * @max_upper_index:  index of max mag in upper band
1527   * @max_lower_index:  index of max mag in lower band
1528   * @bin_pwr_data: Contains FFT magnitudes (except for secondary 80 segment)
1529   * @bin_pwr_data_5mhz: Contains FFT magnitudes for the extra 5 MHz
1530   *                     in 165 MHz/restricted 80p80 mode
1531   * @bin_pwr_data_sec80: Contains FFT magnitudes for the secondary 80 segment
1532   * @freq: Center frequency of primary 20MHz channel in MHz
1533   * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz
1534   * @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz
1535   * @agile_freq1:        Center frequency in MHz of the entire span(for 80+80 MHz
1536   *                      agile Scan it is primary 80 MHz span) across which
1537   *                      Agile Spectral is carried out. Applicable only for Agile
1538   *                      Spectral samples.
1539   * @agile_freq2:        Center frequency in MHz of the secondary 80 MHz span
1540   *                      across which Agile Spectral is carried out. Applicable
1541   *                      only for Agile Spectral samples in 80+80 MHz mode.
1542   * @freq_loading: spectral control duty cycles
1543   * @noise_floor:  current noise floor (except for secondary 80 segment)
1544   * @noise_floor_sec80:  current noise floor for secondary 80 segment
1545   * @interf_list: List of interference sources
1546   * @classifier_params:  classifier parameters
1547   * @sc:  classifier parameters
1548   * @agc_total_gain: AGC total gain on primary channel
1549   * @agc_total_gain_sec80: AGC total gain on secondary channel
1550   * @gainchange: Indicates a gainchange occurred during the spectral scan
1551   * @gainchange_sec80: Indicates a gainchange occurred in the secondary
1552   * channel during the spectral scan
1553   * @smode: spectral scan mode
1554   * @pri80ind: Indication from hardware that the sample was received on the
1555   * primary 80 MHz segment. If this is set when smode =
1556   * SPECTRAL_SCAN_MODE_AGILE, it indicates that Spectral was carried out on
1557   * pri80 instead of the Agile frequency due to a channel switch - Software may
1558   * choose to ignore the sample in this case.
1559   * @pri80ind_sec80: Indication from hardware that the sample was received on the
1560   * primary 80 MHz segment instead of the secondary 80 MHz segment due to a
1561   * channel switch - Software may choose to ignore the sample if this is set.
1562   * Applicable only if smode = SPECTRAL_SCAN_MODE_NORMAL and for 160/80+80 MHz
1563   * Spectral operation and if the chipset supports fragmented 160/80+80 MHz
1564   * operation.
1565   * @last_raw_timestamp: Previous FFT report's raw timestamp. In case of 160MHz
1566   * it will be primary 80 segment's timestamp as both primary & secondary
1567   * segment's timestamps are expected to be almost equal
1568   * @timestamp_war_offset: Offset calculated based on reset_delay and
1569   * last_raw_stamp. It will be added to raw_timestamp to get tstamp.
1570   * @raw_timestamp: FFT timestamp reported by HW on primary segment.
1571   * @raw_timestamp_sec80: FFT timestamp reported by HW on secondary 80 segment.
1572   * @reset_delay: Time gap between the last spectral report before reset and the
1573   * end of reset.
1574   * @target_reset_count: Indicates the the number of times the target went
1575   * through reset routine after spectral was enabled.
1576   */
1577  struct target_if_samp_msg_params {
1578  	int8_t      rssi;
1579  	int8_t      rssi_sec80;
1580  	int8_t      lower_rssi;
1581  	int8_t      upper_rssi;
1582  	int8_t      chain_ctl_rssi[HOST_MAX_ANTENNA];
1583  	int8_t      chain_ext_rssi[HOST_MAX_ANTENNA];
1584  	uint16_t    bwinfo;
1585  	uint16_t    datalen;
1586  	uint16_t    datalen_sec80;
1587  	uint32_t    tstamp;
1588  	uint32_t    last_tstamp;
1589  	uint16_t    max_mag;
1590  	uint16_t    max_mag_sec80;
1591  	uint16_t    max_index;
1592  	uint16_t    max_index_sec80;
1593  	uint8_t     max_exp;
1594  	int         peak;
1595  	int         pwr_count;
1596  	int         pwr_count_5mhz;
1597  	int         pwr_count_sec80;
1598  	int8_t      nb_lower;
1599  	int8_t      nb_upper;
1600  	uint16_t    max_lower_index;
1601  	uint16_t    max_upper_index;
1602  	uint8_t    *bin_pwr_data;
1603  	uint8_t    *bin_pwr_data_5mhz;
1604  	uint8_t    *bin_pwr_data_sec80;
1605  	uint16_t   freq;
1606  	uint16_t   vhtop_ch_freq_seg1;
1607  	uint16_t   vhtop_ch_freq_seg2;
1608  	uint16_t   agile_freq1;
1609  	uint16_t   agile_freq2;
1610  	uint16_t   freq_loading;
1611  	int16_t     noise_floor;
1612  	int16_t     noise_floor_sec80;
1613  	struct interf_src_rsp interf_list;
1614  	struct spectral_classifier_params classifier_params;
1615  	struct ath_softc *sc;
1616  	uint8_t agc_total_gain;
1617  	uint8_t agc_total_gain_sec80;
1618  	uint8_t gainchange;
1619  	uint8_t gainchange_sec80;
1620  	enum spectral_scan_mode smode;
1621  	uint8_t pri80ind;
1622  	uint8_t pri80ind_sec80;
1623  	uint32_t last_raw_timestamp;
1624  	uint32_t timestamp_war_offset;
1625  	uint32_t raw_timestamp;
1626  	uint32_t raw_timestamp_sec80;
1627  	uint32_t reset_delay;
1628  	uint32_t target_reset_count;
1629  };
1630  #endif
1631  
1632  /**
1633   * struct target_if_spectral_agile_mode_cap - Structure to hold agile
1634   * Spetcral scan capability
1635   * @agile_spectral_cap: agile Spectral scan capability for 20/40/80 MHz
1636   * @agile_spectral_cap_160: agile Spectral scan capability for 160 MHz
1637   * @agile_spectral_cap_80p80: agile Spectral scan capability for 80+80 MHz
1638   * @agile_spectral_cap_320: agile Spectral scan capability for 320 MHz
1639   */
1640  struct target_if_spectral_agile_mode_cap {
1641  	bool agile_spectral_cap;
1642  	bool agile_spectral_cap_160;
1643  	bool agile_spectral_cap_80p80;
1644  	bool agile_spectral_cap_320;
1645  };
1646  
1647  #ifdef WLAN_CONV_SPECTRAL_ENABLE
1648  /**
1649   * target_if_spectral_dump_fft() - Dump Spectral FFT
1650   * @pfft: Pointer to Spectral Phyerr FFT
1651   * @fftlen: FFT length
1652   *
1653   * Return: Success or failure
1654   */
1655  int target_if_spectral_dump_fft(uint8_t *pfft, int fftlen);
1656  
1657  /**
1658   * target_if_dbg_print_samp_param() - Print contents of SAMP struct
1659   * @p: Pointer to SAMP message
1660   *
1661   * Return: Void
1662   */
1663  void target_if_dbg_print_samp_param(struct target_if_samp_msg_params *p);
1664  
1665  /**
1666   * target_if_get_offset_swar_sec80() - Get offset for SWAR according to
1667   *                                     the channel width
1668   * @channel_width: Channel width
1669   *
1670   * Return: Offset for SWAR
1671   */
1672  uint32_t target_if_get_offset_swar_sec80(uint32_t channel_width);
1673  
1674  /**
1675   * target_if_sptrl_register_tx_ops() - Register Spectral target_if Tx Ops
1676   * @tx_ops: Tx Ops
1677   *
1678   * Return: void
1679   */
1680  void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
1681  
1682  #ifndef OPTIMIZED_SAMP_MESSAGE
1683  /**
1684   * target_if_spectral_create_samp_msg() - Create the spectral samp message
1685   * @spectral : Pointer to spectral internal structure
1686   * @params : spectral samp message parameters
1687   *
1688   * API to create the spectral samp message
1689   *
1690   * Return: void
1691   */
1692  void target_if_spectral_create_samp_msg(
1693  	struct target_if_spectral *spectral,
1694  	struct target_if_samp_msg_params *params);
1695  #endif
1696  
1697  #ifdef OPTIMIZED_SAMP_MESSAGE
1698  /**
1699   * target_if_spectral_fill_samp_msg() - Fill the Spectral SAMP message
1700   * @spectral : Pointer to spectral internal structure
1701   * @params: Spectral SAMP message fields
1702   *
1703   * Fill the spectral SAMP message fields using params and detector map.
1704   *
1705   * Return: Success/Failure
1706   */
1707  QDF_STATUS target_if_spectral_fill_samp_msg(
1708  			struct target_if_spectral *spectral,
1709  			struct target_if_samp_msg_params *params);
1710  #endif
1711  
1712  /**
1713   * target_if_spectral_process_report_gen3() - Process spectral report for gen3
1714   * @pdev:    Pointer to pdev object
1715   * @buf: Pointer to spectral report
1716   *
1717   * Process phyerror event for gen3
1718   *
1719   * Return: Success/Failure
1720   */
1721  int target_if_spectral_process_report_gen3(struct wlan_objmgr_pdev *pdev,
1722  					   void *buf);
1723  
1724  /**
1725   * target_if_process_phyerr_gen2() - Process PHY Error for gen2
1726   * @spectral: Pointer to Spectral object
1727   * @data: Pointer to phyerror event buffer
1728   * @datalen: Data length
1729   * @p_rfqual: RF quality info
1730   * @p_chaninfo: Channel info
1731   * @tsf64: 64 bit tsf timestamp
1732   * @acs_stats: ACS stats
1733   *
1734   * Process PHY Error for gen2
1735   *
1736   * Return: Success/Failure
1737   */
1738  int target_if_process_phyerr_gen2(
1739  	struct target_if_spectral *spectral,
1740  	uint8_t *data,
1741  	uint32_t datalen, struct target_if_spectral_rfqual_info *p_rfqual,
1742  	struct target_if_spectral_chan_info *p_chaninfo,
1743  	uint64_t tsf64,
1744  	struct target_if_spectral_acs_stats *acs_stats);
1745  
1746  /**
1747   * target_if_spectral_send_intf_found_msg() - Indicate to application layer that
1748   * interference has been found
1749   * @pdev: Pointer to pdev
1750   * @cw_int: 1 if CW interference is found, 0 if WLAN interference is found
1751   * @dcs_enabled: 1 if DCS is enabled, 0 if DCS is disabled
1752   *
1753   * Send message to application layer
1754   * indicating that interference has been found
1755   *
1756   * Return: None
1757   */
1758  void target_if_spectral_send_intf_found_msg(
1759  	struct wlan_objmgr_pdev *pdev,
1760  	uint16_t cw_int, uint32_t dcs_enabled);
1761  
1762  /**
1763   * target_if_stop_spectral_scan() - Stop spectral scan
1764   * @pdev: Pointer to pdev object
1765   * @smode: Spectral scan mode
1766   * @err: Pointer to error code
1767   *
1768   * API to stop the current on-going spectral scan
1769   *
1770   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
1771   */
1772  QDF_STATUS target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev,
1773  					const enum spectral_scan_mode smode,
1774  					enum spectral_cp_error_code *err);
1775  
1776  /**
1777   * target_if_spectral_get_vdev() - Get pointer to vdev to be used for Spectral
1778   * operations
1779   * @spectral: Pointer to Spectral target_if internal private data
1780   * @smode: spectral scan mode
1781   *
1782   * Spectral operates on pdev. However, in order to retrieve some WLAN
1783   * properties, a vdev is required. To facilitate this, the function returns the
1784   * first vdev in our pdev. The caller should release the reference to the vdev
1785   * once it is done using it.
1786   * TODO: If the framework later provides an API to obtain the first active
1787   * vdev, then it would be preferable to use this API.
1788   *
1789   * Return: Pointer to vdev on success, NULL on failure
1790   */
1791  struct wlan_objmgr_vdev *target_if_spectral_get_vdev(
1792  	struct target_if_spectral *spectral,
1793  	enum spectral_scan_mode smode);
1794  
1795  /**
1796   * target_if_spectral_dump_hdr_gen2() - Dump Spectral header for gen2
1797   * @phdr: Pointer to Spectral Phyerr Header
1798   *
1799   * Dump Spectral header
1800   *
1801   * Return: Success/Failure
1802   */
1803  int target_if_spectral_dump_hdr_gen2(struct spectral_phyerr_hdr_gen2 *phdr);
1804  
1805  /**
1806   * target_if_get_combrssi_sec80_seg_gen2() - Get approximate combined RSSI
1807   *                                           for Secondary 80 segment
1808   * @spectral: Pointer to spectral object
1809   * @p_sfft_sec80: Pointer to search fft info of secondary 80 segment
1810   *
1811   * Get approximate combined RSSI for Secondary 80 segment
1812   *
1813   * Return: Combined RSSI for secondary 80Mhz segment
1814   */
1815  int8_t target_if_get_combrssi_sec80_seg_gen2(
1816  	struct target_if_spectral *spectral,
1817  	struct spectral_search_fft_info_gen2 *p_sfft_sec80);
1818  
1819  /**
1820   * target_if_spectral_dump_tlv_gen2() - Dump Spectral TLV for gen2
1821   * @ptlv: Pointer to Spectral Phyerr TLV
1822   * @is_160_format: Indicates 160 format
1823   *
1824   * Dump Spectral TLV for gen2
1825   *
1826   * Return: Success/Failure
1827   */
1828  int target_if_spectral_dump_tlv_gen2(
1829  	struct spectral_phyerr_tlv_gen2 *ptlv, bool is_160_format);
1830  
1831  /**
1832   * target_if_spectral_dump_phyerr_data_gen2() - Dump Spectral
1833   * related PHY Error for gen2
1834   * @data: Pointer to phyerror buffer
1835   * @datalen: Data length
1836   * @is_160_format: Indicates 160 format
1837   *
1838   * Dump Spectral related PHY Error for gen2
1839   *
1840   * Return: Success/Failure
1841   */
1842  int target_if_spectral_dump_phyerr_data_gen2(
1843  	uint8_t *data,
1844  	uint32_t datalen,
1845  	bool is_160_format);
1846  
1847  /**
1848   * target_if_dbg_print_samp_msg() - Print contents of SAMP Message
1849   * @pmsg: Pointer to SAMP message
1850   *
1851   * Print contents of SAMP Message
1852   *
1853   * Return: Void
1854   */
1855  void target_if_dbg_print_samp_msg(struct spectral_samp_msg *pmsg);
1856  
1857  /**
1858   * get_target_if_spectral_handle_from_pdev() - Get handle to target_if internal
1859   * Spectral data
1860   * @pdev: Pointer to pdev
1861   *
1862   * Return: Handle to target_if internal Spectral data on success, NULL on
1863   * failure
1864   */
1865  struct target_if_spectral *get_target_if_spectral_handle_from_pdev(
1866  	struct wlan_objmgr_pdev *pdev);
1867  
1868  /**
1869   * get_target_if_spectral_handle_from_psoc() - Get handle to psoc target_if
1870   * internal Spectral data
1871   * @psoc: Pointer to psoc
1872   *
1873   * Return: Handle to target_if psoc internal Spectral data on success, NULL on
1874   * failure
1875   */
1876  static inline
get_target_if_spectral_handle_from_psoc(struct wlan_objmgr_psoc * psoc)1877  struct target_if_psoc_spectral *get_target_if_spectral_handle_from_psoc(
1878  	struct wlan_objmgr_psoc *psoc)
1879  {
1880  	struct wlan_lmac_if_rx_ops *rx_ops;
1881  	struct target_if_psoc_spectral *psoc_spectral;
1882  
1883  	if (!psoc) {
1884  		spectral_err("psoc is null");
1885  		return NULL;
1886  	}
1887  
1888  	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1889  	if (!rx_ops) {
1890  		spectral_err("rx_ops is null");
1891  		return NULL;
1892  	}
1893  
1894  	psoc_spectral = (struct target_if_psoc_spectral *)
1895  		rx_ops->sptrl_rx_ops.sptrlro_get_psoc_target_handle(psoc);
1896  
1897  	return psoc_spectral;
1898  }
1899  
1900  /**
1901   * target_if_vdev_get_chan_freq() - Get vdev operating channel frequency
1902   * @vdev: Pointer to vdev
1903   *
1904   * Get the operating channel frequency of a given vdev
1905   *
1906   * Return: Operating channel frequency of a vdev in MHz
1907   */
1908  static inline
target_if_vdev_get_chan_freq(struct wlan_objmgr_vdev * vdev)1909  int16_t target_if_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev)
1910  {
1911  	struct wlan_objmgr_psoc *psoc = NULL;
1912  	struct wlan_lmac_if_rx_ops *rx_ops;
1913  
1914  	psoc = wlan_vdev_get_psoc(vdev);
1915  	if (!psoc) {
1916  		spectral_err("psoc is NULL");
1917  		return -EINVAL;
1918  	}
1919  	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1920  	if (!rx_ops) {
1921  		spectral_err("rx_ops is null");
1922  		return -EINVAL;
1923  	}
1924  
1925  	return rx_ops->sptrl_rx_ops.sptrlro_vdev_get_chan_freq(
1926  		vdev);
1927  }
1928  
1929  /**
1930   * target_if_vdev_get_chan_freq_seg2() - Get center frequency of secondary 80 of
1931   * given vdev
1932   * @vdev: Pointer to vdev
1933   *
1934   * Get the center frequency of secondary 80 of given vdev
1935   *
1936   * Return: center frequency of secondary 80
1937   */
1938  static inline
target_if_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev * vdev)1939  int16_t target_if_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev)
1940  {
1941  	struct wlan_objmgr_psoc *psoc = NULL;
1942  	struct wlan_lmac_if_rx_ops *rx_ops;
1943  
1944  	psoc = wlan_vdev_get_psoc(vdev);
1945  	if (!psoc) {
1946  		spectral_err("psoc is NULL");
1947  		return -EINVAL;
1948  	}
1949  
1950  	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1951  	if (!rx_ops) {
1952  		spectral_err("rx_ops is null");
1953  		return -EINVAL;
1954  	}
1955  
1956  	return rx_ops->sptrl_rx_ops.sptrlro_vdev_get_chan_freq_seg2(vdev);
1957  }
1958  
1959  /**
1960   * target_if_vdev_get_ch_width() - Get vdev operating channel bandwidth
1961   * @vdev: Pointer to vdev
1962   *
1963   * Get the operating channel bandwidth of a given vdev
1964   *
1965   * Return: channel bandwidth enumeration corresponding to the vdev
1966   */
1967  static inline
target_if_vdev_get_ch_width(struct wlan_objmgr_vdev * vdev)1968  enum phy_ch_width target_if_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev)
1969  {
1970  	struct wlan_objmgr_psoc *psoc = NULL;
1971  	enum phy_ch_width ch_width;
1972  	struct wlan_lmac_if_rx_ops *rx_ops;
1973  
1974  	psoc = wlan_vdev_get_psoc(vdev);
1975  	if (!psoc) {
1976  		spectral_err("psoc is NULL");
1977  		return CH_WIDTH_INVALID;
1978  	}
1979  
1980  	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1981  	if (!rx_ops) {
1982  		spectral_err("rx_ops is null");
1983  		return CH_WIDTH_INVALID;
1984  	}
1985  
1986  	ch_width = rx_ops->sptrl_rx_ops.sptrlro_vdev_get_ch_width(vdev);
1987  
1988  	if (ch_width == CH_WIDTH_160MHZ) {
1989  		int16_t cfreq2;
1990  
1991  		cfreq2 = target_if_vdev_get_chan_freq_seg2(vdev);
1992  		if (cfreq2 < 0) {
1993  			spectral_err("Invalid value for cfreq2 %d", cfreq2);
1994  			return CH_WIDTH_INVALID;
1995  		}
1996  
1997  		/* Use non zero cfreq2 to identify 80p80 */
1998  		if (cfreq2)
1999  			ch_width = CH_WIDTH_80P80MHZ;
2000  	}
2001  
2002  	return ch_width;
2003  }
2004  
2005  /**
2006   * target_if_vdev_get_sec20chan_freq_mhz() - Get the frequency of secondary
2007   * 20 MHz channel for a given vdev
2008   * @vdev: Pointer to vdev
2009   * @sec20chan_freq: Location to return secondary 20 MHz channel
2010   *
2011   * Get the frequency of secondary 20 MHz channel for a given vdev
2012   *
2013   * Return: 0 if 20 MHz channel was returned, negative errno otherwise
2014   */
2015  static inline
target_if_vdev_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev * vdev,uint16_t * sec20chan_freq)2016  int target_if_vdev_get_sec20chan_freq_mhz(
2017  	struct wlan_objmgr_vdev *vdev,
2018  	uint16_t *sec20chan_freq)
2019  {
2020  	struct wlan_objmgr_psoc *psoc = NULL;
2021  	struct wlan_lmac_if_rx_ops *rx_ops;
2022  
2023  	psoc = wlan_vdev_get_psoc(vdev);
2024  	if (!psoc) {
2025  		spectral_err("psoc is NULL");
2026  		return -EINVAL;
2027  	}
2028  
2029  	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
2030  	if (!rx_ops) {
2031  		spectral_err("rx_ops is null");
2032  		return -EINVAL;
2033  	}
2034  
2035  	return rx_ops->sptrl_rx_ops.
2036  		sptrlro_vdev_get_sec20chan_freq_mhz(vdev, sec20chan_freq);
2037  }
2038  
2039  /**
2040   * target_if_spectral_is_feature_disabled_psoc() - Check if Spectral feature is
2041   * disabled for a given psoc
2042   * @psoc: Pointer to psoc
2043   *
2044   * Return: true or false
2045   */
2046  static inline
target_if_spectral_is_feature_disabled_psoc(struct wlan_objmgr_psoc * psoc)2047  bool target_if_spectral_is_feature_disabled_psoc(struct wlan_objmgr_psoc *psoc)
2048  {
2049  	struct wlan_lmac_if_rx_ops *rx_ops;
2050  
2051  	if (!psoc) {
2052  		spectral_err("psoc is NULL");
2053  		return true;
2054  	}
2055  
2056  	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
2057  	if (!rx_ops) {
2058  		spectral_err("rx_ops is null");
2059  		return true;
2060  	}
2061  
2062  	if (rx_ops->sptrl_rx_ops.
2063  	    sptrlro_spectral_is_feature_disabled_psoc)
2064  		return rx_ops->sptrl_rx_ops.
2065  		       sptrlro_spectral_is_feature_disabled_psoc(psoc);
2066  
2067  	return true;
2068  }
2069  
2070  /**
2071   * target_if_spectral_is_feature_disabled_pdev() - Check if Spectral feature is
2072   * disabled for a given pdev
2073   * @pdev: Pointer to pdev
2074   *
2075   * Return: true or false
2076   */
2077  static inline
target_if_spectral_is_feature_disabled_pdev(struct wlan_objmgr_pdev * pdev)2078  bool target_if_spectral_is_feature_disabled_pdev(struct wlan_objmgr_pdev *pdev)
2079  {
2080  	struct wlan_lmac_if_rx_ops *rx_ops;
2081  	struct wlan_objmgr_psoc *psoc;
2082  
2083  	if (!pdev) {
2084  		spectral_err("pdev is NULL");
2085  		return true;
2086  	}
2087  
2088  	psoc = wlan_pdev_get_psoc(pdev);
2089  	if (!psoc) {
2090  		spectral_err("psoc is NULL");
2091  		return true;
2092  	}
2093  
2094  	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
2095  	if (!rx_ops) {
2096  		spectral_err("rx_ops is null");
2097  		return true;
2098  	}
2099  
2100  	if (rx_ops->sptrl_rx_ops.
2101  	    sptrlro_spectral_is_feature_disabled_pdev)
2102  		return rx_ops->sptrl_rx_ops.
2103  		       sptrlro_spectral_is_feature_disabled_pdev(pdev);
2104  
2105  	return true;
2106  }
2107  
2108  /**
2109   * target_if_spectral_set_rxchainmask() - Set Spectral Rx chainmask
2110   * @pdev: Pointer to pdev
2111   * @spectral_rx_chainmask: Spectral Rx chainmask
2112   *
2113   * Return: None
2114   */
2115  static inline
target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev * pdev,uint8_t spectral_rx_chainmask)2116  void target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev *pdev,
2117  					uint8_t spectral_rx_chainmask)
2118  {
2119  	struct wlan_objmgr_psoc *psoc = NULL;
2120  	struct target_if_spectral *spectral = NULL;
2121  	enum spectral_scan_mode smode = SPECTRAL_SCAN_MODE_NORMAL;
2122  	struct wlan_lmac_if_rx_ops *rx_ops;
2123  
2124  	psoc = wlan_pdev_get_psoc(pdev);
2125  	if (!psoc) {
2126  		spectral_err("psoc is NULL");
2127  		return;
2128  	}
2129  
2130  	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
2131  	if (!rx_ops) {
2132  		spectral_err("rx_ops is null");
2133  		return;
2134  	}
2135  
2136  	if (smode >= SPECTRAL_SCAN_MODE_MAX) {
2137  		spectral_err("Invalid Spectral mode %u", smode);
2138  		return;
2139  	}
2140  
2141  	if (rx_ops->sptrl_rx_ops.
2142  	    sptrlro_spectral_is_feature_disabled_pdev(pdev)) {
2143  		spectral_info("Spectral feature is disabled");
2144  		return;
2145  	}
2146  
2147  	spectral = get_target_if_spectral_handle_from_pdev(pdev);
2148  	if (!spectral) {
2149  		spectral_err("Spectral target if object is null");
2150  		return;
2151  	}
2152  
2153  	/* set chainmask for all the modes */
2154  	for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++)
2155  		spectral->params[smode].ss_chn_mask = spectral_rx_chainmask;
2156  }
2157  
2158  /**
2159   * target_if_spectral_process_phyerr() - Process Spectral PHY error
2160   * @pdev: Pointer to pdev
2161   * @data: PHY error data received from FW
2162   * @datalen: Length of data
2163   * @p_rfqual: Pointer to RF Quality information
2164   * @p_chaninfo: Pointer to channel information
2165   * @tsf64: TSF time instance at which the Spectral sample was received
2166   * @acs_stats: ACS stats
2167   *
2168   * Process Spectral PHY error by extracting necessary information from the data
2169   * sent by FW, and send the extracted information to application layer.
2170   *
2171   * Return: None
2172   */
2173  static inline
target_if_spectral_process_phyerr(struct wlan_objmgr_pdev * pdev,uint8_t * data,uint32_t datalen,struct target_if_spectral_rfqual_info * p_rfqual,struct target_if_spectral_chan_info * p_chaninfo,uint64_t tsf64,struct target_if_spectral_acs_stats * acs_stats)2174  void target_if_spectral_process_phyerr(
2175  	struct wlan_objmgr_pdev *pdev,
2176  	uint8_t *data, uint32_t datalen,
2177  	struct target_if_spectral_rfqual_info *p_rfqual,
2178  	struct target_if_spectral_chan_info *p_chaninfo,
2179  	uint64_t tsf64,
2180  	struct target_if_spectral_acs_stats *acs_stats)
2181  {
2182  	struct target_if_spectral *spectral = NULL;
2183  	struct target_if_spectral_ops *p_sops = NULL;
2184  
2185  	spectral = get_target_if_spectral_handle_from_pdev(pdev);
2186  	if (!spectral) {
2187  		spectral_err("Spectral target if object is null");
2188  		return;
2189  	}
2190  
2191  	p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral);
2192  	if (!p_sops->spectral_process_phyerr) {
2193  		spectral_err("null spectral_process_phyerr");
2194  		return;
2195  	}
2196  	p_sops->spectral_process_phyerr(spectral, data, datalen,
2197  					p_rfqual, p_chaninfo,
2198  					tsf64, acs_stats);
2199  }
2200  
2201  static QDF_STATUS
target_if_get_spectral_msg_type(enum spectral_scan_mode smode,enum spectral_msg_type * msg_type)2202  target_if_get_spectral_msg_type(enum spectral_scan_mode smode,
2203  				enum spectral_msg_type *msg_type) {
2204  
2205  	switch (smode) {
2206  	case SPECTRAL_SCAN_MODE_NORMAL:
2207  		*msg_type = SPECTRAL_MSG_NORMAL_MODE;
2208  		break;
2209  
2210  	case SPECTRAL_SCAN_MODE_AGILE:
2211  		*msg_type = SPECTRAL_MSG_AGILE_MODE;
2212  		break;
2213  
2214  	default:
2215  		spectral_err("Invalid spectral mode");
2216  		return QDF_STATUS_E_FAILURE;
2217  	}
2218  
2219  	return QDF_STATUS_SUCCESS;
2220  }
2221  
2222  static inline bool
is_ch_width_160_or_80p80(enum phy_ch_width ch_width)2223  is_ch_width_160_or_80p80(enum phy_ch_width ch_width)
2224  {
2225  	return (ch_width == CH_WIDTH_160MHZ || ch_width == CH_WIDTH_80P80MHZ);
2226  }
2227  
2228  /**
2229   * free_samp_msg_skb() - Free SAMP message skb
2230   * @spectral: Pointer to Spectral
2231   * @smode: Spectral Scan mode
2232   *
2233   * Free SAMP message skb, if error in report processing
2234   *
2235   * Return: void
2236   */
2237  static inline void
free_samp_msg_skb(struct target_if_spectral * spectral,enum spectral_scan_mode smode)2238  free_samp_msg_skb(struct target_if_spectral *spectral,
2239  		  enum spectral_scan_mode smode)
2240  {
2241  	enum spectral_msg_type smsg_type;
2242  	QDF_STATUS ret;
2243  
2244  	if (smode >= SPECTRAL_SCAN_MODE_MAX) {
2245  		spectral_err_rl("Invalid Spectral mode %d", smode);
2246  		return;
2247  	}
2248  
2249  	if (is_ch_width_160_or_80p80(spectral->ch_width[smode])) {
2250  		ret = target_if_get_spectral_msg_type(smode, &smsg_type);
2251  		if (QDF_IS_STATUS_ERROR(ret)) {
2252  			spectral_err("Failed to get spectral message type");
2253  			return;
2254  		}
2255  		spectral->nl_cb.free_sbuff(spectral->pdev_obj,
2256  					   smsg_type);
2257  	}
2258  }
2259  
2260  /**
2261   * init_160mhz_delivery_state_machine() - Initialize 160MHz Spectral
2262   *                                        state machine
2263   * @spectral: Pointer to Spectral
2264   *
2265   * Initialize 160MHz Spectral state machine
2266   *
2267   * Return: void
2268   */
2269  static inline void
init_160mhz_delivery_state_machine(struct target_if_spectral * spectral)2270  init_160mhz_delivery_state_machine(struct target_if_spectral *spectral)
2271  {
2272  	uint8_t smode;
2273  
2274  	smode = 0;
2275  	for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++)
2276  		spectral->state_160mhz_delivery[smode] =
2277  				SPECTRAL_REPORT_WAIT_PRIMARY80;
2278  }
2279  
2280  /**
2281   * reset_160mhz_delivery_state_machine() - Reset 160MHz Spectral state machine
2282   * @spectral: Pointer to Spectral
2283   * @smode: Spectral scan mode
2284   *
2285   * Reset 160MHz Spectral state machine
2286   *
2287   * Return: void
2288   */
2289  static inline void
reset_160mhz_delivery_state_machine(struct target_if_spectral * spectral,enum spectral_scan_mode smode)2290  reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral,
2291  				    enum spectral_scan_mode smode)
2292  {
2293  	if (smode >= SPECTRAL_SCAN_MODE_MAX) {
2294  		spectral_err_rl("Invalid Spectral mode %d", smode);
2295  		return;
2296  	}
2297  
2298  	free_samp_msg_skb(spectral, smode);
2299  
2300  	if (is_ch_width_160_or_80p80(spectral->ch_width[smode])) {
2301  		spectral->state_160mhz_delivery[smode] =
2302  			SPECTRAL_REPORT_WAIT_PRIMARY80;
2303  	}
2304  }
2305  
2306  /**
2307   * is_secondaryseg_expected() - Is waiting for secondary 80 report
2308   * @spectral: Pointer to Spectral
2309   * @smode: Spectral scan mode
2310   *
2311   * Return true if secondary 80 report expected and mode is 160 MHz
2312   *
2313   * Return: true or false
2314   */
2315  static inline
is_secondaryseg_expected(struct target_if_spectral * spectral,enum spectral_scan_mode smode)2316  bool is_secondaryseg_expected(struct target_if_spectral *spectral,
2317  			      enum spectral_scan_mode smode)
2318  {
2319  	return
2320  	(is_ch_width_160_or_80p80(spectral->ch_width[smode]) &&
2321  	 spectral->rparams.fragmentation_160[smode] &&
2322  	 (spectral->state_160mhz_delivery[smode] ==
2323  	  SPECTRAL_REPORT_WAIT_SECONDARY80));
2324  }
2325  
2326  /**
2327   * is_primaryseg_expected() - Is waiting for primary 80 report
2328   * @spectral: Pointer to Spectral
2329   * @smode: Spectral scan mode
2330   *
2331   * Return true if mode is 160 Mhz and primary 80 report expected or
2332   * mode is not 160 Mhz
2333   *
2334   * Return: true or false
2335   */
2336  static inline
is_primaryseg_expected(struct target_if_spectral * spectral,enum spectral_scan_mode smode)2337  bool is_primaryseg_expected(struct target_if_spectral *spectral,
2338  			    enum spectral_scan_mode smode)
2339  {
2340  	return
2341  	(!is_ch_width_160_or_80p80(spectral->ch_width[smode]) ||
2342  	 !spectral->rparams.fragmentation_160[smode] ||
2343  	 (spectral->state_160mhz_delivery[smode] ==
2344  	  SPECTRAL_REPORT_WAIT_PRIMARY80));
2345  }
2346  
2347  #ifndef OPTIMIZED_SAMP_MESSAGE
2348  /**
2349   * is_primaryseg_rx_inprog() - Is primary 80 report processing is in progress
2350   * @spectral: Pointer to Spectral
2351   * @smode: Spectral scan mode
2352   *
2353   * Is primary 80 report processing is in progress
2354   *
2355   * Return: true or false
2356   */
2357  static inline
is_primaryseg_rx_inprog(struct target_if_spectral * spectral,enum spectral_scan_mode smode)2358  bool is_primaryseg_rx_inprog(struct target_if_spectral *spectral,
2359  			     enum spectral_scan_mode smode)
2360  {
2361  	return
2362  	(!is_ch_width_160_or_80p80(spectral->ch_width[smode]) ||
2363  	 spectral->spectral_gen == SPECTRAL_GEN2 ||
2364  	 (spectral->spectral_gen == SPECTRAL_GEN3 &&
2365  	  (!spectral->rparams.fragmentation_160[smode] ||
2366  	   spectral->state_160mhz_delivery[smode] ==
2367  	   SPECTRAL_REPORT_RX_PRIMARY80)));
2368  }
2369  
2370  /**
2371   * is_secondaryseg_rx_inprog() - Is secondary80 report processing is in progress
2372   * @spectral: Pointer to Spectral
2373   * @smode: Spectral scan mode
2374   *
2375   * Is secondary 80 report processing is in progress
2376   *
2377   * Return: true or false
2378   */
2379  static inline
is_secondaryseg_rx_inprog(struct target_if_spectral * spectral,enum spectral_scan_mode smode)2380  bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral,
2381  			       enum spectral_scan_mode smode)
2382  {
2383  	return
2384  	(is_ch_width_160_or_80p80(spectral->ch_width[smode]) &&
2385  	 (spectral->spectral_gen == SPECTRAL_GEN2 ||
2386  	  ((spectral->spectral_gen == SPECTRAL_GEN3) &&
2387  	   (!spectral->rparams.fragmentation_160[smode] ||
2388  	    spectral->state_160mhz_delivery[smode] ==
2389  	    SPECTRAL_REPORT_RX_SECONDARY80))));
2390  }
2391  #endif
2392  
2393  /**
2394   * clamp_fft_bin_value() - Clamp the FFT bin value between min and max
2395   * @fft_bin_value: FFT bin value as reported by HW
2396   * @pwr_format: FFT bin format (linear or dBm format)
2397   *
2398   * Each FFT bin value is represented as an 8 bit integer in SAMP message. But
2399   * depending on the configuration, the FFT bin value reported by HW might
2400   * exceed 8 bits. Clamp the FFT bin value between the min and max value
2401   * which can be represented by 8 bits. For linear mode, min and max FFT bin
2402   * value which can be represented by 8 bit is 0 and U8_MAX respectively. For
2403   * dBm mode,  min and max FFT bin value which can be represented by 8 bit is
2404   * S8_MIN and S8_MAX respectively.
2405   *
2406   * Return: Clamped FFT bin value
2407   */
2408  static inline uint8_t
clamp_fft_bin_value(uint16_t fft_bin_value,uint16_t pwr_format)2409  clamp_fft_bin_value(uint16_t fft_bin_value, uint16_t pwr_format)
2410  {
2411  	uint8_t clamped_fft_bin_value = 0;
2412  
2413  	switch (pwr_format) {
2414  	case SPECTRAL_PWR_FORMAT_LINEAR:
2415  		if (qdf_unlikely(fft_bin_value > MAX_FFTBIN_VALUE_LINEAR_MODE))
2416  			clamped_fft_bin_value = MAX_FFTBIN_VALUE_LINEAR_MODE;
2417  		else
2418  			clamped_fft_bin_value = fft_bin_value;
2419  		break;
2420  
2421  	case SPECTRAL_PWR_FORMAT_DBM:
2422  		if (qdf_unlikely((int16_t)fft_bin_value >
2423  		    MAX_FFTBIN_VALUE_DBM_MODE))
2424  			clamped_fft_bin_value = MAX_FFTBIN_VALUE_DBM_MODE;
2425  		else if (qdf_unlikely((int16_t)fft_bin_value <
2426  			 MIN_FFTBIN_VALUE_DBM_MODE))
2427  			clamped_fft_bin_value = MIN_FFTBIN_VALUE_DBM_MODE;
2428  		else
2429  			clamped_fft_bin_value = fft_bin_value;
2430  		break;
2431  
2432  	default:
2433  		spectral_err_rl("Invalid pwr format: %d.", pwr_format);
2434  		return 0;
2435  	}
2436  
2437  	return clamped_fft_bin_value;
2438  }
2439  
2440  /**
2441   * target_if_160mhz_delivery_state_change() - State transition for 160Mhz
2442   *                                            Spectral
2443   * @spectral: Pointer to spectral object
2444   * @smode: Spectral scan mode
2445   * @detector_id: Detector id
2446   *
2447   * Move the states of state machine for 160MHz spectral scan report receive
2448   *
2449   * Return: QDF_STATUS
2450   */
2451  QDF_STATUS
2452  target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral,
2453  				       enum spectral_scan_mode smode,
2454  				       uint8_t detector_id);
2455  
2456  /**
2457   * target_if_sops_is_spectral_enabled() - Get whether Spectral is enabled
2458   * @arg: Pointer to handle for Spectral target_if internal private data
2459   * @smode: Spectral scan mode
2460   *
2461   * Function to check whether Spectral is enabled
2462   *
2463   * Return: True if Spectral is enabled, false if Spectral is not enabled
2464   */
2465  uint32_t target_if_sops_is_spectral_enabled(void *arg,
2466  					    enum spectral_scan_mode smode);
2467  
2468  /**
2469   * target_if_sops_is_spectral_active() - Get whether Spectral is active
2470   * @arg: Pointer to handle for Spectral target_if internal private data
2471   * @smode: Spectral scan mode
2472   *
2473   * Function to check whether Spectral is active
2474   *
2475   * Return: True if Spectral is active, false if Spectral is not active
2476   */
2477  uint32_t target_if_sops_is_spectral_active(void *arg,
2478  					   enum spectral_scan_mode smode);
2479  
2480  /**
2481   * target_if_sops_start_spectral_scan() - Start Spectral scan
2482   * @arg: Pointer to handle for Spectral target_if internal private data
2483   * @smode: Spectral scan mode
2484   * @err: Pointer to error code
2485   *
2486   * Function to start spectral scan
2487   *
2488   * Return: 0 on success else failure
2489   */
2490  uint32_t target_if_sops_start_spectral_scan(void *arg,
2491  					    enum spectral_scan_mode smode,
2492  					    enum spectral_cp_error_code *err);
2493  
2494  /**
2495   * target_if_sops_stop_spectral_scan() - Stop Spectral scan
2496   * @arg: Pointer to handle for Spectral target_if internal private data
2497   * @smode: Spectral scan mode
2498   *
2499   * Function to stop spectral scan
2500   *
2501   * Return: 0 in case of success, -1 on failure
2502   */
2503  uint32_t target_if_sops_stop_spectral_scan(void *arg,
2504  					   enum spectral_scan_mode smode);
2505  
2506  /**
2507   * target_if_spectral_get_extension_channel() - Get the current Extension
2508   *                                              channel (in MHz)
2509   * @arg: Pointer to handle for Spectral target_if internal private data
2510   * @smode: Spectral scan mode
2511   *
2512   * Return: Current Extension channel (in MHz) on success, 0 on failure or if
2513   * extension channel is not present.
2514   */
2515  uint32_t
2516  target_if_spectral_get_extension_channel(void *arg,
2517  					 enum spectral_scan_mode smode);
2518  
2519  /**
2520   * target_if_spectral_get_current_channel() - Get the current channel (in MHz)
2521   * @arg: Pointer to handle for Spectral target_if internal private data
2522   * @smode: Spectral scan mode
2523   *
2524   * Return: Current channel (in MHz) on success, 0 on failure
2525   */
2526  uint32_t
2527  target_if_spectral_get_current_channel(void *arg,
2528  				       enum spectral_scan_mode smode);
2529  
2530  
2531  /**
2532   * target_if_spectral_reset_hw() - Reset the hardware
2533   * @arg: Pointer to handle for Spectral target_if internal private data
2534   *
2535   * This is only a placeholder since it is not currently required in the offload
2536   * case.
2537   *
2538   * Return: 0
2539   */
2540  uint32_t target_if_spectral_reset_hw(void *arg);
2541  
2542  /**
2543   * target_if_spectral_get_chain_noise_floor() - Get the Chain noise floor from
2544   * Noisefloor history buffer
2545   * @arg: Pointer to handle for Spectral target_if internal private data
2546   * @nf_buf: Pointer to buffer into which chain Noise Floor data should be copied
2547   *
2548   * This is only a placeholder since it is not currently required in the offload
2549   * case.
2550   *
2551   * Return: 0
2552   */
2553  uint32_t target_if_spectral_get_chain_noise_floor(void *arg, int16_t *nf_buf);
2554  
2555  /**
2556   * target_if_spectral_get_ext_noisefloor() - Get the extension channel
2557   * noisefloor
2558   * @arg: Pointer to handle for Spectral target_if internal private data
2559   *
2560   * This is only a placeholder since it is not currently required in the offload
2561   * case.
2562   *
2563   * Return: 0
2564   */
2565  int8_t target_if_spectral_get_ext_noisefloor(void *arg);
2566  
2567  /**
2568   * target_if_spectral_get_ctl_noisefloor() - Get the control channel noisefloor
2569   * @arg: Pointer to handle for Spectral target_if internal private data
2570   *
2571   * This is only a placeholder since it is not currently required in the offload
2572   * case.
2573   *
2574   * Return: 0
2575   */
2576  int8_t target_if_spectral_get_ctl_noisefloor(void *arg);
2577  
2578  /**
2579   * target_if_spectral_get_capability() - Get whether a given Spectral hardware
2580   * capability is available
2581   * @arg: Pointer to handle for Spectral target_if internal private data
2582   * @type: Spectral hardware capability type
2583   *
2584   * Return: True if the capability is available, false if the capability is not
2585   * available
2586   */
2587  uint32_t target_if_spectral_get_capability(
2588  	void *arg, enum spectral_capability_type type);
2589  
2590  /**
2591   * target_if_spectral_set_rxfilter() - Set the RX Filter before Spectral start
2592   * @arg: Pointer to handle for Spectral target_if internal private data
2593   * @rxfilter: Rx filter to be used
2594   *
2595   * Note: This is only a placeholder function. It is not currently required since
2596   * FW should be taking care of setting the required filters.
2597   *
2598   * Return: 0
2599   */
2600  uint32_t target_if_spectral_set_rxfilter(void *arg, int rxfilter);
2601  
2602  /**
2603   * target_if_spectral_sops_configure_params() - Configure user supplied Spectral
2604   * parameters
2605   * @arg: Pointer to handle for Spectral target_if internal private data
2606   * @params: Spectral parameters
2607   * @smode: Spectral scan mode
2608   *
2609   * Return: 0 in case of success, -1 on failure
2610   */
2611  uint32_t target_if_spectral_sops_configure_params(
2612  				void *arg, struct spectral_config *params,
2613  				enum spectral_scan_mode smode);
2614  
2615  /**
2616   * target_if_spectral_get_rxfilter() - Get the current RX Filter settings
2617   * @arg: Pointer to handle for Spectral target_if internal private data
2618   *
2619   * Note: This is only a placeholder function. It is not currently required since
2620   * FW should be taking care of setting the required filters.
2621   *
2622   * Return: 0
2623   */
2624  uint32_t target_if_spectral_get_rxfilter(void *arg);
2625  
2626  /**
2627   * target_if_pdev_spectral_deinit() - De-initialize target_if Spectral
2628   * functionality for the given pdev
2629   * @pdev: Pointer to pdev object
2630   *
2631   * Return: None
2632   */
2633  void target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev);
2634  
2635  /**
2636   * target_if_set_spectral_config() - Set spectral config
2637   * @pdev:       Pointer to pdev object
2638   * @param: Spectral parameter id and value
2639   * @smode: Spectral scan mode
2640   * @err: Pointer to Spectral error code
2641   *
2642   * API to set spectral configurations
2643   *
2644   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
2645   */
2646  QDF_STATUS target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev,
2647  					 const struct spectral_cp_param *param,
2648  					 const enum spectral_scan_mode smode,
2649  					 enum spectral_cp_error_code *err);
2650  
2651  /**
2652   * target_if_pdev_spectral_init() - Initialize target_if Spectral
2653   * functionality for the given pdev
2654   * @pdev: Pointer to pdev object
2655   *
2656   * Return: On success, pointer to Spectral target_if internal private data, on
2657   * failure, NULL
2658   */
2659  void *target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev);
2660  
2661  /**
2662   * target_if_spectral_sops_get_params() - Get user configured Spectral
2663   * parameters
2664   * @arg: Pointer to handle for Spectral target_if internal private data
2665   * @params: Pointer to buffer into which Spectral parameters should be copied
2666   * @smode: Spectral scan mode
2667   *
2668   * Return: 0 in case of success, -1 on failure
2669   */
2670  uint32_t target_if_spectral_sops_get_params(
2671  			void *arg, struct spectral_config *params,
2672  			enum spectral_scan_mode smode);
2673  
2674  /**
2675   * target_if_init_spectral_capability() - Initialize Spectral capability
2676   *
2677   * @spectral: Pointer to Spectral target_if internal private data
2678   * @target_type: target type
2679   *
2680   * This is a workaround.
2681   *
2682   * Return: QDF_STATUS
2683   */
2684  QDF_STATUS
2685  target_if_init_spectral_capability(struct target_if_spectral *spectral,
2686  				   uint32_t target_type);
2687  
2688  /**
2689   * target_if_start_spectral_scan() - Start spectral scan
2690   * @pdev: Pointer to pdev object
2691   * @vdev_id: VDEV id
2692   * @smode: Spectral scan mode
2693   * @err: Spectral error code
2694   *
2695   * API to start spectral scan
2696   *
2697   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
2698   */
2699  QDF_STATUS target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev,
2700  					 uint8_t vdev_id,
2701  					 enum spectral_scan_mode smode,
2702  					 enum spectral_cp_error_code *err);
2703  
2704  /**
2705   * target_if_get_spectral_config() - Get spectral configuration
2706   * @pdev: Pointer to pdev object
2707   * @param: Pointer to spectral_config structure in which the configuration
2708   * should be returned
2709   * @smode: Spectral scan mode
2710   *
2711   * API to get the current spectral configuration
2712   *
2713   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
2714   */
2715  QDF_STATUS target_if_get_spectral_config(struct wlan_objmgr_pdev *pdev,
2716  					 struct spectral_config *param,
2717  					 enum spectral_scan_mode smode);
2718  
2719  /**
2720   * target_if_spectral_scan_enable_params() - Enable use of desired Spectral
2721   *                                           parameters
2722   * @spectral: Pointer to Spectral target_if internal private data
2723   * @spectral_params: Pointer to Spectral parameters
2724   * @smode: Spectral scan mode
2725   * @err: Spectral error code
2726   *
2727   * Enable use of desired Spectral parameters by configuring them into HW, and
2728   * starting Spectral scan
2729   *
2730   * Return: 0 on success, 1 on failure
2731   */
2732  int target_if_spectral_scan_enable_params(
2733  		struct target_if_spectral *spectral,
2734  		struct spectral_config *spectral_params,
2735  		enum spectral_scan_mode smode,
2736  		enum spectral_cp_error_code *err);
2737  
2738  /**
2739   * target_if_is_spectral_active() - Get whether Spectral is active
2740   * @pdev: Pointer to pdev object
2741   * @smode: Spectral scan mode
2742   *
2743   * Return: True if Spectral is active, false if Spectral is not active
2744   */
2745  bool target_if_is_spectral_active(struct wlan_objmgr_pdev *pdev,
2746  				  enum spectral_scan_mode smode);
2747  
2748  /**
2749   * target_if_is_spectral_enabled() - Get whether Spectral is enabled
2750   * @pdev: Pointer to pdev object
2751   * @smode: Spectral scan mode
2752   *
2753   * Return: True if Spectral is enabled, false if Spectral is not enabled
2754   */
2755  bool target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev,
2756  				   enum spectral_scan_mode smode);
2757  
2758  /**
2759   * target_if_set_debug_level() - Set debug level for Spectral
2760   * @pdev: Pointer to pdev object
2761   * @debug_level: Debug level
2762   *
2763   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
2764   *
2765   */
2766  QDF_STATUS target_if_set_debug_level(struct wlan_objmgr_pdev *pdev,
2767  				     uint32_t debug_level);
2768  
2769  /**
2770   * target_if_get_debug_level() - Get debug level for Spectral
2771   * @pdev: Pointer to pdev object
2772   *
2773   * Return: Current debug level
2774   */
2775  uint32_t target_if_get_debug_level(struct wlan_objmgr_pdev *pdev);
2776  
2777  
2778  /**
2779   * target_if_get_spectral_capinfo() - Get Spectral capability information
2780   * @pdev: Pointer to pdev object
2781   * @scaps: Buffer into which data should be copied
2782   *
2783   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
2784   */
2785  QDF_STATUS target_if_get_spectral_capinfo(struct wlan_objmgr_pdev *pdev,
2786  					  struct spectral_caps *scaps);
2787  
2788  
2789  /**
2790   * target_if_get_spectral_diagstats() - Get Spectral diagnostic statistics
2791   * @pdev:  Pointer to pdev object
2792   * @stats: Buffer into which data should be copied
2793   *
2794   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
2795   */
2796  QDF_STATUS target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev,
2797  					    struct spectral_diag_stats *stats);
2798  
2799  QDF_STATUS
2800  target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral,
2801  				       enum spectral_scan_mode smode,
2802  				       uint8_t detector_id);
2803  
2804  #ifdef OPTIMIZED_SAMP_MESSAGE
2805  /**
2806   * target_if_spectral_get_num_fft_bins() - Get number of FFT bins from FFT size
2807   * according to the Spectral report mode.
2808   * @fft_size: FFT length
2809   * @report_mode: Spectral report mode
2810   *
2811   * Get number of FFT bins from FFT size according to the Spectral
2812   * report mode.
2813   *
2814   * Return: Number of FFT bins
2815   */
2816  static inline uint32_t
target_if_spectral_get_num_fft_bins(uint32_t fft_size,enum spectral_report_mode report_mode)2817  target_if_spectral_get_num_fft_bins(uint32_t fft_size,
2818  				    enum spectral_report_mode report_mode)
2819  {
2820  	switch (report_mode) {
2821  	case SPECTRAL_REPORT_MODE_0:
2822  	case SPECTRAL_REPORT_MODE_1:
2823  		return 0;
2824  	case SPECTRAL_REPORT_MODE_2:
2825  		return (1 << (fft_size - 1));
2826  	case SPECTRAL_REPORT_MODE_3:
2827  		return (1 << fft_size);
2828  	default:
2829  		return -EINVAL;
2830  	}
2831  }
2832  #endif /* OPTIMIZED_SAMP_MESSAGE */
2833  
2834  #ifdef OPTIMIZED_SAMP_MESSAGE
2835  /**
2836   * target_if_get_detector_chwidth() - Get per-detector bandwidth
2837   * based on channel width and fragmentation.
2838   * @ch_width: Spectral scan channel width
2839   * @fragmentation_160: Target type has fragmentation or not
2840   *
2841   * Get per-detector BW.
2842   *
2843   * Return: detector BW
2844   */
2845  static inline
target_if_get_detector_chwidth(enum phy_ch_width ch_width,bool fragmentation_160)2846  enum phy_ch_width target_if_get_detector_chwidth(enum phy_ch_width ch_width,
2847  						 bool fragmentation_160)
2848  {
2849  	return ((ch_width == CH_WIDTH_160MHZ && fragmentation_160) ?
2850  		CH_WIDTH_80MHZ : ((ch_width == CH_WIDTH_80P80MHZ) ?
2851  		CH_WIDTH_80MHZ : ch_width));
2852  }
2853  
2854  /**
2855   * target_if_spectral_set_start_end_freq() - Set start and end frequencies for
2856   * a given center frequency
2857   * @cfreq: Center frequency for which start and end freq need to be set
2858   * @ch_width: Spectral scan Channel width
2859   * @fragmentation_160: Target type has fragmentation or not
2860   * @start_end_freq: Array containing start and end frequency of detector
2861   *
2862   * Set the start and end frequencies for given center frequency in destination
2863   * detector info struct
2864   *
2865   * Return: void
2866   */
2867  static inline
target_if_spectral_set_start_end_freq(uint32_t cfreq,enum phy_ch_width ch_width,bool fragmentation_160,uint32_t * start_end_freq)2868  void target_if_spectral_set_start_end_freq(uint32_t cfreq,
2869  					   enum phy_ch_width ch_width,
2870  					   bool fragmentation_160,
2871  					   uint32_t *start_end_freq)
2872  {
2873  	enum phy_ch_width det_ch_width;
2874  
2875  	det_ch_width = target_if_get_detector_chwidth(ch_width,
2876  						      fragmentation_160);
2877  
2878  	start_end_freq[0] = cfreq - (wlan_reg_get_bw_value(det_ch_width) >> 1);
2879  	start_end_freq[1] = cfreq + (wlan_reg_get_bw_value(det_ch_width) >> 1);
2880  }
2881  #endif /* OPTIMIZED_SAMP_MESSAGE */
2882  
2883  #ifdef DIRECT_BUF_RX_ENABLE
2884  /**
2885   * target_if_consume_spectral_report_gen3() -  Process fft report for gen3
2886   * @spectral: Pointer to spectral object
2887   * @report: Pointer to spectral report
2888   *
2889   * Process fft report for gen3
2890   *
2891   * Return: Success/Failure
2892   */
2893  int
2894  target_if_consume_spectral_report_gen3(
2895  	 struct target_if_spectral *spectral,
2896  	 struct spectral_report *report);
2897  #endif
2898  
2899  /**
2900   * target_if_spectral_fw_hang() - Crash the FW from Spectral module
2901   * @spectral: Pointer to Spectral LMAC object
2902   *
2903   * Return: QDF_STATUS of operation
2904   */
2905  QDF_STATUS target_if_spectral_fw_hang(struct target_if_spectral *spectral);
2906  
2907  /**
2908   * target_if_spectral_finite_scan_update() - Update scan count for finite scan
2909   * and stop Spectral scan when required
2910   * @spectral: Pointer to Spectral target_if internal private data
2911   * @smode: Spectral scan mode
2912   *
2913   * This API decrements the number of Spectral reports expected from target for
2914   * a finite Spectral scan. When expected number of reports are received from
2915   * target Spectral scan is stopped.
2916   *
2917   * Return: QDF_STATUS on success
2918   */
2919  QDF_STATUS
2920  target_if_spectral_finite_scan_update(struct target_if_spectral *spectral,
2921  				      enum spectral_scan_mode smode);
2922  
2923  /**
2924   * target_if_spectral_is_finite_scan() - Check Spectral scan is finite/infinite
2925   * @spectral: Pointer to Spectral target_if internal private data
2926   * @smode: Spectral scan mode
2927   * @finite_spectral_scan: location to store result
2928   *
2929   * API to check whether Spectral scan is finite/infinite for the give mode.
2930   * A non zero scan count indicates that scan is finite. Scan count of 0
2931   * indicates an infinite Spectral scan.
2932   *
2933   * Return: QDF_STATUS on success
2934   */
2935  QDF_STATUS
2936  target_if_spectral_is_finite_scan(struct target_if_spectral *spectral,
2937  				  enum spectral_scan_mode smode,
2938  				  bool *finite_spectral_scan);
2939  
2940  #ifdef BIG_ENDIAN_HOST
2941  /**
2942   * target_if_byte_swap_spectral_headers_gen3() - Apply byte-swap on headers
2943   * @spectral: Pointer to Spectral target_if internal private data
2944   * @data: Pointer to the start of Spectral Scan Summary report
2945   *
2946   * This API is only required for Big-endian Host platforms.
2947   * It applies 32-bit byte-swap on Spectral Scan Summary and Search FFT reports
2948   * and copies them back to the source location.
2949   * Padding bytes that lie between the reports won't be touched.
2950   *
2951   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
2952   */
2953  QDF_STATUS target_if_byte_swap_spectral_headers_gen3(
2954  	 struct target_if_spectral *spectral,
2955  	 void *data);
2956  
2957  /**
2958   * target_if_byte_swap_spectral_fft_bins_gen3() - Apply byte-swap on FFT bins
2959   * @rparams: Pointer to Spectral report parameters
2960   * @bin_pwr_data: Pointer to the start of FFT bins
2961   * @num_fftbins: Number of FFT bins
2962   *
2963   * This API is only required for Big-endian Host platforms.
2964   * It applies pack-mode-aware byte-swap on the FFT bins as below:
2965   *   1. pack-mode 0 (i.e., 1 FFT bin per DWORD):
2966   *        Reads the least significant 2 bytes of each DWORD, applies 16-bit
2967   *        byte-swap on that value, and copies it back to the source location.
2968   *   2. pack-mode 1 (i.e., 2 FFT bins per DWORD):
2969   *        Reads each FFT bin, applies 16-bit byte-swap on that value,
2970   *        and copies it back to the source location.
2971   *   3. pack-mode 2 (4 FFT bins per DWORD):
2972   *        Nothing
2973   *
2974   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
2975   */
2976  QDF_STATUS target_if_byte_swap_spectral_fft_bins_gen3(
2977  	const struct spectral_report_params *rparams,
2978  	void *bin_pwr_data, size_t num_fftbins);
2979  #endif /* BIG_ENDIAN_HOST */
2980  
2981  #ifdef OPTIMIZED_SAMP_MESSAGE
2982  /**
2983   * target_if_populate_fft_bins_info() - Populate the start and end bin
2984   * indices, on per-detector level.
2985   * @spectral: Pointer to target_if spectral internal structure
2986   * @smode: Spectral scan mode
2987   *
2988   * Populate the start and end bin indices, on per-detector level.
2989   *
2990   * Return: Success/Failure
2991   */
2992  QDF_STATUS
2993  target_if_populate_fft_bins_info(struct target_if_spectral *spectral,
2994  				 enum spectral_scan_mode smode);
2995  #else
2996  static inline QDF_STATUS
target_if_populate_fft_bins_info(struct target_if_spectral * spectral,enum spectral_scan_mode smode)2997  target_if_populate_fft_bins_info(struct target_if_spectral *spectral,
2998  				 enum spectral_scan_mode smode)
2999  {
3000  	return QDF_STATUS_SUCCESS;
3001  }
3002  #endif
3003  
3004  /**
3005   * spectral_is_session_info_expected_from_target() - Check if spectral scan
3006   * session is expected from target
3007   * @pdev: pdev pointer
3008   * @is_session_info_expected: Pointer to caller variable
3009   *
3010   * Return: QDF_STATUS of operation
3011   */
3012  QDF_STATUS
3013  spectral_is_session_info_expected_from_target(struct wlan_objmgr_pdev *pdev,
3014  					      bool *is_session_info_expected);
3015  
3016  #ifdef WIN32
3017  #pragma pack(pop, target_if_spectral)
3018  #endif
3019  #ifdef __ATTRIB_PACK
3020  #undef __ATTRIB_PACK
3021  #endif
3022  
3023  /**
3024   * target_if_spectral_copy_fft_bins() - Copy FFT bins from source buffer to
3025   * destination buffer
3026   * @spectral: Pointer to Spectral LMAC object
3027   * @src_fft_buf: Pointer to source FFT buffer
3028   * @dest_fft_buf: Pointer to destination FFT buffer
3029   * @fft_bin_count: Number of FFT bins to copy
3030   * @bytes_copied: Number of bytes copied by this API
3031   * @pwr_format: Spectral FFT bin format (linear/dBm mode)
3032   *
3033   * Different targets supports different FFT bin widths. This API encapsulates
3034   * all those details and copies 8-bit FFT value into the destination buffer.
3035   * Also, this API takes care of handling big-endian mode.
3036   * In essence, it does the following.
3037   *   - Read DWORDs one by one
3038   *   - Extract individual FFT bins out of it
3039   *   - Copy the FFT bin to destination buffer
3040   *
3041   * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
3042   */
3043  QDF_STATUS
3044  target_if_spectral_copy_fft_bins(struct target_if_spectral *spectral,
3045  				 const void *src_fft_buf,
3046  				 void *dest_fft_buf,
3047  				 uint32_t fft_bin_count,
3048  				 uint32_t *bytes_copied,
3049  				 uint16_t pwr_format);
3050  #endif /* WLAN_CONV_SPECTRAL_ENABLE */
3051  
3052  struct spectral_capabilities_event_params;
3053  /**
3054   * target_if_wmi_extract_spectral_caps_fixed_param() - Wrapper function to
3055   * extract fixed params from Spectral capabilities WMI event
3056   * @psoc: Pointer to psoc object
3057   * @evt_buf: Event buffer
3058   * @param: Spectral capabilities event parameters data structure to be filled
3059   * by this API
3060   *
3061   * Return: QDF_STATUS of operation
3062   */
3063  QDF_STATUS target_if_wmi_extract_spectral_caps_fixed_param(
3064  			struct wlan_objmgr_psoc *psoc,
3065  			uint8_t *evt_buf,
3066  			struct spectral_capabilities_event_params *param);
3067  
3068  struct spectral_scan_bw_capabilities;
3069  /**
3070   * target_if_wmi_extract_spectral_scan_bw_caps() - Wrapper function to
3071   * extract bandwidth capabilities from Spectral capabilities WMI event
3072   * @psoc: Pointer to psoc object
3073   * @evt_buf: Event buffer
3074   * @bw_caps: Data structure to be filled by this API after extraction
3075   *
3076   * Return: QDF_STATUS of operation
3077   */
3078  QDF_STATUS
3079  target_if_wmi_extract_spectral_scan_bw_caps(
3080  			struct wlan_objmgr_psoc *psoc,
3081  			uint8_t *evt_buf,
3082  			struct spectral_scan_bw_capabilities *bw_caps);
3083  
3084  struct spectral_fft_size_capabilities;
3085  /**
3086   * target_if_wmi_extract_spectral_fft_size_caps() - Wrapper function to
3087   * extract fft size capabilities from Spectral capabilities WMI event
3088   * @psoc: Pointer to psoc object
3089   * @evt_buf: Event buffer
3090   * @fft_size_caps: Data structure to be filled by this API after extraction
3091   *
3092   * Return: QDF_STATUS of operation
3093   */
3094  QDF_STATUS
3095  target_if_wmi_extract_spectral_fft_size_caps(
3096  			struct wlan_objmgr_psoc *psoc,
3097  			uint8_t *evt_buf,
3098  			struct spectral_fft_size_capabilities *fft_size_caps);
3099  #endif /* _TARGET_IF_SPECTRAL_H_ */
3100