qcacmn: validate user given agile center frequency

Validate user provided agile center frequency and throw
an error if it is invalid.

CRs-Fixed: 2529280
Change-Id: Ibb43dda98d29d8bc8360d1a204c67b64ca987ca6
This commit is contained in:
Edayilliam Jayadev
2019-09-17 15:39:32 +05:30
committed by nshrivas
parent 542fe34d96
commit b38cb7a8f0
3 changed files with 252 additions and 4 deletions

View File

@@ -425,12 +425,16 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev,
case SPECTRAL_ACTIVATE_SCAN: case SPECTRAL_ACTIVATE_SCAN:
err = &sscan_req->action_req.sscan_err_code; err = &sscan_req->action_req.sscan_err_code;
sc->sptrlc_start_spectral_scan(pdev, smode, err); ret = sc->sptrlc_start_spectral_scan(pdev, smode, err);
if (QDF_IS_STATUS_ERROR(ret))
goto bad;
break; break;
case SPECTRAL_STOP_SCAN: case SPECTRAL_STOP_SCAN:
err = &sscan_req->action_req.sscan_err_code; err = &sscan_req->action_req.sscan_err_code;
sc->sptrlc_stop_spectral_scan(pdev, smode, err); ret = sc->sptrlc_stop_spectral_scan(pdev, smode, err);
if (QDF_IS_STATUS_ERROR(ret))
goto bad;
break; break;
case SPECTRAL_GET_CAPABILITY_INFO: case SPECTRAL_GET_CAPABILITY_INFO:

View File

