Pārlūkot izejas kodu

qcacld-3.0: Connect in 11b mode if INI is set to 11b and AP is 11bg

Currenly if the dot11Mode INI is set to 11b_only mode and the BSS we
are trying to connect is 11b/g mixed mode, then the connection happens
with phyMode 1 (11 b/g) but the data rates are set only for 11b mode
which leads the FW to assert when a data traffic with 11g rates is
triggered.

Connect to the BSS in 11b mode only if the INI is set to 11b_only and
the BSS we are trying to connect is in 11b/g mode.

Change-Id: I952394323efeacf5baae39b3a6d2adf7eae96a81
CRs-Fixed: 2328434
Vignesh Viswanathan 6 gadi atpakaļ
vecāks
revīzija
ad265f2b05
2 mainītis faili ar 57 papildinājumiem un 26 dzēšanām
  1. 15 4
      core/sme/src/csr/csr_api_roam.c
  2. 42 22
      core/sme/src/csr/csr_util.c

+ 15 - 4
core/sme/src/csr/csr_api_roam.c

@@ -4533,12 +4533,23 @@ QDF_STATUS csr_roam_prepare_bss_config(tpAniSirGlobal pMac,
 				  pProfile, &cfgDot11Mode, pIes)) {
 		pBssConfig->uCfgDot11Mode = cfgDot11Mode;
 	} else {
+		/*
+		 * No matching phy mode found, force to 11b/g based on INI for
+		 * 2.4Ghz and to 11a mode for 5Ghz
+		 */
 		sme_warn("Can not find match phy mode");
-		/* force it */
-		if (BAND_2G == pBssConfig->eBand)
-			pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
-		else
+		if (BAND_2G == pBssConfig->eBand) {
+			if (pMac->roam.configParam.phyMode &
+			    (eCSR_DOT11_MODE_11b | eCSR_DOT11_MODE_11b_ONLY)) {
+				pBssConfig->uCfgDot11Mode =
+						eCSR_CFG_DOT11_MODE_11B;
+			} else {
+				pBssConfig->uCfgDot11Mode =
+						eCSR_CFG_DOT11_MODE_11G;
+			}
+		} else {
 			pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+		}
 	}
 
 	sme_debug("phyMode=%d, uCfgDot11Mode=%d negotiatedAuthType %d",

+ 42 - 22
core/sme/src/csr/csr_util.c

@@ -1698,10 +1698,13 @@ uint32_t csr_get_rts_thresh(tpAniSirGlobal mac_ctx)
 	return mac_ctx->mlme_cfg->threshold.rts_threshold;
 }
 
-static eCsrPhyMode csr_translate_to_phy_mode_from_bss_desc(
-						tSirBssDescription *pSirBssDesc)
+static eCsrPhyMode
+csr_translate_to_phy_mode_from_bss_desc(tpAniSirGlobal mac_ctx,
+					tSirBssDescription *pSirBssDesc,
+					tDot11fBeaconIEs *ies)
 {
 	eCsrPhyMode phyMode;
+	uint8_t i;
 
 	switch (pSirBssDesc->nwType) {
 	case eSIR_11A_NW_TYPE:
@@ -1713,9 +1716,23 @@ static eCsrPhyMode csr_translate_to_phy_mode_from_bss_desc(
 		break;
 
 	case eSIR_11G_NW_TYPE:
-		phyMode = eCSR_DOT11_MODE_11g;
-		break;
+		phyMode = eCSR_DOT11_MODE_11g_ONLY;
+
+		/* Check if the BSS is in b/g mixed mode or g_only mode */
+		if (!ies || !ies->SuppRates.present) {
+			sme_debug("Unable to get rates, assume G only mode");
+			break;
+		}
 
+		for (i = 0; i < ies->SuppRates.num_rates; i++) {
+			if (csr_rates_is_dot11_rate11b_supported_rate(
+			    ies->SuppRates.rates[i])) {
+				sme_debug("One B rate is supported");
+				phyMode = eCSR_DOT11_MODE_11g;
+				break;
+			}
+		}
+		break;
 	case eSIR_11N_NW_TYPE:
 		phyMode = eCSR_DOT11_MODE_11n;
 		break;
@@ -1821,7 +1838,8 @@ QDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac,
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	eCsrPhyMode phyMode =
-		csr_translate_to_phy_mode_from_bss_desc(pBSSDescription);
+		csr_translate_to_phy_mode_from_bss_desc(pMac, pBSSDescription,
+							pIes);
 
 	if (pIes) {
 		if (pIes->HTCaps.present) {
@@ -1851,7 +1869,8 @@ QDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac,
  *
  * Return: true or false
  */
-static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn,
+static bool csr_get_phy_mode_in_use(tpAniSirGlobal mac_ctx,
+				    eCsrPhyMode phyModeIn,
 				    eCsrPhyMode bssPhyMode,
 				    bool f5GhzBand,
 				    enum csr_cfgdot11mode *pCfgDot11ModeToUse)
@@ -1890,21 +1909,16 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn,
 		break;
 
 	case eCSR_DOT11_MODE_11g_ONLY:
-		if (eCSR_DOT11_MODE_11g == bssPhyMode) {
+		if ((bssPhyMode == eCSR_DOT11_MODE_11g) ||
+		    (bssPhyMode == eCSR_DOT11_MODE_11g_ONLY)) {
 			fMatch = true;
 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
 		}
 		break;
 
 	case eCSR_DOT11_MODE_11b:
-		if (!f5GhzBand) {
-			fMatch = true;
-			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
-		}
-		break;
-
 	case eCSR_DOT11_MODE_11b_ONLY:
-		if (eCSR_DOT11_MODE_11b == bssPhyMode) {
+		if (!f5GhzBand && (bssPhyMode != eCSR_DOT11_MODE_11g_ONLY)) {
 			fMatch = true;
 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
 		}
@@ -1914,6 +1928,7 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn,
 		fMatch = true;
 		switch (bssPhyMode) {
 		case eCSR_DOT11_MODE_11g:
+		case eCSR_DOT11_MODE_11g_ONLY:
 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
 			break;
 		case eCSR_DOT11_MODE_11b:
@@ -1946,6 +1961,7 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn,
 		fMatch = true;
 		switch (bssPhyMode) {
 		case eCSR_DOT11_MODE_11g:
+		case eCSR_DOT11_MODE_11g_ONLY:
 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
 			break;
 		case eCSR_DOT11_MODE_11b:
@@ -1975,6 +1991,7 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn,
 		fMatch = true;
 		switch (bssPhyMode) {
 		case eCSR_DOT11_MODE_11g:
+		case eCSR_DOT11_MODE_11g_ONLY:
 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
 			break;
 		case eCSR_DOT11_MODE_11b:
@@ -2007,6 +2024,7 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn,
 		fMatch = true;
 		switch (bssPhyMode) {
 		case eCSR_DOT11_MODE_11g:
+		case eCSR_DOT11_MODE_11g_ONLY:
 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
 			break;
 		case eCSR_DOT11_MODE_11b:
@@ -2106,19 +2124,21 @@ bool csr_is_phy_mode_match(tpAniSirGlobal pMac, uint32_t phyMode,
 		} else {
 			phyMode2 = phyMode;
 		}
-		fMatch = csr_get_phy_mode_in_use(phyMode2, phyModeInBssDesc,
-				WLAN_REG_IS_5GHZ_CH(pSirBssDesc->channelId),
-				&cfgDot11ModeToUse);
+		fMatch = csr_get_phy_mode_in_use(pMac, phyMode2,
+						 phyModeInBssDesc,
+						 WLAN_REG_IS_5GHZ_CH(
+						 pSirBssDesc->channelId),
+						 &cfgDot11ModeToUse);
 	} else {
 		bitMask = 1;
 		loopCount = 0;
 		while (loopCount < eCSR_NUM_PHY_MODE) {
 			phyMode2 = (phyMode & (bitMask << loopCount++));
-			if (0 != phyMode2 && csr_get_phy_mode_in_use(phyMode2,
-						phyModeInBssDesc,
-						WLAN_REG_IS_5GHZ_CH
-						(pSirBssDesc->channelId),
-						&cfgDot11ModeToUse)) {
+			if (0 != phyMode2 &&
+			    csr_get_phy_mode_in_use(pMac, phyMode2,
+			    phyModeInBssDesc,
+			    WLAN_REG_IS_5GHZ_CH(pSirBssDesc->channelId),
+			    &cfgDot11ModeToUse)) {
 				fMatch = true;
 				break;
 			}