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:
Min Liu
2020-09-25 21:04:07 +08:00
committed by snandini
父節點 673bc215ed
當前提交 8f903508a1
共有 2 個文件被更改,包括 86 次插入19 次删除

查看文件

@@ -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(&params);
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;