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);