xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/sm_engine/src/wlan_sm_engine_dbg.c (revision 8cfe6b10058a04cafb17eed051f2ddf11bee8931)
1 /*
2  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: Implements general SM debug framework
20  */
21 #include <wlan_sm_engine.h>
22 #include <wlan_sm_engine_dbg.h>
23 
24 void wlan_sm_save_history(struct wlan_sm *sm,
25 			  enum wlan_sm_trace_type trace_type,
26 			  uint8_t initial_state, uint8_t final_state,
27 			  uint16_t event_type)
28 {
29 	struct wlan_sm_history *p_sm_history = &sm->history;
30 	struct wlan_sm_history_info *p_memento;
31 
32 	/*
33 	 * History saved in circular buffer.
34 	 * Save a pointer to next write location and increment pointer.
35 	 */
36 	qdf_spin_lock_bh(&p_sm_history->sm_history_lock);
37 	p_memento = &p_sm_history->data[p_sm_history->index];
38 	p_sm_history->index++;
39 
40 	p_sm_history->index %= WLAN_SM_ENGINE_HISTORY_SIZE;
41 
42 	qdf_spin_unlock_bh(&p_sm_history->sm_history_lock);
43 
44 	qdf_mem_zero(p_memento, sizeof(*p_memento));
45 	p_memento->trace_type = trace_type;
46 	p_memento->initial_state = initial_state;
47 	p_memento->final_state = final_state;
48 	p_memento->event_type = event_type;
49 	p_memento->time = qdf_get_log_timestamp();
50 }
51 
52 void wlan_sm_history_init(struct wlan_sm *sm)
53 {
54 	qdf_mem_zero(&sm->history, sizeof(struct wlan_sm_history));
55 	qdf_spinlock_create(&sm->history.sm_history_lock);
56 }
57 
58 void wlan_sm_history_delete(struct wlan_sm *sm)
59 {
60 	qdf_spinlock_destroy(&sm->history.sm_history_lock);
61 }
62 
63 static void wlan_sm_print_history_entry(struct wlan_sm *sm,
64 					struct wlan_sm_history_info *ent,
65 					uint16_t i)
66 {
67 	const char *event_name = NULL;
68 
69 	if (sm->event_names) {
70 		if (ent->event_type < sm->num_event_names)
71 			event_name = sm->event_names[ent->event_type];
72 
73 		if (!ent->trace_type)
74 			return;
75 
76 		sm_engine_nofl_err(
77 			"| 0x%016llx |%6d |%11d |%23s[%3d] |%19s[%2d] |%19s[%2d] |",
78 			ent->time, i, ent->trace_type,
79 			event_name ? event_name : "UNKNOWN_EVENT",
80 			ent->event_type,
81 			sm->state_info[ent->initial_state].name,
82 			ent->initial_state,
83 			sm->state_info[ent->final_state].name,
84 			ent->final_state);
85 	} else {
86 		sm_engine_nofl_err(
87 			"| 0x%016llx |%6d |%11d |%28d |%19s[%2d] |%19s[%2d] |",
88 			ent->time, i, ent->trace_type,
89 			ent->event_type,
90 			sm->state_info[ent->initial_state].name,
91 			ent->initial_state,
92 			sm->state_info[ent->final_state].name,
93 			ent->final_state);
94 	}
95 }
96 
97 void wlan_sm_print_history(struct wlan_sm *sm)
98 {
99 	struct wlan_sm_history *p_sm_history = &sm->history;
100 	uint8_t i;
101 	uint8_t idx;
102 
103 	/*
104 	 * History saved in circular buffer.
105 	 * Save a pointer to next write location and increment pointer.
106 	 */
107 	qdf_spin_lock_bh(&p_sm_history->sm_history_lock);
108 
109 	sm_engine_nofl_err("|%19s |%6s |%11s |%28s |%23s |%23s |", "Time",
110 			   "Index", "Trace Type", "Event",
111 			   "Initial State", "Final State");
112 
113 	for (i = 0; i < WLAN_SM_ENGINE_HISTORY_SIZE; i++) {
114 		idx = (p_sm_history->index + i) % WLAN_SM_ENGINE_HISTORY_SIZE;
115 		wlan_sm_print_history_entry(
116 			sm, &p_sm_history->data[idx], idx);
117 	}
118 
119 	qdf_spin_unlock_bh(&p_sm_history->sm_history_lock);
120 }
121 
122 #if SM_HIST_DEBUGFS_SUPPORT
123 static void wlan_sm_print_fs_history_entry(struct wlan_sm *sm,
124 					   struct wlan_sm_history_info *ent,
125 					   uint16_t i, qdf_debugfs_file_t m)
126 {
127 	const char *event_name = NULL;
128 
129 	if (sm->event_names) {
130 		if (ent->event_type < sm->num_event_names)
131 			event_name = sm->event_names[ent->event_type];
132 
133 		if (!ent->trace_type)
134 			return;
135 
136 		qdf_debugfs_printf(
137 			m, "| 0x%016llx |%6d |%11d |%23s[%3d] |%19s[%2d] |%19s[%2d] |\n",
138 			ent->time, i, ent->trace_type,
139 			event_name ? event_name : "UNKNOWN_EVENT",
140 			ent->event_type,
141 			sm->state_info[ent->initial_state].name,
142 			ent->initial_state,
143 			sm->state_info[ent->final_state].name,
144 			ent->final_state);
145 	} else {
146 		qdf_debugfs_printf(
147 			m, "| 0x%016llx |%6d |%11d |%28d |%19s[%2d] |%19s[%2d] |\n",
148 			ent->time, i, ent->trace_type,
149 			ent->event_type,
150 			sm->state_info[ent->initial_state].name,
151 			ent->initial_state,
152 			sm->state_info[ent->final_state].name,
153 			ent->final_state);
154 	}
155 }
156 
157 void wlan_sm_print_fs_history(struct wlan_sm *sm, qdf_debugfs_file_t m)
158 {
159 	struct wlan_sm_history *p_sm_history = &sm->history;
160 	uint8_t i;
161 	uint8_t idx;
162 
163 	/*
164 	 * History saved in circular buffer.
165 	 * Save a pointer to next write location and increment pointer.
166 	 */
167 	qdf_spin_lock_bh(&p_sm_history->sm_history_lock);
168 	qdf_debugfs_printf(m, "|%19s |%6s |%11s |%28s |%23s |%23s |\n", "Time",
169 			   "Index", "Trace Type", "Event",
170 			   "Initial State", "Final State");
171 
172 	for (i = 0; i < WLAN_SM_ENGINE_HISTORY_SIZE; i++) {
173 		idx = (p_sm_history->index + i) % WLAN_SM_ENGINE_HISTORY_SIZE;
174 		wlan_sm_print_fs_history_entry(sm, &p_sm_history->data[idx],
175 					       idx, m);
176 	}
177 
178 	qdf_spin_unlock_bh(&p_sm_history->sm_history_lock);
179 }
180 #endif
181