Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 1 | /* |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 2 | * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 3 | * |
| 4 | * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| 5 | * |
| 6 | * |
| 7 | * Permission to use, copy, modify, and/or distribute this software for |
| 8 | * any purpose with or without fee is hereby granted, provided that the |
| 9 | * above copyright notice and this permission notice appear in all |
| 10 | * copies. |
| 11 | * |
| 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| 13 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| 14 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| 15 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| 16 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| 17 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| 18 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| 19 | * PERFORMANCE OF THIS SOFTWARE. |
| 20 | */ |
| 21 | |
| 22 | /* |
| 23 | * This file was originally distributed by Qualcomm Atheros, Inc. |
| 24 | * under proprietary terms before Copyright ownership was assigned |
| 25 | * to the Linux Foundation. |
| 26 | */ |
| 27 | |
| 28 | /****************************************************************************** |
| 29 | * wlan_logging_sock_svc.c |
| 30 | * |
| 31 | ******************************************************************************/ |
| 32 | #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE |
Vinay Krishna Eranna | 2c0ac30 | 2014-12-17 15:21:40 +0530 | [diff] [blame] | 33 | #include <linux/rtc.h> |
Vinay Krishna Eranna | 0b11262 | 2014-04-21 20:17:57 +0530 | [diff] [blame] | 34 | #include <vmalloc.h> |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 35 | #include <wlan_nlink_srv.h> |
| 36 | #include <vos_status.h> |
| 37 | #include <vos_trace.h> |
| 38 | #include <wlan_nlink_common.h> |
| 39 | #include <wlan_logging_sock_svc.h> |
| 40 | #include <vos_types.h> |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 41 | #include <kthread.h> |
Rajesh Babu Prathipati | 71e9c44 | 2014-07-01 22:08:29 +0530 | [diff] [blame] | 42 | #include "vos_memory.h" |
Sushant Kaushik | 1ede332 | 2015-07-07 17:26:50 +0530 | [diff] [blame] | 43 | #include <linux/ratelimit.h> |
Ratnam Rachuri | c798dbe | 2015-07-17 11:19:44 +0530 | [diff] [blame] | 44 | #include <asm/arch_timer.h> |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 45 | |
| 46 | #define LOGGING_TRACE(level, args...) \ |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 47 | VOS_TRACE(VOS_MODULE_ID_SVC, level, ## args) |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 48 | |
| 49 | /* Global variables */ |
| 50 | |
| 51 | #define ANI_NL_MSG_LOG_TYPE 89 |
Vinay Krishna Eranna | 8382e0e | 2014-06-18 19:19:58 +0530 | [diff] [blame] | 52 | #define ANI_NL_MSG_READY_IND_TYPE 90 |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 53 | #define ANI_NL_MSG_LOG_PKT_TYPE 91 |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 54 | #define ANI_NL_MSG_FW_LOG_PKT_TYPE 92 |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 55 | #define INVALID_PID -1 |
| 56 | |
| 57 | #define MAX_LOGMSG_LENGTH 4096 |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 58 | #define LOGGER_MGMT_DATA_PKT_POST_MASK 0x001 |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 59 | #define HOST_LOG_POST_MASK 0x002 |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 60 | #define LOGGER_FW_LOG_PKT_POST_MASK 0x003 |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 61 | #define LOGGER_FATAL_EVENT_POST_MASK 0x004 |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 62 | |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 63 | #define LOGGER_MAX_DATA_MGMT_PKT_Q_LEN (8) |
| 64 | #define LOGGER_MAX_FW_LOG_PKT_Q_LEN (16) |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 65 | |
Sushant Kaushik | 1ede332 | 2015-07-07 17:26:50 +0530 | [diff] [blame] | 66 | #define NL_BDCAST_RATELIMIT_INTERVAL (5*HZ) |
Sushant Kaushik | 8ddaa38 | 2015-06-23 12:17:25 +0530 | [diff] [blame] | 67 | #define NL_BDCAST_RATELIMIT_BURST 1 |
| 68 | |
Ratnam Rachuri | c798dbe | 2015-07-17 11:19:44 +0530 | [diff] [blame] | 69 | /* Qtimer Frequency */ |
| 70 | #define QTIMER_FREQ 19200000 |
| 71 | |
Sushant Kaushik | 8ddaa38 | 2015-06-23 12:17:25 +0530 | [diff] [blame] | 72 | static DEFINE_RATELIMIT_STATE(errCnt, \ |
| 73 | NL_BDCAST_RATELIMIT_INTERVAL, \ |
| 74 | NL_BDCAST_RATELIMIT_BURST); |
| 75 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 76 | struct log_msg { |
| 77 | struct list_head node; |
| 78 | unsigned int radio; |
| 79 | unsigned int index; |
| 80 | /* indicates the current filled log length in logbuf */ |
| 81 | unsigned int filled_length; |
| 82 | /* |
| 83 | * Buf to hold the log msg |
| 84 | * tAniHdr + log |
| 85 | */ |
| 86 | char logbuf[MAX_LOGMSG_LENGTH]; |
| 87 | }; |
| 88 | |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 89 | struct logger_log_complete { |
| 90 | uint32_t is_fatal; |
| 91 | uint32_t indicator; |
| 92 | uint32_t reason_code; |
| 93 | bool is_report_in_progress; |
| 94 | bool is_flush_complete; |
| 95 | }; |
| 96 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 97 | struct wlan_logging { |
| 98 | /* Log Fatal and ERROR to console */ |
| 99 | bool log_fe_to_console; |
| 100 | /* Number of buffers to be used for logging */ |
| 101 | int num_buf; |
| 102 | /* Lock to synchronize access to shared logging resource */ |
| 103 | spinlock_t spin_lock; |
| 104 | /* Holds the free node which can be used for filling logs */ |
| 105 | struct list_head free_list; |
| 106 | /* Holds the filled nodes which needs to be indicated to APP */ |
| 107 | struct list_head filled_list; |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 108 | /* Points to head of logger pkt queue */ |
| 109 | vos_pkt_t *data_mgmt_pkt_queue; |
| 110 | /* Holds number of pkts in vos pkt queue */ |
| 111 | unsigned int data_mgmt_pkt_qcnt; |
| 112 | /* Lock to synchronize of queue/dequeue of pkts in logger pkt queue */ |
| 113 | spinlock_t data_mgmt_pkt_lock; |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 114 | /* Points to head of logger fw log pkt queue */ |
| 115 | vos_pkt_t *fw_log_pkt_queue; |
| 116 | /* Holds number of pkts in fw log vos pkt queue */ |
| 117 | unsigned int fw_log_pkt_qcnt; |
| 118 | /* Lock to synchronize of queue/dequeue of pkts in fw log pkt queue */ |
| 119 | spinlock_t fw_log_pkt_lock; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 120 | /* Wait queue for Logger thread */ |
| 121 | wait_queue_head_t wait_queue; |
| 122 | /* Logger thread */ |
| 123 | struct task_struct *thread; |
| 124 | /* Logging thread sets this variable on exit */ |
| 125 | struct completion shutdown_comp; |
| 126 | /* Indicates to logger thread to exit */ |
| 127 | bool exit; |
| 128 | /* Holds number of dropped logs*/ |
| 129 | unsigned int drop_count; |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 130 | /* Holds number of dropped vos pkts*/ |
| 131 | unsigned int pkt_drop_cnt; |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 132 | /* Holds number of dropped fw log vos pkts*/ |
| 133 | unsigned int fw_log_pkt_drop_cnt; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 134 | /* current logbuf to which the log will be filled to */ |
| 135 | struct log_msg *pcur_node; |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 136 | /* Event flag used for wakeup and post indication*/ |
| 137 | unsigned long event_flag; |
| 138 | /* Indicates logger thread is activated */ |
| 139 | bool is_active; |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 140 | /* data structure for log complete event*/ |
| 141 | struct logger_log_complete log_complete; |
| 142 | spinlock_t bug_report_lock; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 143 | }; |
| 144 | |
| 145 | static struct wlan_logging gwlan_logging; |
| 146 | static struct log_msg *gplog_msg; |
| 147 | |
| 148 | /* PID of the APP to log the message */ |
| 149 | static int gapp_pid = INVALID_PID; |
Sushant Kaushik | 9cb1c9c | 2015-06-23 11:57:10 +0530 | [diff] [blame] | 150 | static char wlan_logging_ready[] = "WLAN LOGGING READY"; |
| 151 | |
| 152 | /* |
| 153 | * Broadcast Logging service ready indication to any Logging application |
| 154 | * Each netlink message will have a message of type tAniMsgHdr inside. |
| 155 | */ |
| 156 | void wlan_logging_srv_nl_ready_indication(void) |
| 157 | { |
| 158 | struct sk_buff *skb = NULL; |
| 159 | struct nlmsghdr *nlh; |
| 160 | tAniNlHdr *wnl = NULL; |
| 161 | int payload_len; |
| 162 | int err; |
| 163 | static int rate_limit; |
| 164 | |
| 165 | payload_len = sizeof(tAniHdr) + sizeof(wlan_logging_ready) + |
| 166 | sizeof(wnl->radio); |
| 167 | skb = dev_alloc_skb(NLMSG_SPACE(payload_len)); |
| 168 | if (NULL == skb) { |
| 169 | if (!rate_limit) { |
| 170 | LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, |
| 171 | "NLINK: skb alloc fail %s", __func__); |
| 172 | } |
| 173 | rate_limit = 1; |
| 174 | return; |
| 175 | } |
| 176 | rate_limit = 0; |
| 177 | |
| 178 | nlh = nlmsg_put(skb, 0, 0, ANI_NL_MSG_LOG, payload_len, |
| 179 | NLM_F_REQUEST); |
| 180 | if (NULL == nlh) { |
| 181 | LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, |
| 182 | "%s: nlmsg_put() failed for msg size[%d]", |
| 183 | __func__, payload_len); |
| 184 | kfree_skb(skb); |
| 185 | return; |
| 186 | } |
| 187 | |
| 188 | wnl = (tAniNlHdr *) nlh; |
| 189 | wnl->radio = 0; |
| 190 | wnl->wmsg.type = ANI_NL_MSG_READY_IND_TYPE; |
| 191 | wnl->wmsg.length = sizeof(wlan_logging_ready); |
| 192 | memcpy((char*)&wnl->wmsg + sizeof(tAniHdr), |
| 193 | wlan_logging_ready, |
| 194 | sizeof(wlan_logging_ready)); |
| 195 | |
| 196 | /* sender is in group 1<<0 */ |
| 197 | NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; |
| 198 | |
| 199 | /*multicast the message to all listening processes*/ |
| 200 | err = nl_srv_bcast(skb); |
| 201 | if (err) { |
| 202 | LOGGING_TRACE(VOS_TRACE_LEVEL_INFO_LOW, |
| 203 | "NLINK: Ready Indication Send Fail %s, err %d", |
| 204 | __func__, err); |
| 205 | } |
| 206 | return; |
| 207 | } |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 208 | |
| 209 | /* Utility function to send a netlink message to an application |
| 210 | * in user space |
| 211 | */ |
| 212 | static int wlan_send_sock_msg_to_app(tAniHdr *wmsg, int radio, |
| 213 | int src_mod, int pid) |
| 214 | { |
| 215 | int err = -1; |
| 216 | int payload_len; |
| 217 | int tot_msg_len; |
| 218 | tAniNlHdr *wnl = NULL; |
| 219 | struct sk_buff *skb; |
| 220 | struct nlmsghdr *nlh; |
Vinay Krishna Eranna | b4c6a42 | 2015-03-20 18:33:47 +0530 | [diff] [blame] | 221 | int wmsg_length = wmsg->length; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 222 | static int nlmsg_seq; |
| 223 | |
| 224 | if (radio < 0 || radio > ANI_MAX_RADIOS) { |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 225 | pr_err("%s: invalid radio id [%d]", |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 226 | __func__, radio); |
| 227 | return -EINVAL; |
| 228 | } |
| 229 | |
| 230 | payload_len = wmsg_length + sizeof(wnl->radio); |
| 231 | tot_msg_len = NLMSG_SPACE(payload_len); |
| 232 | skb = dev_alloc_skb(tot_msg_len); |
| 233 | if (skb == NULL) { |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 234 | pr_err("%s: dev_alloc_skb() failed for msg size[%d]", |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 235 | __func__, tot_msg_len); |
| 236 | return -ENOMEM; |
| 237 | } |
| 238 | nlh = nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, |
| 239 | NLM_F_REQUEST); |
| 240 | if (NULL == nlh) { |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 241 | pr_err("%s: nlmsg_put() failed for msg size[%d]", |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 242 | __func__, tot_msg_len); |
| 243 | kfree_skb(skb); |
| 244 | return -ENOMEM; |
| 245 | } |
| 246 | |
| 247 | wnl = (tAniNlHdr *) nlh; |
| 248 | wnl->radio = radio; |
Rajesh Babu Prathipati | 71e9c44 | 2014-07-01 22:08:29 +0530 | [diff] [blame] | 249 | vos_mem_copy(&wnl->wmsg, wmsg, wmsg_length); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 250 | |
| 251 | err = nl_srv_ucast(skb, pid, MSG_DONTWAIT); |
Vinay Krishna Eranna | 8147e70 | 2015-03-06 17:43:41 +0530 | [diff] [blame] | 252 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 253 | return err; |
| 254 | } |
| 255 | |
| 256 | static void set_default_logtoapp_log_level(void) |
| 257 | { |
| 258 | vos_trace_setValue(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ALL, VOS_TRUE); |
| 259 | vos_trace_setValue(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ALL, VOS_TRUE); |
| 260 | vos_trace_setValue(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ALL, VOS_TRUE); |
| 261 | vos_trace_setValue(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ALL, VOS_TRUE); |
| 262 | vos_trace_setValue(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ALL, VOS_TRUE); |
| 263 | vos_trace_setValue(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ALL, |
| 264 | VOS_TRUE); |
| 265 | vos_trace_setValue(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ALL, VOS_TRUE); |
Kaushik, Sushant | ac4fa6c | 2014-12-10 17:07:41 +0530 | [diff] [blame] | 266 | vos_trace_setValue(VOS_MODULE_ID_PMC, VOS_TRACE_LEVEL_ALL, VOS_TRUE); |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 267 | vos_trace_setValue(VOS_MODULE_ID_SVC, VOS_TRACE_LEVEL_ALL, VOS_TRUE); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 268 | } |
| 269 | |
| 270 | static void clear_default_logtoapp_log_level(void) |
| 271 | { |
| 272 | int module; |
| 273 | |
| 274 | for (module = 0; module < VOS_MODULE_ID_MAX; module++) { |
| 275 | vos_trace_setValue(module, VOS_TRACE_LEVEL_NONE, |
| 276 | VOS_FALSE); |
| 277 | vos_trace_setValue(module, VOS_TRACE_LEVEL_FATAL, |
| 278 | VOS_TRUE); |
| 279 | vos_trace_setValue(module, VOS_TRACE_LEVEL_ERROR, |
| 280 | VOS_TRUE); |
| 281 | } |
| 282 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 283 | vos_trace_setValue(VOS_MODULE_ID_RSV4, VOS_TRACE_LEVEL_NONE, |
| 284 | VOS_FALSE); |
| 285 | } |
| 286 | |
| 287 | /* Need to call this with spin_lock acquired */ |
| 288 | static int wlan_queue_logmsg_for_app(void) |
| 289 | { |
| 290 | char *ptr; |
| 291 | int ret = 0; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 292 | ptr = &gwlan_logging.pcur_node->logbuf[sizeof(tAniHdr)]; |
| 293 | ptr[gwlan_logging.pcur_node->filled_length] = '\0'; |
| 294 | |
| 295 | *(unsigned short *)(gwlan_logging.pcur_node->logbuf) = |
| 296 | ANI_NL_MSG_LOG_TYPE; |
| 297 | *(unsigned short *)(gwlan_logging.pcur_node->logbuf + 2) = |
| 298 | gwlan_logging.pcur_node->filled_length; |
| 299 | list_add_tail(&gwlan_logging.pcur_node->node, |
| 300 | &gwlan_logging.filled_list); |
| 301 | |
| 302 | if (!list_empty(&gwlan_logging.free_list)) { |
| 303 | /* Get buffer from free list */ |
| 304 | gwlan_logging.pcur_node = |
| 305 | (struct log_msg *)(gwlan_logging.free_list.next); |
| 306 | list_del_init(gwlan_logging.free_list.next); |
| 307 | } else if (!list_empty(&gwlan_logging.filled_list)) { |
| 308 | /* Get buffer from filled list */ |
| 309 | /* This condition will drop the packet from being |
| 310 | * indicated to app |
| 311 | */ |
| 312 | gwlan_logging.pcur_node = |
| 313 | (struct log_msg *)(gwlan_logging.filled_list.next); |
Vinay Krishna Eranna | c253297 | 2014-06-26 22:25:19 +0530 | [diff] [blame] | 314 | ++gwlan_logging.drop_count; |
Sushant Kaushik | 20a9820 | 2014-08-14 16:07:49 +0530 | [diff] [blame] | 315 | /* print every 64th drop count */ |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 316 | if (vos_is_multicast_logging() && |
| 317 | (!(gwlan_logging.drop_count % 0x40))) { |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 318 | pr_err("%s: drop_count = %u index = %d filled_length = %d\n", |
Vinay Krishna Eranna | c253297 | 2014-06-26 22:25:19 +0530 | [diff] [blame] | 319 | __func__, gwlan_logging.drop_count, |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 320 | gwlan_logging.pcur_node->index, |
| 321 | gwlan_logging.pcur_node->filled_length); |
| 322 | } |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 323 | list_del_init(gwlan_logging.filled_list.next); |
| 324 | ret = 1; |
| 325 | } |
| 326 | |
| 327 | /* Reset the current node values */ |
| 328 | gwlan_logging.pcur_node->filled_length = 0; |
| 329 | return ret; |
| 330 | } |
| 331 | |
| 332 | |
| 333 | int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length) |
| 334 | { |
| 335 | /* Add the current time stamp */ |
| 336 | char *ptr; |
Ratnam Rachuri | c798dbe | 2015-07-17 11:19:44 +0530 | [diff] [blame] | 337 | char tbuf[100]; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 338 | int tlen; |
| 339 | int total_log_len; |
| 340 | unsigned int *pfilled_length; |
| 341 | bool wake_up_thread = false; |
Pradeep Kumar Goudagunta | 8526f83 | 2014-04-17 14:56:09 +0530 | [diff] [blame] | 342 | unsigned long flags; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 343 | |
Ratnam Rachuri | 3119f8a | 2015-07-23 14:55:21 +0530 | [diff] [blame] | 344 | struct timeval tv; |
| 345 | struct rtc_time tm; |
Vinay Krishna Eranna | 2c0ac30 | 2014-12-17 15:21:40 +0530 | [diff] [blame] | 346 | unsigned long local_time; |
Ratnam Rachuri | c798dbe | 2015-07-17 11:19:44 +0530 | [diff] [blame] | 347 | u64 qtimer_ticks; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 348 | |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 349 | if (!vos_is_multicast_logging()) { |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 350 | /* |
| 351 | * This is to make sure that we print the logs to kmsg console |
| 352 | * when no logger app is running. This is also needed to |
| 353 | * log the initial messages during loading of driver where even |
| 354 | * if app is running it will not be able to |
| 355 | * register with driver immediately and start logging all the |
| 356 | * messages. |
| 357 | */ |
Vinay Krishna Eranna | 8233736 | 2014-09-06 18:19:03 +0530 | [diff] [blame] | 358 | pr_err("%s\n", to_be_sent); |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 359 | } else { |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 360 | |
Vinay Krishna Eranna | 2c0ac30 | 2014-12-17 15:21:40 +0530 | [diff] [blame] | 361 | /* Format the Log time [hr:min:sec.microsec] */ |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 362 | do_gettimeofday(&tv); |
Vinay Krishna Eranna | 2c0ac30 | 2014-12-17 15:21:40 +0530 | [diff] [blame] | 363 | |
| 364 | /* Convert rtc to local time */ |
| 365 | local_time = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); |
| 366 | rtc_time_to_tm(local_time, &tm); |
Ratnam Rachuri | c798dbe | 2015-07-17 11:19:44 +0530 | [diff] [blame] | 367 | /* Firmware Time Stamp */ |
| 368 | qtimer_ticks = arch_counter_get_cntpct(); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 369 | |
Ratnam Rachuri | 3119f8a | 2015-07-23 14:55:21 +0530 | [diff] [blame] | 370 | tlen = snprintf(tbuf, sizeof(tbuf), "[%02d:%02d:%02d.%06lu] [%016llX]" |
| 371 | " [%s] ", tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec, |
| 372 | qtimer_ticks, current->comm); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 373 | /* 1+1 indicate '\n'+'\0' */ |
| 374 | total_log_len = length + tlen + 1 + 1; |
| 375 | |
Pradeep Kumar Goudagunta | 8526f83 | 2014-04-17 14:56:09 +0530 | [diff] [blame] | 376 | spin_lock_irqsave(&gwlan_logging.spin_lock, flags); |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 377 | |
c_hpothu | 1418175 | 2014-12-10 11:52:09 +0530 | [diff] [blame] | 378 | // wlan logging svc resources are not yet initialized |
| 379 | if (!gwlan_logging.pcur_node) { |
| 380 | spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); |
| 381 | return -EIO; |
| 382 | } |
| 383 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 384 | pfilled_length = &gwlan_logging.pcur_node->filled_length; |
| 385 | |
| 386 | /* Check if we can accomodate more log into current node/buffer */ |
| 387 | if ((MAX_LOGMSG_LENGTH - (*pfilled_length + sizeof(tAniNlHdr))) < |
| 388 | total_log_len) { |
| 389 | wake_up_thread = true; |
| 390 | wlan_queue_logmsg_for_app(); |
| 391 | pfilled_length = &gwlan_logging.pcur_node->filled_length; |
| 392 | } |
| 393 | |
| 394 | ptr = &gwlan_logging.pcur_node->logbuf[sizeof(tAniHdr)]; |
| 395 | |
| 396 | /* Assumption here is that we receive logs which is always less than |
| 397 | * MAX_LOGMSG_LENGTH, where we can accomodate the |
| 398 | * tAniNlHdr + [context][timestamp] + log |
| 399 | * VOS_ASSERT if we cannot accomodate the the complete log into |
| 400 | * the available buffer. |
| 401 | * |
| 402 | * Continue and copy logs to the available length and discard the rest. |
| 403 | */ |
| 404 | if (MAX_LOGMSG_LENGTH < (sizeof(tAniNlHdr) + total_log_len)) { |
| 405 | VOS_ASSERT(0); |
| 406 | total_log_len = MAX_LOGMSG_LENGTH - sizeof(tAniNlHdr) - 2; |
| 407 | } |
| 408 | |
Rajesh Babu Prathipati | 71e9c44 | 2014-07-01 22:08:29 +0530 | [diff] [blame] | 409 | vos_mem_copy(&ptr[*pfilled_length], tbuf, tlen); |
| 410 | vos_mem_copy(&ptr[*pfilled_length + tlen], to_be_sent, |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 411 | min(length, (total_log_len - tlen))); |
| 412 | *pfilled_length += tlen + min(length, total_log_len - tlen); |
| 413 | ptr[*pfilled_length] = '\n'; |
| 414 | *pfilled_length += 1; |
| 415 | |
Pradeep Kumar Goudagunta | 8526f83 | 2014-04-17 14:56:09 +0530 | [diff] [blame] | 416 | spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 417 | |
| 418 | /* Wakeup logger thread */ |
Vinay Krishna Eranna | 8382e0e | 2014-06-18 19:19:58 +0530 | [diff] [blame] | 419 | if ((true == wake_up_thread)) { |
| 420 | /* If there is logger app registered wakeup the logging |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 421 | * thread |
Vinay Krishna Eranna | 8382e0e | 2014-06-18 19:19:58 +0530 | [diff] [blame] | 422 | */ |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 423 | |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 424 | set_bit(HOST_LOG_POST_MASK, &gwlan_logging.event_flag); |
Vinay Krishna Eranna | 8382e0e | 2014-06-18 19:19:58 +0530 | [diff] [blame] | 425 | wake_up_interruptible(&gwlan_logging.wait_queue); |
Vinay Krishna Eranna | 8382e0e | 2014-06-18 19:19:58 +0530 | [diff] [blame] | 426 | } |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 427 | |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 428 | if (gwlan_logging.log_fe_to_console |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 429 | && ((VOS_TRACE_LEVEL_FATAL == log_level) |
| 430 | || (VOS_TRACE_LEVEL_ERROR == log_level))) { |
Vinay Krishna Eranna | 8233736 | 2014-09-06 18:19:03 +0530 | [diff] [blame] | 431 | pr_err("%s\n", to_be_sent); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 432 | } |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 433 | } |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 434 | |
| 435 | return 0; |
| 436 | } |
| 437 | |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 438 | static int send_fw_log_pkt_to_user(void) |
| 439 | { |
| 440 | int ret = -1; |
| 441 | int extra_header_len, nl_payload_len; |
| 442 | struct sk_buff *skb = NULL; |
| 443 | static int nlmsg_seq; |
| 444 | vos_pkt_t *current_pkt; |
| 445 | vos_pkt_t *next_pkt; |
| 446 | VOS_STATUS status = VOS_STATUS_E_FAILURE; |
| 447 | unsigned long flags; |
| 448 | |
| 449 | tAniNlHdr msg_header; |
| 450 | |
| 451 | do { |
| 452 | spin_lock_irqsave(&gwlan_logging.fw_log_pkt_lock, flags); |
| 453 | |
| 454 | if (!gwlan_logging.fw_log_pkt_queue) { |
| 455 | spin_unlock_irqrestore( |
| 456 | &gwlan_logging.fw_log_pkt_lock, flags); |
| 457 | return -EIO; |
| 458 | } |
| 459 | |
| 460 | /* pick first pkt from queued chain */ |
| 461 | current_pkt = gwlan_logging.fw_log_pkt_queue; |
| 462 | |
| 463 | /* get the pointer to the next packet in the chain */ |
| 464 | status = vos_pkt_walk_packet_chain(current_pkt, &next_pkt, |
| 465 | TRUE); |
| 466 | |
| 467 | /* both "success" and "empty" are acceptable results */ |
| 468 | if (!((status == VOS_STATUS_SUCCESS) || |
| 469 | (status == VOS_STATUS_E_EMPTY))) { |
| 470 | ++gwlan_logging.fw_log_pkt_drop_cnt; |
| 471 | spin_unlock_irqrestore( |
| 472 | &gwlan_logging.fw_log_pkt_lock, flags); |
| 473 | pr_err("%s: Failure walking packet chain", __func__); |
| 474 | return -EIO; |
| 475 | } |
| 476 | |
| 477 | /* update queue head with next pkt ptr which could be NULL */ |
| 478 | gwlan_logging.fw_log_pkt_queue = next_pkt; |
| 479 | --gwlan_logging.fw_log_pkt_qcnt; |
| 480 | spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, flags); |
| 481 | |
| 482 | status = vos_pkt_get_os_packet(current_pkt, (v_VOID_t **)&skb, |
| 483 | TRUE); |
| 484 | if (!VOS_IS_STATUS_SUCCESS(status)) { |
| 485 | ++gwlan_logging.fw_log_pkt_drop_cnt; |
| 486 | pr_err("%s: Failure extracting skb from vos pkt", |
| 487 | __func__); |
| 488 | return -EIO; |
| 489 | } |
| 490 | |
| 491 | /*return vos pkt since skb is already detached */ |
| 492 | vos_pkt_return_packet(current_pkt); |
| 493 | |
| 494 | extra_header_len = sizeof(msg_header.radio) + sizeof(tAniHdr); |
| 495 | nl_payload_len = NLMSG_ALIGN(extra_header_len + skb->len); |
| 496 | |
| 497 | msg_header.nlh.nlmsg_type = ANI_NL_MSG_LOG; |
| 498 | msg_header.nlh.nlmsg_len = nl_payload_len; |
| 499 | msg_header.nlh.nlmsg_flags = NLM_F_REQUEST; |
| 500 | msg_header.nlh.nlmsg_pid = gapp_pid; |
| 501 | msg_header.nlh.nlmsg_seq = nlmsg_seq++; |
| 502 | |
| 503 | msg_header.radio = 0; |
| 504 | |
| 505 | msg_header.wmsg.type = ANI_NL_MSG_FW_LOG_PKT_TYPE; |
| 506 | msg_header.wmsg.length = skb->len; |
| 507 | |
| 508 | if (unlikely(skb_headroom(skb) < sizeof(msg_header))) { |
| 509 | pr_err("VPKT [%d]: Insufficient headroom, head[%p]," |
| 510 | " data[%p], req[%zu]", __LINE__, skb->head, |
| 511 | skb->data, sizeof(msg_header)); |
| 512 | return -EIO; |
| 513 | } |
| 514 | |
| 515 | vos_mem_copy(skb_push(skb, sizeof(msg_header)), &msg_header, |
| 516 | sizeof(msg_header)); |
| 517 | |
| 518 | ret = nl_srv_bcast(skb); |
| 519 | if (ret < 0) { |
| 520 | pr_info("%s: Send Failed %d drop_count = %u\n", |
| 521 | __func__, ret, ++gwlan_logging.fw_log_pkt_drop_cnt); |
| 522 | } else { |
| 523 | ret = 0; |
| 524 | } |
| 525 | |
| 526 | } while (next_pkt); |
| 527 | |
| 528 | return ret; |
| 529 | } |
| 530 | |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 531 | static int send_data_mgmt_log_pkt_to_user(void) |
| 532 | { |
| 533 | int ret = -1; |
| 534 | int extra_header_len, nl_payload_len; |
| 535 | struct sk_buff *skb = NULL; |
| 536 | static int nlmsg_seq; |
| 537 | vos_pkt_t *current_pkt; |
| 538 | vos_pkt_t *next_pkt; |
| 539 | VOS_STATUS status = VOS_STATUS_E_FAILURE; |
| 540 | unsigned long flags; |
| 541 | |
| 542 | tAniNlLogHdr msg_header; |
| 543 | |
| 544 | do { |
| 545 | spin_lock_irqsave(&gwlan_logging.data_mgmt_pkt_lock, flags); |
| 546 | |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 547 | if (!gwlan_logging.data_mgmt_pkt_queue) { |
| 548 | spin_unlock_irqrestore( |
| 549 | &gwlan_logging.data_mgmt_pkt_lock, flags); |
| 550 | return -EIO; |
| 551 | } |
| 552 | |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 553 | /* pick first pkt from queued chain */ |
| 554 | current_pkt = gwlan_logging.data_mgmt_pkt_queue; |
| 555 | |
| 556 | /* get the pointer to the next packet in the chain */ |
| 557 | status = vos_pkt_walk_packet_chain(current_pkt, &next_pkt, |
| 558 | TRUE); |
| 559 | |
| 560 | /* both "success" and "empty" are acceptable results */ |
| 561 | if (!((status == VOS_STATUS_SUCCESS) || |
| 562 | (status == VOS_STATUS_E_EMPTY))) { |
| 563 | ++gwlan_logging.pkt_drop_cnt; |
| 564 | spin_unlock_irqrestore( |
| 565 | &gwlan_logging.data_mgmt_pkt_lock, flags); |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 566 | pr_err("%s: Failure walking packet chain", __func__); |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 567 | return -EIO; |
| 568 | } |
| 569 | |
| 570 | /* update queue head with next pkt ptr which could be NULL */ |
| 571 | gwlan_logging.data_mgmt_pkt_queue = next_pkt; |
| 572 | --gwlan_logging.data_mgmt_pkt_qcnt; |
| 573 | spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, flags); |
| 574 | |
| 575 | status = vos_pkt_get_os_packet(current_pkt, (v_VOID_t **)&skb, |
| 576 | TRUE); |
| 577 | if (!VOS_IS_STATUS_SUCCESS(status)) { |
| 578 | ++gwlan_logging.pkt_drop_cnt; |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 579 | pr_err("%s: Failure extracting skb from vos pkt", |
| 580 | __func__); |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 581 | return -EIO; |
| 582 | } |
| 583 | |
| 584 | /*return vos pkt since skb is already detached */ |
| 585 | vos_pkt_return_packet(current_pkt); |
| 586 | |
| 587 | extra_header_len = sizeof(msg_header.radio) + sizeof(tAniHdr) + |
| 588 | sizeof(msg_header.frameSize); |
| 589 | nl_payload_len = NLMSG_ALIGN(extra_header_len + skb->len); |
| 590 | |
| 591 | msg_header.nlh.nlmsg_type = ANI_NL_MSG_LOG; |
| 592 | msg_header.nlh.nlmsg_len = nl_payload_len; |
| 593 | msg_header.nlh.nlmsg_flags = NLM_F_REQUEST; |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 594 | msg_header.nlh.nlmsg_pid = 0; |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 595 | msg_header.nlh.nlmsg_seq = nlmsg_seq++; |
| 596 | |
| 597 | msg_header.radio = 0; |
| 598 | |
| 599 | msg_header.wmsg.type = ANI_NL_MSG_LOG_PKT_TYPE; |
| 600 | msg_header.wmsg.length = skb->len + sizeof(uint32); |
| 601 | |
| 602 | msg_header.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES; |
| 603 | |
| 604 | if (unlikely(skb_headroom(skb) < sizeof(msg_header))) { |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 605 | pr_err("VPKT [%d]: Insufficient headroom, head[%p]," |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 606 | " data[%p], req[%zu]", __LINE__, skb->head, |
| 607 | skb->data, sizeof(msg_header)); |
| 608 | return -EIO; |
| 609 | } |
| 610 | |
| 611 | vos_mem_copy(skb_push(skb, sizeof(msg_header)), &msg_header, |
| 612 | sizeof(msg_header)); |
| 613 | |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 614 | ret = nl_srv_bcast(skb); |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 615 | if (ret < 0) { |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 616 | pr_info("%s: Send Failed %d drop_count = %u\n", |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 617 | __func__, ret, ++gwlan_logging.pkt_drop_cnt); |
| 618 | } else { |
| 619 | ret = 0; |
| 620 | } |
| 621 | |
| 622 | } while (next_pkt); |
| 623 | |
| 624 | return ret; |
| 625 | } |
| 626 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 627 | static int send_filled_buffers_to_user(void) |
| 628 | { |
| 629 | int ret = -1; |
| 630 | struct log_msg *plog_msg; |
| 631 | int payload_len; |
| 632 | int tot_msg_len; |
| 633 | tAniNlHdr *wnl; |
| 634 | struct sk_buff *skb = NULL; |
| 635 | struct nlmsghdr *nlh; |
| 636 | static int nlmsg_seq; |
Pradeep Kumar Goudagunta | 8526f83 | 2014-04-17 14:56:09 +0530 | [diff] [blame] | 637 | unsigned long flags; |
Vinay Krishna Eranna | c253297 | 2014-06-26 22:25:19 +0530 | [diff] [blame] | 638 | static int rate_limit; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 639 | |
| 640 | while (!list_empty(&gwlan_logging.filled_list) |
| 641 | && !gwlan_logging.exit) { |
| 642 | |
| 643 | skb = dev_alloc_skb(MAX_LOGMSG_LENGTH); |
| 644 | if (skb == NULL) { |
Vinay Krishna Eranna | c253297 | 2014-06-26 22:25:19 +0530 | [diff] [blame] | 645 | if (!rate_limit) { |
| 646 | pr_err("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u\n", |
| 647 | __func__, MAX_LOGMSG_LENGTH, |
| 648 | gwlan_logging.drop_count); |
| 649 | } |
| 650 | rate_limit = 1; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 651 | ret = -ENOMEM; |
| 652 | break; |
| 653 | } |
Vinay Krishna Eranna | c253297 | 2014-06-26 22:25:19 +0530 | [diff] [blame] | 654 | rate_limit = 0; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 655 | |
Pradeep Kumar Goudagunta | 8526f83 | 2014-04-17 14:56:09 +0530 | [diff] [blame] | 656 | spin_lock_irqsave(&gwlan_logging.spin_lock, flags); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 657 | |
| 658 | plog_msg = (struct log_msg *) |
| 659 | (gwlan_logging.filled_list.next); |
| 660 | list_del_init(gwlan_logging.filled_list.next); |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 661 | spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 662 | /* 4 extra bytes for the radio idx */ |
| 663 | payload_len = plog_msg->filled_length + |
| 664 | sizeof(wnl->radio) + sizeof(tAniHdr); |
| 665 | |
| 666 | tot_msg_len = NLMSG_SPACE(payload_len); |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 667 | nlh = nlmsg_put(skb, 0, nlmsg_seq++, |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 668 | ANI_NL_MSG_LOG, payload_len, |
| 669 | NLM_F_REQUEST); |
| 670 | if (NULL == nlh) { |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 671 | spin_lock_irqsave(&gwlan_logging.spin_lock, flags); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 672 | list_add_tail(&plog_msg->node, |
| 673 | &gwlan_logging.free_list); |
Pradeep Kumar Goudagunta | 8526f83 | 2014-04-17 14:56:09 +0530 | [diff] [blame] | 674 | spin_unlock_irqrestore(&gwlan_logging.spin_lock, |
| 675 | flags); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 676 | pr_err("%s: drop_count = %u\n", __func__, |
| 677 | ++gwlan_logging.drop_count); |
| 678 | pr_err("%s: nlmsg_put() failed for msg size[%d]\n", |
| 679 | __func__, tot_msg_len); |
| 680 | dev_kfree_skb(skb); |
| 681 | skb = NULL; |
| 682 | ret = -EINVAL; |
| 683 | continue; |
| 684 | } |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 685 | |
| 686 | wnl = (tAniNlHdr *) nlh; |
| 687 | wnl->radio = plog_msg->radio; |
Rajesh Babu Prathipati | 71e9c44 | 2014-07-01 22:08:29 +0530 | [diff] [blame] | 688 | vos_mem_copy(&wnl->wmsg, plog_msg->logbuf, |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 689 | plog_msg->filled_length + |
| 690 | sizeof(tAniHdr)); |
| 691 | |
Pradeep Kumar Goudagunta | 8526f83 | 2014-04-17 14:56:09 +0530 | [diff] [blame] | 692 | spin_lock_irqsave(&gwlan_logging.spin_lock, flags); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 693 | list_add_tail(&plog_msg->node, |
| 694 | &gwlan_logging.free_list); |
Pradeep Kumar Goudagunta | 8526f83 | 2014-04-17 14:56:09 +0530 | [diff] [blame] | 695 | spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 696 | |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 697 | ret = nl_srv_bcast(skb); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 698 | if (ret < 0) { |
Sushant Kaushik | 8ddaa38 | 2015-06-23 12:17:25 +0530 | [diff] [blame] | 699 | if (__ratelimit(&errCnt)) |
| 700 | { |
| 701 | pr_info("%s: Send Failed %d drop_count = %u\n", |
| 702 | __func__, ret, gwlan_logging.drop_count); |
| 703 | } |
| 704 | gwlan_logging.drop_count++; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 705 | skb = NULL; |
c_hpothu | 0424d04 | 2014-11-19 19:37:14 +0530 | [diff] [blame] | 706 | break; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 707 | } else { |
| 708 | skb = NULL; |
| 709 | ret = 0; |
| 710 | } |
| 711 | } |
| 712 | |
| 713 | return ret; |
| 714 | } |
| 715 | |
| 716 | /** |
| 717 | * wlan_logging_thread() - The WLAN Logger thread |
| 718 | * @Arg - pointer to the HDD context |
| 719 | * |
| 720 | * This thread logs log message to App registered for the logs. |
| 721 | */ |
| 722 | static int wlan_logging_thread(void *Arg) |
| 723 | { |
| 724 | int ret_wait_status = 0; |
Vinay Krishna Eranna | c253297 | 2014-06-26 22:25:19 +0530 | [diff] [blame] | 725 | int ret = 0; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 726 | |
| 727 | set_user_nice(current, -2); |
| 728 | |
| 729 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) |
| 730 | daemonize("wlan_logging_thread"); |
| 731 | #endif |
| 732 | |
| 733 | while (!gwlan_logging.exit) { |
| 734 | ret_wait_status = wait_event_interruptible( |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 735 | gwlan_logging.wait_queue, |
| 736 | (test_bit(HOST_LOG_POST_MASK, &gwlan_logging.event_flag) || |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 737 | gwlan_logging.exit || |
| 738 | test_bit(LOGGER_MGMT_DATA_PKT_POST_MASK,&gwlan_logging.event_flag) || |
| 739 | test_bit(LOGGER_FW_LOG_PKT_POST_MASK, &gwlan_logging.event_flag) || |
| 740 | test_bit(LOGGER_FATAL_EVENT_POST_MASK, &gwlan_logging.event_flag))); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 741 | |
| 742 | if (ret_wait_status == -ERESTARTSYS) { |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 743 | pr_err("%s: wait_event return -ERESTARTSYS", __func__); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 744 | break; |
| 745 | } |
| 746 | |
| 747 | if (gwlan_logging.exit) { |
c_hpothu | 0424d04 | 2014-11-19 19:37:14 +0530 | [diff] [blame] | 748 | break; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 749 | } |
| 750 | |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 751 | if (test_and_clear_bit(HOST_LOG_POST_MASK, |
| 752 | &gwlan_logging.event_flag)) { |
| 753 | ret = send_filled_buffers_to_user(); |
| 754 | if (-ENOMEM == ret) { |
| 755 | msleep(200); |
| 756 | } |
| 757 | } |
| 758 | |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 759 | if (test_and_clear_bit(LOGGER_FW_LOG_PKT_POST_MASK, |
| 760 | &gwlan_logging.event_flag)) { |
| 761 | send_fw_log_pkt_to_user(); |
| 762 | } |
| 763 | |
| 764 | if (test_and_clear_bit(LOGGER_MGMT_DATA_PKT_POST_MASK, |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 765 | &gwlan_logging.event_flag)) { |
| 766 | send_data_mgmt_log_pkt_to_user(); |
Vinay Krishna Eranna | c253297 | 2014-06-26 22:25:19 +0530 | [diff] [blame] | 767 | } |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 768 | |
| 769 | if (test_and_clear_bit(LOGGER_FATAL_EVENT_POST_MASK, |
| 770 | &gwlan_logging.event_flag)) { |
| 771 | if (gwlan_logging.log_complete.is_flush_complete == true) { |
| 772 | gwlan_logging.log_complete.is_flush_complete = false; |
| 773 | vos_send_fatal_event_done(); |
| 774 | } |
| 775 | else { |
| 776 | gwlan_logging.log_complete.is_flush_complete = true; |
| 777 | set_bit(HOST_LOG_POST_MASK,&gwlan_logging.event_flag); |
| 778 | set_bit(LOGGER_FW_LOG_PKT_POST_MASK,&gwlan_logging.event_flag); |
| 779 | set_bit(LOGGER_FATAL_EVENT_POST_MASK,&gwlan_logging.event_flag); |
| 780 | wake_up_interruptible(&gwlan_logging.wait_queue); |
| 781 | } |
| 782 | } |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 783 | } |
| 784 | |
Vinay Krishna Eranna | d1d284f | 2014-10-28 20:09:55 +0530 | [diff] [blame] | 785 | complete_and_exit(&gwlan_logging.shutdown_comp, 0); |
| 786 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 787 | return 0; |
| 788 | } |
| 789 | |
| 790 | /* |
| 791 | * Process all the Netlink messages from Logger Socket app in user space |
| 792 | */ |
| 793 | static int wlan_logging_proc_sock_rx_msg(struct sk_buff *skb) |
| 794 | { |
| 795 | tAniNlHdr *wnl; |
| 796 | int radio; |
| 797 | int type; |
| 798 | int ret; |
| 799 | |
Hanumantha Reddy Pothula | 05b0b55 | 2015-06-18 14:26:10 +0530 | [diff] [blame] | 800 | if (TRUE == vos_isUnloadInProgress()) |
| 801 | { |
| 802 | pr_info("%s: unload in progress\n",__func__); |
| 803 | return -ENODEV; |
| 804 | } |
| 805 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 806 | wnl = (tAniNlHdr *) skb->data; |
| 807 | radio = wnl->radio; |
| 808 | type = wnl->nlh.nlmsg_type; |
| 809 | |
| 810 | if (radio < 0 || radio > ANI_MAX_RADIOS) { |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 811 | pr_err("%s: invalid radio id [%d]\n", |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 812 | __func__, radio); |
| 813 | return -EINVAL; |
| 814 | } |
| 815 | |
| 816 | if (gapp_pid != INVALID_PID) { |
| 817 | if (wnl->nlh.nlmsg_pid > gapp_pid) { |
| 818 | gapp_pid = wnl->nlh.nlmsg_pid; |
| 819 | } |
| 820 | |
| 821 | spin_lock_bh(&gwlan_logging.spin_lock); |
| 822 | if (gwlan_logging.pcur_node->filled_length) { |
| 823 | wlan_queue_logmsg_for_app(); |
| 824 | } |
| 825 | spin_unlock_bh(&gwlan_logging.spin_lock); |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 826 | set_bit(HOST_LOG_POST_MASK, &gwlan_logging.event_flag); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 827 | wake_up_interruptible(&gwlan_logging.wait_queue); |
| 828 | } else { |
| 829 | /* This is to set the default levels (WLAN logging |
| 830 | * default values not the VOS trace default) when |
| 831 | * logger app is registered for the first time. |
| 832 | */ |
| 833 | gapp_pid = wnl->nlh.nlmsg_pid; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 834 | } |
| 835 | |
| 836 | ret = wlan_send_sock_msg_to_app(&wnl->wmsg, 0, |
| 837 | ANI_NL_MSG_LOG, wnl->nlh.nlmsg_pid); |
| 838 | if (ret < 0) { |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 839 | pr_err("wlan_send_sock_msg_to_app: failed"); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 840 | } |
| 841 | |
| 842 | return ret; |
| 843 | } |
| 844 | |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 845 | void wlan_init_log_completion(void) |
| 846 | { |
| 847 | gwlan_logging.log_complete.indicator = WLAN_LOG_TYPE_NON_FATAL; |
| 848 | gwlan_logging.log_complete.is_fatal = WLAN_LOG_INDICATOR_UNUSED; |
| 849 | gwlan_logging.log_complete.is_report_in_progress = false; |
| 850 | gwlan_logging.log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED; |
| 851 | |
| 852 | spin_lock_init(&gwlan_logging.bug_report_lock); |
| 853 | } |
| 854 | |
| 855 | int wlan_set_log_completion(uint32 is_fatal, |
| 856 | uint32 indicator, |
| 857 | uint32 reason_code) |
| 858 | { |
| 859 | unsigned long flags; |
| 860 | |
| 861 | spin_lock_irqsave(&gwlan_logging.bug_report_lock, flags); |
| 862 | gwlan_logging.log_complete.indicator = indicator; |
| 863 | gwlan_logging.log_complete.is_fatal = is_fatal; |
| 864 | gwlan_logging.log_complete.is_report_in_progress = true; |
| 865 | gwlan_logging.log_complete.reason_code = reason_code; |
| 866 | spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags); |
| 867 | |
| 868 | return 0; |
| 869 | } |
| 870 | void wlan_get_log_completion(uint32 *is_fatal, |
| 871 | uint32 *indicator, |
| 872 | uint32 *reason_code) |
| 873 | { |
| 874 | unsigned long flags; |
| 875 | |
| 876 | spin_lock_irqsave(&gwlan_logging.bug_report_lock, flags); |
| 877 | *indicator = gwlan_logging.log_complete.indicator; |
| 878 | *is_fatal = gwlan_logging.log_complete.is_fatal; |
| 879 | *reason_code = gwlan_logging.log_complete.reason_code; |
| 880 | gwlan_logging.log_complete.is_report_in_progress = false; |
| 881 | |
| 882 | spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags); |
| 883 | |
| 884 | } |
| 885 | bool wlan_is_log_report_in_progress(void) |
| 886 | { |
| 887 | return gwlan_logging.log_complete.is_report_in_progress; |
| 888 | } |
| 889 | |
| 890 | void wlan_reset_log_report_in_progress(void) |
| 891 | { |
| 892 | unsigned long flags; |
| 893 | |
| 894 | spin_lock_irqsave(&gwlan_logging.bug_report_lock, flags); |
| 895 | gwlan_logging.log_complete.is_report_in_progress = false; |
| 896 | spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags); |
| 897 | } |
| 898 | |
| 899 | |
| 900 | void wlan_deinit_log_completion(void) |
| 901 | { |
| 902 | return; |
| 903 | } |
| 904 | |
| 905 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 906 | int wlan_logging_sock_activate_svc(int log_fe_to_console, int num_buf) |
| 907 | { |
| 908 | int i = 0; |
| 909 | unsigned long irq_flag; |
| 910 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 911 | gapp_pid = INVALID_PID; |
| 912 | |
Vinay Krishna Eranna | 0b11262 | 2014-04-21 20:17:57 +0530 | [diff] [blame] | 913 | gplog_msg = (struct log_msg *) vmalloc( |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 914 | num_buf * sizeof(struct log_msg)); |
| 915 | if (!gplog_msg) { |
| 916 | pr_err("%s: Could not allocate memory\n", __func__); |
| 917 | return -ENOMEM; |
| 918 | } |
| 919 | |
| 920 | vos_mem_zero(gplog_msg, (num_buf * sizeof(struct log_msg))); |
| 921 | |
| 922 | gwlan_logging.log_fe_to_console = !!log_fe_to_console; |
| 923 | gwlan_logging.num_buf = num_buf; |
| 924 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 925 | spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); |
| 926 | INIT_LIST_HEAD(&gwlan_logging.free_list); |
| 927 | INIT_LIST_HEAD(&gwlan_logging.filled_list); |
| 928 | |
| 929 | for (i = 0; i < num_buf; i++) { |
| 930 | list_add(&gplog_msg[i].node, &gwlan_logging.free_list); |
| 931 | gplog_msg[i].index = i; |
| 932 | } |
| 933 | gwlan_logging.pcur_node = (struct log_msg *) |
| 934 | (gwlan_logging.free_list.next); |
| 935 | list_del_init(gwlan_logging.free_list.next); |
| 936 | spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); |
| 937 | |
| 938 | init_waitqueue_head(&gwlan_logging.wait_queue); |
| 939 | gwlan_logging.exit = false; |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 940 | clear_bit(HOST_LOG_POST_MASK, &gwlan_logging.event_flag); |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 941 | clear_bit(LOGGER_MGMT_DATA_PKT_POST_MASK, &gwlan_logging.event_flag); |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 942 | clear_bit(LOGGER_FW_LOG_PKT_POST_MASK, &gwlan_logging.event_flag); |
| 943 | clear_bit(LOGGER_FATAL_EVENT_POST_MASK, &gwlan_logging.event_flag); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 944 | init_completion(&gwlan_logging.shutdown_comp); |
| 945 | gwlan_logging.thread = kthread_create(wlan_logging_thread, NULL, |
| 946 | "wlan_logging_thread"); |
| 947 | if (IS_ERR(gwlan_logging.thread)) { |
| 948 | pr_err("%s: Could not Create LogMsg Thread Controller", |
| 949 | __func__); |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 950 | spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); |
Vinay Krishna Eranna | 6c158fa | 2014-05-13 00:42:41 +0530 | [diff] [blame] | 951 | vfree(gplog_msg); |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 952 | gplog_msg = NULL; |
| 953 | gwlan_logging.pcur_node = NULL; |
| 954 | spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 955 | return -ENOMEM; |
| 956 | } |
| 957 | wake_up_process(gwlan_logging.thread); |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 958 | gwlan_logging.is_active = true; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 959 | |
| 960 | nl_srv_register(ANI_NL_MSG_LOG, wlan_logging_proc_sock_rx_msg); |
| 961 | |
Sushant Kaushik | 9cb1c9c | 2015-06-23 11:57:10 +0530 | [diff] [blame] | 962 | //Broadcast SVC ready message to logging app/s running |
| 963 | wlan_logging_srv_nl_ready_indication(); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 964 | return 0; |
| 965 | } |
| 966 | |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 967 | int wlan_logging_flush_pkt_queue(void) |
| 968 | { |
| 969 | vos_pkt_t *pkt_queue_head; |
| 970 | unsigned long flags; |
| 971 | |
| 972 | spin_lock_irqsave(&gwlan_logging.data_mgmt_pkt_lock, flags); |
| 973 | if (NULL != gwlan_logging.data_mgmt_pkt_queue) { |
| 974 | pkt_queue_head = gwlan_logging.data_mgmt_pkt_queue; |
| 975 | gwlan_logging.data_mgmt_pkt_queue = NULL; |
| 976 | gwlan_logging.pkt_drop_cnt = 0; |
| 977 | gwlan_logging.data_mgmt_pkt_qcnt = 0; |
| 978 | spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, |
| 979 | flags); |
| 980 | vos_pkt_return_packet(pkt_queue_head); |
| 981 | } else { |
| 982 | spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, |
| 983 | flags); |
| 984 | } |
| 985 | |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 986 | spin_lock_irqsave(&gwlan_logging.fw_log_pkt_lock, flags); |
| 987 | if (NULL != gwlan_logging.fw_log_pkt_queue) { |
| 988 | pkt_queue_head = gwlan_logging.fw_log_pkt_queue; |
| 989 | gwlan_logging.fw_log_pkt_queue = NULL; |
| 990 | gwlan_logging.fw_log_pkt_drop_cnt = 0; |
| 991 | gwlan_logging.fw_log_pkt_qcnt = 0; |
| 992 | spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, |
| 993 | flags); |
| 994 | vos_pkt_return_packet(pkt_queue_head); |
| 995 | } else { |
| 996 | spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, |
| 997 | flags); |
| 998 | } |
| 999 | |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1000 | return 0; |
| 1001 | } |
| 1002 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 1003 | int wlan_logging_sock_deactivate_svc(void) |
| 1004 | { |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 1005 | unsigned long irq_flag; |
| 1006 | |
| 1007 | if (!gplog_msg) |
| 1008 | return 0; |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 1009 | |
| 1010 | nl_srv_unregister(ANI_NL_MSG_LOG, wlan_logging_proc_sock_rx_msg); |
| 1011 | clear_default_logtoapp_log_level(); |
| 1012 | gapp_pid = INVALID_PID; |
| 1013 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 1014 | INIT_COMPLETION(gwlan_logging.shutdown_comp); |
Vinay Krishna Eranna | d1d284f | 2014-10-28 20:09:55 +0530 | [diff] [blame] | 1015 | gwlan_logging.exit = true; |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1016 | gwlan_logging.is_active = false; |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 1017 | vos_set_multicast_logging(0); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 1018 | wake_up_interruptible(&gwlan_logging.wait_queue); |
Vinay Krishna Eranna | d1d284f | 2014-10-28 20:09:55 +0530 | [diff] [blame] | 1019 | wait_for_completion(&gwlan_logging.shutdown_comp); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 1020 | |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 1021 | spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); |
Vinay Krishna Eranna | 0b11262 | 2014-04-21 20:17:57 +0530 | [diff] [blame] | 1022 | vfree(gplog_msg); |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 1023 | gplog_msg = NULL; |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 1024 | gwlan_logging.pcur_node = NULL; |
| 1025 | spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 1026 | |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1027 | wlan_logging_flush_pkt_queue(); |
| 1028 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 1029 | return 0; |
| 1030 | } |
| 1031 | |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 1032 | int wlan_logging_sock_init_svc(void) |
| 1033 | { |
| 1034 | spin_lock_init(&gwlan_logging.spin_lock); |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1035 | spin_lock_init(&gwlan_logging.data_mgmt_pkt_lock); |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 1036 | spin_lock_init(&gwlan_logging.fw_log_pkt_lock); |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 1037 | gapp_pid = INVALID_PID; |
| 1038 | gwlan_logging.pcur_node = NULL; |
| 1039 | |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 1040 | wlan_init_log_completion(); |
| 1041 | |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 1042 | return 0; |
| 1043 | } |
| 1044 | |
| 1045 | int wlan_logging_sock_deinit_svc(void) |
| 1046 | { |
| 1047 | gwlan_logging.pcur_node = NULL; |
| 1048 | gapp_pid = INVALID_PID; |
| 1049 | |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 1050 | wlan_deinit_log_completion(); |
| 1051 | return 0; |
Vinay Krishna Eranna | 273ec5a | 2014-05-10 18:05:25 +0530 | [diff] [blame] | 1052 | } |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1053 | |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 1054 | int wlan_queue_data_mgmt_pkt_for_app(vos_pkt_t *pPacket) |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1055 | { |
| 1056 | unsigned long flags; |
| 1057 | vos_pkt_t *next_pkt; |
| 1058 | vos_pkt_t *free_pkt; |
| 1059 | VOS_STATUS status = VOS_STATUS_E_FAILURE; |
| 1060 | |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1061 | spin_lock_irqsave(&gwlan_logging.data_mgmt_pkt_lock, flags); |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 1062 | if (gwlan_logging.data_mgmt_pkt_qcnt >= LOGGER_MAX_DATA_MGMT_PKT_Q_LEN) { |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1063 | status = vos_pkt_walk_packet_chain( |
| 1064 | gwlan_logging.data_mgmt_pkt_queue, &next_pkt, TRUE); |
| 1065 | /*both "success" and "empty" are acceptable results*/ |
| 1066 | if (!((status == VOS_STATUS_SUCCESS) || |
| 1067 | (status == VOS_STATUS_E_EMPTY))) { |
| 1068 | ++gwlan_logging.pkt_drop_cnt; |
| 1069 | spin_unlock_irqrestore( |
| 1070 | &gwlan_logging.data_mgmt_pkt_lock, flags); |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 1071 | pr_err("%s: Failure walking packet chain", __func__); |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1072 | /*keep returning pkts to avoid low resource cond*/ |
| 1073 | vos_pkt_return_packet(pPacket); |
| 1074 | return VOS_STATUS_E_FAILURE; |
| 1075 | } |
| 1076 | |
| 1077 | free_pkt = gwlan_logging.data_mgmt_pkt_queue; |
| 1078 | gwlan_logging.data_mgmt_pkt_queue = next_pkt; |
| 1079 | /*returning head of pkt queue. latest pkts are important*/ |
| 1080 | --gwlan_logging.data_mgmt_pkt_qcnt; |
| 1081 | spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, |
| 1082 | flags); |
| 1083 | vos_pkt_return_packet(free_pkt); |
| 1084 | } else { |
| 1085 | spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, |
| 1086 | flags); |
| 1087 | } |
| 1088 | |
| 1089 | spin_lock_irqsave(&gwlan_logging.data_mgmt_pkt_lock, flags); |
| 1090 | |
| 1091 | if (gwlan_logging.data_mgmt_pkt_queue) { |
| 1092 | vos_pkt_chain_packet(gwlan_logging.data_mgmt_pkt_queue, |
| 1093 | pPacket, TRUE); |
| 1094 | } else { |
| 1095 | gwlan_logging.data_mgmt_pkt_queue = pPacket; |
| 1096 | } |
| 1097 | ++gwlan_logging.data_mgmt_pkt_qcnt; |
| 1098 | |
| 1099 | spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, flags); |
| 1100 | |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 1101 | set_bit(LOGGER_MGMT_DATA_PKT_POST_MASK, &gwlan_logging.event_flag); |
Siddharth Bhal | 7bd1993 | 2015-03-03 16:54:36 +0530 | [diff] [blame] | 1102 | wake_up_interruptible(&gwlan_logging.wait_queue); |
| 1103 | |
| 1104 | return VOS_STATUS_SUCCESS; |
| 1105 | } |
| 1106 | |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 1107 | /** |
| 1108 | * wlan_logging_set_log_level() - Set the logging level |
| 1109 | * |
| 1110 | * This function is used to set the logging level of host debug messages |
| 1111 | * |
| 1112 | * Return: None |
| 1113 | */ |
| 1114 | void wlan_logging_set_log_level(void) |
| 1115 | { |
| 1116 | set_default_logtoapp_log_level(); |
| 1117 | } |
| 1118 | |
Siddharth Bhal | ec0b72c | 2015-05-12 21:35:54 +0530 | [diff] [blame] | 1119 | int wlan_queue_fw_log_pkt_for_app(vos_pkt_t *pPacket) |
| 1120 | { |
| 1121 | unsigned long flags; |
| 1122 | vos_pkt_t *next_pkt; |
| 1123 | vos_pkt_t *free_pkt; |
| 1124 | VOS_STATUS status = VOS_STATUS_E_FAILURE; |
| 1125 | |
| 1126 | spin_lock_irqsave(&gwlan_logging.fw_log_pkt_lock, flags); |
| 1127 | if (gwlan_logging.fw_log_pkt_qcnt >= LOGGER_MAX_FW_LOG_PKT_Q_LEN) { |
| 1128 | status = vos_pkt_walk_packet_chain( |
| 1129 | gwlan_logging.fw_log_pkt_queue, &next_pkt, TRUE); |
| 1130 | /*both "success" and "empty" are acceptable results*/ |
| 1131 | if (!((status == VOS_STATUS_SUCCESS) || |
| 1132 | (status == VOS_STATUS_E_EMPTY))) { |
| 1133 | ++gwlan_logging.fw_log_pkt_drop_cnt; |
| 1134 | spin_unlock_irqrestore( |
| 1135 | &gwlan_logging.fw_log_pkt_lock, flags); |
| 1136 | pr_err("%s: Failure walking packet chain", __func__); |
| 1137 | /*keep returning pkts to avoid low resource cond*/ |
| 1138 | vos_pkt_return_packet(pPacket); |
| 1139 | return VOS_STATUS_E_FAILURE; |
| 1140 | } |
| 1141 | |
| 1142 | free_pkt = gwlan_logging.fw_log_pkt_queue; |
| 1143 | gwlan_logging.fw_log_pkt_queue = next_pkt; |
| 1144 | /*returning head of pkt queue. latest pkts are important*/ |
| 1145 | --gwlan_logging.fw_log_pkt_qcnt; |
| 1146 | spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, |
| 1147 | flags); |
| 1148 | vos_pkt_return_packet(free_pkt); |
| 1149 | } else { |
| 1150 | spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, |
| 1151 | flags); |
| 1152 | } |
| 1153 | |
| 1154 | spin_lock_irqsave(&gwlan_logging.fw_log_pkt_lock, flags); |
| 1155 | |
| 1156 | if (gwlan_logging.fw_log_pkt_queue) { |
| 1157 | vos_pkt_chain_packet(gwlan_logging.fw_log_pkt_queue, |
| 1158 | pPacket, TRUE); |
| 1159 | } else { |
| 1160 | gwlan_logging.fw_log_pkt_queue = pPacket; |
| 1161 | } |
| 1162 | ++gwlan_logging.fw_log_pkt_qcnt; |
| 1163 | |
| 1164 | spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, flags); |
| 1165 | |
| 1166 | set_bit(LOGGER_FW_LOG_PKT_POST_MASK, &gwlan_logging.event_flag); |
| 1167 | wake_up_interruptible(&gwlan_logging.wait_queue); |
| 1168 | |
| 1169 | return VOS_STATUS_SUCCESS; |
| 1170 | } |
| 1171 | |
| 1172 | int wlan_queue_logpkt_for_app(vos_pkt_t *pPacket, uint32 pkt_type) |
| 1173 | { |
| 1174 | VOS_STATUS status = VOS_STATUS_E_FAILURE; |
| 1175 | |
| 1176 | if (pPacket == NULL) { |
| 1177 | pr_err("%s: Null param", __func__); |
| 1178 | VOS_ASSERT(0); |
| 1179 | return VOS_STATUS_E_FAILURE; |
| 1180 | } |
| 1181 | |
| 1182 | if (gwlan_logging.is_active == false) { |
| 1183 | /*return all packets queued*/ |
| 1184 | wlan_logging_flush_pkt_queue(); |
| 1185 | |
| 1186 | /*return currently received pkt*/ |
| 1187 | vos_pkt_return_packet(pPacket); |
| 1188 | return VOS_STATUS_E_FAILURE; |
| 1189 | } |
| 1190 | |
| 1191 | switch (pkt_type) { |
| 1192 | case LOG_PKT_TYPE_DATA_MGMT: |
| 1193 | status = wlan_queue_data_mgmt_pkt_for_app(pPacket); |
| 1194 | break; |
| 1195 | |
| 1196 | case LOG_PKT_TYPE_FW_LOG: |
| 1197 | status = wlan_queue_fw_log_pkt_for_app(pPacket); |
| 1198 | break; |
| 1199 | |
| 1200 | default: |
| 1201 | pr_info("%s: Unknown pkt received %d", __func__, pkt_type); |
| 1202 | status = VOS_STATUS_E_INVAL; |
| 1203 | break; |
| 1204 | }; |
| 1205 | |
| 1206 | return status; |
| 1207 | } |
Sushant Kaushik | 215778f | 2015-05-21 14:05:36 +0530 | [diff] [blame] | 1208 | |
Sachin Ahuja | 715aafc | 2015-07-21 23:35:10 +0530 | [diff] [blame] | 1209 | |
| 1210 | void wlan_process_done_indication(uint8 type, uint32 reason_code) |
| 1211 | { |
| 1212 | if ((type == WLAN_QXDM_LOGGING) && (wlan_is_log_report_in_progress() == TRUE)) |
| 1213 | { |
| 1214 | pr_info("%s: Setting LOGGER_FATAL_EVENT\n", __func__); |
| 1215 | set_bit(LOGGER_FATAL_EVENT_POST_MASK, &gwlan_logging.event_flag); |
| 1216 | wake_up_interruptible(&gwlan_logging.wait_queue); |
| 1217 | } |
| 1218 | } |
| 1219 | |
Vinay Krishna Eranna | d938c42 | 2014-03-10 17:14:21 +0530 | [diff] [blame] | 1220 | #endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ |