blob: d9b0ba22cd56c0295b6168444bad04479e12ec39 [file] [log] [blame]
Saurabh Misra96998db2014-07-10 12:15:48 -07001/*
2 **************************************************************************
Stephen Wang3e2dbd12018-03-14 17:28:17 -07003 * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
Saurabh Misra96998db2014-07-10 12:15:48 -07004 * 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 copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 **************************************************************************
15 */
16/*
17 * nss_log.c
18 * NSS FW debug logger retrieval from DDR (memory)
19 *
20 */
21#include <linux/types.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/errno.h>
26#include <linux/mm.h>
27#include <linux/fs.h>
28#include <linux/miscdevice.h>
29#include <linux/posix-timers.h>
30#include <linux/interrupt.h>
31#include <linux/time.h>
32#include <linux/platform_device.h>
Saurabh Misra96998db2014-07-10 12:15:48 -070033#include <linux/device.h>
34#include <nss_hal.h>
35#include "nss_core.h"
36#include "nss_log.h"
37
38/*
Saurabh Misra96998db2014-07-10 12:15:48 -070039 * Private data for each device file open instance
40 */
41struct nss_log_data {
42 void *load_mem; /* Pointer to struct nss_log_descriptor - descriptor data */
43 dma_addr_t dma_addr; /* Handle to DMA */
44 uint32_t last_entry; /* Last known sampled entry (or index) */
45 uint32_t nentries; /* Caches the total number of entries of log buffer */
46 int nss_id; /* NSS Core id being used */
47};
48
49/*
50 * Saves the ring buffer address for logging per NSS core
51 */
52struct nss_ring_buffer_addr {
53 void *addr; /* Pointer to struct nss_log_descriptor */
54 dma_addr_t dma_addr; /* DMA Handle */
55 uint32_t nentries; /* Number of entries in the ring buffer */
56 int refcnt; /* Reference count */
57};
58
59static struct nss_ring_buffer_addr nss_rbe[NSS_MAX_CORES];
60
61static DEFINE_MUTEX(nss_log_mutex);
62static wait_queue_head_t nss_log_wq;
63static nss_log_msg_callback_t nss_debug_interface_cb;
64static void *nss_debug_interface_app_data = NULL;
65
66static wait_queue_head_t msg_wq;
67enum nss_cmn_response msg_response;
68static bool msg_event;
69
70/*
71 * nss_log_llseek()
72 * Seek operation.
73 */
74static loff_t nss_log_llseek(struct file *file, loff_t offset, int origin)
75{
76 struct nss_log_data *data = file->private_data;
77
78 switch (origin) {
79 case SEEK_SET:
80 break;
81 case SEEK_CUR:
82 offset += file->f_pos;
83 break;
84 case SEEK_END:
85 offset = ((data->nentries * sizeof(struct nss_log_entry)) + sizeof(struct nss_log_descriptor)) - offset;
86 break;
87 default:
88 return -EINVAL;
89 }
90
91 return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
92}
93
94/*
95 * nss_log_open()
96 * Open operation for our device. We let as many instance run together
97 */
98static int nss_log_open(struct inode *inode, struct file *filp)
99{
100 struct nss_log_data *data = NULL;
101 struct nss_top_instance *nss_top;
102 struct nss_ctx_instance *nss_ctx;
103 int nss_id;
104
105 /*
106 * i_private is passed to us by debug_fs_create()
107 */
Stephen Wangaed46332016-12-12 17:29:03 -0800108 nss_id = (int)(nss_ptr_t)inode->i_private;
Saurabh Misra96998db2014-07-10 12:15:48 -0700109 if (nss_id < 0 || nss_id >= NSS_MAX_CORES) {
110 nss_warning("nss_id is not valid :%d\n", nss_id);
111 return -ENODEV;
112 }
113
114 nss_top = &nss_top_main;
115 nss_ctx = &nss_top->nss[nss_id];
116
117 data = kzalloc(sizeof(struct nss_log_data), GFP_KERNEL);
118 if (!data) {
119 nss_warning("%p: Failed to allocate memory for log_data", nss_ctx);
120 return -ENOMEM;
121 }
122
123 mutex_lock(&nss_log_mutex);
124 if (!nss_rbe[nss_id].addr) {
125 mutex_unlock(&nss_log_mutex);
126 kfree(data);
127 nss_warning("%p: Ring buffer not configured yet for nss_id:%d", nss_ctx, nss_id);
128 return -EIO;
129 }
130
131 /*
132 * Actual ring buffer.
133 */
134 data->load_mem = nss_rbe[nss_id].addr;
135 data->last_entry = 0;
136 data->nentries = nss_rbe[nss_id].nentries;
137 data->dma_addr = nss_rbe[nss_id].dma_addr;
138
139 /*
140 * Increment the reference count so that we don't free
141 * the memory
142 */
143 nss_rbe[nss_id].refcnt++;
144 data->nss_id = nss_id;
145 filp->private_data = data;
146 mutex_unlock(&nss_log_mutex);
147
148 return 0;
149}
150
151/*
152 * nss_log_release()
153 * release gets called when close() is called on the file
154 * descriptor. We unmap the IO region.
155 */
156static int nss_log_release(struct inode *inode, struct file *filp)
157{
158 struct nss_log_data *data = filp->private_data;
159
160 if (!data) {
161 return -EINVAL;
162 }
163
164 mutex_lock(&nss_log_mutex);
165 nss_rbe[data->nss_id].refcnt--;
166 BUG_ON(nss_rbe[data->nss_id].refcnt < 0);
167 if (nss_rbe[data->nss_id].refcnt == 0) {
168 wake_up(&nss_log_wq);
169 }
170 mutex_unlock(&nss_log_mutex);
171 kfree(data);
172 return 0;
173}
174
175/*
Saurabh Misra6d42da72015-03-05 14:57:01 -0800176 * nss_log_current_entry()
177 * Reads current entry index from NSS log descriptor.
178 */
179static uint32_t nss_log_current_entry(struct nss_log_descriptor *desc)
180{
181 rmb();
182 return desc->current_entry;
183}
184
185/*
Saurabh Misra96998db2014-07-10 12:15:48 -0700186 * nss_log_read()
187 * Read operation lets command like cat and tail read our memory log buffer data.
188 */
189static ssize_t nss_log_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
190{
191 struct nss_log_data *data = filp->private_data;
192 struct nss_log_descriptor *desc;
193 size_t bytes = 0;
194 size_t b;
195 struct nss_log_entry *rb;
196 uint32_t entry;
197 uint32_t offset, index;
198 char msg[NSS_LOG_OUTPUT_LINE_SIZE];
199
200 if (!data) {
201 return -EINVAL;
202 }
203
204 desc = data->load_mem;
205 if (!desc) {
206 nss_warning("%p: load_mem is NULL", data);
207 return -EINVAL;
208 }
209
210 /*
211 * If buffer is too small to fit even one entry.
212 */
213 if (size < NSS_LOG_OUTPUT_LINE_SIZE) {
214 return 0;
215 }
216
217 /*
218 * Get the current index
219 */
220 dma_sync_single_for_cpu(NULL, data->dma_addr, sizeof (struct nss_log_descriptor), DMA_FROM_DEVICE);
Saurabh Misra6d42da72015-03-05 14:57:01 -0800221 entry = nss_log_current_entry(desc);
Saurabh Misra96998db2014-07-10 12:15:48 -0700222
223 /*
224 * If the current and last sampled indexes are same then bail out.
225 */
226 if (unlikely(data->last_entry == entry)) {
227 return 0;
228 }
229
230 /*
231 * If this is the first read (after open) on our device file.
232 */
233 if (unlikely(*ppos == 0)) {
234 /*
235 * If log buffer has rolled over. Almost all the time
236 * it will be true.
237 */
238 if (likely(entry > data->nentries)) {
239 /*
240 * Determine how much we can stuff in one
241 * buffer passed to us and accordingly
242 * reduce our index.
243 */
244 data->last_entry = entry - data->nentries;
245 } else {
246 data->last_entry = 0;
247 }
248 } else if (unlikely(entry > data->nentries && ((entry - data->nentries) > data->last_entry))) {
249 /*
250 * If FW is producing debug buffer at a pace faster than
251 * we can consume, then we restrict our iteration.
252 */
253 data->last_entry = entry - data->nentries;
254 }
255
256 /*
257 * Iterate over indexes.
258 */
259 while (entry > data->last_entry) {
260 index = offset = (data->last_entry % data->nentries);
261 offset = (offset * sizeof (struct nss_log_entry))
262 + offsetof(struct nss_log_descriptor, log_ring_buffer);
263
264 dma_sync_single_for_cpu(NULL, data->dma_addr + offset,
265 sizeof(struct nss_log_entry), DMA_FROM_DEVICE);
266 rb = &desc->log_ring_buffer[index];
267
268 b = snprintf(msg, sizeof(msg), NSS_LOG_LINE_FORMAT,
269 rb->thread_num, rb->timestamp, rb->message);
270
271 data->last_entry++;
272
273 /*
274 * Copy to user buffer and if we fail then we return
275 * failure.
276 */
277 if (copy_to_user(buf + bytes, msg, b) == 0) {
278 bytes += b;
279 } else {
280 bytes = -EFAULT;
281 break;
282 }
283
284 /*
285 * If we ran out of space in the buffer.
286 */
287 if ((bytes + NSS_LOG_OUTPUT_LINE_SIZE) >= size)
288 break;
289 }
290
291 if (bytes > 0)
292 *ppos = bytes;
293
294 return bytes;
295}
296
297struct file_operations nss_logs_core_ops = {
298 .owner = THIS_MODULE,
299 .open = nss_log_open,
300 .read = nss_log_read,
301 .release = nss_log_release,
302 .llseek = nss_log_llseek,
303};
304
305/*
306 * nss_debug_interface_set_callback()
307 * Sets the callback
308 */
309void nss_debug_interface_set_callback(nss_log_msg_callback_t cb, void *app_data)
310{
311 nss_debug_interface_cb = cb;
312 nss_debug_interface_app_data = app_data;
313}
314
315/*
316 * nss_debug_interface_event()
317 * Received an event from NSS FW
318 */
319static void nss_debug_interface_event(void *app_data, struct nss_debug_interface_msg *nim)
320{
321 struct nss_cmn_msg *ncm = (struct nss_cmn_msg *)nim;
322
323 msg_response = ncm->response;
324 msg_event = true;
325 wake_up(&msg_wq);
326}
327
328/*
329 * nss_debug_interface_handler()
330 * handle NSS -> HLOS messages for debug interfaces
331 */
332static void nss_debug_interface_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
333{
334 struct nss_debug_interface_msg *ntm = (struct nss_debug_interface_msg *)ncm;
335 nss_log_msg_callback_t cb;
336
337 BUG_ON(ncm->interface != NSS_DEBUG_INTERFACE);
338
339 /*
340 * Is this a valid request/response packet?
341 */
342 if (ncm->type > NSS_DEBUG_INTERFACE_TYPE_MAX) {
343 nss_warning("%p: received invalid message %d for CAPWAP interface", nss_ctx, ncm->type);
344 return;
345 }
346
Suruchi Agarwalef8a8702016-01-08 12:40:08 -0800347 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_debug_interface_msg)) {
348 nss_warning("%p: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Saurabh Misra96998db2014-07-10 12:15:48 -0700349 return;
350 }
351
352 nss_core_log_msg_failures(nss_ctx, ncm);
353
354 /*
355 * Update the callback and app_data for NOTIFY messages.
356 */
357 if (ncm->response == NSS_CMM_RESPONSE_NOTIFY) {
Stephen Wangaed46332016-12-12 17:29:03 -0800358 ncm->cb = (nss_ptr_t)nss_debug_interface_cb;
359 ncm->app_data = (nss_ptr_t)nss_debug_interface_app_data;
Saurabh Misra96998db2014-07-10 12:15:48 -0700360 }
361
362 /*
363 * Do we have a callback
364 */
365 if (!ncm->cb) {
366 nss_trace("%p: cb is null for interface %d", nss_ctx, ncm->interface);
367 return;
368 }
369
370 cb = (nss_log_msg_callback_t)ncm->cb;
371 cb((void *)ncm->app_data, ntm);
372}
373
374/*
375 * nss_debug_interface_tx()
376 * Transmit a debug interface message to NSS FW
377 */
378static nss_tx_status_t nss_debug_interface_tx(struct nss_ctx_instance *nss_ctx, struct nss_debug_interface_msg *msg)
379{
Saurabh Misra96998db2014-07-10 12:15:48 -0700380 struct nss_cmn_msg *ncm = &msg->cm;
Saurabh Misra96998db2014-07-10 12:15:48 -0700381
382 /*
383 * Sanity check the message
384 */
385 if (ncm->interface != NSS_DEBUG_INTERFACE) {
386 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
387 return NSS_TX_FAILURE;
388 }
389
390 if (ncm->type > NSS_DEBUG_INTERFACE_TYPE_MAX) {
391 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
392 return NSS_TX_FAILURE;
393 }
394
Stephen Wang3e2dbd12018-03-14 17:28:17 -0700395 return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE);
Saurabh Misra96998db2014-07-10 12:15:48 -0700396}
397
398/*
399 * nss_debug_log_buffer_alloc()
400 * Allocates and Initializes log buffer for the use in NSS FW (logging)
401 */
402bool nss_debug_log_buffer_alloc(uint8_t nss_id, uint32_t nentry)
403{
404 struct nss_ring_buffer_addr old_rbe;
405 struct nss_debug_interface_msg msg;
406 struct nss_debug_log_memory_msg *dbg;
407 struct nss_top_instance *nss_top;
408 struct nss_ctx_instance *nss_ctx;
409 dma_addr_t dma_addr;
410 uint32_t size;
411 void *addr = NULL;
412 nss_tx_status_t status;
413 bool err = false;
414 bool old_state = false;
415
Radha krishna Simha Jigurudf53f022015-11-09 12:31:26 +0530416 if (nss_id >= NSS_MAX_CORES) {
Saurabh Misra96998db2014-07-10 12:15:48 -0700417 return false;
418 }
419
420 nss_top = &nss_top_main;
421 nss_ctx = &nss_top->nss[nss_id];
422
423 if (nss_ctx->state != NSS_CORE_STATE_INITIALIZED) {
424 nss_warning("%p: NSS Core:%d is not initialized yet\n", nss_ctx, nss_id);
425 return false;
426 }
427
428 memset(&msg, 0, sizeof(struct nss_debug_interface_msg));
429
430 size = sizeof (struct nss_log_descriptor) + (sizeof (struct nss_log_entry) * nentry);
431 addr = kmalloc(size, GFP_ATOMIC);
432 if (!addr) {
433 nss_warning("%p: Failed to allocate memory for logging (size:%d)\n", nss_ctx, size);
434 return false;
435 }
436
437 memset(addr, 0, size);
Stephen Wangefd38512017-01-24 14:01:02 -0800438 dma_addr = (uint32_t)dma_map_single(nss_ctx->dev, addr, size, DMA_FROM_DEVICE);
439 if (unlikely(dma_mapping_error(nss_ctx->dev, dma_addr))) {
Saurabh Misra96998db2014-07-10 12:15:48 -0700440 nss_warning("%p: Failed to map address in DMA", nss_ctx);
441 goto fail2;
442 }
443
444 /*
445 * If we already have ring buffer associated with nss_id, then
446 * we must wait before we attach a new ring buffer.
447 */
448 mutex_lock(&nss_log_mutex);
449 if (nss_rbe[nss_id].addr) {
450 mutex_unlock(&nss_log_mutex);
451 if (!wait_event_timeout(nss_log_wq, nss_rbe[nss_id].refcnt == 0, 5 * HZ)) {
452 nss_warning("%p: Timeout waiting for refcnt to become 0\n", nss_ctx);
453 goto fail1;
454 }
455
456 mutex_lock(&nss_log_mutex);
457 if (!nss_rbe[nss_id].addr) {
458 mutex_unlock(&nss_log_mutex);
459 goto fail1;
460 }
461 if (nss_rbe[nss_id].refcnt > 0) {
462 mutex_unlock(&nss_log_mutex);
463 nss_warning("%p: Some other thread is condenting..opting out\n", nss_ctx);
464 goto fail1;
465 }
466
467 /*
468 * Save the original dma buffer. In case we fail down the line, we will
469 * restore the state. Otherwise, old_state will be freed once we get
470 * ACK from NSS FW.
471 */
472 old_state = true;
473 memcpy(&old_rbe, &nss_rbe[nss_id], sizeof (struct nss_ring_buffer_addr));
474 }
475
476 nss_rbe[nss_id].addr = addr;
477 nss_rbe[nss_id].nentries = nentry;
478 nss_rbe[nss_id].refcnt = 1; /* Block other threads till we are done */
479 nss_rbe[nss_id].dma_addr = dma_addr;
480 mutex_unlock(&nss_log_mutex);
481
482 memset(&msg, 0, sizeof (struct nss_debug_interface_msg));
483 nss_cmn_msg_init(&msg.cm, NSS_DEBUG_INTERFACE, NSS_DEBUG_INTERFACE_TYPE_LOG_BUF_INIT,
484 sizeof(struct nss_debug_log_memory_msg), nss_debug_interface_event, NULL);
485
486 dbg = &msg.msg.addr;
487 dbg->nentry = nentry;
488 dbg->version = NSS_DEBUG_LOG_VERSION;
Saurabh Misra6d42da72015-03-05 14:57:01 -0800489 dbg->phy_addr = dma_addr;
Saurabh Misra96998db2014-07-10 12:15:48 -0700490
491 msg_event = false;
492 status = nss_debug_interface_tx(nss_ctx, &msg);
493 if (status != NSS_TX_SUCCESS) {
494 nss_warning("%p: Failed to send message to debug interface:%d\n", nss_ctx, status);
495 err = true;
496 } else {
497 int r;
498
499 /*
500 * Wait for 5 seconds since this is a critical operation.
501 */
502 r = wait_event_timeout(msg_wq, msg_event == true, 5 * HZ);
503 if (r == 0) {
504 nss_warning("%p: Timeout send message to debug interface\n", nss_ctx);
505 err = true;
506 } else if (msg_response != NSS_CMN_RESPONSE_ACK) {
507 nss_warning("%p: Response error for send message to debug interface:%d\n", nss_ctx, msg_response);
508 err = true;
509 }
510 }
511
512 /*
513 * If we had to free the previous allocation for ring buffer.
514 */
515 if (old_state == true) {
516 /*
517 * If we didn't fail, then we must unmap and free previous dma buffer
518 */
519 if (err == false) {
520 uint32_t old_size;
521
522 old_size = sizeof (struct nss_log_descriptor) +
523 (sizeof (struct nss_log_entry) * old_rbe.nentries);
Stephen Wangefd38512017-01-24 14:01:02 -0800524 dma_unmap_single(nss_ctx->dev, old_rbe.dma_addr, old_size, DMA_FROM_DEVICE);
Saurabh Misra96998db2014-07-10 12:15:48 -0700525 kfree(old_rbe.addr);
526 } else {
527 /*
528 * Restore the original dma buffer since we failed somewhere.
529 */
530 mutex_lock(&nss_log_mutex);
531 memcpy(&nss_rbe[nss_id], &old_rbe, sizeof (struct nss_ring_buffer_addr));
532 mutex_unlock(&nss_log_mutex);
533 wake_up(&nss_log_wq);
534 }
535 } else {
536 /*
537 * There was no logbuffer allocated from host side.
538 */
539
540 /*
541 * If there was error, then we need to reset back. Note that we are
542 * still holding refcnt.
543 */
544 if (err == true) {
545 mutex_lock(&nss_log_mutex);
546 nss_rbe[nss_id].addr = NULL;
547 nss_rbe[nss_id].nentries = 0;
548 nss_rbe[nss_id].refcnt = 0;
549 nss_rbe[nss_id].dma_addr = 0;
550 mutex_unlock(&nss_log_mutex);
551 wake_up(&nss_log_wq);
552 }
553 }
554
555 if (err == false) {
556 mutex_lock(&nss_log_mutex);
557 nss_rbe[nss_id].refcnt--; /* we are done */
558 mutex_unlock(&nss_log_mutex);
559 wake_up(&nss_log_wq);
560 return true;
561 }
562
563fail1:
564 if (addr) {
565 dma_unmap_single(NULL, dma_addr, size, DMA_FROM_DEVICE);
566 }
567fail2:
568 kfree(addr);
569 wake_up(&nss_log_wq);
570 return false;
571}
572
573/*
574 * nss_logbuffer_handler()
575 * Enable NSS debug output
576 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700577int nss_logbuffer_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Saurabh Misra96998db2014-07-10 12:15:48 -0700578{
579 int ret;
Thomas Wucf215082017-08-02 14:23:37 -0700580 int core_status;
Saurabh Misra96998db2014-07-10 12:15:48 -0700581 int i;
582
583 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
584 if (ret) {
585 return ret;
586 }
587
588 if (!write) {
589 return ret;
590 }
591
592 if (nss_ctl_logbuf < 32) {
593 printk("Invalid NSS FW logbuffer size:%d (must be > 32)\n", nss_ctl_logbuf);
594 nss_ctl_logbuf = 0;
595 return ret;
596 }
597
598 for (i = 0; i < NSS_MAX_CORES; i++) {
Thomas Wucf215082017-08-02 14:23:37 -0700599 /*
600 * Register the callback handler and allocate the debug log buffers
601 */
602 core_status = nss_core_register_handler(&nss_top_main.nss[i], NSS_DEBUG_INTERFACE, nss_debug_interface_handler, NULL);
603 if (core_status != NSS_CORE_STATUS_SUCCESS) {
604 nss_warning("NSS logbuffer init failed with register handler:%d\n", core_status);
605 }
606
Saurabh Misra96998db2014-07-10 12:15:48 -0700607 if (nss_debug_log_buffer_alloc(i, nss_ctl_logbuf) == false) {
608 nss_warning("%d: Failed to set debug log buffer on NSS core", i);
609 }
610 }
611
612 return ret;
613}
614
615/*
616 * nss_log_init()
617 * Initializes NSS FW logs retrieval logic from /sys
618 */
619void nss_log_init(void)
620{
Saurabh Misra96998db2014-07-10 12:15:48 -0700621 int i;
Yu Huang8c107082017-07-24 14:58:26 -0700622 struct dentry *logs_dentry;
623 struct dentry *core_log_dentry;
Saurabh Misra96998db2014-07-10 12:15:48 -0700624
625 memset(nss_rbe, 0, sizeof(nss_rbe));
626 init_waitqueue_head(&nss_log_wq);
627 init_waitqueue_head(&msg_wq);
628
629 /*
630 * Create directory for obtaining NSS FW logs from each core
631 */
Yu Huang8c107082017-07-24 14:58:26 -0700632 logs_dentry = debugfs_create_dir("logs", nss_top_main.top_dentry);
633 if (unlikely(!logs_dentry)) {
Saurabh Misra96998db2014-07-10 12:15:48 -0700634 nss_warning("Failed to create qca-nss-drv/logs directory in debugfs");
635 return;
636 }
637
638 for (i = 0; i < NSS_MAX_CORES; i++) {
639 char file[10];
640 extern struct file_operations nss_logs_core_ops;
641
642 snprintf(file, sizeof(file), "core%d", i);
Yu Huang8c107082017-07-24 14:58:26 -0700643 core_log_dentry = debugfs_create_file(file, 0400,
644 logs_dentry, (void *)(nss_ptr_t)i, &nss_logs_core_ops);
645 if (unlikely(!core_log_dentry)) {
Saurabh Misra96998db2014-07-10 12:15:48 -0700646 nss_warning("Failed to create qca-nss-drv/logs/%s file in debugfs", file);
647 return;
648 }
649 }
650
651 nss_debug_interface_set_callback(nss_debug_interface_event, NULL);
Saurabh Misra96998db2014-07-10 12:15:48 -0700652}