/*
 *  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 "module_ethernet.h"
#include "module_ipv4.h"
#include "module_ipv6.h"
#include "module_pppoe.h"
#include "module_hidrv.h"
#include "module_timer.h"
#include "system.h"
#include "gemac.h"
#include "fpp.h"
#include "layer2.h"
#include "module_qm.h"
#include "module_wifi.h"

int PPPoE_Get_Next_SessionEntry(pPPPoECommand pSessionCmd, int reset_action);


#if defined(COMCERTO_2000)

static pPPPoE_Info pppoe_alloc(void)
{
	int i;

	for (i = 0; i < PPPOE_MAX_ITF; i++)
		if (!pppoe_itf[i].itf.type)
			return &pppoe_itf[i];

	return NULL;
}


static void pppoe_free(pPPPoE_Info pEntry)
{
	pEntry->itf.type = 0;
}


static void pppoe_add(pPPPoE_Info pEntry, U16 hash_key)
{
	struct pfe_ctrl *ctrl = &pfe->ctrl;
	int id;
	PPPoE_Info pppoe;

	/* Add to our local hash */
	slist_add(&pppoe_cache[hash_key], &pEntry->list);

	/* Construct the hardware entry, converting virtual addresses and endianess where needed */
	memcpy(&pppoe, pEntry, sizeof(PPPoE_Info));
	pppoe.itf.phys = (void *)cpu_to_be32(virt_to_class(pEntry->itf.phys));
	slist_set_next(&pppoe.list, (void *)cpu_to_be32(virt_to_class_dmem(slist_next(&pEntry->list))));
	pppoe.relay = (void *)cpu_to_be32(virt_to_class_dmem(pEntry->relay));
	pppoe.ppp_flags = cpu_to_be32(pEntry->ppp_flags);

	/* Update the PE pppoe interface in DMEM, for each PE */
	for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
		pe_dmem_memcpy_to32(id, virt_to_class_dmem(pEntry), &pppoe, sizeof(PPPoE_Info));

	/* Now add the interface to the PE pppoe hash in DMEM, for each PE and atomically */

	pe_sync_stop(ctrl, CLASS_MASK);

	/* We use the fact that slist_add() always adds to the head of the list */
	for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
		pe_dmem_write(id, cpu_to_be32(virt_to_class_dmem(&pEntry->list)), virt_to_class_dmem(&pppoe_cache[hash_key]), sizeof(struct slist_entry *));

	pe_start(ctrl, CLASS_MASK);
}


static void pppoe_remove(pPPPoE_Info pEntry, U16 hash_key)
{
	struct pfe_ctrl *ctrl = &pfe->ctrl;
	struct slist_entry *prev;
	int id;

	/* Now remove the interface from the PE pppoe hash in DMEM, for each PE and atomically */

	prev = slist_prev(&pppoe_cache[hash_key], &pEntry->list);
	
	pe_sync_stop(ctrl, CLASS_MASK);

	for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
		pe_dmem_write(id, cpu_to_be32(virt_to_class_dmem(slist_next(&pEntry->list))), virt_to_class_dmem(prev), sizeof(struct slist_entry *));

	pe_start(ctrl, CLASS_MASK);

	/* Remove from our local hash */
	slist_remove_after(prev);
}

void M_pppoe_encapsulate(PMetadata mtd, pPPPoE_Info ppp_info, U16 ethertype, U8 update)
{

}

#else

static pPPPoE_Info pppoe_alloc(void)
{
	return Heap_Alloc_ARAM(sizeof (PPPoE_Info));
}

static void pppoe_free(pPPPoE_Info pEntry)
{
	Heap_Free(pEntry);
}

static void pppoe_add(pPPPoE_Info pEntry, U16 hash_key)
{
	slist_add(&pppoe_cache[hash_key], &pEntry->list);
}

static void pppoe_remove(pPPPoE_Info pEntry, U16 hash_key)
{
	slist_remove(&pppoe_cache[hash_key], &pEntry->list);
}

#endif

