From 850aa79f0603b4c2698164c7c6f16d2891ea4dc9 Mon Sep 17 00:00:00 2001 From: Shashikala Prabhu Date: Thu, 9 Dec 2021 22:52:31 +0530 Subject: [PATCH] qcacmn: Add changes to get the correct link info offset With the existing offset calculation formula in util_get_link_info_offset function, the calculated offset was always greater than the length of the ML IE. Hence, the above function always returned the value 0 for the offset. The reason is, for example, '(BIT (4) & multi_link_ctrl) * 6'. We are expecting this calculation to return a value of 6, but it is returning 96 (= 0x10*6). Modified the util_get_link_info_offset() to use WLAN_ML_BV_CTRL_PBM_* presence bitmap to get the link info offset. Change-Id: Ic548361ac2e82bddaed574cf197c3523d47304d5 CRs-Fixed: 3091674 --- .../scan/dispatcher/src/wlan_scan_utils_api.c | 73 ++++++++++++++++--- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c index ba809438cb..afe1d2bb5b 100644 --- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -1780,21 +1780,72 @@ static void util_scan_set_security(struct scan_cache_entry *scan_params) #define CMN_INFO_LINK_ID_PRESENT_BIT BIT(5) #define LINK_INFO_MAC_ADDR_PRESENT_BIT BIT(5) +/* This function is implemented as per IEEE802.11be D1.0, there is no difference + * in presence bitmap for beacon, probe response and probe request frames. + * This code is to be revisited for future drafts if the presence bitmap values + * changes for the beacon, probe response and probe request frames. + */ static uint8_t util_get_link_info_offset(uint8_t *ml_ie) { - uint8_t offset = ML_CMN_INFO_OFFSET; - uint8_t ml_ie_len = ml_ie[1]; - uint16_t multi_link_ctrl = *(uint16_t *)(ml_ie + ML_CONTROL_OFFSET); + qdf_size_t ml_ie_len = 0; + qdf_size_t parsed_ie_len = 0; + struct wlan_ie_multilink *mlie_fixed; + uint16_t mlcontrol; + uint16_t presencebm; - offset += (BIT(4) & multi_link_ctrl) * 6 + - (BIT(5) & multi_link_ctrl) * 1 + - (BIT(6) & multi_link_ctrl) * 1 + - (BIT(7) & multi_link_ctrl) * 2 + - (BIT(8) & multi_link_ctrl) * 2 + - (BIT(9) & multi_link_ctrl) * 2; + if (!ml_ie) { + scm_err("ml_ie is null"); + return 0; + } - if (offset < ml_ie_len) - return offset; + ml_ie_len = ml_ie[TAG_LEN_POS]; + if (!ml_ie_len) { + scm_err("ml_ie_len is zero"); + return 0; + } + + if (ml_ie_len < sizeof(struct wlan_ie_multilink)) { + scm_err_rl("Length %zu octets is smaller than required for the fixed portion of Multi-Link element (%zu octets)", + ml_ie_len, sizeof(struct wlan_ie_multilink)); + return 0; + } + + mlie_fixed = (struct wlan_ie_multilink *)ml_ie; + mlcontrol = le16toh(mlie_fixed->mlcontrol); + presencebm = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX, + WLAN_ML_CTRL_PBM_BITS); + + parsed_ie_len += sizeof(*mlie_fixed); + + /* Check if MLD MAC address is present */ + if (presencebm & WLAN_ML_BV_CTRL_PBM_MLDMACADDR_P) + parsed_ie_len += QDF_MAC_ADDR_SIZE; + + /* Check if Link ID info is present */ + if (presencebm & WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P) + parsed_ie_len += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE; + + /* Check if BSS parameter change count is present */ + if (presencebm & WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P) + parsed_ie_len += WLAN_ML_BV_CINFO_BSSPARAMCHNGCNT_SIZE; + + /* Check if Medium Sync Delay Info is present */ + if (presencebm & WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P) + parsed_ie_len += WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_SIZE; + + /* Check if EML cap is present */ + if (presencebm & WLAN_ML_BV_CTRL_PBM_EMLCAP_P) + parsed_ie_len += WLAN_ML_BV_CINFO_EMLCAP_SIZE; + + /* Check if MLD cap is present */ + if (presencebm & WLAN_ML_BV_CTRL_PBM_MLDCAP_P) + parsed_ie_len += WLAN_ML_BV_CINFO_MLDCAP_SIZE; + + /* Offset calculation starts from the beginning of the ML IE (including + * EID) hence, adding the size of IE header to ML IE length. + */ + if (parsed_ie_len < (ml_ie_len + sizeof(struct ie_header))) + return parsed_ie_len; return 0; }