Эх сурвалжийг харах

qcacld-3.0: Advertise max NSS capability with few IOT APs

Few IOT APs advertise reduced NSS capabilities on ending
up in bad state. These APs can later recover to support
the actual NSS capabilities. In this scenario, when STA
initiates connection to these APs, which are in bad state,
reduced NSS capabilities is advertised. STA cannot later
upgrade NSS capabilities to the minimum of STA max NSS
capability and APs actual NSS capability, once AP recovers.

Fix is to advertise max NSS capability during connection
with these IOT APs based on vendor OUIs and downgrade if
AP still advertises reduced NSS capability in association
response.

Change-Id: I49ea13534b1a44fd9ffadd1e8fb44e9d782147c4
CRs-Fixed: 2453938
Yeshwanth Sriram Guntuka 6 жил өмнө
parent
commit
22ed80066a

+ 3 - 1
components/action_oui/dispatcher/inc/wlan_action_oui_public_struct.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -88,6 +88,7 @@
  * @ACTION_OUI_SWITCH_TO_11N_MODE: connect in 11n
  * @ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN: connect in 1x1 & disable diversity gain
  * @ACTION_OUI_DISABLE_AGGRESSIVE_TX: disable aggressive TX in firmware
+ * @ACTION_OUI_FORCE_MAX_NSS: Force Max NSS connection with few IOT APs
  * @ACTION_OUI_MAXIMUM_ID: maximun number of action oui types
  */
 enum action_oui_id {
@@ -98,6 +99,7 @@ enum action_oui_id {
 	ACTION_OUI_SWITCH_TO_11N_MODE = 4,
 	ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN = 5,
 	ACTION_OUI_DISABLE_AGGRESSIVE_TX = 6,
+	ACTION_OUI_FORCE_MAX_NSS = 7,
 	ACTION_OUI_MAXIMUM_ID
 };
 

+ 38 - 0
core/hdd/inc/hdd_config.h

@@ -1336,6 +1336,43 @@ enum host_log_level {
 	"", \
 	"Set modulized host debug log level")
 
+/*
+ * <ini>
+ * gActionOUIForceMaxNss - Used to specify action OUIs for Max NSS connection
+ * @Default:
+ * Note: User should strictly add new action OUIs at the end of this
+ * default value.
+ *
+ * Default OUIs: (All values in Hex)
+ * OUI 1 :001018
+ *   OUI data Len : 06
+ *   OUI Data : 0201009c0000
+ *   OUI data Mask: FC
+ *   Info Mask : 01 - only OUI present in Info mask
+ * OUI 2 :001018
+ *   OUI data Len : 06
+ *   OUI Data : 0201001c0000
+ *   OUI data Mask: FC
+ *   Info Mask : 01 - only OUI present in Info mask
+ *
+ * This ini is used to specify the AP OUIs with which max capability is
+ * sent in association request even though AP advertises 1x1 capability.
+ *
+ * Related: None
+ *
+ * Supported Feature: Action OUIs
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ACTION_OUI_FORCE_MAX_NSS CFG_INI_STRING( \
+			"gActionOUIForceMaxNss", \
+			0, \
+			ACTION_OUI_MAX_STR_LEN, \
+			"001018 06 0201009c0000 FC 01 001018 06 0201001c0000 FC 01", \
+			"Used to specify action OUIs for forcing max NSS connection")
+
 #define CFG_HDD_ALL \
 	CFG_ENABLE_PACKET_LOG_ALL \
 	CFG_ENABLE_RUNTIME_PM_ALL \
@@ -1348,6 +1385,7 @@ enum host_log_level {
 	CFG(CFG_ACTION_OUI_ITO_ALTERNATE) \
 	CFG(CFG_ACTION_OUI_ITO_EXTENSION) \
 	CFG(CFG_ACTION_OUI_DISABLE_AGGRESSIVE_TX) \
+	CFG(CFG_ACTION_OUI_FORCE_MAX_NSS) \
 	CFG(CFG_ACTION_OUI_SWITCH_TO_11N_MODE) \
 	CFG(CFG_ADVERTISE_CONCURRENT_OPERATION) \
 	CFG(CFG_BUG_ON_REINIT_FAILURE) \

+ 3 - 0
core/hdd/src/wlan_hdd_main.c

@@ -9513,6 +9513,9 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
 		      cfg_get(psoc,
 			      CFG_ACTION_OUI_DISABLE_AGGRESSIVE_TX),
 			      ACTION_OUI_MAX_STR_LEN);
+	qdf_str_lcopy(config->action_oui_str[ACTION_OUI_FORCE_MAX_NSS],
+		      cfg_get(psoc, CFG_ACTION_OUI_FORCE_MAX_NSS),
+		      ACTION_OUI_MAX_STR_LEN);
 	config->enable_rtt_support = cfg_get(psoc, CFG_ENABLE_RTT_SUPPORT);
 	config->is_unit_test_framework_enabled =
 			cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK);

+ 2 - 0
core/mac/src/include/parser_api.h

@@ -56,6 +56,8 @@
 
 #define NSS_1x1_MODE 1
 #define NSS_2x2_MODE 2
+#define NSS_3x3_MODE 3
+#define NSS_4x4_MODE 4
 #define MBO_IE_ASSOC_DISALLOWED_SUBATTR_ID 0x04
 
 /* QCN IE definitions */

+ 53 - 0
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -510,6 +510,39 @@ lim_handle_assoc_reject_status(struct mac_context *mac_ctx,
 }
 #endif
 
+/**
+ * lim_get_nss_supported_by_ap() - finds out nss from AP's beacons
+ * @vht_caps: VHT capabilities
+ * @ht_caps: HT capabilities
+ *
+ * Return: nss advertised by AP in beacon
+ */
+static uint8_t lim_get_nss_supported_by_ap(tDot11fIEVHTCaps *vht_caps,
+					   tDot11fIEHTCaps *ht_caps)
+{
+	if (vht_caps->present) {
+		if ((vht_caps->rxMCSMap & 0xC0) != 0xC0)
+			return NSS_4x4_MODE;
+
+		if ((vht_caps->rxMCSMap & 0x30) != 0x30)
+			return NSS_3x3_MODE;
+
+		if ((vht_caps->rxMCSMap & 0x0C) != 0x0C)
+			return NSS_2x2_MODE;
+	} else if (ht_caps->present) {
+		if (ht_caps->supportedMCSSet[3])
+			return NSS_4x4_MODE;
+
+		if (ht_caps->supportedMCSSet[2])
+			return NSS_3x3_MODE;
+
+		if (ht_caps->supportedMCSSet[1])
+			return NSS_2x2_MODE;
+	}
+
+	return NSS_1x1_MODE;
+}
+
 /**
  * lim_process_assoc_rsp_frame() - Processes assoc response
  * @mac_ctx: Pointer to Global MAC structure
@@ -541,6 +574,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx,
 	uint8_t sme_sessionid = 0;
 	struct csr_roam_session *roam_session;
 #endif
+	uint8_t ap_nss;
+
 	/* Initialize status code to success. */
 	if (lim_is_roam_synch_in_progress(session_entry))
 		hdr = (tpSirMacMgmtHdr) mac_ctx->roam.pReassocResp;
@@ -842,6 +877,9 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx,
 			session_entry, assoc_rsp->statusCode ? QDF_STATUS_E_FAILURE :
 			QDF_STATUS_SUCCESS, assoc_rsp->statusCode);
 
+	ap_nss = lim_get_nss_supported_by_ap(&assoc_rsp->VHTCaps,
+					     &assoc_rsp->HTCaps);
+
 	if (subtype == LIM_REASSOC) {
 		pe_debug("Successfully Reassociated with BSS");
 #ifdef FEATURE_WLAN_ESE
@@ -877,6 +915,14 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx,
 				session_entry, false);
 			goto assocReject;
 		}
+
+		if (ap_nss < session_entry->nss) {
+			session_entry->nss = ap_nss;
+			lim_objmgr_update_vdev_nss(mac_ctx->psoc,
+						   session_entry->smeSessionId,
+						   ap_nss);
+		}
+
 		if ((session_entry->limMlmState ==
 		    eLIM_MLM_WT_FT_REASSOC_RSP_STATE) ||
 			lim_is_roam_synch_in_progress(session_entry)) {
@@ -963,6 +1009,13 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx,
 	if (lim_search_pre_auth_list(mac_ctx, hdr->sa))
 		lim_delete_pre_auth_node(mac_ctx, hdr->sa);
 
+	if (ap_nss < session_entry->nss) {
+		session_entry->nss = ap_nss;
+		lim_objmgr_update_vdev_nss(mac_ctx->psoc,
+					   session_entry->smeSessionId,
+					   ap_nss);
+	}
+
 	lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, session_entry);
 	/*
 	 * Extract the AP capabilities from the beacon that

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

@@ -159,8 +159,8 @@ static void lim_check_he_ldpc_cap(struct pe_session *session,
 {}
 #endif
 
-static void lim_objmgr_update_vdev_nss(struct wlan_objmgr_psoc *psoc,
-				       uint8_t vdev_id, uint8_t nss)
+void lim_objmgr_update_vdev_nss(struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id, uint8_t nss)
 {
 	struct wlan_objmgr_vdev *vdev;
 

+ 11 - 0
core/mac/src/pe/lim/lim_prop_exts_utils.h

@@ -56,4 +56,15 @@ lim_extract_ap_capability(struct mac_context *mac_ctx, uint8_t *p_ie,
 
 ePhyChanBondState lim_get_htcb_state(ePhyChanBondState aniCBMode);
 
+/**
+ * lim_objmgr_update_vdev_nss() - update nss in vdev object
+ * @psoc: Pointer to Global MAC structure
+ * @vdev_id: vdev id
+ * @nss: nss
+ *
+ * Return: None
+ */
+void lim_objmgr_update_vdev_nss(struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id, uint8_t nss);
+
 #endif /* __LIM_PROP_EXTS_UTILS_H */

