Pārlūkot izejas kodu

qcacld-3.0: Support wlan ipa clk voting for kona

Support wlan ipa clk voting for kona. Host should provide
bandiwdth levels to IPA driver for which IPA uc monitors
the levels. Once the threshold is reached IPA uc interrupts
the IPA driver and IPA driver informs host driver via callback
registered.

Change-Id: I9fd805d69858a413f20b9e55a9c02a82054c646b
CRs-Fixed: 2526300
Sravan Kumar Kairam 5 gadi atpakaļ
vecāks
revīzija
761ae63623

+ 15 - 0
components/ipa/core/inc/wlan_ipa_priv.h

@@ -74,6 +74,8 @@
 
 #define IPA_WLAN_RX_SOFTIRQ_THRESH 32
 
+#define WLAN_IPA_UC_BW_MONITOR_LEVEL        3
+
 /**
  * enum - IPA UC operation message
  *
@@ -142,6 +144,18 @@ enum wlan_ipa_forward_type {
 	WLAN_IPA_FORWARD_PKT_DISCARD = 2
 };
 
+/**
+ * enum wlan_ipa_bw_level -ipa bandwidth level
+ * @WLAN_IPA_BW_LEVEL_LOW: vote for low bandwidth
+ * @WLAN_IPA_BW_LEVEL_MEDIUM: vote for medium bandwidth
+ * @WLAN_IPA_BW_LEVEL_HIGH: vote for high bandwidth
+ */
+enum wlan_ipa_bw_level {
+	WLAN_IPA_BW_LEVEL_LOW,
+	WLAN_IPA_BW_LEVEL_MEDIUM,
+	WLAN_IPA_BW_LEVEL_HIGH,
+};
+
 /**
  * struct llc_snap_hdr - LLC snap header
  * @dsap: Destination service access point
@@ -665,6 +679,7 @@ struct wlan_ipa_priv {
 	uint32_t wdi_version;
 	bool is_smmu_enabled;	/* IPA caps returned from ipa_wdi_init */
 	qdf_atomic_t stats_quota;
+	uint8_t curr_bw_level;
 };
 
 #define WLAN_IPA_WLAN_FRAG_HEADER        sizeof(struct frag_header)

+ 38 - 0
components/ipa/core/src/wlan_ipa_core.c

@@ -1758,6 +1758,42 @@ static void wlan_ipa_uc_offload_enable_disable(struct wlan_ipa_priv *ipa_ctx,
 	}
 }
 
