diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 88d0edd569a4..63b1320a47c0 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 6cd9324ecd27..f26d5c8c8173 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 79fdd8ec4b3c..adb963e59e7d 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 a2a392a934b6..bce640631c36 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 f663ace5131f..8e1ba364100d 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 640cc20cfac4..8adb9bf67c5d 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 366f3a25f47b..6fd632e28900 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 6fbb1ef5831d..63472994ba1b 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;