/*
 *  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 "module_ethernet.h"
#include "fe.h"
#include "module_Rx.h"
#include "module_stat.h"
#include "layer2.h"
#include "module_timer.h"
#include "module_bridge.h"

#if !defined (COMCERTO_2000)
PVOID bridge_snapshot_alloc(U32 size)
{
	return Heap_Alloc(size);
}

void bridge_snapshot_free(PVOID p)
{
	Heap_Free(p);
}

#else

extern U32 L2Bridge_timeout;

PVOID bridge_snapshot_alloc(U32 size)
{
	return pfe_kzalloc(size, GFP_KERNEL);
}

void bridge_snapshot_free(PVOID p)
{
	pfe_kfree(p);
}
#endif


/* This function returns total bridge entries configured 
   in a given hash index */

static int rx_Get_Hash_BridgeEntries(int bridge_hash_index)
{
	
	int tot_bridge_entries = 0;
	PL2Bridge_entry pEntry;
	struct slist_entry *entry;

	slist_for_each(pEntry, entry, &bridge_cache[bridge_hash_index], list)
	{
		tot_bridge_entries++;
	}
		
	return tot_bridge_entries;
}

/* This function fills the snapshot of bridge entries 
   in a given hash index */

static int rx_Bridge_Get_Hash_Snapshot(int bt_hash_index, int br_tot_entries, PL2BridgeQueryEntryResponse pBridgeSnapshot)
{
	int tot_bridge_entries=0;
	PL2Bridge_entry pBridgeEntry;
	struct slist_entry *entry;
		
	slist_for_each(pBridgeEntry, entry, &bridge_cache[bt_hash_index], list) 
	{
		if(br_tot_entries > 0)
		{
			pBridgeSnapshot->input_interface  = pBridgeEntry->input_interface;
			pBridgeSnapshot->input_vlan       = htons(pBridgeEntry->input_vlan);
			pBridgeSnapshot->output_interface  = pBridgeEntry->output_itf->index;
			pBridgeSnapshot->output_vlan       = htons(pBridgeEntry->output_vlan);
			SFL_memcpy(pBridgeSnapshot->destaddr, pBridgeEntry->da, 2 * ETHER_ADDR_LEN);
			pBridgeSnapshot->ethertype       = htons(pBridgeEntry->ethertype);
			pBridgeSnapshot->pkt_priority    = pBridgeEntry->pkt_priority == 0xFF ? 0x8000 : pBridgeEntry->pkt_priority;
			pBridgeSnapshot->vlan_priority = pBridgeEntry->vlan_priority_mark ? 0x8000 : pBridgeEntry->vlan_priority;
			pBridgeSnapshot->session_id = htons(pBridgeEntry->session_id);
			pBridgeSnapshot->qmod = pBridgeEntry->qmod;
			SFL_memcpy(pBridgeSnapshot->input_name, get_onif_name(phy_port[pBridgeEntry->input_interface].itf.index), 16);
			SFL_memcpy(pBridgeSnapshot->output_name, get_onif_name(pBridgeEntry->output_itf->index), 16);
		
			pBridgeSnapshot++;
			tot_bridge_entries++;
			br_tot_entries--;
		}
	}
		
	return tot_bridge_entries;

}

/* This function creates the snapshot memory and returns the 
   next bridge entry from the snapshop of the bridge entries of a
   single hash to the caller  */

