/*
 * Copyright (c) 2015, Sony Mobile Communications Inc.
 *
 * 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/firmware.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/soc/qcom/smd.h>

#define WCNSS_REQUEST_TIMEOUT	(5 * HZ)

#define NV_FRAGMENT_SIZE	3072
#define NVBIN_FILE		"wlan/prima/WCNSS_qcom_wlan_nv.bin"

/**
 * struct wcnss_ctrl - driver context
 * @dev:	device handle
 * @channel:	SMD channel handle
 * @ack:	completion for outstanding requests
 * @ack_status:	status of the outstanding request
 * @download_nv_work: worker for uploading nv binary
 */
struct wcnss_ctrl {
	struct device *dev;
	struct qcom_smd_channel *channel;

	struct completion ack;
	int ack_status;

	struct work_struct download_nv_work;
};

/* message types */
enum {
	WCNSS_VERSION_REQ = 0x01000000,
	WCNSS_VERSION_RESP,
	WCNSS_DOWNLOAD_NV_REQ,
	WCNSS_DOWNLOAD_NV_RESP,
	WCNSS_UPLOAD_CAL_REQ,
	WCNSS_UPLOAD_CAL_RESP,
	WCNSS_DOWNLOAD_CAL_REQ,
	WCNSS_DOWNLOAD_CAL_RESP,
};

/**
 * struct wcnss_msg_hdr - common packet header for requests and responses
 * @type:	packet message type
 * @len:	total length of the packet, including this header
 */
struct wcnss_msg_hdr {
	u32 type;
	u32 len;
} __packed;

/**
 * struct wcnss_version_resp - version request response
 * @hdr:	common packet wcnss_msg_hdr header
 */
struct wcnss_version_resp {
	struct wcnss_msg_hdr hdr;
	u8 major;
	u8 minor;
	u8 version;
	u8 revision;
} __packed;

/**
 * struct wcnss_download_nv_req - firmware fragment request
 * @hdr:	common packet wcnss_msg_hdr header
 * @seq:	sequence number of this fragment
 * @last:	boolean indicator of this being the last fragment of the binary
 * @frag_size:	length of this fragment
 * @fragment:	fragment data
 */
struct wcnss_download_nv_req {
	struct wcnss_msg_hdr hdr;
	u16 seq;
	u16 last;
	u32 frag_size;
	u8 fragment[];
} __packed;

/**
 * struct wcnss_download_nv_resp - firmware download response
 * @hdr:	common packet wcnss_msg_hdr header
 * @status:	boolean to indicate success of the download
 */
struct wcnss_download_nv_resp {
	struct wcnss_msg_hdr hdr;
	u8 status;
} __packed;

/**
 * wcnss_ctrl_smd_callback() - handler from SMD responses
 * @qsdev:	smd device handle
 * @data:	pointer to the incoming data packet
 * @count:	size of the incoming data packet
 *
 * Handles any incoming packets from the remote WCNSS_CTRL service.
 */
static int wcnss_ctrl_smd_callback(struct qcom_smd_device *qsdev,
				   const void *data,
				   size_t count)
{
	struct wcnss_ctrl *wcnss = dev_get_drvdata(&qsdev->dev);
	const struct wcnss_download_nv_resp *nvresp;
	const struct wcnss_version_resp *version;
	const struct wcnss_msg_hdr *hdr = data;

	switch (hdr->type) {
	case WCNSS_VERSION_RESP:
		if (count != sizeof(*version)) {
			dev_err(wcnss->dev,
				"invalid size of version response\n");
			break;
		}

		version = data;
		dev_info(wcnss->dev, "WCNSS Version %d.%d %d.%d\n",
			 version->major, version->minor,
			 version->version, version->revision);

		schedule_work(&wcnss->download_nv_work);
		break;
	case WCNSS_DOWNLOAD_NV_RESP:
		if (count != sizeof(*nvresp)) {
			dev_err(wcnss->dev,
				"invalid size of download response\n");
			break;
		}

		nvresp = data;
		wcnss->ack_status = nvresp->status;
		complete(&wcnss->ack);
		break;
	default:
		dev_info(wcnss->dev, "unknown message type %d\n", hdr->type);
		break;
	}

	return 0;
}

