Browse Source

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
Abhishek Ambure 4 years ago
parent
commit
04a9776404

+ 13 - 7
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;

+ 2 - 2
core/mac/src/pe/lim/lim_process_assoc_req_frame.c

@@ -1750,8 +1750,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);

+ 1 - 1
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -207,7 +207,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. */

+ 7 - 6
core/wma/src/wma_mgmt.c

@@ -1596,13 +1596,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,