qcacmn: Add target_if/wmi implementation of get_tx_power

Add changes to support get tx power from within cp_stats component.

Change-Id: I89ac372bd31a8aa5a76938dc4ea4cfe05d6c7cf1
CRs-Fixed: 2210311
This commit is contained in:
Naveen Rawat
2018-04-06 10:57:20 -07:00
committed by nshrivas
parent a2a1eb1619
commit 299269828a
5 changed files with 214 additions and 7 deletions

View File

@@ -72,7 +72,7 @@ target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/ */
QDF_STATUS QDF_STATUS
target_if_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *tx_ops); target_if_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops);
#else #else
static inline QDF_STATUS static inline QDF_STATUS
target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)

View File

@@ -78,3 +78,9 @@ target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
QDF_STATUS
target_if_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
{
return QDF_STATUS_SUCCESS;
}

View File

@@ -40,7 +40,129 @@
#include <wlan_tgt_def_config.h> #include <wlan_tgt_def_config.h>
#include <wmi_unified_api.h> #include <wmi_unified_api.h>
#include <wlan_osif_priv.h> #include <wlan_osif_priv.h>
#include "wlan_cp_stats_utils_api.h" #include <wlan_cp_stats_utils_api.h>
#include <wlan_cp_stats_mc_tgt_api.h>
#define TGT_INVALID_SNR (0)
#define TGT_NOISE_FLOOR_DBM (-96)
#define TGT_MAX_SNR (TGT_NOISE_FLOOR_DBM * (-1))
#define TGT_IS_VALID_SNR(x) ((x) >= 0 && (x) < TGT_MAX_SNR)
static void target_if_cp_stats_free_stats_event(struct stats_event *ev)
{
qdf_mem_free(ev->pdev_stats);
ev->pdev_stats = NULL;
}
static QDF_STATUS target_if_cp_stats_extract_pdev_stats(
struct wmi_unified *wmi_hdl,
wmi_host_stats_event *stats_param,
struct stats_event *ev,
uint8_t *data)
{
uint32_t i;
QDF_STATUS status;
wmi_host_pdev_stats pdev_stats;
ev->num_pdev_stats = stats_param->num_pdev_stats;
if (!ev->num_pdev_stats)
return QDF_STATUS_SUCCESS;
/*
* num_pdev_stats is validated within function wmi_extract_stats_param
* which is called to populated wmi_host_stats_event stats_param
*/
ev->pdev_stats = qdf_mem_malloc(sizeof(*ev->pdev_stats) *
ev->num_pdev_stats);
if (!ev->pdev_stats) {
cp_stats_err("malloc failed");
return QDF_STATUS_E_NOMEM;
}
for (i = 0; i < ev->num_pdev_stats; i++) {
status = wmi_extract_pdev_stats(wmi_hdl, data, i, &pdev_stats);
if (QDF_IS_STATUS_ERROR(status)) {
cp_stats_err("wmi_extract_pdev_stats failed");
return status;
}
ev->pdev_stats[i].max_pwr = pdev_stats.chan_tx_pwr;
}
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl,
struct stats_event *ev,
uint8_t *data)
{
QDF_STATUS status;
wmi_host_stats_event stats_param = {0};
status = wmi_extract_stats_param(wmi_hdl, data, &stats_param);
if (QDF_IS_STATUS_ERROR(status)) {
cp_stats_debug("stats param extract failed: %d", status);
return status;
}
cp_stats_debug("num: pdev: %d, vdev: %d, peer: %d, rssi: %d",
stats_param.num_pdev_stats, stats_param.num_vdev_stats,
stats_param.num_peer_stats, stats_param.num_rssi_stats);
status = target_if_cp_stats_extract_pdev_stats(wmi_hdl, &stats_param,
ev, data);
if (QDF_IS_STATUS_ERROR(status))
return status;
return QDF_STATUS_SUCCESS;
}
/**
* target_if_mc_cp_stats_stats_event_handler() - function to handle stats event
* from firmware.
* @scn: scn handle
* @data: data buffer for event
* @datalen: data length
*
* Return: status of operation.
*/
static int target_if_mc_cp_stats_stats_event_handler(ol_scn_t scn,
uint8_t *data,
uint32_t datalen)
{
QDF_STATUS status;
struct stats_event ev = {0};
struct wlan_objmgr_psoc *psoc;
struct wmi_unified *wmi_handle;
struct wlan_lmac_if_cp_stats_rx_ops *rx_ops;
if (!scn || !data) {
cp_stats_err("scn: 0x%pK, data: 0x%pK", scn, data);
return -EINVAL;
}
psoc = target_if_get_psoc_from_scn_hdl(scn);
if (!psoc) {
cp_stats_err("null psoc");
return -EINVAL;
}
wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
rx_ops = target_if_cp_stats_get_rx_ops(psoc);
if (!rx_ops || !rx_ops->process_stats_event) {
cp_stats_err("callback not registered");
return -EINVAL;
}
status = target_if_cp_stats_extract_event(wmi_handle, &ev, data);
if (QDF_IS_STATUS_ERROR(status)) {
cp_stats_err("extract event failed");
goto end;
}
status = rx_ops->process_stats_event(psoc, &ev);
end:
target_if_cp_stats_free_stats_event(&ev);
return qdf_status_to_os_return(status);
}
static void target_if_cp_stats_inc_wake_lock_stats(uint32_t reason, static void target_if_cp_stats_inc_wake_lock_stats(uint32_t reason,
struct wake_lock_stats *stats, struct wake_lock_stats *stats,
@@ -86,9 +208,20 @@ static void target_if_cp_stats_inc_wake_lock_stats(uint32_t reason,
static QDF_STATUS static QDF_STATUS
target_if_cp_stats_register_event_handler(struct wlan_objmgr_psoc *psoc) target_if_cp_stats_register_event_handler(struct wlan_objmgr_psoc *psoc)
{ {
QDF_STATUS status;
if (!psoc) { if (!psoc) {
cp_stats_err("PSOC is NULL!"); cp_stats_err("PSOC is NULL!");
return QDF_STATUS_E_INVAL; return QDF_STATUS_E_NULL_VALUE;
}
status = wmi_unified_register_event_handler(GET_WMI_HDL_FROM_PSOC(psoc),
wmi_update_stats_event_id,
target_if_mc_cp_stats_stats_event_handler,
WMI_RX_WORK_CTX);
if (status) {
cp_stats_err("Failed to register stats event cb");
return status;
} }
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
@@ -102,9 +235,52 @@ target_if_cp_stats_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
return QDF_STATUS_E_INVAL; return QDF_STATUS_E_INVAL;
} }
wmi_unified_unregister_event_handler(GET_WMI_HDL_FROM_PSOC(psoc),
wmi_update_stats_event_id);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
static uint32_t get_stats_id(enum stats_req_type type)
{
switch (type) {
default:
break;
case TYPE_CONNECTION_TX_POWER:
return WMI_REQUEST_PDEV_STAT;
}
return 0;
}
/**
* target_if_cp_stats_send_stats_req() - API to send stats request to wmi
* @psoc: pointer to psoc object
* @req: pointer to object containing stats request parameters
*
* Return: status of operation.
*/
static QDF_STATUS target_if_cp_stats_send_stats_req(
struct wlan_objmgr_psoc *psoc,
enum stats_req_type type,
struct request_info *req)
{
struct wmi_unified *wmi_handle;
struct stats_request_params param = {0};
wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
if (!wmi_handle) {
cp_stats_err("wmi_handle is null.");
return QDF_STATUS_E_NULL_VALUE;
}
/* refer (WMI_REQUEST_STATS_CMDID) */
param.stats_id = get_stats_id(type);
param.vdev_id = req->vdev_id;
param.pdev_id = req->pdev_id;
return wmi_unified_stats_request_send(wmi_handle, req->peer_mac_addr,
&param);
}
QDF_STATUS QDF_STATUS
target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
{ {
@@ -127,7 +303,14 @@ target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
target_if_cp_stats_unregister_event_handler; target_if_cp_stats_unregister_event_handler;
cp_stats_tx_ops->inc_wake_lock_stats = cp_stats_tx_ops->inc_wake_lock_stats =
target_if_cp_stats_inc_wake_lock_stats; target_if_cp_stats_inc_wake_lock_stats;
cp_stats_tx_ops->send_req_stats = target_if_cp_stats_send_stats_req;
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
QDF_STATUS
target_if_cp_stats_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
{
rx_ops->cp_stats_rx_ops.process_stats_event =
tgt_mc_cp_stats_process_stats_event;
return QDF_STATUS_SUCCESS;
}

View File

@@ -4874,6 +4874,7 @@ struct rx_reorder_queue_remove_params {
* @num_chan_stats: number of channel stats * @num_chan_stats: number of channel stats
* @pdev_id: device id for the radio * @pdev_id: device id for the radio
* @num_bcn_stats: number of beacon stats * @num_bcn_stats: number of beacon stats
* @num_rssi_stats: number of rssi stats
*/ */
typedef struct { typedef struct {
wmi_host_stats_id stats_id; wmi_host_stats_id stats_id;
@@ -4885,6 +4886,7 @@ typedef struct {
uint32_t num_chan_stats; uint32_t num_chan_stats;
uint32_t pdev_id; uint32_t pdev_id;
uint32_t num_bcn_stats; uint32_t num_bcn_stats;
uint32_t num_rssi_stats;
} wmi_host_stats_event; } wmi_host_stats_event;
/** /**

View File

@@ -19145,14 +19145,16 @@ static QDF_STATUS extract_peer_sta_kickout_ev_tlv(wmi_unified_t wmi_handle,
static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
void *evt_buf, wmi_host_stats_event *stats_param) void *evt_buf, wmi_host_stats_event *stats_param)
{ {
WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
wmi_stats_event_fixed_param *ev; wmi_stats_event_fixed_param *ev;
wmi_per_chain_rssi_stats *rssi_event;
WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
qdf_mem_zero(stats_param, sizeof(*stats_param));
param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf; param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) evt_buf;
ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param; ev = (wmi_stats_event_fixed_param *) param_buf->fixed_param;
rssi_event = param_buf->chain_stats;
if (!ev) { if (!ev) {
WMI_LOGE("%s: Failed to alloc memory\n", __func__); WMI_LOGE("%s: event fixed param NULL\n", __func__);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
@@ -19201,6 +19203,20 @@ static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( stats_param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host(
ev->pdev_id); ev->pdev_id);
/* if chain_stats is not populated */
if (!param_buf->chain_stats || !param_buf->num_chain_stats)
return QDF_STATUS_SUCCESS;
if (WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats !=
WMITLV_GET_TLVTAG(rssi_event->tlv_header))
return QDF_STATUS_SUCCESS;
if (WMITLV_GET_STRUCT_TLVLEN(wmi_per_chain_rssi_stats) !=
WMITLV_GET_TLVTAG(rssi_event->tlv_header))
return QDF_STATUS_SUCCESS;
stats_param->num_rssi_stats = rssi_event->num_per_chain_rssi_stats;
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }