Ver Fonte

qcacld-3.0: Enable station SMPS only if the session supported NSS > 1

If HT SMPS is enabled and if the session supported NSS > 1
then include SMPS IE in the HT capabilities of the association
and the reassociation management frame.Enabling SMPS with an AP
whose capability is only 1x1 will result in association/reassociation
request being rejected or an unexpected behavior. Send SMPS force mode
to FW to trigger SMPS action frame only if SMPS is enabled in the
INI. For dynamic antenna switch, the chain mask manager will send
the SMPS action frames.

CRs-Fixed: 931250
Change-Id: Ifff2ef2c8790994a68e676b8bba2fb03c21370d4
Archana Ramachandran há 9 anos atrás
pai
commit
20d2e23fca

+ 1 - 0
core/mac/inc/sir_api.h

@@ -1032,6 +1032,7 @@ typedef struct sSirSmeJoinRsp {
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
 	tSirSmeHTProfile HTProfile;
 #endif
+	bool supported_nss_1x1;
 	uint8_t frames[1];
 } tSirSmeJoinRsp, *tpSirSmeJoinRsp;
 

+ 2 - 0
core/mac/inc/sir_mac_prot_def.h

@@ -386,6 +386,8 @@
 #define SIR_MAC_VHT_OPMODE_EID         199
 #define SIR_MAC_MAX_SUPPORTED_MCS_SET    16
 
+#define VHT_MCS_1x1 0xFFFC
+
 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
 #define SIR_MAC_QCOM_VENDOR_EID      200
 #define SIR_MAC_QCOM_VENDOR_OUI      "\x00\xA0\xC6"

+ 2 - 0
core/mac/src/pe/include/lim_session.h

@@ -474,6 +474,8 @@ typedef struct sPESession       /* Added to Support BT-AMP */
 	struct csa_offload_params saved_csa_params;
 	/* To hold OBSS Scan IE Parameters */
 	struct obss_scanparam obss_ht40_scanparam;
+	/* Supported NSS is intersection of self and peer NSS */
+	bool supported_nss_1x1;
 } tPESession, *tpPESession;
 
 /*-------------------------------------------------------------------------

+ 16 - 1
core/mac/src/pe/lim/lim_assoc_utils.c

@@ -1590,6 +1590,15 @@ tSirRetStatus lim_populate_vht_mcs_set(tpAniSirGlobal mac_ctx,
 		mac_ctx->roam.configParam.enable2x2,
 		rates->vhtRxMCSMap, rates->vhtTxMCSMap);
 
+	if (NULL != session_entry) {
+		session_entry->supported_nss_1x1 =
+			((rates->vhtTxMCSMap & VHT_MCS_1x1) ==
+			 VHT_MCS_1x1) ? true : false;
+		lim_log(mac_ctx, LOG1,
+		       FL("VHT supported nss 1x1: %d"),
+		       session_entry->supported_nss_1x1);
+	}
+
 	return eSIR_SUCCESS;
 error:
 
@@ -1891,6 +1900,11 @@ lim_populate_peer_rate_set(tpAniSirGlobal pMac,
 				       (pMac, LOG2, FL("%x "),
 				       pRates->supportedMCSSet[i]);
 			       )
+
+		psessionEntry->supported_nss_1x1 =
+			((pRates->supportedMCSSet[1] != 0) ? false : true);
+		PELOG1(lim_log(pMac, LOG1, FL("HT supported nss 1x1: %d"),
+			      psessionEntry->supported_nss_1x1);)
 	}
 	lim_populate_vht_mcs_set(pMac, pRates, pVHTCaps, psessionEntry);
 	return eSIR_SUCCESS;
@@ -2996,7 +3010,8 @@ lim_add_sta_self(tpAniSirGlobal pMac, uint16_t staIdx, uint8_t updateSta,
 	pAddStaParams->vhtTxMUBformeeCapable = psessionEntry->txMuBformee;
 	pAddStaParams->enableVhtpAid = psessionEntry->enableVhtpAid;
 	pAddStaParams->enableAmpduPs = psessionEntry->enableAmpduPs;
-	pAddStaParams->enableHtSmps = psessionEntry->enableHtSmps;
+	pAddStaParams->enableHtSmps = (psessionEntry->enableHtSmps &&
+				(!psessionEntry->supported_nss_1x1));
 	pAddStaParams->htSmpsconfig = psessionEntry->htSmpsvalue;
 
 	/* For Self STA get the LDPC capability from session i.e config.ini */

