2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include "../spectral_common.h"
22 /* enum spectral_mode:
24 * @SPECTRAL_DISABLED: spectral mode is disabled
25 * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with
27 * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples
28 * is performed manually.
29 * @SPECTRAL_CHANSCAN: Like manual, but also triggered when changing channels
30 * during a channel scan.
33 SPECTRAL_DISABLED
= 0,
39 #define SPECTRAL_SCAN_BITMASK 0x10
40 /* Radar info packet format, used for DFS and spectral formats. */
41 struct ath_radar_info
{
47 /* The HT20 spectral data has 4 bytes of additional information at it's end.
49 * [7:0]: all bins {max_magnitude[1:0], bitmap_weight[5:0]}
50 * [7:0]: all bins max_magnitude[9:2]
51 * [7:0]: all bins {max_index[5:0], max_magnitude[11:10]}
52 * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
54 struct ath_ht20_mag_info
{
59 /* WARNING: don't actually use this struct! MAC may vary the amount of
60 * data by -1/+2. This struct is for reference only.
62 struct ath_ht20_fft_packet
{
63 u8 data
[SPECTRAL_HT20_NUM_BINS
];
64 struct ath_ht20_mag_info mag_info
;
65 struct ath_radar_info radar_info
;
68 #define SPECTRAL_HT20_TOTAL_DATA_LEN (sizeof(struct ath_ht20_fft_packet))
69 #define SPECTRAL_HT20_SAMPLE_LEN (sizeof(struct ath_ht20_mag_info) +\
70 SPECTRAL_HT20_NUM_BINS)
72 /* Dynamic 20/40 mode:
74 * [7:0]: lower bins {max_magnitude[1:0], bitmap_weight[5:0]}
75 * [7:0]: lower bins max_magnitude[9:2]
76 * [7:0]: lower bins {max_index[5:0], max_magnitude[11:10]}
77 * [7:0]: upper bins {max_magnitude[1:0], bitmap_weight[5:0]}
78 * [7:0]: upper bins max_magnitude[9:2]
79 * [7:0]: upper bins {max_index[5:0], max_magnitude[11:10]}
80 * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
82 struct ath_ht20_40_mag_info
{
88 /* WARNING: don't actually use this struct! MAC may vary the amount of
89 * data. This struct is for reference only.
91 struct ath_ht20_40_fft_packet
{
92 u8 data
[SPECTRAL_HT20_40_NUM_BINS
];
93 struct ath_ht20_40_mag_info mag_info
;
94 struct ath_radar_info radar_info
;
97 struct ath_spec_scan_priv
{
99 /* relay(fs) channel for spectral scan */
100 struct rchan
*rfs_chan_spec_scan
;
101 enum spectral_mode spectral_mode
;
102 struct ath_spec_scan spec_config
;
105 #define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet))
106 #define SPECTRAL_HT20_40_SAMPLE_LEN (sizeof(struct ath_ht20_40_mag_info) +\
107 SPECTRAL_HT20_40_NUM_BINS)
109 #define SPECTRAL_SAMPLE_MAX_LEN SPECTRAL_HT20_40_SAMPLE_LEN
111 /* grabs the max magnitude from the all/upper/lower bins */
112 static inline u16
spectral_max_magnitude(u8
*bins
)
114 return (bins
[0] & 0xc0) >> 6 |
115 (bins
[1] & 0xff) << 2 |
116 (bins
[2] & 0x03) << 10;
119 /* return the max magnitude from the all/upper/lower bins */
120 static inline u8
spectral_max_index(u8
*bins
, int num_bins
)
122 s8 m
= (bins
[2] & 0xfc) >> 2;
123 u8 zero_idx
= num_bins
/ 2;
125 /* It's a 5 bit signed int, remove its sign and use one's
126 * complement interpretation to add the sign back to the 8
134 /* Bring the zero point to the beginning
135 * instead of the middle so that we can use
136 * it for array lookup and that we don't deal
137 * with negative values later
141 /* Sanity check to make sure index is within bounds */
142 if (m
< 0 || m
> num_bins
- 1)
148 static inline u8
spectral_max_index_ht40(u8
*bins
)
152 idx
= spectral_max_index(bins
, SPECTRAL_HT20_40_NUM_BINS
);
154 /* positive values and zero are starting at the beginning
157 return idx
% (SPECTRAL_HT20_40_NUM_BINS
/ 2);
160 static inline u8
spectral_max_index_ht20(u8
*bins
)
162 return spectral_max_index(bins
, SPECTRAL_HT20_NUM_BINS
);
165 /* return the bitmap weight from the all/upper/lower bins */
166 static inline u8
spectral_bitmap_weight(u8
*bins
)
168 return bins
[0] & 0x3f;
171 #ifdef CONFIG_ATH9K_COMMON_SPECTRAL
172 void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv
*spec_priv
, struct dentry
*debugfs_phy
);
173 void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv
*spec_priv
);
175 void ath9k_cmn_spectral_scan_trigger(struct ath_common
*common
,
176 struct ath_spec_scan_priv
*spec_priv
);
177 int ath9k_cmn_spectral_scan_config(struct ath_common
*common
,
178 struct ath_spec_scan_priv
*spec_priv
,
179 enum spectral_mode spectral_mode
);
180 int ath_cmn_process_fft(struct ath_spec_scan_priv
*spec_priv
, struct ieee80211_hdr
*hdr
,
181 struct ath_rx_status
*rs
, u64 tsf
);
183 static inline void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv
*spec_priv
,
184 struct dentry
*debugfs_phy
)
188 static inline void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv
*spec_priv
)
192 static inline void ath9k_cmn_spectral_scan_trigger(struct ath_common
*common
,
193 struct ath_spec_scan_priv
*spec_priv
)
197 static inline int ath_cmn_process_fft(struct ath_spec_scan_priv
*spec_priv
,
198 struct ieee80211_hdr
*hdr
,
199 struct ath_rx_status
*rs
, u64 tsf
)
203 #endif /* CONFIG_ATH9K_COMMON_SPECTRAL */
205 #endif /* SPECTRAL_H */