/*
 *  Copyright (c) 2009 Mindspeed Technologies, Inc.
 *
 *  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 "modules.h"
#include "channels.h"
#include "events.h"
#include "module_tx.h"
#include "system.h"
#include "fpart.h"
#include "fpool.h"
#include "fpp.h"
#include "module_hidrv.h"

#if !defined(COMCERTO_2000) || defined(COMCERTO_2000_CONTROL)
U32 FCODE_TO_EVENT(U32 fcode)
{
	U32 eventid;
	switch((fcode & 0xFF00) >> 8)
	{
		case FC_RX:
			if (fcode >= L2BRIDGE_FIRST_COMMAND && fcode <= L2BRIDGE_LAST_COMMAND)
				eventid = EVENT_BRIDGE;
			else
				eventid = EVENT_PKT_RX;
			break;

		case FC_IPV4: eventid = EVENT_IPV4; break;

		case FC_IPV6: eventid = EVENT_IPV6; break;

		case FC_QM: eventid = EVENT_QM; break;

		case FC_TX: eventid = EVENT_PKT_TX; break;

		case FC_PPPOE: eventid = EVENT_PPPOE; break;

		case FC_MC: eventid = EVENT_MC6; break;

		case FC_RTP: eventid = EVENT_RTP_RELAY; break;

		case FC_VLAN: eventid = EVENT_VLAN; break;

		case FC_IPSEC: eventid = EVENT_IPS_IN; break;

		case FC_TRC: eventid = EVENT_IPS_OUT; break;

		case FC_TNL:eventid = EVENT_TNL_IN; break;

#ifdef CFG_MACVLAN
		case FC_MACVLAN: eventid = EVENT_MACVLAN; break;
#endif
#ifdef CFG_STATS
		case FC_STAT:eventid = EVENT_STAT; break;
#endif
		case FC_ALTCONF: eventid = EVENT_IPV4; break;

#ifdef CFG_WIFI_OFFLOAD
		case FC_WIFI_RX: eventid = EVENT_PKT_WIFIRX; break;
#endif

		case FC_NATPT: eventid = EVENT_NATPT; break;
#ifdef CFG_PCAP
		case FC_PKTCAP: eventid = EVENT_PKTCAP; break;
#endif

#ifdef CFG_DIAGS
		case FC_FPPDIAG: eventid = EVENT_IPV4; break;
#endif
#if defined(COMCERTO_2000_CONTROL) && !defined(ICC_DISABLE)
		case FC_ICC: eventid = EVENT_ICC; break;
#endif
		case FC_L2TP: eventid = EVENT_L2TP; break;
		default: eventid = 0; break;
	}

	return eventid;
}
#endif /* !defined(COMCERTO_2000) || defined(COMCERTO_2000_CONTROL) */

#if !defined(COMCERTO_2000)

BOOL M_hidrv_init(PModuleDesc pModule)
{
	
	/* module entry point and channels registration */
	pModule->entry = &M_hidrv_entry;
	pModule->cmdproc = NULL;
	HAL_arm1_fiq_enable_1(IRQM_FROMHOST);
	host_cmd.code = 0xFFFF;
	return 0;
	
}

void msg_send(HostMessage *pmsg)
{
	DISABLE_INTERRUPTS();

	pmsg->next = NULL;
	if (hostmsg_queue.head) {
		HostMessage *ptail = hostmsg_queue.tail;
		ptail->next = pmsg;
		hostmsg_queue.tail = pmsg;
	}
	else {
		hostmsg_queue.tail = hostmsg_queue.head = pmsg;
		set_event(gEventStatusReg, 1 << EVENT_HIDRV);
	}

	ENABLE_INTERRUPTS();
}


void M_hidrv_entry(void)
{
	U32	   tmp;

	// process host command
	if (host_cmd.code != 0xFFFF)
	{
		CmdProc cmdproc;
		U16 retlen;
		U32 eventid;
		eventid = FCODE_TO_EVENT(host_cmd.code);
		cmdproc = gCmdProcTable[eventid];
		if (cmdproc)
		{
			retlen = (*cmdproc)(host_cmd.code, host_cmd.length, host_cmd.data);
			if (retlen == 0)
			{
				host_cmd.data[0] = NO_ERR;
				retlen = 2;
			}
		}
		else
		{
			host_cmd.data[0] = ERR_UNKNOWN_COMMAND;
			retlen = 2;
		}
		tmp = (U32)retlen | (((U32)host_cmd.code) << 16);
		*(V32*)CMD_MBOX_1_ADDR = tmp;
		SFL_memcpy((U32*)CMD_DATA_ADDR, host_cmd.data, retlen);
		*(V32*)CMD_MBOX_0_ADDR |= M0_ACK;

		DISABLE_INTERRUPTS();
		HAL_arm1_fiq_enable_1(IRQM_FROMHOST);
		ENABLE_INTERRUPTS();

		host_cmd.code = 0xFFFF;		// mark no host command
	}

	// process host messages
	DISABLE_INTERRUPTS();
	while (hostmsg_queue.head)
	{
		HostMessage *pmsg;
		if ( *(V32*)EVENT_MBOX_0_ADDR & M0_EVENT) {
			// SMI is busy (pending event in SMI)
			// enable interrupt raised when available
			HAL_arm1_fiq_enable_1(IRQM_TOHOST);
			break;
		}
		else {
			pmsg = hostmsg_queue.head;
		   	tmp = (U32)pmsg->length | ( ((U32)pmsg->code) << 16);
		   	*(V32*)EVENT_MBOX_1_ADDR = tmp;
		    	SFL_memcpy((U32*)EVENT_DATA_ADDR, pmsg->data, pmsg->length);
			HAL_clear_interrupt_1(IRQM_TOHOST);
			*(V32*)EVENT_MBOX_0_ADDR |= M0_EVENT;
			HAL_generate_int_1(IRQM_CSP_HIDRV);
			hostmsg_queue.head = pmsg->next;
			msg_free(pmsg);
		}
	}
	ENABLE_INTERRUPTS();
}


HostMessage *msg_alloc(void)
{
	return SFL_alloc_part_lock(&HostmsgPart);
}

void msg_free(HostMessage *msg)
{
	SFL_free_part(&HostmsgPart, msg);
}


#endif
