/*
 * Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#if defined(CONFIG_ATH_PROCFS_DIAG_SUPPORT)
#include <linux/module.h>       /* Specifically, a module */
#include <linux/kernel.h>       /* We're doing kernel work */
#include <linux/version.h>      /* We're doing kernel work */
#include <linux/proc_fs.h>      /* Necessary because we use the proc fs */
#include <linux/uaccess.h>        /* for copy_from_user */
#include "hif.h"
#include "hif_main.h"
#if defined(HIF_USB)
#include "if_usb.h"
#endif
#if defined(HIF_SDIO)
#include "if_sdio.h"
#endif
#include "hif_debug.h"
#include "pld_common.h"
#include "target_type.h"

#define PROCFS_NAME             "athdiagpfs"
#ifdef MULTI_IF_NAME
#define PROCFS_DIR              "cld" MULTI_IF_NAME
#else
#define PROCFS_DIR              "cld"
#endif

/**
 * This structure hold information about the /proc file
 *
 */
static struct proc_dir_entry *proc_file, *proc_dir;

static void *get_hif_hdl_from_file(struct file *file)
{
	struct hif_opaque_softc *scn;

	scn = (struct hif_opaque_softc *)PDE_DATA(file_inode(file));
	return (void *)scn;
}

static ssize_t ath_procfs_diag_read(struct file *file, char __user *buf,
				    size_t count, loff_t *pos)
{
	hif_handle_t hif_hdl;
	int rv;
	uint8_t *read_buffer = NULL;
	struct hif_softc *scn;
	uint32_t offset = 0, memtype = 0;
	struct hif_target_info *tgt_info;

	hif_hdl = get_hif_hdl_from_file(file);
	scn = HIF_GET_SOFTC(hif_hdl);

	if (scn->bus_ops.hif_addr_in_boundary(hif_hdl, (uint32_t)(*pos)))
		return -EINVAL;

	read_buffer = qdf_mem_malloc(count);
	if (NULL == read_buffer) {
		HIF_ERROR("%s: cdf_mem_alloc failed", __func__);
		return -ENOMEM;
	}

	HIF_DBG("rd buff 0x%pK cnt %zu offset 0x%x buf 0x%pK",
		 read_buffer, count, (int)*pos, buf);

	tgt_info = hif_get_target_info_handle(GET_HIF_OPAQUE_HDL(hif_hdl));
	if ((scn->bus_type == QDF_BUS_TYPE_SNOC) ||
	    (scn->bus_type ==  QDF_BUS_TYPE_PCI &&
	    ((tgt_info->target_type == TARGET_TYPE_QCA6290) ||
	     (tgt_info->target_type == TARGET_TYPE_QCA6390) ||
	     (tgt_info->target_type == TARGET_TYPE_QCA8074) ||
	     (tgt_info->target_type == TARGET_TYPE_QCA8074V2) ||
	     (tgt_info->target_type == TARGET_TYPE_QCA6018)))) {
		memtype = ((uint32_t)(*pos) & 0xff000000) >> 24;
		offset = (uint32_t)(*pos) & 0xffffff;
		HIF_TRACE("%s: offset 0x%x memtype 0x%x, datalen %zu\n",
			  __func__, offset, memtype, count);
		rv = pld_athdiag_read(scn->qdf_dev->dev,
				      offset, memtype, count,
				      (uint8_t *)read_buffer);
		goto out;
	}

	if ((count == 4) && ((((uint32_t) (*pos)) & 3) == 0)) {
		/* reading a word? */
		rv = hif_diag_read_access(hif_hdl, (uint32_t)(*pos),
					  (uint32_t *)read_buffer);
	} else {
		rv = hif_diag_read_mem(hif_hdl, (uint32_t)(*pos),
				       (uint8_t *)read_buffer, count);
	}

out:
	if (rv) {
		qdf_mem_free(read_buffer);
		return -EIO;
	}

	if (copy_to_user(buf, read_buffer, count)) {
		qdf_mem_free(read_buffer);
		HIF_ERROR("%s: copy_to_user error in /proc/%s",
			__func__, PROCFS_NAME);
		return -EFAULT;
	}
	qdf_mem_free(read_buffer);
	return count;
}

