diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index da9f21f05422..6e8909c5c959 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -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"); + + 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; + } + + /* 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; } - - 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; } - ch_params.ch_width = ap_new_ch_width ; + 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; + } + if (!csa_cent_freq2) { + pe_err("CSA WBW 80MHz has invalid seg1 freq %d", + csa_cent_freq2); + return QDF_STATUS_E_INVAL; + } + /* 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; + } + 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; - } 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 (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"); - 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"); - 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; - } - 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; - } } + + 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; }