diff --git a/Kbuild b/Kbuild index bb06e84311eb..3fc0b7227418 100644 --- a/Kbuild +++ b/Kbuild @@ -65,6 +65,7 @@ ifeq ($(KERNEL_BUILD), 0) # builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT # config. ifneq ($(TARGET_BUILD_VARIANT),user) + CONFIG_FEATURE_PKTLOG := y ifeq ($(CONFIG_SLUB_DEBUG_ON),y) CONFIG_FEATURE_DP_TRACE := y else @@ -1114,6 +1115,10 @@ ifeq ($(CONFIG_WLAN_FASTPATH), y) CDEFINES += -DWLAN_FEATURE_FASTPATH endif +ifeq ($(CONFIG_FEATURE_PKTLOG), y) +CDEFINES += -DFEATURE_PKTLOG +endif + ifeq ($(CONFIG_FEATURE_DP_TRACE), y) CDEFINES += -DFEATURE_DP_TRACE endif diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 5e34ee250f81..bd3017f9b3a1 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -1246,7 +1246,13 @@ typedef enum { #define CFG_ENABLE_PACKET_LOG "gEnablePacketLog" #define CFG_ENABLE_PACKET_LOG_MIN (0) #define CFG_ENABLE_PACKET_LOG_MAX (1) +#ifdef FEATURE_PKTLOG #define CFG_ENABLE_PACKET_LOG_DEFAULT (1) +#else +#define CFG_ENABLE_PACKET_LOG_DEFAULT (0) +#endif + + /* gFwDebugLogType takes values from enum dbglog_process_t, * make default value as DBGLOG_PROCESS_NET_RAW to give the diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index f60551c32523..c534a7dd8e39 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -4203,9 +4203,9 @@ static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy, hdd_err("attr flag failed"); return -EINVAL; } - start_log.flag = nla_get_u32( + start_log.is_iwpriv_command = nla_get_u32( tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]); - hdd_info("flag=%d", start_log.flag); + hdd_info("is_iwpriv_command =%d", start_log.is_iwpriv_command); cds_set_ring_log_level(start_log.ring_id, start_log.verbose_level); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 65d40ea06b84..33f9cfc6a96d 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -6913,7 +6913,15 @@ int hdd_pktlog_enable_disable(hdd_context_t *hdd_ctx, bool enable, enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF; start_log.ini_triggered = cds_is_packet_log_enabled(); start_log.user_triggered = user_triggered; - + /* + * Use "is_iwpriv_command" flag to distinguish iwpriv command from other + * commands. Host uses this flag to decide whether to send pktlog + * disable command to fw without sending pktlog enable command + * previously. For eg, If vendor sends pktlog disable command without + * sending pktlog enable command, then host discards the packet + * but for iwpriv command, host will send it to fw. + */ + start_log.is_iwpriv_command = 1; 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); diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index ed3a56846ed5..43b6ccd0d892 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -3219,14 +3219,14 @@ typedef struct { * @name: Attribute which indicates the type of logging like per packet * statistics, connectivity etc. * @verbose_level: Verbose level which can be 0,1,2,3 - * @flag: Flag field for future use + * @is_iwpriv_command: Set 1 for iwpriv command * @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; + uint32_t is_iwpriv_command; bool ini_triggered; uint8_t user_triggered; }; diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 20e9db12667b..1a04362b8549 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -14672,7 +14672,7 @@ QDF_STATUS sme_wifi_start_logger(tHalHandle hal, qdf_mem_zero(req_msg, len); req_msg->verbose_level = start_log.verbose_level; - req_msg->flag = start_log.flag; + req_msg->is_iwpriv_command = start_log.is_iwpriv_command; req_msg->ring_id = start_log.ring_id; req_msg->ini_triggered = start_log.ini_triggered; req_msg->user_triggered = start_log.user_triggered; diff --git a/core/utils/pktlog/include/pktlog_ac.h b/core/utils/pktlog/include/pktlog_ac.h index 9d213e0c76bb..a7fcf493a98b 100644 --- a/core/utils/pktlog/include/pktlog_ac.h +++ b/core/utils/pktlog/include/pktlog_ac.h @@ -72,7 +72,8 @@ 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, - bool ini, uint8_t user); + bool ini, uint8_t user, + uint32_t is_iwpriv_command); int (*pktlog_setsize)(struct hif_opaque_softc *scn, int32_t log_state); int (*pktlog_disable)(struct hif_opaque_softc *scn); }; @@ -104,6 +105,7 @@ struct ol_pktlog_dev_t { uint32_t htc_err_cnt; uint8_t htc_endpoint; void *htc_pdev; + bool vendor_cmd_send; }; #define PKTLOG_SYSCTL_SIZE 14 @@ -131,7 +133,7 @@ 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, - bool, uint8_t); + bool, uint8_t, uint32_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); @@ -161,7 +163,7 @@ static inline void pktlog_init(struct hif_opaque_softc *scn) return; } static int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, - bool ini, uint8_t user) + bool ini, uint8_t user, uint32_t is_iwpriv_command) { return 0; } diff --git a/core/utils/pktlog/include/pktlog_ac_i.h b/core/utils/pktlog/include/pktlog_ac_i.h index 78fd0ebd26f3..15b83d35ce8b 100644 --- a/core/utils/pktlog/include/pktlog_ac_i.h +++ b/core/utils/pktlog/include/pktlog_ac_i.h @@ -32,7 +32,11 @@ #include #include -#define PKTLOG_DEFAULT_BUFSIZE (1024 * 1024) +#ifdef FEATURE_PKTLOG +#define PKTLOG_DEFAULT_BUFSIZE (10 * 1024 * 1024) /* 10MB */ +#else +#define PKTLOG_DEFAULT_BUFSIZE (1 * 1024 * 1024) /* 1MB */ +#endif #define PKTLOG_DEFAULT_SACK_THR 3 #define PKTLOG_DEFAULT_TAIL_LENGTH 100 #define PKTLOG_DEFAULT_THRUPUT_THRESH (64 * 1024) diff --git a/core/utils/pktlog/linux_ac.c b/core/utils/pktlog/linux_ac.c index b92de81f683d..f885d6672038 100644 --- a/core/utils/pktlog/linux_ac.c +++ b/core/utils/pktlog/linux_ac.c @@ -232,7 +232,7 @@ qdf_sysctl_decl(ath_sysctl_pktlog_enable, ctl, write, filp, buffer, lenp, ppos) if (ret == 0) ret = pl_dev->pl_funcs->pktlog_enable( (struct hif_opaque_softc *)scn, enable, - cds_is_packet_log_enabled(), 0); + cds_is_packet_log_enabled(), 0, 1); else printk(PKTLOG_TAG "%s:proc_dointvec failed\n", __func__); @@ -440,6 +440,7 @@ static int pktlog_attach(struct hif_opaque_softc *scn) * might be good to move to pktlog_init */ /* pl_dev->tgt_pktlog_alloced = false; */ + pl_dev->vendor_cmd_send = false; pl_info_lnx->proc_entry = NULL; pl_info_lnx->sysctl_header = NULL; @@ -848,6 +849,14 @@ pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) if (log_buf == NULL) return 0; + if (pl_info->log_state) { + /* Read is not allowed when write is going on + * When issuing cat command, ensure to send + * pktlog disable command first. + */ + return -EINVAL; + } + if (*ppos == 0 && pl_info->log_state) { pl_info->saved_state = pl_info->log_state; pl_info->log_state = 0; diff --git a/core/utils/pktlog/pktlog_ac.c b/core/utils/pktlog/pktlog_ac.c index db6284871bc4..dc7d0927fcb6 100644 --- a/core/utils/pktlog/pktlog_ac.c +++ b/core/utils/pktlog/pktlog_ac.c @@ -355,6 +355,7 @@ void pktlog_init(struct hif_opaque_softc *scn) pl_info->pktlen = 0; pl_info->start_time_thruput = 0; pl_info->start_time_per = 0; + pdev_txrx_handle->pl_dev->vendor_cmd_send = false; PKTLOG_TX_SUBSCRIBER.callback = pktlog_callback; PKTLOG_RX_SUBSCRIBER.callback = pktlog_callback; @@ -365,7 +366,8 @@ void pktlog_init(struct hif_opaque_softc *scn) } int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, - bool ini_triggered, uint8_t user_triggered) + bool ini_triggered, uint8_t user_triggered, + uint32_t is_iwpriv_command) { struct ol_pktlog_dev_t *pl_dev; struct ath_pktlog_info *pl_info; @@ -397,6 +399,15 @@ int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, if (!pl_info) return 0; + /* is_iwpriv_command : 0 indicates its a vendor command + * log_state: 0 indicates pktlog disable command + * vendor_cmd_send flag; false means no vendor pktlog enable + * command was sent previously + */ + if (is_iwpriv_command == 0 && log_state == 0 && + pl_dev->vendor_cmd_send == false) + return 0; + if (!pl_dev->tgt_pktlog_alloced) { if (pl_info->buf == NULL) { error = pktlog_alloc_buf(scn); @@ -442,8 +453,13 @@ int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, printk("Device cannot be enabled, %s\n", __func__); return -1; } + + if (is_iwpriv_command == 0) + pl_dev->vendor_cmd_send = true; } else { pl_dev->pl_funcs->pktlog_disable(scn); + if (is_iwpriv_command == 0) + pl_dev->vendor_cmd_send = false; } pl_info->log_state = log_state; diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 939bd532673f..35cf0b88b049 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -5441,11 +5441,13 @@ void wma_set_wifi_start_packet_stats(void *wma_handle, if (start_log->verbose_level == WLAN_LOG_LEVEL_ACTIVE) { pktlog_enable(scn, log_state, start_log->ini_triggered, - start_log->user_triggered); + start_log->user_triggered, + start_log->is_iwpriv_command); WMA_LOGI("%s: Enabling per packet stats", __func__); } else { pktlog_enable(scn, 0, start_log->ini_triggered, - start_log->user_triggered); + start_log->user_triggered, + start_log->is_iwpriv_command); WMA_LOGI("%s: Disabling per packet stats", __func__); } }