From 761ae63623ee19245c1e18e60de15a7c0ba15e86 Mon Sep 17 00:00:00 2001 From: Sravan Kumar Kairam Date: Wed, 11 Sep 2019 21:27:16 +0530 Subject: [PATCH] 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 --- components/ipa/core/inc/wlan_ipa_priv.h | 15 +++++++++ components/ipa/core/src/wlan_ipa_core.c | 38 +++++++++++++++++++++ components/ipa/core/src/wlan_ipa_stats.c | 34 +++++++++++++++++++ core/hdd/src/wlan_hdd_main.c | 42 ++++++++++++++++-------- 4 files changed, 116 insertions(+), 13 deletions(-) diff --git a/components/ipa/core/inc/wlan_ipa_priv.h b/components/ipa/core/inc/wlan_ipa_priv.h index cf5cb05d5f6e..f588d3c9941e 100644 --- a/components/ipa/core/inc/wlan_ipa_priv.h +++ b/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) diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index e88f0571251f..9adf9b246257 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/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); } } diff --git a/components/ipa/core/src/wlan_ipa_stats.c b/components/ipa/core/src/wlan_ipa_stats.c index c701bf25606b..842a0b502d60 100644 --- a/components/ipa/core/src/wlan_ipa_stats.c +++ b/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, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index c8ae1a867641..8a87ba2bead9 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/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);