static int PPPoE_Handle_Get_Idle(U16* p, U16 Length)
{
	pPPPoEIdleTimeCmd cmd;
	POnifDesc ppp_if;
	pPPPoE_Info pppoeinfo;

	cmd = (pPPPoEIdleTimeCmd)p;
	if (Length != sizeof(PPPoEIdleTimeCmd)) 
		return ERR_WRONG_COMMAND_SIZE;

	ppp_if = get_onif_by_name(cmd->ppp_intf);

	if (!ppp_if)
		return ERR_UNKNOWN_INTERFACE;
	
	if(ppp_if->itf->type & IF_TYPE_PPPOE)
	{
		pppoeinfo = (pPPPoE_Info)ppp_if->itf;
		if (pppoeinfo && (pppoeinfo->ppp_flags & PPPOE_AUTO_MODE))
		{
			cmd = (pPPPoEIdleTimeCmd)(p+1);
			SFL_memcpy(cmd->ppp_intf,ppp_if->name,sizeof(ppp_if->name));
#if defined(COMCERTO_2000)
			/* FIXME, add writeback to DDR, in the data path, to signal session activity */
			/* for now just prevent it from expiring */
			cmd->recv_idle = 0;
			cmd->xmit_idle = 0;
#else
			cmd->recv_idle = (ct_timer - pppoeinfo->last_pkt_rcvd) / CT_TICKS_PER_SECOND;
			cmd->xmit_idle= (ct_timer - pppoeinfo->last_pkt_xmit) / CT_TICKS_PER_SECOND;
#endif
			return NO_ERR;
		}
	}

	return ERR_UNKNOWN_INTERFACE;
}


