diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 89bfd49789..b36ef6e874 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -981,6 +981,16 @@ QDF_STATUS mlme_update_tgt_he_caps_in_cfg(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS mlme_update_tgt_eht_caps_in_cfg(struct wlan_objmgr_psoc *psoc, struct wma_tgt_cfg *cfg); + +/** + * wlan_mlme_convert_eht_op_bw_to_phy_ch_width() - convert channel width in eht + * operation IE to phy_ch_width + * @channel_width: channel width in eht operation IE + * + * Return: phy_ch_width + */ +enum phy_ch_width wlan_mlme_convert_eht_op_bw_to_phy_ch_width( + uint8_t channel_width); #endif /** diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index a251cf5aa9..03e50eb8d6 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -1042,6 +1042,23 @@ QDF_STATUS mlme_update_tgt_eht_caps_in_cfg(struct wlan_objmgr_psoc *psoc, } return QDF_STATUS_SUCCESS; } + +enum phy_ch_width wlan_mlme_convert_eht_op_bw_to_phy_ch_width( + uint8_t channel_width) +{ + enum phy_ch_width phy_bw = CH_WIDTH_20MHZ; + + if (channel_width == WLAN_EHT_CHWIDTH_320) + phy_bw = CH_WIDTH_320MHZ; + else if (channel_width == WLAN_EHT_CHWIDTH_160) + phy_bw = CH_WIDTH_160MHZ; + else if (channel_width == WLAN_EHT_CHWIDTH_80) + phy_bw = CH_WIDTH_80MHZ; + else if (channel_width == WLAN_EHT_CHWIDTH_40) + phy_bw = CH_WIDTH_40MHZ; + + return phy_bw; +} #endif #ifdef WLAN_FEATURE_11BE_MLO diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c index 932c93d4a1..7e716a4774 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c @@ -799,31 +799,64 @@ lim_update_mcs_rate_set(struct wlan_objmgr_vdev *vdev, tDot11fIEHTCaps *ht_cap) * * Return: None. */ -static void +static QDF_STATUS lim_update_sta_vdev_punc(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, tpSirAssocRsp assoc_resp) { struct wlan_objmgr_vdev *vdev; struct wlan_channel *des_chan; + enum phy_ch_width ori_bw; + uint16_t ori_puncture_bitmap; + uint16_t primary_puncture_bitmap = 0; + if (!assoc_resp->eht_op.disabled_sub_chan_bitmap_present) + return QDF_STATUS_SUCCESS; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_LEGACY_MAC_ID); if (!vdev) { pe_err("vdev not found for id: %d", vdev_id); - return; + return QDF_STATUS_E_FAILURE; } des_chan = wlan_vdev_mlme_get_des_chan(vdev); - des_chan->puncture_bitmap = + ori_puncture_bitmap = *(uint16_t *)assoc_resp->eht_op.disabled_sub_chan_bitmap; - pe_debug("sta vdev %d puncture %d", vdev_id, des_chan->puncture_bitmap); + + ori_bw = wlan_mlme_convert_eht_op_bw_to_phy_ch_width( + assoc_resp->eht_op.channel_width); + wlan_reg_extract_puncture_by_bw(ori_bw, ori_puncture_bitmap, + des_chan->ch_freq, + assoc_resp->eht_op.ccfs1, + CH_WIDTH_20MHZ, + &primary_puncture_bitmap); + if (primary_puncture_bitmap) { + pe_err("sta vdev %d freq %d assoc rsp bw %d puncture 0x%x primary chan is punctured", + vdev_id, des_chan->ch_freq, ori_bw, ori_puncture_bitmap); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + return QDF_STATUS_E_FAILURE; + } + if (des_chan->ch_width == ori_bw) + des_chan->puncture_bitmap = ori_puncture_bitmap; + else + wlan_reg_extract_puncture_by_bw(ori_bw, ori_puncture_bitmap, + des_chan->ch_freq, + assoc_resp->eht_op.ccfs1, + des_chan->ch_width, + &des_chan->puncture_bitmap); + pe_debug("sta vdev %d freq %d assoc rsp bw %d puncture 0x%x center frequency %d intersect bw %d puncture 0x%x", + vdev_id, des_chan->ch_freq, ori_bw, ori_puncture_bitmap, + assoc_resp->eht_op.ccfs1, des_chan->ch_width, + des_chan->puncture_bitmap); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + + return QDF_STATUS_SUCCESS; } #else -static void +static QDF_STATUS lim_update_sta_vdev_punc(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, tpSirAssocRsp assoc_resp) { + return QDF_STATUS_SUCCESS; } #endif @@ -1371,8 +1404,11 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, session_entry->nss); lim_update_vdev_rate_set(mac_ctx->psoc, session_entry->smeSessionId, assoc_rsp); - lim_update_sta_vdev_punc(mac_ctx->psoc, session_entry->smeSessionId, - assoc_rsp); + if (QDF_IS_STATUS_ERROR(lim_update_sta_vdev_punc( + mac_ctx->psoc, + session_entry->smeSessionId, + assoc_rsp))) + goto assocReject; /* * Extract the AP capabilities from the beacon that