Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f136d386 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: cnss: add CNSS logger service to support advanced CLD logging"

parents b769b045 2584e1ae
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -74,3 +74,5 @@ config BUS_AUTO_SUSPEND
	  during system pm.
	  during system pm.
	  This config flag controls the feature per target based. The feature
	  This config flag controls the feature per target based. The feature
	  requires CNSS driver support.
	  requires CNSS driver support.

source "drivers/net/wireless/cnss/logger/Kconfig"
+2 −0
Original line number Original line Diff line number Diff line
@@ -2,4 +2,6 @@


obj-$(CONFIG_CNSS)	+= cnss_pci.o
obj-$(CONFIG_CNSS)	+= cnss_pci.o
obj-$(CONFIG_CNSS)	+= cnss_sdio.o
obj-$(CONFIG_CNSS)	+= cnss_sdio.o
obj-$(CONFIG_CNSS_LOGGER)	+= logger/

obj-$(CONFIG_CNSS)	+= cnss_common.o
obj-$(CONFIG_CNSS)	+= cnss_common.o
+6 −0
Original line number Original line Diff line number Diff line
config CNSS_LOGGER
	tristate "CNSS Logging Service Driver"
	---help---
	  This module adds support for the CNSS Logging Service for CLD
	  driver, including the netlink socket service registration, transmit,
	  event receive.
+6 −0
Original line number Original line Diff line number Diff line
obj-$(CONFIG_CNSS_LOGGER) += logger.o

logger-y += main.o	\
	    nl_service.o

logger-$(CONFIG_DEBUG_FS) += debugfs.o
+134 −0
Original line number Original line Diff line number Diff line
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include <linux/debugfs.h>

#include "logger.h"

#define CNSS_LOGGER_STATE_DUMP_BUFFER	(2 * 1024) /* 2KB */

static int logger_state_dump_device(struct logger_device *dev, char *buf,
				    int buf_len)
{
	int len = 0;
	struct logger_event_handler *cur;

	len += scnprintf(buf + len, buf_len - len,
			"==============================================\n");

	len += scnprintf(buf + len, buf_len - len,
			"driver [%s] is registered with radio index: %d\n",
			dev->name, dev->radio_idx);

	if (list_empty(&dev->event_list)) {
		len += scnprintf(buf + len, buf_len - len,
				 "No event registered!\n");
		return len;
	}

	list_for_each_entry(cur, &dev->event_list, list) {
		len += scnprintf(buf + len, buf_len - len,
				"\t event %d\n", cur->event);
	}
	len += scnprintf(buf + len, buf_len - len, "\n");

	return len;
}

static int logger_state_dump(struct logger_context *ctx, char *buf, int buf_len)
{
	int len = 0;
	struct logger_device *cur;

	if (list_empty(&ctx->dev_list)) {
		len += scnprintf(buf + len, buf_len - len,
				 "=======================\n");
		len += scnprintf(buf + len, buf_len - len,
				 "No driver registered!\n");
		return 0;
	}

	list_for_each_entry(cur, &ctx->dev_list, list)
		len += logger_state_dump_device(cur, (buf + len), buf_len);

	return 0;
}

static int logger_state_open(struct inode *inode, struct file *file)
{
	struct logger_context *ctx = inode->i_private;
	void *buf;
	int ret;

	mutex_lock(&ctx->con_mutex);

	buf = kmalloc(CNSS_LOGGER_STATE_DUMP_BUFFER, GFP_KERNEL);
	if (!buf) {
		ret = -ENOMEM;
		goto error_unlock;
	}

	ret = logger_state_dump(ctx, buf, CNSS_LOGGER_STATE_DUMP_BUFFER);
	if (ret)
		goto error_free;

	file->private_data = buf;
	mutex_unlock(&ctx->con_mutex);
	return 0;

error_free:
	kfree(buf);

error_unlock:
	mutex_unlock(&ctx->con_mutex);

	return ret;
}

static int logger_state_release(struct inode *inode, struct file *file)
{
	kfree(file->private_data);
	return 0;
}

static ssize_t logger_state_read(struct file *file, char __user *user_buf,
				 size_t count, loff_t *ppos)
{
	const char *buf = file->private_data;
	unsigned int len = strlen(buf);

	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}

static const struct file_operations fops_logger_state = {
	.open = logger_state_open,
	.release = logger_state_release,
	.read = logger_state_read,
	.owner = THIS_MODULE,
	.llseek = default_llseek,
};

void logger_debugfs_init(struct logger_context *ctx)
{
	if (!ctx->debugfs_entry)
		ctx->debugfs_entry = debugfs_create_dir("cnss_logger", NULL);

	debugfs_create_file("state", S_IRUSR, ctx->debugfs_entry, ctx,
			    &fops_logger_state);
}

void logger_debugfs_remove(struct logger_context *ctx)
{
	debugfs_remove(ctx->debugfs_entry);
}
Loading