1 /*
2  * Copyright (c) 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: qdf_hang_event_notifier
20   * This file provides OS dependent QDF notifier call for hang event
21   */
22 
23 #ifndef QDF_HANG_EVENT_NOTIFIER_H
24 #define QDF_HANG_EVENT_NOTIFIER_H
25 
26 #include <qdf_notifier.h>
27 
28 #define QDF_HANG_EVENT_VERSION "1"
29 /* Max hang event buffer size */
30 #define QDF_HANG_EVENT_DATA_SIZE 390
31 /* Max offset which host can write */
32 #define QDF_WLAN_MAX_HOST_OFFSET 194
33 /* Start of the Firmware Data offset */
34 #define QDF_WLAN_HANG_FW_OFFSET 195
35 
36 /**
37  * enum hang_event_tag - Hang event tag for various modules
38  * @HANG_EVT_TAG_CDS: CDS module hang event tag
39  * @HANG_EVT_TAG_OS_IF: OS interface module hang event tag
40  * @HANG_EVT_TAG_OS_IF_SCAN: scan module hang event tag
41  * @HANG_EVT_TAG_LEGACY_MAC: Legacy mac module hang event tag
42  * @HANG_EVT_TAG_WMI_EVT_HIST: WMI event history hang event tag
43  * @HANG_EVT_TAG_WMI_CMD_HIST: WMI command history hang event tag
44  * @HANG_EVT_TAG_HTC_CREDIT_HIST: HTC credit history hang event tag
45  * @HANG_EVT_TAG_DP_PEER_INFO: DP peer info hang event tag
46  * @HANG_EVT_TAG_CE_INFO: Copy Engine hang event tag
47  * @HANG_EVT_TAG_BUS_INFO: Bus hang event tag
48  */
49 enum hang_event_tag {
50 	HANG_EVT_TAG_CDS,
51 	HANG_EVT_TAG_OS_IF,
52 	HANG_EVT_TAG_OS_IF_SCAN,
53 	HANG_EVT_TAG_LEGACY_MAC,
54 	HANG_EVT_TAG_WMI_EVT_HIST,
55 	HANG_EVT_TAG_WMI_CMD_HIST,
56 	HANG_EVT_TAG_HTC_CREDIT_HIST,
57 	HANG_EVT_TAG_DP_PEER_INFO,
58 	HANG_EVT_TAG_CE_INFO,
59 	HANG_EVT_TAG_BUS_INFO
60 };
61 
62 #define QDF_HANG_EVENT_TLV_HDR_SIZE   (sizeof(uint16_t))
63 
64 #define QDF_HANG_EVT_SET_HDR(tlv_buf, tag, len) \
65 	(((uint16_t *)(tlv_buf))[0]) = (((tag) << 8) | ((len) & 0x000000FF))
66 
67 #define QDF_HANG_GET_STRUCT_TLVLEN(tlv_struct) \
68 	((uint16_t)(sizeof(tlv_struct) - QDF_HANG_EVENT_TLV_HDR_SIZE))
69 
70 /**
71  * struct qdf_notifer_data - Private data for notifier data
72  * @hang_data: Data filled by notifier
73  * @offset: Current offset of the hang data buffer
74  */
75 struct qdf_notifer_data {
76 	uint8_t *hang_data;
77 	unsigned int offset;
78 };
79 
80 #ifdef WLAN_HANG_EVENT
81 /**
82  * qdf_hang_event_register_notifier() - Hang data notifier register
83  * @nb: Notifier block
84  *
85  * This function registers notifier block for the hang data notifier chain
86  * the registered function will be invoked when the hang data notifier call
87  * is invoked.
88  *
89  * Return: QDF_STATUS
90  */
91 QDF_STATUS qdf_hang_event_register_notifier(qdf_notif_block *nb);
92 
93 /**
94  * qdf_hang_event_unregister_notifier() - Hang data notifier unregister
95  * @nb: Notifier block
96  *
97  * This function unregisters notifier block for the hang data notifier chain.
98  *
99  * Return: QDF_STATUS
100  */
101 QDF_STATUS qdf_hang_event_unregister_notifier(qdf_notif_block *nb);
102 
103 /**
104  * qdf_hang_event_notifier_call() - Hang data notifier register
105  * @v: state
106  * @data: Private data for this notifier chain
107  *
108  * This function when invoked will call the functions registered with this
109  * notifier chain.
110  *
111  * Return: QDF_STATUS
112  */
113 QDF_STATUS qdf_hang_event_notifier_call(unsigned long v, void *data);
114 #else
115 static inline
qdf_hang_event_register_notifier(qdf_notif_block * nb)116 QDF_STATUS qdf_hang_event_register_notifier(qdf_notif_block *nb)
117 {
118 	return QDF_STATUS_SUCCESS;
119 }
120 
121 static inline
qdf_hang_event_unregister_notifier(qdf_notif_block * nb)122 QDF_STATUS qdf_hang_event_unregister_notifier(qdf_notif_block *nb)
123 {
124 	return QDF_STATUS_SUCCESS;
125 }
126 
127 static inline
qdf_hang_event_notifier_call(unsigned long v,void * data)128 QDF_STATUS qdf_hang_event_notifier_call(unsigned long v, void *data)
129 {
130 	return QDF_STATUS_SUCCESS;
131 }
132 #endif
133 #endif
134