/*
 * Copyright (c) 2014 Redpine Signals 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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/firmware.h>
#include <net/rsi_91x.h>
#include "rsi_mgmt.h"
#include "rsi_common.h"
#include "rsi_coex.h"
#include "rsi_hal.h"
#include "rsi_usb.h"

u32 rsi_zone_enabled = /* INFO_ZONE |
			INIT_ZONE |
			MGMT_TX_ZONE |
			MGMT_RX_ZONE |
			DATA_TX_ZONE |
			DATA_RX_ZONE |
			FSM_ZONE |
			ISR_ZONE | */
			ERR_ZONE |
			0;
EXPORT_SYMBOL_GPL(rsi_zone_enabled);

#ifdef CONFIG_RSI_COEX
static struct rsi_proto_ops g_proto_ops = {
	.coex_send_pkt = rsi_coex_send_pkt,
	.get_host_intf = rsi_get_host_intf,
	.set_bt_context = rsi_set_bt_context,
};
#endif

/**
 * rsi_dbg() - This function outputs informational messages.
 * @zone: Zone of interest for output message.
 * @fmt: printf-style format for output message.
 *
 * Return: none
 */
void rsi_dbg(u32 zone, const char *fmt, ...)
{
	struct va_format vaf;
	va_list args;

	va_start(args, fmt);

	vaf.fmt = fmt;
	vaf.va = &args;

	if (zone & rsi_zone_enabled)
		pr_info("%pV", &vaf);
	va_end(args);
}
EXPORT_SYMBOL_GPL(rsi_dbg);

static char *opmode_str(int oper_mode)
{
	switch (oper_mode) {
	case DEV_OPMODE_WIFI_ALONE:
		return "Wi-Fi alone";
	case DEV_OPMODE_BT_ALONE:
		return "BT EDR alone";
	case DEV_OPMODE_BT_LE_ALONE:
		return "BT LE alone";
	case DEV_OPMODE_BT_DUAL:
		return "BT Dual";
	case DEV_OPMODE_STA_BT:
		return "Wi-Fi STA + BT EDR";
	case DEV_OPMODE_STA_BT_LE:
		return "Wi-Fi STA + BT LE";
	case DEV_OPMODE_STA_BT_DUAL:
		return "Wi-Fi STA + BT DUAL";
	case DEV_OPMODE_AP_BT:
		return "Wi-Fi AP + BT EDR";
	case DEV_OPMODE_AP_BT_DUAL:
		return "Wi-Fi AP + BT DUAL";
	}

	return "Unknown";
}

void rsi_print_version(struct rsi_common *common)
{
	rsi_dbg(ERR_ZONE, "================================================\n");
	rsi_dbg(ERR_ZONE, "================ RSI Version Info ==============\n");
	rsi_dbg(ERR_ZONE, "================================================\n");
	rsi_dbg(ERR_ZONE, "FW Version\t: %d.%d.%d\n",
		common->lmac_ver.major, common->lmac_ver.minor,
		common->lmac_ver.release_num);
	rsi_dbg(ERR_ZONE, "Operating mode\t: %d [%s]",
		common->oper_mode, opmode_str(common->oper_mode));
	rsi_dbg(ERR_ZONE, "Firmware file\t: %s", common->priv->fw_file_name);
	rsi_dbg(ERR_ZONE, "================================================\n");
}

/**
 * rsi_prepare_skb() - This function prepares the skb.
 * @common: Pointer to the driver private structure.
 * @buffer: Pointer to the packet data.
 * @pkt_len: Length of the packet.
 * @extended_desc: Extended descriptor.
 *
 * Return: Successfully skb.
 */
static struct sk_buff *rsi_prepare_skb(struct rsi_common *common,
				       u8 *buffer,
				       u32 pkt_len,
				       u8 extended_desc)
{
	struct sk_buff *skb = NULL;
	u8 payload_offset;

	if (WARN(!pkt_len, "%s: Dummy pkt received", __func__))
		return NULL;

	if (pkt_len > (RSI_RCV_BUFFER_LEN * 4)) {
		rsi_dbg(ERR_ZONE, "%s: Pkt size > max rx buf size %d\n",
			__func__, pkt_len);
		pkt_len = RSI_RCV_BUFFER_LEN * 4;
	}

	pkt_len -= extended_desc;
	skb = dev_alloc_skb(pkt_len + FRAME_DESC_SZ);
	if (skb == NULL)
		return NULL;

	payload_offset = (extended_desc + FRAME_DESC_SZ);
	skb_put(skb, pkt_len);
	memcpy((skb->data), (buffer + payload_offset), skb->len);

	return skb;
}

/**
 * rsi_read_pkt() - This function reads frames from the card.
 * @common: Pointer to the driver private structure.
 * @rx_pkt: Received pkt.
 * @rcv_pkt_len: Received pkt length. In case of USB it is 0.
 *
 * Return: 0 on success, -1 on failure.
 */
