Commit c92f774a authored by Tamizh Chelvam Raja's avatar Tamizh Chelvam Raja Committed by Kalle Valo

wifi: ath11k: Add spectral scan support for 160 MHz

There are two types of 160 MHz spectral scan support mentioned below

1. Fragmented approach
2. Single event approach

In this fragmented approach, single 160 MHz will be split as two
80 MHz buffer. First fft sample buffer will contain spectral scan
result of primary 80 MHz and the second fft sample buffer will contain
secondary 80 MHz and here cfreq1 and cfreq2 will be mentioned.
In case of 160 MHz on 36th channel will contain cfreq1 as 5210 and
cfreq2 as 5290. Chipsets which support this approach are IPQ8074/IPQ6018.

Replacing freq1 with freq2 in every secondary sepctral scan event to
distinguish between two different 80 MHz spectral event data.

In the 2nd approach each fft sample buffer will contain spectral scan
result for whole 160 MHz by mentioning cfreq1 as 5250 which is center
frequency of whole 160 MHz. Chipset which support this approach is QCN9074.

Host will receive spectral event from target for every 5 fft samples.

Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01120-QCAHKSWPL-1
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01120-QCAHKSWP
Signed-off-by: default avatarTamizh Chelvam Raja <quic_tamizhr@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20220725055001.15194-1-quic_tamizhr@quicinc.com
parent 710a95f9
......@@ -70,6 +70,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.summary_pad_sz = 0,
.fft_hdr_len = 16,
.max_fft_bins = 512,
.fragment_160mhz = true,
},
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
......@@ -149,6 +150,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.summary_pad_sz = 0,
.fft_hdr_len = 16,
.max_fft_bins = 512,
.fragment_160mhz = true,
},
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
......@@ -228,6 +230,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.summary_pad_sz = 0,
.fft_hdr_len = 0,
.max_fft_bins = 0,
.fragment_160mhz = false,
},
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
......@@ -308,6 +311,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.summary_pad_sz = 16,
.fft_hdr_len = 24,
.max_fft_bins = 1024,
.fragment_160mhz = false,
},
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
......@@ -387,6 +391,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.summary_pad_sz = 0,
.fft_hdr_len = 0,
.max_fft_bins = 0,
.fragment_160mhz = false,
},
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
......@@ -468,6 +473,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.summary_pad_sz = 0,
.fft_hdr_len = 0,
.max_fft_bins = 0,
.fragment_160mhz = false,
},
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
......@@ -548,6 +554,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.summary_pad_sz = 0,
.fft_hdr_len = 0,
.max_fft_bins = 0,
.fragment_160mhz = false,
},
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
......
......@@ -173,6 +173,7 @@ struct ath11k_hw_params {
u8 summary_pad_sz;
u8 fft_hdr_len;
u16 max_fft_bins;
bool fragment_160mhz;
} spectral;
u16 interface_modes;
......
......@@ -30,6 +30,7 @@
#define ATH11K_SPECTRAL_20MHZ 20
#define ATH11K_SPECTRAL_40MHZ 40
#define ATH11K_SPECTRAL_80MHZ 80
#define ATH11K_SPECTRAL_160MHZ 160
#define ATH11K_SPECTRAL_SIGNATURE 0xFA
......@@ -183,6 +184,8 @@ static int ath11k_spectral_scan_trigger(struct ath11k *ar)
if (ar->spectral.mode == ATH11K_SPECTRAL_DISABLED)
return 0;
ar->spectral.is_primary = true;
ret = ath11k_wmi_vdev_spectral_enable(ar, arvif->vdev_id,
ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR,
ATH11K_WMI_SPECTRAL_ENABLE_CMD_ENABLE);
......@@ -585,6 +588,7 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
u8 chan_width_mhz, bin_sz;
int ret;
u32 check_length;
bool fragment_sample = false;
lockdep_assert_held(&ar->spectral.lock);
......@@ -639,6 +643,13 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
case ATH11K_SPECTRAL_80MHZ:
fft_sample->chan_width_mhz = chan_width_mhz;
break;
case ATH11K_SPECTRAL_160MHZ:
if (ab->hw_params.spectral.fragment_160mhz) {
chan_width_mhz /= 2;
fragment_sample = true;
}
fft_sample->chan_width_mhz = chan_width_mhz;
break;
default:
ath11k_warn(ab, "invalid channel width %d\n", chan_width_mhz);
return -EINVAL;
......@@ -663,6 +674,17 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
freq = summary->meta.freq2;
fft_sample->freq2 = __cpu_to_be16(freq);
/* If freq2 is available then the spectral scan results are fragmented
* as primary and secondary
*/
if (fragment_sample && freq) {
if (!ar->spectral.is_primary)
fft_sample->freq1 = cpu_to_be16(freq);
/* We have to toggle the is_primary to handle the next report */
ar->spectral.is_primary = !ar->spectral.is_primary;
}
ath11k_spectral_parse_fft(fft_sample->data, fft_report->bins, num_bins,
ab->hw_params.spectral.fft_sz);
......
......@@ -35,6 +35,7 @@ struct ath11k_spectral {
u16 count;
u8 fft_size;
bool enabled;
bool is_primary;
};
#ifdef CONFIG_ATH11K_SPECTRAL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment