From e38f4d255fe0c0922ce03a0eee360dcf541b7ffd Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Thu, 20 Oct 2016 17:30:59 -0700 Subject: qcacld-3.0: Update the CSA processing with new VHT op definition channel width is not populated properly into the channel switch parameters hence the phy_mode is configured wrongly to the FW. Correct the channel width in the channel switch parameters and update the CSA processing with new VHT operation IE definition. Change-Id: I4f299dd721b602efb9e64797b1bdb34972e07797 CRs-Fixed: 1081503 (cherry picked from commit ebc53cabfb357847e434a4c822878fc4f1910be3) --- core/mac/src/pe/lim/lim_send_sme_rsp_messages.c | 343 ++++++++++++++---------- core/mac/src/pe/lim/lim_utils.h | 3 + 2 files changed, 205 insertions(+), 141 deletions(-) (limited to 'core/mac/src') 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 ab2fcb67c14c..b5094115ff18 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 @@ -1962,6 +1962,67 @@ lim_send_sme_ibss_peer_ind(tpAniSirGlobal pMac, } +void lim_process_csa_wdw_ie(tpAniSirGlobal mac_ctx, + struct csa_offload_params *csa_params, + tLimWiderBWChannelSwitchInfo *chnl_switch_info, + tpPESession session_entry) +{ + struct ch_params_s ch_params = {0}; + uint8_t ap_new_ch_width; + bool new_ch_width_dfn = false; + uint8_t center_freq_diff; + + ap_new_ch_width = csa_params->new_ch_width + 1; + 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; + } + session_entry->gLimChannelSwitch.state = + eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + if ((ap_new_ch_width == CH_WIDTH_160MHZ) && + !new_ch_width_dfn) { + ch_params.ch_width = CH_WIDTH_160MHZ; + cds_set_channel_params(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; + } + 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; + + if (session_entry->ch_width == ap_new_ch_width) + goto prnt_log; + + if (session_entry->ch_width == CH_WIDTH_80MHZ) { + chnl_switch_info->newChanWidth = CH_WIDTH_80MHZ; + chnl_switch_info->newCenterChanFreq1 = 0; + } else { + session_entry->ch_width = ap_new_ch_width; + chnl_switch_info->newChanWidth = ap_new_ch_width; + } +prnt_log: + lim_log(mac_ctx, LOG1, + FL("new channel: %d new_ch_width:%d seg0:%d seg1:%d"), + csa_params->channel, + chnl_switch_info->newChanWidth, + chnl_switch_info->newCenterChanFreq0, + chnl_switch_info->newCenterChanFreq1); +} /** * lim_handle_csa_offload_msg() - Handle CSA offload message * @mac_ctx: pointer to global adapter context @@ -2011,181 +2072,181 @@ void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) goto err; } - if (LIM_IS_STA_ROLE(session_entry)) { - /* - * on receiving channel switch announcement from AP, delete all - * TDLS peers before leaving BSS and proceed for channel switch - */ - lim_delete_tdls_peers(mac_ctx, session_entry); - - lim_ch_switch = &session_entry->gLimChannelSwitch; - session_entry->gLimChannelSwitch.switchMode = - csa_params->switch_mode; - /* timer already started by firmware, switch immediately */ - session_entry->gLimChannelSwitch.switchCount = 0; - session_entry->gLimChannelSwitch.primaryChannel = - csa_params->channel; - session_entry->gLimChannelSwitch.state = - eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; - session_entry->gLimChannelSwitch.ch_width = CH_WIDTH_20MHZ; - lim_ch_switch->sec_ch_offset = - session_entry->htSecondaryChannelOffset; - session_entry->gLimChannelSwitch.ch_center_freq_seg0 = 0; - session_entry->gLimChannelSwitch.ch_center_freq_seg1 = 0; - chnl_switch_info = - &session_entry->gLimWiderBWChannelSwitch; + if (!LIM_IS_STA_ROLE(session_entry)) { + lim_log(mac_ctx, LOG1, FL("Invalid role to handle CSA")); + goto err; + } - lim_log(mac_ctx, LOG1, - FL("vht:%d ht:%d flag:%x chan:%d seg1:%d seg2:%d width:%d country:%s class:%d"), + /* + * on receiving channel switch announcement from AP, delete all + * TDLS peers before leaving BSS and proceed for channel switch + */ + lim_delete_tdls_peers(mac_ctx, session_entry); + + lim_ch_switch = &session_entry->gLimChannelSwitch; + session_entry->gLimChannelSwitch.switchMode = + csa_params->switch_mode; + /* timer already started by firmware, switch immediately */ + session_entry->gLimChannelSwitch.switchCount = 0; + session_entry->gLimChannelSwitch.primaryChannel = + csa_params->channel; + session_entry->gLimChannelSwitch.state = + eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; + session_entry->gLimChannelSwitch.ch_width = CH_WIDTH_20MHZ; + lim_ch_switch->sec_ch_offset = + session_entry->htSecondaryChannelOffset; + session_entry->gLimChannelSwitch.ch_center_freq_seg0 = 0; + session_entry->gLimChannelSwitch.ch_center_freq_seg1 = 0; + chnl_switch_info = + &session_entry->gLimWiderBWChannelSwitch; + + lim_log(mac_ctx, LOG1, + FL("vht:%d ht:%d flag:%x chan:%d"), session_entry->vhtCapability, session_entry->htSupportedChannelWidthSet, csa_params->ies_present_flag, - csa_params->channel, csa_params->new_ch_freq_seg1, + csa_params->channel); + lim_log(mac_ctx, LOG1, + FL("seg1:%d seg2:%d width:%d country:%s class:%d"), + csa_params->new_ch_freq_seg1, csa_params->new_ch_freq_seg2, csa_params->new_ch_width, mac_ctx->scan.countryCodeCurrent, csa_params->new_op_class); - if (session_entry->vhtCapability && - session_entry->htSupportedChannelWidthSet) { - if (csa_params->ies_present_flag & lim_wbw_ie_present) { + if (session_entry->vhtCapability && + session_entry->htSupportedChannelWidthSet) { + if (csa_params->ies_present_flag & lim_wbw_ie_present) { + lim_process_csa_wdw_ie(mac_ctx, csa_params, + chnl_switch_info, session_entry); + lim_ch_switch->sec_ch_offset = + csa_params->sec_chan_offset; + } else if (csa_params->ies_present_flag + & lim_xcsa_ie_present) { + chan_space = + cds_reg_dmn_get_chanwidth_from_opclass( + mac_ctx->scan.countryCodeCurrent, + csa_params->channel, + csa_params->new_op_class); + session_entry->gLimChannelSwitch.state = + eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + + if (chan_space == 80) { + chnl_switch_info->newChanWidth = + CH_WIDTH_80MHZ; + } else if (chan_space == 40) { + chnl_switch_info->newChanWidth = + CH_WIDTH_40MHZ; + } else { chnl_switch_info->newChanWidth = - csa_params->new_ch_width; - chnl_switch_info->newCenterChanFreq0 = - csa_params->new_ch_freq_seg1; - chnl_switch_info->newCenterChanFreq1 = - csa_params->new_ch_freq_seg2; - session_entry->gLimChannelSwitch.state = - eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; - session_entry->gLimChannelSwitch.ch_width = - csa_params->new_ch_width + 1; - } else if (csa_params->ies_present_flag - & lim_xcsa_ie_present) { - chan_space = - cds_reg_dmn_get_chanwidth_from_opclass( - mac_ctx->scan.countryCodeCurrent, - csa_params->channel, - csa_params->new_op_class); - session_entry->gLimChannelSwitch.state = - eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; - - if (chan_space == 80) { - chnl_switch_info->newChanWidth = - CH_WIDTH_80MHZ; - } else if (chan_space == 40) { - chnl_switch_info->newChanWidth = - CH_WIDTH_40MHZ; - } else { - chnl_switch_info->newChanWidth = - CH_WIDTH_20MHZ; - lim_ch_switch->state = - eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; - } + CH_WIDTH_20MHZ; + lim_ch_switch->state = + eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; + } + + ch_params.ch_width = + chnl_switch_info->newChanWidth; + cds_set_channel_params(csa_params->channel, + 0, &ch_params); + chnl_switch_info->newCenterChanFreq0 = + ch_params.center_freq_seg0; + /* + * This is not applicable for 20/40/80 MHz. + * Only used when we support 80+80 MHz operation. + * In case of 80+80 MHz, this parameter indicates + * center channel frequency index of 80 MHz + * channel offrequency segment 1. + */ + chnl_switch_info->newCenterChanFreq1 = + ch_params.center_freq_seg1; + lim_ch_switch->sec_ch_offset = + ch_params.sec_ch_offset; + } + session_entry->gLimChannelSwitch.ch_center_freq_seg0 = + chnl_switch_info->newCenterChanFreq0; + session_entry->gLimChannelSwitch.ch_center_freq_seg1 = + chnl_switch_info->newCenterChanFreq1; + session_entry->gLimChannelSwitch.ch_width = + chnl_switch_info->newChanWidth; + + } else if (session_entry->htSupportedChannelWidthSet) { + if (csa_params->ies_present_flag + & lim_xcsa_ie_present) { + chan_space = + cds_reg_dmn_get_chanwidth_from_opclass( + mac_ctx->scan.countryCodeCurrent, + csa_params->channel, + csa_params->new_op_class); + lim_ch_switch->state = + eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + if (chan_space == 40) { + lim_ch_switch->ch_width = + CH_WIDTH_40MHZ; + chnl_switch_info->newChanWidth = + CH_WIDTH_40MHZ; ch_params.ch_width = chnl_switch_info->newChanWidth; - cds_set_channel_params(csa_params->channel, + cds_set_channel_params( + csa_params->channel, 0, &ch_params); - chnl_switch_info->newCenterChanFreq0 = + lim_ch_switch->ch_center_freq_seg0 = ch_params.center_freq_seg0; - /* - * This is not applicable for 20/40/80 MHz. - * Only used when we support 80+80 MHz operation. - * In case of 80+80 MHz, this parameter indicates - * center channel frequency index of 80 MHz - * channel offrequency segment 1. - */ - chnl_switch_info->newCenterChanFreq1 = - ch_params.center_freq_seg1; lim_ch_switch->sec_ch_offset = ch_params.sec_ch_offset; - - } - session_entry->gLimChannelSwitch.ch_center_freq_seg0 = - chnl_switch_info->newCenterChanFreq0; - session_entry->gLimChannelSwitch.ch_center_freq_seg1 = - chnl_switch_info->newCenterChanFreq1; - session_entry->gLimChannelSwitch.ch_width = - chnl_switch_info->newChanWidth; - - } else if (session_entry->htSupportedChannelWidthSet) { - if (csa_params->ies_present_flag - & lim_xcsa_ie_present) { - chan_space = - cds_reg_dmn_get_chanwidth_from_opclass( - mac_ctx->scan.countryCodeCurrent, - csa_params->channel, - csa_params->new_op_class); - lim_ch_switch->state = - eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; - if (chan_space == 40) { - lim_ch_switch->ch_width = - CH_WIDTH_40MHZ; - chnl_switch_info->newChanWidth = - CH_WIDTH_40MHZ; - ch_params.ch_width = - chnl_switch_info->newChanWidth; - cds_set_channel_params( - csa_params->channel, - 0, &ch_params); - lim_ch_switch->ch_center_freq_seg0 = - ch_params.center_freq_seg0; - lim_ch_switch->sec_ch_offset = - ch_params.sec_ch_offset; - } else { - lim_ch_switch->ch_width = - CH_WIDTH_20MHZ; - chnl_switch_info->newChanWidth = - CH_WIDTH_40MHZ; - lim_ch_switch->state = - eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; - lim_ch_switch->sec_ch_offset = - PHY_SINGLE_CHANNEL_CENTERED; - } } else { lim_ch_switch->ch_width = + CH_WIDTH_20MHZ; + chnl_switch_info->newChanWidth = CH_WIDTH_40MHZ; lim_ch_switch->state = - eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; - ch_params.ch_width = CH_WIDTH_40MHZ; - cds_set_channel_params(csa_params->channel, - 0, &ch_params); - lim_ch_switch->ch_center_freq_seg0 = - ch_params.center_freq_seg0; + eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; lim_ch_switch->sec_ch_offset = - ch_params.sec_ch_offset; + PHY_SINGLE_CHANNEL_CENTERED; } - + } else { + lim_ch_switch->ch_width = + CH_WIDTH_40MHZ; + lim_ch_switch->state = + eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + ch_params.ch_width = CH_WIDTH_40MHZ; + cds_set_channel_params(csa_params->channel, + 0, &ch_params); + lim_ch_switch->ch_center_freq_seg0 = + ch_params.center_freq_seg0; + lim_ch_switch->sec_ch_offset = + ch_params.sec_ch_offset; } - lim_log(mac_ctx, LOG1, FL("new ch width = %d space:%d"), + + } + lim_log(mac_ctx, LOG1, FL("new ch width = %d space:%d"), session_entry->gLimChannelSwitch.ch_width, chan_space); - lim_prepare_for11h_channel_switch(mac_ctx, session_entry); - csa_offload_ind = qdf_mem_malloc(sizeof(tSmeCsaOffloadInd)); - if (NULL == csa_offload_ind) { - lim_log(mac_ctx, LOGE, + lim_prepare_for11h_channel_switch(mac_ctx, session_entry); + csa_offload_ind = qdf_mem_malloc(sizeof(tSmeCsaOffloadInd)); + if (NULL == csa_offload_ind) { + lim_log(mac_ctx, LOGE, FL("memalloc fail eWNI_SME_CSA_OFFLOAD_EVENT")); - goto err; - } + goto err; + } - csa_offload_ind->mesgType = eWNI_SME_CSA_OFFLOAD_EVENT; - csa_offload_ind->mesgLen = sizeof(tSmeCsaOffloadInd); - qdf_mem_copy(csa_offload_ind->bssid.bytes, session_entry->bssId, - QDF_MAC_ADDR_SIZE); - mmh_msg.type = eWNI_SME_CSA_OFFLOAD_EVENT; - mmh_msg.bodyptr = csa_offload_ind; - mmh_msg.bodyval = 0; - lim_log(mac_ctx, LOG1, + csa_offload_ind->mesgType = eWNI_SME_CSA_OFFLOAD_EVENT; + csa_offload_ind->mesgLen = sizeof(tSmeCsaOffloadInd); + qdf_mem_copy(csa_offload_ind->bssid.bytes, session_entry->bssId, + QDF_MAC_ADDR_SIZE); + mmh_msg.type = eWNI_SME_CSA_OFFLOAD_EVENT; + mmh_msg.bodyptr = csa_offload_ind; + mmh_msg.bodyval = 0; + lim_log(mac_ctx, LOG1, FL("Sending eWNI_SME_CSA_OFFLOAD_EVENT to SME.")); - MTRACE(mac_trace_msg_tx + MTRACE(mac_trace_msg_tx (mac_ctx, session_entry->peSessionId, mmh_msg.type)); #ifdef FEATURE_WLAN_DIAG_SUPPORT - lim_diag_event_report(mac_ctx, + lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_SWITCH_CHL_IND_EVENT, session_entry, eSIR_SUCCESS, eSIR_SUCCESS); #endif - lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT); - } + lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT); err: qdf_mem_free(csa_params); diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 80a37c3f8605..5ad6bd0921e4 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -64,6 +64,9 @@ typedef enum { #define VHT_MCS_3x3_MASK 0x30 #define VHT_MCS_2x2_MASK 0x0C +#define CENTER_FREQ_DIFF_160MHz 8 +#define CENTER_FREQ_DIFF_80P80MHz 16 + #define IS_VHT_NSS_1x1(__mcs_map) ((__mcs_map & 0xFFFC) == 0xFFFC) #ifdef WLAN_FEATURE_11W -- cgit v1.2.3