--- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -32,6 +32,7 @@ static const struct ath11k_hw_params ath .board_size = IPQ8074_MAX_BOARD_DATA_SZ, .cal_size = IPQ8074_MAX_CAL_DATA_SZ, }, + .spectral_fft_sz = 2, }, { .dev_id = ATH11K_HW_IPQ6018, @@ -41,6 +42,7 @@ static const struct ath11k_hw_params ath .board_size = IPQ6018_MAX_BOARD_DATA_SZ, .cal_size = IPQ6018_MAX_CAL_DATA_SZ, }, + .spectral_fft_sz = 4, }, }; --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -112,6 +112,7 @@ struct ath11k_hw_params { size_t board_size; size_t cal_size; } fw; + u8 spectral_fft_sz; }; struct ath11k_fw_ie { --- a/drivers/net/wireless/ath/ath11k/spectral.c +++ b/drivers/net/wireless/ath/ath11k/spectral.c @@ -17,6 +17,8 @@ #define ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS 32 #define ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS 256 +#define ATH11K_SPECTRAL_SAMPLE_FFT_BIN_MASK 0xFF + #define ATH11K_SPECTRAL_SCAN_COUNT_MAX 4095 /* Max channel computed by sum of 2g and 5g band channels */ @@ -109,7 +111,7 @@ struct spectral_search_fft_report { __le32 info1; __le32 info2; __le32 reserve0; - __le16 bins[0]; + u8 bins[0]; } __packed; struct ath11k_spectral_search_report { @@ -555,6 +557,30 @@ static u8 ath11k_spectral_get_max_exp(s8 return max_exp; } +static void ath11k_spectral_parse_32bit_fft(u8 *outbins, u8 *inbins, int num_bins) +{ + int i; + __le32 *data = (__le32 *)inbins; + + i = 0; + while (i < num_bins) { + outbins[i] = (__le32_to_cpu(data[i])) & ATH11K_SPECTRAL_SAMPLE_FFT_BIN_MASK; + i++; + } +} + +static void ath11k_spectral_parse_16bit_fft(u8 *outbins, u8 *inbins, int num_bins) +{ + int i; + __le16 *data = (__le16 *)inbins; + + i = 0; + while (i < num_bins) { + outbins[i] = (__le16_to_cpu(data[i])) & ATH11K_SPECTRAL_SAMPLE_FFT_BIN_MASK; + i++; + } +} + static int ath11k_spectral_process_fft(struct ath11k *ar, struct ath11k_spectral_summary_report *summary, @@ -566,13 +592,19 @@ int ath11k_spectral_process_fft(struct a struct spectral_search_fft_report *fft_report = data; struct ath11k_spectral_search_report search; struct spectral_tlv *tlv; - int tlv_len, bin_len, num_bins, i; + int tlv_len, bin_len, num_bins; u16 length, freq; u8 chan_width_mhz; int ret; lockdep_assert_held(&ar->spectral.lock); + if (!ab->hw_params.spectral_fft_sz) { + ath11k_warn(ab, "invalid bin size type for hw rev %d\n", + ab->hw_rev); + return -EINVAL; + } + tlv = (struct spectral_tlv *)data; tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN, __le32_to_cpu(tlv->header)); /* convert Dword into bytes */ @@ -634,10 +666,20 @@ int ath11k_spectral_process_fft(struct a freq = summary->meta.freq2; fft_sample->freq2 = __cpu_to_be16(freq); - i = 0; - while (i < num_bins) { - fft_sample->data[i] = (__le16_to_cpu(fft_report->bins[i])) & 0xFF; - i++; + switch (ab->hw_params.spectral_fft_sz) { + case 4: + ath11k_spectral_parse_32bit_fft(fft_sample->data, + fft_report->bins, + num_bins); + break; + case 2: + ath11k_spectral_parse_16bit_fft(fft_sample->data, + fft_report->bins, + num_bins); + break; + default: + ath11k_warn(ab, "unsupported fft size %u\n", ab->hw_params.spectral_fft_sz); + return -EOPNOTSUPP; } fft_sample->max_exp = ath11k_spectral_get_max_exp(fft_sample->max_index,