qcacld-3.0: Add support to enable/disable packetlog using iwpriv

Add support to enable/disable packetlog using
iwpriv wlan0 pktlog command.

Change-Id: Ia17f659e16221985be5cd9e75ebf0c46f2dc5693
CRs-Fixed: 970647
This commit is contained in:
Srinivas Girigowda 2016-02-25 16:02:42 -08:00 • committed by qcabuildsw
commit c34f11dfd8
13 changed files with 194 additions and 64 deletions

View file

@ -144,7 +144,8 @@ typedef struct {
#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV + 9)
#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV + 10)
#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV + 11)
/* (SIOCIWFIRSTPRIV+12) is unused */
#define QCSAP_IOCTL_SET_PKTLOG (SIOCIWFIRSTPRIV + 12)
/* Private ioctls and their sub-ioctls */
#define QCSAP_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 13)
#define QCSAP_GET_STATS 1

View file

@ -1690,6 +1690,20 @@ static inline QDF_STATUS hdd_register_for_sap_restart_with_channel_switch(void)
}
#endif
#if !defined(REMOVE_PKT_LOG)
int hdd_process_pktlog_command(hdd_context_t *hdd_ctx, uint32_t set_value);
int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable, uint8_t);
#else
int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable, uint8_t)
{
return 0;
}
int hdd_process_pktlog_command(hdd_context_t *hdd_ctx, uint32_t set_value)
{
return 0;
}
#endif /* REMOVE_PKT_LOG */
#ifdef FEATURE_TSO
/**
* hdd_set_tso_flags() - enable TSO flags in the network device
@ -1806,13 +1820,4 @@ static inline void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
#endif
void hdd_wlan_update_target_info(hdd_context_t *hdd_ctx, void *context);
#if !defined(REMOVE_PKT_LOG)
int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable);
#else
int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable)
{
return 0;
}
#endif /* REMOVE_PKT_LOG */
#endif /* end #if !defined(WLAN_HDD_MAIN_H) */

View file

@ -3602,6 +3602,39 @@ static iw_softap_set_max_tx_power(struct net_device *dev,
return ret;
}
int
static __iw_softap_set_pktlog(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
hdd_context_t *hdd_ctx;
int *value = (int *)extra;
ENTER_DEV(dev);
if (NULL == value)
return -ENOMEM;
hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
return hdd_process_pktlog_command(hdd_ctx, value[0]);
}
int
static iw_softap_set_pktlog(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret;
cds_ssr_protect(__func__);
ret = __iw_softap_set_pktlog(dev, info, wrqu, extra);
cds_ssr_unprotect(__func__);
return ret;
}
int
static __iw_softap_set_tx_power(struct net_device *dev,
struct iw_request_info *info,
@ -6096,6 +6129,12 @@ static const struct iw_priv_args hostapd_private_args[] = {
0, "setTxMaxPower"
}
,
{
QCSAP_IOCTL_SET_PKTLOG,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "pktlog"
}
,
/* Set HDD CFG Ini param */
{
QCSAP_IOCTL_SET_INI_CFG,
@ -6195,6 +6234,8 @@ static const iw_handler hostapd_private[] = {
iw_softap_set_tx_power,
[QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] =
iw_softap_set_max_tx_power,
[QCSAP_IOCTL_SET_PKTLOG - SIOCIWFIRSTPRIV] =
iw_softap_set_pktlog,
[QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV] =
iw_softap_set_ini_cfg,
[QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] =

View file

@ -6704,6 +6704,47 @@ static inline void hdd_release_rtnl_lock(void) { }
#endif
#if !defined(REMOVE_PKT_LOG)
/**
* hdd_process_pktlog_command() - process pktlog command
* @hdd_ctx: hdd context
* @set_value: value set by user
*
* Return: 0 for success or error.
*/
int hdd_process_pktlog_command(hdd_context_t *hdd_ctx, uint32_t set_value)
{
int ret;
bool enable;
uint8_t user_triggered = 0;
ret = wlan_hdd_validate_context(hdd_ctx);
if (0 != ret)
return ret;
hdd_info("set pktlog %d", set_value);
if (set_value > 2) {
hdd_err("invalid pktlog value %d", set_value);
return -EINVAL;
}
/*
* set_value = 0 then disable packetlog
* set_value = 1 enable packetlog forcefully
* set_vlaue = 2 then disable packetlog if disabled through ini or
* enable packetlog with AUTO type.
*/
enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
true : false;
if (1 == set_value) {
enable = true;
user_triggered = 1;
}
return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered);
}
/**
* hdd_pktlog_enable_disable() - Enable/Disable packet logging
* @hdd_ctx: HDD context
@ -6711,7 +6752,8 @@ static inline void hdd_release_rtnl_lock(void) { }
*
* Return: 0 on success; error number otherwise
*/
int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable)
int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable,
uint8_t user_triggered)
{
struct sir_wifi_start_log start_log;
QDF_STATUS status;
@ -6719,6 +6761,9 @@ int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable)
start_log.ring_id = RING_ID_PER_PACKET_STATS;
start_log.verbose_level =
enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
start_log.ini_triggered = cds_is_packet_log_enabled();
start_log.user_triggered = user_triggered;
status = sme_wifi_start_logger(hdd_ctx->hHal, start_log);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("sme_wifi_start_logger failed(err=%d)", status);
@ -7537,7 +7582,7 @@ int hdd_wlan_startup(struct device *dev)
if (cds_is_packet_log_enabled())
hdd_pktlog_enable_disable(hdd_ctx, true);
hdd_pktlog_enable_disable(hdd_ctx, true, 0);
ret = hdd_register_notifiers(hdd_ctx);
if (ret)

View file

@ -1444,7 +1444,7 @@ QDF_STATUS hdd_wlan_re_init(void)
goto err_cds_disable;
if (cds_is_packet_log_enabled())
hdd_pktlog_enable_disable(pHddCtx, true);
hdd_pktlog_enable_disable(pHddCtx, true, 0);
hdd_err("WLAN host driver reinitiation completed!");
goto success;

View file

@ -165,7 +165,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
#define WE_TXRX_FWSTATS_RESET 41
#define WE_SET_MAX_TX_POWER_2_4 42
#define WE_SET_MAX_TX_POWER_5_0 43
/* 44 is unused */
#define WE_SET_PKTLOG 44
/* Private ioctl for packet powe save */
#define WE_PPS_PAID_MATCH 45
#define WE_PPS_GID_MATCH 46
@ -5158,6 +5158,11 @@ static int __iw_setint_getnone(struct net_device *dev,
break;
}
case WE_SET_PKTLOG:
{
hdd_process_pktlog_command(hdd_ctx, set_value);
break;
}
case WE_SET_HIGHER_DTIM_TRANSITION:
{
if (!((set_value == false) || (set_value == true))) {
@ -9895,6 +9900,11 @@ static const struct iw_priv_args we_private_args[] = {
0,
"setTxMaxPower5G"},
{WE_SET_PKTLOG,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0,
"pktlog"},
/* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA
* as well to keep same syntax as in SAP. Now onwards, STA
* will support both */

View file

@ -3174,11 +3174,15 @@ typedef struct {
* statistics, connectivity etc.
* @verbose_level: Verbose level which can be 0,1,2,3
* @flag: Flag field for future use
* @ini_triggered: triggered using ini
* @user_triggered: triggered by user
*/
struct sir_wifi_start_log {
uint32_t ring_id;
uint32_t verbose_level;
uint32_t flag;
bool ini_triggered;
uint8_t user_triggered;
};

View file

@ -14446,6 +14446,8 @@ QDF_STATUS sme_wifi_start_logger(tHalHandle hal,
req_msg->verbose_level = start_log.verbose_level;
req_msg->flag = start_log.flag;
req_msg->ring_id = start_log.ring_id;
req_msg->ini_triggered = start_log.ini_triggered;
req_msg->user_triggered = start_log.user_triggered;
status = sme_acquire_global_lock(&mac->sme);
if (status != QDF_STATUS_SUCCESS) {

View file

@ -66,10 +66,13 @@ extern void pktlog_release_buf(struct hif_opaque_softc *scn);
ssize_t pktlog_read_proc_entry(char *buf, size_t nbytes, loff_t *ppos,
struct ath_pktlog_info *pl_info, bool *read_complete);
int pktlog_send_per_pkt_stats_to_user(void);
A_STATUS
wdi_pktlog_unsubscribe(struct ol_txrx_pdev_t *txrx_pdev, uint32_t log_state);
struct ol_pl_arch_dep_funcs {
void (*pktlog_init)(struct hif_opaque_softc *scn);
int (*pktlog_enable)(struct hif_opaque_softc *scn, int32_t log_state);
int (*pktlog_enable)(struct hif_opaque_softc *scn, int32_t log_state,
bool ini, uint8_t user);
int (*pktlog_setsize)(struct hif_opaque_softc *scn, int32_t log_state);
int (*pktlog_disable)(struct hif_opaque_softc *scn);
};
@ -82,6 +85,8 @@ struct ol_pl_os_dep_funcs {
struct ath_pktlog_wmi_params {
WMI_PKTLOG_EVENT pktlog_event;
WMI_CMD_ID cmd_id;
bool ini_triggered;
uint8_t user_triggered;
};
extern struct ol_pl_arch_dep_funcs ol_pl_funcs;
@ -93,7 +98,8 @@ struct ol_pktlog_dev_t {
struct ath_pktlog_info *pl_info;
ol_ath_generic_softc_handle scn;
char *name;
bool tgt_pktlog_enabled;
bool tgt_pktlog_alloced;
bool is_pktlog_cb_subscribed;
bool mt_pktlog_enabled;
uint32_t htc_err_cnt;
uint8_t htc_endpoint;
@ -124,7 +130,8 @@ extern struct ol_pktlog_dev_t ol_pl_dev;
void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data);
void pktlog_init(struct hif_opaque_softc *scn);
int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state);
int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state,
bool, uint8_t);
int pktlog_setsize(struct hif_opaque_softc *scn, int32_t log_state);
int pktlog_disable(struct hif_opaque_softc *scn);
int pktlogmod_init(void *context);
@ -153,7 +160,8 @@ static inline void pktlog_init(struct hif_opaque_softc *scn)
{
return;
}
static int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state)
static int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state,
bool ini, uint8_t user)
{
return 0;
}

View file

@ -231,7 +231,8 @@ qdf_sysctl_decl(ath_sysctl_pktlog_enable, ctl, write, filp, buffer, lenp, ppos)
lenp, ppos);
if (ret == 0)
ret = pl_dev->pl_funcs->pktlog_enable(
(struct hif_opaque_softc *)scn, enable);
(struct hif_opaque_softc *)scn, enable,
cds_is_packet_log_enabled(), 0);
else
printk(PKTLOG_TAG "%s:proc_dointvec failed\n",
__func__);
@ -438,7 +439,7 @@ static int pktlog_attach(struct hif_opaque_softc *scn)
* initialize log info
* might be good to move to pktlog_init
*/
/* pl_dev->tgt_pktlog_enabled = false; */
/* pl_dev->tgt_pktlog_alloced = false; */
pl_info_lnx->proc_entry = NULL;
pl_info_lnx->sysctl_header = NULL;
@ -491,10 +492,18 @@ static void pktlog_sysctl_unregister(struct ol_pktlog_dev_t *pl_dev)
static void pktlog_detach(struct hif_opaque_softc *scn)
{
struct ol_pktlog_dev_t *pl_dev = (struct ol_pktlog_dev_t *)
get_pl_handle(scn);
struct ol_txrx_pdev_t *txrx_pdev;
struct ol_pktlog_dev_t *pl_dev;
struct ath_pktlog_info *pl_info;
txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
if (!txrx_pdev) {
printk("%s: Invalid txrx_pdev context\n", __func__);
ASSERT(0);
return;
}
pl_dev = txrx_pdev->pl_dev;
if (!pl_dev) {
printk("%s: Invalid pktlog context\n", __func__);
ASSERT(0);
@ -506,8 +515,10 @@ static void pktlog_detach(struct hif_opaque_softc *scn)
pktlog_sysctl_unregister(pl_dev);
pktlog_cleanup(pl_info);
if (pl_info->buf)
if (pl_info->buf) {
pktlog_release_buf(scn);
pl_dev->tgt_pktlog_alloced = false;
}
if (pl_dev) {
kfree(pl_info);
@ -1034,15 +1045,7 @@ void pktlogmod_exit(void *context)
if (!pl_dev || g_pktlog_pde == NULL)
return;
/*
* Disable firmware side pktlog function
*/
if (pl_dev->tgt_pktlog_enabled) {
if (pl_dev->pl_funcs->pktlog_enable(scn, 0)) {
printk("%s: cannot disable pktlog in the target\n",
__func__);
}
}
pktlog_detach(scn);
/*
* pdev kill needs to be implemented

View file

@ -74,7 +74,8 @@ void ol_pl_sethandle(ol_pktlog_dev_handle *pl_handle,
}
static A_STATUS pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types,
WMI_CMD_ID cmd_id)
WMI_CMD_ID cmd_id, bool ini_triggered,
uint8_t user_triggered)
{
cds_msg_t msg = { 0 };
QDF_STATUS status;
@ -87,6 +88,8 @@ static A_STATUS pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types,
param->cmd_id = cmd_id;
param->pktlog_event = event_types;
param->ini_triggered = ini_triggered;
param->user_triggered = user_triggered;
msg.type = WMA_PKTLOG_ENABLE_REQ;
msg.bodyptr = param;
@ -102,8 +105,9 @@ static A_STATUS pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types,
return A_OK;
}
static inline A_STATUS pktlog_enable_tgt(struct hif_opaque_softc *_scn,
uint32_t log_state)
static inline A_STATUS
pktlog_enable_tgt(struct hif_opaque_softc *_scn, uint32_t log_state,
bool ini_triggered, uint8_t user_triggered)
{
uint32_t types = 0;
@ -122,7 +126,8 @@ static inline A_STATUS pktlog_enable_tgt(struct hif_opaque_softc *_scn,
if (log_state & ATH_PKTLOG_SW_EVENT)
types |= WMI_PKTLOG_EVENT_SW;
return pktlog_wma_post_msg(types, WMI_PDEV_PKTLOG_ENABLE_CMDID);
return pktlog_wma_post_msg(types, WMI_PDEV_PKTLOG_ENABLE_CMDID,
ini_triggered, user_triggered);
}
static inline A_STATUS
@ -248,7 +253,7 @@ void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data)
}
}
static inline A_STATUS
A_STATUS
wdi_pktlog_unsubscribe(struct ol_txrx_pdev_t *txrx_pdev, uint32_t log_state)
{
if (log_state & ATH_PKTLOG_TX) {
@ -308,16 +313,17 @@ int pktlog_disable(struct hif_opaque_softc *scn)
pl_dev = txrx_pdev->pl_dev;
pl_info = pl_dev->pl_info;
if (pktlog_wma_post_msg(0, WMI_PDEV_PKTLOG_DISABLE_CMDID)) {
if (pktlog_wma_post_msg(0, WMI_PDEV_PKTLOG_DISABLE_CMDID, 0, 0)) {
printk("Failed to disable pktlog in target\n");
return -1;
}
if (wdi_pktlog_unsubscribe(txrx_pdev, pl_info->log_state)) {
if (pl_dev->is_pktlog_cb_subscribed &&
wdi_pktlog_unsubscribe(txrx_pdev, pl_info->log_state)) {
printk("Cannot unsubscribe pktlog from the WDI\n");
return -1;
}
pl_dev->is_pktlog_cb_subscribed = false;
return 0;
}
@ -358,7 +364,8 @@ void pktlog_init(struct hif_opaque_softc *scn)
PKTLOG_SW_EVENT_SUBSCRIBER.callback = pktlog_callback;
}
int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state)
int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state,
bool ini_triggered, uint8_t user_triggered)
{
struct ol_pktlog_dev_t *pl_dev;
struct ath_pktlog_info *pl_info;
@ -390,7 +397,7 @@ int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state)
if (!pl_info)
return 0;
if (log_state != 0 && !pl_dev->tgt_pktlog_enabled) {
if (!pl_dev->tgt_pktlog_alloced) {
if (pl_info->buf == NULL) {
error = pktlog_alloc_buf(scn);
@ -418,25 +425,25 @@ int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state)
pl_info->start_time_thruput = os_get_timestamp();
pl_info->start_time_per = pl_info->start_time_thruput;
pl_dev->tgt_pktlog_alloced = true;
}
if (log_state != 0) {
/* WDI subscribe */
if (wdi_pktlog_subscribe(txrx_pdev, log_state)) {
if ((!pl_dev->is_pktlog_cb_subscribed) &&
wdi_pktlog_subscribe(txrx_pdev, log_state)) {
printk("Unable to subscribe to the WDI %s\n", __func__);
return -1;
}
pl_dev->is_pktlog_cb_subscribed = true;
/* WMI command to enable pktlog on the firmware */
if (pktlog_enable_tgt(scn, log_state)) {
if (pktlog_enable_tgt(scn, log_state, ini_triggered,
user_triggered)) {
printk("Device cannot be enabled, %s\n", __func__);
return -1;
} else {
pl_dev->tgt_pktlog_enabled = true;
}
} else if (!log_state && pl_dev->tgt_pktlog_enabled) {
} else {
pl_dev->pl_funcs->pktlog_disable(scn);
pl_dev->tgt_pktlog_enabled = false;
if (wdi_pktlog_unsubscribe(txrx_pdev, pl_info->log_state)) {
printk("Cannot unsubscribe pktlog from the WDI\n");
return -1;
}
}
pl_info->log_state = log_state;
@ -470,8 +477,17 @@ int pktlog_setsize(struct hif_opaque_softc *scn, int32_t size)
return -EINVAL;
}
if (pl_info->buf != NULL)
if (pl_info->buf != NULL) {
if (pl_dev->is_pktlog_cb_subscribed &&
wdi_pktlog_unsubscribe(pdev_txrx_handle,
pl_info->log_state)) {
printk("Cannot unsubscribe pktlog from the WDI\n");
return -EFAULT;
}
pktlog_release_buf(scn);
pl_dev->is_pktlog_cb_subscribed = false;
pl_dev->tgt_pktlog_alloced = false;
}
if (size != 0)
pl_info->buf_size = size;

View file

@ -2224,19 +2224,12 @@ QDF_STATUS wma_pktlog_wmi_send_cmd(WMA_HANDLE handle,
tp_wma_handle wma_handle = (tp_wma_handle) handle;
int ret;
/*Check if packet log is enabled in cfg.ini */
if (!cds_is_packet_log_enabled()) {
WMA_LOGE("%s:pkt log is not enabled in cfg.ini", __func__);
return QDF_STATUS_E_FAILURE;
}
ret = wmi_unified_pktlog_wmi_send_cmd(wma_handle->wmi_handle,
params->pktlog_event,
params->cmd_id);
params->pktlog_event,
params->cmd_id, params->user_triggered);
if (ret)
return QDF_STATUS_E_FAILURE;
return QDF_STATUS_SUCCESS;
}
#endif /* REMOVE_PKT_LOG */

View file

@ -5333,10 +5333,12 @@ void wma_set_wifi_start_packet_stats(void *wma_handle,
ATH_PKTLOG_TEXT | ATH_PKTLOG_SW_EVENT;
if (start_log->verbose_level == WLAN_LOG_LEVEL_ACTIVE) {
pktlog_enable(scn, log_state);
pktlog_enable(scn, log_state, start_log->ini_triggered,
start_log->user_triggered);
WMA_LOGI("%s: Enabling per packet stats", __func__);
} else {
pktlog_enable(scn, 0);
pktlog_enable(scn, 0, start_log->ini_triggered,
start_log->user_triggered);
WMA_LOGI("%s: Disabling per packet stats", __func__);
}
}