/*
 * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * 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.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/**
 * DOC : wlan_hdd_memdump.c
 *
 * WLAN Host Device Driver file for dumping firmware memory
 *
 */

#include <sme_api.h>
#include <wlan_hdd_includes.h>
#include "wlan_hdd_memdump.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
#include <linux/uaccess.h> /* for copy_to_user */

/**
 * hdd_fw_dump_context - hdd firmware memory dump context
 *
 * @request_id: userspace assigned firmware memory dump request ID
 * @response_event: firmware memory dump request wait event
 */
struct hdd_fw_dump_context {
	uint32_t request_id;
	struct completion response_event;
};
static struct hdd_fw_dump_context fw_dump_context;

/**
 * memdump_cleanup_timer_cb() - Timer callback function for memory dump cleanup.
 *
 * @data: Callback data (used to stored HDD context)
 *
 * Callback function registered for memory dump cleanup VOS timer.
 *
 * Return: none
 */

static void memdump_cleanup_timer_cb(void *data)
{
	int status;
	struct hdd_context *hdd_ctx = data;
	qdf_dma_addr_t paddr;
	qdf_dma_addr_t dma_ctx = 0;
	qdf_device_t qdf_ctx;

	status = wlan_hdd_validate_context(hdd_ctx);
	if (status)
		return;


	if (!hdd_ctx->fw_dump_loc) {
		hdd_debug("Memory dump already freed");
		return;
	}

	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
	if (!qdf_ctx) {
		hdd_err("QDF context is NULL");
		return;
	}

	paddr = hdd_ctx->dump_loc_paddr;
	mutex_lock(&hdd_ctx->memdump_lock);
	qdf_mem_free_consistent(qdf_ctx, qdf_ctx->dev,
		FW_MEM_DUMP_SIZE, hdd_ctx->fw_dump_loc, paddr, dma_ctx);
	hdd_ctx->fw_dump_loc = NULL;
	hdd_ctx->memdump_in_progress = false;
	mutex_unlock(&hdd_ctx->memdump_lock);

}

/**
 * wlan_hdd_cfg80211_fw_mem_dump_cb() -  Callback to receive FW memory dump
 * @ctx: pointer to HDD context.
 * @dump_rsp: pointer to fw dump copy complete response
 *
 * This is a callback function used to indicate user space about the
 * availability for firmware memory dump via vendor event.
 *
 * Return: None
 */
void wlan_hdd_cfg80211_fw_mem_dump_cb(void *ctx,
					     struct fw_dump_rsp *dump_rsp)
{
	struct hdd_context *hdd_ctx = ctx;
	struct hdd_fw_dump_context *context;
	int status;

	status = wlan_hdd_validate_context(hdd_ctx);
	if (status)
		return;


	spin_lock(&hdd_context_lock);
	context = &fw_dump_context;
	/* validate the response received */
	if (!dump_rsp->dump_complete ||
	    context->request_id != dump_rsp->request_id) {
		spin_unlock(&hdd_context_lock);
		hdd_err("request_id: %d response_id: %d status: %d",
		       context->request_id, dump_rsp->request_id,
		       dump_rsp->dump_complete);
		return;
	}
	complete(&context->response_event);
	spin_unlock(&hdd_context_lock);

	return;
}

/**
 * wlan_hdd_send_memdump_rsp - send memory dump response to user space
 * @hdd_ctx: Pointer to hdd context
 *
 * Return: 0 for success; non-zero for failure
 */
static int wlan_hdd_send_memdump_rsp(struct hdd_context *hdd_ctx)
{
	struct sk_buff *skb;
	int status;

	status = wlan_hdd_validate_context(hdd_ctx);
	if (status)
		return status;


	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
			NLMSG_HDRLEN + NLA_HDRLEN + sizeof(uint32_t));

	if (!skb) {
		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
		return -ENOMEM;
	}

	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MEMDUMP_SIZE,
			     FW_MEM_DUMP_SIZE)) {
		hdd_err("nla put fail");
		goto nla_put_failure;
	}

	cfg80211_vendor_cmd_reply(skb);
	hdd_debug("Memdump event sent successfully to user space");
	return 0;