static int PPPoE_Handle_Relay_Entry(U16 *p, U16 Length)
{
	pPPPoERelayCommand cmd;
	pPPPoE_Info pEntry, plastEntry = NULL;
	pPPPoE_Info pRelayEntry, plastRelayEntry = NULL;
	POnifDesc onif,relayonif;
	U16 hash_key,relay_hash_key;
	struct slist_entry *entry;

	cmd = (pPPPoERelayCommand) p;
	if (Length != sizeof(PPPoERelayCommand))
		return ERR_WRONG_COMMAND_SIZE;

	cmd->sesID = htons(cmd->sesID);
	cmd->relaysesID = htons(cmd->relaysesID);

	hash_key = HASH_PPPOE(cmd->sesID, cmd->peermac1);
	relay_hash_key = HASH_PPPOE(cmd->relaysesID, cmd->peermac2);

	switch (cmd->action)
	{
	case ACTION_REGISTER:

		slist_for_each(pEntry, entry, &pppoe_cache[hash_key], list)
		{
			 if((pEntry->sessionID == cmd->sesID) && TESTEQ_MACADDR(pEntry->DstMAC, cmd->peermac1))
				return ERR_PPPOE_ENTRY_ALREADY_REGISTERED; //trying to add the same pppoe session
		}

		slist_for_each(pRelayEntry, entry, &pppoe_cache[relay_hash_key], list)
		{
			if((pRelayEntry->sessionID == cmd->relaysesID) && TESTEQ_MACADDR(pRelayEntry->DstMAC, cmd->peermac2))
				return ERR_PPPOE_ENTRY_ALREADY_REGISTERED; //trying to add the same pppoe session
		}

		if ((pEntry = pppoe_alloc()) == NULL)
		{
			return ERR_NOT_ENOUGH_MEMORY;
		}
		memset(pEntry, 0, sizeof (PPPoE_Info));
		pEntry->itf.type = IF_TYPE_PPPOE;

		if ((pRelayEntry = pppoe_alloc()) == NULL)
		{
			pppoe_free(pEntry);
			return ERR_CREATION_FAILED;
		}
		memset(pRelayEntry, 0, sizeof (PPPoE_Info));
		pRelayEntry->itf.type = IF_TYPE_PPPOE;

		/* populate relay pairs */
		pEntry->sessionID = cmd->sesID;
		COPY_MACADDR(pEntry->DstMAC,cmd->peermac1);

		pRelayEntry->sessionID = cmd->relaysesID;
		COPY_MACADDR(pRelayEntry->DstMAC,cmd->peermac2);

		/*Check if the Physical interface is known by the Interface manager*/
		onif = get_onif_by_name(cmd->ipifname);
		relayonif = get_onif_by_name(cmd->opifname);

		if ((!onif) || (!relayonif)) {
			pppoe_free(pEntry);
			pppoe_free(pRelayEntry);
			return ERR_UNKNOWN_INTERFACE;
		}

		pEntry->itf.phys = onif->itf;
		pRelayEntry->itf.phys = relayonif->itf;

		/*Now link these two entries by relay ptr */
		pEntry->relay = pRelayEntry;
		pRelayEntry->relay = pEntry;

		/* FIXME, we need to add both entries atomically */
		pppoe_add(pEntry, hash_key);
		pppoe_add(pRelayEntry, relay_hash_key);

		PPPoE_entries++;

#ifdef CFG_STATS
		gStatPPPoEQueryStatus = STAT_PPPOE_QUERY_NOT_READY;
#endif
		break;

	case ACTION_DEREGISTER:
		slist_for_each(pEntry, entry, &pppoe_cache[hash_key], list)
		{
			if (pEntry->relay)
			{
				if((pEntry->sessionID == cmd->sesID) && TESTEQ_MACADDR(pEntry->DstMAC, cmd->peermac1)
				&& (pEntry->relay->sessionID == cmd->relaysesID) &&
				TESTEQ_MACADDR(pEntry->relay->DstMAC, cmd->peermac2))
					goto found;

			}

			plastEntry = pEntry;
	        }

		return ERR_PPPOE_ENTRY_NOT_FOUND;

	found:
		/* Now relay part as we already searched for relay link, just check for peer2mac and relaysesID */

		slist_for_each(pRelayEntry, entry, &pppoe_cache[relay_hash_key], list)
		{
			if((pRelayEntry->sessionID == cmd->relaysesID) &&
			     (TESTEQ_MACADDR(pRelayEntry->DstMAC, cmd->peermac2)) &&
			     (pRelayEntry->relay == pEntry))
				goto found_relay;

			plastRelayEntry = pRelayEntry;
		}

		return ERR_PPPOE_ENTRY_NOT_FOUND;

	found_relay:
		pppoe_remove(pEntry, hash_key);
		pppoe_remove(pRelayEntry, relay_hash_key);

		pppoe_free(pEntry);
		pppoe_free(pRelayEntry);

		PPPoE_entries--;

#ifdef CFG_STATS
		gStatPPPoEQueryStatus = STAT_PPPOE_QUERY_NOT_READY;
#endif

		 break;

	default :
		return ERR_UNKNOWN_COMMAND;
	}

	return NO_ERR;
}

