diff --git a/components/mlme/dispatcher/inc/cfg_mlme_sta.h b/components/mlme/dispatcher/inc/cfg_mlme_sta.h index 802c262dd2..926bd3e6ca 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_sta.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_sta.h @@ -125,7 +125,7 @@ * gStaPrefer80MHzOver160MHz - set sta preference to connect in 80HZ/160HZ * @Min: 0 * @Max: 1 - * @Default: 1 + * @Default: 0 * * This ini is used to set sta preference to connect in 80HZ/160HZ * @@ -142,7 +142,7 @@ */ #define CFG_STA_PREFER_80MHZ_OVER_160MHZ CFG_INI_BOOL( \ "gStaPrefer80MHzOver160MHz", \ - 1, \ + 0, \ "Sta preference to connect in 80HZ/160HZ") /* diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 258678629e..b3a3e6bd4d 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -841,6 +841,9 @@ struct mlme_vht_capabilities_info { uint8_t as_cap; bool disable_ldpc_with_txbf_ap; bool vht_mcs_10_11_supp; + uint8_t extended_nss_bw_supp; + uint8_t vht_extended_nss_bw_cap; + uint8_t max_nsts_total; }; /** diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index e22a1b2133..54cdd05266 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -2640,6 +2640,11 @@ wlan_mlme_cfg_set_vht_chan_width(struct wlan_objmgr_psoc *psoc, uint8_t value) return QDF_STATUS_E_FAILURE; mlme_obj->cfg.vht_caps.vht_cap_info.supp_chan_width = value; + if (value == VHT_CAP_160_AND_80P80_SUPP || + value == VHT_CAP_160_SUPP) { + mlme_obj->cfg.vht_caps.vht_cap_info.vht_extended_nss_bw_cap = 1; + mlme_obj->cfg.vht_caps.vht_cap_info.extended_nss_bw_supp = 0; + } return QDF_STATUS_SUCCESS; } diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 475865b7a2..2206a52446 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -855,15 +855,15 @@ static void hdd_copy_ht_operation(struct hdd_station_ctx *hdd_sta_ctx, static void hdd_copy_vht_center_freq(struct ieee80211_vht_operation *ieee_ops, tDot11fIEVHTOperation *roam_ops) { - ieee_ops->center_freq_seg0_idx = roam_ops->chanCenterFreqSeg1; - ieee_ops->center_freq_seg1_idx = roam_ops->chanCenterFreqSeg2; + ieee_ops->center_freq_seg0_idx = roam_ops->chan_center_freq_seg0; + ieee_ops->center_freq_seg1_idx = roam_ops->chan_center_freq_seg1; } #else static void hdd_copy_vht_center_freq(struct ieee80211_vht_operation *ieee_ops, tDot11fIEVHTOperation *roam_ops) { - ieee_ops->center_freq_seg1_idx = roam_ops->chanCenterFreqSeg1; - ieee_ops->center_freq_seg2_idx = roam_ops->chanCenterFreqSeg2; + ieee_ops->center_freq_seg1_idx = roam_ops->chan_center_freq_seg0; + ieee_ops->center_freq_seg2_idx = roam_ops->chan_center_freq_seg1; } #endif /* KERNEL_VERSION(4, 12, 0) */ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 01d19a638a..62132ce2a4 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1780,9 +1780,8 @@ static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx, struct wiphy *wiphy = hdd_ctx->wiphy; struct ieee80211_supported_band *band_5g = wiphy->bands[HDD_NL80211_BAND_5GHZ]; - uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ; + uint32_t ch_width; struct wma_caps_per_phy caps_per_phy; - uint8_t val = 0; if (!band_5g) { hdd_debug("5GHz band disabled, skipping capability population"); @@ -1802,32 +1801,22 @@ static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx, if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) { - status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, - VHT_CAP_160_AND_80P80_SUPP); - if (QDF_IS_STATUS_ERROR(status)) - hdd_err("could not set the VHT CAP 160"); band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; - ch_width = eHT_CHANNEL_WIDTH_80P80MHZ; + ch_width = VHT_CAP_160_AND_80P80_SUPP; } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) { - status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, - VHT_CAP_160_SUPP); - if (QDF_IS_STATUS_ERROR(status)) - hdd_err("could not set the VHT CAP 160"); band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; - ch_width = eHT_CHANNEL_WIDTH_160MHZ; + ch_width = VHT_CAP_160_SUPP; + } else { + ch_width = VHT_CAP_NO_160M_SUPP; } - status = - ucfg_mlme_cfg_get_vht_chan_width(hdd_ctx->psoc, &val); - if (QDF_IS_STATUS_ERROR(status)) - hdd_err("could not get channel_width"); - - val = QDF_MIN(val, ch_width); - status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, val); + status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width); if (QDF_IS_STATUS_ERROR(status)) hdd_err("could not set the channel width"); + else + hdd_debug("supported channel width %d", ch_width); if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) { band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index b14150e54f..a6f5352afc 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -539,7 +539,9 @@ struct sir_vht_config { uint32_t vht_link_adapt:2; uint32_t rx_antpattern:1; uint32_t tx_antpattern:1; - uint32_t unused:2; + uint32_t extended_nss_bw_supp:2; + uint8_t max_nsts_total:2; + uint8_t vht_extended_nss_bw_cap:1; }; diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index b482c20f0a..2dfdfa6d58 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -168,9 +168,21 @@ #define VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2 780 #define VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2 780 +#define VHT_CAP_NO_160M_SUPP 0 #define VHT_CAP_160_SUPP 1 #define VHT_CAP_160_AND_80P80_SUPP 2 +#define VHT_NO_EXTD_NSS_BW_SUPP 0 +#define VHT_EXTD_NSS_80_HALF_NSS_160 1 +#define VHT_EXTD_NSS_80_HALF_NSS_80P80 2 +#define VHT_EXTD_NSS_80_3QUART_NSS_80P80 3 +#define VHT_EXTD_NSS_160_HALF_NSS_80P80 1 +#define VHT_EXTD_NSS_160_3QUART_NSS_80P80 2 +#define VHT_EXTD_NSS_2X_NSS_160_1X_NSS_80P80 3 +#define VHT_EXTD_NSS_2X_NSS_80_1X_NSS_80P80 3 + +#define VHT_MAX_NSS 8 + #define VHT_MCS_1x1 0xFFFC #define VHT_MCS_2x2 0xFFF3 @@ -1022,7 +1034,7 @@ typedef struct sSirMacMeasReqIE { /* VHT Capabilities Info */ typedef struct sSirMacVHTCapabilityInfo { #ifndef ANI_LITTLE_BIT_ENDIAN - uint32_t reserved1:2; + uint32_t extended_nss_bw_supp:2; uint32_t txAntPattern:1; uint32_t rxAntPattern:1; uint32_t vhtLinkAdaptCap:2; @@ -1062,27 +1074,29 @@ typedef struct sSirMacVHTCapabilityInfo { uint32_t vhtLinkAdaptCap:2; uint32_t rxAntPattern:1; uint32_t txAntPattern:1; - uint32_t reserved1:2; + uint32_t extended_nss_bw_supp:2; #endif } qdf_packed tSirMacVHTCapabilityInfo; typedef struct sSirMacVHTTxSupDataRateInfo { #ifndef ANI_LITTLE_BIT_ENDIAN - uint16_t reserved:3; + uint16_t reserved:2; + uint16_t vht_extended_nss_bw_cap:1; uint16_t txSupDataRate:13; #else uint16_t txSupDataRate:13; - uint16_t reserved:3; + uint16_t vht_extended_nss_bw_cap:1; + uint16_t reserved:2; #endif } qdf_packed tSirMacVHTTxSupDataRateInfo; typedef struct sSirMacVHTRxSupDataRateInfo { #ifndef ANI_LITTLE_BIT_ENDIAN - uint16_t reserved:3; + uint16_t max_nsts_total:3; uint16_t rxSupDataRate:13; #else uint16_t rxSupDataRate:13; - uint16_t reserved:3; + uint16_t max_nsts_total:3; #endif } qdf_packed tSirMacVHTRxSupDataRateInfo; @@ -1947,7 +1961,7 @@ struct he_capability_info { #define SIR_MAC_VHT_CAP_LINK_ADAPT_CAP 26 #define SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN 28 #define SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN 29 -#define SIR_MAC_VHT_CAP_RESERVED2 30 +#define SIR_MAC_VHT_CAP_EXTD_NSS_BW 30 #define SIR_MAC_HT_CAP_ADVCODING_S 0 #define SIR_MAC_HT_CAP_CHWIDTH40_S 1 diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms index ce1e8039ca..e3af3560cc 100644 --- a/core/mac/src/cfg/cfgUtil/dot11f.frms +++ b/core/mac/src/cfg/cfgUtil/dot11f.frms @@ -2398,26 +2398,27 @@ IE VHTCaps (EID_VHT_CAPABILITIES) vhtLinkAdaptCap: 2; rxAntPattern: 1; txAntPattern: 1; - reserved1: 2; + extended_nss_bw_supp: 2; } rxMCSMap, 2; { rxHighSupDataRate: 13; - reserved2: 3; + max_nsts_total: 3; } txMCSMap, 2; { txSupDataRate: 13; - reserved3: 3; + vht_extended_nss_bw_cap: 1; + reserved: 2; } } IE VHTOperation (EID_VHT_OPERATION_ELEMENT) { - chanWidth, 1; - chanCenterFreqSeg1, 1; - chanCenterFreqSeg2, 1; - basicMCSSet, 2; + chanWidth, 1; + chan_center_freq_seg0, 1; + chan_center_freq_seg1, 1; + basicMCSSet, 2; } IE VHTExtBssLoad (EID_VHT_EXT_BSS_LOAD) @@ -2550,7 +2551,8 @@ IE HTInfo (EID_HT_INFO) nonGFDevicesPresent: 1; transmitBurstLimit: 1; obssNonHTStaPresent:1; - reserved: 11; + chan_center_freq_seg2:8; + reserved: 3; } @@ -2577,10 +2579,11 @@ IE HTInfo (EID_HT_INFO) IE OperatingMode (EID_OPERATING_MODE) { { //Operating Mode field - chanWidth: 2; - reserved: 2; - rxNSS: 3; - rxNSSType: 1; + chanWidth: 2; + vht_160_80p80_supp: 1; + no_ldpc: 1; + rxNSS: 3; + rxNSSType: 1; } } diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h index d8b0d3555f..89436fbf02 100644 --- a/core/mac/src/include/dot11f.h +++ b/core/mac/src/include/dot11f.h @@ -26,7 +26,7 @@ * * * This file was automatically generated by 'framesc' - * Fri Sep 13 10:34:49 2019 from the following file(s): + * Thu Sep 19 14:00:22 2019 from the following file(s): * * dot11f.frms * @@ -3643,13 +3643,14 @@ typedef struct sDot11fIEVHTCaps { uint32_t vhtLinkAdaptCap:2; uint32_t rxAntPattern:1; uint32_t txAntPattern:1; - uint32_t reserved1:2; + uint32_t extended_nss_bw_supp:2; uint16_t rxMCSMap; uint16_t rxHighSupDataRate:13; - uint16_t reserved2:3; + uint16_t max_nsts_total:3; uint16_t txMCSMap; uint16_t txSupDataRate:13; - uint16_t reserved3:3; + uint16_t vht_extended_nss_bw_cap:1; + uint16_t reserved:2; } tDot11fIEVHTCaps; #define DOT11F_EID_VHTCAPS (191) @@ -3689,8 +3690,8 @@ uint32_t dot11f_get_packed_ie_VHTCaps( typedef struct sDot11fIEVHTOperation { uint8_t present; uint8_t chanWidth; - uint8_t chanCenterFreqSeg1; - uint8_t chanCenterFreqSeg2; + uint8_t chan_center_freq_seg0; + uint8_t chan_center_freq_seg1; uint16_t basicMCSSet; } tDot11fIEVHTOperation; @@ -5355,7 +5356,8 @@ typedef struct sDot11fIEHTInfo { uint16_t nonGFDevicesPresent:1; uint16_t transmitBurstLimit:1; uint16_t obssNonHTStaPresent:1; - uint16_t reserved:11; + uint16_t chan_center_freq_seg2:8; + uint16_t reserved:3; uint16_t basicSTBCMCS:7; uint16_t dualCTSProtection:1; uint16_t secondaryBeacon:1; @@ -5863,7 +5865,8 @@ uint32_t dot11f_get_packed_ie_OBSSScanParameters( typedef struct sDot11fIEOperatingMode { uint8_t present; uint8_t chanWidth:2; - uint8_t reserved:2; + uint8_t vht_160_80p80_supp:1; + uint8_t no_ldpc:1; uint8_t rxNSS:3; uint8_t rxNSSType:1; } tDot11fIEOperatingMode; diff --git a/core/mac/src/include/dph_global.h b/core/mac/src/include/dph_global.h index 3e9d5e2a2e..da370679c5 100644 --- a/core/mac/src/include/dph_global.h +++ b/core/mac/src/include/dph_global.h @@ -148,10 +148,14 @@ typedef struct sDphHashNode { uint8_t staType; uint8_t vhtSupportedChannelWidthSet; + enum phy_ch_width ch_width; uint8_t vhtSupportedRxNss; uint8_t vhtBeamFormerCapable; uint8_t vht_su_bfee_capable; uint8_t vht_mcs_10_11_supp; + uint8_t vht_160mhz_nss; + uint8_t vht_80p80mhz_nss; + uint8_t vht_extended_nss_bw_cap; #ifdef WLAN_FEATURE_11W TX_TIMER pmfSaQueryTimer; uint16_t pmfSaQueryCurrentTransId; diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c index b5cc37bdf4..82fd7d8903 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/core/mac/src/pe/lim/lim_assoc_utils.c @@ -1359,11 +1359,124 @@ lim_decide_short_slot(struct mac_context *mac_ctx, tpDphHashNode sta_ds, } } +static uint8_t lim_get_nss_from_vht_mcs_map(uint16_t mcs_map) +{ + uint8_t nss = 0; + uint16_t mcs_mask = 0x3; + + for (nss = 0; nss < VHT_MAX_NSS; nss++) { + if ((mcs_map & mcs_mask) == mcs_mask) + return nss; + + mcs_mask = (mcs_mask << 2); + } + + return nss; +} + +static void lim_get_vht_gt80_nss(struct mac_context *mac_ctx, + struct sDphHashNode *sta_ds, + tDot11fIEVHTCaps *vht_caps, + struct pe_session *session) +{ + uint8_t nss; + + if (!vht_caps->vht_extended_nss_bw_cap) { + sta_ds->vht_160mhz_nss = 0; + sta_ds->vht_80p80mhz_nss = 0; + pe_debug("peer does not support vht extnd nss bw"); + + return; + } + + nss = lim_get_nss_from_vht_mcs_map(vht_caps->rxMCSMap); + + if (!nss) { + pe_debug("Invalid peer VHT MCS map %0X", vht_caps->rxMCSMap); + nss = 1; + } + + switch (vht_caps->supportedChannelWidthSet) { + case VHT_CAP_NO_160M_SUPP: + if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_80_HALF_NSS_160) { + sta_ds->vht_160mhz_nss = nss / 2; + sta_ds->vht_80p80mhz_nss = 0; + } else if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_80_HALF_NSS_80P80) { + sta_ds->vht_160mhz_nss = nss / 2; + sta_ds->vht_80p80mhz_nss = nss / 2; + } else if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_80_3QUART_NSS_80P80) { + sta_ds->vht_160mhz_nss = (nss * 3) / 4; + sta_ds->vht_80p80mhz_nss = (nss * 3) / 4; + } else { + sta_ds->vht_160mhz_nss = 0; + sta_ds->vht_80p80mhz_nss = 0; + } + break; + case VHT_CAP_160_SUPP: + sta_ds->vht_160mhz_nss = nss; + if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_160_HALF_NSS_80P80) { + sta_ds->vht_80p80mhz_nss = nss / 2; + } else if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_160_3QUART_NSS_80P80) { + sta_ds->vht_80p80mhz_nss = (nss * 3) / 4; + } else if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_2X_NSS_160_1X_NSS_80P80) { + if (nss > (VHT_MAX_NSS / 2)) { + pe_debug("Invalid extnd nss bw support val"); + sta_ds->vht_80p80mhz_nss = nss / 2; + break; + } + sta_ds->vht_160mhz_nss = nss * 2; + if (session->nss == MAX_VDEV_NSS) + break; + if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2) + break; + session->nss *= 2; + } else { + sta_ds->vht_80p80mhz_nss = 0; + } + break; + case VHT_CAP_160_AND_80P80_SUPP: + if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_2X_NSS_80_1X_NSS_80P80) { + if (nss > (VHT_MAX_NSS / 2)) { + pe_debug("Invalid extnd nss bw support val"); + break; + } + if (session->nss == MAX_VDEV_NSS) + break; + if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2) + break; + session->nss *= 2; + } else { + sta_ds->vht_160mhz_nss = nss; + sta_ds->vht_80p80mhz_nss = nss; + } + break; + default: + sta_ds->vht_160mhz_nss = 0; + sta_ds->vht_80p80mhz_nss = 0; + } + pe_debug("AP Nss config: 160MHz: %d, 80P80MHz %d", + sta_ds->vht_160mhz_nss, sta_ds->vht_80p80mhz_nss); + sta_ds->vht_160mhz_nss = QDF_MIN(sta_ds->vht_160mhz_nss, session->nss); + sta_ds->vht_80p80mhz_nss = QDF_MIN(sta_ds->vht_80p80mhz_nss, + session->nss); + pe_debug("Session Nss config: 160MHz: %d, 80P80MHz %d, session Nss %d", + sta_ds->vht_160mhz_nss, sta_ds->vht_80p80mhz_nss, + session->nss); +} + QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, struct supported_rates *rates, tDot11fIEVHTCaps *peer_vht_caps, struct pe_session *session_entry, - uint8_t nss) + uint8_t nss, + struct sDphHashNode *sta_ds) { uint32_t self_sta_dot11mode = 0; uint16_t mcs_map_mask = MCSMAPMASK1x1; @@ -1375,6 +1488,9 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, if (!IS_DOT11_MODE_VHT(self_sta_dot11mode)) return QDF_STATUS_SUCCESS; + if (!peer_vht_caps || !peer_vht_caps->present) + return QDF_STATUS_SUCCESS; + vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; rates->vhtRxMCSMap = (uint16_t)vht_cap_info->rx_mcs_map; @@ -1412,9 +1528,6 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, } } - if ((!peer_vht_caps) || (!peer_vht_caps->present)) - return QDF_STATUS_SUCCESS; - rates->vhtTxHighestDataRate = QDF_MIN(rates->vhtTxHighestDataRate, peer_vht_caps->txSupDataRate); @@ -1428,24 +1541,19 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, if ((peer_vht_caps->txMCSMap & mcs_map_mask) < (rates->vhtRxMCSMap & mcs_map_mask)) { rates->vhtRxMCSMap &= ~(mcs_map_mask); - rates->vhtRxMCSMap |= - (peer_vht_caps->txMCSMap & mcs_map_mask); + rates->vhtRxMCSMap |= (peer_vht_caps->txMCSMap & mcs_map_mask); } if ((peer_vht_caps->rxMCSMap & mcs_map_mask) < (rates->vhtTxMCSMap & mcs_map_mask)) { rates->vhtTxMCSMap &= ~(mcs_map_mask); - rates->vhtTxMCSMap |= - (peer_vht_caps->rxMCSMap & mcs_map_mask); + rates->vhtTxMCSMap |= (peer_vht_caps->rxMCSMap & mcs_map_mask); } if (mcs_map_mask2x2) { - uint16_t peer_mcs_map, self_mcs_map; - peer_mcs_map = - peer_vht_caps->txMCSMap & mcs_map_mask2x2; - self_mcs_map = - rates->vhtRxMCSMap & mcs_map_mask2x2; + peer_mcs_map = peer_vht_caps->txMCSMap & mcs_map_mask2x2; + self_mcs_map = rates->vhtRxMCSMap & mcs_map_mask2x2; if ((self_mcs_map != mcs_map_mask2x2) && ((peer_mcs_map == mcs_map_mask2x2) || @@ -1454,10 +1562,8 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, rates->vhtRxMCSMap |= peer_mcs_map; } - peer_mcs_map = - (peer_vht_caps->rxMCSMap & mcs_map_mask2x2); - self_mcs_map = - (rates->vhtTxMCSMap & mcs_map_mask2x2); + peer_mcs_map = (peer_vht_caps->rxMCSMap & mcs_map_mask2x2); + self_mcs_map = (rates->vhtTxMCSMap & mcs_map_mask2x2); if ((self_mcs_map != mcs_map_mask2x2) && ((peer_mcs_map == mcs_map_mask2x2) || @@ -1466,18 +1572,24 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, rates->vhtTxMCSMap |= peer_mcs_map; } } - pe_debug("enable2x2 - %d nss %d vhtRxMCSMap - %x vhtTxMCSMap - %x", vht_cap_info->enable2x2, nss, rates->vhtRxMCSMap, rates->vhtTxMCSMap); - if (session_entry) { - session_entry->supported_nss_1x1 = - ((rates->vhtTxMCSMap & VHT_MCS_1x1) == - VHT_MCS_1x1) ? true : false; - pe_debug("VHT supported nss 1x1: %d", - session_entry->supported_nss_1x1); - } + if (!session_entry) + return QDF_STATUS_SUCCESS; + + session_entry->supported_nss_1x1 = + ((rates->vhtTxMCSMap & VHT_MCS_1x1) == VHT_MCS_1x1) ? + true : false; + pe_debug("VHT supported nss 1x1: %d", session_entry->supported_nss_1x1); + + if (!sta_ds || CH_WIDTH_80MHZ >= session_entry->ch_width) + return QDF_STATUS_SUCCESS; + + sta_ds->vht_extended_nss_bw_cap = + peer_vht_caps->vht_extended_nss_bw_cap; + lim_get_vht_gt80_nss(mac_ctx, sta_ds, peer_vht_caps, session_entry); return QDF_STATUS_SUCCESS; } @@ -1605,8 +1717,8 @@ QDF_STATUS lim_populate_own_rate_set(struct mac_context *mac_ctx, for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) pe_debug("%x ", rates->supportedMCSSet[i]); } - lim_populate_vht_mcs_set(mac_ctx, rates, vht_caps, - session_entry, session_entry->nss); + lim_populate_vht_mcs_set(mac_ctx, rates, vht_caps, session_entry, + session_entry->nss, NULL); lim_populate_he_mcs_set(mac_ctx, rates, he_caps, session_entry, session_entry->nss); @@ -1641,7 +1753,8 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, uint8_t basicOnly, struct pe_session *pe_session, tDot11fIEVHTCaps *pVHTCaps, - tDot11fIEhe_cap *he_caps) + tDot11fIEhe_cap *he_caps, + struct sDphHashNode *sta_ds) { tSirMacRateSet tempRateSet; tSirMacRateSet tempRateSet2; @@ -1772,8 +1885,8 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, pe_debug("HT supported nss 1x1: %d", pe_session->supported_nss_1x1); } - lim_populate_vht_mcs_set(mac, pRates, pVHTCaps, - pe_session, pe_session->nss); + lim_populate_vht_mcs_set(mac, pRates, pVHTCaps, pe_session, + pe_session->nss, sta_ds); lim_populate_he_mcs_set(mac, pRates, he_caps, pe_session, pe_session->nss); @@ -2012,7 +2125,7 @@ QDF_STATUS lim_populate_matching_rate_set(struct mac_context *mac_ctx, } } lim_populate_vht_mcs_set(mac_ctx, &sta_ds->supportedRates, vht_caps, - session_entry, session_entry->nss); + session_entry, session_entry->nss, sta_ds); lim_populate_he_mcs_set(mac_ctx, &sta_ds->supportedRates, he_caps, session_entry, session_entry->nss); /* @@ -2074,8 +2187,8 @@ static uint32_t lim_populate_vht_caps(tDot11fIEVHTCaps input_caps) SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | (input_caps.txAntPattern << SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | - (input_caps.reserved1 << - SIR_MAC_VHT_CAP_RESERVED2)); + (input_caps.extended_nss_bw_supp << + SIR_MAC_VHT_CAP_EXTD_NSS_BW)); return vht_caps; } @@ -2259,7 +2372,7 @@ lim_add_sta(struct mac_context *mac_ctx, add_sta_params->maxAmpduSize = sta_ds->htMaxRxAMpduFactor; add_sta_params->fShortGI20Mhz = sta_ds->htShortGI20Mhz; add_sta_params->fShortGI40Mhz = sta_ds->htShortGI40Mhz; - add_sta_params->ch_width = sta_ds->htSupportedChannelWidthSet; + add_sta_params->ch_width = sta_ds->ch_width; add_sta_params->mimoPS = sta_ds->htMIMOPSState; pe_debug("maxAmpduDensity: %d maxAmpduDensity: %d", @@ -3414,8 +3527,8 @@ static void lim_update_vhtcaps_assoc_resp(struct mac_context *mac_ctx, SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | (vht_caps->txAntPattern << SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | - (vht_caps->reserved1 << - SIR_MAC_VHT_CAP_RESERVED2)); + (vht_caps->extended_nss_bw_supp << + SIR_MAC_VHT_CAP_EXTD_NSS_BW)); pAddBssParams->staContext.maxAmpduSize = SIR_MAC_GET_VHT_MAX_AMPDU_EXPO( @@ -3665,6 +3778,19 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp if (vht_caps && pAddBssParams->staContext.stbc_capable) pAddBssParams->staContext.stbc_capable = vht_caps->rxSTBC; + if (pe_session->ch_width == CH_WIDTH_160MHZ || + pe_session->ch_width == CH_WIDTH_80P80MHZ) { + sta_context->vht_160mhz_nss = + sta->vht_160mhz_nss; + sta_context->vht_80p80mhz_nss = + sta->vht_80p80mhz_nss; + sta_context->vht_extended_nss_bw_cap = + sta->vht_extended_nss_bw_cap; + } else { + sta_context->vht_160mhz_nss = 0; + sta_context->vht_80p80mhz_nss = 0; + sta_context->vht_extended_nss_bw_cap = 0; + } } if (lim_is_session_he_capable(pe_session) && pAssocRsp->he_cap.present) { @@ -4166,7 +4292,7 @@ QDF_STATUS lim_sta_send_add_bss_pre_assoc(struct mac_context *mac, pBeaconStruct->HTCaps.supportedMCSSet, false, pe_session, &pBeaconStruct->VHTCaps, - &pBeaconStruct->he_cap); + &pBeaconStruct->he_cap, NULL); pAddBssParams->staContext.encryptType = pe_session->encryptType; diff --git a/core/mac/src/pe/lim/lim_assoc_utils.h b/core/mac/src/pe/lim/lim_assoc_utils.h index d89ef88ecb..8f7fd3ccc0 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.h +++ b/core/mac/src/pe/lim/lim_assoc_utils.h @@ -62,7 +62,8 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, uint8_t basicOnly, struct pe_session *pe_session, tDot11fIEVHTCaps *pVHTCaps, - tDot11fIEhe_cap *he_caps); + tDot11fIEhe_cap *he_caps, + struct sDphHashNode *sta_ds); /** * lim_populate_own_rate_set() - comprises the basic and extended rates read @@ -311,6 +312,7 @@ void lim_send_sme_tsm_ie_ind(struct mac_context *mac, * @peer_vht_caps: pointer to peer vht capabilities * @session_entry: pe session entry * @nss: number of spatial streams + * @sta_ds: pointer to peer sta data structure * * Populates vht mcs rate set based on peer and self capabilities * @@ -320,7 +322,8 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, struct supported_rates *rates, tDot11fIEVHTCaps *peer_vht_caps, struct pe_session *session_entry, - uint8_t nss); + uint8_t nss, + struct sDphHashNode *sta_ds); /** * lim_extract_ies_from_deauth_disassoc() - Extract IEs from deauth/disassoc diff --git a/core/mac/src/pe/lim/lim_ft.c b/core/mac/src/pe/lim/lim_ft.c index 6639864a2a..017857ddd7 100644 --- a/core/mac/src/pe/lim/lim_ft.c +++ b/core/mac/src/pe/lim/lim_ft.c @@ -233,8 +233,8 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | (pBeaconStruct->VHTCaps.txAntPattern << SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | - (pBeaconStruct->VHTCaps.reserved1 << - SIR_MAC_VHT_CAP_RESERVED2)); + (pBeaconStruct->VHTCaps.extended_nss_bw_supp << + SIR_MAC_VHT_CAP_EXTD_NSS_BW)); } else { pAddBssParams->vhtCapable = 0; } @@ -343,7 +343,7 @@ void lim_ft_prepare_add_bss_req(struct mac_context *mac, pBeaconStruct->HTCaps.supportedMCSSet, false, ft_session, &pBeaconStruct->VHTCaps, - &pBeaconStruct->he_cap); + &pBeaconStruct->he_cap, NULL); } pAddBssParams->maxTxPower = ft_session->maxTxPower; @@ -561,9 +561,9 @@ void lim_fill_ft_session(struct mac_context *mac, ft_session->ch_width = pBeaconStruct->VHTOperation.chanWidth + 1; ft_session->ch_center_freq_seg0 = - pBeaconStruct->VHTOperation.chanCenterFreqSeg1; + pBeaconStruct->VHTOperation.chan_center_freq_seg0; ft_session->ch_center_freq_seg1 = - pBeaconStruct->VHTOperation.chanCenterFreqSeg2; + pBeaconStruct->VHTOperation.chan_center_freq_seg1; } else { if (pBeaconStruct->HTInfo.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index 1228c40782..09d4e3a9e8 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -1488,11 +1488,17 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, *assoc_req_copied = true; } - sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present; - if ((vht_caps) && vht_caps->present) - sta_ds->mlmStaContext.vhtCapability = vht_caps->present; - else - sta_ds->mlmStaContext.vhtCapability = false; + if (!assoc_req->wmeInfoPresent) { + sta_ds->mlmStaContext.htCapability = 0; + sta_ds->mlmStaContext.vhtCapability = 0; + } else { + sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present; + if ((vht_caps) && vht_caps->present) + sta_ds->mlmStaContext.vhtCapability = vht_caps->present; + else + sta_ds->mlmStaContext.vhtCapability = false; + } + lim_update_stads_he_capable(sta_ds, assoc_req); sta_ds->qos.addtsPresent = (assoc_req->addtsPresent == 0) ? false : true; @@ -1523,7 +1529,7 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, sta_ds->mlmStaContext.capabilityInfo = assoc_req->capabilityInfo; if (IS_DOT11_MODE_HT(session->dot11mode) && - assoc_req->HTCaps.present && assoc_req->wmeInfoPresent) { + sta_ds->mlmStaContext.htCapability) { sta_ds->htGreenfield = (uint8_t) assoc_req->HTCaps.greenField; sta_ds->htAMpduDensity = assoc_req->HTCaps.mpduDensity; sta_ds->htDsssCckRate40MHzSupport = @@ -1558,66 +1564,63 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, sta_ds->htSupportedChannelWidthSet = (uint8_t) assoc_req->HTCaps.supportedChannelWidthSet; - /* - * peer just follows AP; so when we are softAP/GO, - * we just store our session entry's secondary channel offset - * here in peer INFRA STA. However, if peer's 40MHz channel - * width support is disabled then secondary channel will be zero - */ - sta_ds->htSecondaryChannelOffset = - (sta_ds->htSupportedChannelWidthSet) ? - session->htSecondaryChannelOffset : 0; - if (assoc_req->operMode.present) { - enum phy_ch_width ch_width; - - ch_width = assoc_req->operMode.chanWidth; - if (session->ch_width < ch_width) - ch_width = session->ch_width; - - sta_ds->vhtSupportedChannelWidthSet = - (uint8_t) ((ch_width == CH_WIDTH_80MHZ) ? - WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ : - WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ); - sta_ds->htSupportedChannelWidthSet = - (uint8_t) (ch_width ? - eHT_CHANNEL_WIDTH_40MHZ : - eHT_CHANNEL_WIDTH_20MHZ); - } else if ((vht_caps) && vht_caps->present) { + if (session->ch_width > CH_WIDTH_20MHZ && + session->ch_width <= CH_WIDTH_80P80MHZ && + sta_ds->htSupportedChannelWidthSet) { /* - * Check if STA has enabled it's channel bonding mode. - * If channel bonding mode is enabled, we decide based - * on SAP's current configuration. else, we set it to - * VHT20. + * peer just follows AP; so when we are softAP/GO, + * we just store our session entry's secondary channel + * offset here in peer INFRA STA. However, if peer's + * 40MHz channel width support is disabled then + * secondary channel will be zero */ - sta_ds->vhtSupportedChannelWidthSet = - (uint8_t) ((sta_ds->htSupportedChannelWidthSet - == eHT_CHANNEL_WIDTH_20MHZ) ? - WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ : - session->ch_width - 1); - sta_ds->htMaxRxAMpduFactor = - vht_caps->maxAMPDULenExp; + sta_ds->htSecondaryChannelOffset = + session->htSecondaryChannelOffset; + sta_ds->ch_width = CH_WIDTH_40MHZ; + if (sta_ds->mlmStaContext.vhtCapability) { + if (assoc_req->operMode.present) { + sta_ds->ch_width = + assoc_req->operMode.chanWidth; + } else if (vht_caps->supportedChannelWidthSet == + VHT_CAP_160_AND_80P80_SUPP) { + sta_ds->ch_width = CH_WIDTH_80P80MHZ; + } else if (vht_caps->supportedChannelWidthSet == + VHT_CAP_160_SUPP) { + if (vht_caps->vht_extended_nss_bw_cap && + vht_caps->extended_nss_bw_supp) + sta_ds->ch_width = + CH_WIDTH_80P80MHZ; + else + sta_ds->ch_width = + CH_WIDTH_160MHZ; + } else if (vht_caps->vht_extended_nss_bw_cap) { + if (vht_caps->extended_nss_bw_supp == + VHT_EXTD_NSS_80_HALF_NSS_160) + sta_ds->ch_width = + CH_WIDTH_160MHZ; + else if (vht_caps->extended_nss_bw_supp > + VHT_EXTD_NSS_80_HALF_NSS_160) + sta_ds->ch_width = + CH_WIDTH_80P80MHZ; + else + sta_ds->ch_width = + CH_WIDTH_80MHZ; + } else { + sta_ds->ch_width = CH_WIDTH_80MHZ; + } + + sta_ds->ch_width = QDF_MIN(sta_ds->ch_width, + session->ch_width); + } + } else { + sta_ds->htSupportedChannelWidthSet = 0; + sta_ds->htSecondaryChannelOffset = 0; + sta_ds->ch_width = CH_WIDTH_20MHZ; } - /* Lesser among the AP and STA bandwidth of operation. */ - sta_ds->htSupportedChannelWidthSet = - (sta_ds->htSupportedChannelWidthSet < - session->htSupportedChannelWidthSet) ? - sta_ds->htSupportedChannelWidthSet : - session->htSupportedChannelWidthSet; - - if (!sta_ds->htSupportedChannelWidthSet) - sta_ds->vhtSupportedChannelWidthSet = - WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; - sta_ds->htLdpcCapable = (uint8_t) assoc_req->HTCaps.advCodingCap; } - if ((vht_caps) && vht_caps->present && - assoc_req->wmeInfoPresent) { - sta_ds->vhtLdpcCapable = - (uint8_t) vht_caps->ldpcCodingCap; - } - if (assoc_req->ExtCap.present) sta_ds->non_ecsa_capable = !((struct s_ext_cap *)assoc_req->ExtCap.bytes)-> @@ -1625,12 +1628,10 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, else sta_ds->non_ecsa_capable = 1; - if (!assoc_req->wmeInfoPresent) { - sta_ds->mlmStaContext.htCapability = 0; - sta_ds->mlmStaContext.vhtCapability = 0; - } - - if (sta_ds->mlmStaContext.vhtCapability && vht_caps) { + if (sta_ds->mlmStaContext.vhtCapability && + IS_DOT11_MODE_VHT(session->dot11mode)) { + sta_ds->vhtLdpcCapable = + (uint8_t)vht_caps->ldpcCodingCap; if (session->vht_config.su_beam_formee && vht_caps->suBeamFormerCap) sta_ds->vhtBeamFormerCapable = 1; 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 d3e451fa7e..3f48fecf43 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 @@ -193,7 +193,8 @@ void lim_update_assoc_sta_datas(struct mac_context *mac_ctx, if (lim_populate_peer_rate_set(mac_ctx, &sta_ds->supportedRates, assoc_rsp->HTCaps.supportedMCSSet, false, session_entry, - vht_caps, he_cap) != QDF_STATUS_SUCCESS) { + vht_caps, he_cap, sta_ds) != + QDF_STATUS_SUCCESS) { pe_err("could not get rateset and extended rate set"); return; } diff --git a/core/mac/src/pe/lim/lim_process_mlm_host_roam.c b/core/mac/src/pe/lim/lim_process_mlm_host_roam.c index 9c17c1fb3a..c2b2d3ca03 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_host_roam.c +++ b/core/mac/src/pe/lim/lim_process_mlm_host_roam.c @@ -485,7 +485,7 @@ void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac, pAddStaParams->updateSta = false; lim_populate_peer_rate_set(mac, &pAddStaParams->supportedRates, NULL, - false, pe_session, NULL, NULL); + false, pe_session, NULL, NULL, NULL); if (pe_session->htCapability) { pAddStaParams->htCapable = pe_session->htCapability; diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c index d3fedfe3ef..85b692698d 100644 --- a/core/mac/src/pe/lim/lim_process_tdls.c +++ b/core/mac/src/pe/lim/lim_process_tdls.c @@ -2185,7 +2185,8 @@ lim_tdls_populate_dot11f_vht_caps(struct mac_context *mac, uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap; pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern; pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern; - pDot11f->reserved1 = uVHTCapabilityInfo.vhtCapInfo.reserved1; + pDot11f->extended_nss_bw_supp = + uVHTCapabilityInfo.vhtCapInfo.extended_nss_bw_supp; pDot11f->rxMCSMap = add_sta_req->vht_cap.supp_mcs.rx_mcs_map; @@ -2193,6 +2194,8 @@ lim_tdls_populate_dot11f_vht_caps(struct mac_context *mac, uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff; pDot11f->rxHighSupDataRate = uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate; + pDot11f->max_nsts_total = + uVHTSupDataRateInfo.vhtRxsupDataRateInfo.max_nsts_total; pDot11f->txMCSMap = add_sta_req->vht_cap.supp_mcs.tx_mcs_map; @@ -2201,7 +2204,8 @@ lim_tdls_populate_dot11f_vht_caps(struct mac_context *mac, pDot11f->txSupDataRate = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate; - pDot11f->reserved3 = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved; + pDot11f->vht_extended_nss_bw_cap = + uVHTSupDataRateInfo.vhtTxSupDataRateInfo.vht_extended_nss_bw_cap; lim_log_vht_cap(mac, pDot11f); @@ -2396,7 +2400,7 @@ lim_tdls_populate_matching_rate_set(struct mac_context *mac_ctx, } } lim_populate_vht_mcs_set(mac_ctx, &stads->supportedRates, vht_caps, - session_entry, nss); + session_entry, nss, NULL); /** * Set the erpEnabled bit if the phy is in G mode and at least * one A rate is supported diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.c b/core/mac/src/pe/lim/lim_prop_exts_utils.c index c47d919fe0..769e5e6960 100644 --- a/core/mac/src/pe/lim/lim_prop_exts_utils.c +++ b/core/mac/src/pe/lim/lim_prop_exts_utils.c @@ -214,10 +214,10 @@ static inline bool lim_extract_adaptive_11r_cap(uint8_t *ie, uint16_t ie_len) } #endif -void -lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, - uint16_t ie_len, uint8_t *qos_cap, uint8_t *uapsd, - int8_t *local_constraint, struct pe_session *session) +void lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, + uint16_t ie_len, uint8_t *qos_cap, + uint8_t *uapsd, int8_t *local_constraint, + struct pe_session *session) { tSirProbeRespBeacon *beacon_struct; uint8_t ap_bcon_ch_width; @@ -227,6 +227,8 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, uint8_t vht_ch_wd; uint8_t center_freq_diff; struct s_ext_cap *ext_cap; + uint8_t chan_center_freq_seg1; + tDot11fIEVHTCaps *vht_caps; beacon_struct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon)); if (!beacon_struct) @@ -262,6 +264,7 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps)); vht_op = &beacon_struct->VHTOperation; + vht_caps = &beacon_struct->VHTCaps; if (IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps) && vht_op->present && session->vhtCapability) { @@ -286,16 +289,26 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, vht_op->chanWidth) { /* If VHT is supported min 80 MHz support is must */ ap_bcon_ch_width = vht_op->chanWidth; - if ((ap_bcon_ch_width == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) && - vht_op->chanCenterFreqSeg2) { - new_ch_width_dfn = true; - if (vht_op->chanCenterFreqSeg2 > - vht_op->chanCenterFreqSeg1) - center_freq_diff = vht_op->chanCenterFreqSeg2 - - vht_op->chanCenterFreqSeg1; + if (vht_caps->vht_extended_nss_bw_cap) { + if (!vht_caps->extended_nss_bw_supp) + chan_center_freq_seg1 = + vht_op->chan_center_freq_seg1; else - center_freq_diff = vht_op->chanCenterFreqSeg1 - - vht_op->chanCenterFreqSeg2; + chan_center_freq_seg1 = + beacon_struct->HTInfo.chan_center_freq_seg2; + } else { + chan_center_freq_seg1 = vht_op->chan_center_freq_seg1; + } + if (chan_center_freq_seg1 && + (ap_bcon_ch_width == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)) { + new_ch_width_dfn = true; + if (chan_center_freq_seg1 > + vht_op->chan_center_freq_seg0) + center_freq_diff = chan_center_freq_seg1 - + vht_op->chan_center_freq_seg0; + else + center_freq_diff = vht_op->chan_center_freq_seg0 - + chan_center_freq_seg1; if (center_freq_diff == 8) ap_bcon_ch_width = WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ; @@ -320,22 +333,22 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, } /* * VHT OP IE old definition: - * vht_op->chanCenterFreqSeg1: center freq of 80MHz/160MHz/ + * vht_op->chan_center_freq_seg0: center freq of 80MHz/160MHz/ * primary 80 in 80+80MHz. * - * vht_op->chanCenterFreqSeg2: center freq of secondary 80 + * vht_op->chan_center_freq_seg1: center freq of secondary 80 * in 80+80MHz. * * VHT OP IE NEW definition: - * vht_op->chanCenterFreqSeg1: center freq of 80MHz/primary + * vht_op->chan_center_freq_seg0: center freq of 80MHz/primary * 80 in 80+80MHz/center freq of the 80 MHz channel segment * that contains the primary channel in 160MHz mode. * - * vht_op->chanCenterFreqSeg2: center freq of secondary 80 + * vht_op->chan_center_freq_seg1: center freq of secondary 80 * in 80+80MHz/center freq of 160MHz. */ - session->ch_center_freq_seg0 = vht_op->chanCenterFreqSeg1; - session->ch_center_freq_seg1 = vht_op->chanCenterFreqSeg2; + session->ch_center_freq_seg0 = vht_op->chan_center_freq_seg0; + session->ch_center_freq_seg1 = chan_center_freq_seg1; if (vht_ch_wd == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) { /* DUT or AP supports only 160MHz */ if (ap_bcon_ch_width == @@ -343,7 +356,7 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, /* AP is in 160MHz mode */ if (!new_ch_width_dfn) { session->ch_center_freq_seg1 = - vht_op->chanCenterFreqSeg1; + vht_op->chan_center_freq_seg0; session->ch_center_freq_seg0 = lim_get_80Mhz_center_channel( beacon_struct->channelNumber); @@ -372,10 +385,6 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie, session->ch_center_freq_seg0, session->ch_center_freq_seg1, session->ch_width); - if (CH_WIDTH_80MHZ < session->ch_width) { - session->vht_config.su_beam_former = 0; - session->nss = 1; - } } if (session->vhtCapability && diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index c799827dc4..78bc41f87f 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -5435,21 +5435,22 @@ void lim_set_vht_caps(struct mac_context *p_mac, struct pe_session *p_session_en vht_cap->vhtLinkAdaptCap = dot11_vht_cap.vhtLinkAdaptCap; vht_cap->rxAntPattern = dot11_vht_cap.rxAntPattern; vht_cap->txAntPattern = dot11_vht_cap.txAntPattern; - vht_cap->reserved1 = dot11_vht_cap.reserved1; + vht_cap->extended_nss_bw_supp = + dot11_vht_cap.extended_nss_bw_supp; /* Populate VHT MCS Information */ vht_mcs->rxMcsMap = dot11_vht_cap.rxMCSMap; u_vht_data_rate_info.vht_rx_supp_rate.rxSupDataRate = dot11_vht_cap.rxHighSupDataRate; - u_vht_data_rate_info.vht_rx_supp_rate.reserved = - dot11_vht_cap.reserved2; + u_vht_data_rate_info.vht_rx_supp_rate.max_nsts_total = + dot11_vht_cap.max_nsts_total; vht_mcs->rxHighest = u_vht_data_rate_info.u_value; vht_mcs->txMcsMap = dot11_vht_cap.txMCSMap; u_vht_data_rate_info.vht_tx_supp_rate.txSupDataRate = dot11_vht_cap.txSupDataRate; - u_vht_data_rate_info.vht_tx_supp_rate.reserved = - dot11_vht_cap.reserved3; + u_vht_data_rate_info.vht_tx_supp_rate.vht_extended_nss_bw_cap = + dot11_vht_cap.vht_extended_nss_bw_cap; vht_mcs->txHighest = u_vht_data_rate_info.u_value; } } diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c index 520454e2b6..85ee388c78 100644 --- a/core/mac/src/sys/legacy/src/utils/src/dot11f.c +++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c @@ -24,7 +24,7 @@ * * * This file was automatically generated by 'framesc' - * Fri Sep 13 10:34:49 2019 from the following file(s): + * Thu Sep 19 14:00:22 2019 from the following file(s): * * dot11f.frms * @@ -2823,7 +2823,7 @@ uint32_t dot11f_unpack_ie_vht_caps(tpAniSirGlobal pCtx, pDst->vhtLinkAdaptCap = tmp22__ >> 26 & 0x3; pDst->rxAntPattern = tmp22__ >> 28 & 0x1; pDst->txAntPattern = tmp22__ >> 29 & 0x1; - pDst->reserved1 = tmp22__ >> 30 & 0x3; + pDst->extended_nss_bw_supp = tmp22__ >> 30 & 0x3; if (unlikely(ielen < 2)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -2841,7 +2841,7 @@ uint32_t dot11f_unpack_ie_vht_caps(tpAniSirGlobal pCtx, pBuf += 2; ielen -= 2; pDst->rxHighSupDataRate = tmp23__ >> 0 & 0x1fff; - pDst->reserved2 = tmp23__ >> 13 & 0x7; + pDst->max_nsts_total = tmp23__ >> 13 & 0x7; if (unlikely(ielen < 2)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -2857,7 +2857,8 @@ uint32_t dot11f_unpack_ie_vht_caps(tpAniSirGlobal pCtx, framesntohs(pCtx, &tmp24__, pBuf, 0); pDst->txSupDataRate = tmp24__ >> 0 & 0x1fff; - pDst->reserved3 = tmp24__ >> 13 & 0x7; + pDst->vht_extended_nss_bw_cap = tmp24__ >> 13 & 0x1; + pDst->reserved = tmp24__ >> 14 & 0x3; (void)pCtx; return status; } /* End dot11f_unpack_ie_vht_caps. */ @@ -2889,7 +2890,7 @@ uint32_t dot11f_unpack_ie_vht_operation(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - pDst->chanCenterFreqSeg1 = *pBuf; + pDst->chan_center_freq_seg0 = *pBuf; pBuf += 1; ielen -= (uint8_t)1; if (unlikely(ielen < 1)) { @@ -2897,7 +2898,7 @@ uint32_t dot11f_unpack_ie_vht_operation(tpAniSirGlobal pCtx, return DOT11F_INCOMPLETE_IE; } - pDst->chanCenterFreqSeg2 = *pBuf; + pDst->chan_center_freq_seg1 = *pBuf; pBuf += 1; ielen -= (uint8_t)1; if (unlikely(ielen < 2)) { @@ -4825,7 +4826,8 @@ uint32_t dot11f_unpack_ie_ht_info(tpAniSirGlobal pCtx, pDst->nonGFDevicesPresent = tmp49__ >> 2 & 0x1; pDst->transmitBurstLimit = tmp49__ >> 3 & 0x1; pDst->obssNonHTStaPresent = tmp49__ >> 4 & 0x1; - pDst->reserved = tmp49__ >> 5 & 0x7ff; + pDst->chan_center_freq_seg2 = tmp49__ >> 5 & 0xff; + pDst->reserved = tmp49__ >> 13 & 0x7; if (unlikely(ielen < 2)) { pDst->present = 0; return DOT11F_INCOMPLETE_IE; @@ -5878,7 +5880,8 @@ uint32_t dot11f_unpack_ie_operating_mode(tpAniSirGlobal pCtx, tmp58__ = *pBuf; pDst->chanWidth = tmp58__ >> 0 & 0x3; - pDst->reserved = tmp58__ >> 2 & 0x3; + pDst->vht_160_80p80_supp = tmp58__ >> 2 & 0x1; + pDst->no_ldpc = tmp58__ >> 3 & 0x1; pDst->rxNSS = tmp58__ >> 4 & 0x7; pDst->rxNSSType = tmp58__ >> 7 & 0x1; (void)pCtx; @@ -21091,7 +21094,7 @@ uint32_t dot11f_pack_ie_vht_caps(tpAniSirGlobal pCtx, tmp119__ |= (pSrc->vhtLinkAdaptCap << 26); tmp119__ |= (pSrc->rxAntPattern << 28); tmp119__ |= (pSrc->txAntPattern << 29); - tmp119__ |= (pSrc->reserved1 << 30); + tmp119__ |= (pSrc->extended_nss_bw_supp << 30); if (unlikely(nBuf < 4)) return DOT11F_INCOMPLETE_IE; @@ -21104,7 +21107,7 @@ uint32_t dot11f_pack_ie_vht_caps(tpAniSirGlobal pCtx, pBuf += 2; tmp120__ = 0U; tmp120__ |= (pSrc->rxHighSupDataRate << 0); - tmp120__ |= (pSrc->reserved2 << 13); + tmp120__ |= (pSrc->max_nsts_total << 13); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; @@ -21117,7 +21120,8 @@ uint32_t dot11f_pack_ie_vht_caps(tpAniSirGlobal pCtx, pBuf += 2; tmp121__ = 0U; tmp121__ |= (pSrc->txSupDataRate << 0); - tmp121__ |= (pSrc->reserved3 << 13); + tmp121__ |= (pSrc->vht_extended_nss_bw_cap << 13); + tmp121__ |= (pSrc->reserved << 14); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; @@ -21154,10 +21158,10 @@ uint32_t dot11f_pack_ie_vht_operation(tpAniSirGlobal pCtx, *pBuf = pSrc->chanWidth; *pnConsumed += 1; pBuf += 1; - *pBuf = pSrc->chanCenterFreqSeg1; + *pBuf = pSrc->chan_center_freq_seg0; *pnConsumed += 1; pBuf += 1; - *pBuf = pSrc->chanCenterFreqSeg2; + *pBuf = pSrc->chan_center_freq_seg1; *pnConsumed += 1; pBuf += 1; frameshtons(pCtx, pBuf, pSrc->basicMCSSet, 0); @@ -22931,7 +22935,8 @@ uint32_t dot11f_pack_ie_ht_info(tpAniSirGlobal pCtx, tmp146__ |= (pSrc->nonGFDevicesPresent << 2); tmp146__ |= (pSrc->transmitBurstLimit << 3); tmp146__ |= (pSrc->obssNonHTStaPresent << 4); - tmp146__ |= (pSrc->reserved << 5); + tmp146__ |= (pSrc->chan_center_freq_seg2 << 5); + tmp146__ |= (pSrc->reserved << 13); if (unlikely(nBuf < 2)) return DOT11F_INCOMPLETE_IE; @@ -23584,7 +23589,8 @@ uint32_t dot11f_pack_ie_operating_mode(tpAniSirGlobal pCtx, ++pBuf; ++(*pnConsumed); tmp155__ = 0U; tmp155__ |= (pSrc->chanWidth << 0); - tmp155__ |= (pSrc->reserved << 2); + tmp155__ |= (pSrc->vht_160_80p80_supp << 2); + tmp155__ |= (pSrc->no_ldpc << 3); tmp155__ |= (pSrc->rxNSS << 4); tmp155__ |= (pSrc->rxNSSType << 7); if (unlikely(nBuf < 1)) diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 46760fb9bc..da468b7e7a 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -875,10 +875,10 @@ static void lim_log_vht_operation(struct mac_context *mac, { #ifdef DUMP_MGMT_CNTNTS pe_debug("chanWidth: %d", pDot11f->chanWidth); - pe_debug("chanCenterFreqSeg1: %d", - pDot11f->chanCenterFreqSeg1); - pe_debug("chanCenterFreqSeg2: %d", - pDot11f->chanCenterFreqSeg2); + pe_debug("chan_center_freq_seg0: %d", + pDot11f->chan_center_freq_seg0); + pe_debug("chan_center_freq_seg1: %d", + pDot11f->chan_center_freq_seg1); pe_debug("basicMCSSet: %d", pDot11f->basicMCSSet); #endif /* DUMP_MGMT_CNTNTS */ } @@ -994,6 +994,8 @@ populate_dot11f_vht_caps(struct mac_context *mac, pDot11f->rxAntPattern = pe_session->vht_config.rx_antpattern; pDot11f->txAntPattern = pe_session->vht_config.tx_antpattern; + pDot11f->extended_nss_bw_supp = + pe_session->vht_config.extended_nss_bw_supp; pDot11f->maxAMPDULenExp = pe_session->vht_config.max_ampdu_lenexp; @@ -1047,12 +1049,17 @@ populate_dot11f_vht_caps(struct mac_context *mac, nCfgValue = vht_cap_info->link_adap_cap; pDot11f->vhtLinkAdaptCap = (nCfgValue & 0x0003); + pDot11f->extended_nss_bw_supp = + vht_cap_info->extended_nss_bw_supp; } + pDot11f->max_nsts_total = vht_cap_info->max_nsts_total; + pDot11f->vht_extended_nss_bw_cap = + vht_cap_info->vht_extended_nss_bw_cap; + nCfgValue = vht_cap_info->mu_bformer; pDot11f->muBeamformerCap = (nCfgValue & 0x0001); - pDot11f->reserved1 = 0; nCfgValue = vht_cap_info->rx_mcs_map; pDot11f->rxMCSMap = (nCfgValue & 0x0000FFFF); @@ -1060,15 +1067,12 @@ populate_dot11f_vht_caps(struct mac_context *mac, nCfgValue = vht_cap_info->rx_supp_data_rate; pDot11f->rxHighSupDataRate = (nCfgValue & 0x00001FFF); - pDot11f->reserved2 = 0; - nCfgValue = vht_cap_info->tx_mcs_map; pDot11f->txMCSMap = (nCfgValue & 0x0000FFFF); nCfgValue = vht_cap_info->tx_supp_data_rate; pDot11f->txSupDataRate = (nCfgValue & 0x00001FFF); - pDot11f->reserved3 = 0; if (pe_session) { if (pe_session->nss == NSS_1x1_MODE) { pDot11f->txMCSMap |= DISABLE_NSS2_MCS; @@ -1114,18 +1118,18 @@ populate_dot11f_vht_operation(struct mac_context *mac, if (pe_session->ch_width > CH_WIDTH_40MHZ) { pDot11f->chanWidth = 1; - pDot11f->chanCenterFreqSeg1 = + pDot11f->chan_center_freq_seg0 = pe_session->ch_center_freq_seg0; if (pe_session->ch_width == CH_WIDTH_80P80MHZ || pe_session->ch_width == CH_WIDTH_160MHZ) - pDot11f->chanCenterFreqSeg2 = + pDot11f->chan_center_freq_seg1 = pe_session->ch_center_freq_seg1; else - pDot11f->chanCenterFreqSeg2 = 0; + pDot11f->chan_center_freq_seg1 = 0; } else { pDot11f->chanWidth = 0; - pDot11f->chanCenterFreqSeg1 = 0; - pDot11f->chanCenterFreqSeg2 = 0; + pDot11f->chan_center_freq_seg0 = 0; + pDot11f->chan_center_freq_seg1 = 0; } pDot11f->basicMCSSet = diff --git a/core/sap/src/sap_ch_select.c b/core/sap/src/sap_ch_select.c index 2f2fed4530..cff9e7c480 100644 --- a/core/sap/src/sap_ch_select.c +++ b/core/sap/src/sap_ch_select.c @@ -1170,9 +1170,9 @@ static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct, *vhtSupport = pBeaconStruct->VHTOperation.present; if (pBeaconStruct->VHTOperation.chanWidth) { *centerFreq = - pBeaconStruct->VHTOperation.chanCenterFreqSeg1; + pBeaconStruct->VHTOperation.chan_center_freq_seg0; *centerFreq_2 = - pBeaconStruct->VHTOperation.chanCenterFreqSeg2; + pBeaconStruct->VHTOperation.chan_center_freq_seg1; /* * LHS follows tSirMacHTChannelWidth, while RHS follows * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 8a0c7d855f..0bdbc21041 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -3477,8 +3477,8 @@ static void csr_roam_populate_channels(tDot11fBeaconIEs *beacon_ies, ePhyChanBondState phy_state; if (beacon_ies->VHTOperation.present) { - *chan1 = beacon_ies->VHTOperation.chanCenterFreqSeg1; - *chan2 = beacon_ies->VHTOperation.chanCenterFreqSeg2; + *chan1 = beacon_ies->VHTOperation.chan_center_freq_seg0; + *chan2 = beacon_ies->VHTOperation.chan_center_freq_seg1; roam_info->chan_info.info = MODE_11AC_VHT80; } else if (beacon_ies->HTInfo.present) { if (beacon_ies->HTInfo.recommendedTxWidthSet == diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h index 49224a0c06..5f92ef516b 100644 --- a/core/wma/inc/wma_if.h +++ b/core/wma/inc/wma_if.h @@ -187,7 +187,7 @@ typedef struct { uint8_t uAPSD; uint8_t maxSPLen; uint8_t htCapable; - uint8_t ch_width; + enum phy_ch_width ch_width; tSirMacHTMIMOPowerSaveState mimoPS; uint8_t maxAmpduSize; uint8_t maxAmpduDensity; @@ -218,6 +218,9 @@ typedef struct { uint8_t csaOffloadEnable; uint8_t vhtCapable; uint8_t vhtSupportedRxNss; + uint8_t vht_160mhz_nss; + uint8_t vht_80p80mhz_nss; + uint8_t vht_extended_nss_bw_cap; uint8_t vhtTxBFCapable; uint8_t enable_su_tx_bformer; uint8_t vhtTxMUBformeeCapable; diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 6535b09895..963daa4d94 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -1650,6 +1650,21 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, ((1 << cmd->peer_nss) - 1)); WMI_VHT_MCS_NOTIFY_EXT_SS_SET(cmd->tx_mcs_set, 1); } + if (params->vht_extended_nss_bw_cap) { + /* + * bit[2:0] : Represents value of Rx NSS for 160 MHz + * bit[5:3] : Represents value of Rx NSS for 80_80 MHz + * Extended NSS support + * bit[30:6]: Reserved + * bit[31] : MSB(0/1): 1 in case of valid data + */ + cmd->peer_bw_rxnss_override |= (1 << 31); + cmd->peer_bw_rxnss_override |= params->vht_160mhz_nss; + cmd->peer_bw_rxnss_override |= + (params->vht_80p80mhz_nss << 3); + WMA_LOGD(FL("peer_bw_rxnss_override %0X"), + cmd->peer_bw_rxnss_override); + } } WMA_LOGD(FL("rx_max_rate: %d, rx_mcs: %x, tx_max_rate: %d, tx_mcs: %x"), @@ -1660,8 +1675,11 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, * Limit nss to max number of rf chain supported by target * Otherwise Fw will crash */ - if (cmd->peer_nss > WMA_MAX_NSS) + if (cmd->peer_nss > WMA_MAX_NSS) { + WMA_LOGE(FL("peer Nss %d is more than supported"), + cmd->peer_nss); cmd->peer_nss = WMA_MAX_NSS; + } wma_populate_peer_he_cap(cmd, params);