diff --git a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h index 22385696a8..1f216ac813 100644 --- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h +++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h @@ -312,8 +312,22 @@ enum qcn_attribute_id { #define WLAN_TPE_IE_MAX_LEN 9 #ifdef WLAN_FEATURE_11BE -/* Bandwidth indication element IE minimum length */ -#define WLAN_BW_IND_IE_MIN_LEN 3 +/* Bandwidth indication element IE maximum length */ +#define WLAN_BW_IND_IE_MAX_LEN 9 + +/* header length is id(1) + length(1)*/ +#define WLAN_IE_HDR_LEN 2 + +/* 20MHz Operating Channel width */ +#define IEEE80211_11BEOP_CHWIDTH_20 0 +/* 40MHz Operating Channel width */ +#define IEEE80211_11BEOP_CHWIDTH_40 1 +/* 80MHz Operating Channel width */ +#define IEEE80211_11BEOP_CHWIDTH_80 2 +/* 160 MHz Operating Channel width */ +#define IEEE80211_11BEOP_CHWIDTH_160 3 +/* 320 MHz Operating Channel width */ +#define IEEE80211_11BEOP_CHWIDTH_320 4 #endif /* Max channel switch time IE length */ @@ -1898,6 +1912,12 @@ struct subelem_header { #define EHTOP_INFO_CHAN_WIDTH_IDX 0 #define EHTOP_INFO_CHAN_WIDTH_BITS 3 +#define BW_IND_PARAM_DISABLED_SC_BITMAP_PRESENT_IDX 1 +#define BW_IND_PARAM_DISABLED_SC_BITMAP_PRESENT_BITS 1 + +#define BW_IND_CHAN_WIDTH_IDX 0 +#define BW_IND_CHAN_WIDTH_BITS 3 + #define EHTOP_RX_MCS_NSS_MAP_IDX 0 #define EHTOP_RX_MCS_NSS_MAP_BITS 4 #define EHTOP_TX_MCS_NSS_MAP_IDX 4 diff --git a/umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h b/umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h index da7d4f8671..1b8c2d3539 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h @@ -582,3 +582,32 @@ QDF_STATUS ml_post_get_link_state_msg(struct wlan_objmgr_vdev *vdev); #endif #endif +#ifdef WLAN_FEATURE_11BE +/** + * util_add_bw_ind() - Adding bandwidth indiacation element + * @bw_ind: pointer to bandwidth indication element + * @ccfs0: EHT Channel Centre Frequency Segment0 information + * @ccfs1: EHT Channel Centre Frequency Segment1 information + * @ch_width: channel width + * @puncture_bitmap: puncturing information + * @bw_ind_len: pointer to length of bandwidth indication element + */ +QDF_STATUS +util_add_bw_ind(struct wlan_ie_bw_ind *bw_ind, uint8_t ccfs0, + uint8_t ccfs1, enum phy_ch_width ch_width, + uint16_t puncture_bitmap, int *bw_ind_len); + +/** + * util_parse_bw_ind() - Parsing of bandwidth indiacation element + * @bw_ind: pointer to bandwidth indication element + * @ccfs0: EHT Channel Centre Frequency Segment0 information + * @ccfs1: EHT Channel Centre Frequency Segment1 information + * @ch_width: channel width + * @puncture_bitmap: puncturing information + */ + +QDF_STATUS +util_parse_bw_ind(struct wlan_ie_bw_ind *bw_ind, uint8_t *ccfs0, + uint8_t *ccfs1, enum phy_ch_width *ch_width, + uint16_t *puncture_bitmap); +#endif diff --git a/umac/mlo_mgr/src/utils_mlo.c b/umac/mlo_mgr/src/utils_mlo.c index 02b723d44a..b42807b341 100644 --- a/umac/mlo_mgr/src/utils_mlo.c +++ b/umac/mlo_mgr/src/utils_mlo.c @@ -4570,3 +4570,122 @@ QDF_STATUS util_get_rvmlie_persta_link_info(uint8_t *mlieseq, } #endif + +#ifdef WLAN_FEATURE_11BE + +QDF_STATUS util_add_bw_ind(struct wlan_ie_bw_ind *bw_ind, uint8_t ccfs0, + uint8_t ccfs1, enum phy_ch_width ch_width, + uint16_t puncture_bitmap, int *bw_ind_len) +{ + uint8_t bw_ind_width; + + if (!bw_ind) { + mlo_err("Pointer to bandwidth indiaction element is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!bw_ind_len) { + mlo_err("Length of bandwidth indaication element is Zero"); + return QDF_STATUS_E_INVAL; + } + + switch (ch_width) { + case CH_WIDTH_20MHZ: + bw_ind_width = IEEE80211_11BEOP_CHWIDTH_20; + break; + case CH_WIDTH_40MHZ: + bw_ind_width = IEEE80211_11BEOP_CHWIDTH_40; + break; + case CH_WIDTH_80MHZ: + bw_ind_width = IEEE80211_11BEOP_CHWIDTH_80; + break; + case CH_WIDTH_160MHZ: + bw_ind_width = IEEE80211_11BEOP_CHWIDTH_160; + break; + case CH_WIDTH_320MHZ: + bw_ind_width = IEEE80211_11BEOP_CHWIDTH_320; + break; + default: + bw_ind_width = IEEE80211_11BEOP_CHWIDTH_20; + } + + bw_ind->elem_id = WLAN_ELEMID_EXTN_ELEM; + *bw_ind_len = WLAN_BW_IND_IE_MAX_LEN; + bw_ind->elem_len = WLAN_BW_IND_IE_MAX_LEN - WLAN_IE_HDR_LEN; + bw_ind->elem_id_extn = WLAN_EXTN_ELEMID_BW_IND; + bw_ind->ccfs0 = ccfs0; + bw_ind->ccfs1 = ccfs1; + QDF_SET_BITS(bw_ind->control, BW_IND_CHAN_WIDTH_IDX, + BW_IND_CHAN_WIDTH_BITS, bw_ind_width); + + if (puncture_bitmap) { + bw_ind->disabled_sub_chan_bitmap[0] = + QDF_GET_BITS(puncture_bitmap, 0, 8); + bw_ind->disabled_sub_chan_bitmap[1] = + QDF_GET_BITS(puncture_bitmap, 8, 8); + QDF_SET_BITS(bw_ind->bw_ind_param, + BW_IND_PARAM_DISABLED_SC_BITMAP_PRESENT_IDX, + BW_IND_PARAM_DISABLED_SC_BITMAP_PRESENT_BITS, 1); + } else { + QDF_SET_BITS(bw_ind->bw_ind_param, + BW_IND_PARAM_DISABLED_SC_BITMAP_PRESENT_IDX, + BW_IND_PARAM_DISABLED_SC_BITMAP_PRESENT_BITS, 0); + bw_ind->elem_len -= + QDF_ARRAY_SIZE(bw_ind->disabled_sub_chan_bitmap); + *bw_ind_len -= + QDF_ARRAY_SIZE(bw_ind->disabled_sub_chan_bitmap); + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS util_parse_bw_ind(struct wlan_ie_bw_ind *bw_ind, uint8_t *ccfs0, + uint8_t *ccfs1, enum phy_ch_width *ch_width, + uint16_t *puncture_bitmap) +{ + uint8_t bw_ind_width; + + if (!bw_ind) { + mlo_err("Pointer to bandwidth indiaction element is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + *ccfs0 = bw_ind->ccfs0; + *ccfs1 = bw_ind->ccfs1; + bw_ind_width = QDF_GET_BITS(bw_ind->control, BW_IND_CHAN_WIDTH_IDX, + BW_IND_CHAN_WIDTH_BITS); + + switch (bw_ind_width) { + case IEEE80211_11BEOP_CHWIDTH_20: + *ch_width = CH_WIDTH_20MHZ; + break; + case IEEE80211_11BEOP_CHWIDTH_40: + *ch_width = CH_WIDTH_40MHZ; + break; + case IEEE80211_11BEOP_CHWIDTH_80: + *ch_width = CH_WIDTH_80MHZ; + break; + case IEEE80211_11BEOP_CHWIDTH_160: + *ch_width = CH_WIDTH_160MHZ; + break; + case IEEE80211_11BEOP_CHWIDTH_320: + *ch_width = CH_WIDTH_320MHZ; + break; + default: + *ch_width = CH_WIDTH_20MHZ; + } + + if (QDF_GET_BITS(bw_ind->bw_ind_param, + BW_IND_PARAM_DISABLED_SC_BITMAP_PRESENT_IDX, + BW_IND_PARAM_DISABLED_SC_BITMAP_PRESENT_BITS)) { + QDF_SET_BITS(*puncture_bitmap, 0, 8, + bw_ind->disabled_sub_chan_bitmap[0]); + QDF_SET_BITS(*puncture_bitmap, 8, 8, + bw_ind->disabled_sub_chan_bitmap[1]); + } else { + *puncture_bitmap = 0; + } + + return QDF_STATUS_SUCCESS; +} +#endif diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c index a41a57e49a..a45ec2d69d 100644 --- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -955,7 +955,7 @@ util_scan_parse_chan_switch_wrapper_ie(struct scan_cache_entry *scan_params, break; #ifdef WLAN_FEATURE_11BE case WLAN_EXTN_ELEMID_BW_IND: - if (sub_ie->ie_len < WLAN_BW_IND_IE_MIN_LEN) + if (sub_ie->ie_len > WLAN_BW_IND_IE_MAX_LEN) return QDF_STATUS_E_INVAL; scan_params->ie_list.bw_ind = (uint8_t *)sub_ie; break;