int rx_Get_Next_Hash_BridgeEntry(PL2BridgeQueryEntryResponse pBridgeCmd, int reset_action)
{
	int bridge_hash_entries;
	PL2BridgeQueryEntryResponse pBridge;
	static PL2BridgeQueryEntryResponse pBridgeSnapshot = NULL;
	static int bridge_hash_index = 0, bridge_snapshot_entries =0, bridge_snapshot_index=0, bridge_snapshot_buf_entries = 0;
	
	if(reset_action)
	{
		bridge_hash_index = 0;
		bridge_snapshot_entries = 0;
		bridge_snapshot_index = 0;
		if(pBridgeSnapshot)
		{
			bridge_snapshot_free(pBridgeSnapshot);
			pBridgeSnapshot = NULL;
		}
		bridge_snapshot_buf_entries = 0;
		return NO_ERR;
	}
	
	if (bridge_snapshot_index == 0)
	{
		while( bridge_hash_index < NUM_BT_ENTRIES)
		{
		
			bridge_hash_entries = rx_Get_Hash_BridgeEntries(bridge_hash_index);
			if(bridge_hash_entries == 0)
			{
				bridge_hash_index++;
				continue;
			}
		   	
		   	if(bridge_hash_entries > bridge_snapshot_buf_entries)
		   	{
		   		if(pBridgeSnapshot)	
		   			bridge_snapshot_free(pBridgeSnapshot);
		   
				pBridgeSnapshot = bridge_snapshot_alloc(bridge_hash_entries * sizeof(L2BridgeQueryEntryResponse));
			
				if (!pBridgeSnapshot)
				{
			    	bridge_hash_index = 0;
			    	bridge_snapshot_buf_entries = 0;
					return ERR_NOT_ENOUGH_MEMORY;
				}
				bridge_snapshot_buf_entries = bridge_hash_entries;
		   	}
		
			bridge_snapshot_entries = rx_Bridge_Get_Hash_Snapshot(bridge_hash_index , bridge_hash_entries, pBridgeSnapshot);
	
			break;
		}
		
		if (bridge_hash_index >= NUM_BT_ENTRIES)
		{
			bridge_hash_index = 0;
			if(pBridgeSnapshot)
			{
				bridge_snapshot_free(pBridgeSnapshot);
				pBridgeSnapshot = NULL;
			}
			bridge_snapshot_buf_entries = 0;
			return ERR_BRIDGE_ENTRY_NOT_FOUND;
		}
		   
	}
	
	pBridge = &pBridgeSnapshot[bridge_snapshot_index++];
	SFL_memcpy(pBridgeCmd, pBridge, sizeof(L2BridgeQueryEntryResponse));
	if (bridge_snapshot_index == bridge_snapshot_entries)
	{
		bridge_snapshot_index = 0;
		bridge_hash_index ++;
	}
		
	
	return NO_ERR;	
		
}



#ifdef CFG_STATS
/* This function fills the snapshot of bridge entries 
   in a given hash index */

static int stat_Bridge_Get_Hash_Snapshot(int stat_bt_hash_index, int stat_tot_br_entries, PStatBridgeEntryResponse pStatBridgeSnapshot)
{
	int stat_bridge_entries=0;
	PL2Bridge_entry pStatBridgeEntry;
	struct slist_entry *entry;
	
	slist_for_each(pStatBridgeEntry, entry, &bridge_cache[stat_bt_hash_index], list)
	{
		if(stat_tot_br_entries > 0)
		{
			pStatBridgeSnapshot->eof = 0;
			pStatBridgeSnapshot->input_interface = pStatBridgeEntry->input_interface;
			pStatBridgeSnapshot->input_vlan = htons(pStatBridgeEntry->input_vlan);
			pStatBridgeSnapshot->output_interface = pStatBridgeEntry->output_itf->index;
			pStatBridgeSnapshot->output_vlan = htons(pStatBridgeEntry->output_vlan);
			SFL_memcpy(pStatBridgeSnapshot->dst_mac, pStatBridgeEntry->da, 2 * ETHER_ADDR_LEN);
			pStatBridgeSnapshot->etherType = htons(pStatBridgeEntry->ethertype);
			pStatBridgeSnapshot->session_id = htons(pStatBridgeEntry->session_id);
#if !defined (COMCERTO_2000)
			pStatBridgeSnapshot->total_packets_transmitted = pStatBridgeEntry->total_packets_transmitted;
#else
			{
				struct _thw_L2Bridge_entry *hw_l2bridge = pStatBridgeEntry->hw_l2bridge;
				class_statistics_get_ddr(hw_l2bridge->total_packets_transmitted,
						&pStatBridgeSnapshot->total_packets_transmitted,
						sizeof(pStatBridgeSnapshot->total_packets_transmitted),
						gStatBridgeQueryStatus & STAT_BRIDGE_QUERY_RESET);
			}
#endif

			SFL_memcpy(pStatBridgeSnapshot->input_name, get_onif_name(phy_port[pStatBridgeEntry->input_interface].itf.index), 16);
			SFL_memcpy(pStatBridgeSnapshot->output_name, get_onif_name(pStatBridgeEntry->output_itf->index), 16);
		
#if !defined (COMCERTO_2000)
			if(gStatBridgeQueryStatus & STAT_BRIDGE_QUERY_RESET)
				pStatBridgeEntry->total_packets_transmitted = 0;
#endif

			pStatBridgeSnapshot++;
			stat_bridge_entries++;
			stat_tot_br_entries--;
		}
	}
		
	return stat_bridge_entries;

}

/* This function creates the snapshot memory and returns the 
   next bridge entry from the snapshop of the bridge entries of a
   single hash to the caller  */

int rx_Get_Next_Hash_Stat_BridgeEntry(PStatBridgeEntryResponse pStatBridgeCmd, int reset_action)
{
	int stat_bridge_hash_entries;
	PStatBridgeEntryResponse pStatBridge;
	static PStatBridgeEntryResponse pStatBridgeSnapshot = NULL;
	static int stat_bridge_hash_index = 0, stat_bridge_snapshot_entries =0, stat_bridge_snapshot_index=0, stat_bridge_snapshot_buf_entries = 0;
	
	if(reset_action)
	{
		stat_bridge_hash_index = 0;
		stat_bridge_snapshot_entries = 0;
		stat_bridge_snapshot_index	=	0;
		if(pStatBridgeSnapshot)
		{
			bridge_snapshot_free(pStatBridgeSnapshot);
			pStatBridgeSnapshot = NULL;
		}
		stat_bridge_snapshot_buf_entries = 0;
		return NO_ERR;
	}
	
	if (stat_bridge_snapshot_index == 0)
	{
		while( stat_bridge_hash_index < NUM_BT_ENTRIES)
		{
		
			stat_bridge_hash_entries = rx_Get_Hash_BridgeEntries(stat_bridge_hash_index);
			if(stat_bridge_hash_entries == 0)
			{
				stat_bridge_hash_index++;
				continue;
			}
		   	
		   	if(stat_bridge_hash_entries > stat_bridge_snapshot_buf_entries)
		   	{
		   		if(pStatBridgeSnapshot)
		   			bridge_snapshot_free(pStatBridgeSnapshot);
		   		pStatBridgeSnapshot = bridge_snapshot_alloc(stat_bridge_hash_entries * sizeof(StatBridgeEntryResponse));
			
				if (!pStatBridgeSnapshot)
				{
			    	stat_bridge_hash_index = 0;
			    	stat_bridge_snapshot_buf_entries = 0;
					return ERR_NOT_ENOUGH_MEMORY;
				}
				stat_bridge_snapshot_buf_entries = 	stat_bridge_hash_entries;
		   	}
			stat_bridge_snapshot_entries = stat_Bridge_Get_Hash_Snapshot(stat_bridge_hash_index ,stat_bridge_hash_entries, pStatBridgeSnapshot);
		
			break;
		}
		
		if (stat_bridge_hash_index >= NUM_BT_ENTRIES)
		{
			stat_bridge_hash_index = 0;
			if(pStatBridgeSnapshot)
			{
				bridge_snapshot_free(pStatBridgeSnapshot);
				pStatBridgeSnapshot = NULL;
			}
			stat_bridge_snapshot_buf_entries = 0;
			return ERR_BRIDGE_ENTRY_NOT_FOUND;
		}
		   
	}
	
	pStatBridge = &pStatBridgeSnapshot[stat_bridge_snapshot_index++];
	SFL_memcpy(pStatBridgeCmd, pStatBridge, sizeof(StatBridgeEntryResponse));
	if (stat_bridge_snapshot_index == stat_bridge_snapshot_entries)
	{
		stat_bridge_snapshot_index = 0;
		stat_bridge_hash_index ++;
	}
		
	
	return NO_ERR;	
		
}
#endif /* CFG_STATS */