static ssize_t ath_procfs_diag_write(struct file *file,
				     const char __user *buf,
				     size_t count, loff_t *pos)
{
	hif_handle_t hif_hdl;
	int rv;
	uint8_t *write_buffer = NULL;
	struct hif_softc *scn;
	uint32_t offset = 0, memtype = 0;
	struct hif_target_info *tgt_info;

	hif_hdl = get_hif_hdl_from_file(file);
	scn = HIF_GET_SOFTC(hif_hdl);

	if (scn->bus_ops.hif_addr_in_boundary(hif_hdl, (uint32_t)(*pos)))
		return -EINVAL;

	write_buffer = qdf_mem_malloc(count);
	if (NULL == write_buffer) {
		HIF_ERROR("%s: cdf_mem_alloc failed", __func__);
		return -ENOMEM;
	}
	if (copy_from_user(write_buffer, buf, count)) {
		qdf_mem_free(write_buffer);
		HIF_ERROR("%s: copy_to_user error in /proc/%s",
			__func__, PROCFS_NAME);
		return -EFAULT;
	}

	HIF_DBG("wr buff 0x%pK buf 0x%pK cnt %zu offset 0x%x value 0x%x",
		 write_buffer, buf, count,
		 (int)*pos, *((uint32_t *) write_buffer));

	tgt_info = hif_get_target_info_handle(GET_HIF_OPAQUE_HDL(hif_hdl));
	if ((scn->bus_type == QDF_BUS_TYPE_SNOC) ||
	    ((scn->bus_type ==  QDF_BUS_TYPE_PCI) &&
	     ((tgt_info->target_type == TARGET_TYPE_QCA6290) ||
	      (tgt_info->target_type == TARGET_TYPE_QCA6390) ||
	      (tgt_info->target_type == TARGET_TYPE_QCA8074) ||
	      (tgt_info->target_type == TARGET_TYPE_QCA8074V2) ||
	      (tgt_info->target_type == TARGET_TYPE_QCA6018)))) {
		memtype = ((uint32_t)(*pos) & 0xff000000) >> 24;
		offset = (uint32_t)(*pos) & 0xffffff;
		HIF_TRACE("%s: offset 0x%x memtype 0x%x, datalen %zu\n",
			  __func__, offset, memtype, count);
		rv = pld_athdiag_write(scn->qdf_dev->dev,
				      offset, memtype, count,
				      (uint8_t *)write_buffer);
		goto out;
	}

	if ((count == 4) && ((((uint32_t) (*pos)) & 3) == 0)) {
		/* reading a word? */
		uint32_t value = *((uint32_t *)write_buffer);

		rv = hif_diag_write_access(hif_hdl, (uint32_t)(*pos), value);
	} else {
		rv = hif_diag_write_mem(hif_hdl, (uint32_t)(*pos),
					(uint8_t *)write_buffer, count);
	}

out:

	qdf_mem_free(write_buffer);
	if (rv == 0)
		return count;
	else
		return -EIO;
}

static const struct file_operations athdiag_fops = {
	.read = ath_procfs_diag_read,
	.write = ath_procfs_diag_write,
};

/*
 * This function is called when the module is loaded
 *
 */
int athdiag_procfs_init(void *scn)
{
	proc_dir = proc_mkdir(PROCFS_DIR, NULL);
	if (proc_dir == NULL) {
		remove_proc_entry(PROCFS_DIR, NULL);
		HIF_ERROR("%s: Error: Could not initialize /proc/%s",
			__func__, PROCFS_DIR);
		return -ENOMEM;
	}

	proc_file = proc_create_data(PROCFS_NAME, 0600, proc_dir,
				     &athdiag_fops, (void *)scn);
	if (proc_file == NULL) {
		remove_proc_entry(PROCFS_NAME, proc_dir);
		HIF_ERROR("%s: Could not initialize /proc/%s",
			__func__, PROCFS_NAME);
		return -ENOMEM;
	}

	HIF_DBG("/proc/%s/%s created", PROCFS_DIR, PROCFS_NAME);
	return 0;               /* everything is ok */
}

/*
 * This function is called when the module is unloaded
 *
 */
void athdiag_procfs_remove(void)
{
	if (proc_dir != NULL) {
		remove_proc_entry(PROCFS_NAME, proc_dir);
		HIF_DBG("/proc/%s/%s removed", PROCFS_DIR, PROCFS_NAME);
		remove_proc_entry(PROCFS_DIR, NULL);
		HIF_DBG("/proc/%s removed", PROCFS_DIR);
		proc_dir = NULL;
	}
}
#else
int athdiag_procfs_init(void *scn)
{
	return 0;
}
void athdiag_procfs_remove(void) {}
#endif
