qcacld-3.0: Store pktlog events when pktlog is enabled by default in INI

Host should not honor any vendor pktlog disable command
if NO vendor pktlog enable command is sent previously.

Currently, vendor sends pktlog disable command without sending enable
command during init and because pktlog is enabled in ini by default,
Host sends the pktlog disable command to firmware which is not as expected.

To fix this, host uses reserved flag in wifi_start_log to distinguish
vendor command from iwpriv or pktlog conf tool command and vendor disable
pktlog command will be sent to firmware only when vendor pktlog enable
commands is sent previously.

Moreover, pktlog INI enable by default and Pktlog buffer size are now
controlled using a macro FEATURE_PKTLOG depending on build variant.
For production/user build, pktlog is default disable and buffer size is
1 MB, whereas for dev build, pktlog is default enable and buffer size is
10 MB.

Change-Id: If64cd522e91cbe9a6d94d8626eb758282fcfd1bd
CRs-Fixed: 1072584
diff --git a/Kbuild b/Kbuild
index bb06e84..3fc0b72 100644
--- a/Kbuild
+++ b/Kbuild
@@ -65,6 +65,7 @@
 	# 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 @@
 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 5e34ee2..bd3017f 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -1246,7 +1246,13 @@
 #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 f60551c..c534a7d 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -4203,9 +4203,9 @@
 		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 65d40ea..33f9cfc 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -6913,7 +6913,15 @@
 			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 ed3a568..43b6ccd 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -3219,14 +3219,14 @@
  * @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 20e9db1..1a04362 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -14672,7 +14672,7 @@
 	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 9d213e0..a7fcf49 100644
--- a/core/utils/pktlog/include/pktlog_ac.h
+++ b/core/utils/pktlog/include/pktlog_ac.h
@@ -72,7 +72,8 @@
 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 @@
 	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_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 @@
 	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 78fd0eb..15b83d3 100644
--- a/core/utils/pktlog/include/pktlog_ac_i.h
+++ b/core/utils/pktlog/include/pktlog_ac_i.h
@@ -32,7 +32,11 @@
 #include <ol_txrx_internal.h>
 #include <pktlog_ac.h>
 
-#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 b92de81..f885d66 100644
--- a/core/utils/pktlog/linux_ac.c
+++ b/core/utils/pktlog/linux_ac.c
@@ -232,7 +232,7 @@
 		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 @@
 	 * 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 @@
 	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 db62848..dc7d092 100644
--- a/core/utils/pktlog/pktlog_ac.c
+++ b/core/utils/pktlog/pktlog_ac.c
@@ -355,6 +355,7 @@
 	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 @@
 }
 
 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 @@
 	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 @@
 			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 939bd53..35cf0b8 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -5441,11 +5441,13 @@
 
 	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__);
 	}
 }