Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2013 Qualcomm Atheros, Inc.
0003  *
0004  * Permission to use, copy, modify, and/or distribute this software for any
0005  * purpose with or without fee is hereby granted, provided that the above
0006  * copyright notice and this permission notice appear in all copies.
0007  *
0008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0015  */
0016 
0017 #ifndef SPECTRAL_H
0018 #define SPECTRAL_H
0019 
0020 #include "../spectral_common.h"
0021 
0022 /* enum spectral_mode:
0023  *
0024  * @SPECTRAL_DISABLED: spectral mode is disabled
0025  * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with
0026  *  something else.
0027  * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples
0028  *  is performed manually.
0029  * @SPECTRAL_CHANSCAN: Like manual, but also triggered when changing channels
0030  *  during a channel scan.
0031  */
0032 enum spectral_mode {
0033     SPECTRAL_DISABLED = 0,
0034     SPECTRAL_BACKGROUND,
0035     SPECTRAL_MANUAL,
0036     SPECTRAL_CHANSCAN,
0037 };
0038 
0039 #define SPECTRAL_SCAN_BITMASK       0x10
0040 /* Radar info packet format, used for DFS and spectral formats. */
0041 struct ath_radar_info {
0042     u8 pulse_length_pri;
0043     u8 pulse_length_ext;
0044     u8 pulse_bw_info;
0045 } __packed;
0046 
0047 /* The HT20 spectral data has 4 bytes of additional information at it's end.
0048  *
0049  * [7:0]: all bins {max_magnitude[1:0], bitmap_weight[5:0]}
0050  * [7:0]: all bins  max_magnitude[9:2]
0051  * [7:0]: all bins {max_index[5:0], max_magnitude[11:10]}
0052  * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
0053  */
0054 struct ath_ht20_mag_info {
0055     u8 all_bins[3];
0056     u8 max_exp;
0057 } __packed;
0058 
0059 /* WARNING: don't actually use this struct! MAC may vary the amount of
0060  * data by -1/+2. This struct is for reference only.
0061  */
0062 struct ath_ht20_fft_packet {
0063     u8 data[SPECTRAL_HT20_NUM_BINS];
0064     struct ath_ht20_mag_info mag_info;
0065     struct ath_radar_info radar_info;
0066 } __packed;
0067 
0068 #define SPECTRAL_HT20_TOTAL_DATA_LEN    (sizeof(struct ath_ht20_fft_packet))
0069 #define SPECTRAL_HT20_SAMPLE_LEN    (sizeof(struct ath_ht20_mag_info) +\
0070                     SPECTRAL_HT20_NUM_BINS)
0071 
0072 /* Dynamic 20/40 mode:
0073  *
0074  * [7:0]: lower bins {max_magnitude[1:0], bitmap_weight[5:0]}
0075  * [7:0]: lower bins  max_magnitude[9:2]
0076  * [7:0]: lower bins {max_index[5:0], max_magnitude[11:10]}
0077  * [7:0]: upper bins {max_magnitude[1:0], bitmap_weight[5:0]}
0078  * [7:0]: upper bins  max_magnitude[9:2]
0079  * [7:0]: upper bins {max_index[5:0], max_magnitude[11:10]}
0080  * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
0081  */
0082 struct ath_ht20_40_mag_info {
0083     u8 lower_bins[3];
0084     u8 upper_bins[3];
0085     u8 max_exp;
0086 } __packed;
0087 
0088 /* WARNING: don't actually use this struct! MAC may vary the amount of
0089  * data. This struct is for reference only.
0090  */
0091 struct ath_ht20_40_fft_packet {
0092     u8 data[SPECTRAL_HT20_40_NUM_BINS];
0093     struct ath_ht20_40_mag_info mag_info;
0094     struct ath_radar_info radar_info;
0095 } __packed;
0096 
0097 struct ath_spec_scan_priv {
0098     struct ath_hw *ah;
0099     /* relay(fs) channel for spectral scan */
0100     struct rchan *rfs_chan_spec_scan;
0101     enum spectral_mode spectral_mode;
0102     struct ath_spec_scan spec_config;
0103 };
0104 
0105 #define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet))
0106 #define SPECTRAL_HT20_40_SAMPLE_LEN (sizeof(struct ath_ht20_40_mag_info) +\
0107                     SPECTRAL_HT20_40_NUM_BINS)
0108 
0109 #define SPECTRAL_SAMPLE_MAX_LEN     SPECTRAL_HT20_40_SAMPLE_LEN
0110 
0111 /* grabs the max magnitude from the all/upper/lower bins */
0112 static inline u16 spectral_max_magnitude(u8 *bins)
0113 {
0114     return (bins[0] & 0xc0) >> 6 |
0115            (bins[1] & 0xff) << 2 |
0116            (bins[2] & 0x03) << 10;
0117 }
0118 
0119 /* return the max magnitude from the all/upper/lower bins */
0120 static inline u8 spectral_max_index(u8 *bins, int num_bins)
0121 {
0122     s8 m = (bins[2] & 0xfc) >> 2;
0123     u8 zero_idx = num_bins / 2;
0124 
0125     /* It's a 5 bit signed int, remove its sign and use one's
0126      * complement interpretation to add the sign back to the 8
0127      * bit int
0128      */
0129     if (m & 0x20) {
0130         m &= ~0x20;
0131         m |= 0xe0;
0132     }
0133 
0134     /* Bring the zero point to the beginning
0135      * instead of the middle so that we can use
0136      * it for array lookup and that we don't deal
0137      * with negative values later
0138      */
0139     m += zero_idx;
0140 
0141     /* Sanity check to make sure index is within bounds */
0142     if (m < 0 || m > num_bins - 1)
0143         m = 0;
0144 
0145     return m;
0146 }
0147 
0148 static inline u8 spectral_max_index_ht40(u8 *bins)
0149 {
0150     u8 idx;
0151 
0152     idx = spectral_max_index(bins, SPECTRAL_HT20_40_NUM_BINS);
0153 
0154     /* positive values and zero are starting at the beginning
0155      * of the data field.
0156      */
0157     return idx % (SPECTRAL_HT20_40_NUM_BINS / 2);
0158 }
0159 
0160 static inline u8 spectral_max_index_ht20(u8 *bins)
0161 {
0162     return spectral_max_index(bins, SPECTRAL_HT20_NUM_BINS);
0163 }
0164 
0165 /* return the bitmap weight from the all/upper/lower bins */
0166 static inline u8 spectral_bitmap_weight(u8 *bins)
0167 {
0168     return bins[0] & 0x3f;
0169 }
0170 
0171 #ifdef CONFIG_ATH9K_COMMON_SPECTRAL
0172 void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy);
0173 void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv);
0174 
0175 void ath9k_cmn_spectral_scan_trigger(struct ath_common *common,
0176                  struct ath_spec_scan_priv *spec_priv);
0177 int ath9k_cmn_spectral_scan_config(struct ath_common *common,
0178                    struct ath_spec_scan_priv *spec_priv,
0179                    enum spectral_mode spectral_mode);
0180 int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr,
0181             struct ath_rx_status *rs, u64 tsf);
0182 #else
0183 static inline void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,
0184                          struct dentry *debugfs_phy)
0185 {
0186 }
0187 
0188 static inline void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
0189 {
0190 }
0191 
0192 static inline void ath9k_cmn_spectral_scan_trigger(struct ath_common *common,
0193                            struct ath_spec_scan_priv *spec_priv)
0194 {
0195 }
0196 
0197 static inline int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv,
0198                       struct ieee80211_hdr *hdr,
0199                       struct ath_rx_status *rs, u64 tsf)
0200 {
0201     return 0;
0202 }
0203 #endif /* CONFIG_ATH9K_COMMON_SPECTRAL */
0204 
0205 #endif /* SPECTRAL_H */