static int PPPoE_Handle_Entry(U16 *p, U16 Length)
{
	pPPPoECommand cmd;
	pPPPoE_Info pEntry, plastEntry = NULL;
	POnifDesc phys_onif;
	U32 hash_key;
	struct slist_entry *entry;

	cmd = (pPPPoECommand) p;
	if (Length != sizeof(PPPoECommand))
		return ERR_WRONG_COMMAND_SIZE;

	cmd->sessionID = htons(cmd->sessionID);

	hash_key = HASH_PPPOE(cmd->sessionID, cmd->macAddr);

	switch (cmd->action)
	{
	case ACTION_DEREGISTER:
		slist_for_each(pEntry, entry, &pppoe_cache[hash_key], list)
		{
			if ((pEntry->sessionID == cmd->sessionID) && TESTEQ_MACADDR(pEntry->DstMAC, cmd->macAddr) &&
			    (pEntry->relay == NULL)  && !strcmp(get_onif_name(pEntry->itf.index), (char *)cmd->log_intf) )
				goto found;

			plastEntry = pEntry;
		}

		return ERR_PPPOE_ENTRY_NOT_FOUND;

	found:
		pppoe_remove(pEntry, hash_key);

		/*Tell the Interface Manager to remove the pppoe IF*/
		remove_onif_by_index(pEntry->itf.index);

		pppoe_free(pEntry);

		PPPoE_entries--;

#ifdef CFG_STATS
		gStatPPPoEQueryStatus = STAT_PPPOE_QUERY_NOT_READY;
#endif
		break;

	case ACTION_REGISTER:

		if (get_onif_by_name(cmd->log_intf))
			return ERR_PPPOE_ENTRY_ALREADY_REGISTERED;

		/*Check if the Physical interface is known by the Interface manager*/
		phys_onif = get_onif_by_name(cmd->phy_intf);
		if (!phys_onif)
			return ERR_UNKNOWN_INTERFACE;

		slist_for_each(pEntry, entry, &pppoe_cache[hash_key], list)
		{
			if ((pEntry->sessionID == cmd->sessionID) && TESTEQ_MACADDR(pEntry->DstMAC, cmd->macAddr))
				return ERR_PPPOE_ENTRY_ALREADY_REGISTERED; //trying to add exactly the same vlan entry
		}

		if ((pEntry = pppoe_alloc()) == NULL)
		{
			return ERR_NOT_ENOUGH_MEMORY;
		}

		memset(pEntry, 0, sizeof (PPPoE_Info));

		/* populate pppoe_info entry */
		pEntry->sessionID = cmd->sessionID;
		COPY_MACADDR(pEntry->DstMAC,cmd->macAddr);

		pEntry->last_pkt_rcvd = ct_timer;
		pEntry->last_pkt_xmit = ct_timer;

		if (cmd->mode & PPPOE_AUTO_MODE)
			pEntry->ppp_flags |= PPPOE_AUTO_MODE;

		/*Now create a new interface in the Interface Manager and remember the index*/
		if (!add_onif(cmd->log_intf, &pEntry->itf, phys_onif->itf, IF_TYPE_PPPOE))
		{
			pppoe_free(pEntry);
			return ERR_CREATION_FAILED;
		}

		pppoe_add(pEntry, hash_key);

		PPPoE_entries++;

#ifdef CFG_STATS
		gStatPPPoEQueryStatus = STAT_PPPOE_QUERY_NOT_READY;
#endif
		break;

	case ACTION_QUERY:
	case ACTION_QUERY_CONT:
		{
		int rc;

		rc = PPPoE_Get_Next_SessionEntry(cmd, cmd->action == ACTION_QUERY);
		return rc;

		}

	default:
		return ERR_UNKNOWN_ACTION;
	}

	/* return success */
	return NO_ERR;
}


static U16 M_pppoe_cmdproc(U16 cmd_code, U16 cmd_len, U16 *pcmd)
{
	U16 rc = NO_ERR;
	U16 ret_len = 2;
	U16 action;

        switch (cmd_code)
	{
		case CMD_PPPOE_ENTRY:
			action = *pcmd;
			rc = PPPoE_Handle_Entry(pcmd, cmd_len);
			if (rc == NO_ERR && (action == ACTION_QUERY || action == ACTION_QUERY_CONT))
				ret_len = sizeof(PPPoECommand);
			break;

		case CMD_PPPOE_RELAY_ENTRY:
			action = *pcmd;
			rc = PPPoE_Handle_Relay_Entry(pcmd, cmd_len);
			if (rc == NO_ERR && (action == ACTION_QUERY || action == ACTION_QUERY_CONT))
				ret_len = sizeof(PPPoECommand);
			break;

		case CMD_PPPOE_GET_IDLE:
			rc = PPPoE_Handle_Get_Idle(pcmd, cmd_len);
			if (rc == NO_ERR)
				ret_len = sizeof(PPPoEIdleTimeCmd) + 2;
			break;	

		default:
			rc = ERR_UNKNOWN_COMMAND;
			break;
        }

	*pcmd = rc;
	return ret_len;
}


int pppoe_init(void)
{
	int i;

#if !defined(COMCERTO_2000)
	set_event_handler(EVENT_PPPOE, M_pppoe_ingress);
#endif

	set_cmd_handler(EVENT_PPPOE, M_pppoe_cmdproc);

	for (i = 0; i < NUM_PPPOE_ENTRIES; i++)
	{
		slist_head_init(&pppoe_cache[i]);
	}

	return 0;
}

void pppoe_exit(void)
{
	/* FIXME remove all pppoe interfaces */
}