+ 43 - 26
core/sme/src/csr/csr_api_roam.c

@@ -8785,6 +8785,11 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
 #endif
 		}
 
+		if (pSmeJoinRsp->nss < session_ptr->nss) {
+			session_ptr->nss = pSmeJoinRsp->nss;
+			session_ptr->vdev_nss = pSmeJoinRsp->nss;
+		}
+
 		session_ptr->supported_nss_1x1 =
 			pSmeJoinRsp->supported_nss_1x1;
 		sme_debug("SME session supported nss: %d",
@@ -9199,6 +9204,10 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(struct mac_context *mac
 		result = eCsrReassocSuccess;
 		csr_session = CSR_GET_SESSION(mac, pSmeJoinRsp->sessionId);
 		if (csr_session) {
+			if (pSmeJoinRsp->nss < csr_session->nss) {
+				csr_session->nss = pSmeJoinRsp->nss;
+				csr_session->vdev_nss = pSmeJoinRsp->nss;
+			}
 			csr_session->supported_nss_1x1 =
 				pSmeJoinRsp->supported_nss_1x1;
 			sme_debug("SME session supported nss: %d",
@@ -15310,6 +15319,8 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
 	tDot11fIEVHTCaps *vht_caps = NULL;
 	bool bvalue = 0;
 	eCsrAuthType akm;
+	bool force_max_nss;
+	uint8_t ap_nss;
 
 	if (!pSession) {
 		sme_err("session %d not found", sessionId);
@@ -15414,32 +15425,6 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
 			dot11mode = MLME_DOT11_MODE_11N;
 		}
 
-		if (IS_5G_CH(pBssDescription->channelId))
-			vdev_type_nss = &mac->vdev_type_nss_5g;
-		else
-			vdev_type_nss = &mac->vdev_type_nss_2g;
-		if (pSession->pCurRoamProfile->csrPersona ==
-		    QDF_P2P_CLIENT_MODE)
-			pSession->vdev_nss = vdev_type_nss->p2p_cli;
-		else
-			pSession->vdev_nss = vdev_type_nss->sta;
-		pSession->nss = pSession->vdev_nss;
-
-		if (pSession->nss > csr_get_nss_supported_by_sta_and_ap(
-						&pIes->VHTCaps,
-						&pIes->HTCaps, dot11mode)) {
-			pSession->nss = csr_get_nss_supported_by_sta_and_ap(
-						&pIes->VHTCaps, &pIes->HTCaps,
-						dot11mode);
-			pSession->vdev_nss = pSession->nss;
-		}
-
-		if (!mac->mlme_cfg->vht_caps.vht_cap_info.enable2x2)
-			pSession->nss = 1;
-
-		if (pSession->nss == 1)
-			pSession->supported_nss_1x1 = true;
-
 		ieLen = csr_get_ielen_from_bss_description(pBssDescription);
 
 		/* Dump the Vendor Specific IEs*/
@@ -15461,6 +15446,38 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
 		vendor_ap_search_attr.enable_5g =
 					IS_5G_CH(pBssDescription->channelId);
 
+		if (IS_5G_CH(pBssDescription->channelId))
+			vdev_type_nss = &mac->vdev_type_nss_5g;
+		else
+			vdev_type_nss = &mac->vdev_type_nss_2g;
+		if (pSession->pCurRoamProfile->csrPersona ==
+		    QDF_P2P_CLIENT_MODE)
+			pSession->vdev_nss = vdev_type_nss->p2p_cli;
+		else
+			pSession->vdev_nss = vdev_type_nss->sta;
+		pSession->nss = pSession->vdev_nss;
+
+		force_max_nss = ucfg_action_oui_search(mac->psoc,
+						&vendor_ap_search_attr,
+						ACTION_OUI_FORCE_MAX_NSS);
+
+		if (!mac->mlme_cfg->vht_caps.vht_cap_info.enable2x2) {
+			force_max_nss = false;
+			pSession->nss = 1;
+		}
+
+		if (!force_max_nss)
+			ap_nss = csr_get_nss_supported_by_sta_and_ap(
+						&pIes->VHTCaps,
+						&pIes->HTCaps, dot11mode);
+		if (!force_max_nss && pSession->nss > ap_nss) {
+			pSession->nss = ap_nss;
+			pSession->vdev_nss = pSession->nss;
+		}
+
+		if (pSession->nss == 1)
+			pSession->supported_nss_1x1 = true;
+
 		is_vendor_ap_present =
 				ucfg_action_oui_search(mac->psoc,
 						       &vendor_ap_search_attr,