qcacld-3.0: Fix get peer statistics failure
Fix the following regression issues which will cause get peer statistics failure: - Number of peer statistics is not updated in the callback - Sta info reference count is not released - Incorrect nla len Change-Id: Ia7cdf28324402fd647a6d4e80b27612ccabb32f2 CRs-Fixed: 2785764
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user