+ 6 - 0
core/mac/src/pe/lim/lim_ft.c

@@ -933,6 +933,12 @@ void lim_fill_ft_session(tpAniSirGlobal pMac,
 		eHT_CHANNEL_WIDTH_40MHZ))
 		lim_init_obss_params(pMac, pftSessionEntry);
 
+	pftSessionEntry->enableHtSmps = psessionEntry->enableHtSmps;
+	pftSessionEntry->smpsMode = psessionEntry->smpsMode;
+	lim_log(pMac, LOG1, FL("FT session enable smps: %d mode: %d"),
+		pftSessionEntry->enableHtSmps,
+		pftSessionEntry->smpsMode);
+
 	qdf_mem_free(pBeaconStruct);
 }
 

+ 10 - 0
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -1744,6 +1744,10 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
 		session->enableAmpduPs = sme_join_req->enableAmpduPs;
 		session->enableHtSmps = sme_join_req->enableHtSmps;
 		session->htSmpsvalue = sme_join_req->htSmps;
+		lim_log(mac_ctx, LOG1,
+			FL("enableHtSmps: %d htSmps: %d"),
+			session->enableHtSmps,
+			session->htSmpsvalue);
 
 		/*Store Persona */
 		session->pePersona = sme_join_req->staPersona;
@@ -2164,6 +2168,12 @@ static void __lim_process_sme_reassoc_req(tpAniSirGlobal mac_ctx,
 	session_entry->dot11mode = reassoc_req->dot11mode;
 	session_entry->vhtCapability =
 		IS_DOT11_MODE_VHT(reassoc_req->dot11mode);
+
+	session_entry->enableHtSmps = reassoc_req->enableHtSmps;
+	session_entry->htSmpsvalue = reassoc_req->htSmps;
+	lim_log(mac_ctx, LOG1, FL("enableHtSmps: %d htSmps: %d"),
+		session_entry->enableHtSmps,
+		session_entry->htSmpsvalue);
 	/*
 	 * Reassociate request is expected
 	 * in link established state only.

+ 7 - 0
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -493,6 +493,13 @@ lim_send_sme_join_reassoc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
 
 		lim_handle_join_rsp_status(mac_ctx, session_entry, result_code,
 			sme_join_rsp);
+
+		/* Send supported NSS 1x1 to SME */
+		sme_join_rsp->supported_nss_1x1 =
+			session_entry->supported_nss_1x1;
+		lim_log(mac_ctx, LOG1,
+		       FL("SME Join Rsp is supported NSS 1X1: %d"),
+		       sme_join_rsp->supported_nss_1x1);
 	}
 
 	sme_join_rsp->messageType = msg_type;

+ 12 - 0
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -769,6 +769,18 @@ populate_dot11f_ht_caps(tpAniSirGlobal pMac,
 			pDot11f->supportedMCSSet[1] = 0;
 	}
 
+	/* If STA mode, session supported NSS > 1 and
+	 * SMPS enabled publish HT SMPS IE
+	 */
+	if (psessionEntry && (!pMac->lteCoexAntShare) &&
+	    LIM_IS_STA_ROLE(psessionEntry) &&
+	    (psessionEntry->enableHtSmps) &&
+	    (!psessionEntry->supported_nss_1x1)) {
+		lim_log(pMac, LOG1, FL("Add SM power save IE: %d"),
+			psessionEntry->htSmpsvalue);
+		pDot11f->mimoPowerSave = psessionEntry->htSmpsvalue;
+	}
+
 	CFG_GET_INT(nSirStatus, pMac, WNI_CFG_EXT_HT_CAP_INFO, nCfgValue);
 
 	uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;

+ 1 - 0
core/sme/inc/csr_internal.h

