qcacld-3.0: Add support for TWT clear statistics

Add support to send TWT clear statistics request
to firmware.

Change-Id: I435b743955d44a02235b92f98beb302a6a21f036
CRs-Fixed: 2855624
This commit is contained in:
Rajasekaran Kalidoss 2021-01-15 12:21:05 +05:30 • committed by snandini
commit 1f52db8f0a
3 changed files with 188 additions and 0 deletions

View file

@ -153,6 +153,21 @@ QDF_STATUS ucfg_mc_cp_stats_send_stats_request(struct wlan_objmgr_vdev *vdev,
enum stats_req_type type,
struct request_info *info);
/**
* wlan_cfg80211_mc_twt_clear_infra_cp_stats() - send request to reset
* control path statistics
* @vdev: pointer to vdev object
* @dialog_id: dialod id of the twt session
* @twt_peer_mac: mac address of the peer
*
* Return: 0 for success or error code for failure
*/
int
wlan_cfg80211_mc_twt_clear_infra_cp_stats(
struct wlan_objmgr_vdev *vdev,
uint32_t dialog_id,
uint8_t twt_peer_mac[QDF_MAC_ADDR_SIZE]);
/**
* wlan_cfg80211_mc_twt_get_infra_cp_stats() - send twt get statistic request
* @vdev: pointer to vdev object

View file

@ -2558,6 +2558,52 @@ hdd_twt_pack_get_stats_resp_nlmsg(struct sk_buff *reply_skb,
return QDF_STATUS_SUCCESS;
}
/**
* hdd_twt_clear_session_traffic_stats() - Parses twt nl attrributes and
* sends clear twt stats request for a single or all sessions
* @adapter: hdd_adapter
* @twt_param_attr: twt nl attributes
*
* Return: 0 on success, negative value on failure
*/
static int hdd_twt_clear_session_traffic_stats(struct hdd_adapter *adapter,
struct nlattr *twt_param_attr)
{
struct hdd_station_ctx *hdd_sta_ctx =
WLAN_HDD_GET_STATION_CTX_PTR(adapter);
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX + 1];
int ret, id;
uint32_t dialog_id;
uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
ret = wlan_cfg80211_nla_parse_nested(
tb,
QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX,
twt_param_attr,
qca_wlan_vendor_twt_stats_dialog_policy);
if (ret)
return ret;
id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID;
if (!tb[id]) {
hdd_err_rl("TWT Clear stats - dialog id param is must");
return -EINVAL;
}
dialog_id = (uint32_t)nla_get_u8(tb[id]);
qdf_mem_copy(peer_mac,
hdd_sta_ctx->conn_info.bssid.bytes,
QDF_MAC_ADDR_SIZE);
hdd_debug("dialog_id %d peer mac_addr " QDF_MAC_ADDR_FMT,
dialog_id, QDF_MAC_ADDR_REF(peer_mac));
ret = wlan_cfg80211_mc_twt_clear_infra_cp_stats(adapter->vdev,
dialog_id, peer_mac);
return ret;
}
/**
* hdd_twt_get_session_traffic_stats() - Obtains twt session traffic statistics
* and sends response to the user space
@ -2794,6 +2840,10 @@ static int hdd_twt_configure(struct hdd_adapter *adapter,
ret = hdd_twt_get_session_traffic_stats(adapter,
twt_param_attr);
break;
case QCA_WLAN_TWT_CLEAR_STATS:
ret = hdd_twt_clear_session_traffic_stats(adapter,
twt_param_attr);
break;
default:
hdd_err("Invalid TWT Operation");
ret = -EINVAL;

View file

@ -769,6 +769,129 @@ get_twt_stats_fail:
return NULL;
}
/**
* infra_cp_stats_reset_cb() - callback function to handle stats event
* due to reset action
* @ev: stats event buffer
* @cookie: a cookie for the request context
*
* Return: None
*/
static void infra_cp_stats_reset_cb(struct infra_cp_stats_event *ev,
void *cookie)
{
struct infra_cp_stats_event *priv;
struct osif_request *request;
request = osif_request_get(cookie);
if (!request) {
osif_err("Obsolete request");
return;
}
priv = osif_request_priv(request);
osif_debug("clear stats action %d req_id %d, status %d num_cp_stats %d",
ev->action, ev->request_id, ev->status,
ev->num_twt_infra_cp_stats);
osif_request_complete(request);
osif_request_put(request);
}
/**
* @wlan_cfg80211_mc_twt_clear_infra_cp_stats() - send clear twt statistics
* request to firmware
* @vdev: vdev id
* @dialog_id: dialog id of the twt session.
* @twt_peer_mac: peer mac address
*
* Return: 0 for success or error code for failure
*/
int
wlan_cfg80211_mc_twt_clear_infra_cp_stats(
struct wlan_objmgr_vdev *vdev,
uint32_t dialog_id,
uint8_t twt_peer_mac[QDF_MAC_ADDR_SIZE])
{
int ret;
void *cookie;
QDF_STATUS status;
struct infra_cp_stats_event *priv;
struct wlan_objmgr_peer *peer;
struct osif_request *request;
struct infra_cp_stats_cmd_info info = {0};
static const struct osif_request_params params = {
.priv_size = sizeof(*priv),
.timeout_ms = 2 * CP_STATS_WAIT_TIME_STAT,
.dealloc = wlan_cfg80211_mc_infra_cp_stats_dealloc,
};
osif_debug("Enter");
request = osif_request_alloc(&params);
if (!request)
return -ENOMEM;
cookie = osif_request_cookie(request);
priv = osif_request_priv(request);
priv->twt_infra_cp_stats =
qdf_mem_malloc(sizeof(*priv->twt_infra_cp_stats));
if (!priv->twt_infra_cp_stats) {
ret = -ENOMEM;
goto clear_twt_stats_fail;
}
info.request_cookie = cookie;
info.stats_id = TYPE_REQ_CTRL_PATH_TWT_STAT;
info.action = ACTION_REQ_CTRL_PATH_STAT_RESET;
info.infra_cp_stats_resp_cb = infra_cp_stats_reset_cb;
info.num_pdev_ids = 0;
info.num_vdev_ids = MAX_TWT_STAT_VDEV_ENTRIES;
info.vdev_id[0] = wlan_vdev_get_id(vdev);
info.num_mac_addr_list = MAX_TWT_STAT_MAC_ADDR_ENTRIES;
qdf_mem_copy(&info.peer_mac_addr[0], twt_peer_mac, QDF_MAC_ADDR_SIZE);
info.dialog_id = dialog_id;
info.num_pdev_ids = 0;
peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_CP_STATS_ID);
if (!peer) {
osif_err("peer is null");
ret = -EINVAL;
goto clear_twt_stats_fail;
}
wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
status = ucfg_infra_cp_stats_register_resp_cb(wlan_vdev_get_psoc(vdev),
&info);
if (QDF_IS_STATUS_ERROR(status)) {
osif_err("Failed to register resp callback: %d", status);
ret = qdf_status_to_os_return(status);
goto clear_twt_stats_fail;
}
status = ucfg_send_infra_cp_stats_request(vdev, &info);
if (QDF_IS_STATUS_ERROR(status)) {
osif_err("Failed to send twt stats request status: %d",
status);
ret = qdf_status_to_os_return(status);
goto clear_twt_stats_fail;
}
ret = osif_request_wait_for_response(request);
if (ret)
osif_err("wait failed or timed out ret: %d", ret);
clear_twt_stats_fail:
osif_request_put(request);
osif_debug("Exit");
return ret;
}
#endif
#endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */