/**
 * Copyright (c) 2008 - 2013 Quantenna Communications Inc
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 **/
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/device.h>
#include <linux/version.h>

#include <asm/io.h>
#include <asm/board/soc.h>

#include "qdrv_mac.h"
#include "qdrv_soc.h"
#include "qdrv_debug.h"
#include "qdrv_auc.h"
#include "qdrv_hal.h"
#include "qdrv_wlan.h"
#include "qdrv_vap.h"
#include "qdrv_fw.h"
#include <qtn/topaz_tqe.h>


static qtn_shared_node_stats_t *s_per_node_stats_ptr = NULL;
static qtn_shared_vap_stats_t *s_per_vap_stats_ptr = NULL;

static size_t auc_get_sram_size(void)
{
	struct shared_params *sp = qtn_mproc_sync_shared_params_get();

	if (sp->fw_no_mu)
		return CONFIG_ARC_AUC_NOMU_SRAM_SIZE;
	else
		return CONFIG_ARC_AUC_MU_SRAM_SIZE;
}

static void auc_clear_addr_range(unsigned long physaddr, unsigned long size)
{
	void *vaddr = ioremap_nocache(physaddr, size);

	if (!vaddr) {
		DBGPRINTF_E("0x%lx, 0x%lx cannot be mapped\n", physaddr, size);
	} else {
		qdrv_fw_auc_memzero(vaddr, size, physaddr);
		iounmap(vaddr);
	}
}

static void auc_clear_mem(void)
{
	auc_clear_addr_range(TOPAZ_AUC_IMEM_ADDR, TOPAZ_AUC_IMEM_SIZE);
	auc_clear_addr_range(TOPAZ_AUC_DMEM_ADDR, TOPAZ_AUC_DMEM_SIZE);
	auc_clear_addr_range(RUBY_DRAM_BEGIN + CONFIG_ARC_AUC_BASE, CONFIG_ARC_AUC_SIZE);
	auc_clear_addr_range(RUBY_SRAM_BEGIN + CONFIG_ARC_AUC_SRAM_BASE, auc_get_sram_size());
}

void qdrv_auc_stats_setup(void)
{
	unsigned long phyaddr;
	struct shared_params *sp = qtn_mproc_sync_shared_params_get();

	if (unlikely(!sp || !sp->auc.node_stats || !sp->auc.vap_stats)) {
		DBGPRINTF(DBG_LL_ERR, QDRV_LF_TRACE, "Stats setup: failed\n");
		return;
	}

	if (!s_per_node_stats_ptr) {
		phyaddr = qdrv_fw_auc_to_host_addr((unsigned long)sp->auc.node_stats);
		s_per_node_stats_ptr = ioremap_nocache(phyaddr, QTN_NCIDX_MAX * sizeof(qtn_shared_node_stats_t));
	}

	if (!s_per_vap_stats_ptr) {
		phyaddr = qdrv_fw_auc_to_host_addr((unsigned long)sp->auc.vap_stats);
		s_per_vap_stats_ptr = ioremap_nocache(phyaddr, QTN_MAX_VAPS * sizeof(qtn_shared_vap_stats_t));
	}

	DBGPRINTF(DBG_LL_INFO, QDRV_LF_TRACE, "Stats setup: Node : %p - %p\n"
			"             Vap  : %p - %p\n",
			sp->auc.node_stats,
			s_per_node_stats_ptr,
			sp->auc.vap_stats,
			s_per_vap_stats_ptr);
}

void qdrv_auc_stats_unmap(void)
{
	if (s_per_node_stats_ptr)
		iounmap(s_per_node_stats_ptr);
	if (s_per_vap_stats_ptr)
		iounmap(s_per_vap_stats_ptr);
}

qtn_shared_node_stats_t* qdrv_auc_get_node_stats(uint8_t node)
{
	return (s_per_node_stats_ptr) ? (s_per_node_stats_ptr + node) : NULL;
}

qtn_shared_vap_stats_t* qdrv_auc_get_vap_stats(uint8_t vapid)
{
	return (s_per_vap_stats_ptr) ? (s_per_vap_stats_ptr + vapid) : NULL;
}

void qdrv_auc_update_multicast_stats(void *ctx, uint8_t nid)
{
	uint8_t vapid;
	struct ieee80211com *ic = (struct ieee80211com *)ctx;
	struct ieee80211_node *node;
	struct ieee80211vap *vap;
	struct qdrv_vap * qv;
	qtn_shared_node_stats_t *nstats;
	qtn_shared_vap_stats_t *vstats;

	if (!ctx)
		return;

	node = ic->ic_node_idx_ni[nid];
	if (unlikely(!node))
		return;

	vap = node->ni_vap;
	qv = container_of(vap, struct qdrv_vap, iv);
	vapid = QDRV_WLANID_FROM_DEVID(qv->devid);
	nstats = qdrv_auc_get_node_stats(nid);
	vstats = qdrv_auc_get_vap_stats(vapid);

	if (unlikely(!nstats || !vstats))
		return;

	nstats->qtn_tx_mcast++;
	vstats->qtn_tx_mcast++;
}

void qdrv_auc_print_memory_map(void)
{
	int bank = 0;
	u_int32_t auc_sram_start, auc_sram_end, auc_sram_size, auc_sram_bank_end;
	struct shared_params *sp = qtn_mproc_sync_shared_params_get();

	auc_sram_size = auc_get_sram_size();
	auc_sram_start = RUBY_SRAM_BEGIN + CONFIG_ARC_AUC_SRAM_BASE;
	auc_sram_end = auc_sram_start + auc_sram_size;

	printk("AuC SRAM start 0x%08x end 0x%08x size %d\n",
		  auc_sram_start, auc_sram_end, auc_sram_size);

	if (sp->fw_no_mu)
		printk("AuC is configured for non-MU SRAM layout\n");
	else
		printk("AuC is configured for MU-enabled SRAM layout\n");

	auc_sram_bank_end = auc_sram_start + RUBY_SRAM_BANK_SIZE;
	while (auc_sram_start < auc_sram_end) {
		printk("AuC SRAM bank %d start 0x%08x end 0x%08x\n",
		       bank++, auc_sram_start, auc_sram_bank_end);
		auc_sram_start = auc_sram_bank_end;
		auc_sram_bank_end += RUBY_SRAM_BANK_SIZE;
	}
}

int qdrv_auc_init(struct qdrv_cb *qcb)
{
	u32 auc_start_addr = 0;
	struct qdrv_wlan *qw = qcb->macs[0].data;

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "-->Enter");

	qtn_mproc_sync_shared_params_get()->auc.auc_config = global_auc_config;

	qdrv_auc_print_memory_map();

	auc_clear_mem();

	if (qdrv_fw_load_auc(qcb->dev, qcb->auc_firmware, &auc_start_addr) < 0) {
		DBGPRINTF_E("AuC load firmware failed\n");
		DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");
		return -1;
	}

	DBGPRINTF(DBG_LL_INFO, QDRV_LF_DSP, "Firmware start address is %x\n", auc_start_addr);

	hal_enable_auc();

	tqe_reg_multicast_tx_stats(qdrv_auc_update_multicast_stats, &qw->ic);

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");

	return 0;
}

int qdrv_auc_exit(struct qdrv_cb *qcb)
{
	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "-->Enter");

	qdrv_auc_stats_unmap();
	hal_disable_auc();

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");

	return 0;
}

