/*
<:copyright-BRCM:2016:DUAL/GPL:standard

   Broadcom Proprietary and Confidential.(c) 2016 Broadcom
   All Rights Reserved

Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:

   As a special exception, the copyright holders of this software give
   you permission to link this software with independent modules, and
   to copy and distribute the resulting executable under terms of your
   choice, provided that you also meet, for each linked independent
   module, the terms and conditions of the license of that module.
   An independent module is a module which is not derived from this
   software.  The special exception does not apply to any modifications
   of the software.

Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.

:>
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>       /* everything... */
#include <linux/fcntl.h>    /* O_ACCMODE */
#include <linux/aio.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/vmalloc.h>

#include <bcm_dev_log_task.h>
#include <bcmolt_dev_log_kernel.h>
#include <bcmolt_dev_log_ioctl.h>

int dev_log_chrdev_major = 215;         /* Should comply the value in targets/makeDev */
module_param(dev_log_chrdev_major, int, S_IRUSR | S_IRGRP | S_IWGRP);
MODULE_PARM_DESC(dev_log_chrdev_major, "devlog_major");

int dev_log_buffer_size_kb = 2048;      /* Buffer size in kB */
module_param(dev_log_buffer_size_kb, int, S_IRUSR | S_IRGRP | S_IWGRP);
MODULE_PARM_DESC(dev_log_buffer_size_kb, "devlog_bufsize_kb");

int dev_log_queue_size = 256;           /* Queue size */
module_param(dev_log_queue_size, int, S_IRUSR | S_IRGRP | S_IWGRP);
MODULE_PARM_DESC(dev_log_queue_size, "devlog_qsize");

static bcmos_mutex dev_log_lock;
static int dev_log_num_users;
static char *dev_log_buffer;

/*
 * Open and close
 */
static int dev_log_chrdev_open(struct inode *inode, struct file *filp)
{
    BCMOS_TRACE_DEBUG("\n");
    bcmos_mutex_lock(&dev_log_lock);
    if (dev_log_num_users >= 1)
    {
        bcmos_mutex_unlock(&dev_log_lock);
        return -EBUSY;
    }
    ++dev_log_num_users;
    bcmos_mutex_unlock(&dev_log_lock);
    return 0;
}


static int dev_log_chrdev_release(struct inode *inode, struct file *filp)
{
    BCMOS_TRACE_DEBUG("\n");
    --dev_log_num_users;
    return 0;
}

static ssize_t dev_log_chrdev_write(struct file *filp, const char __user *buf,
    size_t count, loff_t *f_pos)
{
    return -EOPNOTSUPP;
}

static long dev_log_chrdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    int linux_rc = 0;
    bcmos_errno rc;
    dev_log_io_param io_param;
    dev_log_id id;

    /* don't even decode wrong cmds: better returning  ENOTTY than EFAULT */
    if (_IOC_TYPE(cmd) != DEV_LOG_CHRDEV_IOC_MAGIC)
        return -ENOTTY;

    /*
     * the type is a bitmask, and VERIFY_WRITE catches R/W
     * transfers. Note that the type is user-oriented, while
     * verify_area is kernel-oriented, so the concept of "read" and
     * "write" is reversed
     */
    if (_IOC_DIR(cmd) & _IOC_READ)
        linux_rc = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
    else if (_IOC_DIR(cmd) & _IOC_WRITE)
        linux_rc =  !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
    if (linux_rc)
        return -EFAULT;

    switch (cmd)
    {

    case DEV_LOG_CHRDEV_DB_READ:
    {
        int i;

        for (i = 0; i < bcm_dev_log_get_num_of_entries(); i++)
        {
            dev_log_id_parm id_parm = {};

            id = bcm_dev_log_id_get_by_index(i);
            if (id == DEV_LOG_INVALID_ID)
            {
                break;
            }
            bcm_dev_log_id_get(id, &id_parm);
            io_param.db_read.ids[i].index = i;
            strncpy(io_param.db_read.ids[i].name, id_parm.name, sizeof(io_param.db_read.ids[i].name));
            io_param.db_read.ids[i].default_type = id_parm.default_log_type;
            io_param.db_read.ids[i].default_level = id_parm.default_log_level;
            /* Reset to defaults to keep in sync with the user space */
            bcm_dev_log_id_set_levels_and_type_to_default(id);
        }
        io_param.db_read.num_ids = i;
        linux_rc = copy_to_user((char *)arg, (char *)&io_param.db_read, sizeof(io_param.db_read));
    }
    break;

    case DEV_LOG_CHRDEV_LEVEL_SET:
    {
        linux_rc = copy_from_user((char *)&io_param.level_set, (char *)arg, sizeof(io_param.level_set));
        if (linux_rc < 0)
            break;
        id = bcm_dev_log_id_get_by_index(io_param.level_set.index);
        if (id == DEV_LOG_INVALID_ID)
        {
            BCMOS_TRACE_ERR("log_id index %u is invalid\n", io_param.level_set.index);
        }
        rc = bcm_dev_log_id_set_level(id, io_param.level_set.level_print, io_param.level_set.level_save);
        if (rc)
        {
            BCMOS_TRACE_ERR("bcm_dev_log_id_set_level(%ld,%d,%d)->%s\n",
                (long)id, (int)io_param.level_set.level_print, (int)io_param.level_set.level_save, bcmos_strerror(rc));
            linux_rc = -EINVAL;
        }
    }
    break;

    case DEV_LOG_CHRDEV_TYPE_SET:
    {
        linux_rc = copy_from_user((char *)&io_param.type_set, (char *)arg, sizeof(io_param.type_set));
        if (linux_rc < 0)
            break;
        /* Map index to log id */
        id = bcm_dev_log_id_get_by_index(io_param.type_set.index);
        if (id == DEV_LOG_INVALID_ID)
        {
            BCMOS_TRACE_ERR("log_id index %u is invalid\n", io_param.type_set.index);
        }
        rc = bcm_dev_log_id_set_type(id, io_param.type_set.type);
        if (rc)
        {
            BCMOS_TRACE_ERR("bcm_dev_log_id_set_type(%ld,%d)->%s\n",
                (long)id, (int)io_param.type_set.type, bcmos_strerror(rc));
            linux_rc = -EINVAL;
        }
    }
    break;

    case DEV_LOG_CHRDEV_MSG_READ:
    {
        uint32_t buf_len = sizeof(io_param.msg_read.msg);
        bcm_dev_log_file *log_file = bcm_dev_log_file_get(0);

        if (!log_file)
        {
            linux_rc = -EINVAL;
            break;
        }

        linux_rc = copy_from_user((char *)&io_param.msg_read, (char *)arg, sizeof(io_param.msg_read.offset));
        if (linux_rc < 0)
            break;

        rc = bcm_dev_log_file_read(log_file, &io_param.msg_read.offset, io_param.msg_read.msg, buf_len);
        if (rc <= 0)
        {
            if (rc == 0)
                linux_rc = -EAGAIN;
            else
                linux_rc = -EINVAL;
            break;
        }
        linux_rc = copy_to_user((char *)arg, (char *)&io_param.msg_read,
            offsetof(dev_log_io_param, msg_read.msg) + rc);
    }
    break;

    default:  /* redundant, as cmd was checked against MAXNR */
        rc = -ENOTTY;
        break;
    }

    return linux_rc;
}

/*
 * The fops
 */
static struct file_operations dev_log_chrdev_fops =
{
    .owner = THIS_MODULE,
    .open = dev_log_chrdev_open,
    .release = dev_log_chrdev_release,
    .write = dev_log_chrdev_write,
    .unlocked_ioctl = dev_log_chrdev_ioctl
};

static struct cdev dev_log_chrdev_cdev;
static int is_chrdev_reg, is_cdev_add;

static bcmos_errno dev_log_chrdev_init(void)
{
    dev_t dev = MKDEV(dev_log_chrdev_major, 0);
    int linux_rc;

    is_chrdev_reg = 0;
    is_cdev_add = 0;
    /*
     * Register your major, and accept a dynamic number.
     */
    if (!dev_log_chrdev_major)
        return -1;
    linux_rc = register_chrdev_region(dev, 0, "dev_log");
    if (linux_rc < 0)
    {
        BCMOS_TRACE_RETURN(BCM_ERR_IO, "register_chrdev_region()->%d\n", linux_rc);
    }
    is_chrdev_reg = 1;

    cdev_init(&dev_log_chrdev_cdev, &dev_log_chrdev_fops);
    linux_rc = cdev_add(&dev_log_chrdev_cdev, dev, 1);
    if (linux_rc < 0)
    {
        BCMOS_TRACE_RETURN(BCM_ERR_IO, "cdev_add()->%d\n", linux_rc);
    }
    is_cdev_add = 1;

    return BCM_ERR_OK;
}

static void dev_log_chrdev_exit(void)
{
    if (is_cdev_add)
        cdev_del(&dev_log_chrdev_cdev);
    if (is_chrdev_reg)
        unregister_chrdev_region(MKDEV(dev_log_chrdev_major, 0), 1);
}

static int dev_log_time_to_str_cb(uint32_t time_stamp, char *time_str, int time_str_size)
{
    return snprintf(time_str, time_str_size, "%u", time_stamp / 1000); /* Convert from usec to msec. */
}

/** Initialize dev_log linux kernel support */
bcmos_errno bcm_dev_log_linux_init(void)
{
    void *addresses[1];
    uint32_t sizes[1] = { dev_log_buffer_size_kb * 1024 };
    uint32_t flags[1] = { BCM_DEV_LOG_FILE_FLAG_WRAP_AROUND };
    bcmos_errno rc;

    if (!dev_log_queue_size || !dev_log_buffer_size_kb)
        return BCM_ERR_PARM;

    rc = dev_log_chrdev_init();
    if (rc)
        return rc;

    /* Initialize logger */
    dev_log_buffer = vmalloc(dev_log_buffer_size_kb * 1024);
    if (!dev_log_buffer)
    {
        dev_log_chrdev_exit();
        BCMOS_TRACE_ERR("Can't allocate dev_log buffer (%d bytes)\n", dev_log_buffer_size_kb * 1024);
        return BCM_ERR_NOMEM;
    }
    addresses[0] = dev_log_buffer;
    rc = bcm_dev_log_init_default_logger(addresses, sizes, flags, BCM_SIZEOFARRAY(addresses), 0x4000, TASK_PRIORITY_DEV_LOG, dev_log_queue_size);
    if (rc)
    {
        dev_log_chrdev_exit();
        vfree(dev_log_buffer);
        BCMOS_TRACE_ERR("Failed to create logger. Error %s\n", bcmos_strerror(rc));
        return rc;
    }

    bcm_dev_log_set_time_to_str_cb(dev_log_time_to_str_cb);

    bcmos_mutex_create(&dev_log_lock, 0, NULL);

    return BCM_ERR_OK;
}

/** Clean-up dev_log linux kernel support */
void bcm_dev_log_linux_exit(void)
{
    dev_log_chrdev_exit();
    if (dev_log_buffer)
    {
        vfree(dev_log_buffer);
    }
    bcmos_mutex_destroy(&dev_log_lock);
}
