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 15e63f3ceb1e..63ec9d887d04 100644 --- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h +++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h @@ -939,6 +939,42 @@ struct wlan_ie_vhtop { uint16_t vhtop_basic_mcs_set; } qdf_packed; +#define WLAN_HE_PHYCAP_160_SUPPORT BIT(2) +#define WLAN_HE_PHYCAP_80_80_SUPPORT BIT(3) +#define WLAN_HE_MACCAP_LEN 6 +#define WLAN_HE_PHYCAP_LEN 11 +#define WLAN_HE_MAX_MCS_MAPS 3 +/** + * struct wlan_ie_hecaps - HT capabilities + * @elem_id: HE caps IE + * @elem_len: HE caps IE len + * @elem_id_extn: HE caps extension id + * @he_mac_cap: HE mac capabilities + * @he_phy_cap: HE phy capabilities + * @phy_cap_bytes: HT phy capability bytes + * @supported_ch_width_set: Supported channel width set + * @mcs_bw_map: MCS NSS map per bandwidth + * @rx_mcs_map: RX MCS map + * @tx_mcs_map: TX MCS map + */ +struct wlan_ie_hecaps { + uint8_t elem_id; + uint8_t elem_len; + uint8_t elem_id_extn; + uint8_t he_mac_cap[WLAN_HE_MACCAP_LEN]; + union { + uint8_t phy_cap_bytes[WLAN_HE_PHYCAP_LEN]; + struct { + uint32_t reserved:1; + uint32_t supported_ch_width_set:7; + } qdf_packed; + } qdf_packed he_phy_cap; + struct { + uint16_t rx_mcs_map; + uint16_t tx_mcs_map; + } qdf_packed mcs_bw_map[WLAN_HE_MAX_MCS_MAPS]; +} qdf_packed; + /** * struct he_oper_6g_param: 6 Ghz params for HE * @primary_channel: HE 6GHz Primary channel number diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c index 06e8928fa234..6a2dfd37b90a 100644 --- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -1269,21 +1269,47 @@ static int util_scan_scm_calc_nss_supported_by_ap( { struct htcap_cmn_ie *htcap; struct wlan_ie_vhtcaps *vhtcaps; - uint8_t rx_mcs_map; + struct wlan_ie_hecaps *hecaps; + uint16_t rx_mcs_map = 0; htcap = (struct htcap_cmn_ie *) util_scan_entry_htcap(scan_params); vhtcaps = (struct wlan_ie_vhtcaps *) util_scan_entry_vhtcap(scan_params); - if (vhtcaps) { + hecaps = (struct wlan_ie_hecaps *) + util_scan_entry_hecap(scan_params); + + if (hecaps) { + /* Using rx mcs map related to 80MHz or lower as in some + * cases higher mcs may suuport lesser NSS than that + * of lowe mcs. Thus giving max NSS capability. + */ + rx_mcs_map = + qdf_cpu_to_le16(hecaps->mcs_bw_map[0].rx_mcs_map); + } else if (vhtcaps) { rx_mcs_map = vhtcaps->rx_mcs_map; - if ((rx_mcs_map & 0xC0) != 0xC0) + } + + if (hecaps || vhtcaps) { + if ((rx_mcs_map & 0xC000) != 0xC000) + return 8; + + if ((rx_mcs_map & 0x3000) != 0x3000) + return 7; + + if ((rx_mcs_map & 0x0C00) != 0x0C00) + return 6; + + if ((rx_mcs_map & 0x0300) != 0x0300) + return 5; + + if ((rx_mcs_map & 0x00C0) != 0x00C0) return 4; - if ((rx_mcs_map & 0x30) != 0x30) + if ((rx_mcs_map & 0x0030) != 0x0030) return 3; - if ((rx_mcs_map & 0x0C) != 0x0C) + if ((rx_mcs_map & 0x000C) != 0x000C) return 2; } else if (htcap) { if (htcap->mcsset[3])