From f63c83abc1b10944d941d041130801fbaf7503ab Mon Sep 17 00:00:00 2001 From: sheenam monga Date: Mon, 29 Jun 2020 15:43:45 +0530 Subject: [PATCH] qcacld-3.0: Consider phy mode sent by fw to get dot11 mode Currently, after roaming only vht ie is used to get dot11 mode which may casue issue whenever vendor vht ie is present but vht ie is not present in beacon. Host updates dot11 mode to 11N based on missing vht ie and does not consider vendor vht but fw considers vendor vht ie which causes different dot11 modes in fw and host. Consider phy mode sent by fw in roam sync event to get dot11 mode to maintain compatibility between host and fw. Change-Id: Ie9e4cbadd84d239c6f386f296c77677b15ce0500 CRs-Fixed: 2714566 --- core/mac/inc/sir_api.h | 1 + core/mac/src/pe/include/lim_ft.h | 6 +- core/mac/src/pe/lim/lim_api.c | 3 +- core/mac/src/pe/lim/lim_assoc_utils.c | 7 +- core/mac/src/pe/lim/lim_assoc_utils.h | 14 ++ core/mac/src/pe/lim/lim_ft.c | 221 ++++++++++++++++---------- core/mac/src/pe/lim/lim_ft_preauth.c | 2 +- core/wma/src/wma_scan_roam.c | 8 +- 8 files changed, 172 insertions(+), 90 deletions(-) diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 88d0edd569..63b1320a47 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -2923,6 +2923,7 @@ struct roam_offload_synch_ind { uint16_t hlp_data_len; uint8_t hlp_data[FILS_MAX_HLP_DATA_LEN]; bool is_ft_im_roam; + enum wlan_phymode phy_mode; /*phy mode sent by fw */ }; #ifdef WLAN_FEATURE_ROAM_OFFLOAD diff --git a/core/mac/src/pe/include/lim_ft.h b/core/mac/src/pe/include/lim_ft.h index 6cd9324ecd..f26d5c8c81 100644 --- a/core/mac/src/pe/include/lim_ft.h +++ b/core/mac/src/pe/include/lim_ft.h @@ -139,7 +139,8 @@ static inline int lim_process_ft_pre_auth_req(struct mac_context *mac, void lim_fill_ft_session(struct mac_context *mac, struct bss_description *pbssDescription, struct pe_session *ft_session, - struct pe_session *pe_session); + struct pe_session *pe_session, + enum wlan_phymode bss_phymode); /** * lim_ft_prepare_add_bss_req() - Create Add Bss Req to the new AP @@ -162,7 +163,8 @@ QDF_STATUS lim_send_preauth_scan_offload(struct mac_context *mac_ctx, static inline void lim_fill_ft_session(struct mac_context *mac, struct bss_description *pbssDescription, struct pe_session *ft_session, - struct pe_session *pe_session) + struct pe_session *pe_session, + enum wlan_phymode bss_phymode) {} static inline void lim_ft_prepare_add_bss_req(struct mac_context *mac, struct pe_session *ft_session, diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 79fdd8ec4b..adb963e59e 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -2465,7 +2465,8 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, ft_session_ptr->csaOffloadEnable = session_ptr->csaOffloadEnable; /* Next routine will update nss and vdev_nss with AP's capabilities */ - lim_fill_ft_session(mac_ctx, bss_desc, ft_session_ptr, session_ptr); + lim_fill_ft_session(mac_ctx, bss_desc, ft_session_ptr, + session_ptr, roam_sync_ind_ptr->phy_mode); /* Next routine may update nss based on dot11Mode */ lim_ft_prepare_add_bss_req(mac_ctx, ft_session_ptr, bss_desc); diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c index a2a392a934..bce640631c 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/core/mac/src/pe/lim/lim_assoc_utils.c @@ -3279,9 +3279,10 @@ lim_del_bss(struct mac_context *mac, tpDphHashNode sta, uint16_t bss_idx, * * Return : void */ -static void lim_update_vhtcaps_assoc_resp(struct mac_context *mac_ctx, - struct bss_params *pAddBssParams, - tDot11fIEVHTCaps *vht_caps, struct pe_session *pe_session) +void lim_update_vhtcaps_assoc_resp(struct mac_context *mac_ctx, + struct bss_params *pAddBssParams, + tDot11fIEVHTCaps *vht_caps, + struct pe_session *pe_session) { pAddBssParams->staContext.vht_caps = ((vht_caps->maxMPDULen << diff --git a/core/mac/src/pe/lim/lim_assoc_utils.h b/core/mac/src/pe/lim/lim_assoc_utils.h index f663ace513..8e1ba36410 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.h +++ b/core/mac/src/pe/lim/lim_assoc_utils.h @@ -361,4 +361,18 @@ void lim_extract_ies_from_deauth_disassoc(struct pe_session *session, uint8_t *deauth_disassoc_frame, uint16_t deauth_disassoc_frame_len); + +/** + * lim_update_vhtcaps_assoc_resp : Update VHT caps in assoc response. + * @mac_ctx Pointer to Global MAC structure + * @pAddBssParams: parameters required for add bss params. + * @vht_caps: VHT capabilities. + * @pe_session : session entry. + * + * Return : void + */ +void lim_update_vhtcaps_assoc_resp(struct mac_context *mac_ctx, + struct bss_params *pAddBssParams, + tDot11fIEVHTCaps *vht_caps, + struct pe_session *pe_session); #endif /* __LIM_ASSOC_UTILS_H */ diff --git a/core/mac/src/pe/lim/lim_ft.c b/core/mac/src/pe/lim/lim_ft.c index 640cc20cfa..8adb9bf67c 100644 --- a/core/mac/src/pe/lim/lim_ft.c +++ b/core/mac/src/pe/lim/lim_ft.c @@ -120,6 +120,7 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, tAddStaParams *sta_ctx; bool chan_width_support = false; tSchBeaconStruct *pBeaconStruct; + tDot11fIEVHTCaps *vht_caps = NULL; /* Nothing to be done if the session is not in STA mode */ if (!LIM_IS_STA_ROLE(ft_session)) { @@ -194,47 +195,21 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, if (pBeaconStruct->VHTOperation.chanWidth && chan_width_support) pAddBssParams->ch_width = pBeaconStruct->VHTOperation.chanWidth + 1; - pAddBssParams->staContext.vht_caps = - ((pBeaconStruct->VHTCaps.maxMPDULen << - SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | - (pBeaconStruct->VHTCaps.supportedChannelWidthSet << - SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | - (pBeaconStruct->VHTCaps.ldpcCodingCap << - SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | - (pBeaconStruct->VHTCaps.shortGI80MHz << - SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | - (pBeaconStruct->VHTCaps.shortGI160and80plus80MHz << - SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | - (pBeaconStruct->VHTCaps.txSTBC << - SIR_MAC_VHT_CAP_TXSTBC) | - (pBeaconStruct->VHTCaps.rxSTBC << - SIR_MAC_VHT_CAP_RXSTBC) | - (pBeaconStruct->VHTCaps.suBeamFormerCap << - SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | - (pBeaconStruct->VHTCaps.suBeamformeeCap << - SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | - (pBeaconStruct->VHTCaps.csnofBeamformerAntSup << - SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | - (pBeaconStruct->VHTCaps.numSoundingDim << - SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | - (pBeaconStruct->VHTCaps.muBeamformerCap << - SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) | - (pBeaconStruct->VHTCaps.muBeamformeeCap << - SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | - (pBeaconStruct->VHTCaps.vhtTXOPPS << - SIR_MAC_VHT_CAP_TXOPPS) | - (pBeaconStruct->VHTCaps.htcVHTCap << - SIR_MAC_VHT_CAP_HTC_CAP) | - (pBeaconStruct->VHTCaps.maxAMPDULenExp << - SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | - (pBeaconStruct->VHTCaps.vhtLinkAdaptCap << - SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | - (pBeaconStruct->VHTCaps.rxAntPattern << - SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | - (pBeaconStruct->VHTCaps.txAntPattern << - SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | - (pBeaconStruct->VHTCaps.extended_nss_bw_supp << - SIR_MAC_VHT_CAP_EXTD_NSS_BW)); + vht_caps = &pBeaconStruct->VHTCaps; + lim_update_vhtcaps_assoc_resp(mac, pAddBssParams, + vht_caps, ft_session); + } else if (ft_session->vhtCapability && + pBeaconStruct->vendor_vht_ie.VHTCaps.present) { + pe_debug("VHT caps are present in vendor specific IE"); + pAddBssParams->vhtCapable = + pBeaconStruct->vendor_vht_ie.VHTCaps.present; + if (pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth && + chan_width_support) + pAddBssParams->ch_width = + pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth + 1; + vht_caps = &pBeaconStruct->vendor_vht_ie.VHTCaps; + lim_update_vhtcaps_assoc_resp(mac, pAddBssParams, + vht_caps, ft_session); } else { pAddBssParams->vhtCapable = 0; } @@ -382,12 +357,99 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, #endif #if defined(WLAN_FEATURE_ROAM_OFFLOAD) + +/** + * lim_convert_phymode_to_dot11mode() - get dot11 mode from phymode + * @phymode: phymode + * + * The function is to convert the phymode to corresponding dot11 mode + * + * Return: dot11mode. + */ +static uint8_t lim_convert_phymode_to_dot11mode(enum wlan_phymode phymode) +{ + + if (IS_WLAN_PHYMODE_HE(phymode)) + return MLME_DOT11_MODE_11AX; + + if (IS_WLAN_PHYMODE_VHT(phymode)) + return MLME_DOT11_MODE_11AC; + + if (IS_WLAN_PHYMODE_HT(phymode)) + return MLME_DOT11_MODE_11N; + + if (phymode == WLAN_PHYMODE_11G) + return MLME_DOT11_MODE_11G; + + if (phymode == WLAN_PHYMODE_11G_ONLY) + return MLME_DOT11_MODE_11G_ONLY; + + if (phymode == WLAN_PHYMODE_11A) + return MLME_DOT11_MODE_11A; + + if (phymode == WLAN_PHYMODE_11B) + return MLME_DOT11_MODE_11B; + + return MLME_DOT11_MODE_ALL; +} + +/** + * lim_calculate_dot11_mode() - calculate dot11 mode. + * @mac_context: mac context + * @bcn: beacon structure + * @band: reg_wifi_band + * + * The function is to calculate dot11 mode in case fw doen't send phy mode. + * + * Return: dot11mode. + */ +static uint8_t lim_calculate_dot11_mode(struct mac_context *mac_ctx, + tSchBeaconStruct *bcn, + enum reg_wifi_band band) +{ + enum mlme_dot11_mode self_dot11_mode; + + self_dot11_mode = mac_ctx->mlme_cfg->dot11_mode.dot11_mode; + + if (band == REG_BAND_2G) + return MLME_DOT11_MODE_11G; + else + return MLME_DOT11_MODE_11A; + + switch (self_dot11_mode) { + case MLME_DOT11_MODE_11AX: + case MLME_DOT11_MODE_11AX_ONLY: + case MLME_DOT11_MODE_ALL: + if (bcn->he_cap.present) + return MLME_DOT11_MODE_11AX; + else if (bcn->VHTCaps.present || + bcn->vendor_vht_ie.present) + return MLME_DOT11_MODE_11AC; + else if (bcn->HTCaps.present) + return MLME_DOT11_MODE_11N; + case MLME_DOT11_MODE_11AC: + case MLME_DOT11_MODE_11AC_ONLY: + if (bcn->VHTCaps.present || + bcn->vendor_vht_ie.present) + return MLME_DOT11_MODE_11AC; + else if (bcn->HTCaps.present) + return MLME_DOT11_MODE_11N; + case MLME_DOT11_MODE_11N: + case MLME_DOT11_MODE_11N_ONLY: + if (bcn->HTCaps.present) + return MLME_DOT11_MODE_11N; + default: + break; + } +} + /** * lim_fill_dot11mode() - to fill 802.11 mode in FT session * @mac_ctx: pointer to mac ctx * @ft_session: FT session * @pe_session: PE session * @bcn: AP beacon pointer + * @bss_phymode: bss phy mode * * This API fills FT session's dot11mode either from pe session or * from CFG depending on the condition. @@ -397,48 +459,24 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, static void lim_fill_dot11mode(struct mac_context *mac_ctx, struct pe_session *ft_session, struct pe_session *pe_session, - tSchBeaconStruct *bcn) + tSchBeaconStruct *bcn, + enum wlan_phymode bss_phymode) { - uint32_t self_dot11_mode; - if (pe_session->ftPEContext.pFTPreAuthReq && !csr_is_roam_offload_enabled(mac_ctx)) { ft_session->dot11mode = pe_session->ftPEContext.pFTPreAuthReq->dot11mode; return; } - self_dot11_mode = mac_ctx->mlme_cfg->dot11_mode.dot11_mode; - pe_debug("selfDot11Mode: %d", self_dot11_mode); - if (ft_session->limRFBand == REG_BAND_2G) - ft_session->dot11mode = MLME_DOT11_MODE_11G; - else - ft_session->dot11mode = MLME_DOT11_MODE_11A; - switch (self_dot11_mode) { - case MLME_DOT11_MODE_11AX: - case MLME_DOT11_MODE_11AX_ONLY: - if (bcn->he_cap.present) - ft_session->dot11mode = MLME_DOT11_MODE_11AX; - else if (bcn->VHTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11AC; - else if (bcn->HTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11N; - break; - case MLME_DOT11_MODE_11AC: - case MLME_DOT11_MODE_11AC_ONLY: - if (bcn->VHTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11AC; - else if (bcn->HTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11N; - break; - case MLME_DOT11_MODE_11N: - case MLME_DOT11_MODE_11N_ONLY: - if (bcn->HTCaps.present) - ft_session->dot11mode = MLME_DOT11_MODE_11N; - break; - default: - break; - } + if (bss_phymode == WLAN_PHYMODE_AUTO) + ft_session->dot11mode = lim_calculate_dot11_mode( + mac_ctx, bcn, + ft_session->limRFBand); + + else + ft_session->dot11mode = + lim_convert_phymode_to_dot11mode(bss_phymode); } #elif defined(WLAN_FEATURE_HOST_ROAM) /** @@ -447,6 +485,7 @@ static void lim_fill_dot11mode(struct mac_context *mac_ctx, * @ft_session: FT session * @pe_session: PE session * @bcn: AP beacon pointer + * @bss_phymode: bss phy mode * * This API fills FT session's dot11mode either from pe session. * @@ -455,7 +494,8 @@ static void lim_fill_dot11mode(struct mac_context *mac_ctx, static void lim_fill_dot11mode(struct mac_context *mac_ctx, struct pe_session *ft_session, struct pe_session *pe_session, - tSchBeaconStruct *bcn) + tSchBeaconStruct *bcn, + enum wlan_phymode bss_phymode) { ft_session->dot11mode = pe_session->ftPEContext.pFTPreAuthReq->dot11mode; @@ -471,7 +511,9 @@ static void lim_fill_dot11mode(struct mac_context *mac_ctx, *------------------------------------------------------------------*/ void lim_fill_ft_session(struct mac_context *mac, struct bss_description *pbssDescription, - struct pe_session *ft_session, struct pe_session *pe_session) + struct pe_session *ft_session, + struct pe_session *pe_session, + enum wlan_phymode bss_phymode) { uint8_t currentBssUapsd; uint8_t bss_chan_id; @@ -523,12 +565,15 @@ void lim_fill_ft_session(struct mac_context *mac, ft_session->curr_op_freq = pbssDescription->chan_freq; ft_session->limRFBand = lim_get_rf_band(ft_session->curr_op_freq); - lim_fill_dot11mode(mac, ft_session, pe_session, pBeaconStruct); - pe_debug("dot11mode: %d", ft_session->dot11mode); + lim_fill_dot11mode(mac, ft_session, pe_session, pBeaconStruct, + bss_phymode); + pe_debug("dot11mode: %d bss_phymode %d", ft_session->dot11mode, + bss_phymode); ft_session->vhtCapability = - (IS_DOT11_MODE_VHT(ft_session->dot11mode) - && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)); + (IS_DOT11_MODE_VHT(ft_session->dot11mode) && + (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) || + IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor_vht_ie.VHTCaps))); ft_session->htCapability = (IS_DOT11_MODE_HT(ft_session->dot11mode) && pBeaconStruct->HTCaps.present); @@ -560,9 +605,14 @@ void lim_fill_ft_session(struct mac_context *mac, pBeaconStruct->VHTOperation.present && ft_session->vhtCapability) { ft_session->vhtCapabilityPresentInBeacon = 1; + } else if (IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor_vht_ie.VHTCaps) && + pBeaconStruct->vendor_vht_ie.VHTOperation.present && + ft_session->vhtCapability){ + ft_session->vhtCapabilityPresentInBeacon = 1; } else { ft_session->vhtCapabilityPresentInBeacon = 0; } + if (ft_session->htRecommendedTxWidthSet) { ft_session->ch_width = CH_WIDTH_40MHZ; if (ft_session->vhtCapabilityPresentInBeacon && @@ -573,6 +623,15 @@ void lim_fill_ft_session(struct mac_context *mac, pBeaconStruct->VHTOperation.chan_center_freq_seg0; ft_session->ch_center_freq_seg1 = pBeaconStruct->VHTOperation.chan_center_freq_seg1; + } else if (ft_session->vhtCapabilityPresentInBeacon && + pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth){ + ft_session->ch_width = + pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth + 1; + ft_session->ch_center_freq_seg0 = + pBeaconStruct->vendor_vht_ie.VHTOperation.chan_center_freq_seg0; + ft_session->ch_center_freq_seg1 = + pBeaconStruct->vendor_vht_ie.VHTOperation.chan_center_freq_seg1; + } else { if (pBeaconStruct->HTInfo.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) diff --git a/core/mac/src/pe/lim/lim_ft_preauth.c b/core/mac/src/pe/lim/lim_ft_preauth.c index 366f3a25f4..6fd632e289 100644 --- a/core/mac/src/pe/lim/lim_ft_preauth.c +++ b/core/mac/src/pe/lim/lim_ft_preauth.c @@ -339,7 +339,7 @@ QDF_STATUS lim_ft_setup_auth_session(struct mac_context *mac, if (req && req->pbssDescription) { lim_fill_ft_session(mac, req->pbssDescription, ft_session, - pe_session); + pe_session, WLAN_PHYMODE_AUTO); lim_ft_prepare_add_bss_req(mac, ft_session, req->pbssDescription); } diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 6fbb1ef583..63472994ba 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -2548,10 +2548,14 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, } else { wma_fill_data_synch_event(wma, roam_synch_ind_ptr, param_buf); } - chan = param_buf->chan; - if (chan) + if (chan) { roam_synch_ind_ptr->chan_freq = chan->mhz; + roam_synch_ind_ptr->phy_mode = + wma_fw_to_host_phymode(WMI_GET_CHANNEL_MODE(chan)); + } else { + roam_synch_ind_ptr->phy_mode = WLAN_PHYMODE_AUTO; + } key = param_buf->key; key_ft = param_buf->key_ext;