qcacld-3.0: Enhance hang info feature

* Use separate hang reason for case that lack of credit after suspend
* Add hang buf offset check to avoid overflow

Change-Id: Ic794d02672cd663598da66b9e75924c41b5ef0e8
CRs-Fixed: 2801343
diff --git a/Kbuild b/Kbuild
index 7e2e01f..9b59fec 100644
--- a/Kbuild
+++ b/Kbuild
@@ -2967,6 +2967,7 @@
 endif
 
 cppflags-$(CONFIG_WLAN_HANG_EVENT) += -DHIF_CE_LOG_INFO
+cppflags-$(CONFIG_WLAN_HANG_EVENT) += -DHIF_BUS_LOG_INFO
 cppflags-$(CONFIG_WLAN_HANG_EVENT) += -DDP_SUPPORT_RECOVERY_NOTIFY
 #endof dummy flags
 
diff --git a/components/pmo/core/src/wlan_pmo_suspend_resume.c b/components/pmo/core/src/wlan_pmo_suspend_resume.c
index d9a6ea2..6df3318 100644
--- a/components/pmo/core/src/wlan_pmo_suspend_resume.c
+++ b/components/pmo/core/src/wlan_pmo_suspend_resume.c
@@ -860,7 +860,7 @@
 		pmo_err("No Credits after HTC ACK:%d, pending_cmds:%d,"
 			 "cannot resume back", host_credits, wmi_pending_cmds);
 		htc_dump_counter_info(pmo_core_psoc_get_htc_handle(psoc));
-		qdf_trigger_self_recovery(psoc, QDF_SUSPEND_TIMEOUT);
+		qdf_trigger_self_recovery(psoc, QDF_SUSPEND_NO_CREDIT);
 	}
 	pmo_debug("WOW enabled successfully in fw: credits:%d pending_cmds: %d",
 		host_credits, wmi_pending_cmds);
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index 97eeea6..e83d402 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -574,10 +574,9 @@
 	if (!cds_hang_evt_buff)
 		return NOTIFY_STOP_MASK;
 
-	if (cds_hang_data->offset >= QDF_WLAN_MAX_HOST_OFFSET)
-		return NOTIFY_STOP_MASK;
-
 	total_len = sizeof(*cmd);
+	if (cds_hang_data->offset + total_len > QDF_WLAN_HANG_FW_OFFSET)
+		return NOTIFY_STOP_MASK;
 
 	cds_hang_evt_buff = cds_hang_data->hang_data + cds_hang_data->offset;
 	cmd = (struct cds_hang_event_fixed_param *)cds_hang_evt_buff;
diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c
index 148553b..644c48d 100644
--- a/core/dp/txrx/ol_txrx.c
+++ b/core/dp/txrx/ol_txrx.c
@@ -138,7 +138,8 @@
 	if (!peer)
 		return -EINVAL;
 
-	if (notif_data->offset >= QDF_WLAN_MAX_HOST_OFFSET)
+	if (notif_data->offset + sizeof(struct peer_hang_data) >
+			QDF_WLAN_HANG_FW_OFFSET)
 		return NOTIFY_STOP_MASK;
 
 	QDF_HANG_EVT_SET_HDR(&hang_data.tlv_header,
diff --git a/core/hdd/src/wlan_hdd_hang_event.c b/core/hdd/src/wlan_hdd_hang_event.c
index 745dcd9..cfded7a 100644
--- a/core/hdd/src/wlan_hdd_hang_event.c
+++ b/core/hdd/src/wlan_hdd_hang_event.c
@@ -58,12 +58,11 @@
 	if (!hdd_ctx)
 		return NOTIFY_STOP_MASK;
 
-	if (hdd_hang_data->offset >= QDF_WLAN_MAX_HOST_OFFSET)
-		return NOTIFY_STOP_MASK;
-
 	if (state == QDF_SCAN_ATTEMPT_FAILURES) {
 		total_len = sizeof(*cmd_scan);
 		hdd_buf_ptr = hdd_hang_data->hang_data + hdd_hang_data->offset;
+		if (hdd_hang_data->offset + total_len > QDF_WLAN_HANG_FW_OFFSET)
+			return NOTIFY_STOP_MASK;
 		cmd_scan = (struct hdd_scan_fixed_param *)hdd_buf_ptr;
 		QDF_HANG_EVT_SET_HDR(&cmd_scan->tlv_header,
 				     HANG_EVT_TAG_OS_IF_SCAN,
@@ -85,6 +84,12 @@
 		}
 		total_len = sizeof(*cmd);
 		hdd_buf_ptr = hdd_hang_data->hang_data + hdd_hang_data->offset;
+		if (hdd_hang_data->offset + total_len >
+				QDF_WLAN_HANG_FW_OFFSET) {
+			hdd_objmgr_put_vdev(vdev);
+			dev_put(adapter->dev);
+			return NOTIFY_STOP_MASK;
+		}
 		cmd = (struct hdd_hang_event_fixed_param *)hdd_buf_ptr;
 		QDF_HANG_EVT_SET_HDR(&cmd->tlv_header,
 				     HANG_EVT_TAG_OS_IF,
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index ffb26bc..743b65e 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -763,6 +763,7 @@
 	uint8_t *pe_data;
 	uint8_t i;
 	struct pe_hang_event_fixed_param *cmd;
+	size_t size;
 
 	if (!data)
 		return NOTIFY_STOP_MASK;
@@ -771,13 +772,13 @@
 	if (!mac)
 		return NOTIFY_STOP_MASK;
 
-	if (pe_hang_data->offset >= QDF_WLAN_MAX_HOST_OFFSET)
-		return NOTIFY_STOP_MASK;
-
+	size = sizeof(*cmd);
 	for (i = 0; i < mac->lim.maxBssId; i++) {
 		session = &mac->lim.gpSession[i];
 		if (!session->valid)
 			continue;
+		if (pe_hang_data->offset + size > QDF_WLAN_HANG_FW_OFFSET)
+			return NOTIFY_STOP_MASK;
 
 		pe_data = (pe_hang_data->hang_data + pe_hang_data->offset);
 		cmd = (struct pe_hang_event_fixed_param *)pe_data;
@@ -788,7 +789,7 @@
 		cmd->limprevmlmstate = session->limPrevMlmState;
 		cmd->limsmestate = session->limSmeState;
 		cmd->limprevsmestate = session->limPrevSmeState;
-		pe_hang_data->offset += sizeof(*cmd);
+		pe_hang_data->offset += size;
 	}
 
 	return NOTIFY_OK;