+#ifdef WDI3_STATS_UPDATE
+static void wlan_ipa_uc_bw_monitor(struct wlan_ipa_priv *ipa_ctx, bool stop)
+{
+	qdf_ipa_wdi_bw_info_t bw_info;
+	uint32_t bw_low = ipa_ctx->config->ipa_bw_low;
+	uint32_t bw_medium = ipa_ctx->config->ipa_bw_medium;
+	uint32_t bw_high = ipa_ctx->config->ipa_bw_high;
+	int ret;
+
+	bw_info.num = WLAN_IPA_UC_BW_MONITOR_LEVEL;
+	/* IPA uc will mobitor three bw levels for wlan client */
+	QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_1(&bw_info) = bw_low;
+	QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_2(&bw_info) = bw_medium;
+	QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_3(&bw_info) = bw_high;
+	QDF_IPA_WDI_BW_INFO_START_STOP(&bw_info) = stop;
+
+	ret = qdf_ipa_uc_bw_monitor(&bw_info);
+	if (ret)
+		ipa_err("ipa uc bw monitor fails");
+
+	if (!stop) {
+		cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+				       QDF_IPA_CLIENT_WLAN2_CONS,
+				       ipa_ctx->config->ipa_bw_low);
+		ipa_ctx->curr_bw_level = WLAN_IPA_BW_LEVEL_LOW;
+	}
+
+	ipa_debug("ipa uc bw monitor %s", stop ? "stop" : "start");
+}
+#else
+static inline
+void wlan_ipa_uc_bw_monitor(struct wlan_ipa_priv *ipa_ctx, bool stop)
+{
+}
+#endif
+
 /**
  * __wlan_ipa_wlan_evt() - IPA event handler
  * @net_dev: Interface net device
@@ -2211,6 +2247,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 
 				return QDF_STATUS_E_BUSY;
 			}
+			wlan_ipa_uc_bw_monitor(ipa_ctx, false);
 		}
 
 		ipa_ctx->sap_num_connected_sta++;
@@ -2303,6 +2340,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 					wlan_ipa_uc_disable_pipes(ipa_ctx);
 				} else {
 					wlan_ipa_uc_handle_last_discon(ipa_ctx);
+					wlan_ipa_uc_bw_monitor(ipa_ctx, true);
 				}
 			}
 

+ 34 - 0
components/ipa/core/src/wlan_ipa_stats.c

@@ -763,6 +763,40 @@ void wlan_ipa_uc_stat(struct wlan_ipa_priv *ipa_ctx)
 static void __wlan_ipa_wdi_meter_notifier_cb(qdf_ipa_wdi_meter_evt_type_t evt,
 					     void *data)
 {
+	struct wlan_ipa_priv *ipa_ctx = wlan_ipa_get_obj_context();
+	struct qdf_ipa_inform_wlan_bw *bw_info;
+	uint8_t bw_level_index;
+	uint64_t throughput;
+
+	if (evt != IPA_INFORM_WLAN_BW)
+		return;
+
+	bw_info = data;
+	bw_level_index = QDF_IPA_INFORM_WLAN_BW_INDEX(bw_info);
+	throughput = QDF_IPA_INFORM_WLAN_BW_THROUGHPUT(bw_info);
+	ipa_debug("bw_info idx:%d tp:%llu", bw_level_index, throughput);
+
+	if (bw_level_index == ipa_ctx->curr_bw_level)
+		return;
+
+	if (bw_level_index == WLAN_IPA_BW_LEVEL_LOW) {
+		cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+				       QDF_IPA_CLIENT_WLAN2_CONS,
+				       ipa_ctx->config->ipa_bw_low);
+		ipa_ctx->curr_bw_level = WLAN_IPA_BW_LEVEL_LOW;
+	} else if (bw_level_index == WLAN_IPA_BW_LEVEL_MEDIUM) {
+		cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+				       QDF_IPA_CLIENT_WLAN2_CONS,
+				       ipa_ctx->config->ipa_bw_medium);
+		ipa_ctx->curr_bw_level = WLAN_IPA_BW_LEVEL_MEDIUM;
+	} else if (bw_level_index == WLAN_IPA_BW_LEVEL_HIGH) {
+		cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+				       QDF_IPA_CLIENT_WLAN2_CONS,
+				       ipa_ctx->config->ipa_bw_high);
+		ipa_ctx->curr_bw_level = WLAN_IPA_BW_LEVEL_HIGH;
+	}
+
+	ipa_debug("Requested BW level: %d", ipa_ctx->curr_bw_level);
 }
 
 void wlan_ipa_update_tx_stats(struct wlan_ipa_priv *ipa_ctx, uint64_t sta_tx,

+ 29 - 13
core/hdd/src/wlan_hdd_main.c

@@ -8498,6 +8498,30 @@ void hdd_set_driver_del_ack_enable(uint16_t vdev_id,
 }
 #endif
 
+#ifdef WDI3_STATS_UPDATE
+static inline
+void hdd_ipa_set_perf_level(struct hdd_context *hdd_ctx,
+			    uint64_t *tx_pkts, uint64_t *rx_pkts,
+			    uint32_t *ipa_tx_pkts, uint32_t *ipa_rx_pkts)
+{
+}
+#else
+static void hdd_ipa_set_perf_level(struct hdd_context *hdd_ctx,
+				   uint64_t *tx_pkts, uint64_t *rx_pkts,
+				   uint32_t *ipa_tx_pkts, uint32_t *ipa_rx_pkts)
+{
+	if (ucfg_ipa_is_fw_wdi_activated(hdd_ctx->pdev)) {
+		ucfg_ipa_uc_stat_query(hdd_ctx->pdev, ipa_tx_pkts,
+				       ipa_rx_pkts);
+		*tx_pkts += *ipa_tx_pkts;
+		*rx_pkts += *ipa_rx_pkts;
+
+		ucfg_ipa_set_perf_level(hdd_ctx->pdev, *tx_pkts, *rx_pkts);
+		ucfg_ipa_uc_stat_request(hdd_ctx->pdev, 2);
+	}
+}
+#endif
+
 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
 static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
 {
@@ -8599,19 +8623,11 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
 	/* Send embedded Tx packet bytes on STA & SAP interface to IPA driver */
 	ucfg_ipa_update_tx_stats(hdd_ctx->pdev, sta_tx_bytes, sap_tx_bytes);
 
-	if (ucfg_ipa_is_fw_wdi_activated(hdd_ctx->pdev)) {
-		ucfg_ipa_uc_stat_query(hdd_ctx->pdev, &ipa_tx_packets,
-				&ipa_rx_packets);
-		tx_packets += (uint64_t)ipa_tx_packets;
-		rx_packets += (uint64_t)ipa_rx_packets;
-
-		if (con_sap_adapter) {
-			con_sap_adapter->stats.tx_packets += ipa_tx_packets;
-			con_sap_adapter->stats.rx_packets += ipa_rx_packets;
-		}
-
-		ucfg_ipa_set_perf_level(hdd_ctx->pdev, tx_packets, rx_packets);
-		ucfg_ipa_uc_stat_request(hdd_ctx->pdev, 2);
+	hdd_ipa_set_perf_level(hdd_ctx, &tx_packets, &rx_packets,
+			       &ipa_tx_packets, &ipa_rx_packets);
+	if (con_sap_adapter) {
+		con_sap_adapter->stats.tx_packets += ipa_tx_packets;
+		con_sap_adapter->stats.rx_packets += ipa_rx_packets;
 	}
 
 	hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);