int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len)
{
	u8 *frame_desc = NULL, extended_desc = 0;
	u32 index, length = 0, queueno = 0;
	u16 actual_length = 0, offset;
	struct sk_buff *skb = NULL;
#ifdef CONFIG_RSI_COEX
	u8 bt_pkt_type;
#endif

	index = 0;
	do {
		frame_desc = &rx_pkt[index];
		actual_length = *(u16 *)&frame_desc[0];
		offset = *(u16 *)&frame_desc[2];
		if (!rcv_pkt_len && offset >
			RSI_MAX_RX_USB_PKT_SIZE - FRAME_DESC_SZ)
			goto fail;

		queueno = rsi_get_queueno(frame_desc, offset);
		length = rsi_get_length(frame_desc, offset);

		/* Extended descriptor is valid for WLAN queues only */
		if (queueno == RSI_WIFI_DATA_Q || queueno == RSI_WIFI_MGMT_Q)
			extended_desc = rsi_get_extended_desc(frame_desc,
							      offset);

		switch (queueno) {
		case RSI_COEX_Q:
#ifdef CONFIG_RSI_COEX
			if (common->coex_mode > 1)
				rsi_coex_recv_pkt(common, frame_desc + offset);
			else
#endif
				rsi_mgmt_pkt_recv(common,
						  (frame_desc + offset));
			break;

		case RSI_WIFI_DATA_Q:
			skb = rsi_prepare_skb(common,
					      (frame_desc + offset),
					      length,
					      extended_desc);
			if (skb == NULL)
				goto fail;

			rsi_indicate_pkt_to_os(common, skb);
			break;

		case RSI_WIFI_MGMT_Q:
			rsi_mgmt_pkt_recv(common, (frame_desc + offset));
			break;

#ifdef CONFIG_RSI_COEX
		case RSI_BT_MGMT_Q:
		case RSI_BT_DATA_Q:
#define BT_RX_PKT_TYPE_OFST	14
#define BT_CARD_READY_IND	0x89
			bt_pkt_type = frame_desc[offset + BT_RX_PKT_TYPE_OFST];
			if (bt_pkt_type == BT_CARD_READY_IND) {
				rsi_dbg(INFO_ZONE, "BT Card ready recvd\n");
				if (common->fsm_state == FSM_MAC_INIT_DONE)
					rsi_attach_bt(common);
				else
					common->bt_defer_attach = true;
			} else {
				if (common->bt_adapter)
					rsi_bt_ops.recv_pkt(common->bt_adapter,
							frame_desc + offset);
			}
			break;
#endif

		default:
			rsi_dbg(ERR_ZONE, "%s: pkt from invalid queue: %d\n",
				__func__,   queueno);
			goto fail;
		}

		index  += actual_length;
		rcv_pkt_len -= actual_length;
	} while (rcv_pkt_len > 0);

	return 0;
fail:
	return -EINVAL;
}
EXPORT_SYMBOL_GPL(rsi_read_pkt);

/**
 * rsi_tx_scheduler_thread() - This function is a kernel thread to send the
 *			       packets to the device.
 * @common: Pointer to the driver private structure.
 *
 * Return: None.
 */
static void rsi_tx_scheduler_thread(struct rsi_common *common)
{
	struct rsi_hw *adapter = common->priv;
	u32 timeout = EVENT_WAIT_FOREVER;

	do {
		if (adapter->determine_event_timeout)
			timeout = adapter->determine_event_timeout(adapter);
		rsi_wait_event(&common->tx_thread.event, timeout);
		rsi_reset_event(&common->tx_thread.event);

		if (common->init_done)
			rsi_core_qos_processor(common);
	} while (atomic_read(&common->tx_thread.thread_done) == 0);
	complete_and_exit(&common->tx_thread.completion, 0);
}

#ifdef CONFIG_RSI_COEX
enum rsi_host_intf rsi_get_host_intf(void *priv)
{
	struct rsi_common *common = (struct rsi_common *)priv;

	return common->priv->rsi_host_intf;
}

void rsi_set_bt_context(void *priv, void *bt_context)
{
	struct rsi_common *common = (struct rsi_common *)priv;

	common->bt_adapter = bt_context;
}
#endif

void rsi_attach_bt(struct rsi_common *common)
{
#ifdef CONFIG_RSI_COEX
	if (rsi_bt_ops.attach(common, &g_proto_ops))
		rsi_dbg(ERR_ZONE,
			"Failed to attach BT module\n");
#endif
}

/**
 * rsi_91x_init() - This function initializes os interface operations.
 * @oper_mode: One of DEV_OPMODE_*.
 *
 * Return: Pointer to the adapter structure on success, NULL on failure .
 */
struct rsi_hw *rsi_91x_init(u16 oper_mode)
{
	struct rsi_hw *adapter = NULL;
	struct rsi_common *common = NULL;
	u8 ii = 0;

	adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
	if (!adapter)
		return NULL;

	adapter->priv = kzalloc(sizeof(*common), GFP_KERNEL);
	if (adapter->priv == NULL) {
		rsi_dbg(ERR_ZONE, "%s: Failed in allocation of memory\n",
			__func__);
		kfree(adapter);
		return NULL;
	} else {
		common = adapter->priv;
		common->priv = adapter;
	}

	for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
		skb_queue_head_init(&common->tx_queue[ii]);

	rsi_init_event(&common->tx_thread.event);
	mutex_init(&common->mutex);
	mutex_init(&common->tx_lock);
	mutex_init(&common->rx_lock);
	mutex_init(&common->tx_bus_mutex);

	if (rsi_create_kthread(common,
			       &common->tx_thread,
			       rsi_tx_scheduler_thread,
			       "Tx-Thread")) {
		rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__);
		goto err;
	}

	rsi_default_ps_params(adapter);
	init_bgscan_params(common);
	spin_lock_init(&adapter->ps_lock);
	timer_setup(&common->roc_timer, rsi_roc_timeout, 0);
	init_completion(&common->wlan_init_completion);
	adapter->device_model = RSI_DEV_9113;
	common->oper_mode = oper_mode;

	/* Determine coex mode */
	switch (common->oper_mode) {
	case DEV_OPMODE_STA_BT_DUAL:
	case DEV_OPMODE_STA_BT:
	case DEV_OPMODE_STA_BT_LE:
	case DEV_OPMODE_BT_ALONE:
	case DEV_OPMODE_BT_LE_ALONE:
	case DEV_OPMODE_BT_DUAL:
		common->coex_mode = 2;
		break;
	case DEV_OPMODE_AP_BT_DUAL:
	case DEV_OPMODE_AP_BT:
		common->coex_mode = 4;
		break;
	case DEV_OPMODE_WIFI_ALONE:
		common->coex_mode = 1;
		break;
	default:
		common->oper_mode = 1;
		common->coex_mode = 1;
	}
	rsi_dbg(INFO_ZONE, "%s: oper_mode = %d, coex_mode = %d\n",
		__func__, common->oper_mode, common->coex_mode);

	adapter->device_model = RSI_DEV_9113;
#ifdef CONFIG_RSI_COEX
	if (common->coex_mode > 1) {
		if (rsi_coex_attach(common)) {
			rsi_dbg(ERR_ZONE, "Failed to init coex module\n");
			rsi_kill_thread(&common->tx_thread);
			goto err;
		}
	}
#endif

	common->init_done = true;
	return adapter;

err:
	kfree(common);
	kfree(adapter);
	return NULL;
}
EXPORT_SYMBOL_GPL(rsi_91x_init);

/**
 * rsi_91x_deinit() - This function de-intializes os intf operations.
 * @adapter: Pointer to the adapter structure.
 *
 * Return: None.
 */
void rsi_91x_deinit(struct rsi_hw *adapter)
{
	struct rsi_common *common = adapter->priv;
	u8 ii;

	rsi_dbg(INFO_ZONE, "%s: Performing deinit os ops\n", __func__);

	rsi_kill_thread(&common->tx_thread);

	for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
		skb_queue_purge(&common->tx_queue[ii]);

#ifdef CONFIG_RSI_COEX
	if (common->coex_mode > 1) {
		if (common->bt_adapter) {
			rsi_bt_ops.detach(common->bt_adapter);
			common->bt_adapter = NULL;
		}
		rsi_coex_detach(common);
	}
#endif

	common->init_done = false;

	kfree(common);
	kfree(adapter->rsi_dev);
	kfree(adapter);
}
EXPORT_SYMBOL_GPL(rsi_91x_deinit);

/**
 * rsi_91x_hal_module_init() - This function is invoked when the module is
 *			       loaded into the kernel.
 *			       It registers the client driver.
 * @void: Void.
 *
 * Return: 0 on success, -1 on failure.
 */
static int rsi_91x_hal_module_init(void)
{
	rsi_dbg(INIT_ZONE, "%s: Module init called\n", __func__);
	return 0;
}

/**
 * rsi_91x_hal_module_exit() - This function is called at the time of
 *			       removing/unloading the module.
 *			       It unregisters the client driver.
 * @void: Void.
 *
 * Return: None.
 */
static void rsi_91x_hal_module_exit(void)
{
	rsi_dbg(INIT_ZONE, "%s: Module exit called\n", __func__);
}

module_init(rsi_91x_hal_module_init);
module_exit(rsi_91x_hal_module_exit);
MODULE_AUTHOR("Redpine Signals Inc");
MODULE_DESCRIPTION("Station driver for RSI 91x devices");
MODULE_VERSION("0.1");
MODULE_LICENSE("Dual BSD/GPL");