nla_put_failure:
	kfree_skb(skb);
	return -EINVAL;
}

/**
 * __wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
 * @wiphy:   pointer to wireless wiphy structure.
 * @wdev:    pointer to wireless_dev structure.
 * @data:    Pointer to the NL data.
 * @data_len:Length of @data
 *
 * This is called when wlan driver needs to get the firmware memory dump
 * via vendor specific command.
 *
 * Return:   0 on success, error number otherwise.
 */
static int __wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
					       struct wireless_dev *wdev,
					       const void *data, int data_len)
{
	int status;
	QDF_STATUS sme_status;
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct fw_dump_req fw_mem_dump_req;
	struct fw_dump_seg_req *seg_req;
	uint8_t loop;
	qdf_dma_addr_t paddr;
	qdf_dma_addr_t dma_ctx = 0;
	qdf_device_t qdf_ctx;
	unsigned long rc;
	struct hdd_fw_dump_context *context;

	ENTER_DEV(wdev->netdev);

	status = wlan_hdd_validate_context(hdd_ctx);
	if (status)
		return status;

	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
	if (!qdf_ctx) {
		hdd_err("QDF context is NULL");
		return -EINVAL;
	}

	if (hdd_ctx->memdump_in_progress) {
		hdd_err("Already a memdump req in progress.");
		return -EBUSY;
	}

	/*
	 * Allocate memory for fw memory dump. Memory allocated should be
	 * contiguous. Physical address of the allocated memory is passed
	 * to the FW for copy
	 *
	 * Reuse the memory if available.
	 */
	mutex_lock(&hdd_ctx->memdump_lock);
	if (!hdd_ctx->fw_dump_loc) {
		hdd_ctx->fw_dump_loc = qdf_mem_alloc_consistent(
			qdf_ctx, qdf_ctx->dev, FW_MEM_DUMP_SIZE, &paddr);
		if (!hdd_ctx->fw_dump_loc) {
			mutex_unlock(&hdd_ctx->memdump_lock);
			hdd_err("qdf_mem_alloc_consistent failed");
			return -ENOMEM;
		}
		hdd_ctx->dump_loc_paddr = paddr;
	} else {
		paddr = hdd_ctx->dump_loc_paddr;
	}
	mutex_unlock(&hdd_ctx->memdump_lock);

	/*
	 * Currently request_id and num_seg is assumed to be default(1)
	 * It is assumed that firmware dump requested is for DRAM section
	 * only
	 */

	fw_mem_dump_req.request_id = FW_MEM_DUMP_REQ_ID;
	fw_mem_dump_req.num_seg = FW_MEM_DUMP_NUM_SEG;

	hdd_debug("request_id:%d num_seg:%d",
		fw_mem_dump_req.request_id, fw_mem_dump_req.num_seg);
	seg_req = (struct fw_dump_seg_req *) fw_mem_dump_req.segment;
	for (loop = 0; loop < fw_mem_dump_req.num_seg; loop++) {
		seg_req->seg_id = 1;
		seg_req->seg_start_addr_lo = FW_DRAM_LOCATION;
		seg_req->seg_start_addr_hi = 0;
		seg_req->seg_length = FW_MEM_DUMP_SIZE;
		seg_req->dst_addr_lo = hdd_ctx->dump_loc_paddr;
		seg_req->dst_addr_hi = 0;
		hdd_debug("seg_number:%d", loop);
		hdd_debug("seg_id:%d start_addr_lo:0x%x start_addr_hi:0x%x",
		    seg_req->seg_id, seg_req->seg_start_addr_lo,
		    seg_req->seg_start_addr_hi);
		hdd_debug("seg_length:%d dst_addr_lo:0x%x dst_addr_hi:0x%x",
		    seg_req->seg_length, seg_req->dst_addr_lo,
		    seg_req->dst_addr_hi);
		seg_req++;
	}

	/**
	 * Start the cleanup timer.
	 * Memory allocated for this request will be freed up
	 * once the timer expires. Memory dump request is expected to be
	 * completed by this time.
	 *
	 * User space will not be able to access the dump after this time.
	 * New request should be issued to get the dump again.
	 */
	qdf_mc_timer_start(&hdd_ctx->memdump_cleanup_timer,
			MEMDUMP_COMPLETION_TIME_MS);
	hdd_ctx->memdump_in_progress = true;

	spin_lock(&hdd_context_lock);
	context = &fw_dump_context;
	context->request_id = fw_mem_dump_req.request_id;
	INIT_COMPLETION(context->response_event);
	spin_unlock(&hdd_context_lock);

	sme_status = sme_fw_mem_dump(hdd_ctx->hHal, &fw_mem_dump_req);
	if (QDF_STATUS_SUCCESS != sme_status) {
		hdd_err("sme_fw_mem_dump Failed");
		mutex_lock(&hdd_ctx->memdump_lock);
		qdf_mem_free_consistent(qdf_ctx, qdf_ctx->dev,
			FW_MEM_DUMP_SIZE, hdd_ctx->fw_dump_loc, paddr, dma_ctx);
		hdd_ctx->fw_dump_loc = NULL;
		mutex_unlock(&hdd_ctx->memdump_lock);
		hdd_ctx->memdump_in_progress = false;
		if (QDF_TIMER_STATE_RUNNING ==
			qdf_mc_timer_get_current_state(
				&hdd_ctx->memdump_cleanup_timer)) {
			qdf_mc_timer_stop(&hdd_ctx->memdump_cleanup_timer);
		}
		return -EINVAL;
	}

	rc = wait_for_completion_timeout(&context->response_event,
		msecs_to_jiffies(MEMDUMP_COMPLETION_TIME_MS));
	if (!rc) {
		hdd_err("Target response timed out for request_id: %d",
		       context->request_id);
		return -ETIMEDOUT;
	}

	status = wlan_hdd_send_memdump_rsp(hdd_ctx);
	if (status)
		hdd_err("Failed to send FW memory dump rsp to user space");

	return status;
}

/**
 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
 * @wiphy:   pointer to wireless wiphy structure.
 * @wdev:    pointer to wireless_dev structure.
 * @data:    Pointer to the NL data.
 * @data_len:Length of @data
 *
 * This is called when wlan driver needs to get the firmware memory dump
 * via vendor specific command.
 *
 * Return:   0 on success, error number otherwise.
 */
int wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
				      struct wireless_dev *wdev,
				      const void *data, int data_len)
{
	int ret;

	cds_ssr_protect(__func__);
	ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data, data_len);
	cds_ssr_unprotect(__func__);

	return ret;
}

#define PROCFS_MEMDUMP_DIR "debug"
#define PROCFS_MEMDUMP_NAME "fwdump"
#define PROCFS_MEMDUMP_PERM 0444

static struct proc_dir_entry *proc_file, *proc_dir;

/** memdump_get_file_data() - get data available in proc file
 *
 * @file - handle for the proc file.
 *
 * This function is used to retrieve the data passed while
 * creating proc file entry.
 *
 * Return: void pointer to hdd_context
 */
static void *memdump_get_file_data(struct file *file)
{
	void *hdd_ctx;

	hdd_ctx = PDE_DATA(file_inode(file));
	return hdd_ctx;
}

/**
 * memdump_read() - perform read operation in memory dump proc file
 *
 * @file  - handle for the proc file.
 * @buf   - pointer to user space buffer.
 * @count - number of bytes to be read.
 * @pos   - offset in the from buffer.
 *
 * This function performs read operation for the memory dump proc file.
 *
 * Return: number of bytes read on success, error code otherwise.
 */
