diff --git a/core/hdd/src/wlan_hdd_station_info.c b/core/hdd/src/wlan_hdd_station_info.c index 426669c63ea0..7c6a7c9bac55 100644 --- a/core/hdd/src/wlan_hdd_station_info.c +++ b/core/hdd/src/wlan_hdd_station_info.c @@ -1512,7 +1512,6 @@ static int hdd_get_peer_stats(struct hdd_adapter *adapter, struct cdp_peer_stats *peer_stats; struct stats_event *stats; QDF_STATUS status; - bool found = false; int i, ret = 0; peer_stats = qdf_mem_malloc(sizeof(*peer_stats)); @@ -1552,14 +1551,10 @@ static int hdd_get_peer_stats(struct hdd_adapter *adapter, stainfo->tx_retry_fw = stats->peer_stats_info_ext->tx_retries; stainfo->tx_retry_exhaust_fw = stats->peer_stats_info_ext->tx_failed; - wlan_cfg80211_mc_cp_stats_free_stats_event(stats); - - stats = wlan_cfg80211_mc_cp_stats_get_station_stats(adapter->vdev, - &ret); - if (ret || !stats || !stats->num_peer_adv_stats) { - wlan_cfg80211_mc_cp_stats_free_stats_event(stats); - hdd_err("Failed to get peer stats info"); - return -EINVAL; + /* Optional, just print logs here */ + if (!stats->num_peer_adv_stats) { + hdd_debug("Failed to get peer adv stats info"); + stainfo->rx_fcs_count = 0; } for (i = 0; i < stats->num_peer_adv_stats; i++) { @@ -1568,16 +1563,10 @@ static int hdd_get_peer_stats(struct hdd_adapter *adapter, QDF_MAC_ADDR_SIZE)) { stainfo->rx_fcs_count = stats->peer_adv_stats[i]. fcs_count; - found = true; break; } } - if (!found) { - hdd_err("Peer not found"); - ret = -EINVAL; - } - wlan_cfg80211_mc_cp_stats_free_stats_event(stats); return ret; @@ -1602,7 +1591,8 @@ hdd_add_peer_stats_get_len(struct hdd_station_info *stainfo) nla_attr_size(sizeof(stainfo->tx_retry_exhaust)) + nla_attr_size(sizeof(stainfo->tx_total_fw)) + nla_attr_size(sizeof(stainfo->tx_retry_fw)) + - nla_attr_size(sizeof(stainfo->tx_retry_exhaust_fw))); + nla_attr_size(sizeof(stainfo->tx_retry_exhaust_fw)) + + nla_attr_size(sizeof(stainfo->rx_fcs_count))); } /** @@ -1852,20 +1842,29 @@ static int hdd_get_station_remote_ex(struct hdd_context *hdd_ctx, hdd_get_sta_info_by_mac(&adapter->sta_info_list, mac_addr.bytes, STA_INFO_HDD_GET_STATION_REMOTE); + int status; /* For now, only connected STAs are supported */ if (!stainfo) { - hdd_err_rl("Failed to get peer STA"); + hdd_err_rl("Failed to get peer STA " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr.bytes)); return -EINVAL; } is_associated = hdd_is_peer_associated(adapter, &mac_addr); if (!is_associated) { - hdd_err_rl("Peer STA is not associated"); + hdd_err_rl("Peer STA is not associated " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(mac_addr.bytes)); + hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true, + STA_INFO_HDD_GET_STATION_REMOTE); return -EINVAL; } - return hdd_get_connected_station_info_ex(hdd_ctx, adapter, stainfo); + status = hdd_get_connected_station_info_ex(hdd_ctx, adapter, stainfo); + hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true, + STA_INFO_HDD_GET_STATION_REMOTE); + + return status; } /** diff --git a/os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c b/os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c index 01d02e0127cc..a930f908056a 100644 --- a/os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c +++ b/os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c @@ -756,12 +756,50 @@ static void get_peer_stats_cb(struct stats_event *ev, void *cookie) qdf_mem_copy(priv->peer_stats_info_ext, ev->peer_stats_info_ext, peer_stats_info_size); + priv->num_peer_stats_info_ext = ev->num_peer_stats_info_ext; peer_stats_cb_fail: osif_request_complete(request); osif_request_put(request); } +/** + * get_station_adv_stats_cb() - get_station_adv_stats_cb callback function + * @ev: station stats buffer + * @cookie: a cookie for the request context + * + * Return: None + */ +static void get_station_adv_stats_cb(struct stats_event *ev, void *cookie) +{ + struct stats_event *priv; + struct osif_request *request; + uint32_t peer_adv_size; + + request = osif_request_get(cookie); + if (!request) { + osif_err("Obsolete request"); + return; + } + + priv = osif_request_priv(request); + peer_adv_size = sizeof(*ev->peer_adv_stats) * ev->num_peer_adv_stats; + + if (peer_adv_size) { + priv->peer_adv_stats = qdf_mem_malloc(peer_adv_size); + if (!priv->peer_adv_stats) + goto station_adv_stats_cb_fail; + + qdf_mem_copy(priv->peer_adv_stats, ev->peer_adv_stats, + peer_adv_size); + } + priv->num_peer_adv_stats = ev->num_peer_adv_stats; + +station_adv_stats_cb_fail: + osif_request_complete(request); + osif_request_put(request); +} + struct stats_event * wlan_cfg80211_mc_cp_stats_get_peer_stats(struct wlan_objmgr_vdev *vdev, const uint8_t *mac_addr, @@ -829,6 +867,36 @@ wlan_cfg80211_mc_cp_stats_get_peer_stats(struct wlan_objmgr_vdev *vdev, priv->peer_stats_info_ext = NULL; osif_request_put(request); + request = osif_request_alloc(¶ms); + if (!request) { + wlan_cfg80211_mc_cp_stats_free_stats_event(out); + *errno = -ENOMEM; + return NULL; + } + + cookie = osif_request_cookie(request); + priv = osif_request_priv(request); + info.cookie = cookie; + info.u.get_peer_stats_cb = get_station_adv_stats_cb; + status = ucfg_mc_cp_stats_send_stats_request(vdev, TYPE_STATION_STATS, + &info); + if (QDF_IS_STATUS_ERROR(status)) { + osif_err("Failed to send stats request status: %d", status); + *errno = qdf_status_to_os_return(status); + goto get_peer_stats_fail; + } + + *errno = osif_request_wait_for_response(request); + if (*errno) { + osif_err("wait failed or timed out ret: %d", *errno); + goto get_peer_stats_fail; + } + + out->num_peer_adv_stats = priv->num_peer_adv_stats; + out->peer_adv_stats = priv->peer_adv_stats; + priv->peer_adv_stats = NULL; + osif_request_put(request); + osif_debug("Exit"); return out;