/*  
 *  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_hidrv.h"
#include "system.h"
#include "gemac.h"
#include "fpp.h"
#include "module_vlan.h"
#include "layer2.h"


int Vlan_Get_Next_Hash_Entry(PVlanCommand pVlanCmd, int reset_action);


#if defined(COMCERTO_2000)

static PVlanEntry vlan_alloc(void)
{
	int i;

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

	return NULL;
}

static void vlan_free(PVlanEntry pEntry)
{
	pEntry->itf.type = 0;
}

static void vlan_add(PVlanEntry pEntry, U16 hash_key)
{
	struct pfe_ctrl *ctrl = &pfe->ctrl;
	int id;
	VlanEntry vlan;

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

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

	/* Update the PE vlan 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), &vlan, sizeof(VlanEntry));

	/* Now add the interface to the PE vlan 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(&vlan_cache[hash_key]), sizeof(struct slist_entry *));

	pe_start(ctrl, CLASS_MASK);
}

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

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

	prev = slist_prev(&vlan_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_vlan_encapsulate(PMetadata mtd, PVlanEntry pEntry, U16 ethertype, U8 update)
{

}
#else

static PVlanEntry vlan_alloc(void)
{
	return Heap_Alloc_ARAM(sizeof (VlanEntry));
}

static void vlan_free(PVlanEntry pEntry)
{
	Heap_Free(pEntry);
}

static void vlan_add(PVlanEntry pEntry, U16 hash_key)
{
	slist_add(&vlan_cache[hash_key], &pEntry->list);
}

static void vlan_remove(PVlanEntry pEntry, U16 hash_key)
{
	slist_remove(&vlan_cache[hash_key], &pEntry->list);
}

#endif

static U16 Vlan_handle_reset(void)
{
	PVlanEntry pEntry;
	struct slist_entry *entry;
	int i;

	/* free VLAN entries */
	for(i = 0; i < NUM_VLAN_ENTRIES; i++)
	{
		slist_for_each_safe(pEntry, entry, &vlan_cache[i], list)
		{
			remove_onif_by_index(pEntry->itf.index);
			vlan_remove(pEntry, i);
			vlan_free(pEntry);
		}
	}

	return NO_ERR;
}


static U16 Vlan_handle_entry(U16 * p,U16 Length)
{
	PVlanEntry pEntry,plastEntry = NULL;
	struct slist_entry *entry;
	VlanCommand vlancmd;
	POnifDesc phys_onif;
	U16	hash_key;
	int reset_action = 0;

	// Check length
	if (Length != sizeof(VlanCommand))
		return ERR_WRONG_COMMAND_SIZE;
	
	SFL_memcpy((U8*)&vlancmd, (U8*)p,  sizeof(VlanCommand));

	hash_key = HASH_VLAN(htons(vlancmd.vlanID));

	switch(vlancmd.action)
	{
		case ACTION_DEREGISTER: 

			slist_for_each(pEntry, entry, &vlan_cache[hash_key], list)
			{
				if ((pEntry->VlanId == htons(vlancmd.vlanID & 0xfff)) && (strcmp(get_onif_name(pEntry->itf.index), (char *)vlancmd.vlanifname) == 0))
					goto found;

				plastEntry = pEntry;
			}

			return ERR_VLAN_ENTRY_NOT_FOUND;

		found:
			vlan_remove(pEntry, hash_key);

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

			break;

		case ACTION_REGISTER: 

			if (get_onif_by_name(vlancmd.vlanifname))
				return ERR_VLAN_ENTRY_ALREADY_REGISTERED;

			slist_for_each(pEntry, entry, &vlan_cache[hash_key], list)
			{
				if ((pEntry->VlanId == htons(vlancmd.vlanID & 0xfff)) && (strcmp(get_onif_name(pEntry->itf.index), (char *)vlancmd.vlanifname) == 0) )
					return ERR_VLAN_ENTRY_ALREADY_REGISTERED; //trying to add exactly the same vlan entry
			}

			if ((pEntry = vlan_alloc()) == NULL)
			{
			  	return ERR_NOT_ENOUGH_MEMORY;
			}
			
	  		memset(pEntry, 0, sizeof (VlanEntry));
			pEntry->VlanId = htons(vlancmd.vlanID & 0xfff);

			/*Check if the Physical interface is known by the Interface manager*/
			phys_onif = get_onif_by_name(vlancmd.phyifname);
			if (!phys_onif)
			{
				vlan_free(pEntry);
				return ERR_UNKNOWN_INTERFACE;
			}

			/*Now create a new interface in the Interface Manager and remember the index*/
			if (!add_onif(vlancmd.vlanifname, &pEntry->itf, phys_onif->itf, IF_TYPE_VLAN))
			{
				vlan_free(pEntry);
				return ERR_CREATION_FAILED;
			}

			vlan_add(pEntry, hash_key);

			break;
			
		case ACTION_QUERY:
			reset_action = 1;
		case ACTION_QUERY_CONT:
		{
			PVlanCommand pVlan = (VlanCommand*)p;
			int rc;
			
			rc = Vlan_Get_Next_Hash_Entry(pVlan, reset_action);
			return rc;
		}
		
			
		default:
			return ERR_UNKNOWN_ACTION;
	}

	return NO_ERR;
}


static U16 M_vlan_cmdproc(U16 cmd_code, U16 cmd_len, U16 *pcmd)
{
	U16 rc;
	U16 retlen = 2;
	U16 action;

	switch (cmd_code)
	{
		case CMD_VLAN_ENTRY:
			action = *pcmd;
			rc = Vlan_handle_entry(pcmd, cmd_len);
			if (rc == NO_ERR && (action == ACTION_QUERY || action == ACTION_QUERY_CONT))
				retlen += sizeof (VlanCommand);
			break;

		case CMD_VLAN_ENTRY_RESET:
			rc = Vlan_handle_reset();
			break;

		default:
			rc = ERR_UNKNOWN_COMMAND;
			break;
	}

	*pcmd = rc;
	return retlen;
}


int vlan_init(void)
{
	int i;

#if !defined(COMCERTO_2000)
	set_event_handler(EVENT_VLAN, M_vlan_entry);
#endif

	set_cmd_handler(EVENT_VLAN, M_vlan_cmdproc);

	for(i = 0; i < NUM_VLAN_ENTRIES; i++)
	{
		slist_head_init(&vlan_cache[i]);
	}

	return 0;
}


void vlan_exit(void)
{
	/* FIXME just call vlan reset ? */
}
