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 cdp_peer_stats *peer_stats;
|
||||||
struct stats_event *stats;
|
struct stats_event *stats;
|
||||||
QDF_STATUS status;
|
QDF_STATUS status;
|
||||||
bool found = false;
|
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
peer_stats = qdf_mem_malloc(sizeof(*peer_stats));
|
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_fw = stats->peer_stats_info_ext->tx_retries;
|
||||||
stainfo->tx_retry_exhaust_fw = stats->peer_stats_info_ext->tx_failed;
|
stainfo->tx_retry_exhaust_fw = stats->peer_stats_info_ext->tx_failed;
|
||||||
|
|
||||||
wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
|
/* Optional, just print logs here */
|
||||||
|
if (!stats->num_peer_adv_stats) {
|
||||||
stats = wlan_cfg80211_mc_cp_stats_get_station_stats(adapter->vdev,
|
hdd_debug("Failed to get peer adv stats info");
|
||||||
&ret);
|
stainfo->rx_fcs_count = 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < stats->num_peer_adv_stats; i++) {
|
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)) {
|
QDF_MAC_ADDR_SIZE)) {
|
||||||
stainfo->rx_fcs_count = stats->peer_adv_stats[i].
|
stainfo->rx_fcs_count = stats->peer_adv_stats[i].
|
||||||
fcs_count;
|
fcs_count;
|
||||||
found = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
hdd_err("Peer not found");
|
|
||||||
ret = -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
|
wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
|
||||||
|
|
||||||
return ret;
|
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_retry_exhaust)) +
|
||||||
nla_attr_size(sizeof(stainfo->tx_total_fw)) +
|
nla_attr_size(sizeof(stainfo->tx_total_fw)) +
|
||||||
nla_attr_size(sizeof(stainfo->tx_retry_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,
|
hdd_get_sta_info_by_mac(&adapter->sta_info_list,
|
||||||
mac_addr.bytes,
|
mac_addr.bytes,
|
||||||
STA_INFO_HDD_GET_STATION_REMOTE);
|
STA_INFO_HDD_GET_STATION_REMOTE);
|
||||||
|
int status;
|
||||||
|
|
||||||
/* For now, only connected STAs are supported */
|
/* For now, only connected STAs are supported */
|
||||||
if (!stainfo) {
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_associated = hdd_is_peer_associated(adapter, &mac_addr);
|
is_associated = hdd_is_peer_associated(adapter, &mac_addr);
|
||||||
if (!is_associated) {
|
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 -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,
|
qdf_mem_copy(priv->peer_stats_info_ext, ev->peer_stats_info_ext,
|
||||||
peer_stats_info_size);
|
peer_stats_info_size);
|
||||||
|
priv->num_peer_stats_info_ext = ev->num_peer_stats_info_ext;
|
||||||
|
|
||||||
peer_stats_cb_fail:
|
peer_stats_cb_fail:
|
||||||
osif_request_complete(request);
|
osif_request_complete(request);
|
||||||
osif_request_put(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 *
|
struct stats_event *
|
||||||
wlan_cfg80211_mc_cp_stats_get_peer_stats(struct wlan_objmgr_vdev *vdev,
|
wlan_cfg80211_mc_cp_stats_get_peer_stats(struct wlan_objmgr_vdev *vdev,
|
||||||
const uint8_t *mac_addr,
|
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;
|
priv->peer_stats_info_ext = NULL;
|
||||||
osif_request_put(request);
|
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");
|
osif_debug("Exit");
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
Reference in New Issue
Block a user