diff --git a/os_if/linux/cp_stats/inc/wlan_cfg80211_mc_cp_stats.h b/os_if/linux/cp_stats/inc/wlan_cfg80211_mc_cp_stats.h index 3a1bab06c862..4450e7fe46cd 100644 --- a/os_if/linux/cp_stats/inc/wlan_cfg80211_mc_cp_stats.h +++ b/os_if/linux/cp_stats/inc/wlan_cfg80211_mc_cp_stats.h @@ -62,6 +62,17 @@ int wlan_cfg80211_mc_cp_stats_get_wakelock_stats(struct wlan_objmgr_psoc *psoc, int wlan_cfg80211_mc_cp_stats_get_tx_power(struct wlan_objmgr_vdev *vdev, int *dbm); +/** + * wlan_cfg80211_mc_cp_stats_get_peer_rssi() - API to fetch peer rssi + * @vdev: Pointer to vdev + * @macaddress: mac address + * @rssi_info: stats structure within which rssi info will be populated + * + * Return: 0 on success, negative value on failure + */ +int wlan_cfg80211_mc_cp_stats_get_peer_rssi(struct wlan_objmgr_vdev *vdev, + uint8_t *macaddress, + struct stats_event *rssi_info); #endif /* QCA_SUPPORT_CP_STATS */ #endif /* __WLAN_CFG80211_MC_CP_STATS_H__ */ diff --git a/os_if/linux/cp_stats/src/wlan_cfg80211_mc_cp_stats.c b/os_if/linux/cp_stats/src/wlan_cfg80211_mc_cp_stats.c index c2b420057f78..7873958670f6 100644 --- a/os_if/linux/cp_stats/src/wlan_cfg80211_mc_cp_stats.c +++ b/os_if/linux/cp_stats/src/wlan_cfg80211_mc_cp_stats.c @@ -279,3 +279,80 @@ fetch_tx_power: return ret; } +/** + * get_peer_rssi_cb() - get_peer_rssi_cb callback function + * @mac_addr: mac address + * @cookie: a cookie for the request context + * + * Return: None + */ +static void get_peer_rssi_cb(struct stats_event *ev, void *cookie) +{ + struct stats_event *priv; + struct osif_request *request; + + request = osif_request_get(cookie); + if (!request) { + cfg80211_err("Obsolete request"); + return; + } + + priv = osif_request_priv(request); + *priv = *ev; + osif_request_complete(request); + osif_request_put(request); +} + +int wlan_cfg80211_mc_cp_stats_get_peer_rssi(struct wlan_objmgr_vdev *vdev, + uint8_t *mac_addr, + struct stats_event *rssi_info) +{ + int ret = 0; + void *cookie; + QDF_STATUS status; + struct stats_event *priv; + struct request_info info = {0}; + struct osif_request *request = NULL; + static const struct osif_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = CP_STATS_WAIT_TIME_STAT, + }; + + qdf_mem_zero(rssi_info, sizeof(*rssi_info)); + request = osif_request_alloc(¶ms); + if (!request) { + cfg80211_err("Request allocation failure, return cached value"); + return -EINVAL; + } + + cookie = osif_request_cookie(request); + priv = osif_request_priv(request); + info.cookie = cookie; + info.u.get_peer_rssi_cb = get_peer_rssi_cb; + info.vdev_id = wlan_vdev_get_id(vdev); + info.pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev)); + qdf_mem_copy(info.peer_mac_addr, mac_addr, WLAN_MACADDR_LEN); + status = ucfg_mc_cp_stats_send_stats_request(vdev, TYPE_PEER_STATS, + &info); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("stats req failed: %d", status); + ret = qdf_status_to_os_return(status); + } else { + ret = osif_request_wait_for_response(request); + if (ret) { + cfg80211_err("wait failed or timed out ret: %d", ret); + } else { + *rssi_info = *priv; + } + } + + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. + */ + if (request) + osif_request_put(request); + + return ret; +}