@@ -2179,6 +2179,216 @@ target_if_spectral_find_agile_width(enum phy_ch_width chwidth)
} }
} }
/**
* target_if_calculate_center_freq() - Helper routine to
* check whether given frequency is center frequency of a
* WLAN channel
*
* @spectral: Pointer to Spectral object
* @chan_freq: Center frequency of a WLAN channel
* @is_valid: Indicates whether given frequency is valid
*
* Return: QDF_STATUS
*/
static QDF_STATUS
target_if_is_center_freq_of_any_chan(struct wlan_objmgr_pdev *pdev,
uint32_t chan_freq,
bool *is_valid)
{
struct regulatory_channel *cur_chan_list;
int i;
if (!pdev) {
spectral_err("pdev object is null");
return QDF_STATUS_E_FAILURE;
}
if (!is_valid) {
spectral_err("is valid argument is null");
return QDF_STATUS_E_FAILURE;
}
cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(*cur_chan_list));
if (!cur_chan_list)
return QDF_STATUS_E_FAILURE;
if (wlan_reg_get_current_chan_list(
pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
spectral_err("Failed to get cur_chan list");
qdf_mem_free(cur_chan_list);
return QDF_STATUS_E_FAILURE;
}
*is_valid = false;
for (i = 0; i < NUM_CHANNELS; i++) {
uint32_t flags;
uint32_t center_freq;
flags = cur_chan_list[i].chan_flags;
center_freq = cur_chan_list[i].center_freq;
if (!(flags & REGULATORY_CHAN_DISABLED) &&
(center_freq == chan_freq)) {
*is_valid = true;
break;
}
}
qdf_mem_free(cur_chan_list);
return QDF_STATUS_SUCCESS;
}
/**
* target_if_calculate_center_freq() - Helper routine to
* find the center frequency of the agile span from a
* WLAN channel center frequency
*
* @spectral: Pointer to Spectral object
* @chan_freq: Center frequency of a WLAN channel
* @center_freq: Pointer to center frequency
*
* Return: QDF_STATUS
*/
static QDF_STATUS
target_if_calculate_center_freq(struct target_if_spectral *spectral,
uint16_t chan_freq,
uint16_t *center_freq)
{
struct wlan_objmgr_vdev *vdev;
enum phy_ch_width ch_width;
enum phy_ch_width agile_ch_width;
uint16_t chan_num;
if (!spectral) {
spectral_err("spectral target if object is null");
return QDF_STATUS_E_FAILURE;
}
if (!center_freq) {
spectral_err("center_freq argument is null");
return QDF_STATUS_E_FAILURE;
}
chan_num = wlan_reg_freq_to_chan(spectral->pdev_obj, chan_freq);
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) {
*center_freq = chan_freq;
} else {
uint16_t start_freq;
uint16_t end_freq;
const struct bonded_channel *bonded_chan_ptr = NULL;
wlan_reg_get_5g_bonded_channel_and_state
(spectral->pdev_obj, chan_num, agile_ch_width,
&bonded_chan_ptr);
if (!bonded_chan_ptr) {
spectral_err("Bonded channel is not found");
return QDF_STATUS_E_FAILURE;
}
start_freq = wlan_reg_chan_to_freq(spectral->pdev_obj,
bonded_chan_ptr->start_ch);
end_freq = wlan_reg_chan_to_freq(spectral->pdev_obj,
bonded_chan_ptr->end_ch);
*center_freq = (start_freq + end_freq) >> 1;
}
return QDF_STATUS_SUCCESS;
}
/**
* target_if_validate_center_freq() - Helper routine to
* validate user provided agile center frequency
*
* @spectral: Pointer to Spectral object
* @center_freq: User provided agile span center frequency
* @is_valid: Indicates whether agile span center frequency is valid
*
* Return: QDF_STATUS
*/
static QDF_STATUS
target_if_validate_center_freq(struct target_if_spectral *spectral,
uint16_t center_freq,
bool *is_valid)
{
struct wlan_objmgr_vdev *vdev;
enum phy_ch_width ch_width;
enum phy_ch_width agile_ch_width;
uint16_t chan_num;
struct wlan_objmgr_pdev *pdev;
QDF_STATUS status;
if (!spectral) {
spectral_err("spectral target if object is null");
return QDF_STATUS_E_FAILURE;
}
if (!is_valid) {
spectral_err("is_valid argument is null");
return QDF_STATUS_E_FAILURE;
}
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) {
status = target_if_is_center_freq_of_any_chan
(pdev, center_freq, is_valid);
if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE;
} else {
uint16_t start_freq;
uint16_t end_freq;
const struct bonded_channel *bonded_chan_ptr = NULL;
bool is_chan;
status = target_if_is_center_freq_of_any_chan
(pdev, center_freq + 10, &is_chan);
if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE;
if (is_chan) {
uint32_t calulated_center_freq;
chan_num = wlan_reg_freq_to_chan(pdev,
center_freq + 10);
wlan_reg_get_5g_bonded_channel_and_state
(pdev, chan_num, agile_ch_width,
&bonded_chan_ptr);
if (!bonded_chan_ptr) {
spectral_err("Bonded channel is not found");
return QDF_STATUS_E_FAILURE;
}
start_freq = wlan_reg_chan_to_freq
(pdev, bonded_chan_ptr->start_ch);
end_freq = wlan_reg_chan_to_freq
(pdev, bonded_chan_ptr->end_ch);
calulated_center_freq = (start_freq + end_freq) >> 1;
*is_valid = (center_freq == calulated_center_freq);
} else {
*is_valid = false;
}
}
return QDF_STATUS_SUCCESS;
}
/** /**
* target_if_is_agile_span_overlap_with_operating_span() - Helper routine to * target_if_is_agile_span_overlap_with_operating_span() - Helper routine to
* check whether agile span overlaps with current operating band. * check whether agile span overlaps with current operating band.
@@ -2310,6 +2520,8 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
struct spectral_config *sparams; struct spectral_config *sparams;
QDF_STATUS status; QDF_STATUS status;
bool is_overlapping; bool is_overlapping;
uint16_t agile_cfreq;
bool is_valid_chan;
if (!err) { if (!err) {
spectral_err("Error code argument is null"); spectral_err("Error code argument is null");
@@ -2412,8 +2624,38 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
sparams->ss_chn_mask = value; sparams->ss_chn_mask = value;
break; break;
case SPECTRAL_PARAM_FREQUENCY: case SPECTRAL_PARAM_FREQUENCY:
status = target_if_is_center_freq_of_any_chan
(spectral->pdev_obj, value, &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,
value,
&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, value, &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 = value;
}
status = target_if_is_agile_span_overlap_with_operating_span status = target_if_is_agile_span_overlap_with_operating_span
(spectral, value, &is_overlapping); (spectral, agile_cfreq, &is_overlapping);
if (QDF_IS_STATUS_ERROR(status)) if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
@@ -2422,7 +2664,7 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
*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 = value; sparams->ss_frequency = agile_cfreq;
break; break;
} }

View File

@@ -215,6 +215,8 @@ QDF_STATUS wlan_reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
return reg_get_current_chan_list(pdev, chan_list); return reg_get_current_chan_list(pdev, chan_list);
} }
qdf_export_symbol(wlan_reg_get_current_chan_list);
/** /**
* wlan_reg_get_bw_value() - give bandwidth value * wlan_reg_get_bw_value() - give bandwidth value
* bw: bandwidth enum * bw: bandwidth enum