From 7da05db9f2d7608ec2c904971fe6dadde54c3863 Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Tue, 26 May 2020 16:40:08 +0530 Subject: [PATCH] qcacld-3.0: Add different PLD vote for latency sensitive case Any connection in 11g/a is very latency sensitive and we need to vote for a higher DDR frequency than in the other phy modes. Identify the number of latency sensitive connections in STA mode and vote for higher DDR frequency for the latency sensitive cases. Change-Id: I2ce20b2b40213bde52211eae659c9673c6e0d305 CRs-fixed: 2695045 --- core/hdd/inc/wlan_hdd_main.h | 50 ++++++++++++++++++++++++++++++++ core/hdd/src/wlan_hdd_assoc.c | 9 ++++++ core/hdd/src/wlan_hdd_cfg80211.c | 31 ++++++++++++++++++++ core/hdd/src/wlan_hdd_cfg80211.h | 9 ++++++ core/hdd/src/wlan_hdd_main.c | 19 +++++++++++- core/pld/inc/pld_common.h | 2 ++ 6 files changed, 119 insertions(+), 1 deletion(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 37766275dc16..c8f58ae4e560 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1642,6 +1642,7 @@ struct hdd_fw_ver_info { * @pdev: object manager pdev context * @iftype_data_2g: Interface data for 2g band * @iftype_data_5g: Interface data for 5g band + * @num_latency_critical_clients: Number of latency critical clients connected * @bus_bw_work: work for periodically computing DDR bus bandwidth requirements * @g_event_flags: a bitmap of hdd_driver_flags * @psoc_idle_timeout_work: delayed work for psoc idle shutdown @@ -1708,6 +1709,7 @@ struct hdd_context { int32_t oem_pid; #endif + qdf_atomic_t num_latency_critical_clients; /** Concurrency Parameters*/ uint32_t concurrency_mode; @@ -2537,6 +2539,54 @@ QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr, */ bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx); +/** + * hdd_add_latency_critical_client() - Add latency critical client + * @hdd_ctx: Global HDD context + * @phymode: the phymode of the connected adapter + * + * This function adds to the latency critical count if the present + * connection is also a latency critical one. + * + * Returns: None + */ +static inline void +hdd_add_latency_critical_client(struct hdd_context *hdd_ctx, + enum qca_wlan_802_11_mode phymode) +{ + switch (phymode) { + case QCA_WLAN_802_11_MODE_11A: + case QCA_WLAN_802_11_MODE_11G: + qdf_atomic_inc(&hdd_ctx->num_latency_critical_clients); + break; + default: + break; + } +} + +/** + * hdd_del_latency_critical_client() - Add tlatency critical client + * @hdd_ctx: Global HDD context + * @phymode: the phymode of the connected adapter + * + * This function removes from the latency critical count if the present + * connection is also a latency critical one. + * + * Returns: None + */ +static inline void +hdd_del_latency_critical_client(struct hdd_context *hdd_ctx, + enum qca_wlan_802_11_mode phymode) +{ + switch (phymode) { + case QCA_WLAN_802_11_MODE_11A: + case QCA_WLAN_802_11_MODE_11G: + qdf_atomic_dec(&hdd_ctx->num_latency_critical_clients); + break; + default: + break; + } +} + #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH /** * hdd_bus_bw_compute_prev_txrx_stats() - get tx and rx stats diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index a5d197cebd5b..551d0f3e4434 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1574,6 +1574,11 @@ static void hdd_send_association_event(struct net_device *dev, roam_info->tdls_prohibited, adapter->vdev); #endif + + hdd_add_latency_critical_client( + hdd_ctx, + hdd_convert_cfgdot11mode_to_80211mode( + sta_ctx->conn_info.dot11mode)); /* start timer in sta/p2p_cli */ hdd_bus_bw_compute_prev_txrx_stats(adapter); hdd_bus_bw_compute_timer_start(hdd_ctx); @@ -1613,6 +1618,10 @@ static void hdd_send_association_event(struct net_device *dev, false, adapter->vdev); + hdd_del_latency_critical_client( + hdd_ctx, + hdd_convert_cfgdot11mode_to_80211mode( + sta_ctx->conn_info.dot11mode)); /* stop timer in sta/p2p_cli */ hdd_bus_bw_compute_reset_prev_txrx_stats(adapter); hdd_bus_bw_compute_timer_try_stop(hdd_ctx); diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index c53e4b7557a2..42abedb23899 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -22977,6 +22977,37 @@ static int wlan_hdd_cfg80211_get_chainmask(struct wiphy *wiphy, return errno; } +enum qca_wlan_802_11_mode +hdd_convert_cfgdot11mode_to_80211mode(enum csr_cfgdot11mode mode) +{ + switch (mode) { + case eCSR_CFG_DOT11_MODE_11A: + return QCA_WLAN_802_11_MODE_11A; + case eCSR_CFG_DOT11_MODE_11B: + return QCA_WLAN_802_11_MODE_11B; + case eCSR_CFG_DOT11_MODE_11G: + return QCA_WLAN_802_11_MODE_11G; + case eCSR_CFG_DOT11_MODE_11N: + return QCA_WLAN_802_11_MODE_11N; + case eCSR_CFG_DOT11_MODE_11AC: + return QCA_WLAN_802_11_MODE_11AC; + case eCSR_CFG_DOT11_MODE_11G_ONLY: + return QCA_WLAN_802_11_MODE_11G; + case eCSR_CFG_DOT11_MODE_11N_ONLY: + return QCA_WLAN_802_11_MODE_11N; + case eCSR_CFG_DOT11_MODE_11AC_ONLY: + return QCA_WLAN_802_11_MODE_11AC; + case eCSR_CFG_DOT11_MODE_11AX: + return QCA_WLAN_802_11_MODE_11AX; + case eCSR_CFG_DOT11_MODE_11AX_ONLY: + return QCA_WLAN_802_11_MODE_11AX; + case eCSR_CFG_DOT11_MODE_ABG: + case eCSR_CFG_DOT11_MODE_AUTO: + default: + return QCA_WLAN_802_11_MODE_INVALID; + } +} + /** * struct cfg80211_ops - cfg80211_ops * diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 8008466ad5a3..f20b99f8b4a6 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -816,4 +816,13 @@ void wlan_hdd_set_wlm_mode(struct hdd_context *hdd_ctx, uint16_t latency_level) } #endif +/** + * hdd_convert_cfgdot11mode_to_80211mode() - Function to convert cfg dot11 mode + * to 80211 mode + * @mode: cfg dot11 mode + * + * Return: 80211 mode + */ +enum qca_wlan_802_11_mode +hdd_convert_cfgdot11mode_to_80211mode(enum csr_cfgdot11mode mode); #endif diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index de55c7897107..34e6aecd74da 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -6243,6 +6243,7 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio } qdf_spinlock_create(&adapter->vdev_lock); + qdf_atomic_init(&hdd_ctx->num_latency_critical_clients); hdd_init_completion(adapter); INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); @@ -8952,7 +8953,22 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, hdd_ctx->cur_vote_level = next_vote_level; vote_level_change = true; - pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level); + /* + * 11g/a clients are latency sensitive, and any delay in DDR + * access for fetching the packet can cause throughput drop. + * For 11g/a clients LOW voting level is not sufficient for + * peak throughput. Vote for higher DDR frequency if latency + * critical connections are present. + */ + if (hdd_ctx->config->enable_latency_crit_clients && + (next_vote_level == PLD_BUS_WIDTH_LOW || + next_vote_level == PLD_BUS_WIDTH_IDLE) && + qdf_atomic_read(&hdd_ctx->num_latency_critical_clients)) + pld_request_bus_bandwidth(hdd_ctx->parent_dev, + PLD_BUS_WIDTH_LOW_LATENCY); + else + pld_request_bus_bandwidth(hdd_ctx->parent_dev, + next_vote_level); if ((next_vote_level == PLD_BUS_WIDTH_LOW) || (next_vote_level == PLD_BUS_WIDTH_IDLE)) { @@ -14429,6 +14445,7 @@ exit: * connected */ if (!hdd_is_any_adapter_connected(hdd_ctx)) { + qdf_atomic_set(&hdd_ctx->num_latency_critical_clients, 0); hdd_ctx->cur_vote_level = PLD_BUS_WIDTH_NONE; pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_NONE); diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h index 26803cf1a19a..4028a922548d 100644 --- a/core/pld/inc/pld_common.h +++ b/core/pld/inc/pld_common.h @@ -76,6 +76,7 @@ enum pld_bus_type { * @PLD_BUS_WIDTH_MEDIUM: vote for medium bus bandwidth * @PLD_BUS_WIDTH_HIGH: vote for high bus bandwidth * @PLD_BUS_WIDTH_VERY_HIGH: vote for very high bus bandwidth + * @PLD_BUS_WIDTH_LOW_LATENCY: vote for low latency bus bandwidth */ enum pld_bus_width_type { PLD_BUS_WIDTH_NONE, @@ -84,6 +85,7 @@ enum pld_bus_width_type { PLD_BUS_WIDTH_MEDIUM, PLD_BUS_WIDTH_HIGH, PLD_BUS_WIDTH_VERY_HIGH, + PLD_BUS_WIDTH_LOW_LATENCY, }; #define PLD_MAX_FILE_NAME NAME_MAX