From 36d19b09ca933be42064004c9f98e9484e11d0f0 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Thu, 22 Feb 2018 00:59:49 +0530 Subject: [PATCH] qcacld-3.0: Cache last connection info Prima to qcacld-3.0 Propagation Currently last connection info is not getting cached, so when GETBSSINFO command comes information is extracted from current conn_info which does not contain all the information required as this information is cleared after disconnection. To address this issue cache the connection info before clearing it. Change-Id: I3ec13264f97e7a4d0dc4699b463074062d087e82 CRs-Fixed: 2204530 --- core/hdd/inc/wlan_hdd_main.h | 1 + core/hdd/src/wlan_hdd_assoc.c | 3 + core/hdd/src/wlan_hdd_cfg80211.c | 97 +++++++++++++++++--------------- core/hdd/src/wlan_hdd_stats.c | 5 +- 4 files changed, 60 insertions(+), 46 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 8c4a19ab7e1e..331c1e127c40 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -644,6 +644,7 @@ struct hdd_station_ctx { enum nl80211_wpa_versions wpa_versions; struct qdf_mac_addr requested_bssid; struct hdd_connection_info conn_info; + struct hdd_connection_info cache_conn_info; struct hdd_roaming_info roam_info; int ft_carrier_on; int ibss_sta_generation; diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index faea1fac71cf..4d1f4b765328 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -866,6 +866,9 @@ static void hdd_save_bss_info(struct hdd_adapter *adapter, } else { hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false; } + /* Cache last connection info */ + qdf_mem_copy(&hdd_sta_ctx->cache_conn_info, &hdd_sta_ctx->conn_info, + sizeof(struct connection_info)); } /** diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index ead668ea1c8c..e187684809c7 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -4678,7 +4678,8 @@ static int32_t hdd_add_tx_bitrate(struct sk_buff *skb, if (!nla_attr) goto fail; /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ - bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate); + 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; @@ -4693,7 +4694,7 @@ static int32_t hdd_add_tx_bitrate(struct sk_buff *skb, goto fail; } if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS, - hdd_sta_ctx->conn_info.txrate.nss)) { + hdd_sta_ctx->cache_conn_info.txrate.nss)) { hdd_err("put fail"); goto fail; } @@ -4720,7 +4721,7 @@ static int32_t hdd_add_sta_info(struct sk_buff *skb, if (!nla_attr) goto fail; if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, - (hdd_sta_ctx->conn_info.signal + 100))) { + (hdd_sta_ctx->cache_conn_info.signal + 100))) { hdd_err("put fail"); goto fail; } @@ -4750,9 +4751,9 @@ static int32_t hdd_add_survey_info(struct sk_buff *skb, if (!nla_attr) goto fail; if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY, - hdd_sta_ctx->conn_info.freq) || + hdd_sta_ctx->cache_conn_info.freq) || nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE, - (hdd_sta_ctx->conn_info.noise + 100))) { + (hdd_sta_ctx->cache_conn_info.noise + 100))) { hdd_err("put fail"); goto fail; } @@ -4781,13 +4782,13 @@ hdd_add_link_standard_info(struct sk_buff *skb, goto fail; if (nla_put(skb, NL80211_ATTR_SSID, - hdd_sta_ctx->conn_info.last_ssid.SSID.length, - hdd_sta_ctx->conn_info.last_ssid.SSID.ssId)) { + hdd_sta_ctx->cache_conn_info.last_ssid.SSID.length, + hdd_sta_ctx->cache_conn_info.last_ssid.SSID.ssId)) { hdd_err("put fail"); goto fail; } if (nla_put(skb, NL80211_ATTR_MAC, QDF_MAC_ADDR_SIZE, - hdd_sta_ctx->conn_info.bssId.bytes)) { + hdd_sta_ctx->cache_conn_info.bssId.bytes)) { goto fail; } if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO)) @@ -4817,17 +4818,17 @@ hdd_add_ap_standard_info(struct sk_buff *skb, nla_attr = nla_nest_start(skb, idx); if (!nla_attr) goto fail; - if (hdd_sta_ctx->conn_info.conn_flag.vht_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present) if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY, - sizeof(hdd_sta_ctx->conn_info.vht_caps), - &hdd_sta_ctx->conn_info.vht_caps)) { + sizeof(hdd_sta_ctx->cache_conn_info.vht_caps), + &hdd_sta_ctx->cache_conn_info.vht_caps)) { hdd_err("put fail"); goto fail; } - if (hdd_sta_ctx->conn_info.conn_flag.ht_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present) if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY, - sizeof(hdd_sta_ctx->conn_info.ht_caps), - &hdd_sta_ctx->conn_info.ht_caps)) { + sizeof(hdd_sta_ctx->cache_conn_info.ht_caps), + &hdd_sta_ctx->cache_conn_info.ht_caps)) { hdd_err("put fail"); goto fail; } @@ -4855,29 +4856,33 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); nl_buf_len = NLMSG_HDRLEN; - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.last_ssid.SSID.length) + + nl_buf_len += sizeof(hdd_sta_ctx-> + cache_conn_info.last_ssid.SSID.length) + QDF_MAC_ADDR_SIZE + - sizeof(hdd_sta_ctx->conn_info.freq) + - sizeof(hdd_sta_ctx->conn_info.noise) + - sizeof(hdd_sta_ctx->conn_info.signal) + + sizeof(hdd_sta_ctx->cache_conn_info.freq) + + sizeof(hdd_sta_ctx->cache_conn_info.noise) + + sizeof(hdd_sta_ctx->cache_conn_info.signal) + (sizeof(uint32_t) * 2) + - sizeof(hdd_sta_ctx->conn_info.txrate.nss) + - sizeof(hdd_sta_ctx->conn_info.roam_count) + - sizeof(hdd_sta_ctx->conn_info.last_auth_type) + - sizeof(hdd_sta_ctx->conn_info.dot11Mode); - if (hdd_sta_ctx->conn_info.conn_flag.vht_present) - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps); - if (hdd_sta_ctx->conn_info.conn_flag.ht_present) - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps); - if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) { - tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie); - nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - - 1); + sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) + + sizeof(hdd_sta_ctx->cache_conn_info.roam_count) + + sizeof(hdd_sta_ctx->cache_conn_info.last_auth_type) + + sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode); + if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present) + nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps); + if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present) + nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps); + if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) { + tmp_hs20 = (uint8_t *)&(hdd_sta_ctx-> + cache_conn_info.hs20vendor_ie); + nl_buf_len += (sizeof(hdd_sta_ctx-> + cache_conn_info.hs20vendor_ie) - 1); } - if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present) - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation); - if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present) - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation); + if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present) + nl_buf_len += sizeof(hdd_sta_ctx-> + cache_conn_info.ht_operation); + if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present) + nl_buf_len += sizeof(hdd_sta_ctx-> + cache_conn_info.vht_operation); skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); @@ -4897,33 +4902,35 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx, goto fail; } if (nla_put_u32(skb, INFO_ROAM_COUNT, - hdd_sta_ctx->conn_info.roam_count) || + hdd_sta_ctx->cache_conn_info.roam_count) || nla_put_u32(skb, INFO_AKM, hdd_convert_auth_type( - hdd_sta_ctx->conn_info.last_auth_type)) || + hdd_sta_ctx->cache_conn_info.last_auth_type)) || nla_put_u32(skb, WLAN802_11_MODE, hdd_convert_dot11mode( - hdd_sta_ctx->conn_info.dot11Mode))) { + hdd_sta_ctx->cache_conn_info.dot11Mode))) { hdd_err("put fail"); goto fail; } - if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present) if (nla_put(skb, HT_OPERATION, - (sizeof(hdd_sta_ctx->conn_info.ht_operation)), - &hdd_sta_ctx->conn_info.ht_operation)) { + (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)), + &hdd_sta_ctx->cache_conn_info.ht_operation)) { hdd_err("put fail"); goto fail; } - if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present) if (nla_put(skb, VHT_OPERATION, - (sizeof(hdd_sta_ctx->conn_info.vht_operation)), - &hdd_sta_ctx->conn_info.vht_operation)) { + (sizeof(hdd_sta_ctx-> + cache_conn_info.vht_operation)), + &hdd_sta_ctx->cache_conn_info.vht_operation)) { hdd_err("put fail"); goto fail; } - if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) if (nla_put(skb, AP_INFO_HS20_INDICATION, - (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1), + (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) + - 1), tmp_hs20 + 1)) { 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 4267ed904f4a..959c362f1573 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -3988,7 +3988,8 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, sta_ctx->conn_info.signal = sinfo->signal; sta_ctx->conn_info.noise = sta_ctx->conn_info.signal - snr; - + sta_ctx->cache_conn_info.signal = sinfo->signal; + sta_ctx->cache_conn_info.noise = sta_ctx->conn_info.noise; wlan_hdd_fill_station_info_signal(sinfo); /* @@ -4348,6 +4349,8 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, qdf_mem_copy(&sta_ctx->conn_info.txrate, &sinfo->txrate, sizeof(sinfo->txrate)); + qdf_mem_copy(&sta_ctx->cache_conn_info.txrate, + &sinfo->txrate, sizeof(sinfo->txrate)); #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS) sinfo->filled |= STATION_INFO_TX_BITRATE |