Browse Source

qcacld-3.0: Fallback to 80MHz capability if HE160 MCS is not valid

If the STA DUT is attempting to connect in 160MHz channel width,
and if the HE160 Rx/Tx MCS is not valid after intersection, the
STA DUT will fallback to 80MHZ channel width.

Change-Id: I11fe8830851fcbb3796703a605568f83c9ff9932
CRs-Fixed: 3011510
Surya Prakash Sivaraj 3 years ago
parent
commit
dcca0ed5fa
1 changed files with 39 additions and 2 deletions
  1. 39 2
      core/mac/src/pe/lim/lim_prop_exts_utils.c

+ 39 - 2
core/mac/src/pe/lim/lim_prop_exts_utils.c

@@ -161,6 +161,36 @@ static void lim_extract_he_op(struct pe_session *session,
 	}
 }
 
+static bool lim_validate_he160_mcs_map(struct mac_context *mac_ctx,
+				       uint16_t peer_rx, uint16_t peer_tx,
+				       uint8_t nss)
+{
+	uint16_t rx_he_mcs_map;
+	uint16_t tx_he_mcs_map;
+	uint16_t he_mcs_map;
+
+	he_mcs_map = *((uint16_t *)mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
+				tx_he_mcs_map_160);
+	rx_he_mcs_map = HE_INTERSECT_MCS(peer_rx, he_mcs_map);
+
+	he_mcs_map = *((uint16_t *)mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
+				rx_he_mcs_map_160);
+	tx_he_mcs_map = HE_INTERSECT_MCS(peer_tx, he_mcs_map);
+
+	if (nss == NSS_1x1_MODE) {
+		rx_he_mcs_map |= HE_MCS_INV_MSK_4_NSS(1);
+		tx_he_mcs_map |= HE_MCS_INV_MSK_4_NSS(1);
+	} else if (nss == NSS_2x2_MODE) {
+		rx_he_mcs_map |= (HE_MCS_INV_MSK_4_NSS(1) &
+				HE_MCS_INV_MSK_4_NSS(2));
+		tx_he_mcs_map |= (HE_MCS_INV_MSK_4_NSS(1) &
+				HE_MCS_INV_MSK_4_NSS(2));
+	}
+
+	return ((rx_he_mcs_map != HE_MCS_ALL_DISABLED) &&
+		(tx_he_mcs_map != HE_MCS_ALL_DISABLED));
+}
+
 static void lim_check_is_he_mcs_valid(struct pe_session *session,
 				      tSirProbeRespBeacon *beacon_struct)
 {
@@ -200,8 +230,10 @@ void lim_update_he_bw_cap_mcs(struct pe_session *session,
 		if (!beacon->he_cap.chan_width_2)
 			is_80mhz = 1;
 		else if (beacon->he_cap.chan_width_2 &&
-			 (*(uint16_t *)beacon->he_cap.rx_he_mcs_map_160 ==
-			  HE_MCS_ALL_DISABLED))
+			 !lim_validate_he160_mcs_map(session->mac_ctx,
+			   *((uint16_t *)beacon->he_cap.rx_he_mcs_map_160),
+			   *((uint16_t *)beacon->he_cap.tx_he_mcs_map_160),
+						     session->nss))
 			is_80mhz = 1;
 		else
 			is_80mhz = 0;
@@ -213,6 +245,11 @@ void lim_update_he_bw_cap_mcs(struct pe_session *session,
 		session->he_config.chan_width_2 = 0;
 		session->he_config.chan_width_3 = 0;
 	} else if (session->ch_width == CH_WIDTH_160MHZ) {
+		if (is_80mhz) {
+			pe_debug("HE160 Rx/Tx MCS is not valid, falling back to 80MHz");
+			session->ch_width = CH_WIDTH_80MHZ;
+			session->he_config.chan_width_2 = 0;
+		}
 		session->he_config.chan_width_3 = 0;
 	}
 	/* Reset the > 20MHz caps for 20MHz connection */