From 4c6f6b643de55c27f978346e0be0cb6babcba267 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Tue, 16 Apr 2019 12:59:57 +0530 Subject: [PATCH] qcacld-3.0: Report max tx_bitrate in case of connected sta Currently as response of GETBSSINFO command driver is sending actual bitrate information in connected and disconnected case. According to new requirement send max supported bitrate of AP as response of GETBSSINFO command in case of connected station. Change-Id: I15624bf0c50af37847b8e1c0fe8bc9a880d3d021 CRs-fixed: 2434270 --- core/hdd/inc/wlan_hdd_assoc.h | 3 + core/hdd/src/wlan_hdd_station_info.c | 83 +++++++++++++++++++++++++--- core/hdd/src/wlan_hdd_stats.c | 23 ++------ core/hdd/src/wlan_hdd_stats.h | 20 +++++++ 4 files changed, 104 insertions(+), 25 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h index af178d612dad..dd80ca27750a 100644 --- a/core/hdd/inc/wlan_hdd_assoc.h +++ b/core/hdd/inc/wlan_hdd_assoc.h @@ -170,6 +170,8 @@ struct hdd_conn_flag { * @auth_time: last authentication established time * @connect_time: last association established time * @ch_width: channel width of operating channel + * @max_tx_bitrate: Max tx bitrate supported by the AP + * to which currently sta is connected. */ struct hdd_connection_info { eConnectionState conn_state; @@ -206,6 +208,7 @@ struct hdd_connection_info { char auth_time[HDD_TIME_STRING_LEN]; char connect_time[HDD_TIME_STRING_LEN]; enum phy_ch_width ch_width; + struct rate_info max_tx_bitrate; }; /* Forward declarations */ diff --git a/core/hdd/src/wlan_hdd_station_info.c b/core/hdd/src/wlan_hdd_station_info.c index 9876b5cf78f3..b559de0f7121 100644 --- a/core/hdd/src/wlan_hdd_station_info.c +++ b/core/hdd/src/wlan_hdd_station_info.c @@ -320,9 +320,12 @@ static int32_t hdd_add_tx_bitrate(struct sk_buff *skb, } /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ - bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx-> - cache_conn_info.txrate); - + if (hdd_conn_is_connected(hdd_sta_ctx)) + bitrate = cfg80211_calculate_bitrate( + &hdd_sta_ctx->cache_conn_info.max_tx_bitrate); + else + bitrate = cfg80211_calculate_bitrate( + &hdd_sta_ctx->cache_conn_info.txrate); /* report 16-bit bitrate only if we can */ bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0; @@ -356,6 +359,53 @@ fail: return -EINVAL; } +/** + * hdd_get_max_tx_bitrate() - Get the max tx bitrate of the AP + * @hdd_ctx: hdd context + * @adapter: hostapd interface + * + * THis function gets the MAX supported rate by AP and cache + * it into connection info structure + * + * Return: None + */ +static void hdd_get_max_tx_bitrate(struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter) +{ + struct station_info sinfo; + uint8_t tx_rate_flags, tx_mcs_index, tx_nss = 1; + uint16_t my_tx_rate; + struct hdd_station_ctx *hdd_sta_ctx; + + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + qdf_mem_zero(&sinfo, sizeof(struct station_info)); + + sinfo.signal = adapter->rssi; + tx_rate_flags = adapter->hdd_stats.class_a_stat.tx_rx_rate_flags; + tx_mcs_index = adapter->hdd_stats.class_a_stat.tx_mcs_index; + my_tx_rate = adapter->hdd_stats.class_a_stat.tx_rate; + + if (!(tx_rate_flags & TX_RATE_LEGACY)) { + tx_nss = adapter->hdd_stats.class_a_stat.tx_nss; + if (tx_nss > 1 && + policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc) && + !policy_mgr_is_hw_dbs_2x2_capable(hdd_ctx->psoc)) { + hdd_debug("Hw mode is DBS, Reduce nss(%d) to 1", + tx_nss); + tx_nss--; + } + } + if (hdd_report_max_rate(hdd_ctx->mac_handle, &sinfo, + tx_rate_flags, tx_mcs_index, + my_tx_rate, tx_nss)) { + hdd_sta_ctx->cache_conn_info.max_tx_bitrate = sinfo.txrate; + hdd_debug("Reporting max tx rate flags %d mcs %d nss %d bw %d", + sinfo.txrate.flags, sinfo.txrate.mcs, + sinfo.txrate.nss, sinfo.txrate.bw); + } +} + /** * hdd_add_sta_info() - add station info attribute * @skb: pointer to sk buff @@ -365,10 +415,18 @@ fail: * Return: Success(0) or reason code for failure */ static int32_t hdd_add_sta_info(struct sk_buff *skb, - struct hdd_station_ctx *hdd_sta_ctx, + struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter, int idx) { struct nlattr *nla_attr; + struct hdd_station_ctx *hdd_sta_ctx; + + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (!hdd_sta_ctx) { + hdd_err("Invalid sta ctx"); + goto fail; + } nla_attr = nla_nest_start(skb, idx); if (!nla_attr) { @@ -381,6 +439,9 @@ static int32_t hdd_add_sta_info(struct sk_buff *skb, hdd_err("put fail"); goto fail; } + if (hdd_conn_is_connected(hdd_sta_ctx)) + hdd_get_max_tx_bitrate(hdd_ctx, adapter); + if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE)) { hdd_err("hdd_add_tx_bitrate failed"); goto fail; @@ -432,9 +493,17 @@ fail: */ static int32_t hdd_add_link_standard_info(struct sk_buff *skb, - struct hdd_station_ctx *hdd_sta_ctx, int idx) + struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter, int idx) { struct nlattr *nla_attr; + struct hdd_station_ctx *hdd_sta_ctx; + + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (!hdd_sta_ctx) { + hdd_err("Invalid sta ctx"); + goto fail; + } nla_attr = nla_nest_start(skb, idx); if (!nla_attr) { @@ -459,7 +528,7 @@ hdd_add_link_standard_info(struct sk_buff *skb, goto fail; } - if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO)) { + if (hdd_add_sta_info(skb, hdd_ctx, adapter, NL80211_ATTR_STA_INFO)) { hdd_err("hdd_add_sta_info failed"); goto fail; } @@ -558,7 +627,7 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, return -ENOMEM; } - if (hdd_add_link_standard_info(skb, hdd_sta_ctx, + if (hdd_add_link_standard_info(skb, hdd_ctx, adapter, LINK_INFO_STANDARD_NL80211_ATTR)) { hdd_err("put fail"); goto fail; diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index 3472db354433..37f7df3d6840 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -3935,24 +3935,11 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy, return status; } -/** - * hdd_report_max_rate() - Fill the max rate stats in the station info structure - * to be sent to the userspace. - * - * @mac_handle: The mac handle - * @sinfo: The station_info struct to be filled - * @tx_rate_flags: The TX rate flags computed from tx rate - * @tx_mcs_index; The TX mcs index computed from tx rate - * @my_tx_rate: The tx_rate from fw stats - * @tx_nss: The TX NSS from fw stats - * - * Return: 0 for success - */ -static int hdd_report_max_rate(mac_handle_t mac_handle, - struct station_info *sinfo, - uint8_t tx_rate_flags, - uint8_t tx_mcs_index, - uint16_t my_tx_rate, uint8_t tx_nss) +int hdd_report_max_rate(mac_handle_t mac_handle, + struct station_info *sinfo, + uint8_t tx_rate_flags, + uint8_t tx_mcs_index, + uint16_t my_tx_rate, uint8_t tx_nss) { uint8_t i, j, rssidx; uint16_t max_rate = 0; diff --git a/core/hdd/src/wlan_hdd_stats.h b/core/hdd/src/wlan_hdd_stats.h index bf5d8fc83d8b..6d38d5711dea 100644 --- a/core/hdd/src/wlan_hdd_stats.h +++ b/core/hdd/src/wlan_hdd_stats.h @@ -464,4 +464,24 @@ int wlan_hdd_get_temperature(struct hdd_adapter *adapter, int *temperature); * Return: none */ void wlan_hdd_display_txrx_stats(struct hdd_context *hdd_ctx); + +/** + * hdd_report_max_rate() - Fill the max rate stats in the station info structure + * to be sent to the userspace. + * + * @mac_handle: The mac handle + * @sinfo: The station_info struct to be filled + * @tx_rate_flags: The TX rate flags computed from tx rate + * @tx_mcs_index; The TX mcs index computed from tx rate + * @my_tx_rate: The tx_rate from fw stats + * @tx_nss: The TX NSS from fw stats + * + * Return: 0 for success + */ +int hdd_report_max_rate(mac_handle_t mac_handle, + struct station_info *sinfo, + uint8_t tx_rate_flags, + uint8_t tx_mcs_index, + uint16_t my_tx_rate, uint8_t tx_nss); + #endif /* end #if !defined(WLAN_HDD_STATS_H) */