static ssize_t memdump_read(struct file *file, char __user *buf,
					size_t count, loff_t *pos)
{
	int status;
	struct hdd_context *hdd_ctx;
	qdf_dma_addr_t paddr;
	qdf_dma_addr_t dma_ctx = 0;
	qdf_device_t qdf_ctx;

	hdd_ctx = memdump_get_file_data(file);

	hdd_debug("Read req for size:%zu pos:%llu", count, *pos);
	status = wlan_hdd_validate_context(hdd_ctx);
	if (status)
		return status;

	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
	if (!qdf_ctx) {
		hdd_err("QDF context is NULL");
		return -EINVAL;
	}

	mutex_lock(&hdd_ctx->memdump_lock);

	if (!hdd_ctx->memdump_in_progress) {
		hdd_err("Current mem dump request timed out/failed");
		status = -EINVAL;
		goto memdump_read_fail;
	}

	if (*pos < 0) {
		hdd_err("Invalid start offset for memdump read");
		status = -EINVAL;
		goto memdump_read_fail;
	} else if (*pos >= FW_MEM_DUMP_SIZE || !count) {
		hdd_debug("No more data to copy");
		status = 0;
		goto memdump_read_fail;
	} else if (count > FW_MEM_DUMP_SIZE - *pos) {
		count = FW_MEM_DUMP_SIZE - *pos;
	}

	if (!hdd_ctx->fw_dump_loc) {
		hdd_err("Invalid fw mem dump location");
		status = -EINVAL;
		goto memdump_read_fail;
	}

	if (copy_to_user(buf, hdd_ctx->fw_dump_loc + *pos, count)) {
		hdd_err("copy to user space failed");
		status = -EFAULT;
		goto memdump_read_fail;
	}

	/* offset(pos) should be updated here based on the copy done*/
	*pos += count;

	/* Entire FW memory dump copy completed */
	if (*pos >= FW_MEM_DUMP_SIZE) {
		paddr = hdd_ctx->dump_loc_paddr;
		qdf_mem_free_consistent(qdf_ctx, qdf_ctx->dev,
			FW_MEM_DUMP_SIZE, hdd_ctx->fw_dump_loc, paddr, dma_ctx);
		hdd_ctx->fw_dump_loc = NULL;
		hdd_ctx->memdump_in_progress = false;
		if (QDF_TIMER_STATE_RUNNING ==
			qdf_mc_timer_get_current_state(
				&hdd_ctx->memdump_cleanup_timer)) {
			qdf_mc_timer_stop(&hdd_ctx->memdump_cleanup_timer);
		}

	}
	status = count;
memdump_read_fail:
	mutex_unlock(&hdd_ctx->memdump_lock);
	return status;
}

/**
 * struct memdump_fops - file operations for memory dump feature
 * @read - read function for memory dump operation.
 *
 * This structure initialize the file operation handle for memory
 * dump feature
 */
static const struct file_operations memdump_fops = {
	read: memdump_read
};

/**
 * memdump_procfs_init() - Initialize procfs for memory dump
 *
 * This function create file under proc file system to be used later for
 * processing firmware memory dump
 *
 * Return:   0 on success, error code otherwise.
 */
static int memdump_procfs_init(void)
{
	struct hdd_context *hdd_ctx;

	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	if (!hdd_ctx) {
		hdd_err("Invalid HDD context");
		return -EINVAL;
	}

	proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
	if (proc_dir == NULL) {
		remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
		pr_debug("Could not initialize /proc/%s\n",
			 PROCFS_MEMDUMP_DIR);
		return -ENOMEM;
	}

	proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
				     PROCFS_MEMDUMP_PERM, proc_dir,
				     &memdump_fops, hdd_ctx);
	if (proc_file == NULL) {
		remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
		pr_debug("Could not initialize /proc/%s\n",
			  PROCFS_MEMDUMP_NAME);
		return -ENOMEM;
	}

	pr_debug("/proc/%s/%s created\n", PROCFS_MEMDUMP_DIR,
		 PROCFS_MEMDUMP_NAME);
	return 0;
}

