xref: /wlan-dirver/qca-wifi-host-cmn/htc/htc_credit_history.c (revision 4865edfd190c086bbe2c69aae12a8226f877b91e)
1 /*
2  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "htc_debug.h"
20 #include "htc_internal.h"
21 #include "htc_credit_history.h"
22 #include <qdf_lock.h>
23 
24 struct HTC_CREDIT_HISTORY {
25 	enum htc_credit_exchange_type type;
26 	uint64_t time;
27 	uint32_t tx_credit;
28 	uint32_t htc_tx_queue_depth;
29 };
30 
31 static qdf_spinlock_t g_htc_credit_lock;
32 static uint32_t g_htc_credit_history_idx;
33 static uint32_t g_htc_credit_history_length;
34 static
35 struct HTC_CREDIT_HISTORY htc_credit_history_buffer[HTC_CREDIT_HISTORY_MAX];
36 
37 
38 #ifdef QCA_WIFI_NAPIER_EMULATION
39 #define HTC_EMULATION_DELAY_IN_MS 20
40 /**
41  * htc_add_delay(): Adds a delay in before proceeding, only for emulation
42  *
43  * Return: None
44  */
45 static inline void htc_add_emulation_delay(void)
46 {
47 	qdf_mdelay(HTC_EMULATION_DELAY_IN_MS);
48 }
49 #else
50 static inline void htc_add_emulation_delay(void)
51 {
52 }
53 #endif
54 
55 void htc_credit_history_init(void)
56 {
57 	qdf_spinlock_create(&g_htc_credit_lock);
58 	g_htc_credit_history_idx = 0;
59 	g_htc_credit_history_length = 0;
60 }
61 
62 /**
63  * htc_credit_record() - records tx que state & credit transactions
64  * @type:		type of echange can be HTC_REQUEST_CREDIT
65  *			or HTC_PROCESS_CREDIT_REPORT
66  * @tx_credits:		current number of tx_credits
67  * @htc_tx_queue_depth:	current hct tx queue depth
68  *
69  * This function records the credits and pending commands whenever a command is
70  * sent or credits are returned.  Call this after the credits have been updated
71  * according to the transaction.  Call this before dequeing commands.
72  *
73  * Consider making this function accept an HTC_ENDPOINT and find the current
74  * credits and queue depth itself.
75  *
76  */
77 void htc_credit_record(enum htc_credit_exchange_type type, uint32_t tx_credit,
78 		       uint32_t htc_tx_queue_depth)
79 {
80 	qdf_spin_lock_bh(&g_htc_credit_lock);
81 	if (g_htc_credit_history_idx >= HTC_CREDIT_HISTORY_MAX)
82 		g_htc_credit_history_idx = 0;
83 
84 	htc_credit_history_buffer[g_htc_credit_history_idx].type = type;
85 	htc_credit_history_buffer[g_htc_credit_history_idx].time =
86 		qdf_get_log_timestamp();
87 	htc_credit_history_buffer[g_htc_credit_history_idx].tx_credit =
88 		tx_credit;
89 	htc_credit_history_buffer[g_htc_credit_history_idx].htc_tx_queue_depth =
90 		htc_tx_queue_depth;
91 
92 	g_htc_credit_history_idx++;
93 	g_htc_credit_history_length++;
94 	htc_add_emulation_delay();
95 	qdf_spin_unlock_bh(&g_htc_credit_lock);
96 }
97 
98 void htc_print_credit_history(HTC_HANDLE htc, uint32_t count,
99 			      qdf_abstract_print *print, void *print_priv)
100 {
101 	uint32_t idx;
102 
103 	print(print_priv, "HTC Credit History (count %u)", count);
104 	qdf_spin_lock_bh(&g_htc_credit_lock);
105 
106 	if (count > HTC_CREDIT_HISTORY_MAX)
107 		count = HTC_CREDIT_HISTORY_MAX;
108 	if (count > g_htc_credit_history_length)
109 		count = g_htc_credit_history_length;
110 
111 	/* subtract count from index, and wrap if necessary */
112 	idx = HTC_CREDIT_HISTORY_MAX + g_htc_credit_history_idx - count;
113 	idx %= HTC_CREDIT_HISTORY_MAX;
114 
115 	print(print_priv,
116 	      "Time (seconds)     Type                         Credits    Queue Depth");
117 	while (count) {
118 		struct HTC_CREDIT_HISTORY *hist =
119 						&htc_credit_history_buffer[idx];
120 		uint64_t secs, usecs;
121 
122 		qdf_log_timestamp_to_secs(hist->time, &secs, &usecs);
123 		print(print_priv, "% 8lld.%06lld    %-25s    %-7.d    %d",
124 		      secs,
125 		      usecs,
126 		      htc_credit_exchange_type_str(hist->type),
127 		      hist->tx_credit,
128 		      hist->htc_tx_queue_depth);
129 
130 		--count;
131 		++idx;
132 		if (idx >= HTC_CREDIT_HISTORY_MAX)
133 			idx = 0;
134 	}
135 
136 	qdf_spin_unlock_bh(&g_htc_credit_lock);
137 }
138