diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h index 94b0315afa46..443cc283f928 100644 --- a/core/cds/inc/cds_api.h +++ b/core/cds/inc/cds_api.h @@ -48,6 +48,7 @@ #include #include #include +#include /* Amount of time to wait for WMA to perform an asynchronous activity. * This value should be larger than the timeout used by WMI to wait for @@ -212,6 +213,8 @@ QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc, v_CONTEXT_t cds_context); void *cds_get_context(QDF_MODULE_ID moduleId); +uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev, + struct cdp_vdev **vdev, uint8_t sessionId); v_CONTEXT_t cds_get_global_context(void); QDF_STATUS cds_alloc_context(void *p_cds_context, QDF_MODULE_ID moduleID, diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 03bb228bb774..b394961918f5 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -84,6 +84,43 @@ static struct ol_if_ops dp_ol_if_ops = { void cds_sys_probe_thread_cback(void *pUserData); +/** cds_get_datapath_handles - Initialize pdev, vdev and soc + * @soc - soc handle + * @vdev - virtual handle + * @pdev - physical handle + */ +uint8_t cds_get_datapath_handles(void **soc, struct cdp_pdev **pdev, + struct cdp_vdev **vdev, uint8_t sessionId) +{ + + (*soc) = cds_get_context(QDF_MODULE_ID_SOC); + + if (!(*soc)) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "soc handle is invalid"); + return -EINVAL; + } + + (*pdev) = cds_get_context(QDF_MODULE_ID_TXRX); + + if (!(*pdev)) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "pdev handle is invalid"); + return -EINVAL; + } + + (*vdev) = cdp_get_vdev_from_vdev_id((*soc), (*pdev), + sessionId); + + if (!(*vdev)) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "vdev handle is invalid"); + return -EINVAL; + } + return 0; +} + + /** * cds_init() - Initialize CDS * diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h index 8995f63db1c6..a7a7865cfdd9 100644 --- a/core/hdd/inc/qc_sap_ioctl.h +++ b/core/hdd/inc/qc_sap_ioctl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -251,6 +251,7 @@ enum { QCASAP_PARAM_TX_STBC, QCASAP_PARAM_RX_STBC, QCSAP_PARAM_CHAN_WIDTH, + QCSAP_PARAM_SET_TXRX_STATS, }; int iw_get_channel_list(struct net_device *dev, diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 40d06981773d..9ab412c1d5e7 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,8 @@ #include "wlan_hdd_power.h" #include "wlan_hdd_object_manager.h" #include +#include +#include #include "wlan_hdd_he.h" @@ -2666,6 +2669,10 @@ static __iw_softap_setparam(struct net_device *dev, QDF_STATUS status; int ret = 0; /* success */ hdd_context_t *hdd_ctx; + struct cdp_vdev *vdev = NULL; + struct cdp_pdev *pdev = NULL; + void *soc = NULL; + struct ol_txrx_stats_req req; ENTER_DEV(dev); @@ -2806,6 +2813,19 @@ static __iw_softap_setparam(struct net_device *dev, set_value, VDEV_CMD); break; } + + case QCSAP_PARAM_SET_TXRX_STATS: + { + ret = cds_get_datapath_handles(&soc, &pdev, &vdev, + pHostapdAdapter->sessionId); + if (ret != 0) + break; + hdd_notice("QCSAP_PARAM_SET_TXRX_STATS val %d", set_value); + qdf_mem_zero(&req, sizeof(req)); + ret = cdp_txrx_stats(soc, vdev, &req, set_value); + break; + } + /* Firmware debug log */ case QCSAP_DBGLOG_LOG_LEVEL: { @@ -5281,11 +5301,14 @@ static const struct iw_priv_args hostapd_private_args[] = { }, { QCSAP_PARAM_SET_MC_RATE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" - }, - { + }, { QCSAP_PARAM_SET_TXRX_FW_STATS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "txrx_fw_stats" + }, { + QCSAP_PARAM_SET_TXRX_STATS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "txrx_stats" }, { QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 0be224b6a8d3..8c4030bce3f9 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -41,6 +41,7 @@ #include #include "scheduler_api.h" #include +#include #include #include "sir_params.h" #include "csr_api.h" @@ -96,7 +97,8 @@ #include "cds_utils.h" #include "wlan_hdd_request_manager.h" #include "os_if_wifi_pos.h" - +#include +#include #define HDD_FINISH_ULA_TIME_OUT 800 #define HDD_SET_MCBC_FILTERS_TO_FW 1 #define HDD_DELETE_MCBC_FILTERS_FROM_FW 0 @@ -1007,6 +1009,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { */ #define WE_SET_CHANNEL 88 #define WE_SET_CONC_SYSTEM_PREF 89 +#define WE_SET_TXRX_STATS 90 /* Private ioctls and their sub-ioctls */ #define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1) @@ -7344,6 +7347,10 @@ static int __iw_setint_getnone(struct net_device *dev, int ret; int enable_pbm, enable_mp; QDF_STATUS status; + void *soc = NULL; + struct ol_txrx_stats_req req; + struct cdp_pdev *pdev = NULL; + struct cdp_vdev *vdev = NULL; ENTER_DEV(dev); @@ -8075,6 +8082,20 @@ static int __iw_setint_getnone(struct net_device *dev, break; } + case WE_SET_TXRX_STATS: + { + hdd_notice("WE_SET_TXRX_STATS val %d", set_value); + ret = cds_get_datapath_handles(&soc, &pdev, &vdev, + pAdapter->sessionId); + + if (ret != 0) + break; + + qdf_mem_zero(&req, sizeof(req)); + ret = cdp_txrx_stats(soc, vdev, &req, set_value); + break; + } + case WE_TXRX_FWSTATS_RESET: { hdd_notice("WE_TXRX_FWSTATS_RESET val %d", set_value); @@ -12628,6 +12649,11 @@ static const struct iw_priv_args we_private_args[] = { 0, "txrx_fw_stats"}, + {WE_SET_TXRX_STATS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "txrx_stats"}, + {WE_TXRX_FWSTATS_RESET, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,