/**
 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
 *
 * This function removes file/dir under proc file system that was
 * processing firmware memory dump
 *
 * Return:  None
 */
static void memdump_procfs_remove(void)
{
	remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
	pr_debug("/proc/%s/%s removed\n", PROCFS_MEMDUMP_DIR,
					  PROCFS_MEMDUMP_NAME);
	remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
	pr_debug("/proc/%s removed\n", PROCFS_MEMDUMP_DIR);
}

/**
 * memdump_init() - Intialization function for memory dump feature
 *
 * This function creates proc file for memdump feature and registers
 * HDD callback function with SME.
 *
 * Return - 0 on success, error otherwise
 */
int memdump_init(void)
{
	struct hdd_context *hdd_ctx;
	int status = 0;
	QDF_STATUS qdf_status;

	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	if (!hdd_ctx) {
		hdd_err("Invalid HDD context");
		return -EINVAL;
	}

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Not initializing memdump in FTM mode");
		return -EINVAL;
	}

	status = memdump_procfs_init();
	if (status) {
		hdd_err("Failed to create proc file");
		return status;
	}

	init_completion(&fw_dump_context.response_event);

	qdf_status = qdf_mc_timer_init(&hdd_ctx->memdump_cleanup_timer,
				    QDF_TIMER_TYPE_SW, memdump_cleanup_timer_cb,
				    (void *)hdd_ctx);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Failed to init memdump cleanup timer");
		return -EINVAL;
	}

	mutex_init(&hdd_ctx->memdump_lock);
	hdd_ctx->memdump_init_done = true;

	return 0;
}

/**
 * memdump_deinit() - De initialize memdump feature
 *
 * This function removes proc file created for memdump feature.
 *
 * Return: None
 */
void memdump_deinit(void)
{
	struct hdd_context *hdd_ctx;
	qdf_dma_addr_t paddr;
	qdf_dma_addr_t dma_ctx = 0;
	qdf_device_t qdf_ctx;
	QDF_STATUS qdf_status;

	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	if (!hdd_ctx) {
		hdd_err("Invalid HDD context");
		return;
	}

	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
		hdd_err("Not deinitializing memdump in FTM mode");
		return;
	}

	if (!hdd_ctx->memdump_init_done) {
		hdd_warn("MemDump not initialized");
		return;
	}
	hdd_ctx->memdump_init_done = false;

	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
	if (!qdf_ctx) {
		hdd_err("QDF context is NULL");
		return;
	}

	memdump_procfs_remove();

	mutex_lock(&hdd_ctx->memdump_lock);
	if (hdd_ctx->fw_dump_loc) {
		paddr = hdd_ctx->dump_loc_paddr;
		qdf_mem_free_consistent(qdf_ctx, qdf_ctx->dev,
			FW_MEM_DUMP_SIZE, hdd_ctx->fw_dump_loc, paddr, dma_ctx);
		hdd_ctx->fw_dump_loc = NULL;
		hdd_ctx->memdump_in_progress = false;
	}
	mutex_unlock(&hdd_ctx->memdump_lock);
	mutex_destroy(&hdd_ctx->memdump_lock);

	if (QDF_TIMER_STATE_RUNNING ==
	  qdf_mc_timer_get_current_state(&hdd_ctx->memdump_cleanup_timer)) {
		qdf_mc_timer_stop(&hdd_ctx->memdump_cleanup_timer);
	}

	qdf_status = qdf_mc_timer_destroy(&hdd_ctx->memdump_cleanup_timer);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
		hdd_err("Failed to deallocate timer");
}

