wil6210: add statistics for suspend time

Add statistics for total, min and max suspend time, that
calculates the time the 11ad device was in suspend.
Those statistics will help to estimate the power impact
of d3hot feature.

Change-Id: I14dfa206b141a4d2b5585d637fe94b2eed91d2b7
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Git-commit: 262345265e599fe5ccc75ba435147d17df04bfd6
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
Signed-off-by: Maya Erez <merez@codeaurora.org>
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index bcceadb..60ea0ec 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1622,6 +1622,8 @@
 	struct wil6210_priv *wil = file->private_data;
 
 	memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats));
+	wil->suspend_stats.min_suspend_time = ULONG_MAX;
+	wil->suspend_stats.collection_start = ktime_get();
 
 	return len;
 }
@@ -1633,18 +1635,27 @@
 	struct wil6210_priv *wil = file->private_data;
 	static char text[400];
 	int n;
+	unsigned long long stats_collection_time =
+		ktime_to_us(ktime_sub(ktime_get(),
+				      wil->suspend_stats.collection_start));
 
 	n = snprintf(text, sizeof(text),
 		     "Suspend statistics:\n"
 		     "successful suspends:%ld failed suspends:%ld\n"
 		     "successful resumes:%ld failed resumes:%ld\n"
-		     "rejected by host:%ld rejected by device:%ld\n",
+		     "rejected by host:%ld rejected by device:%ld\n"
+		     "total suspend time:%lld min suspend time:%lld\n"
+		     "max suspend time:%lld stats collection time: %lld\n",
 		     wil->suspend_stats.successful_suspends,
 		     wil->suspend_stats.failed_suspends,
 		     wil->suspend_stats.successful_resumes,
 		     wil->suspend_stats.failed_resumes,
 		     wil->suspend_stats.rejected_by_host,
-		     wil->suspend_stats.rejected_by_device);
+		     wil->suspend_stats.rejected_by_device,
+		     wil->suspend_stats.total_suspend_time,
+		     wil->suspend_stats.min_suspend_time,
+		     wil->suspend_stats.max_suspend_time,
+		     stats_collection_time);
 
 	n = min_t(int, n, sizeof(text));
 
@@ -1800,6 +1811,8 @@
 
 	wil6210_debugfs_create_ITR_CNT(wil, dbg);
 
+	wil->suspend_stats.collection_start = ktime_get();
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index aff8b1b..dc62bbd 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -581,6 +581,8 @@
 
 	wil->wakeup_trigger = WMI_WAKEUP_TRIGGER_UCAST |
 			      WMI_WAKEUP_TRIGGER_BCAST;
+	memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats));
+	wil->suspend_stats.min_suspend_time = ULONG_MAX;
 
 	return 0;
 
diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c
index 4548829..820ed17 100644
--- a/drivers/net/wireless/ath/wil6210/pm.c
+++ b/drivers/net/wireless/ath/wil6210/pm.c
@@ -300,6 +300,9 @@
 	wil_dbg_pm(wil, "suspend: %s => %d\n",
 		   is_runtime ? "runtime" : "system", rc);
 
+	if (!rc)
+		wil->suspend_stats.suspend_start_time = ktime_get();
+
 	return rc;
 }
 
@@ -309,6 +312,7 @@
 	struct net_device *ndev = wil_to_ndev(wil);
 	bool keep_radio_on = ndev->flags & IFF_UP &&
 			     wil->keep_radio_on_during_sleep;
+	unsigned long long suspend_time_usec = 0;
 
 	wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
 
@@ -326,8 +330,20 @@
 	else
 		rc = wil_resume_radio_off(wil);
 
+	if (rc)
+		goto out;
+
+	suspend_time_usec =
+		ktime_to_us(ktime_sub(ktime_get(),
+				      wil->suspend_stats.suspend_start_time));
+	wil->suspend_stats.total_suspend_time += suspend_time_usec;
+	if (suspend_time_usec < wil->suspend_stats.min_suspend_time)
+		wil->suspend_stats.min_suspend_time = suspend_time_usec;
+	if (suspend_time_usec > wil->suspend_stats.max_suspend_time)
+		wil->suspend_stats.max_suspend_time = suspend_time_usec;
+
 out:
-	wil_dbg_pm(wil, "resume: %s => %d\n",
-		   is_runtime ? "runtime" : "system", rc);
+	wil_dbg_pm(wil, "resume: %s => %d, suspend time %lld usec\n",
+		   is_runtime ? "runtime" : "system", rc, suspend_time_usec);
 	return rc;
 }
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index eca5685..17d7f19 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -91,6 +91,11 @@
 	unsigned long failed_resumes;
 	unsigned long rejected_by_device;
 	unsigned long rejected_by_host;
+	unsigned long long total_suspend_time;
+	unsigned long long min_suspend_time;
+	unsigned long long max_suspend_time;
+	ktime_t collection_start;
+	ktime_t suspend_start_time;
 };
 
 /* Calculate MAC buffer size for the firmware. It includes all overhead,