/* This function returns total L2Flow entries configured 
   in a given hash index */
static int rx_Get_Hash_L2FlowEntries(int L2Flow_hash_index)
{	
	int tot_bridge_entries = 0;
	PL2Flow_entry pL2FlowEntry;
	PL3Flow_entry pL3FlowEntry;
	struct slist_entry *entry;

	/* Hash index matches L2 Flow table*/
	if(L2Flow_hash_index < NUM_BT_ENTRIES)
	{
		/* Only process L2 only entries */
		slist_for_each(pL2FlowEntry, entry, &bridge_cache[L2Flow_hash_index], list)
		{
			if(!pL2FlowEntry->nb_l3_ref)
				tot_bridge_entries++;
		}
	}
	else
	{
		/* Index matches L3 table, process L3 entries */
		slist_for_each(pL3FlowEntry, entry, &bridge_l3_cache[L2Flow_hash_index -NUM_BT_ENTRIES], list)
		{
			tot_bridge_entries++;
		}
	}
	
	return tot_bridge_entries;
}

/* This function fills the snapshot of bridge entries 
   in a given hash index */
static int rx_Get_Hash_Snapshot_L2FlowEntries(int L2Flow_hash_index, int L2Flow_tot_entries, PL2BridgeL2FlowEntryCommand pL2FlowSnapshot)
{
	int tot_bridge_entries = 0;
	PL2Flow_entry pL2FlowEntry;
	PL3Flow_entry pL3FlowEntry;

	if(L2Flow_hash_index < NUM_BT_ENTRIES){
		pL2FlowEntry = container_of(slist_first(&bridge_cache[L2Flow_hash_index]), typeof(L2Flow_entry), list);
		pL3FlowEntry = NULL;
	}
	else{
		pL3FlowEntry = container_of(slist_first(&bridge_l3_cache[L2Flow_hash_index - NUM_BT_ENTRIES]), typeof(L3Flow_entry), list);
		pL2FlowEntry = pL3FlowEntry->l2flow_entry;
	}
		
	while ((pL2FlowEntry) && (L2Flow_tot_entries > 0)) {
		
		memset(pL2FlowSnapshot, 0 , sizeof(L2BridgeL2FlowEntryCommand));
		
		/* L2 info */
		SFL_memcpy(pL2FlowSnapshot->destaddr, pL2FlowEntry->l2flow.da, 2 * ETHER_ADDR_LEN);
		pL2FlowSnapshot->ethertype = pL2FlowEntry->l2flow.ethertype;
		pL2FlowSnapshot->vlan_tag = pL2FlowEntry->l2flow.vlan_tag;
		pL2FlowSnapshot->session_id = pL2FlowEntry->l2flow.session_id;
		SFL_memcpy(pL2FlowSnapshot->input_name, get_onif_name(pL2FlowEntry->input_ifindex), INTERFACE_NAME_LENGTH);
		SFL_memcpy(pL2FlowSnapshot->output_name, get_onif_name(pL2FlowEntry->output_if->index), INTERFACE_NAME_LENGTH);
		
		/* L3-4 info */
		if(pL3FlowEntry){
			SFL_memcpy(pL2FlowSnapshot->saddr, pL3FlowEntry->l3flow.saddr, IPV6_ADDRESS_LENGTH);
			SFL_memcpy(pL2FlowSnapshot->daddr, pL3FlowEntry->l3flow.daddr, IPV6_ADDRESS_LENGTH);
			pL2FlowSnapshot->proto = pL3FlowEntry->l3flow.proto;
			pL2FlowSnapshot->sport = pL3FlowEntry->l3flow.sport;
			pL2FlowSnapshot->dport = pL3FlowEntry->l3flow.dport;
			pL2FlowSnapshot->timeout = (L2Bridge_timeout - (ct_timer - pL3FlowEntry->last_l3flow_timer)) / CT_TICKS_PER_SECOND;
		}
		else
			pL2FlowSnapshot->timeout = (L2Bridge_timeout - (ct_timer - pL2FlowEntry->last_l2flow_timer)) / CT_TICKS_PER_SECOND;
		
		/* Get next entry */
		if(pL3FlowEntry){
			pL3FlowEntry = container_of(slist_next(&pL3FlowEntry->list), typeof(L3Flow_entry), list);
			if(pL3FlowEntry)
				pL2FlowEntry = pL3FlowEntry->l2flow_entry;
			else
				pL2FlowEntry = NULL;
		}
		else
			pL2FlowEntry = container_of(slist_next(&pL2FlowEntry->list), typeof(L2Flow_entry), list);
		
		pL2FlowSnapshot++;
		tot_bridge_entries++;
		L2Flow_tot_entries--;
	}
		
	return tot_bridge_entries;

}