#ifdef MULTI_IF_NAME
#define PROCFS_DRIVER_DUMP_DIR "debugdriver" MULTI_IF_NAME
#else
#define PROCFS_DRIVER_DUMP_DIR "debugdriver"
#endif
#define PROCFS_DRIVER_DUMP_NAME "driverdump"
#define PROCFS_DRIVER_DUMP_PERM 0444

static struct proc_dir_entry *proc_file_driver, *proc_dir_driver;

/**
 * hdd_driver_mem_cleanup() - Frees memory allocated for
 * driver dump
 *
 * This function unallocates driver dump memory.
 *
 * Return: None
 */
static void hdd_driver_mem_cleanup(void)
{
	struct hdd_context *hdd_ctx;

	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	if (!hdd_ctx) {
		hdd_err("Invalid HDD context");
		return;
	}

	if (hdd_ctx->driver_dump_mem) {
		qdf_mem_free(hdd_ctx->driver_dump_mem);
		hdd_ctx->driver_dump_mem = NULL;
	}
}


/**
 * hdd_driver_memdump_read() - perform read operation in driver
 * memory dump proc file
 * @file  - handle for the proc file.
 * @buf   - pointer to user space buffer.
 * @count - number of bytes to be read.
 * @pos   - offset in the from buffer.
 *
 * This function performs read operation for the driver memory dump proc file.
 *
 * Return: number of bytes read on success, error code otherwise.
 */
static ssize_t hdd_driver_memdump_read(struct file *file, char __user *buf,
					size_t count, loff_t *pos)
{
	int status;
	QDF_STATUS qdf_status;
	struct hdd_context *hdd_ctx;
	size_t no_of_bytes_read = 0;

	hdd_ctx = memdump_get_file_data(file);

	hdd_debug("Read req for size:%zu pos:%llu", count, *pos);
	status = wlan_hdd_validate_context(hdd_ctx);
	if (status != 0)
		return -EINVAL;

	mutex_lock(&hdd_ctx->memdump_lock);
	if (*pos < 0) {
		hdd_err("Invalid start offset for memdump read");
		mutex_unlock(&hdd_ctx->memdump_lock);
		return -EINVAL;
	} else if (!count || (hdd_ctx->driver_dump_size &&
				(*pos >= hdd_ctx->driver_dump_size))) {
		mutex_unlock(&hdd_ctx->memdump_lock);
		hdd_debug("No more data to copy");
		return 0;
	} else if ((*pos == 0) || (hdd_ctx->driver_dump_mem == NULL)) {
		/*
		 * Allocate memory for Driver memory dump.
		 */
		if (!hdd_ctx->driver_dump_mem) {
			hdd_ctx->driver_dump_mem =
				qdf_mem_malloc(DRIVER_MEM_DUMP_SIZE);
			if (!hdd_ctx->driver_dump_mem) {
				hdd_err("qdf_mem_malloc failed");
				mutex_unlock(&hdd_ctx->memdump_lock);
				return -ENOMEM;
			}
		}

		qdf_status = qdf_state_info_dump_all(hdd_ctx->driver_dump_mem,
						DRIVER_MEM_DUMP_SIZE,
						&hdd_ctx->driver_dump_size);
		/*
		 * If qdf_status is QDF_STATUS_E_NOMEM, then memory allocated is
		 * insufficient to dump driver information. This print can give
		 * information to allocate more memory if more information from
		 * each layer is added in future.
		 */
		if (qdf_status != QDF_STATUS_SUCCESS)
			hdd_err("Error in dump driver information, status %d",
				qdf_status);
		hdd_debug("driver_dump_size: %d",
					hdd_ctx->driver_dump_size);
	}

	if (count > hdd_ctx->driver_dump_size - *pos)
		no_of_bytes_read = hdd_ctx->driver_dump_size - *pos;
	else
		no_of_bytes_read = count;

	if (copy_to_user(buf, hdd_ctx->driver_dump_mem + *pos,
					no_of_bytes_read)) {
		hdd_err("copy to user space failed");
		mutex_unlock(&hdd_ctx->memdump_lock);
		return -EFAULT;
	}

	/* offset(pos) should be updated here based on the copy done */
	*pos += no_of_bytes_read;

	/* Entire driver memory dump copy completed */
	if (*pos >= hdd_ctx->driver_dump_size)
		hdd_driver_mem_cleanup();

	mutex_unlock(&hdd_ctx->memdump_lock);

	return no_of_bytes_read;
}


