diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c index 665445fa61..57ab0028e8 100644 --- a/core/mac/src/pe/lim/lim_process_action_frame.c +++ b/core/mac/src/pe/lim/lim_process_action_frame.c @@ -249,7 +249,7 @@ static void __lim_process_operating_mode_action_frame(struct mac_context *mac_ct uint32_t status; tpDphHashNode sta_ptr; uint16_t aid; - uint8_t ch_bw = 0; + enum phy_ch_width ch_bw = 0; mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info); diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 1d2d589881..da5abc81e7 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -4883,13 +4883,19 @@ bool lim_check_vht_op_mode_change(struct mac_context *mac, uint8_t chanWidth, uint8_t *peerMac) { QDF_STATUS status; - bool update_allow = false; + bool update_allow; struct ch_params ch_params; struct csa_offload_params *csa_param; + enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(pe_session->vdev); - status = lim_get_update_bw_allow(pe_session, chanWidth, &update_allow); - if (QDF_IS_STATUS_ERROR(status)) - return false; + if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) { + status = lim_get_update_bw_allow(pe_session, chanWidth, + &update_allow); + if (QDF_IS_STATUS_ERROR(status)) + return false; + } else { + update_allow = true; + } if (update_allow) { tUpdateVHTOpMode tempParam; @@ -4904,6 +4910,10 @@ bool lim_check_vht_op_mode_change(struct mac_context *mac, return true; } + if (!wlan_cm_is_vdev_connected(pe_session->vdev)) + return false; + + /* use vdev restart to update STA mode */ qdf_mem_zero(&ch_params, sizeof(ch_params)); ch_params.ch_width = chanWidth; wlan_reg_set_channel_params_for_pwrmode(mac->pdev, @@ -11064,10 +11074,12 @@ void lim_update_nss(struct mac_context *mac_ctx, tpDphHashNode sta_ds, bool lim_update_channel_width(struct mac_context *mac_ctx, tpDphHashNode sta_ptr, struct pe_session *session, - uint8_t ch_width, uint8_t *new_ch_width) + enum phy_ch_width ch_width, + enum phy_ch_width *new_ch_width) { - uint8_t cb_mode, oper_mode; - uint32_t fw_vht_ch_wd; + uint8_t cb_mode; + enum phy_ch_width oper_mode; + enum phy_ch_width fw_vht_ch_wd; if (wlan_reg_is_24ghz_ch_freq(session->curr_op_freq)) cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz; @@ -11085,53 +11097,52 @@ bool lim_update_channel_width(struct mac_context *mac_ctx, if (sta_ptr->htSupportedChannelWidthSet) { if (sta_ptr->vhtSupportedChannelWidthSet > WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) - oper_mode = eHT_CHANNEL_WIDTH_160MHZ; + oper_mode = CH_WIDTH_160MHZ; else oper_mode = sta_ptr->vhtSupportedChannelWidthSet + 1; } else { - oper_mode = eHT_CHANNEL_WIDTH_20MHZ; + oper_mode = CH_WIDTH_20MHZ; } - if (((oper_mode == eHT_CHANNEL_WIDTH_80MHZ) && - (ch_width > eHT_CHANNEL_WIDTH_80MHZ)) || - (oper_mode == ch_width)) + fw_vht_ch_wd = wlan_mlme_get_max_bw(); + + if (ch_width > fw_vht_ch_wd) { + pe_debug_rl(QDF_MAC_ADDR_FMT ": Downgrade new bw: %d to max %d", + QDF_MAC_ADDR_REF(sta_ptr->staAddr), + ch_width, fw_vht_ch_wd); + ch_width = fw_vht_ch_wd; + } + if (oper_mode == ch_width) return false; - fw_vht_ch_wd = wma_get_vht_ch_width(); + pe_debug(QDF_MAC_ADDR_FMT ": Current : %d, New: %d max %d ", + QDF_MAC_ADDR_REF(sta_ptr->staAddr), oper_mode, + ch_width, fw_vht_ch_wd); - pe_debug("ChannelWidth - Current : %d, New: %d mac : " QDF_MAC_ADDR_FMT, - oper_mode, ch_width, QDF_MAC_ADDR_REF(sta_ptr->staAddr)); - - if (ch_width >= eHT_CHANNEL_WIDTH_160MHZ && - (fw_vht_ch_wd >= eHT_CHANNEL_WIDTH_160MHZ)) { + if (ch_width >= CH_WIDTH_160MHZ) { sta_ptr->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ; - sta_ptr->htSupportedChannelWidthSet = - eHT_CHANNEL_WIDTH_40MHZ; - *new_ch_width = eHT_CHANNEL_WIDTH_160MHZ; - } else if (ch_width >= eHT_CHANNEL_WIDTH_80MHZ) { + ch_width = CH_WIDTH_160MHZ; + } else if (ch_width == CH_WIDTH_80MHZ) { sta_ptr->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; - sta_ptr->htSupportedChannelWidthSet = - eHT_CHANNEL_WIDTH_40MHZ; - *new_ch_width = eHT_CHANNEL_WIDTH_80MHZ; - } else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) { + } else if (ch_width == CH_WIDTH_40MHZ) { sta_ptr->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; - sta_ptr->htSupportedChannelWidthSet = - eHT_CHANNEL_WIDTH_40MHZ; - *new_ch_width = eHT_CHANNEL_WIDTH_40MHZ; - } else if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) { + } else if (ch_width == CH_WIDTH_20MHZ) { sta_ptr->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; - sta_ptr->htSupportedChannelWidthSet = - eHT_CHANNEL_WIDTH_20MHZ; - *new_ch_width = eHT_CHANNEL_WIDTH_20MHZ; + } else { + return false; } + if (ch_width >= CH_WIDTH_40MHZ) + sta_ptr->htSupportedChannelWidthSet = CH_WIDTH_40MHZ; + else + sta_ptr->htSupportedChannelWidthSet = CH_WIDTH_20MHZ; + *new_ch_width = ch_width; - lim_check_vht_op_mode_change(mac_ctx, session, *new_ch_width, - sta_ptr->staAddr); - return true; + return lim_check_vht_op_mode_change(mac_ctx, session, *new_ch_width, + sta_ptr->staAddr); } uint8_t lim_get_vht_ch_width(tDot11fIEVHTCaps *vht_cap, @@ -11484,3 +11495,25 @@ next: return false; } + +enum phy_ch_width +lim_convert_vht_chwidth_to_phy_chwidth(uint8_t ch_width, bool is_40) +{ + switch (ch_width) { + case WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ: + return CH_WIDTH_80P80MHZ; + case WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ: + return CH_WIDTH_160MHZ; + case WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ: + return CH_WIDTH_80MHZ; + case WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ: + if (is_40) + return CH_WIDTH_40MHZ; + else + return CH_WIDTH_20MHZ; + default: + pe_debug("Unknown VHT ch width %d", ch_width); + break; + } + return CH_WIDTH_20MHZ; +} diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index bb444da466..50c733028a 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -3115,8 +3115,8 @@ void lim_update_nss(struct mac_context *mac_ctx, tpDphHashNode sta_ds, bool lim_update_channel_width(struct mac_context *mac_ctx, tpDphHashNode sta_ptr, struct pe_session *session, - uint8_t ch_width, - uint8_t *new_ch_width); + enum phy_ch_width ch_width, + enum phy_ch_width *new_ch_width); /** * lim_get_vht_ch_width() - Function to get the VHT @@ -3251,4 +3251,16 @@ bool lim_is_chan_connected_for_mode(struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE opmode, qdf_freq_t freq); + +/** + * lim_convert_vht_chwidth_to_phy_chwidth() - Convert VHT operation + * ch width into phy ch width + * + * @ch_width: VHT op channel width + * @is_40: is 40 MHz + * + * Return: phy chwidth + */ +enum phy_ch_width +lim_convert_vht_chwidth_to_phy_chwidth(uint8_t ch_width, bool is_40); #endif /* __LIM_UTILS_H */ diff --git a/core/mac/src/pe/sch/sch_beacon_process.c b/core/mac/src/pe/sch/sch_beacon_process.c index 87ae8b3765..09af51afa0 100644 --- a/core/mac/src/pe/sch/sch_beacon_process.c +++ b/core/mac/src/pe/sch/sch_beacon_process.c @@ -436,13 +436,12 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds, struct pe_session *session, tpSchBeaconStruct bcn, tpSirMacMgmtHdr mac_hdr, uint8_t cb_mode) { - bool skip_opmode_update = false; - uint8_t oper_mode; - uint32_t fw_vht_ch_wd = wma_get_vht_ch_width(); - uint8_t ch_width = 0, ch_bw; + enum phy_ch_width ch_bw; + enum phy_ch_width ch_width = CH_WIDTH_20MHZ; tDot11fIEVHTCaps *vht_caps = NULL; tDot11fIEVHTOperation *vht_op = NULL; uint8_t bcn_vht_chwidth = 0; + bool is_40 = false; /* * Ignore opmode change during channel change The opmode will be updated @@ -457,15 +456,6 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds, return; } - if (session->vhtCapability && bcn->OperatingMode.present) { - pe_debug("OMN IE is present in the beacon, update NSS/Ch width"); - lim_update_nss(mac_ctx, sta_ds, bcn->OperatingMode.rxNSS, - session); - lim_update_channel_width(mac_ctx, sta_ds, session, - bcn->OperatingMode.chanWidth, &ch_bw); - return; - } - if (bcn->VHTCaps.present) { vht_caps = &bcn->VHTCaps; vht_op = &bcn->VHTOperation; @@ -473,74 +463,27 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds, vht_caps = &bcn->vendor_vht_ie.VHTCaps; vht_op = &bcn->vendor_vht_ie.VHTOperation; } - - if (!(session->vhtCapability && (vht_op && vht_op->present))) + if (!session->vhtCapability || + !(bcn->OperatingMode.present || + (vht_op && vht_op->present && vht_caps))) return; - bcn_vht_chwidth = lim_get_vht_ch_width(&bcn->VHTCaps, - &bcn->VHTOperation, - &bcn->HTInfo); + is_40 = bcn->HTCaps.present ? + bcn->HTCaps.supportedChannelWidthSet : false; - oper_mode = sta_ds->vhtSupportedChannelWidthSet; - if ((oper_mode == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) && - (oper_mode < bcn_vht_chwidth)) - skip_opmode_update = true; - - if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) { - /* - * if channel bonding is disabled from INI do not - * update the chan width - */ - pe_debug_rl("CB disabled skip bw update: old[%d] new[%d]", - oper_mode, bcn->OperatingMode.chanWidth); - - return; - } - - if (!skip_opmode_update && - (oper_mode != bcn_vht_chwidth)) { - pe_debug("received VHTOP CHWidth %d", bcn_vht_chwidth); - pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x", - mac_hdr->sa[0], mac_hdr->sa[1], - mac_hdr->sa[2], mac_hdr->sa[3], - mac_hdr->sa[4], mac_hdr->sa[5]); - - if ((bcn_vht_chwidth >= - WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) && - (fw_vht_ch_wd > eHT_CHANNEL_WIDTH_80MHZ)) { - pe_debug("Updating the CH Width to 160MHz"); - sta_ds->vhtSupportedChannelWidthSet = - bcn_vht_chwidth; - sta_ds->htSupportedChannelWidthSet = - eHT_CHANNEL_WIDTH_40MHZ; - ch_width = eHT_CHANNEL_WIDTH_160MHZ; - } else if (bcn_vht_chwidth >= - WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) { - pe_debug("Updating the CH Width to 80MHz"); - sta_ds->vhtSupportedChannelWidthSet = - WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; - sta_ds->htSupportedChannelWidthSet = - eHT_CHANNEL_WIDTH_40MHZ; - ch_width = eHT_CHANNEL_WIDTH_80MHZ; - } else if (bcn_vht_chwidth == - WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) { - sta_ds->vhtSupportedChannelWidthSet = - WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; - if (bcn->HTCaps.supportedChannelWidthSet) { - pe_debug("Updating the CH Width to 40MHz"); - sta_ds->htSupportedChannelWidthSet = - eHT_CHANNEL_WIDTH_40MHZ; - ch_width = eHT_CHANNEL_WIDTH_40MHZ; - } else { - pe_debug("Updating the CH Width to 20MHz"); - sta_ds->htSupportedChannelWidthSet = - eHT_CHANNEL_WIDTH_20MHZ; - ch_width = eHT_CHANNEL_WIDTH_20MHZ; - } - } - lim_check_vht_op_mode_change(mac_ctx, session, ch_width, - mac_hdr->sa); + if (bcn->OperatingMode.present) { + pe_debug("OMN IE is present in the beacon, update NSS/Ch width"); + lim_update_nss(mac_ctx, sta_ds, bcn->OperatingMode.rxNSS, + session); + ch_width = bcn->OperatingMode.chanWidth; + } else { + bcn_vht_chwidth = lim_get_vht_ch_width(vht_caps, vht_op, + &bcn->HTInfo); + ch_width = + lim_convert_vht_chwidth_to_phy_chwidth(bcn_vht_chwidth, + is_40); } + lim_update_channel_width(mac_ctx, sta_ds, session, ch_width, &ch_bw); } #ifdef WLAN_FEATURE_SR