Prechádzať zdrojové kódy

qcacld-3.0: Handle concurrency for green AP component

Invoke green AP start/stop based on the current concurrency
and present state of green AP state machine.

Change-Id: I5648d236e6492f326c7ba9951da550e229352412
CRs-Fixed: 2173952
Himanshu Agarwal 7 rokov pred
rodič
commit
813b2bf082

+ 13 - 10
core/hdd/inc/wlan_hdd_main.h

@@ -1807,6 +1807,19 @@ enum {
 /*
  * Function declarations and documentation
  */
+
+/**
+ * hdd_start_green_ap_state_mc() - to start green AP state mc based on
+ *        present concurrency and state of green AP state machine.
+ * @hdd_ctx: hdd context
+ * @mode: device mode
+ * @is_session_start: BSS start/stop
+ *
+ * Return: 0 - success, < 0 - failure
+ */
+int hdd_start_green_ap_state_mc(struct hdd_context *hdd_ctx,
+				enum QDF_OPMODE mode, bool is_session_start);
+
 int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
 				uint32_t chan_number,
 				enum phy_ch_width chan_bw);
@@ -2904,16 +2917,6 @@ void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc);
 int hdd_driver_memdump_init(void);
 void hdd_driver_memdump_deinit(void);
 
-/**
- * hdd_check_green_ap_enable() - to check whether to enable green ap or not
- * @hdd_ctx: hdd context
- * @is_enabled: 1 - green ap enabled, 0 - green ap not enabled
- *
- * Return: 0 - success, < 0 - failure
- */
-uint8_t hdd_check_green_ap_enable(struct hdd_context *hdd_ctx,
-				     bool *is_enabled);
-
 /**
  * hdd_is_cli_iface_up() - check if there is any cli iface up
  * @hdd_ctx: HDD context

+ 18 - 3
core/hdd/src/wlan_hdd_assoc.c

@@ -1289,9 +1289,12 @@ static void hdd_send_association_event(struct net_device *dev,
 			return;
 		}
 
-		if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
+		if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo)) {
 			policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
 				adapter->device_mode, adapter->session_id);
+			hdd_start_green_ap_state_mc(hdd_ctx,
+						    adapter->device_mode, true);
+		}
 		memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
 		       sizeof(pCsrRoamInfo->pBssDesc->bssId));
 
@@ -1386,6 +1389,8 @@ static void hdd_send_association_event(struct net_device *dev,
 		memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
 		policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
 				adapter->device_mode, adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
 
 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
 		wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
@@ -2195,9 +2200,12 @@ static void hdd_send_re_assoc_event(struct net_device *dev,
 	 * active session count should still be the same and hence upon
 	 * successful reassoc decrement the active session count here.
 	 */
-	if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
+	if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo)) {
 		policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
 				adapter->device_mode, adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
+	}
 
 	/* Send the Assoc Resp, the supplicant needs this for initial Auth */
 	len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
@@ -2905,11 +2913,16 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 						 * count here.
 						 */
 						if (!hdd_is_roam_sync_in_progress
-								(roam_info))
+								(roam_info)) {
 						policy_mgr_decr_session_set_pcl(
 							hdd_ctx->hdd_psoc,
 							adapter->device_mode,
 							adapter->session_id);
+						hdd_start_green_ap_state_mc(
+							hdd_ctx,
+							adapter->device_mode,
+							false);
+						}
 						hdd_debug("ft_carrier_on is %d, sending roamed indication",
 							 ft_carrier_on);
 						chan =
@@ -3392,6 +3405,8 @@ static void hdd_roam_ibss_indication_handler(struct hdd_adapter *adapter,
 		if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
 			policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
 				adapter->device_mode, adapter->session_id);
+			hdd_start_green_ap_state_mc(hdd_ctx,
+						    adapter->device_mode, true);
 		} else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
 				eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
 			policy_mgr_update_connection_info(hdd_ctx->hdd_psoc,

+ 11 - 37
core/hdd/src/wlan_hdd_hostapd.c

@@ -859,6 +859,8 @@ static int hdd_stop_bss_link(struct hdd_adapter *adapter,
 		policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
 					adapter->device_mode,
 					adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
 	}
 	EXIT();
 	return (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
@@ -5200,6 +5202,8 @@ __iw_softap_stopbss(struct net_device *dev,
 		policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
 					     adapter->device_mode,
 					     adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
 		ret = qdf_status_to_os_return(status);
 	}
 	EXIT();
@@ -8293,10 +8297,13 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter,
 	set_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
 	/* Initialize WMM configuation */
 	hdd_wmm_init(adapter);
-	if (hostapd_state->bss_state == BSS_START)
+	if (hostapd_state->bss_state == BSS_START) {
 		policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
 					adapter->device_mode,
 					adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, adapter->device_mode,
+					    true);
+	}
 #ifdef DHCP_SERVER_OFFLOAD
 	if (iniConfig->enableDHCPServerOffload)
 		wlan_hdd_set_dhcp_server_offload(adapter);
@@ -8424,29 +8431,9 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 		wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
 	}
 