/**
 * struct driver_dump_fops - file operations for driver dump feature
 * @read - read function for driver dump operation.
 *
 * This structure initialize the file operation handle for memory
 * dump feature
 */
static const struct file_operations driver_dump_fops = {
read: hdd_driver_memdump_read
};

/**
 * hdd_driver_memdump_procfs_init() - Initialize procfs for driver memory dump
 *
 * This function create file under proc file system to be used later for
 * processing driver memory dump
 *
 * Return:   0 on success, error code otherwise.
 */
static int hdd_driver_memdump_procfs_init(void)
{
	struct hdd_context *hdd_ctx;

	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
	if (!hdd_ctx) {
		hdd_err("Invalid HDD context");
		return -EINVAL;
	}

	proc_dir_driver = proc_mkdir(PROCFS_DRIVER_DUMP_DIR, NULL);
	if (proc_dir_driver == NULL) {
		pr_debug("Could not initialize /proc/%s\n",
			 PROCFS_DRIVER_DUMP_DIR);
		return -ENOMEM;
	}

	proc_file_driver = proc_create_data(PROCFS_DRIVER_DUMP_NAME,
				     PROCFS_DRIVER_DUMP_PERM, proc_dir_driver,
				     &driver_dump_fops, hdd_ctx);
	if (proc_file_driver == NULL) {
		remove_proc_entry(PROCFS_DRIVER_DUMP_NAME, proc_dir_driver);
		pr_debug("Could not initialize /proc/%s\n",
			  PROCFS_DRIVER_DUMP_NAME);
		return -ENOMEM;
	}

	pr_debug("/proc/%s/%s created\n", PROCFS_DRIVER_DUMP_DIR,
		 PROCFS_DRIVER_DUMP_NAME);
	return 0;
}

/**
 * hdd_driver_memdump_procfs_remove() - Remove file/dir under procfs
 * for driver memory dump
 *
 * This function removes file/dir under proc file system that was
 * processing driver memory dump
 *
 * Return:  None
 */
static void hdd_driver_memdump_procfs_remove(void)
{
	remove_proc_entry(PROCFS_DRIVER_DUMP_NAME, proc_dir_driver);
	pr_debug("/proc/%s/%s removed\n", PROCFS_DRIVER_DUMP_DIR,
					  PROCFS_DRIVER_DUMP_NAME);
	remove_proc_entry(PROCFS_DRIVER_DUMP_DIR, NULL);
	pr_debug("/proc/%s removed\n", PROCFS_DRIVER_DUMP_DIR);
}

/**
 * hdd_driver_memdump_init() - Intialization function for driver
 * memory dump feature
 *
 * This function creates proc file for driver memdump feature
 *
 * Return - 0 on success, error otherwise
 */
int hdd_driver_memdump_init(void)
{
	int status;

	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
		hdd_err("Not initializing memdump in FTM mode");
		return -EINVAL;
	}

	status = hdd_driver_memdump_procfs_init();
	if (status) {
		hdd_err("Failed to create proc file");
		return status;
	}

	return 0;
}

/**
 * hdd_driver_memdump_deinit() - De initialize driver memdump feature
 *
 * This function removes proc file created for driver memdump feature.
 *
 * Return: None
 */
void hdd_driver_memdump_deinit(void)
{
	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
		hdd_err("Not deinitializing memdump in FTM mode");
		return;
	}

	hdd_driver_memdump_procfs_remove();

	hdd_driver_mem_cleanup();
}
