xref: /wlan-dirver/qca-wifi-host-cmn/utils/host_diag_log/src/host_diag_log.c (revision dd4dc88b837a295134aa9869114a2efee0f4894b)
1 /*
2  * Copyright (c) 2014-2019 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 /*============================================================================
20    FILE:         host_diag_log.c
21 
22    OVERVIEW:     This source file contains definitions for WLAN UTIL diag APIs
23 
24    DEPENDENCIES:
25    ============================================================================*/
26 
27 #include "qdf_types.h"
28 #include "i_host_diag_core_log.h"
29 #include "host_diag_core_event.h"
30 #include "wlan_nlink_common.h"
31 #include "cds_sched.h"
32 #include "wlan_ptt_sock_svc.h"
33 #include "wlan_nlink_srv.h"
34 #include "cds_api.h"
35 #include "wlan_ps_wow_diag.h"
36 #include "qdf_str.h"
37 
38 #define PTT_MSG_DIAG_CMDS_TYPE   (0x5050)
39 
40 #define DIAG_TYPE_LOGS   (1)
41 #define DIAG_TYPE_EVENTS (2)
42 
43 #define DIAG_SWAP16(A) ((((uint16_t)(A) & 0xff00) >> 8) | (((uint16_t)(A) & 0x00ff) << 8))
44 
45 typedef struct event_report_s {
46 	uint32_t diag_type;
47 	uint16_t event_id;
48 	uint16_t length;
49 } event_report_t;
50 
51 /**---------------------------------------------------------------------------
52 
53    \brief host_diag_log_set_code() -
54 
55    This function sets the logging code in the given log record.
56 
57    \param  - ptr - Pointer to the log header type.
58 		- code - log code.
59    \return - None
60 
61    --------------------------------------------------------------------------*/
62 
63 void host_diag_log_set_code(void *ptr, uint16_t code)
64 {
65 	if (ptr) {
66 		/* All log packets are required to start with 'log_header_type' */
67 		((log_hdr_type *) ptr)->code = code;
68 	}
69 }
70 
71 /**---------------------------------------------------------------------------
72 
73    \brief host_diag_log_set_length() -
74 
75    This function sets the length field in the given log record.
76 
77    \param  - ptr - Pointer to the log header type.
78 		- length - log length.
79 
80    \return - None
81 
82    --------------------------------------------------------------------------*/
83 
84 void host_diag_log_set_length(void *ptr, uint16_t length)
85 {
86 	if (ptr) {
87 		/* All log packets are required to start with 'log_header_type' */
88 		((log_hdr_type *) ptr)->len = (uint16_t) length;
89 	}
90 }
91 
92 /**---------------------------------------------------------------------------
93 
94    \brief host_diag_log_submit() -
95 
96    This function sends the log data to the ptt socket app only if it is registered with the driver.
97 
98    \param  - ptr - Pointer to the log header type.
99 
100    \return - None
101 
102    --------------------------------------------------------------------------*/
103 
104 void host_diag_log_submit(void *plog_hdr_ptr)
105 {
106 	log_hdr_type *pHdr = (log_hdr_type *) plog_hdr_ptr;
107 	tAniHdr *wmsg = NULL;
108 	uint8_t *pBuf;
109 	uint16_t data_len;
110 	uint16_t total_len;
111 
112 	if (cds_is_load_or_unload_in_progress()) {
113 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
114 			  "%s: Unloading/Loading in Progress. Ignore!!!",
115 			  __func__);
116 		return;
117 	}
118 
119 	if (nl_srv_is_initialized() != 0)
120 		return;
121 
122 	if (cds_is_multicast_logging()) {
123 		data_len = pHdr->len;
124 
125 		total_len = sizeof(tAniHdr) + sizeof(uint32_t) + data_len;
126 
127 		pBuf = (uint8_t *) qdf_mem_malloc(total_len);
128 
129 		if (!pBuf)
130 			return;
131 
132 		wmsg = (tAniHdr *) pBuf;
133 		wmsg->type = PTT_MSG_DIAG_CMDS_TYPE;
134 		wmsg->length = total_len;
135 		wmsg->length = DIAG_SWAP16(wmsg->length);
136 		pBuf += sizeof(tAniHdr);
137 
138 		/*  Diag Type events or log */
139 		*(uint32_t *) pBuf = DIAG_TYPE_LOGS;
140 		pBuf += sizeof(uint32_t);
141 
142 		memcpy(pBuf, pHdr, data_len);
143 		ptt_sock_send_msg_to_app (wmsg, 0, ANI_NL_MSG_PUMAC,
144 			INVALID_PID);
145 		qdf_mem_free((void *)wmsg);
146 	}
147 	return;
148 }
149 
150 /**
151  * host_diag_log_wlock() - This function is used to send wake lock diag events
152  * @reason: Reason why the wakelock was taken or released
153  * @wake_lock_name: Function in which the wakelock was taken or released
154  * @timeout: Timeout value in case of timed wakelocks
155  * @status: Status field indicating whether the wake lock was taken/released
156  *
157  * This function is used to send wake lock diag events to user space
158  *
159  * Return: None
160  *
161  */
162 void host_diag_log_wlock(uint32_t reason, const char *wake_lock_name,
163 		uint32_t timeout, uint32_t status)
164 {
165 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
166 			struct host_event_wlan_wake_lock);
167 
168 	if ((nl_srv_is_initialized() != 0) ||
169 	    (cds_is_wakelock_enabled() == false))
170 		return;
171 
172 	wlan_diag_event.status = status;
173 	wlan_diag_event.reason = reason;
174 	wlan_diag_event.timeout = timeout;
175 	wlan_diag_event.name_len = strlen(wake_lock_name);
176 	strlcpy(&wlan_diag_event.name[0],
177 			wake_lock_name,
178 			wlan_diag_event.name_len+1);
179 
180 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_WAKE_LOCK);
181 }
182 
183 /**---------------------------------------------------------------------------
184 
185    \brief host_diag_event_report_payload() -
186 
187    This function sends the event data to the ptt socket app only if it is
188    registered with the driver.
189 
190    \param  - ptr - Pointer to the log header type.
191 
192    \return - None
193 
194    --------------------------------------------------------------------------*/
195 
196 void host_diag_event_report_payload(uint16_t event_Id, uint16_t length,
197 				    void *pPayload)
198 {
199 	tAniHdr *wmsg = NULL;
200 	uint8_t *pBuf;
201 	event_report_t *pEvent_report;
202 	uint16_t total_len;
203 
204 	if (cds_is_load_or_unload_in_progress()) {
205 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
206 			  "%s: Unloading/Loading in Progress. Ignore!!!",
207 			  __func__);
208 		return;
209 	}
210 
211 	if (nl_srv_is_initialized() != 0)
212 		return;
213 
214 	if (cds_is_multicast_logging()) {
215 		total_len = sizeof(tAniHdr) + sizeof(event_report_t) + length;
216 
217 		pBuf = (uint8_t *) qdf_mem_malloc(total_len);
218 
219 		if (!pBuf)
220 			return;
221 
222 		wmsg = (tAniHdr *) pBuf;
223 		wmsg->type = PTT_MSG_DIAG_CMDS_TYPE;
224 		wmsg->length = total_len;
225 		wmsg->length = DIAG_SWAP16(wmsg->length);
226 		pBuf += sizeof(tAniHdr);
227 
228 		pEvent_report = (event_report_t *) pBuf;
229 		pEvent_report->diag_type = DIAG_TYPE_EVENTS;
230 		pEvent_report->event_id = event_Id;
231 		pEvent_report->length = length;
232 
233 		pBuf += sizeof(event_report_t);
234 
235 		memcpy(pBuf, pPayload, length);
236 
237 		if (ptt_sock_send_msg_to_app
238 			    (wmsg, 0, ANI_NL_MSG_PUMAC, INVALID_PID) < 0) {
239 			QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
240 				  "Ptt Socket error sending message to the app!!");
241 			qdf_mem_free((void *)wmsg);
242 			return;
243 		}
244 
245 		qdf_mem_free((void *)wmsg);
246 	}
247 
248 	return;
249 
250 }
251 
252 /**
253  * host_log_low_resource_failure() - This function is used to send low
254  * resource failure event
255  * @event_sub_type: Reason why the failure was observed
256  *
257  * This function is used to send low resource failure events to user space
258  *
259  * Return: None
260  *
261  */
262 void host_log_low_resource_failure(uint8_t event_sub_type)
263 {
264 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
265 			struct host_event_wlan_low_resource_failure);
266 
267 	wlan_diag_event.event_sub_type = event_sub_type;
268 
269 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event,
270 					EVENT_WLAN_LOW_RESOURCE_FAILURE);
271 }
272 
273 void host_log_rsn_info(uint8_t *ucast_cipher, uint8_t *mcast_cipher,
274 		       uint8_t *akm_suite, uint8_t *group_mgmt)
275 {
276 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
277 				 struct event_wlan_csr_rsn_info);
278 
279 	qdf_mem_copy(wlan_diag_event.ucast_cipher, ucast_cipher,
280 		     RSN_OUI_SIZE);
281 	qdf_mem_copy(wlan_diag_event.mcast_cipher, mcast_cipher,
282 		     RSN_OUI_SIZE);
283 	qdf_mem_copy(wlan_diag_event.akm_suite, akm_suite,
284 		     RSN_OUI_SIZE);
285 	qdf_mem_copy(wlan_diag_event.group_mgmt, group_mgmt,
286 		     RSN_OUI_SIZE);
287 
288 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event,
289 				    EVENT_WLAN_RSN_INFO);
290 }
291 
292 void
293 host_log_wlan_auth_info(uint16_t auth_algo_num, uint16_t auth_tx_seq_num,
294 			uint16_t auth_status_code)
295 {
296 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event,
297 				 struct event_wlan_lim_auth_info);
298 
299 	wlan_diag_event.auth_algo_num = auth_algo_num;
300 	wlan_diag_event.auth_transaction_seq_num = auth_tx_seq_num;
301 	wlan_diag_event.auth_status_code = auth_status_code;
302 
303 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event,
304 				    EVENT_WLAN_AUTH_INFO);
305 }
306 
307 #ifdef FEATURE_WLAN_DIAG_SUPPORT
308 /**
309  * qdf_wow_wakeup_host_event()- send wow wakeup event
310  * @wow_wakeup_cause: WOW wakeup reason code
311  *
312  * This function sends wow wakeup reason code diag event
313  *
314  * Return: void.
315  */
316 void qdf_wow_wakeup_host_event(uint8_t wow_wakeup_cause)
317 {
318 	WLAN_HOST_DIAG_EVENT_DEF(wowRequest,
319 		host_event_wlan_powersave_wow_payload_type);
320 	qdf_mem_zero(&wowRequest, sizeof(wowRequest));
321 
322 	wowRequest.event_subtype = WLAN_WOW_WAKEUP;
323 	wowRequest.wow_wakeup_cause = wow_wakeup_cause;
324 	WLAN_HOST_DIAG_EVENT_REPORT(&wowRequest,
325 		EVENT_WLAN_POWERSAVE_WOW);
326 }
327 
328 void host_log_acs_req_event(uint8_t *intf, const uint8_t *hw_mode, uint16_t bw,
329 			    uint8_t ht, uint8_t vht, uint16_t chan_start,
330 			    uint16_t chan_end)
331 {
332 	WLAN_HOST_DIAG_EVENT_DEF(acs_req, struct host_event_wlan_acs_req);
333 
334 	qdf_str_lcopy(acs_req.intf, intf, HOST_EVENT_INTF_STR_LEN);
335 	qdf_str_lcopy(acs_req.hw_mode, hw_mode, HOST_EVENT_HW_MODE_STR_LEN);
336 	acs_req.bw = bw;
337 	acs_req.ht = ht;
338 	acs_req.vht = vht;
339 	acs_req.chan_start = chan_start;
340 	acs_req.chan_end = chan_end;
341 
342 	WLAN_HOST_DIAG_EVENT_REPORT(&acs_req, EVENT_WLAN_ACS_REQ);
343 }
344 
345 void host_log_acs_scan_start(uint32_t scan_id, uint8_t vdev_id)
346 {
347 	WLAN_HOST_DIAG_EVENT_DEF(acs_scan_start,
348 				 struct host_event_wlan_acs_scan_start);
349 
350 	acs_scan_start.scan_id = scan_id;
351 	acs_scan_start.vdev_id = vdev_id;
352 
353 	WLAN_HOST_DIAG_EVENT_REPORT(&acs_scan_start,
354 				    EVENT_WLAN_ACS_SCAN_START);
355 }
356 
357 void host_log_acs_scan_done(const uint8_t *status,
358 			    uint8_t vdev_id, uint32_t scan_id)
359 {
360 	WLAN_HOST_DIAG_EVENT_DEF(acs_scan_done,
361 				 struct host_event_wlan_acs_scan_done);
362 
363 	qdf_str_lcopy(acs_scan_done.status, status, HOST_EVENT_STATUS_STR_LEN);
364 	acs_scan_done.vdev_id = vdev_id;
365 	acs_scan_done.scan_id = scan_id;
366 
367 	WLAN_HOST_DIAG_EVENT_REPORT(&acs_scan_done, EVENT_WLAN_ACS_SCAN_DONE);
368 }
369 
370 void host_log_acs_chan_spect_weight(uint16_t chan, uint16_t weight,
371 				    int32_t rssi, uint16_t bss_count)
372 {
373 	WLAN_HOST_DIAG_EVENT_DEF(
374 		acs_chan_spect_weight,
375 		struct host_event_wlan_acs_chan_spectral_weight);
376 
377 	acs_chan_spect_weight.chan = chan;
378 	acs_chan_spect_weight.weight = weight;
379 	acs_chan_spect_weight.rssi = rssi;
380 	acs_chan_spect_weight.bss_count = bss_count;
381 
382 	WLAN_HOST_DIAG_EVENT_REPORT(&acs_chan_spect_weight,
383 				    EVENT_WLAN_ACS_CHANNEL_SPECTRAL_WEIGHT);
384 }
385 
386 void host_log_acs_best_chan(uint16_t chan, uint16_t weight)
387 {
388 	WLAN_HOST_DIAG_EVENT_DEF(acs_best_chan,
389 				 struct host_event_wlan_acs_best_chan);
390 
391 	acs_best_chan.chan = chan;
392 	acs_best_chan.weight = weight;
393 
394 	WLAN_HOST_DIAG_EVENT_REPORT(&acs_best_chan,
395 				    EVENT_WLAN_ACS_BEST_CHANNEL);
396 }
397 
398 #endif
399