/**
 * wcnss_request_version() - send a version request to WCNSS
 * @wcnss:	wcnss ctrl driver context
 */
static int wcnss_request_version(struct wcnss_ctrl *wcnss)
{
	struct wcnss_msg_hdr msg;

	msg.type = WCNSS_VERSION_REQ;
	msg.len = sizeof(msg);

	return qcom_smd_send(wcnss->channel, &msg, sizeof(msg));
}

/**
 * wcnss_download_nv() - send nv binary to WCNSS
 * @work:	work struct to acquire wcnss context
 */
static void wcnss_download_nv(struct work_struct *work)
{
	struct wcnss_ctrl *wcnss = container_of(work, struct wcnss_ctrl, download_nv_work);
	struct wcnss_download_nv_req *req;
	const struct firmware *fw;
	const void *data;
	ssize_t left;
	int ret;

	req = kzalloc(sizeof(*req) + NV_FRAGMENT_SIZE, GFP_KERNEL);
	if (!req)
		return;

	ret = request_firmware(&fw, NVBIN_FILE, wcnss->dev);
	if (ret) {
		dev_err(wcnss->dev, "Failed to load nv file %s: %d\n",
			NVBIN_FILE, ret);
		goto free_req;
	}

	data = fw->data;
	left = fw->size;

	req->hdr.type = WCNSS_DOWNLOAD_NV_REQ;
	req->hdr.len = sizeof(*req) + NV_FRAGMENT_SIZE;

	req->last = 0;
	req->frag_size = NV_FRAGMENT_SIZE;

	req->seq = 0;
	do {
		if (left <= NV_FRAGMENT_SIZE) {
			req->last = 1;
			req->frag_size = left;
			req->hdr.len = sizeof(*req) + left;
		}

		memcpy(req->fragment, data, req->frag_size);

		ret = qcom_smd_send(wcnss->channel, req, req->hdr.len);
		if (ret) {
			dev_err(wcnss->dev, "failed to send smd packet\n");
			goto release_fw;
		}

		/* Increment for next fragment */
		req->seq++;

		data += req->hdr.len;
		left -= NV_FRAGMENT_SIZE;
	} while (left > 0);

	ret = wait_for_completion_timeout(&wcnss->ack, WCNSS_REQUEST_TIMEOUT);
	if (!ret)
		dev_err(wcnss->dev, "timeout waiting for nv upload ack\n");
	else if (wcnss->ack_status != 1)
		dev_err(wcnss->dev, "nv upload response failed err: %d\n",
			wcnss->ack_status);

release_fw:
	release_firmware(fw);
free_req:
	kfree(req);
}

static int wcnss_ctrl_probe(struct qcom_smd_device *sdev)
{
	struct wcnss_ctrl *wcnss;

	wcnss = devm_kzalloc(&sdev->dev, sizeof(*wcnss), GFP_KERNEL);
	if (!wcnss)
		return -ENOMEM;

	wcnss->dev = &sdev->dev;
	wcnss->channel = sdev->channel;

	init_completion(&wcnss->ack);
	INIT_WORK(&wcnss->download_nv_work, wcnss_download_nv);

	dev_set_drvdata(&sdev->dev, wcnss);

	return wcnss_request_version(wcnss);
}

static const struct qcom_smd_id wcnss_ctrl_smd_match[] = {
	{ .name = "WCNSS_CTRL" },
	{}
};

static struct qcom_smd_driver wcnss_ctrl_driver = {
	.probe = wcnss_ctrl_probe,
	.callback = wcnss_ctrl_smd_callback,
	.smd_match_table = wcnss_ctrl_smd_match,
	.driver  = {
		.name  = "qcom_wcnss_ctrl",
		.owner = THIS_MODULE,
	},
};

module_qcom_smd_driver(wcnss_ctrl_driver);

MODULE_DESCRIPTION("Qualcomm WCNSS control driver");
MODULE_LICENSE("GPL v2");
