From 4c11f80dcbc33619c8ab7645361349efc8dcd742 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Wed, 29 Apr 2020 16:48:06 +0800 Subject: [PATCH] qcacld-3.0: Refine Max chanwidth selection for SAP chanswitch Remove the calls to wlan_reg_dmn_get_opclass_from_channel API when SAP is changing channel by ECSA/CSA. The API accepts channel number and will cause issue when 6GHz band is supported in target. Change-Id: Ib6c67417f1a0edae88b5e714e3ed23c589e7eb62 CRs-Fixed: 2676354 --- .../src/pe/lim/lim_process_sme_req_messages.c | 48 ++++++------------- core/mac/src/pe/lim/lim_utils.c | 34 +++++++++++-- core/mac/src/pe/lim/lim_utils.h | 30 ++++++++++-- .../src/sys/legacy/src/utils/src/parser_api.c | 44 ++++++----------- core/sap/src/sap_module.c | 47 ++++-------------- 5 files changed, 93 insertions(+), 110 deletions(-) diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index b41135df9896..70382fee5c77 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -5352,7 +5352,6 @@ end: void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, uint16_t new_channel_freq, enum phy_ch_width ch_bandwidth, - enum offset_t offset, struct pe_session *session_entry) { uint8_t op_class = 0; @@ -5361,17 +5360,11 @@ void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, uint8_t switch_count; uint8_t new_channel = 0; + op_class = + lim_op_class_from_bandwidth(mac_ctx, new_channel_freq, + ch_bandwidth, + session_entry->gLimChannelSwitch.sec_ch_offset); new_channel = wlan_reg_freq_to_chan(mac_ctx->pdev, new_channel_freq); - if (WLAN_REG_IS_6GHZ_CHAN_FREQ(new_channel_freq)) - wlan_reg_freq_width_to_chan_op_class - (mac_ctx->pdev, new_channel_freq, - ch_width_in_mhz(ch_bandwidth), - true, BIT(BEHAV_NONE), &op_class, - &new_channel); - else - op_class = wlan_reg_dmn_get_opclass_from_channel - (mac_ctx->scan.countryCodeCurrent, new_channel, offset); - if (LIM_IS_AP_ROLE(session_entry) && (mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false)) switch_mode = session_entry->gLimChannelSwitch.switchMode; @@ -5401,7 +5394,6 @@ void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx, uint16_t new_channel_freq, enum phy_ch_width ch_bandwidth, - enum offset_t offset, struct pe_session *session_entry) { uint8_t op_class = 0, new_channel; @@ -5411,18 +5403,12 @@ void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx, tpDphHashNode dph_node_array_ptr; dph_node_array_ptr = session_entry->dph.dphHashTable.pDphNodeArray; - + op_class = + lim_op_class_from_bandwidth(mac_ctx, new_channel_freq, + ch_bandwidth, + session_entry->gLimChannelSwitch.sec_ch_offset); new_channel = wlan_reg_freq_to_chan(mac_ctx->pdev, new_channel_freq); - if (WLAN_REG_IS_6GHZ_CHAN_FREQ(new_channel_freq)) - wlan_reg_freq_width_to_chan_op_class - (mac_ctx->pdev, new_channel_freq, - ch_width_in_mhz(ch_bandwidth), - true, BIT(BEHAV_NONE), &op_class, - &new_channel); - else - op_class = wlan_reg_dmn_get_opclass_from_channel - (mac_ctx->scan.countryCodeCurrent, - new_channel, offset); + if (LIM_IS_AP_ROLE(session_entry) && (false == mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch)) switch_mode = session_entry->gLimChannelSwitch.switchMode; @@ -5470,7 +5456,6 @@ static void lim_process_sme_dfs_csa_ie_request(struct mac_context *mac_ctx, struct pe_session *session_entry = NULL; uint8_t session_id; tLimWiderBWChannelSwitchInfo *wider_bw_ch_switch; - enum offset_t ch_offset; QDF_STATUS status; enum phy_ch_width ch_width; uint32_t target_ch_freq; @@ -5607,19 +5592,13 @@ skip_vht: if (QDF_IS_STATUS_ERROR(status)) pe_err("cannot start ap_ecsa_timer"); - if (ch_width == CH_WIDTH_80MHZ || ch_width == CH_WIDTH_160MHZ || - ch_width == CH_WIDTH_80P80MHZ) - ch_offset = BW80; - else - ch_offset = dfs_csa_ie_req->ch_params.sec_ch_offset; - pe_debug("IE count:%d chan:%d freq %d width:%d wrapper:%d ch_offset:%d", session_entry->gLimChannelSwitch.switchCount, session_entry->gLimChannelSwitch.primaryChannel, session_entry->gLimChannelSwitch.sw_target_freq, session_entry->gLimChannelSwitch.ch_width, session_entry->dfsIncludeChanWrapperIe, - ch_offset); + session_entry->gLimChannelSwitch.sec_ch_offset); /* Send ECSA/CSA Action frame after updating the beacon */ if (CHAN_HOP_ALL_BANDS_ENABLE && @@ -5627,10 +5606,10 @@ skip_vht: lim_send_chan_switch_action_frame (mac_ctx, session_entry->gLimChannelSwitch.primaryChannel, - ch_width, ch_offset, session_entry); + ch_width, session_entry); else send_extended_chan_switch_action_frame - (mac_ctx, target_ch_freq, ch_width, ch_offset, + (mac_ctx, target_ch_freq, ch_width, session_entry); } @@ -5671,8 +5650,9 @@ static void lim_process_ext_change_channel(struct mac_context *mac_ctx, new_ext_chan_freq = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev, ext_chng_channel->new_channel); + session_entry->gLimChannelSwitch.sec_ch_offset = 0; send_extended_chan_switch_action_frame(mac_ctx, new_ext_chan_freq, 0, - 0, session_entry); + session_entry); } /** diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index de52327469a5..c4e8fa15119e 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -5851,6 +5851,33 @@ QDF_STATUS lim_strip_supp_op_class_update_struct(struct mac_context *mac_ctx, return QDF_STATUS_SUCCESS; } +uint8_t lim_op_class_from_bandwidth(struct mac_context *mac_ctx, + uint16_t channel_freq, + enum phy_ch_width ch_bandwidth, + enum offset_t offset) +{ + uint8_t op_class = 0; + uint16_t ch_behav_limit = BEHAV_NONE; + uint8_t channel; + + if (ch_bandwidth == CH_WIDTH_40MHZ && + wlan_reg_is_24ghz_ch_freq(channel_freq)) { + if (offset == BW40_LOW_PRIMARY) + ch_behav_limit = BEHAV_BW40_LOW_PRIMARY; + else + ch_behav_limit = BEHAV_BW40_HIGH_PRIMARY; + } else if (ch_bandwidth == CH_WIDTH_80P80MHZ) { + ch_behav_limit = BEHAV_BW80_PLUS; + } + wlan_reg_freq_width_to_chan_op_class_auto + (mac_ctx->pdev, channel_freq, + ch_width_in_mhz(ch_bandwidth), + true, BIT(ch_behav_limit), &op_class, + &channel); + + return op_class; +} + /** * lim_update_extcap_struct() - poputlate the dot11f structure * @mac_ctx: global MAC context @@ -7690,7 +7717,7 @@ void lim_process_ap_ecsa_timeout(void *data) { struct pe_session *session = (struct pe_session *)data; struct mac_context *mac_ctx; - uint8_t bcn_int, ch_width, offset; + uint8_t bcn_int, ch_width; uint32_t ch_freq; QDF_STATUS status; @@ -7723,17 +7750,16 @@ void lim_process_ap_ecsa_timeout(void *data) ch_freq = session->gLimChannelSwitch.sw_target_freq; ch_width = session->gLimChannelSwitch.ch_width; - offset = session->gLimChannelSwitch.sec_ch_offset; if (mac_ctx->mlme_cfg->dfs_cfg.dfs_beacon_tx_enhanced) { if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) { send_extended_chan_switch_action_frame (mac_ctx, ch_freq, ch_width, - offset, session); + session); } else { /* Send Action frame after updating beacon */ lim_send_chan_switch_action_frame (mac_ctx, ch_freq, ch_width, - offset, session); + session); } } diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 24c573fd5e36..c3491634eecd 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -627,6 +627,13 @@ struct pe_session *lim_is_ibss_session_active(struct mac_context *mac) } #endif +/** + * ch_width_in_mhz() - API to get channel space in MHz + * + * For CH_WIDTH_80P80MHZ, the channel space is max channel space of one + * segment - 80MHz. + * + */ static inline uint8_t ch_width_in_mhz(enum phy_ch_width ch_width) { switch (ch_width) { @@ -637,7 +644,7 @@ static inline uint8_t ch_width_in_mhz(enum phy_ch_width ch_width) case CH_WIDTH_160MHZ: return 160; case CH_WIDTH_80P80MHZ: - return 160; + return 80; case CH_WIDTH_5MHZ: return 5; case CH_WIDTH_10MHZ: @@ -1689,7 +1696,6 @@ void lim_send_start_bss_confirm(struct mac_context *mac_ctx, * @mac_ctx: pointer to global mac structure * @new_channel_freq: new channel freq(Mhz) to switch to. * @ch_bandwidth: ch bw of enum phy_ch_width - * @offset: BW of type enum offset_t * @session_entry: pe session * * Return: void @@ -1697,7 +1703,6 @@ void lim_send_start_bss_confirm(struct mac_context *mac_ctx, void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx, uint16_t new_channel_freq, enum phy_ch_width ch_bandwidth, - enum offset_t offset, struct pe_session *session_entry); /** @@ -1707,7 +1712,6 @@ void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx, * @mac_ctx: pointer to global mac structure * @new_channel_freq: new channel to switch to. * @ch_bandwidth: channel bw of type enum phy_ch_width - * @offset: BW of enum offset_t * @session_entry: pe session * * This function is called to send ECSA frame for STA/CLI and SAP/GO. @@ -1717,7 +1721,6 @@ void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx, void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx, uint16_t new_channel_freq, enum phy_ch_width ch_bandwidth, - enum offset_t offset, struct pe_session *session_entry); /** @@ -2029,6 +2032,23 @@ QDF_STATUS lim_mon_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme, QDF_STATUS lim_get_capability_info(struct mac_context *mac, uint16_t *pCap, struct pe_session *pe_session); +/** + * lim_op_class_from_bandwidth() - get op class from bandwidth + * @mac_ctx: mac context + * @channel_freq: channel frequency MHz + * @ch_bandwidth: channel bandwidth + * @offset: second channel offfset + * + * This API can get the operating class based on channel freq, + * bandwidth and second channel offset. + * + * Return: op class + */ +uint8_t lim_op_class_from_bandwidth(struct mac_context *mac_ctx, + uint16_t channel_freq, + enum phy_ch_width ch_bandwidth, + enum offset_t offset); + /** * lim_flush_bssid() - flush bssid from scan cache * @mac_ctx: pointer to mac data diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 1a895d47f52e..fe802ac7a14a 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -179,34 +179,19 @@ void populate_dot_11_f_ext_chann_switch_ann(struct mac_context *mac_ptr, struct pe_session *session_entry) { uint8_t ch_offset; - uint8_t op_class = 0; - uint8_t chan_num = 0; uint32_t sw_target_freq; uint8_t primary_channel; enum phy_ch_width ch_width; ch_width = session_entry->gLimChannelSwitch.ch_width; - if (ch_width == CH_WIDTH_80MHZ) - ch_offset = BW80; - else - ch_offset = session_entry->gLimChannelSwitch.sec_ch_offset; + ch_offset = session_entry->gLimChannelSwitch.sec_ch_offset; dot_11_ptr->switch_mode = session_entry->gLimChannelSwitch.switchMode; sw_target_freq = session_entry->gLimChannelSwitch.sw_target_freq; primary_channel = session_entry->gLimChannelSwitch.primaryChannel; - if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sw_target_freq)) { - wlan_reg_freq_width_to_chan_op_class - (mac_ptr->pdev, sw_target_freq, - ch_width_in_mhz(ch_width), - true, BIT(BEHAV_NONE), &op_class, &chan_num); - dot_11_ptr->new_reg_class = op_class; - } else { - dot_11_ptr->new_reg_class = - wlan_reg_dmn_get_opclass_from_channel - (mac_ptr->scan.countryCodeCurrent, - primary_channel, ch_offset); - } - + dot_11_ptr->new_reg_class = + lim_op_class_from_bandwidth(mac_ptr, sw_target_freq, ch_width, + ch_offset); dot_11_ptr->new_channel = session_entry->gLimChannelSwitch.primaryChannel; dot_11_ptr->switch_count = @@ -249,32 +234,31 @@ populate_dot11_supp_operating_classes(struct mac_context *mac_ptr, tDot11fIESuppOperatingClasses *dot_11_ptr, struct pe_session *session_entry) { - uint8_t ch_bandwidth; + uint8_t ch_offset; if (session_entry->ch_width == CH_WIDTH_80MHZ) { - ch_bandwidth = BW80; + ch_offset = BW80; } else { switch (session_entry->htSecondaryChannelOffset) { case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: - ch_bandwidth = BW40_HIGH_PRIMARY; + ch_offset = BW40_HIGH_PRIMARY; break; case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: - ch_bandwidth = BW40_LOW_PRIMARY; + ch_offset = BW40_LOW_PRIMARY; break; default: - ch_bandwidth = BW20; + ch_offset = BW20; break; } } wlan_reg_dmn_get_curr_opclasses(&dot_11_ptr->num_classes, &dot_11_ptr->classes[1]); - dot_11_ptr->classes[0] = wlan_reg_dmn_get_opclass_from_channel( - mac_ptr->scan.countryCodeCurrent, - wlan_reg_freq_to_chan( - mac_ptr->pdev, - session_entry->curr_op_freq), - ch_bandwidth); + dot_11_ptr->classes[0] = + lim_op_class_from_bandwidth(mac_ptr, + session_entry->curr_op_freq, + session_entry->ch_width, + ch_offset); dot_11_ptr->num_classes++; dot_11_ptr->present = 1; } diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 716396f0f6df..b93a4c6380e5 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -1210,7 +1210,7 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context, uint32_t chan_freq) { struct mac_context *mac_ctx; - uint8_t bw; + uint32_t max_fw_bw; mac_ctx = sap_get_mac_context(); if (!mac_ctx) { @@ -1224,8 +1224,7 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context, * SAP coming up in HT40 on channel switch we are * disabling channel bonding in 2.4Ghz. */ - mac_ctx->sap.SapDfsInfo.new_chanWidth = 0; - + mac_ctx->sap.SapDfsInfo.new_chanWidth = CH_WIDTH_20MHZ; } else { if (sap_context->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11ac || @@ -1235,48 +1234,22 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context, eCSR_DOT11_MODE_11ax || sap_context->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11ax_ONLY) { - bw = BW80; + max_fw_bw = sme_get_vht_ch_width(); + if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) + mac_ctx->sap.SapDfsInfo.new_chanWidth = + CH_WIDTH_160MHZ; + else + mac_ctx->sap.SapDfsInfo.new_chanWidth = + CH_WIDTH_80MHZ; } else if (sap_context->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11n || sap_context->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11n_ONLY) { - bw = BW40_HIGH_PRIMARY; + mac_ctx->sap.SapDfsInfo.new_chanWidth = CH_WIDTH_40MHZ; } else { /* For legacy 11a mode return 20MHz */ mac_ctx->sap.SapDfsInfo.new_chanWidth = CH_WIDTH_20MHZ; - return QDF_STATUS_SUCCESS; } - - for (; bw >= BW20; bw--) { - uint16_t op_class; - - op_class = wlan_reg_dmn_get_opclass_from_channel( - mac_ctx->scan.countryCodeCurrent, - wlan_reg_freq_to_chan(mac_ctx->pdev, chan_freq), - bw); - /* - * Do not continue if bw is 20. This mean channel is not - * found and thus set BW20 for the channel. - */ - if (!op_class && bw > BW20) - continue; - - if (bw == BW80) { - mac_ctx->sap.SapDfsInfo.new_chanWidth = - CH_WIDTH_80MHZ; - } else if (bw == BW40_HIGH_PRIMARY) { - mac_ctx->sap.SapDfsInfo.new_chanWidth = - CH_WIDTH_40MHZ; - } else if (bw == BW40_LOW_PRIMARY) { - mac_ctx->sap.SapDfsInfo.new_chanWidth = - CH_WIDTH_40MHZ; - } else { - mac_ctx->sap.SapDfsInfo.new_chanWidth = - CH_WIDTH_20MHZ; - } - break; - } - } return QDF_STATUS_SUCCESS;