Browse Source

qcacld-3.0: Set IPA perf level based on bandwidth

Upon an update of the policy_mgr connection table, added logics
to get max bandwidth among all the available connections. The
max bandwidth is passed to HDD IPA component via policy_mgr DP
callbacks, which in turn is used to decide proper IPA perf levels.

Change-Id: I20b3e01b433db566bec2a315a76f3015869fc176
CRs-Fixed: 3609165
Jia Ding 1 year ago
parent
commit
1dee62d637

+ 2 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -2253,6 +2253,7 @@ struct policy_mgr_cdp_cbacks {
  * @hdd_ipa_set_mcc_mode_cb: Callback to set mcc mode for ipa module
  * @hdd_v2_flow_pool_map: Callback to create vdev flow pool
  * @hdd_v2_flow_pool_unmap: Callback to delete vdev flow pool
+ * @hdd_ipa_set_perf_level_bw: Callback to set ipa perf level based on BW
  */
 struct policy_mgr_dp_cbacks {
 	void (*hdd_disable_rx_ol_in_concurrency)(bool);
@@ -2260,6 +2261,7 @@ struct policy_mgr_dp_cbacks {
 	void (*hdd_ipa_set_mcc_mode_cb)(bool);
 	void (*hdd_v2_flow_pool_map)(int);
 	void (*hdd_v2_flow_pool_unmap)(int);
+	void (*hdd_ipa_set_perf_level_bw)(enum hw_mode_bandwidth bw);
 };
 
 /**

+ 8 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -491,6 +491,7 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc,
 {
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 	bool mcc_mode;
+	enum hw_mode_bandwidth max_bw;
 
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
@@ -534,6 +535,13 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc,
 
 		if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb)
 			pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode);
+
+		if (pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw) {
+			max_bw = policy_mgr_get_connection_max_channel_width(
+					psoc);
+			policy_mgr_debug("max channel width %d", max_bw);
+			pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw(max_bw);
+		}
 	}
 
 	if (pm_ctx->conc_cbacks.connection_info_update)

+ 35 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -5019,6 +5019,7 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc,
 	QDF_STATUS qdf_status;
 	bool mcc_mode;
 	uint32_t session_count, cur_freq;
+	enum hw_mode_bandwidth max_bw;
 
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
@@ -5116,6 +5117,13 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc,
 
 		if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb)
 			pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode);
+
+		if (pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw) {
+			max_bw = policy_mgr_get_connection_max_channel_width(
+					psoc);
+			policy_mgr_debug("max channel width %d", max_bw);
+			pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw(max_bw);
+		}
 	}
 
 	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE ||
@@ -12396,3 +12404,30 @@ bool policy_mgr_get_vdev_diff_freq_new_conn(struct wlan_objmgr_psoc *psoc,
 	return match;
 }
 
+enum hw_mode_bandwidth
+policy_mgr_get_connection_max_channel_width(struct wlan_objmgr_psoc *psoc)
+{
+	enum hw_mode_bandwidth bw = HW_MODE_20_MHZ;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint32_t conn_index = 0;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("pm_ctx is NULL");
+		return HW_MODE_20_MHZ;
+	}
+
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+
+	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_index++) {
+		if (pm_conc_connection_list[conn_index].in_use &&
+		    pm_conc_connection_list[conn_index].bw > bw)
+			bw = pm_conc_connection_list[conn_index].bw;
+	}
+
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return bw;
+}
+

+ 13 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -1183,4 +1183,17 @@ policy_mgr_set_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx,
 {
 }
 #endif
+
+/**
+ * policy_mgr_get_connection_max_channel_width() - Get max channel width
+ * among vdevs in use
+ * @psoc: PSOC object pointer
+ *
+ * This function returns max channel width among in-use vdevs
+ *
+ * Return: enum hw_mode_bandwidth
+ */
+enum hw_mode_bandwidth
+policy_mgr_get_connection_max_channel_width(struct wlan_objmgr_psoc *psoc);
+
 #endif

+ 2 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -929,6 +929,8 @@ QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc,
 		dp_cbacks->hdd_v2_flow_pool_map;
 	pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap =
 		dp_cbacks->hdd_v2_flow_pool_unmap;
+	pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw =
+		dp_cbacks->hdd_ipa_set_perf_level_bw;
 
 	return QDF_STATUS_SUCCESS;
 }

+ 16 - 0
core/hdd/inc/wlan_hdd_ipa.h

@@ -66,6 +66,17 @@ QDF_STATUS hdd_ipa_get_tx_pipe(struct hdd_context *hdd_ctx,
 			       struct wlan_hdd_link_info *link,
 			       bool *tx_pipe);
 
+/*
+ * hdd_ipa_set_perf_level_bw() - Set ipa perf level based on BW
+ * @bw: enum hw_mode_bandwidth
+ *
+ * This routine is called to set IPA perf level based on max BW configured
+ * among in-use STA and SAP vdevs.
+ *
+ * Return: None
+ */
+void hdd_ipa_set_perf_level_bw(enum hw_mode_bandwidth bw);
+
 #else
 static inline
 void hdd_ipa_send_nbuf_to_network(qdf_nbuf_t skb, qdf_netdev_t dev)
@@ -83,5 +94,10 @@ hdd_ipa_get_tx_pipe(struct hdd_context *hdd_ctx,
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+static inline void hdd_ipa_set_perf_level_bw(enum hw_mode_bandwidth bw)
+{
+}
+
 #endif
 #endif /* HDD_IPA_H__ */

+ 20 - 0
core/hdd/src/wlan_hdd_ipa.c

@@ -436,4 +436,24 @@ QDF_STATUS hdd_ipa_get_tx_pipe(struct hdd_context *hdd_ctx,
 }
 #endif /* IPA_WDI3_TX_TWO_PIPES */
 
+void hdd_ipa_set_perf_level_bw(enum hw_mode_bandwidth bw)
+{
+	struct hdd_context *hdd_ctx;
+	enum wlan_ipa_bw_level lvl;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx)
+		return;
+
+	if (bw == HW_MODE_320_MHZ)
+		lvl = WLAN_IPA_BW_LEVEL_HIGH;
+	else if (bw == HW_MODE_160_MHZ)
+		lvl = WLAN_IPA_BW_LEVEL_MEDIUM;
+	else
+		lvl = WLAN_IPA_BW_LEVEL_LOW;
+
+	hdd_debug("Vote IPA perf level to %d", lvl);
+	ucfg_ipa_set_perf_level_bw(hdd_ctx->pdev, lvl);
+}
+
 #endif

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

@@ -16436,6 +16436,8 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx)
 	dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
 	dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
 	dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
+	if (ucfg_ipa_set_perf_level_bw_enabled(hdd_ctx->pdev))
+		dp_cbs.hdd_ipa_set_perf_level_bw = hdd_ipa_set_perf_level_bw;
 	status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		hdd_debug("Failed to register DP cb with Policy Manager");