-	if (adapter->device_mode == QDF_SAP_MODE) {
-		uint8_t num_sessions;
-
+	if (adapter->device_mode == QDF_SAP_MODE)
 		wlan_hdd_del_station(adapter);
 
-		/*
-		 * For AP+AP mode, only trigger GREEN_AP_PS_STOP_EVENT, when the
-		 * last AP stops.
-		 */
-		status = policy_mgr_mode_specific_num_open_sessions(
-				hdd_ctx->hdd_psoc, QDF_SAP_MODE, &num_sessions);
-		if (status == QDF_STATUS_SUCCESS) {
-			if (num_sessions == 1) {
-				hdd_debug("Disabling Green AP");
-				ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
-							    false);
-				wlan_green_ap_stop(hdd_ctx->hdd_pdev);
-			}
-		} else {
-			hdd_err("Failed to get num open sessions for QDF_SAP_MODE");
-		}
-	}
-
 	cds_flush_work(&adapter->sap_stop_bss_work);
 	/*
 	 * When ever stop ap adapter gets called, we need to check
@@ -8509,6 +8496,8 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 		policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
 						adapter->device_mode,
 						adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
 		adapter->session.ap.beacon = NULL;
 		qdf_mem_free(old);
 	}
@@ -8697,9 +8686,6 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 	int status;
 	struct sme_sta_inactivity_timeout  *sta_inactivity_timer;
 	uint8_t channel;
-	bool is_enabled = false;
-	uint8_t ret;
-
 	ENTER();
 
 	clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
@@ -8813,18 +8799,6 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 		}
 	}
 
-	ret = hdd_check_green_ap_enable(hdd_ctx, &is_enabled);
-	if (!ret) {
-		hdd_debug("Green AP enable status: %d", is_enabled);
-		if (is_enabled) {
-			hdd_debug("Enabling Green AP");
-			ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev, true);
-			wlan_green_ap_start(hdd_ctx->hdd_pdev);
-		}
-	} else {
-		hdd_err("Failed to check if Green AP should be enabled or not");
-	}
-
 	if (adapter->device_mode == QDF_P2P_GO_MODE) {
 		struct hdd_adapter  *p2p_adapter;
 

+ 137 - 43
core/hdd/src/wlan_hdd_main.c

@@ -309,6 +309,125 @@ void hdd_start_complete(int ret)
 	complete(&wlan_start_comp);
 }
 
+/**
+ * hdd_check_green_ap_enable() - to check whether to enable green ap or not
+ * @hdd_ctx: hdd context
+ * @enable_green_ap: 1 - enable green ap enabled, 0 - disbale green ap
+ *
+ * Return: 0 - success, < 0 - failure
+ */
+static int hdd_check_green_ap_enable(struct hdd_context *hdd_ctx,
+				     bool *enable_green_ap)
+{
+	uint8_t num_sessions, mode;
+	QDF_STATUS status;
+
+	for (mode = 0;
+	     mode < QDF_MAX_NO_OF_MODE;
+	     mode++) {
+		if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
+			continue;
+
+		status = policy_mgr_mode_specific_num_active_sessions(
+					hdd_ctx->hdd_psoc, mode, &num_sessions);
+		hdd_debug("No. of active sessions for mode: %d is %d",
+			  mode, num_sessions);
+		if (status != QDF_STATUS_SUCCESS) {
+			hdd_err("Failed to get num sessions for mode: %d",
+				mode);
+			return -EINVAL;
+		} else if (num_sessions) {
+			*enable_green_ap = false;
+			return 0;
+		}
+	}
+	*enable_green_ap = true;
+	return 0;
+}
+
+int hdd_start_green_ap_state_mc(struct hdd_context *hdd_ctx,
+				enum QDF_OPMODE mode, bool is_session_start)
+{
+	struct hdd_config *cfg;
+	bool enable_green_ap = false;
+	uint8_t num_sap_sessions = 0, num_p2p_go_sessions = 0, ret = 0;
+
+	cfg = hdd_ctx->config;
+	if (!cfg) {
+		hdd_err("NULL hdd config");
+		return -EINVAL;
+	}
+
+	if (!cfg->enable2x2 || !cfg->enableGreenAP) {
+		hdd_info("Green AP support not present: enable2x2: %d, enableGreenAp: %d",
+			 cfg->enable2x2, cfg->enableGreenAP);
+		return 0;
+	}
+
+	policy_mgr_mode_specific_num_active_sessions(hdd_ctx->hdd_psoc,
+						     QDF_SAP_MODE,
+						     &num_sap_sessions);
+	policy_mgr_mode_specific_num_active_sessions(hdd_ctx->hdd_psoc,
+						     QDF_P2P_GO_MODE,
+						     &num_p2p_go_sessions);
+
+	switch (mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_IBSS_MODE:
+		if (!num_sap_sessions && !num_p2p_go_sessions)
+			return 0;
+
+		if (is_session_start) {
+			hdd_debug("Disabling Green AP");
+			ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
+						    false);
+			wlan_green_ap_stop(hdd_ctx->hdd_pdev);
+		} else {
+			ret = hdd_check_green_ap_enable(hdd_ctx,
+							&enable_green_ap);
+			if (!ret) {
+				if (enable_green_ap) {
+					hdd_debug("Enabling Green AP");
+					ucfg_green_ap_set_ps_config(
+						hdd_ctx->hdd_pdev, true);
+					wlan_green_ap_start(hdd_ctx->hdd_pdev);
+				}
+			} else {
+				hdd_err("Failed to check Green AP enable status");
+			}
+		}
+		break;
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+		if (is_session_start) {
+			ret = hdd_check_green_ap_enable(hdd_ctx,
+							&enable_green_ap);
+			if (!ret) {
+				if (enable_green_ap) {
+					hdd_debug("Enabling Green AP");
+					ucfg_green_ap_set_ps_config(
+						hdd_ctx->hdd_pdev, true);
+					wlan_green_ap_start(hdd_ctx->hdd_pdev);
+				}
+			} else {
+				hdd_err("Failed to check Green AP enable status");
+			}
+		} else {
+			if (!num_sap_sessions && !num_p2p_go_sessions) {
+				hdd_debug("Disabling Green AP");
+				ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
+							    false);
+				wlan_green_ap_stop(hdd_ctx->hdd_pdev);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
 /**
  * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
  * @hdd_ctx: pointer to struct hdd_context
@@ -1802,28 +1921,6 @@ static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
 }
 #endif
 
-uint8_t hdd_check_green_ap_enable(struct hdd_context *hdd_ctx,
-				     bool *is_enabled)
-{
-	struct hdd_config *cfg;
-	uint32_t concurrency_mode;
-
-	cfg = hdd_ctx->config;
-	if (!cfg) {
-		hdd_err("NULL hdd config");
-		return -EINVAL;
-	}
-
-	concurrency_mode = policy_mgr_get_concurrency_mode(hdd_ctx->hdd_psoc);
-
-	if (cfg->enable2x2 && cfg->enableGreenAP) {
-		if ((concurrency_mode & (1 << QDF_SAP_MODE)) &&
-		    !(concurrency_mode & (~(1 << QDF_SAP_MODE))))
-			*is_enabled = true;
-	}
-	return 0;
-}
-
 static int hdd_update_green_ap_config(struct hdd_context *hdd_ctx)
 {
 	struct green_ap_user_cfg green_ap_cfg;
@@ -3849,10 +3946,6 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
 	}
 	hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
 
-	hdd_debug("Disabling Green AP");
-	ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev, false);
-	wlan_green_ap_stop(hdd_ctx->hdd_pdev);
-
 	qdf_mem_set(sta_ctx->conn_info.staId,
 		sizeof(sta_ctx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
 
@@ -4740,8 +4833,6 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
 	tSirUpdateIE updateIE;
 	unsigned long rc;
 	tsap_Config_t *sap_config;
-	bool is_enabled = false;
-	uint8_t ret;
 
 	ENTER();
 
@@ -4845,19 +4936,6 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
 			return QDF_STATUS_E_FAILURE;
 		}
 
-		ret = hdd_check_green_ap_enable(hdd_ctx, &is_enabled);
-		if (!ret) {
-			hdd_debug("Green AP enable status: %d", is_enabled);
-			if (is_enabled) {
-				hdd_debug("Enabling Green AP");
-				ucfg_green_ap_set_ps_config(hdd_ctx->hdd_pdev,
-							    true);
-				wlan_green_ap_start(hdd_ctx->hdd_pdev);
-			}
-		} else {
-			hdd_err("Failed to check if Green AP should be enabled or not");
-		}
-
 		hdd_vdev_destroy(adapter);
 		break;
 
@@ -4925,6 +5003,9 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
 			policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
 						adapter->device_mode,
 						adapter->session_id);
+			hdd_start_green_ap_state_mc(hdd_ctx,
+						    adapter->device_mode,
+						    false);
 
 			qdf_copy_macaddr(&updateIE.bssid,
 					 &adapter->mac_addr);
@@ -5095,6 +5176,8 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
 		hdd_deinit_tx_rx(adapter);
 		policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
 				adapter->device_mode, adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, adapter->device_mode,
+					    false);
 		if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
 			hdd_wmm_adapter_close(adapter);
 			clear_bit(WMM_INIT_DONE, &adapter->event_flags);
@@ -11410,6 +11493,8 @@ void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
 		policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
 						ap_adapter->device_mode,
 						ap_adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, ap_adapter->device_mode,
+					    false);
 		hdd_debug("SAP Stop Success");
 	} else {
 		hdd_err("Can't stop ap because its not started");
@@ -11474,10 +11559,13 @@ void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
 	hdd_info("SAP Start Success");
 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
 	set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
-	if (hostapd_state->bss_state == BSS_START)
+	if (hostapd_state->bss_state == BSS_START) {
 		policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
 					ap_adapter->device_mode,
 					ap_adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, ap_adapter->device_mode,
+					    true);
+	}
 	mutex_unlock(&hdd_ctx->sap_lock);
 
 	return;
@@ -13222,6 +13310,8 @@ void hdd_restart_sap(struct hdd_adapter *ap_adapter)
 		clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
 		policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
 			ap_adapter->device_mode, ap_adapter->session_id);
+		hdd_start_green_ap_state_mc(hdd_ctx, ap_adapter->device_mode,
+					    false);
 		hdd_err("SAP Stop Success");
 
 		if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
@@ -13253,10 +13343,14 @@ void hdd_restart_sap(struct hdd_adapter *ap_adapter)
 		}
 		hdd_err("SAP Start Success");
 		set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
-		if (hostapd_state->bss_state == BSS_START)
+		if (hostapd_state->bss_state == BSS_START) {
 			policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
 						ap_adapter->device_mode,
 						ap_adapter->session_id);
+			hdd_start_green_ap_state_mc(hdd_ctx,
+						    ap_adapter->device_mode,
+						    true);
+		}
 	}
 end:
 	mutex_unlock(&hdd_ctx->sap_lock);