From 0ceb5ca62003c3df13dddd336fb68b307d391315 Mon Sep 17 00:00:00 2001 From: Abhishek Ambure Date: Fri, 15 Nov 2019 18:22:45 +0530 Subject: [PATCH] qcacld-3.0: Parse Channel Switch Wrapper IE in CSA event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit “New channel width” information is not present in CSA event received by host. When STA processes CSA beacon & CSA action frame and moves to new channel, “New channel width” & "new channel center frequencies" are not applied. Firmware adds "Channel switch wrapper IE" information in CSA event and sets "WMI_CSWRAP_IE_EXTENDED_PRESENT" bit in ies_present_flag. Channel switch wrapper ie elemets are parsed to get Wide Bandwidth Channel Switch information. Change-Id: I095c49ae5a78cbfa8947e98cc39ec647aa7f3d27 CRs-Fixed: 2571406 --- core/wma/src/wma_features.c | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index b26370008dca..e46042a211ba 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -1071,6 +1071,32 @@ int wma_unified_csa_offload_enable(tp_wma_handle wma, uint8_t vdev_id) } #endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */ +static uint8_t * +wma_parse_ch_switch_wrapper_ie(uint8_t *ch_wr_ie, uint8_t sub_ele_id) +{ + uint8_t len = 0, sub_ele_len = 0; + struct ie_header *ele; + + ele = (struct ie_header *)ch_wr_ie; + if (ele->ie_id != WLAN_ELEMID_CHAN_SWITCH_WRAP || + ele->ie_len == 0) + return NULL; + + len = ele->ie_len; + ele = (struct ie_header *)(ch_wr_ie + sizeof(struct ie_header)); + + while (len > 0) { + sub_ele_len = sizeof(struct ie_header) + ele->ie_len; + len -= sub_ele_len; + if (ele->ie_id == sub_ele_id) + return (uint8_t *)ele; + + ele = (struct ie_header *)((uint8_t *)ele + sub_ele_len); + } + + return NULL; +} + /** * wma_csa_offload_handler() - CSA event handler * @handle: wma handle @@ -1148,12 +1174,32 @@ int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len) csa_offload_event->new_ch_width = wb_ie->new_ch_width; csa_offload_event->new_ch_freq_seg1 = wb_ie->new_ch_freq_seg1; csa_offload_event->new_ch_freq_seg2 = wb_ie->new_ch_freq_seg2; + } else if (csa_event->ies_present_flag & + WMI_CSWRAP_IE_EXTENDED_PRESENT) { + wb_ie = (struct ieee80211_ie_wide_bw_switch *) + wma_parse_ch_switch_wrapper_ie( + (uint8_t *)&csa_event->cswrap_ie_extended, + WLAN_ELEMID_WIDE_BAND_CHAN_SWITCH); + if (wb_ie) { + csa_offload_event->new_ch_width = wb_ie->new_ch_width; + csa_offload_event->new_ch_freq_seg1 = + wb_ie->new_ch_freq_seg1; + csa_offload_event->new_ch_freq_seg2 = + wb_ie->new_ch_freq_seg2; + csa_event->ies_present_flag |= WMI_WBW_IE_PRESENT; + } } csa_offload_event->ies_present_flag = csa_event->ies_present_flag; WMA_LOGD("CSA: New Channel = %d BSSID:%pM", csa_offload_event->channel, csa_offload_event->bssId); + WMA_LOGD("CSA: IEs Present Flag = 0x%x new ch width = %d ch center freq1 = %d ch center freq2 = %d new op class = %d", + csa_event->ies_present_flag, + csa_offload_event->new_ch_width, + csa_offload_event->new_ch_freq_seg1, + csa_offload_event->new_ch_freq_seg2, + csa_offload_event->new_op_class); cur_chan = cds_freq_to_chan(intr[vdev_id].mhz); /*