From 75a963377332fdbefe2b938761da64449b65e9df Mon Sep 17 00:00:00 2001 From: Abhishek Ambure Date: Wed, 20 Jan 2021 00:36:32 +0530 Subject: [PATCH] qcacld-3.0: Update proper peer VHT MCS MAP and self NSS Problem scenario: 1) Host uses self RX and peer VHT TX NSS intersection to update peer VHT RX MCS map and self NSS in pe_session. 2) Host updates peer VHT TX MCS map and self TX NSS from PE session to FW. FW uses these values to select TX rates for data packets. 3) If an AP supports 1 TX NSS and 2 RX NSS and host supports 2 TX and RX NSS, as a result of intersection host sets VHT TX MCS map to 0xfffe i.e. 1x1 and associates with AP in 1x1. Which leads to low TX throughput. Fix: Use intersection of peer VHT RX MCS map and self VHT TX NSS to update NSS to firmware. Change-Id: I4104e3502c45923625143cd32da8cb4529df05a2 CRs-Fixed: 2847115 --- core/mac/src/pe/lim/lim_assoc_utils.c | 20 ++++++++++++------- .../src/pe/lim/lim_process_assoc_req_frame.c | 4 ++-- .../src/pe/lim/lim_process_assoc_rsp_frame.c | 2 +- core/wma/src/wma_mgmt.c | 13 ++++++------ 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c index 7fa3a894ad44..a57e19081e95 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/core/mac/src/pe/lim/lim_assoc_utils.c @@ -1300,12 +1300,14 @@ QDF_STATUS lim_populate_vht_mcs_set(struct mac_context *mac_ctx, } } - rates->vhtTxHighestDataRate = - QDF_MIN(rates->vhtTxHighestDataRate, - peer_vht_caps->txSupDataRate); - rates->vhtRxHighestDataRate = - QDF_MIN(rates->vhtRxHighestDataRate, - peer_vht_caps->rxHighSupDataRate); + if (peer_vht_caps->txSupDataRate) + rates->vhtTxHighestDataRate = + QDF_MIN(rates->vhtTxHighestDataRate, + peer_vht_caps->txSupDataRate); + if (peer_vht_caps->rxHighSupDataRate) + rates->vhtRxHighestDataRate = + QDF_MIN(rates->vhtRxHighestDataRate, + peer_vht_caps->rxHighSupDataRate); if (session_entry && session_entry->nss == NSS_2x2_MODE) mcs_map_mask2x2 = MCSMAPMASK2x2; @@ -1750,7 +1752,11 @@ QDF_STATUS lim_populate_peer_rate_set(struct mac_context *mac, if (IS_DOT11_MODE_HE(pe_session->dot11mode) && he_caps) { lim_calculate_he_nss(pRates, pe_session); } else if (pe_session->vhtCapability) { - if ((pRates->vhtRxMCSMap & MCSMAPMASK2x2) == MCSMAPMASK2x2) + /* + * pRates->vhtTxMCSMap is intersection of self tx and peer rx + * mcs so update nss as per peer rx mcs + */ + if ((pRates->vhtTxMCSMap & MCSMAPMASK2x2) == MCSMAPMASK2x2) pe_session->nss = NSS_1x1_MODE; } else if (pRates->supportedMCSSet[1] == 0) { pe_session->nss = NSS_1x1_MODE; 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 2e7796d716cc..d60329d785af 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 @@ -1722,8 +1722,8 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, sta_ds->vhtSupportedRxNss = assoc_req->operMode.rxNSS + 1; } else { sta_ds->vhtSupportedRxNss = - ((sta_ds->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2) - == MCSMAPMASK2x2) ? 1 : 2; + ((sta_ds->supportedRates.vhtTxMCSMap & MCSMAPMASK2x2) + == MCSMAPMASK2x2) ? 1 : 2; } lim_update_stads_he_6ghz_op(session, sta_ds); lim_update_sta_ds_op_classes(assoc_req, sta_ds); 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 43358121c345..22c2be3aa801 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 @@ -205,7 +205,7 @@ void lim_update_assoc_sta_datas(struct mac_context *mac_ctx, return; } sta_ds->vhtSupportedRxNss = - ((sta_ds->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2) + ((sta_ds->supportedRates.vhtTxMCSMap & MCSMAPMASK2x2) == MCSMAPMASK2x2) ? 1 : 2; /* If one of the rates is 11g rates, set the ERP mode. */ diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 7a92fedaf0b2..f1166f326d0a 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -1598,13 +1598,14 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, cmd->rx_mcs_set = params->supportedRates.vhtRxMCSMap; cmd->tx_max_rate = params->supportedRates.vhtTxHighestDataRate; cmd->tx_mcs_set = params->supportedRates.vhtTxMCSMap; - - if (params->vhtSupportedRxNss) { + /* + * tx_mcs_set is intersection of self tx NSS and peer rx mcs map + */ + if (params->vhtSupportedRxNss) cmd->peer_nss = params->vhtSupportedRxNss; - } else { - cmd->peer_nss = ((cmd->rx_mcs_set & VHT2x2MCSMASK) - == VHT2x2MCSMASK) ? 1 : 2; - } + else + cmd->peer_nss = ((cmd->tx_mcs_set & VHT2x2MCSMASK) + == VHT2x2MCSMASK) ? 1 : 2; if (params->vht_mcs_10_11_supp) { WMI_SET_BITS(cmd->tx_mcs_set, 16, cmd->peer_nss,