/* This function creates the snapshot memory and returns the 
   next bridge entry from the snapshop of the bridge entries of a
   single hash to the caller  
   Both L2 and L3 tables are linearly parsed */
int rx_Get_Next_Hash_L2FlowEntry(PL2BridgeL2FlowEntryCommand pL2FlowCmd, int reset_action)
{
	int L2Flow_hash_entries;
	static PL2BridgeL2FlowEntryCommand pL2FlowSnapshot = NULL;
	static int L2Flow_hash_index = 0, L2Flow_snapshot_entries = 0, 
		L2Flow_snapshot_index = 0, L2Flow_snapshot_buf_entries = 0;

	/* Reset */
	if(reset_action){
		L2Flow_hash_index = 0;
		L2Flow_snapshot_entries = 0;
		L2Flow_snapshot_index = 0;

		if(pL2FlowSnapshot){
			bridge_snapshot_free(pL2FlowSnapshot);
			pL2FlowSnapshot = NULL;
		}
		L2Flow_snapshot_buf_entries = 0;
	}
	
	if (L2Flow_snapshot_index == 0){
		while( L2Flow_hash_index < (NUM_BT_ENTRIES + NUM_BT_L3_ENTRIES)){

			/* Get next non-null bucket */
			L2Flow_hash_entries = rx_Get_Hash_L2FlowEntries(L2Flow_hash_index);
			if(L2Flow_hash_entries == 0){
				L2Flow_hash_index++;
				continue;
			}
			
		   	/* Alloc snapshot buffer if needed */
		   	if(L2Flow_hash_entries > L2Flow_snapshot_buf_entries){
		   		if(pL2FlowSnapshot)	
		   			bridge_snapshot_free(pL2FlowSnapshot);
		   
				pL2FlowSnapshot = bridge_snapshot_alloc(L2Flow_hash_entries * sizeof(L2BridgeL2FlowEntryCommand));
			
				if (!pL2FlowSnapshot){
					L2Flow_hash_index = 0;
					L2Flow_snapshot_buf_entries = 0;
					return ERR_NOT_ENOUGH_MEMORY;
				}
				L2Flow_snapshot_buf_entries = L2Flow_hash_entries;
		   	}
		
			L2Flow_snapshot_entries = rx_Get_Hash_Snapshot_L2FlowEntries(L2Flow_hash_index , L2Flow_hash_entries, pL2FlowSnapshot);
	
			break;
		}
		
		/* No more entries */
		if (L2Flow_hash_index >= (NUM_BT_ENTRIES + NUM_BT_L3_ENTRIES)){
			L2Flow_hash_index = 0;
			if(pL2FlowSnapshot){
				bridge_snapshot_free(pL2FlowSnapshot);
				pL2FlowSnapshot = NULL;
			}
			L2Flow_snapshot_buf_entries = 0;
			return ERR_BRIDGE_ENTRY_NOT_FOUND;
		}
		   
	}
	
	SFL_memcpy(pL2FlowCmd, &pL2FlowSnapshot[L2Flow_snapshot_index++], sizeof(L2BridgeL2FlowEntryCommand));
	if (L2Flow_snapshot_index == L2Flow_snapshot_entries){
		L2Flow_snapshot_index = 0;
		L2Flow_hash_index ++;
	}
	return NO_ERR;		
}