@@ -965,6 +965,7 @@ typedef struct tagCsrRoamSession {
 	struct csr_roam_stored_profile stored_roam_profile;
 	bool ch_switch_in_progress;
 	bool roam_synch_in_progress;
+	bool supported_nss_1x1;
 } tCsrRoamSession;
 
 typedef struct tagCsrRoamStruct {

+ 5 - 0
core/sme/inc/sme_api.h

@@ -1097,4 +1097,9 @@ static inline QDF_STATUS sme_send_egap_conf_params(uint32_t enable,
 void sme_update_fine_time_measurement_capab(tHalHandle hal, uint32_t val);
 QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hHal, uint32_t vdev_id);
 
+QDF_STATUS sme_update_mimo_power_save(tHalHandle hHal,
+				      uint8_t is_ht_smps_enabled,
+				      uint8_t ht_smps_mode);
+
+bool sme_is_sta_smps_allowed(tHalHandle hHal, uint8_t session_id);
 #endif /* #if !defined( __SME_API_H ) */

+ 57 - 0
core/sme/src/common/sme_api.c

@@ -15385,3 +15385,60 @@ QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hal, uint32_t vdev_id)
 	wma_ht40_stop_obss_scan(wma_handle, vdev_id);
 	return QDF_STATUS_SUCCESS;
 }
+
+/**
+ * sme_update_mimo_power_save() - Update MIMO power save
+ * configuration
+ * @hal: The handle returned by macOpen
+ * @is_ht_smps_enabled: enable/disable ht smps
+ * @ht_smps_mode: smps mode disabled/static/dynamic
+ *
+ * Return: QDF_STATUS if SME update mimo power save
+ * configuration sucsess else failue status
+ */
+QDF_STATUS sme_update_mimo_power_save(tHalHandle hal,
+				      uint8_t is_ht_smps_enabled,
+				      uint8_t ht_smps_mode)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	sms_log(mac_ctx, LOG1,
+		"update SMPS config enable smps: %d mode: %d",
+		is_ht_smps_enabled, ht_smps_mode);
+	mac_ctx->roam.configParam.enableHtSmps =
+		is_ht_smps_enabled;
+	mac_ctx->roam.configParam.htSmps = ht_smps_mode;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * sme_is_sta_smps_allowed() - check if the supported nss for
+ * the session is greater than 1x1 to enable sta SMPS
+ * @hal: The handle returned by macOpen
+ * @session_id: session id
+ *
+ * Return: bool returns true if supported nss is greater than
+ * 1x1 else false
+ */
+bool sme_is_sta_smps_allowed(tHalHandle hal, uint8_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	tCsrRoamSession *csr_session;
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sms_log(mac_ctx, LOGE,
+			"CSR session not valid: %d",
+			session_id);
+		return false;
+	}
+
+	csr_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == csr_session) {
+		sms_log(mac_ctx, LOGE,
+			"SME session not valid: %d",
+			session_id);
+		return false;
+	}
+
+	return (csr_session->supported_nss_1x1 == true) ? false : true;
+}

+ 10 - 0
core/sme/src/csr/csr_api_roam.c

@@ -2290,6 +2290,9 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
 		pMac->roam.configParam.obss_active_dwelltime;
 	pParam->obss_passive_dwelltime =
 		pMac->roam.configParam.obss_passive_dwelltime;
+	pParam->enableHtSmps = pMac->roam.configParam.enableHtSmps;
+	pParam->htSmps = pMac->roam.configParam.htSmps;
+	pParam->send_smps_action = pMac->roam.configParam.send_smps_action;
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -8011,6 +8014,13 @@ static void csr_roam_join_rsp_processor(tpAniSirGlobal pMac,
 					      SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
 #endif
 		}
+
+		session_ptr->supported_nss_1x1 =
+			pSmeJoinRsp->supported_nss_1x1;
+		sms_log(pMac, LOG1,
+			FL("SME session supported nss: %d"),
+			session_ptr->supported_nss_1x1);
+
 		/* *
 		 * The join bssid count can be reset as soon as
 		 * we are done with the join requests and returning

+ 1 - 0
core/wma/inc/wma_internal.h

@@ -814,6 +814,7 @@ int wma_stats_ext_event_handler(void *handle, uint8_t *event_buf,
 #endif
 
 tSmpsModeValue host_map_smps_mode(A_UINT32 fw_smps_mode);
+int wma_smps_mode_to_force_mode_param(uint8_t smps_mode);
 
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
 void wma_register_ll_stats_event_handler(tp_wma_handle wma_handle);

+ 17 - 6
core/wma/src/wma_dev_if.c

@@ -3623,6 +3623,7 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
 	bool peer_assoc_cnf = false;
 	struct vdev_up_params param = {0};
 	struct pdev_params pdev_param = {0};
+	int smps_param;
 
 #ifdef FEATURE_WLAN_TDLS
 	if (STA_ENTRY_TDLS_PEER == params->staType) {
@@ -3798,13 +3799,23 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
 		 __func__, iface->type, iface->sub_type);
 	/* Sta is now associated, configure various params */
 
-	/* SM power save, configure the h/w as configured
-	 * in the ini file. SMPS is not published in assoc
-	 * request. Once configured, fw sends the required
-	 * action frame to AP.
+	/* Send SMPS force command to FW to send the required
+	 * action frame only when SM power save is enbaled in
+	 * the INI. In case dynamic antenna selection, the
+	 * action frames are sent by the chain mask manager.
+	 * In addition to the action frames, The SM power save is
+	 * published in the assoc request HT SMPS IE for both cases.
 	 */
-	if (params->enableHtSmps)
-		wma_set_mimops(wma, params->smesessionId, params->htSmpsconfig);
+	if (params->enableHtSmps) {
+		smps_param = wma_smps_mode_to_force_mode_param(
+			params->htSmpsconfig);
+		if (smps_param >= 0) {
+			WMA_LOGD("%s: Set MIMO power save smps mode %d",
+				__func__, params->htSmpsconfig);
+			wma_set_mimops(wma, params->smesessionId,
+				smps_param);
+		}
+	}
 
 	/* Partial AID match power save, enable when SU bformee */
 	if (params->enableVhtpAid && params->vhtTxBFCapable)

+ 3 - 2
core/wma/src/wma_main.c

@@ -566,8 +566,9 @@ static int32_t wma_set_priv_cfg(tp_wma_handle wma_handle,
 					      privcmd->param_value);
 		break;
 	case WMI_STA_SMPS_FORCE_MODE_CMDID:
-		wma_set_mimops(wma_handle, privcmd->param_vdev_id,
-			       privcmd->param_value);
+		ret = wma_set_mimops(wma_handle,
+				     privcmd->param_vdev_id,
+				     privcmd->param_value);
 		break;
 	case WMI_STA_SMPS_PARAM_CMDID:
 		wma_set_smps_params(wma_handle, privcmd->param_vdev_id,

+ 28 - 0
core/wma/src/wma_utils.c

@@ -315,6 +315,34 @@ tSmpsModeValue host_map_smps_mode(A_UINT32 fw_smps_mode)
 	return smps_mode;
 }
 
+/**
+ * wma_smps_mode_to_force_mode_param() - Map smps mode to force
+ * mode commmand param
+ * @smps_mode: SMPS mode according to the protocol
+ *
+ * Return: int > 0 for success else failure
+ */
+int wma_smps_mode_to_force_mode_param(uint8_t smps_mode)
+{
+	int param = -EINVAL;
+
+	switch (smps_mode) {
+	case STATIC_SMPS_MODE:
+		param = WMI_SMPS_FORCED_MODE_STATIC;
+		break;
+	case DYNAMIC_SMPS_MODE:
+		param = WMI_SMPS_FORCED_MODE_DYNAMIC;
+		break;
+	case SMPS_MODE_DISABLED:
+		param = WMI_SMPS_FORCED_MODE_DISABLED;
+		break;
+	default:
+		WMA_LOGE(FL("smps mode cannot be mapped :%d "),
+			 smps_mode);
+	}
+	return param;
+}
+
 #ifdef WLAN_FEATURE_STATS_EXT
 /**
  * wma_stats_ext_event_handler() - extended stats event handler