qcacmn: Enable Agile Spectral in single synth targets

Some targets have a single synthesizer and it allows
a single Spectral detector to scan in 160 MHz /165 MHz.
Enable Agile Spectral scanning in 160 MHz / 165 MHz for
such targets. Agile creq2 will be populated in the WMI
command after WMI interface changes are merged.

CRs-Fixed: 2648480
Change-Id: I8522cbeeab29ac41479e3041eea376b081c0758a
This commit is contained in:
Edayilliam Jayadev
2020-04-02 11:30:21 +05:30
committed by nshrivas
parent f87f43f8b2
commit 1de47959b6
14 changed files with 563 additions and 263 deletions

View File

@@ -82,6 +82,8 @@ const struct nla_policy spectral_scan_policy[
.type = NLA_U32}, .type = NLA_U32},
[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY] = { [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY] = {
.type = NLA_U32}, .type = NLA_U32},
[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2] = {
.type = NLA_U32},
[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE] = { [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE] = {
.type = NLA_U32}, .type = NLA_U32},
[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG] = { [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG] = {
@@ -112,7 +114,8 @@ static void wlan_spectral_intit_config(struct spectral_config *config_req)
config_req->ss_bin_scale = SPECTRAL_PHYERR_PARAM_NOVAL; config_req->ss_bin_scale = SPECTRAL_PHYERR_PARAM_NOVAL;
config_req->ss_dbm_adj = SPECTRAL_PHYERR_PARAM_NOVAL; config_req->ss_dbm_adj = SPECTRAL_PHYERR_PARAM_NOVAL;
config_req->ss_chn_mask = SPECTRAL_PHYERR_PARAM_NOVAL; config_req->ss_chn_mask = SPECTRAL_PHYERR_PARAM_NOVAL;
config_req->ss_frequency = SPECTRAL_PHYERR_PARAM_NOVAL; config_req->ss_frequency.cfreq1 = SPECTRAL_PHYERR_PARAM_NOVAL;
config_req->ss_frequency.cfreq2 = SPECTRAL_PHYERR_PARAM_NOVAL;
} }
/** /**
@@ -345,9 +348,14 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy,
[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT]); [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT]);
if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY]) if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY])
config_req.ss_frequency = nla_get_u32(tb config_req.ss_frequency.cfreq1 = nla_get_u32(tb
[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY]); [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY]);
config_req.ss_frequency.cfreq2 = 0;
if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2])
config_req.ss_frequency.cfreq2 = nla_get_u32(tb
[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2]);
if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]) { if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]) {
status = convert_spectral_mode_nl_to_internal(nla_get_u32(tb status = convert_spectral_mode_nl_to_internal(nla_get_u32(tb
[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]), &sscan_mode); [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]), &sscan_mode);
@@ -645,7 +653,11 @@ int wlan_cfg80211_spectral_scan_get_config(struct wiphy *wiphy,
sconfig->ss_short_report) || sconfig->ss_short_report) ||
nla_put_u32(skb, nla_put_u32(skb,
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY, QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY,
sconfig->ss_frequency)) sconfig->ss_frequency.cfreq1) ||
nla_put_u32(skb,
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2,
sconfig->ss_frequency.cfreq2))
goto fail; goto fail;
sscan_req.ss_mode = sscan_mode; sscan_req.ss_mode = sscan_mode;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2011,2017-2020 The Linux Foundation. All rights reserved.
* *
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
@@ -126,6 +126,7 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
enum spectral_scan_mode smode = sscan_req->ss_mode; enum spectral_scan_mode smode = sscan_req->ss_mode;
enum spectral_cp_error_code *err; enum spectral_cp_error_code *err;
QDF_STATUS ret; QDF_STATUS ret;
struct spectral_cp_param param;
if (!pdev) { if (!pdev) {
spectral_err("PDEV is NULL!"); spectral_err("PDEV is NULL!");
@@ -142,191 +143,172 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
err = &sscan_req->config_req.sscan_err_code; err = &sscan_req->config_req.sscan_err_code;
sp_in = &sscan_req->config_req.sscan_config; sp_in = &sscan_req->config_req.sscan_config;
if (sp_in->ss_count != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_count != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_SCAN_COUNT;
param.value = sp_in->ss_count;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_SCAN_COUNT,
sp_in->ss_count, smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_fft_period != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_fft_period != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_FFT_PERIOD;
param.value = sp_in->ss_fft_period;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_FFT_PERIOD,
sp_in->ss_fft_period,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_period != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_period != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_SCAN_PERIOD;
param.value = sp_in->ss_period;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_SCAN_PERIOD,
sp_in->ss_period, smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_short_report != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_short_report != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_SHORT_REPORT;
param.value = (uint32_t)sp_in->ss_short_report ? 1 : 0;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_SHORT_REPORT,
(uint32_t)
sp_in->ss_short_report ? 1 : 0,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_spectral_pri != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_spectral_pri != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_SPECT_PRI;
param.value = (uint32_t)sp_in->ss_spectral_pri;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_SPECT_PRI,
(uint32_t)
(sp_in->ss_spectral_pri),
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_fft_size != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_fft_size != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_FFT_SIZE;
param.value = sp_in->ss_fft_size;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_FFT_SIZE,
sp_in->ss_fft_size,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_gc_ena != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_gc_ena != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_GC_ENA;
param.value = sp_in->ss_gc_ena;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_GC_ENA,
sp_in->ss_gc_ena,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_restart_ena != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_restart_ena != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_RESTART_ENA;
param.value = sp_in->ss_restart_ena;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_RESTART_ENA,
sp_in->ss_restart_ena,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_noise_floor_ref != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_noise_floor_ref != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_NOISE_FLOOR_REF;
param.value = sp_in->ss_noise_floor_ref;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_NOISE_FLOOR_REF,
sp_in->ss_noise_floor_ref,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_init_delay != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_init_delay != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_INIT_DELAY;
param.value = sp_in->ss_init_delay;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_INIT_DELAY,
sp_in->ss_init_delay,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_nb_tone_thr != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_nb_tone_thr != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_NB_TONE_THR;
param.value = sp_in->ss_nb_tone_thr;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_NB_TONE_THR,
sp_in->ss_nb_tone_thr,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_str_bin_thr != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_str_bin_thr != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_STR_BIN_THR;
param.value = sp_in->ss_str_bin_thr;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_STR_BIN_THR,
sp_in->ss_str_bin_thr,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_wb_rpt_mode != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_wb_rpt_mode != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_WB_RPT_MODE;
param.value = sp_in->ss_wb_rpt_mode;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_WB_RPT_MODE,
sp_in->ss_wb_rpt_mode,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_rssi_rpt_mode != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_rssi_rpt_mode != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_RSSI_RPT_MODE;
param.value = sp_in->ss_rssi_rpt_mode;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_RSSI_RPT_MODE,
sp_in->ss_rssi_rpt_mode,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_rssi_thr != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_rssi_thr != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_RSSI_THR;
param.value = sp_in->ss_rssi_thr;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_RSSI_THR,
sp_in->ss_rssi_thr,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_pwr_format != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_pwr_format != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_PWR_FORMAT;
param.value = sp_in->ss_pwr_format;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_PWR_FORMAT,
sp_in->ss_pwr_format,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_rpt_mode != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_rpt_mode != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_RPT_MODE;
param.value = sp_in->ss_rpt_mode;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_RPT_MODE,
sp_in->ss_rpt_mode,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_bin_scale != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_bin_scale != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_BIN_SCALE;
param.value = sp_in->ss_bin_scale;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_BIN_SCALE,
sp_in->ss_bin_scale,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
if (sp_in->ss_dbm_adj != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_dbm_adj != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_DBM_ADJ;
param.value = sp_in->ss_dbm_adj;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_DBM_ADJ,
sp_in->ss_dbm_adj,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
@@ -349,22 +331,21 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
spectral_err("Invalid Spectral Chainmask - Inactive Rx antenna chain cannot be an active spectral chain"); spectral_err("Invalid Spectral Chainmask - Inactive Rx antenna chain cannot be an active spectral chain");
goto bad; goto bad;
} else { } else {
param.id = SPECTRAL_PARAM_CHN_MASK;
param.value = sp_in->ss_chn_mask;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_CHN_MASK,
sp_in->ss_chn_mask,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }
} }
if (sp_in->ss_frequency != SPECTRAL_PHYERR_PARAM_NOVAL) { if (sp_in->ss_frequency.cfreq1 != SPECTRAL_PHYERR_PARAM_NOVAL) {
param.id = SPECTRAL_PARAM_FREQUENCY;
param.freq.cfreq1 = sp_in->ss_frequency.cfreq1;
param.freq.cfreq2 = sp_in->ss_frequency.cfreq2;
ret = sc->sptrlc_set_spectral_config ret = sc->sptrlc_set_spectral_config
(pdev, (pdev, &param, smode, err);
SPECTRAL_PARAM_FREQUENCY,
sp_in->ss_frequency,
smode, err);
if (QDF_IS_STATUS_ERROR(ret)) if (QDF_IS_STATUS_ERROR(ret))
goto bad; goto bad;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
* *
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
@@ -132,8 +132,7 @@ struct spectral_context {
void (*sptrlc_pdev_spectral_deinit)(struct wlan_objmgr_pdev *pdev); void (*sptrlc_pdev_spectral_deinit)(struct wlan_objmgr_pdev *pdev);
QDF_STATUS (*sptrlc_set_spectral_config) QDF_STATUS (*sptrlc_set_spectral_config)
(struct wlan_objmgr_pdev *pdev, (struct wlan_objmgr_pdev *pdev,
const uint32_t threshtype, const struct spectral_cp_param *param,
const uint32_t value,
const enum spectral_scan_mode smode, const enum spectral_scan_mode smode,
enum spectral_cp_error_code *err); enum spectral_cp_error_code *err);
QDF_STATUS (*sptrlc_get_spectral_config) QDF_STATUS (*sptrlc_get_spectral_config)

View File

@@ -172,6 +172,21 @@ enum spectral_cap_hw_gen {
SPECTRAL_CAP_HW_GEN_3 = 2, SPECTRAL_CAP_HW_GEN_3 = 2,
}; };
/**
* struct spectral_config_frequency - Spectral scan frequency
* @cfreq1: Center frequency (in MHz) of the span of interest(primary 80 MHz
* span for 80 + 80 agile scan request) or center frequency (in MHz)
* of any WLAN channel in the span of interest.
* @cfreq2: Applicable only for Agile Spectral scan request in 80+80 MHz mode.
* For 80+80 mode it represents the center frequency (in MHz) of the
* secondary 80 MHz span of interest or center frequency (in MHz) of
* any WLAN channel in the secondary 80 MHz span of interest.
*/
struct spectral_config_frequency {
uint32_t cfreq1;
uint32_t cfreq2;
};
/** /**
* struct spectral_config - spectral config parameters * struct spectral_config - spectral config parameters
* @ss_fft_period: Skip interval for FFT reports * @ss_fft_period: Skip interval for FFT reports
@@ -236,9 +251,16 @@ enum spectral_cap_hw_gen {
* Not applicable. Spectral scan would happen in the * Not applicable. Spectral scan would happen in the
* operating span. * operating span.
* Agile mode:- * Agile mode:-
* Center frequency (in MHz) of the interested span * cfreq1 represents the center frequency (in MHz) of
* or center frequency (in MHz) of any WLAN channel * the span of interest(primary 80 MHz span for 80 + 80
* in the interested span. * agile scan request) or center frequency (in MHz) of
* any WLAN channel in the span of interest. cfreq2 is
* applicable only for Agile Spectral scan request in
* 80+80 MHz mode. For 80+80 mode it represents the
* center frequency (in MHz) of the secondary 80 MHz
* span of interest or center frequency (in MHz) of
* any WLAN channel in the secondary 80 MHz span of
* interest.
*/ */
struct spectral_config { struct spectral_config {
uint16_t ss_fft_period; uint16_t ss_fft_period;
@@ -265,7 +287,7 @@ struct spectral_config {
int8_t ss_nf_cal[AH_MAX_CHAINS * 2]; int8_t ss_nf_cal[AH_MAX_CHAINS * 2];
int8_t ss_nf_pwr[AH_MAX_CHAINS * 2]; int8_t ss_nf_pwr[AH_MAX_CHAINS * 2];
int32_t ss_nf_temp_data; int32_t ss_nf_temp_data;
uint32_t ss_frequency; struct spectral_config_frequency ss_frequency;
}; };
/** /**
@@ -526,9 +548,13 @@ struct spectral_samp_data {
* @freq: Operating frequency in MHz * @freq: Operating frequency in MHz
* @vhtop_ch_freq_seg1: VHT Segment 1 centre frequency in MHz * @vhtop_ch_freq_seg1: VHT Segment 1 centre frequency in MHz
* @vhtop_ch_freq_seg2: VHT Segment 2 centre frequency in MHz * @vhtop_ch_freq_seg2: VHT Segment 2 centre frequency in MHz
* @agile_freq: Center frequency in MHz of the entire span across which * @agile_freq1: Center frequency in MHz of the entire span(for 80+80 MHz
* agile Scan it is primary 80 MHz span) across which
* Agile Spectral is carried out. Applicable only for Agile * Agile Spectral is carried out. Applicable only for Agile
* Spectral samples. * Spectral samples.
* @agile_freq2: Center frequency in MHz of the secondary 80 MHz span
* across which Agile Spectral is carried out. Applicable
* only for Agile Spectral samples in 80+80 MHz mode.
* @freq_loading: How busy was the channel * @freq_loading: How busy was the channel
* @dcs_enabled: Whether DCS is enabled * @dcs_enabled: Whether DCS is enabled
* @int_type: Interference type indicated by DCS * @int_type: Interference type indicated by DCS
@@ -540,7 +566,8 @@ struct spectral_samp_msg {
uint16_t freq; uint16_t freq;
uint16_t vhtop_ch_freq_seg1; uint16_t vhtop_ch_freq_seg1;
uint16_t vhtop_ch_freq_seg2; uint16_t vhtop_ch_freq_seg2;
uint16_t agile_freq; uint16_t agile_freq1;
uint16_t agile_freq2;
uint16_t freq_loading; uint16_t freq_loading;
uint16_t dcs_enabled; uint16_t dcs_enabled;
enum dcs_int_type int_type; enum dcs_int_type int_type;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2011,2017-2020 The Linux Foundation. All rights reserved.
* *
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
@@ -242,6 +242,21 @@ enum spectral_dma_debug {
SPECTRAL_DMA_BUFFER_DEBUG, SPECTRAL_DMA_BUFFER_DEBUG,
}; };
/**
* struct spectral_cp_param - Spectral control path data structure which
* contains parameter and its value
* @id: Parameter ID
* @value: Single parameter value
* @freq: Spectral scan frequency
*/
struct spectral_cp_param {
uint32_t id;
union {
uint32_t value;
struct spectral_config_frequency freq;
};
};
/** /**
* struct spectral_chan_stats - channel status info * struct spectral_chan_stats - channel status info
* @cycle_count: Cycle count * @cycle_count: Cycle count

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
* *
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
@@ -68,8 +68,7 @@ void tgt_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev);
/** /**
* tgt_set_spectral_config() - Set spectral config * tgt_set_spectral_config() - Set spectral config
* @pdev: Pointer to pdev object * @pdev: Pointer to pdev object
* @threshtype: spectral parameter type * @param: Pointer object describing Spectral parameter
* @value: Value to be configured for the given spectral parameter
* @smode: Spectral scan mode * @smode: Spectral scan mode
* @err: Spectral control path error code * @err: Spectral control path error code
* *
@@ -78,8 +77,7 @@ void tgt_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev);
* Return: QDF_STATUS_SUCCESS on success, else QDF_STATUS_E_FAILURE * Return: QDF_STATUS_SUCCESS on success, else QDF_STATUS_E_FAILURE
*/ */
QDF_STATUS tgt_set_spectral_config(struct wlan_objmgr_pdev *pdev, QDF_STATUS tgt_set_spectral_config(struct wlan_objmgr_pdev *pdev,
const u_int32_t threshtype, const struct spectral_cp_param *param,
const u_int32_t value,
const enum spectral_scan_mode smode, const enum spectral_scan_mode smode,
enum spectral_cp_error_code *err); enum spectral_cp_error_code *err);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011,2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2011,2017-2020 The Linux Foundation. All rights reserved.
* *
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
@@ -86,7 +86,7 @@ tgt_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev)
QDF_STATUS QDF_STATUS
tgt_set_spectral_config(struct wlan_objmgr_pdev *pdev, tgt_set_spectral_config(struct wlan_objmgr_pdev *pdev,
const u_int32_t threshtype, const u_int32_t value, const struct spectral_cp_param *param,
const enum spectral_scan_mode smode, const enum spectral_scan_mode smode,
enum spectral_cp_error_code *err) enum spectral_cp_error_code *err)
{ {
@@ -94,7 +94,7 @@ tgt_set_spectral_config(struct wlan_objmgr_pdev *pdev,
psoc = wlan_pdev_get_psoc(pdev); psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_set_spectral_config( return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_set_spectral_config(
pdev, threshtype, value, smode, err); pdev, param, smode, err);
} }
QDF_STATUS QDF_STATUS

View File

@@ -137,7 +137,8 @@ target_if_send_vdev_spectral_configure_cmd(struct target_if_spectral *spectral,
sparam.dbm_adj = param->ss_dbm_adj; sparam.dbm_adj = param->ss_dbm_adj;
sparam.chn_mask = param->ss_chn_mask; sparam.chn_mask = param->ss_chn_mask;
sparam.mode = smode; sparam.mode = smode;
sparam.center_freq = param->ss_frequency; sparam.center_freq = param->ss_frequency.cfreq1;
sparam.chan_width = spectral->ch_width[smode];
return spectral->param_wmi_cmd_ops.wmi_spectral_configure_cmd_send( return spectral->param_wmi_cmd_ops.wmi_spectral_configure_cmd_send(
GET_WMI_HDL_FROM_PDEV(pdev), &sparam); GET_WMI_HDL_FROM_PDEV(pdev), &sparam);
@@ -291,7 +292,9 @@ target_if_spectral_info_init_defaults(struct target_if_spectral *spectral,
info->osps_cache.osc_params.ss_fft_period = info->osps_cache.osc_params.ss_fft_period =
SPECTRAL_SCAN_FFT_PERIOD_DEFAULT; SPECTRAL_SCAN_FFT_PERIOD_DEFAULT;
info->osps_cache.osc_params.ss_frequency = info->osps_cache.osc_params.ss_frequency.cfreq1 =
SPECTRAL_SCAN_FREQUENCY_DEFAULT;
info->osps_cache.osc_params.ss_frequency.cfreq2 =
SPECTRAL_SCAN_FREQUENCY_DEFAULT; SPECTRAL_SCAN_FREQUENCY_DEFAULT;
/* The cache is now valid */ /* The cache is now valid */
@@ -353,7 +356,7 @@ target_if_log_read_spectral_params(
const char *function_name, const char *function_name,
struct spectral_config *pparam) struct spectral_config *pparam)
{ {
spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Returning following params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\nss_frequency=%u\n", spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Returning following params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\nss_frequency1=%u\nss_frequency2=%u\n",
function_name, function_name,
pparam->ss_count, pparam->ss_count,
pparam->ss_period, pparam->ss_period,
@@ -373,7 +376,8 @@ target_if_log_read_spectral_params(
pparam->ss_bin_scale, pparam->ss_bin_scale,
pparam->ss_dbm_adj, pparam->ss_dbm_adj,
pparam->ss_chn_mask, pparam->ss_chn_mask,
pparam->ss_frequency); pparam->ss_frequency.cfreq1,
pparam->ss_frequency.cfreq2);
} }
/** /**
@@ -675,7 +679,7 @@ target_if_log_write_spectral_params(
const char *function_name, const char *function_name,
int ret) int ret)
{ {
spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\nss_frequency=%u\nstatus = %d", spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\nss_frequency1=%u\nss_frequency2=%u\nstatus = %d",
function_name, function_name,
param->ss_count, param->ss_count,
param->ss_period, param->ss_period,
@@ -695,7 +699,8 @@ target_if_log_write_spectral_params(
param->ss_bin_scale, param->ss_bin_scale,
param->ss_dbm_adj, param->ss_dbm_adj,
param->ss_chn_mask, param->ss_chn_mask,
param->ss_frequency, param->ss_frequency.cfreq1,
param->ss_frequency.cfreq2,
ret); ret);
} }
@@ -2149,6 +2154,7 @@ target_if_spectral_report_params_init(
smode = SPECTRAL_SCAN_MODE_NORMAL; smode = SPECTRAL_SCAN_MODE_NORMAL;
for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++)
rparams->fragmentation_160[smode] = false; rparams->fragmentation_160[smode] = false;
rparams->max_agile_ch_width = CH_WIDTH_80P80MHZ;
} else { } else {
rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_1; rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_1;
rparams->num_spectral_detectors = rparams->num_spectral_detectors =
@@ -2156,6 +2162,7 @@ target_if_spectral_report_params_init(
smode = SPECTRAL_SCAN_MODE_NORMAL; smode = SPECTRAL_SCAN_MODE_NORMAL;
for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++)
rparams->fragmentation_160[smode] = true; rparams->fragmentation_160[smode] = true;
rparams->max_agile_ch_width = CH_WIDTH_80MHZ;
} }
switch (rparams->version) { switch (rparams->version) {
@@ -2414,28 +2421,80 @@ target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev)
/* target_if_spectral_find_agile_width() - Given a channel width enum, find the /* target_if_spectral_find_agile_width() - Given a channel width enum, find the
* corresponding translation for Agile channel width. * corresponding translation for Agile channel width.
* Translation schema of different operating modes: * @spectral: pointer to Spectral object
* 20 -> 20, 40 -> 40, (80 & 160 & 80_80) -> 80. * @chwidth: operating channel width
* @chwidth: Channel width enum. * @is_80_80_agile: Indicates an 80+80 agile Scan request
* *
* Return: The translated channel width enum. * Return: The translated channel width enum.
*/ */
static enum phy_ch_width static enum phy_ch_width
target_if_spectral_find_agile_width(enum phy_ch_width chwidth) target_if_spectral_find_agile_width(struct target_if_spectral *spectral,
enum phy_ch_width chwidth,
bool is_80_80_agile)
{ {
switch (chwidth) { enum phy_ch_width agile_width;
case CH_WIDTH_20MHZ: struct wlan_objmgr_pdev *pdev;
return CH_WIDTH_20MHZ; struct wlan_objmgr_psoc *psoc;
case CH_WIDTH_40MHZ:
return CH_WIDTH_40MHZ; if (!spectral) {
case CH_WIDTH_80MHZ: spectral_err("Spectral object is null");
case CH_WIDTH_80P80MHZ:
case CH_WIDTH_160MHZ:
return CH_WIDTH_80MHZ;
default:
spectral_err("Invalid chwidth enum %d", chwidth);
return CH_WIDTH_INVALID; return CH_WIDTH_INVALID;
} }
pdev = spectral->pdev_obj;
if (!pdev) {
spectral_err("pdev is null");
return CH_WIDTH_INVALID;
}
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
spectral_err("psoc is null");
return CH_WIDTH_INVALID;
}
switch (chwidth) {
case CH_WIDTH_20MHZ:
agile_width = CH_WIDTH_20MHZ;
break;
case CH_WIDTH_40MHZ:
agile_width = CH_WIDTH_40MHZ;
break;
case CH_WIDTH_80MHZ:
agile_width = CH_WIDTH_80MHZ;
break;
case CH_WIDTH_80P80MHZ:
if (wlan_psoc_nif_fw_ext_cap_get(psoc,
WLAN_SOC_RESTRICTED_80P80_SUPPORT) && !is_80_80_agile)
agile_width = CH_WIDTH_160MHZ;
else
agile_width = CH_WIDTH_80P80MHZ;
if (agile_width > spectral->rparams.max_agile_ch_width)
agile_width = spectral->rparams.max_agile_ch_width;
break;
case CH_WIDTH_160MHZ:
if (wlan_psoc_nif_fw_ext_cap_get(psoc,
WLAN_SOC_RESTRICTED_80P80_SUPPORT) && is_80_80_agile)
agile_width = CH_WIDTH_80P80MHZ;
else
agile_width = CH_WIDTH_160MHZ;
if (agile_width > spectral->rparams.max_agile_ch_width)
agile_width = spectral->rparams.max_agile_ch_width;
break;
default:
spectral_err("Invalid channel width %d", chwidth);
agile_width = CH_WIDTH_INVALID;
break;
}
return agile_width;
} }
/** /**
@@ -2504,6 +2563,7 @@ target_if_is_center_freq_of_any_chan(struct wlan_objmgr_pdev *pdev,
* WLAN channel center frequency * WLAN channel center frequency
* *
* @spectral: Pointer to Spectral object * @spectral: Pointer to Spectral object
* @ch_width: Channel width array
* @chan_freq: Center frequency of a WLAN channel * @chan_freq: Center frequency of a WLAN channel
* @center_freq: Pointer to center frequency * @center_freq: Pointer to center frequency
* *
@@ -2511,11 +2571,10 @@ target_if_is_center_freq_of_any_chan(struct wlan_objmgr_pdev *pdev,
*/ */
static QDF_STATUS static QDF_STATUS
target_if_calculate_center_freq(struct target_if_spectral *spectral, target_if_calculate_center_freq(struct target_if_spectral *spectral,
enum phy_ch_width *ch_width,
uint16_t chan_freq, uint16_t chan_freq,
uint16_t *center_freq) uint16_t *center_freq)
{ {
struct wlan_objmgr_vdev *vdev;
enum phy_ch_width ch_width;
enum phy_ch_width agile_ch_width; enum phy_ch_width agile_ch_width;
if (!spectral) { if (!spectral) {
@@ -2523,30 +2582,33 @@ target_if_calculate_center_freq(struct target_if_spectral *spectral,
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
if (!ch_width) {
spectral_err("Channel width array is null");
return QDF_STATUS_E_INVAL;
}
agile_ch_width = ch_width[SPECTRAL_SCAN_MODE_AGILE];
if (!center_freq) { if (!center_freq) {
spectral_err("center_freq argument is null"); spectral_err("center_freq argument is null");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
vdev = target_if_spectral_get_vdev(spectral);
if (!vdev) {
spectral_err("vdev is NULL");
return QDF_STATUS_E_FAILURE;
}
ch_width = target_if_vdev_get_ch_width(vdev);
wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
agile_ch_width = target_if_spectral_find_agile_width(ch_width);
if (agile_ch_width == CH_WIDTH_20MHZ) { if (agile_ch_width == CH_WIDTH_20MHZ) {
*center_freq = chan_freq; *center_freq = chan_freq;
} else { } else {
uint16_t start_freq; uint16_t start_freq;
uint16_t end_freq; uint16_t end_freq;
const struct bonded_channel_freq *bonded_chan_ptr = NULL; const struct bonded_channel_freq *bonded_chan_ptr = NULL;
enum channel_state state;
wlan_reg_get_5g_bonded_channel_and_state_for_freq state = wlan_reg_get_5g_bonded_channel_and_state_for_freq
(spectral->pdev_obj, chan_freq, agile_ch_width, (spectral->pdev_obj, chan_freq, agile_ch_width,
&bonded_chan_ptr); &bonded_chan_ptr);
if (state == CHANNEL_STATE_DISABLE ||
state == CHANNEL_STATE_INVALID) {
spectral_err("Channel state is disable or invalid");
return QDF_STATUS_E_FAILURE;
}
if (!bonded_chan_ptr) { if (!bonded_chan_ptr) {
spectral_err("Bonded channel is not found"); spectral_err("Bonded channel is not found");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
@@ -2564,6 +2626,7 @@ target_if_calculate_center_freq(struct target_if_spectral *spectral,
* validate user provided agile center frequency * validate user provided agile center frequency
* *
* @spectral: Pointer to Spectral object * @spectral: Pointer to Spectral object
* @ch_width: Channel width array
* @center_freq: User provided agile span center frequency * @center_freq: User provided agile span center frequency
* @is_valid: Indicates whether agile span center frequency is valid * @is_valid: Indicates whether agile span center frequency is valid
* *
@@ -2571,11 +2634,10 @@ target_if_calculate_center_freq(struct target_if_spectral *spectral,
*/ */
static QDF_STATUS static QDF_STATUS
target_if_validate_center_freq(struct target_if_spectral *spectral, target_if_validate_center_freq(struct target_if_spectral *spectral,
enum phy_ch_width *ch_width,
uint16_t center_freq, uint16_t center_freq,
bool *is_valid) bool *is_valid)
{ {
struct wlan_objmgr_vdev *vdev;
enum phy_ch_width ch_width;
enum phy_ch_width agile_ch_width; enum phy_ch_width agile_ch_width;
struct wlan_objmgr_pdev *pdev; struct wlan_objmgr_pdev *pdev;
QDF_STATUS status; QDF_STATUS status;
@@ -2585,20 +2647,18 @@ target_if_validate_center_freq(struct target_if_spectral *spectral,
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
if (!ch_width) {
spectral_err("channel width array is null");
return QDF_STATUS_E_INVAL;
}
agile_ch_width = ch_width[SPECTRAL_SCAN_MODE_AGILE];
if (!is_valid) { if (!is_valid) {
spectral_err("is_valid argument is null"); spectral_err("is_valid argument is null");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
pdev = spectral->pdev_obj; pdev = spectral->pdev_obj;
vdev = target_if_spectral_get_vdev(spectral);
if (!vdev) {
spectral_err("vdev is NULL");
return QDF_STATUS_E_FAILURE;
}
ch_width = target_if_vdev_get_ch_width(vdev);
wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
agile_ch_width = target_if_spectral_find_agile_width(ch_width);
if (agile_ch_width == CH_WIDTH_20MHZ) { if (agile_ch_width == CH_WIDTH_20MHZ) {
status = target_if_is_center_freq_of_any_chan status = target_if_is_center_freq_of_any_chan
@@ -2619,11 +2679,17 @@ target_if_validate_center_freq(struct target_if_spectral *spectral,
if (is_chan) { if (is_chan) {
uint32_t calulated_center_freq; uint32_t calulated_center_freq;
enum channel_state st;
wlan_reg_get_5g_bonded_channel_and_state_for_freq st = wlan_reg_get_5g_bonded_channel_and_state_for_freq
(pdev, center_freq + FREQ_OFFSET_10MHZ, (pdev, center_freq + FREQ_OFFSET_10MHZ,
agile_ch_width, agile_ch_width,
&bonded_chan_ptr); &bonded_chan_ptr);
if (st == CHANNEL_STATE_DISABLE ||
st == CHANNEL_STATE_INVALID) {
spectral_err("Channel state disable/invalid");
return QDF_STATUS_E_FAILURE;
}
if (!bonded_chan_ptr) { if (!bonded_chan_ptr) {
spectral_err("Bonded channel is not found"); spectral_err("Bonded channel is not found");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
@@ -2645,7 +2711,8 @@ target_if_validate_center_freq(struct target_if_spectral *spectral,
* check whether agile span overlaps with current operating band. * check whether agile span overlaps with current operating band.
* *
* @spectral: Pointer to Spectral object * @spectral: Pointer to Spectral object
* @ss_frequency: Agile span center frequency * @ch_width: Channel width array
* @center_freq: Agile span center frequency
* @is_overlapping: Indicates whether Agile span overlaps with operating span * @is_overlapping: Indicates whether Agile span overlaps with operating span
* *
* Helper routine to check whether agile span overlaps with current * Helper routine to check whether agile span overlaps with current
@@ -2656,10 +2723,11 @@ target_if_validate_center_freq(struct target_if_spectral *spectral,
static QDF_STATUS static QDF_STATUS
target_if_is_agile_span_overlap_with_operating_span target_if_is_agile_span_overlap_with_operating_span
(struct target_if_spectral *spectral, (struct target_if_spectral *spectral,
uint32_t ss_frequency, enum phy_ch_width *ch_width,
struct spectral_config_frequency *center_freq,
bool *is_overlapping) bool *is_overlapping)
{ {
enum phy_ch_width ch_width; enum phy_ch_width op_ch_width;
enum phy_ch_width agile_ch_width; enum phy_ch_width agile_ch_width;
const struct bonded_channel_freq *bonded_chan_ptr = NULL; const struct bonded_channel_freq *bonded_chan_ptr = NULL;
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
@@ -2682,29 +2750,53 @@ target_if_is_agile_span_overlap_with_operating_span
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
if (!ch_width) {
spectral_err("channel width array is null");
return QDF_STATUS_E_FAILURE;
}
op_ch_width = ch_width[SPECTRAL_SCAN_MODE_NORMAL];
if (op_ch_width == CH_WIDTH_INVALID) {
spectral_err("Invalid channel width");
return QDF_STATUS_E_INVAL;
}
agile_ch_width = ch_width[SPECTRAL_SCAN_MODE_AGILE];
if (agile_ch_width == CH_WIDTH_INVALID) {
spectral_err("Invalid channel width");
return QDF_STATUS_E_INVAL;
}
if (!is_overlapping) { if (!is_overlapping) {
spectral_err("Argument(is_overlapping) is NULL"); spectral_err("Argument(is_overlapping) is NULL");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
*is_overlapping = false;
vdev = target_if_spectral_get_vdev(spectral); vdev = target_if_spectral_get_vdev(spectral);
if (!vdev) { if (!vdev) {
spectral_err("vdev is NULL"); spectral_err("vdev is NULL");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
ch_width = target_if_vdev_get_ch_width(vdev);
chan_freq = target_if_vdev_get_chan_freq(vdev); chan_freq = target_if_vdev_get_chan_freq(vdev);
cfreq2 = target_if_vdev_get_chan_freq_seg2(vdev); cfreq2 = target_if_vdev_get_chan_freq_seg2(vdev);
wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
if (cfreq2 < 0) if (cfreq2 < 0) {
spectral_err("cfreq2 is invalid");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
}
if (ch_width == CH_WIDTH_20MHZ) { if (op_ch_width == CH_WIDTH_20MHZ) {
op_start_freq = chan_freq - FREQ_OFFSET_10MHZ; op_start_freq = chan_freq - FREQ_OFFSET_10MHZ;
op_end_freq = chan_freq + FREQ_OFFSET_10MHZ; op_end_freq = chan_freq + FREQ_OFFSET_10MHZ;
} else { } else {
wlan_reg_get_5g_bonded_channel_and_state_for_freq enum channel_state state;
(pdev, chan_freq, ch_width, &bonded_chan_ptr);
state = wlan_reg_get_5g_bonded_channel_and_state_for_freq
(pdev, chan_freq, op_ch_width, &bonded_chan_ptr);
if (state == CHANNEL_STATE_DISABLE ||
state == CHANNEL_STATE_INVALID) {
spectral_err("Channel state is disable or invalid");
return QDF_STATUS_E_FAILURE;
}
if (!bonded_chan_ptr) { if (!bonded_chan_ptr) {
spectral_err("Bonded channel is not found"); spectral_err("Bonded channel is not found");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
@@ -2713,29 +2805,60 @@ target_if_is_agile_span_overlap_with_operating_span
op_end_freq = bonded_chan_ptr->end_freq - FREQ_OFFSET_10MHZ; op_end_freq = bonded_chan_ptr->end_freq - FREQ_OFFSET_10MHZ;
} }
agile_ch_width = target_if_spectral_find_agile_width(ch_width); if (agile_ch_width == CH_WIDTH_80P80MHZ) {
if (agile_ch_width == CH_WIDTH_INVALID) agile_start_freq = center_freq->cfreq1 - FREQ_OFFSET_40MHZ;
return QDF_STATUS_E_FAILURE; agile_end_freq = center_freq->cfreq1 + FREQ_OFFSET_40MHZ;
agile_start_freq = ss_frequency - if (agile_end_freq > op_start_freq &&
(wlan_reg_get_bw_value(agile_ch_width) >> 1); op_end_freq > agile_start_freq)
agile_end_freq = ss_frequency +
(wlan_reg_get_bw_value(agile_ch_width) >> 1);
if (agile_end_freq <= op_start_freq || op_end_freq <= agile_start_freq)
*is_overlapping = false;
else
*is_overlapping = true; *is_overlapping = true;
/* Use non zero cfreq2 to identify 80p80 */ agile_start_freq = center_freq->cfreq2 - FREQ_OFFSET_40MHZ;
if (cfreq2) { agile_end_freq = center_freq->cfreq2 + FREQ_OFFSET_40MHZ;
if (agile_end_freq > op_start_freq &&
op_end_freq > agile_start_freq)
*is_overlapping = true;
} else {
agile_start_freq = center_freq->cfreq1 -
(wlan_reg_get_bw_value(agile_ch_width) >> 1);
agile_end_freq = center_freq->cfreq1 +
(wlan_reg_get_bw_value(agile_ch_width) >> 1);
if (agile_end_freq > op_start_freq &&
op_end_freq > agile_start_freq)
*is_overlapping = true;
}
if (op_ch_width == CH_WIDTH_80P80MHZ) {
uint32_t sec80_start_feq; uint32_t sec80_start_feq;
uint32_t sec80_end_freq; uint32_t sec80_end_freq;
sec80_start_feq = cfreq2 - 40; sec80_start_feq = cfreq2 - FREQ_OFFSET_40MHZ;
sec80_end_freq = cfreq2 + 40; sec80_end_freq = cfreq2 + FREQ_OFFSET_40MHZ;
if ((agile_end_freq > sec80_start_feq) && if (agile_ch_width == CH_WIDTH_80P80MHZ) {
(sec80_end_freq > agile_start_freq)) agile_start_freq =
center_freq->cfreq1 - FREQ_OFFSET_40MHZ;
agile_end_freq =
center_freq->cfreq1 + FREQ_OFFSET_40MHZ;
if (agile_end_freq > sec80_start_feq &&
sec80_end_freq > agile_start_freq)
*is_overlapping = true; *is_overlapping = true;
agile_start_freq =
center_freq->cfreq2 - FREQ_OFFSET_40MHZ;
agile_end_freq =
center_freq->cfreq2 + FREQ_OFFSET_40MHZ;
if (agile_end_freq > sec80_start_feq &&
sec80_end_freq > agile_start_freq)
*is_overlapping = true;
} else {
agile_start_freq = center_freq->cfreq1 -
(wlan_reg_get_bw_value(agile_ch_width) >> 1);
agile_end_freq = center_freq->cfreq1 +
(wlan_reg_get_bw_value(agile_ch_width) >> 1);
if (agile_end_freq > sec80_start_feq &&
sec80_end_freq > agile_start_freq)
*is_overlapping = true;
}
} }
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
@@ -2746,15 +2869,29 @@ target_if_is_agile_span_overlap_with_operating_span
* populate channel width for different Spectral modes * populate channel width for different Spectral modes
* *
* @spectral: Pointer to Spectral object * @spectral: Pointer to Spectral object
* @ch_width: Channel width array
* @is_80_80_agile: Indicates whether 80+80 agile scan is requested
* *
* Helper routine to populate channel width for different Spectral modes * Helper routine to populate channel width for different Spectral modes
* *
* Return: QDF_STATUS * Return: QDF_STATUS
*/ */
static QDF_STATUS static QDF_STATUS
target_if_spectral_populate_chwidth(struct target_if_spectral *spectral) { target_if_spectral_populate_chwidth(struct target_if_spectral *spectral,
enum phy_ch_width *ch_width,
bool is_80_80_agile) {
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
enum phy_ch_width vdev_ch_with; enum spectral_scan_mode smode;
enum phy_ch_width vdev_ch_width;
smode = SPECTRAL_SCAN_MODE_NORMAL;
for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++)
ch_width[smode] = CH_WIDTH_INVALID;
if (!spectral) {
spectral_err("Spectral object is null");
return QDF_STATUS_E_INVAL;
}
vdev = target_if_spectral_get_vdev(spectral); vdev = target_if_spectral_get_vdev(spectral);
if (!vdev) { if (!vdev) {
@@ -2762,15 +2899,17 @@ target_if_spectral_populate_chwidth(struct target_if_spectral *spectral) {
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
vdev_ch_with = target_if_vdev_get_ch_width(vdev); vdev_ch_width = target_if_vdev_get_ch_width(vdev);
wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
if (vdev_ch_with == CH_WIDTH_INVALID) { if (vdev_ch_width == CH_WIDTH_INVALID) {
spectral_err("Invalid channel width %d", vdev_ch_with); spectral_err("Invalid channel width %d", vdev_ch_width);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] = vdev_ch_with;
spectral->ch_width[SPECTRAL_SCAN_MODE_AGILE] = ch_width[SPECTRAL_SCAN_MODE_NORMAL] = vdev_ch_width;
target_if_spectral_find_agile_width(vdev_ch_with); ch_width[SPECTRAL_SCAN_MODE_AGILE] =
target_if_spectral_find_agile_width(spectral, vdev_ch_width,
is_80_80_agile);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
@@ -2778,8 +2917,7 @@ target_if_spectral_populate_chwidth(struct target_if_spectral *spectral) {
/** /**
* _target_if_set_spectral_config() - Set spectral config * _target_if_set_spectral_config() - Set spectral config
* @spectral: Pointer to spectral object * @spectral: Pointer to spectral object
* @threshtype: config type * @param: Spectral parameter id and value
* @value: config value
* @smode: Spectral scan mode * @smode: Spectral scan mode
* @err: Spectral error code * @err: Spectral error code
* *
@@ -2789,7 +2927,7 @@ target_if_spectral_populate_chwidth(struct target_if_spectral *spectral) {
*/ */
static QDF_STATUS static QDF_STATUS
_target_if_set_spectral_config(struct target_if_spectral *spectral, _target_if_set_spectral_config(struct target_if_spectral *spectral,
const uint32_t threshtype, const uint32_t value, const struct spectral_cp_param *param,
const enum spectral_scan_mode smode, const enum spectral_scan_mode smode,
enum spectral_cp_error_code *err) enum spectral_cp_error_code *err)
{ {
@@ -2801,6 +2939,9 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
uint16_t agile_cfreq; uint16_t agile_cfreq;
bool is_valid_chan; bool is_valid_chan;
struct spectral_param_min_max *param_min_max; struct spectral_param_min_max *param_min_max;
enum phy_ch_width ch_width[SPECTRAL_SCAN_MODE_MAX];
enum spectral_scan_mode m;
struct spectral_config_frequency center_freq = {0};
if (!err) { if (!err) {
spectral_err("Error code argument is null"); spectral_err("Error code argument is null");
@@ -2809,6 +2950,11 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
} }
*err = SPECTRAL_SCAN_ERR_INVALID; *err = SPECTRAL_SCAN_ERR_INVALID;
if (!param) {
spectral_err("Parameter object is null");
return QDF_STATUS_E_FAILURE;
}
if (!spectral) { if (!spectral) {
spectral_err("spectral object is NULL"); spectral_err("spectral object is NULL");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
@@ -2823,6 +2969,9 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
} }
sparams = &spectral->params[smode]; sparams = &spectral->params[smode];
m = SPECTRAL_SCAN_MODE_NORMAL;
for (; m < SPECTRAL_SCAN_MODE_MAX; m++)
ch_width[m] = CH_WIDTH_INVALID;
if (!spectral->params_valid[smode]) { if (!spectral->params_valid[smode]) {
target_if_spectral_info_read(spectral, target_if_spectral_info_read(spectral,
@@ -2833,90 +2982,115 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
spectral->params_valid[smode] = true; spectral->params_valid[smode] = true;
} }
switch (threshtype) { switch (param->id) {
case SPECTRAL_PARAM_FFT_PERIOD: case SPECTRAL_PARAM_FFT_PERIOD:
sparams->ss_fft_period = value; sparams->ss_fft_period = param->value;
break; break;
case SPECTRAL_PARAM_SCAN_PERIOD: case SPECTRAL_PARAM_SCAN_PERIOD:
sparams->ss_period = value; sparams->ss_period = param->value;
break; break;
case SPECTRAL_PARAM_SCAN_COUNT: case SPECTRAL_PARAM_SCAN_COUNT:
sparams->ss_count = value; sparams->ss_count = param->value;
break; break;
case SPECTRAL_PARAM_SHORT_REPORT: case SPECTRAL_PARAM_SHORT_REPORT:
sparams->ss_short_report = (!!value) ? true : false; sparams->ss_short_report = (!!param->value) ? true : false;
break; break;
case SPECTRAL_PARAM_SPECT_PRI: case SPECTRAL_PARAM_SPECT_PRI:
sparams->ss_spectral_pri = (!!value) ? true : false; sparams->ss_spectral_pri = (!!param->value) ? true : false;
break; break;
case SPECTRAL_PARAM_FFT_SIZE: case SPECTRAL_PARAM_FFT_SIZE:
status = target_if_spectral_populate_chwidth(spectral); status = target_if_spectral_populate_chwidth
(spectral, ch_width, spectral->params
[SPECTRAL_SCAN_MODE_AGILE].ss_frequency.cfreq2 > 0);
if (QDF_IS_STATUS_ERROR(status)) if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
if ((value < param_min_max->fft_size_min) || if ((param->value < param_min_max->fft_size_min) ||
(value > param_min_max->fft_size_max (param->value > param_min_max->fft_size_max
[spectral->ch_width[smode]])) { [ch_width[smode]])) {
*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
sparams->ss_fft_size = value; sparams->ss_fft_size = param->value;
break; break;
case SPECTRAL_PARAM_GC_ENA: case SPECTRAL_PARAM_GC_ENA:
sparams->ss_gc_ena = !!value; sparams->ss_gc_ena = !!param->value;
break; break;
case SPECTRAL_PARAM_RESTART_ENA: case SPECTRAL_PARAM_RESTART_ENA:
sparams->ss_restart_ena = !!value; sparams->ss_restart_ena = !!param->value;
break; break;
case SPECTRAL_PARAM_NOISE_FLOOR_REF: case SPECTRAL_PARAM_NOISE_FLOOR_REF:
sparams->ss_noise_floor_ref = value; sparams->ss_noise_floor_ref = param->value;
break; break;
case SPECTRAL_PARAM_INIT_DELAY: case SPECTRAL_PARAM_INIT_DELAY:
sparams->ss_init_delay = value; sparams->ss_init_delay = param->value;
break; break;
case SPECTRAL_PARAM_NB_TONE_THR: case SPECTRAL_PARAM_NB_TONE_THR:
sparams->ss_nb_tone_thr = value; sparams->ss_nb_tone_thr = param->value;
break; break;
case SPECTRAL_PARAM_STR_BIN_THR: case SPECTRAL_PARAM_STR_BIN_THR:
sparams->ss_str_bin_thr = value; sparams->ss_str_bin_thr = param->value;
break; break;
case SPECTRAL_PARAM_WB_RPT_MODE: case SPECTRAL_PARAM_WB_RPT_MODE:
sparams->ss_wb_rpt_mode = !!value; sparams->ss_wb_rpt_mode = !!param->value;
break; break;
case SPECTRAL_PARAM_RSSI_RPT_MODE: case SPECTRAL_PARAM_RSSI_RPT_MODE:
sparams->ss_rssi_rpt_mode = !!value; sparams->ss_rssi_rpt_mode = !!param->value;
break; break;
case SPECTRAL_PARAM_RSSI_THR: case SPECTRAL_PARAM_RSSI_THR:
sparams->ss_rssi_thr = value; sparams->ss_rssi_thr = param->value;
break; break;
case SPECTRAL_PARAM_PWR_FORMAT: case SPECTRAL_PARAM_PWR_FORMAT:
sparams->ss_pwr_format = !!value; sparams->ss_pwr_format = !!param->value;
break; break;
case SPECTRAL_PARAM_RPT_MODE: case SPECTRAL_PARAM_RPT_MODE:
if ((value < SPECTRAL_PARAM_RPT_MODE_MIN) || if ((param->value < SPECTRAL_PARAM_RPT_MODE_MIN) ||
(value > SPECTRAL_PARAM_RPT_MODE_MAX)) { (param->value > SPECTRAL_PARAM_RPT_MODE_MAX)) {
*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
sparams->ss_rpt_mode = value; sparams->ss_rpt_mode = param->value;
break; break;
case SPECTRAL_PARAM_BIN_SCALE: case SPECTRAL_PARAM_BIN_SCALE:
sparams->ss_bin_scale = value; sparams->ss_bin_scale = param->value;
break; break;
case SPECTRAL_PARAM_DBM_ADJ: case SPECTRAL_PARAM_DBM_ADJ:
sparams->ss_dbm_adj = !!value; sparams->ss_dbm_adj = !!param->value;
break; break;
case SPECTRAL_PARAM_CHN_MASK: case SPECTRAL_PARAM_CHN_MASK:
sparams->ss_chn_mask = value; sparams->ss_chn_mask = param->value;
break; break;
case SPECTRAL_PARAM_FREQUENCY: case SPECTRAL_PARAM_FREQUENCY:
status = target_if_spectral_populate_chwidth(
spectral, ch_width, param->freq.cfreq2 > 0);
if (QDF_IS_STATUS_ERROR(status)) {
spectral_err("Failed to populate channel width");
return QDF_STATUS_E_FAILURE;
}
if (ch_width[smode] != CH_WIDTH_80P80MHZ &&
param->freq.cfreq2) {
*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
spectral_err("Non zero cfreq2 expected for 80p80 only");
return QDF_STATUS_E_INVAL;
}
if (ch_width[smode] == CH_WIDTH_80P80MHZ &&
!param->freq.cfreq2) {
*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
spectral_err("Non zero cfreq2 expected for 80p80");
return QDF_STATUS_E_INVAL;
}
status = target_if_is_center_freq_of_any_chan status = target_if_is_center_freq_of_any_chan
(spectral->pdev_obj, value, &is_valid_chan); (spectral->pdev_obj, param->freq.cfreq1,
&is_valid_chan);
if (QDF_IS_STATUS_ERROR(status)) if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
if (is_valid_chan) { if (is_valid_chan) {
status = target_if_calculate_center_freq(spectral, status = target_if_calculate_center_freq(
value, spectral, ch_width,
param->freq.cfreq1,
&agile_cfreq); &agile_cfreq);
if (QDF_IS_STATUS_ERROR(status)) { if (QDF_IS_STATUS_ERROR(status)) {
*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
@@ -2926,7 +3100,8 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
bool is_valid_agile_cfreq; bool is_valid_agile_cfreq;
status = target_if_validate_center_freq status = target_if_validate_center_freq
(spectral, value, &is_valid_agile_cfreq); (spectral, ch_width, param->freq.cfreq1,
&is_valid_agile_cfreq);
if (QDF_IS_STATUS_ERROR(status)) if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
@@ -2936,20 +3111,62 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
agile_cfreq = value; agile_cfreq = param->freq.cfreq1;
}
center_freq.cfreq1 = agile_cfreq;
if (ch_width[smode] == CH_WIDTH_80P80MHZ) {
status = target_if_is_center_freq_of_any_chan
(spectral->pdev_obj, param->freq.cfreq2,
&is_valid_chan);
if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE;
if (is_valid_chan) {
status = target_if_calculate_center_freq(
spectral, ch_width,
param->freq.cfreq2,
&agile_cfreq);
if (QDF_IS_STATUS_ERROR(status)) {
*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
return QDF_STATUS_E_FAILURE;
}
} else {
bool is_valid_agile_cfreq;
status = target_if_validate_center_freq
(spectral, ch_width, param->freq.cfreq2,
&is_valid_agile_cfreq);
if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE;
if (!is_valid_agile_cfreq) {
*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
spectral_err("Invalid agile center frequency");
return QDF_STATUS_E_FAILURE;
}
agile_cfreq = param->freq.cfreq2;
}
center_freq.cfreq2 = agile_cfreq;
} }
status = target_if_is_agile_span_overlap_with_operating_span status = target_if_is_agile_span_overlap_with_operating_span
(spectral, agile_cfreq, &is_overlapping); (spectral, ch_width,
&center_freq, &is_overlapping);
if (QDF_IS_STATUS_ERROR(status)) if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
if (is_overlapping) { if (is_overlapping) {
spectral_err("Agile span overlapping with current BW"); spectral_err("Agile freq %u, %u overlaps with operating span",
center_freq.cfreq1, center_freq.cfreq2);
*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE; *err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
sparams->ss_frequency = agile_cfreq;
sparams->ss_frequency.cfreq1 = center_freq.cfreq1;
sparams->ss_frequency.cfreq2 = center_freq.cfreq2;
break; break;
} }
@@ -2961,7 +3178,7 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
QDF_STATUS QDF_STATUS
target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev,
const uint32_t threshtype, const uint32_t value, const struct spectral_cp_param *param,
const enum spectral_scan_mode smode, const enum spectral_scan_mode smode,
enum spectral_cp_error_code *err) enum spectral_cp_error_code *err)
{ {
@@ -2986,34 +3203,37 @@ target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev,
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
if (!param) {
spectral_err("parameter object is NULL");
return QDF_STATUS_E_FAILURE;
}
if (smode >= SPECTRAL_SCAN_MODE_MAX) { if (smode >= SPECTRAL_SCAN_MODE_MAX) {
spectral_err("Invalid Spectral mode %u", smode); spectral_err("Invalid Spectral mode %u", smode);
*err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED; *err = SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED;
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
if (!spectral->properties[smode][threshtype].supported) { if (!spectral->properties[smode][param->id].supported) {
spectral_err("Spectral parameter(%u) unsupported for mode %u", spectral_err("Spectral parameter(%u) unsupported for mode %u",
threshtype, smode); param->id, smode);
*err = SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED; *err = SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED;
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
if (spectral->properties[smode][threshtype].common_all_modes) { if (spectral->properties[smode][param->id].common_all_modes) {
spectral_warn("Setting Spectral parameter %u for all modes", spectral_warn("Setting Spectral parameter %u for all modes",
threshtype); param->id);
for (; mode < SPECTRAL_SCAN_MODE_MAX; mode++) { for (; mode < SPECTRAL_SCAN_MODE_MAX; mode++) {
status = _target_if_set_spectral_config status = _target_if_set_spectral_config
(spectral, threshtype, value, (spectral, param, mode, err);
mode, err);
if (QDF_IS_STATUS_ERROR(status)) if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
return _target_if_set_spectral_config(spectral, threshtype, return _target_if_set_spectral_config(spectral, param, smode, err);
value, smode, err);
} }
/** /**
@@ -3405,7 +3625,10 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral,
extension_channel = p_sops->get_extension_channel(spectral); extension_channel = p_sops->get_extension_channel(spectral);
current_channel = p_sops->get_current_channel(spectral); current_channel = p_sops->get_current_channel(spectral);
status = target_if_spectral_populate_chwidth(spectral); status = target_if_spectral_populate_chwidth(
spectral, spectral->ch_width,
spectral->params[SPECTRAL_SCAN_MODE_AGILE].
ss_frequency.cfreq2 > 0);
if (QDF_IS_STATUS_ERROR(status)) { if (QDF_IS_STATUS_ERROR(status)) {
spectral_err("Failed to get channel widths"); spectral_err("Failed to get channel widths");
return 1; return 1;
@@ -4060,20 +4283,38 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev,
} }
qdf_spin_lock(&spectral->spectral_lock); qdf_spin_lock(&spectral->spectral_lock);
if (smode == SPECTRAL_SCAN_MODE_AGILE && if (smode == SPECTRAL_SCAN_MODE_AGILE) {
!spectral->params[smode].ss_frequency) { QDF_STATUS status;
bool is_overlapping;
enum phy_ch_width ch_width[SPECTRAL_SCAN_MODE_MAX];
enum spectral_scan_mode m;
enum phy_ch_width op_ch_width;
enum phy_ch_width agile_ch_width;
m = SPECTRAL_SCAN_MODE_NORMAL;
for (; m < SPECTRAL_SCAN_MODE_MAX; m++)
ch_width[m] = CH_WIDTH_INVALID;
status = target_if_spectral_populate_chwidth
(spectral, ch_width, spectral->params
[SPECTRAL_SCAN_MODE_AGILE].ss_frequency.cfreq2 > 0);
if (QDF_IS_STATUS_ERROR(status)) {
spectral_err("Failed to populate channel width");
return QDF_STATUS_E_FAILURE;
}
op_ch_width = ch_width[SPECTRAL_SCAN_MODE_NORMAL];
agile_ch_width = ch_width[SPECTRAL_SCAN_MODE_AGILE];
if (!spectral->params[smode].ss_frequency.cfreq1 ||
(agile_ch_width == CH_WIDTH_80P80MHZ &&
!spectral->params[smode].ss_frequency.cfreq2)) {
*err = SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED; *err = SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED;
qdf_spin_unlock(&spectral->spectral_lock); qdf_spin_unlock(&spectral->spectral_lock);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
if (smode == SPECTRAL_SCAN_MODE_AGILE) {
QDF_STATUS status;
bool is_overlapping;
status = target_if_is_agile_span_overlap_with_operating_span status = target_if_is_agile_span_overlap_with_operating_span
(spectral, (spectral, ch_width,
spectral->params[smode].ss_frequency, &spectral->params[smode].ss_frequency,
&is_overlapping); &is_overlapping);
if (QDF_IS_STATUS_ERROR(status)) { if (QDF_IS_STATUS_ERROR(status)) {
qdf_spin_unlock(&spectral->spectral_lock); qdf_spin_unlock(&spectral->spectral_lock);

View File

@@ -41,7 +41,8 @@
#include <spectral_defs_i.h> #include <spectral_defs_i.h>
#define FREQ_OFFSET_10MHZ 10 #define FREQ_OFFSET_10MHZ (10)
#define FREQ_OFFSET_40MHZ (40)
#ifndef SPECTRAL_USE_NL_BCAST #ifndef SPECTRAL_USE_NL_BCAST
#define SPECTRAL_USE_NL_BCAST (0) #define SPECTRAL_USE_NL_BCAST (0)
#endif #endif
@@ -411,11 +412,17 @@ struct spectral_sscan_summary_report_gen3 {
* @data: Report buffer * @data: Report buffer
* @noisefloor: Noise floor values * @noisefloor: Noise floor values
* @reset_delay: Time taken for warm reset in us * @reset_delay: Time taken for warm reset in us
* @cfreq1: center frequency 1
* @cfreq2: center frequency 2
* @ch_width: channel width
*/ */
struct spectral_report { struct spectral_report {
uint8_t *data; uint8_t *data;
int32_t noisefloor[DBR_MAX_CHAINS]; int32_t noisefloor[DBR_MAX_CHAINS];
uint32_t reset_delay; uint32_t reset_delay;
uint32_t cfreq1;
uint32_t cfreq2;
uint32_t ch_width;
}; };
#endif #endif
/* END of spectral GEN III HW specific details */ /* END of spectral GEN III HW specific details */
@@ -531,6 +538,7 @@ struct spectral_fft_bin_markers_165mhz {
* of FFT bins. * of FFT bins.
* @fragmentation_160: This indicates whether Spectral reports in 160/80p80 is * @fragmentation_160: This indicates whether Spectral reports in 160/80p80 is
* fragmented. * fragmented.
* @max_agile_ch_width: Maximum agile BW supported by the target
* @detid_mode_table: Detector ID to Spectral scan mode table * @detid_mode_table: Detector ID to Spectral scan mode table
* @num_spectral_detectors: Total number of Spectral detectors * @num_spectral_detectors: Total number of Spectral detectors
* @marker: Describes the boundaries of pri80, 5 MHz and sec80 bins * @marker: Describes the boundaries of pri80, 5 MHz and sec80 bins
@@ -540,6 +548,7 @@ struct spectral_report_params {
uint8_t ssumaary_padding_bytes; uint8_t ssumaary_padding_bytes;
uint8_t fft_report_hdr_len; uint8_t fft_report_hdr_len;
bool fragmentation_160[SPECTRAL_SCAN_MODE_MAX]; bool fragmentation_160[SPECTRAL_SCAN_MODE_MAX];
enum phy_ch_width max_agile_ch_width;
enum spectral_scan_mode detid_mode_table[SPECTRAL_DETECTOR_ID_MAX]; enum spectral_scan_mode detid_mode_table[SPECTRAL_DETECTOR_ID_MAX];
uint8_t num_spectral_detectors; uint8_t num_spectral_detectors;
struct spectral_fft_bin_markers_165mhz struct spectral_fft_bin_markers_165mhz
@@ -1110,8 +1119,13 @@ struct target_if_spectral {
* @freq: Center frequency of primary 20MHz channel in MHz * @freq: Center frequency of primary 20MHz channel in MHz
* @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz
* @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz * @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz
* @agile_freq: Center frequency in MHz of the entire span across which Agile * @agile_freq1: Center frequency in MHz of the entire span(for 80+80 MHz
* Spectral is carried out. Applicable only for Agile Spectral samples. * agile Scan it is primary 80 MHz span) across which
* Agile Spectral is carried out. Applicable only for Agile
* Spectral samples.
* @agile_freq2: Center frequency in MHz of the secondary 80 MHz span
* across which Agile Spectral is carried out. Applicable
* only for Agile Spectral samples in 80+80 MHz mode.
* @freq_loading: spectral control duty cycles * @freq_loading: spectral control duty cycles
* @noise_floor: current noise floor (except for secondary 80 segment) * @noise_floor: current noise floor (except for secondary 80 segment)
* @noise_floor_sec80: current noise floor for secondary 80 segment * @noise_floor_sec80: current noise floor for secondary 80 segment
@@ -1172,7 +1186,8 @@ struct target_if_samp_msg_params {
uint16_t freq; uint16_t freq;
uint16_t vhtop_ch_freq_seg1; uint16_t vhtop_ch_freq_seg1;
uint16_t vhtop_ch_freq_seg2; uint16_t vhtop_ch_freq_seg2;
uint16_t agile_freq; uint16_t agile_freq1;
uint16_t agile_freq2;
uint16_t freq_loading; uint16_t freq_loading;
int16_t noise_floor; int16_t noise_floor;
int16_t noise_floor_sec80; int16_t noise_floor_sec80;
@@ -1974,8 +1989,7 @@ void target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev);
/** /**
* target_if_set_spectral_config() - Set spectral config * target_if_set_spectral_config() - Set spectral config
* @pdev: Pointer to pdev object * @pdev: Pointer to pdev object
* @threshtype: config type * @param: Spectral parameter id and value
* @value: config value
* @smode: Spectral scan mode * @smode: Spectral scan mode
* @err: Pointer to Spectral error code * @err: Pointer to Spectral error code
* *
@@ -1984,8 +1998,7 @@ void target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev);
* Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE
*/ */
QDF_STATUS target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, QDF_STATUS target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev,
const uint32_t threshtype, const struct spectral_cp_param *param,
const uint32_t value,
const enum spectral_scan_mode smode, const enum spectral_scan_mode smode,
enum spectral_cp_error_code *err); enum spectral_cp_error_code *err);

View File

@@ -73,8 +73,10 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral,
spec_samp_msg->signature = SPECTRAL_SIGNATURE; spec_samp_msg->signature = SPECTRAL_SIGNATURE;
spec_samp_msg->freq = params->freq; spec_samp_msg->freq = params->freq;
if (params->smode == SPECTRAL_SCAN_MODE_AGILE) if (params->smode == SPECTRAL_SCAN_MODE_AGILE) {
spec_samp_msg->agile_freq = params->agile_freq; spec_samp_msg->agile_freq1 = params->agile_freq1;
spec_samp_msg->agile_freq2 = params->agile_freq2;
}
spec_samp_msg->freq_loading = params->freq_loading; spec_samp_msg->freq_loading = params->freq_loading;
samp_data->spectral_mode = params->smode; samp_data->spectral_mode = params->smode;
samp_data->spectral_data_len = params->datalen; samp_data->spectral_data_len = params->datalen;

View File

@@ -1857,6 +1857,8 @@ target_if_consume_spectral_report_gen3(
/* Advance buf pointer to the search fft report */ /* Advance buf pointer to the search fft report */
data += sizeof(struct spectral_sscan_summary_report_gen3); data += sizeof(struct spectral_sscan_summary_report_gen3);
data += spectral->rparams.ssumaary_padding_bytes; data += spectral->rparams.ssumaary_padding_bytes;
params.vhtop_ch_freq_seg1 = report->cfreq1;
params.vhtop_ch_freq_seg2 = report->cfreq2;
if (is_primaryseg_expected(spectral, spectral_mode)) { if (is_primaryseg_expected(spectral, spectral_mode)) {
/* RSSI is in 1/2 dBm steps, Covert it to dBm scale */ /* RSSI is in 1/2 dBm steps, Covert it to dBm scale */
@@ -1961,10 +1963,12 @@ target_if_consume_spectral_report_gen3(
params.freq = p_sops->get_current_channel(spectral); params.freq = p_sops->get_current_channel(spectral);
if (spectral_mode == SPECTRAL_SCAN_MODE_AGILE) if (spectral_mode == SPECTRAL_SCAN_MODE_AGILE) {
params.agile_freq = params.agile_freq1 = spectral->params[spectral_mode].
spectral->params[spectral_mode].ss_frequency; ss_frequency.cfreq1;
params.agile_freq2 = spectral->params[spectral_mode].
ss_frequency.cfreq2;
}
params.noise_floor = params.noise_floor =
report->noisefloor[chn_idx_lowest_enabled]; report->noisefloor[chn_idx_lowest_enabled];
temp = (uint8_t *)p_fft_report + SPECTRAL_FFT_BINS_POS; temp = (uint8_t *)p_fft_report + SPECTRAL_FFT_BINS_POS;
@@ -2091,9 +2095,6 @@ target_if_consume_spectral_report_gen3(
target_if_dump_fft_report_gen3(spectral, spectral_mode, target_if_dump_fft_report_gen3(spectral, spectral_mode,
p_fft_report, p_sfft); p_fft_report, p_sfft);
params.vhtop_ch_freq_seg1 = 0;
params.vhtop_ch_freq_seg2 = 0;
params.rssi_sec80 = rssi; params.rssi_sec80 = rssi;
vdev = target_if_spectral_get_vdev(spectral); vdev = target_if_spectral_get_vdev(spectral);
@@ -2169,6 +2170,9 @@ int target_if_spectral_process_report_gen3(
qdf_min(sizeof(report.noisefloor), qdf_min(sizeof(report.noisefloor),
sizeof(payload->meta_data.noisefloor))); sizeof(payload->meta_data.noisefloor)));
report.reset_delay = payload->meta_data.reset_delay; report.reset_delay = payload->meta_data.reset_delay;
report.cfreq1 = payload->meta_data.cfreq1;
report.cfreq2 = payload->meta_data.cfreq2;
report.ch_width = payload->meta_data.ch_width;
} }
if (spectral_debug_level & (DEBUG_SPECTRAL2 | DEBUG_SPECTRAL4)) { if (spectral_debug_level & (DEBUG_SPECTRAL2 | DEBUG_SPECTRAL4)) {

View File

@@ -611,8 +611,7 @@ struct wlan_lmac_if_sptrl_tx_ops {
void (*sptrlto_pdev_spectral_deinit)(struct wlan_objmgr_pdev *pdev); void (*sptrlto_pdev_spectral_deinit)(struct wlan_objmgr_pdev *pdev);
QDF_STATUS (*sptrlto_set_spectral_config) QDF_STATUS (*sptrlto_set_spectral_config)
(struct wlan_objmgr_pdev *pdev, (struct wlan_objmgr_pdev *pdev,
const u_int32_t threshtype, const struct spectral_cp_param *param,
const u_int32_t value,
const enum spectral_scan_mode smode, const enum spectral_scan_mode smode,
enum spectral_cp_error_code *err); enum spectral_cp_error_code *err);
QDF_STATUS (*sptrlto_get_spectral_config) QDF_STATUS (*sptrlto_get_spectral_config)

View File

@@ -122,10 +122,16 @@ struct direct_buf_rx_cfg_req {
* *
* @noisefloor: noisefloor * @noisefloor: noisefloor
* @reset_delay: reset delay * @reset_delay: reset delay
* @cfreq1: center frequency 1
* @cfreq2: center frequency 2
* @ch_width: channel width
*/ */
struct direct_buf_rx_metadata { struct direct_buf_rx_metadata {
int32_t noisefloor[WMI_HOST_MAX_NUM_CHAINS]; int32_t noisefloor[WMI_HOST_MAX_NUM_CHAINS];
uint32_t reset_delay; uint32_t reset_delay;
uint32_t cfreq1;
uint32_t cfreq2;
uint32_t ch_width;
}; };
/** /**

View File

@@ -187,6 +187,9 @@ static QDF_STATUS extract_dbr_buf_metadata_tlv(
qdf_min(sizeof(entry->noise_floor), qdf_min(sizeof(entry->noise_floor),
sizeof(param->noisefloor))); sizeof(param->noisefloor)));
param->reset_delay = entry->reset_delay; param->reset_delay = entry->reset_delay;
param->cfreq1 = entry->freq1;
param->cfreq2 = entry->freq2;
param->ch_width = entry->ch_width;
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }