|
@@ -1425,94 +1425,132 @@ static QDF_STATUS lim_process_csa_wbw_ie(struct mac_context *mac_ctx,
|
|
|
{
|
|
|
struct ch_params ch_params = {0};
|
|
|
uint8_t ap_new_ch_width;
|
|
|
- bool new_ch_width_dfn = false;
|
|
|
uint8_t center_freq_diff;
|
|
|
uint32_t fw_vht_ch_wd = wma_get_vht_ch_width() + 1;
|
|
|
+ uint32_t cent_freq1, cent_freq2;
|
|
|
+ uint32_t csa_cent_freq, csa_cent_freq1 = 0, csa_cent_freq2 = 0;
|
|
|
|
|
|
ap_new_ch_width = csa_params->new_ch_width + 1;
|
|
|
|
|
|
- if ((ap_new_ch_width != CH_WIDTH_80MHZ) &&
|
|
|
- (ap_new_ch_width != CH_WIDTH_160MHZ) &&
|
|
|
- (ap_new_ch_width != CH_WIDTH_80P80MHZ)) {
|
|
|
- pe_err("CSA wide BW IE has wrong ch_width %d",
|
|
|
- csa_params->new_ch_width);
|
|
|
- return QDF_STATUS_E_INVAL;
|
|
|
- }
|
|
|
-
|
|
|
if (!csa_params->new_ch_freq_seg1 && !csa_params->new_ch_freq_seg2) {
|
|
|
pe_err("CSA wide BW IE has invalid center freq");
|
|
|
return QDF_STATUS_E_INVAL;
|
|
|
}
|
|
|
- if ((ap_new_ch_width == CH_WIDTH_80MHZ) &&
|
|
|
- csa_params->new_ch_freq_seg2) {
|
|
|
- new_ch_width_dfn = true;
|
|
|
- if (csa_params->new_ch_freq_seg2 >
|
|
|
- csa_params->new_ch_freq_seg1)
|
|
|
- center_freq_diff = csa_params->new_ch_freq_seg2 -
|
|
|
- csa_params->new_ch_freq_seg1;
|
|
|
- else
|
|
|
- center_freq_diff = csa_params->new_ch_freq_seg1 -
|
|
|
- csa_params->new_ch_freq_seg2;
|
|
|
- if (center_freq_diff == CENTER_FREQ_DIFF_160MHz)
|
|
|
- ap_new_ch_width = CH_WIDTH_160MHZ;
|
|
|
- else if (center_freq_diff > CENTER_FREQ_DIFF_80P80MHz)
|
|
|
- ap_new_ch_width = CH_WIDTH_80P80MHZ;
|
|
|
- else
|
|
|
- ap_new_ch_width = CH_WIDTH_80MHZ;
|
|
|
+
|
|
|
+ csa_cent_freq = csa_params->csa_chan_freq;
|
|
|
+ if (wlan_reg_is_6ghz_op_class(mac_ctx->pdev,
|
|
|
+ csa_params->new_op_class)) {
|
|
|
+ cent_freq1 = wlan_reg_chan_opclass_to_freq(
|
|
|
+ csa_params->new_ch_freq_seg1,
|
|
|
+ csa_params->new_op_class, false);
|
|
|
+ cent_freq2 = wlan_reg_chan_opclass_to_freq(
|
|
|
+ csa_params->new_ch_freq_seg2,
|
|
|
+ csa_params->new_op_class, false);
|
|
|
+ } else {
|
|
|
+ cent_freq1 = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev,
|
|
|
+ csa_params->new_ch_freq_seg1);
|
|
|
+ cent_freq2 = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev,
|
|
|
+ csa_params->new_ch_freq_seg2);
|
|
|
}
|
|
|
- session_entry->gLimChannelSwitch.state =
|
|
|
- eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
|
|
|
- if ((ap_new_ch_width == CH_WIDTH_160MHZ) &&
|
|
|
- !new_ch_width_dfn) {
|
|
|
- if (abs(csa_params->new_ch_freq_seg1 - csa_params->channel) !=
|
|
|
- CH_TO_CNTR_FREQ_DIFF_160MHz) {
|
|
|
- pe_err("CSA wide BW IE has invalid center freq");
|
|
|
- return QDF_STATUS_E_INVAL;
|
|
|
+
|
|
|
+ switch (ap_new_ch_width) {
|
|
|
+ case CH_WIDTH_80MHZ:
|
|
|
+ csa_cent_freq1 = cent_freq1;
|
|
|
+ if (csa_params->new_ch_freq_seg2) {
|
|
|
+ center_freq_diff = abs(csa_params->new_ch_freq_seg2 -
|
|
|
+ csa_params->new_ch_freq_seg1);
|
|
|
+ if (center_freq_diff == CENTER_FREQ_DIFF_160MHz) {
|
|
|
+ ap_new_ch_width = CH_WIDTH_160MHZ;
|
|
|
+ csa_cent_freq1 = cent_freq2;
|
|
|
+ csa_params->new_ch_freq_seg1 =
|
|
|
+ csa_params->new_ch_freq_seg2;
|
|
|
+ csa_params->new_ch_freq_seg2 = 0;
|
|
|
+ } else if (center_freq_diff > CENTER_FREQ_DIFF_160MHz) {
|
|
|
+ ap_new_ch_width = CH_WIDTH_80P80MHZ;
|
|
|
+ csa_cent_freq2 = cent_freq2;
|
|
|
+ }
|
|
|
}
|
|
|
+ break;
|
|
|
+ case CH_WIDTH_80P80MHZ:
|
|
|
+ csa_cent_freq1 = cent_freq1;
|
|
|
+ csa_cent_freq2 = cent_freq2;
|
|
|
+ break;
|
|
|
+ case CH_WIDTH_160MHZ:
|
|
|
+ csa_cent_freq1 = cent_freq1;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ pe_err("CSA wide BW IE has wrong ch_width %d", ap_new_ch_width);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
|
|
|
- if (ap_new_ch_width > fw_vht_ch_wd) {
|
|
|
- pe_debug("New BW is not supported, setting BW to %d",
|
|
|
- fw_vht_ch_wd);
|
|
|
- ap_new_ch_width = fw_vht_ch_wd;
|
|
|
+ /* Verify whether the bandwidth and channel segments are valid. */
|
|
|
+ switch (ap_new_ch_width) {
|
|
|
+ case CH_WIDTH_80MHZ:
|
|
|
+ if (abs(csa_cent_freq1 - csa_cent_freq) != 10 &&
|
|
|
+ abs(csa_cent_freq1 - csa_cent_freq) != 30) {
|
|
|
+ pe_err("CSA WBW 80MHz has invalid seg0 freq %d",
|
|
|
+ csa_cent_freq1);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
}
|
|
|
- ch_params.ch_width = ap_new_ch_width ;
|
|
|
- wlan_reg_set_channel_params(mac_ctx->pdev,
|
|
|
- csa_params->channel, 0, &ch_params);
|
|
|
- ap_new_ch_width = ch_params.ch_width;
|
|
|
- csa_params->new_ch_freq_seg1 = ch_params.center_freq_seg0;
|
|
|
- csa_params->new_ch_freq_seg2 = ch_params.center_freq_seg1;
|
|
|
- } else if (!new_ch_width_dfn) {
|
|
|
- if (ap_new_ch_width > fw_vht_ch_wd) {
|
|
|
- pe_debug("New BW is not supported, setting BW to %d",
|
|
|
- fw_vht_ch_wd);
|
|
|
- ap_new_ch_width = fw_vht_ch_wd;
|
|
|
+ if (csa_cent_freq2) {
|
|
|
+ pe_err("CSA WBW 80MHz has invalid seg1 freq %d",
|
|
|
+ csa_cent_freq2);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
}
|
|
|
- if (abs(csa_params->new_ch_freq_seg1 - csa_params->channel) !=
|
|
|
- CH_TO_CNTR_FREQ_DIFF_80MHz) {
|
|
|
- pe_err("CSA wide BW IE has invalid center freq");
|
|
|
+ break;
|
|
|
+ case CH_WIDTH_80P80MHZ:
|
|
|
+ if (abs(csa_cent_freq1 - csa_cent_freq) != 10 &&
|
|
|
+ abs(csa_cent_freq1 - csa_cent_freq) != 30) {
|
|
|
+ pe_err("CSA WBW 80MHz has invalid seg0 freq %d",
|
|
|
+ csa_cent_freq1);
|
|
|
return QDF_STATUS_E_INVAL;
|
|
|
}
|
|
|
- csa_params->new_ch_freq_seg2 = 0;
|
|
|
- }
|
|
|
- if (new_ch_width_dfn) {
|
|
|
- if (abs(csa_params->new_ch_freq_seg1 - csa_params->channel) !=
|
|
|
- CH_TO_CNTR_FREQ_DIFF_80MHz) {
|
|
|
- pe_err("CSA wide BW IE has invalid center freq");
|
|
|
+ if (!csa_cent_freq2) {
|
|
|
+ pe_err("CSA WBW 80MHz has invalid seg1 freq %d",
|
|
|
+ csa_cent_freq2);
|
|
|
return QDF_STATUS_E_INVAL;
|
|
|
}
|
|
|
- if (ap_new_ch_width > fw_vht_ch_wd) {
|
|
|
- pe_debug("New width is not supported, setting BW to %d",
|
|
|
- fw_vht_ch_wd);
|
|
|
- ap_new_ch_width = fw_vht_ch_wd;
|
|
|
+ /* adjacent is not allowed -- that's a 160 MHz channel */
|
|
|
+ if (abs(csa_cent_freq1 - csa_cent_freq2) == 80) {
|
|
|
+ pe_err("CSA WBW wrong bandwidth");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
}
|
|
|
- if ((ap_new_ch_width == CH_WIDTH_160MHZ) &&
|
|
|
- (abs(csa_params->new_ch_freq_seg1 - csa_params->channel) !=
|
|
|
- CH_TO_CNTR_FREQ_DIFF_160MHz)) {
|
|
|
- pe_err("wide BW IE has invalid 160M center freq");
|
|
|
- csa_params->new_ch_freq_seg2 = 0;
|
|
|
- ap_new_ch_width = CH_WIDTH_80MHZ;
|
|
|
+ break;
|
|
|
+ case CH_WIDTH_160MHZ:
|
|
|
+ if (abs(csa_cent_freq1 - csa_cent_freq) != 70 &&
|
|
|
+ abs(csa_cent_freq1 - csa_cent_freq) != 50 &&
|
|
|
+ abs(csa_cent_freq1 - csa_cent_freq) != 30 &&
|
|
|
+ abs(csa_cent_freq1 - csa_cent_freq) != 10) {
|
|
|
+ pr_err("CSA WBW 160MHz has invalid seg0 freq %d",
|
|
|
+ csa_cent_freq1);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+ if (csa_cent_freq2) {
|
|
|
+ pe_err("CSA WBW 80MHz has invalid seg1 freq %d",
|
|
|
+ csa_cent_freq2);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
}
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ pe_err("CSA wide BW IE has wrong ch_width %d", ap_new_ch_width);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
}
|
|
|
+
|
|
|
+ if (ap_new_ch_width > fw_vht_ch_wd) {
|
|
|
+ pe_debug("New BW is not supported, setting BW to %d",
|
|
|
+ fw_vht_ch_wd);
|
|
|
+ ap_new_ch_width = fw_vht_ch_wd;
|
|
|
+ ch_params.ch_width = ap_new_ch_width;
|
|
|
+ wlan_reg_set_channel_params(mac_ctx->pdev,
|
|
|
+ csa_params->channel, 0, &ch_params);
|
|
|
+ ap_new_ch_width = ch_params.ch_width;
|
|
|
+ csa_params->new_ch_freq_seg1 = ch_params.center_freq_seg0;
|
|
|
+ csa_params->new_ch_freq_seg2 = ch_params.center_freq_seg1;
|
|
|
+ }
|
|
|
+
|
|
|
+ session_entry->gLimChannelSwitch.state =
|
|
|
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
|
|
|
+
|
|
|
chnl_switch_info->newChanWidth = ap_new_ch_width;
|
|
|
chnl_switch_info->newCenterChanFreq0 = csa_params->new_ch_freq_seg1;
|
|
|
chnl_switch_info->newCenterChanFreq1 = csa_params->new_ch_freq_seg2;
|
|
@@ -1658,13 +1696,12 @@ void lim_handle_csa_offload_msg(struct mac_context *mac_ctx,
|
|
|
lim_ch_switch->sec_ch_offset =
|
|
|
PHY_SINGLE_CHANNEL_CENTERED;
|
|
|
if (chnl_switch_info->newChanWidth) {
|
|
|
- if (csa_params->channel <
|
|
|
- csa_params->new_ch_freq_seg1)
|
|
|
- lim_ch_switch->sec_ch_offset =
|
|
|
- PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
|
|
|
- else
|
|
|
- lim_ch_switch->sec_ch_offset =
|
|
|
- PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
|
|
|
+ ch_params.ch_width =
|
|
|
+ chnl_switch_info->newChanWidth;
|
|
|
+ wlan_reg_set_channel_params(mac_ctx->pdev,
|
|
|
+ csa_params->channel, 0, &ch_params);
|
|
|
+ lim_ch_switch->sec_ch_offset =
|
|
|
+ ch_params.sec_ch_offset;
|
|
|
session_entry->htSupportedChannelWidthSet =
|
|
|
true;
|
|
|
}
|