/*
 *  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_mc4.h"
#include "types.h"
#include "system.h"
#include "fpp.h"
#include "checksum.h"
#include "module_vlan.h"
#include "module_Rx.h"
#include "module_hidrv.h"
#include "module_timer.h"
#include "module_expt.h"
#include "gemac.h"
#include "fe.h"
#include "layer2.h"
#include "alt_conf.h"
#include "module_rtp_relay.h"
#include "module_qm.h"
#include "module_wifi.h"

#if defined(COMCERTO_2000)
#include "control_common.h"

struct dma_pool *mc4_dma_pool;
extern TIMER_ENTRY mc4_delayed_remove_timer;
extern TIMER_ENTRY mc4_timer;
struct dlist_head hw_mc4_active_list[MC4_NUM_HASH_ENTRIES];
struct dlist_head hw_mc4_removal_list;
#endif
 
#if !defined(COMCERTO_2000)
PVOID MC4_entry_alloc(void)
{
	return Heap_Alloc(sizeof(struct _tMC4Entry));
}

void MC4_entry_free(PMC4Entry this_entry)
{
	Heap_Free((PVOID) this_entry);
}

static int MC4_entry_add(PMC4Entry this_entry, U32 hash)
{
	/* Add software entry to local hash */
	slist_add(&mc4_table_memory[hash], &this_entry->list);
	
	/* check if rtp stats entry is created for this conntrack, if found link the two object and mark the conntrack 's status field for RTP stats */
	rtpqos_mc4_link_stats_entry_by_tuple(this_entry, this_entry->src_addr, this_entry->dst_addr);

	return NO_ERR;
}

static void MC4_entry_remove(PMC4Entry this_entry, U32 hash)
{
	slist_remove(&mc4_table_memory[hash], &this_entry->list);
	MC4_entry_free(this_entry);
}

void MC4_entry_update(PMC4Entry this_entry)
{

}

#else


static void MC4_entry_add_to_pe(U32 dma_addr, U32 hash)
{
	int id;
	U32 *pe_addr;

	pe_addr = (U32*)&mc4_table_memory[hash];

	for (id=CLASS0_ID; id <= CLASS_MAX_ID; id++)
		pe_dmem_write(id, dma_addr, virt_to_class_dmem(pe_addr), 4);
}


void MC4_entry_update(PMC4Entry this_entry)
{
	int i;
	Phw_MC4Entry hw_entry = this_entry->hw_entry;

	hw_entry_set_flags(&this_entry->hw_entry->flags, HASH_ENTRY_UPDATING | HASH_ENTRY_VALID);

	/* FIXME: could be enhanced with a reworked hw_entry structure layout + memcpy */
	hw_entry->src_addr = this_entry->src_addr;
	hw_entry->dst_addr = this_entry->dst_addr;
	hw_entry->status = cpu_to_be16(this_entry->status);

	memcpy(&hw_entry->mcdest, &this_entry->mcdest, sizeof(MCxEntry));
	hw_entry->mcdest.wifi_listener_timer = cpu_to_be32(this_entry->mcdest.wifi_listener_timer);
	for (i=0; i < this_entry->mcdest.num_listeners; i++) {
		hw_entry->mcdest.listeners[i].itf = (struct itf *) cpu_to_be32(virt_to_class_dmem(this_entry->mcdest.listeners[i].itf));
		hw_entry->mcdest.listeners[i].timer = cpu_to_be32(this_entry->mcdest.listeners[i].timer);
	}

	hw_entry_set_flags(&this_entry->hw_entry->flags, HASH_ENTRY_VALID);
}


static void hw_MC4_entry_schedule_remove(struct _thw_MC4Entry *hw_entry)
{
	hw_entry->removal_time = jiffies + 2;
	dlist_add(&hw_mc4_removal_list, &hw_entry->list);
}

/** Processes hardware socket delayed removal list.
* Free all hardware socket in the removal list that have reached their removal time.
*
*
*/
static void hw_MC4_entry_delayed_remove(void)
{
	struct dlist_head *entry;
	struct _thw_MC4Entry *hw_entry;

	dlist_for_each_safe(hw_entry, entry, &hw_mc4_removal_list, list)
	{
		if (!time_after(jiffies, hw_entry->removal_time))
			continue;

		dlist_remove(&hw_entry->list);

		dma_pool_free(mc4_dma_pool, hw_entry, be32_to_cpu(hw_entry->dma_addr));
	}
}


static PVOID MC4_entry_alloc(void)
{
	return pfe_kzalloc(sizeof(struct _tMC4Entry), GFP_KERNEL);
}

static void MC4_entry_free(PMC4Entry this_entry)
{
	pfe_kfree(this_entry);
}

static int MC4_entry_add(PMC4Entry this_entry, U32 hash)
{
	struct _thw_MC4Entry *hw_entry;
	struct _thw_MC4Entry *hw_entry_first;
	dma_addr_t dma_addr;
	int rc = NO_ERR;

	/* Allocate hardware entry */
	hw_entry = dma_pool_alloc(mc4_dma_pool, GFP_ATOMIC, &dma_addr);
	if (!hw_entry)
	{
		rc = ERR_NOT_ENOUGH_MEMORY;
		goto err;
	}

	hw_entry->dma_addr = cpu_to_be32(dma_addr);

	/* Link software conntrack to hardware conntrack */
	this_entry->hw_entry = hw_entry;
	hw_entry->sw_entry = this_entry;

	/* add hw entry to active list and update next pointer */
	if(!dlist_empty(&hw_mc4_active_list[hash]))
	{
		/* list is not empty, and we'll be added at head, so current first will become our next pointer */
		hw_entry_first = container_of(dlist_first(&hw_mc4_active_list[hash]), typeof(struct _thw_MC4Entry), list);
		hw_entry_set_field(&hw_entry->next, hw_entry_get_field(&hw_entry_first->dma_addr));
	}
	else
	{
		/* entry is empty, so we'll be the first and only one entry */
		hw_entry_set_field(&hw_entry->next, 0);
	}

	dlist_add(&hw_mc4_active_list[hash], &hw_entry->list);

	/* check if rtp stats entry is created for this conntrack, if found link the two object and mark the conntrack 's status field for RTP stats */
	rtpqos_mc4_link_stats_entry_by_tuple(this_entry, this_entry->src_addr, this_entry->dst_addr);

	/* reflect changes to hardware entry */
	MC4_entry_update(this_entry);

	/* Update PE's internal memory socket cache tables with the HW entry's DDR address */
	MC4_entry_add_to_pe(hw_entry->dma_addr, hash);

	/* Add software entry to local hash */
	slist_add(&mc4_table_memory[hash], &this_entry->list);

	return NO_ERR;

err:
	MC4_entry_free(this_entry);

	return rc;
}

static void MC4_entry_remove(PMC4Entry this_entry, U32 hash)
{
	struct _thw_MC4Entry *hw_entry;
	struct _thw_MC4Entry *hw_entry_prev;

	/* Check if there is a hardware entry */
	if ((hw_entry = this_entry->hw_entry))
	{
		/* Detach from software socket */
		this_entry->hw_entry = NULL;

		/* if the removed entry is first in hash slot then only PE dmem hash need to be updated */
		if (&hw_entry->list == dlist_first(&hw_mc4_active_list[hash]))
		{
			MC4_entry_add_to_pe(hw_entry_get_field(&hw_entry->next), hash);
		}
		else
		{
			hw_entry_prev = container_of(hw_entry->list.prev, typeof(struct _thw_MC4Entry), list);
			hw_entry_set_field(&hw_entry_prev->next, hw_entry_get_field(&hw_entry->next));
		}
		dlist_remove(&hw_entry->list);

		hw_MC4_entry_schedule_remove(hw_entry);
	}

	slist_remove(&mc4_table_memory[hash], &this_entry->list);
	MC4_entry_free(this_entry);
}

#endif
 
int MC4_Get_Next_Hash_Entry(PMC4Command pMC4Cmd, int reset_action);
extern TIMER_ENTRY mc4_timer;

/**
 * MC4_timeout
 *
 *
 */
static void MC4_timeout(void)
{
	int i, j, k;
	PMC4Entry this_entry;
	BOOL entry_found = FALSE;
	struct slist_entry *entry;

	for(i=0;i<MC4_NUM_HASH_ENTRIES;i++)
	{
	  	slist_for_each_safe(this_entry, entry, &mc4_table_memory[i], list)
		{
			if ((this_entry->mcdest.flags & MC_ACP_LISTENER) && this_entry->mcdest.wifi_listener_timer > 0)
			{
				if ((this_entry->mcdest.wifi_listener_timer -= 10) <= 0)
					this_entry->mcdest.flags &= ~MC_ACP_LISTENER;
				else
					entry_found = TRUE;
			}
			for (j = 0; j < this_entry->mcdest.num_listeners; j++)
			{
				if (this_entry->mcdest.listeners[j].timer <= 0)
					continue;
				entry_found = TRUE;
				if ((this_entry->mcdest.listeners[j].timer -= 10) <= 0)
				{
					if(this_entry->mcdest.listeners[j].uc_bit)
						this_entry->mcdest.num_mc_uc_listeners--;
#ifdef CFG_WIFI_OFFLOAD
					else if(IS_WIFI_PORT(this_entry->mcdest.listeners[j].output_port))
						this_entry->mcdest.num_wifi_mc_listeners--;
#endif
					/* remove listener, and move following entries up */
					for (k = j + 1; k < this_entry->mcdest.num_listeners; k++)
					{
						this_entry->mcdest.listeners[k - 1] = this_entry->mcdest.listeners[k];
					}
					this_entry->mcdest.num_listeners--;
					j -= 1; // need index to remain in place after increment
				}
			}

			if (this_entry->mcdest.num_listeners == 0 && ((this_entry->mcdest.flags & MC_ACP_LISTENER) == 0))
				MC4_entry_remove(this_entry, i);
			else
				MC4_entry_update(this_entry);
	  	}
	}
	/* turn off timer handler if no MC entries */
	if (!entry_found)
		timer_del(&mc4_timer);
}


static int MC4_is_listener(PMC4Entry this_group, POnifDesc onif_desc, U8 * UC_Mac, U16 UC_Bit)
{
	int i;
	U16 onif_index = get_onif_index(onif_desc);

	/* check all listeners */
	for(i = 0; i <this_group->mcdest.num_listeners; i++)
	{
		if (this_group->mcdest.listeners[i].output_index == onif_index) 
		{
			if(UC_Bit){
 	                	if(TESTEQ_MACADDR(UC_Mac, this_group->mcdest.listeners[i].dstmac))
					return i;
                       	}
		  	else  if(this_group->mcdest.listeners[i].dstmac[0] & 0x01)
                               return i;
		}
	}
	/* unknown interface name */
	return -1;
}


/**
 * MC4_check_overlapping_pair
* searches forwarding table for overlapping pairs based on source, destination ipv4 addresses, output interface & mask
 */
static MC4Entry *MC4_check_overlapping_pair(PMC4Command cmd)
{
	PMC4Entry this_entry;
	struct slist_entry *entry;
	U32 hash_key;
	U32 mask_len;
	POnifDesc onif_desc = NULL;
	U32 output_index;
	int i,j;

	hash_key = HASH_MC4(cmd->dst_addr);
	slist_for_each(this_entry, entry, &mc4_table_memory[hash_key], list)
	{
	  	if (cmd->dst_addr == this_entry->dst_addr)
	    	{
	    		for (i = 0; i < cmd->num_output; i++)
	    		{
	    			onif_desc = get_onif_by_name(cmd->output_list[i].output_device_str);
	    			if (onif_desc)
	    			{
	    				output_index = get_onif_index(onif_desc);
	    				for (j = 0; j < this_entry->mcdest.num_listeners; j++)
	    				{
	    					/* Check overlapping pairs on the output indexes that are being programmed */
	    					if(output_index == this_entry->mcdest.listeners[j].output_index)
	    					{
	    						if((U32) cmd->src_addr_mask < this_entry->mcdest.src_mask_len)
	    							mask_len = (U32) cmd->src_addr_mask;
	    						else
	    							mask_len = this_entry->mcdest.src_mask_len;

	    						if (!(ntohl(cmd->src_addr ^  this_entry->src_addr)>>(32 - mask_len))) {
	    							return this_entry;
	    						}
	    					}
	    				}
	    			}
	    			else
	    			{
	    				if(this_entry->mcdest.flags & MC_ACP_LISTENER)
	    				{
						if((U32) cmd->src_addr_mask < this_entry->mcdest.src_mask_len)
							mask_len = (U32) cmd->src_addr_mask;
						else
							mask_len = this_entry->mcdest.src_mask_len;

	      					if (!(ntohl(cmd->src_addr ^  this_entry->src_addr)>>(32 - mask_len))) {
	      						return this_entry;
	      					}
	    				}
	    			}
	    		}
	    	}
	}

  	return NULL;
}


/**
 * MC4_command_add()
 *
 *
 */
static int MC4_command_add(PMC4Command cmd)
{
	PMC4Entry this_entry = NULL;
	struct slist_entry *entry;
	PMC4Entry tmpEntry;
	int i, rc = NO_ERR;
	U32 hash_key;
	POnifDesc onif_desc = NULL;
	PMC4Listener new_listener;
	U8 num_conf_mc_listeners = 0;


	/* some errors parsing on the command*/
	if(cmd->num_output > MC4_MAX_LISTENERS_PER_GROUP)
		return ERR_MC_MAX_LISTENERS;

	hash_key = HASH_MC4(cmd->dst_addr);

	/* check if group entry already exist in the table */
	slist_for_each(this_entry, entry, &mc4_table_memory[hash_key], list)
	{
		if ((cmd->src_addr == this_entry->src_addr) && (cmd->dst_addr == this_entry->dst_addr))
		{
			/* group already registered. just add listeners list the the corresponding entry */

			if((this_entry->mcdest.num_listeners + cmd->num_output) > MC4_MAX_LISTENERS_PER_GROUP)
				return ERR_MC_MAX_LISTENERS;

			for (i = 0; i < cmd->num_output; i++) {
				if(!cmd->output_list[i].uc_bit)
					num_conf_mc_listeners++;
			}

			/* If the number of MC Listeners per group is more than MCx_MAX_MC_LISTENERS_PER_GROUP, throw the error */
			if(this_entry->mcdest.num_listeners - this_entry->mcdest.num_mc_uc_listeners + num_conf_mc_listeners > MCx_MAX_MC_LISTENERS_PER_GROUP)
				return ERR_MC_MAX_LISTENERS;

			break;
		}
	}

	/* If group doesn't exist, create and initialize the entry */
	if(entry == NULL)
	{
		/* IF entry not already present look for overlapping pair.
  	       Place it here so that we allow addition of Listeners to group that already exists */
       	tmpEntry = MC4_check_overlapping_pair(cmd);
		if(tmpEntry != NULL)
			return ERR_MC_ENTRY_OVERLAP;
		
		if ((this_entry = MC4_entry_alloc()) == NULL)
		  	return  ERR_NOT_ENOUGH_MEMORY;

		memset(this_entry, 0, sizeof (MC4Entry));
		this_entry->src_addr =  cmd->src_addr;
		this_entry->mcdest.src_mask_len = cmd->src_addr_mask;
		this_entry->dst_addr =  cmd->dst_addr;
		this_entry->mcdest.flags = cmd->mode;
	  	this_entry->mcdest.queue_base = cmd->queue;

	}

	for (i = 0; i < cmd->num_output; i++)
	{
		/* We have the linux output interface name. Let's find corresponding output
		in the FPP world and pre-computed L2 headers that will be used within
		all the packets belonging to a same flow */
		onif_desc = get_onif_by_name(cmd->output_list[i].output_device_str);
		if (onif_desc)
		{
			if (!(onif_desc->itf->type & IF_TYPE_TUNNEL) && 
			(MC4_is_listener(this_entry, onif_desc, cmd->output_list[i].uc_mac,cmd->output_list[i].uc_bit) < 0))  // ignore if listener already exists or is a tunnel interface
			{
				new_listener = &this_entry->mcdest.listeners[this_entry->mcdest.num_listeners++];

				new_listener->timer = cmd->output_list[i].timer;
				new_listener->shaper_mask = cmd->output_list[i].shaper_mask;
				new_listener->output_index = get_onif_index(onif_desc);
				new_listener->output_port = itf_get_phys_port(onif_desc->itf);

#ifdef COMCERTO_100
				U8 dstmac[ETHER_ADDR_LEN];

				/* set destination MAC address
				     This is all in big-endian format, so be careful in shifting !!
				*/
				*(U16 *)dstmac = MC4_MAC_DEST_MARKER1;
				*(U16 *)(dstmac + 2) = MC4_MAC_DEST_MARKER2 | (this_entry->dst_addr & 0x00007F00);
				*(U16 *)(dstmac + 4) = ((this_entry->dst_addr & 0xFF000000) >> 16) | ((this_entry->dst_addr & 0x00FF0000) >>16);
				new_listener->L2_header_size = l2_precalculate_header(onif_desc->itf, new_listener->L2_header, ETH_HDR_SIZE + VLAN_HDR_SIZE, ETHERTYPE_IPV4_END, &new_listener->output_port, dstmac);
				L1_dc_clean(new_listener->L2_header,new_listener->L2_header+sizeof(new_listener->L2_header)-1);
#else

				if(cmd->output_list[i].uc_bit) { // copy unicast Mac as destination address
					new_listener->uc_bit = 1;
					COPY_MACADDR(new_listener->dstmac, cmd->output_list[i].uc_mac);
					this_entry->mcdest.num_mc_uc_listeners++;
				}
				else
				{
					new_listener->uc_bit = 0;
					*(U16 *)(new_listener->dstmac) = MC4_MAC_DEST_MARKER1;
					*(U16 *)(new_listener->dstmac + 2) = MC4_MAC_DEST_MARKER2 | (this_entry->dst_addr & 0x00007F00);
					*(U16 *)(new_listener->dstmac + 4) = ((this_entry->dst_addr & 0xFF000000) >> 16) | ((this_entry->dst_addr & 0x00FF0000) >>16);
#ifdef CFG_WIFI_OFFLOAD
					if(IS_WIFI_PORT(new_listener->output_port))
						this_entry->mcdest.num_wifi_mc_listeners++;	
#endif					
				}
				new_listener->q_bit = cmd->output_list[i].q_bit;
				new_listener->queue_base =  (new_listener->q_bit) ? cmd->output_list[i].queue: this_entry->mcdest.queue_base;
				new_listener->itf = onif_desc->itf;
				new_listener->family = PROTO_IPV4;
#endif
			}
		}
		else
		{
		       if(cmd->output_list[i].uc_bit)// Unicasting is unsupported when Wi-Fi is not offloaded.
                            return ERR_MC_INTERFACE_NOT_ALLOWED;
			/* default path is to ACP. Don't need to pre-compute L2 header */
			this_entry->mcdest.flags |= MC_ACP_LISTENER;
			this_entry->mcdest.wifi_listener_timer = cmd->output_list[i].timer;
		}

		if ((cmd->output_list[i].timer != 0xFFFFFFFF)  && (cmd->output_list[i].timer > 0))
			timer_add(&mc4_timer, TIMER_TICKS_PER_SEC * 10);

	}

	/* insert new entry in the multicast table */
	/* If group doesn't exist, add it to the table with the listeners list */
	if (entry == NULL)
		rc = MC4_entry_add(this_entry, hash_key);
	else
		MC4_entry_update(this_entry);

	return rc;
}


/**
 * MC4_command_remove()
 *
 *
 */
static int MC4_command_remove(PMC4Command cmd)
{
	PMC4Entry this_entry;
	struct slist_entry *entry;
	int i, j;
	U32 hash_key;
	int	listener_index;
	POnifDesc onif_desc;
	
	hash_key = HASH_MC4(cmd->dst_addr);
	slist_for_each(this_entry, entry, &mc4_table_memory[hash_key], list)
	{
		if ((this_entry->src_addr == cmd->src_addr) && (this_entry->dst_addr == cmd->dst_addr))
			goto found;
	}
	return ERR_MC_ENTRY_NOT_FOUND;

found:
	/* check all listeners to be removed */
	for(i = 0; i < cmd->num_output; i++)
	{
		onif_desc = get_onif_by_name(cmd->output_list[i].output_device_str);
		if(onif_desc)
		{
			if((listener_index = MC4_is_listener(this_entry, onif_desc, cmd->output_list[i].uc_mac,cmd->output_list[i].uc_bit) ) >= 0)
			{
				if(this_entry->mcdest.listeners[listener_index].uc_bit)
					this_entry->mcdest.num_mc_uc_listeners--;
#ifdef CFG_WIFI_OFFLOAD
				else if(IS_WIFI_PORT(this_entry->mcdest.listeners[listener_index].output_port))
					this_entry->mcdest.num_wifi_mc_listeners--;
#endif				
				/* remove listener, and move following entries up */
				for (j = listener_index + 1; j < this_entry->mcdest.num_listeners; j++)
				{
					this_entry->mcdest.listeners[j - 1] = this_entry->mcdest.listeners[j];
#if !defined(COMCERTO_2000_CONTROL)
					L1_dc_clean(&this_entry->mcdest.listeners[j - 1], ((U8*) &this_entry->mcdest.listeners[j])-1);
#endif
				}
				this_entry->mcdest.num_listeners--;
			}
		/* if listener does not belong to the group, just silently continue processing */
		}
		else
		{
			this_entry->mcdest.flags &= ~MC_ACP_LISTENER;
		}
	}
		
	/* no more listerners attached to the group - remove entry */
	if(this_entry->mcdest.num_listeners == 0 && ((this_entry->mcdest.flags & MC_ACP_LISTENER) == 0))
		MC4_entry_remove(this_entry, hash_key);
	else
		MC4_entry_update(this_entry);

	return NO_ERR;
}



// MC4_interface_purge -- remove any listeners referencing an output interface
void MC4_interface_purge(U32 if_index)
{
	int i, j, k;
	PMC4Entry this_entry;
	struct slist_entry *entry;

	for (i = 0; i < MC4_NUM_HASH_ENTRIES; i++)
	{
	  	slist_for_each_safe(this_entry, entry, &mc4_table_memory[i], list)
		{
			for (j = 0; j < this_entry->mcdest.num_listeners; j++)
			{
				if (if_index == this_entry->mcdest.listeners[j].output_index)
				{
					if(this_entry->mcdest.listeners[j].uc_bit)
						this_entry->mcdest.num_mc_uc_listeners--;
#ifdef CFG_WIFI_OFFLOAD
					else if(IS_WIFI_PORT(this_entry->mcdest.listeners[j].output_port))
						this_entry->mcdest.num_wifi_mc_listeners--;
#endif
					/* remove listener, and move following entries up */
					for (k = j + 1; k < this_entry->mcdest.num_listeners; k++)
					{
						this_entry->mcdest.listeners[k - 1] = this_entry->mcdest.listeners[k];
					}
					this_entry->mcdest.num_listeners--;
					j -= 1; // need index to remain in place after increment
				}
			}

			if (this_entry->mcdest.num_listeners == 0 && ((this_entry->mcdest.flags & MC_ACP_LISTENER) == 0))
				MC4_entry_remove(this_entry, i);
			else
				MC4_entry_update(this_entry);
	  	}
	}
}



/**
 * MC4_command_refresh()
 *
 *
 */
static int MC4_command_refresh(PMC4Command cmd)
{
	PMC4Entry this_entry;
	POnifDesc onif_desc, new_onif_desc;
	int listener_refreshed, listener_index;
	int group_qb_refreshed = 0;
	PMC4Listener update_listener;

	this_entry = MC4_rule_search(cmd->src_addr, cmd->dst_addr);
	if(this_entry != NULL)
	{
		this_entry->mcdest.queue_base = cmd->queue;
              for(group_qb_refreshed = 0; group_qb_refreshed < this_entry->mcdest.num_listeners; group_qb_refreshed++)
                      if(!this_entry->mcdest.listeners[group_qb_refreshed].q_bit)
                              this_entry->mcdest.listeners[group_qb_refreshed].queue_base = cmd->queue;
		/* now find listeners to refresh */
		for(listener_refreshed = 0; listener_refreshed < cmd->num_output; listener_refreshed++)
		{
			onif_desc = get_onif_by_name(cmd->output_list[listener_refreshed].output_device_str);
			if (onif_desc)
			{ 
				if ((listener_index = MC4_is_listener(this_entry, onif_desc, cmd->output_list[listener_refreshed].uc_mac, cmd->output_list[listener_refreshed].uc_bit)) >=0)
				{
					update_listener = &this_entry->mcdest.listeners[listener_index];

					if(cmd->output_list[listener_refreshed].if_bit)
					{
						if( (new_onif_desc = (get_onif_by_name(cmd->output_list[listener_refreshed].new_output_device_str))) != NULL)
						{
							if(MC4_is_listener(this_entry, new_onif_desc, cmd->output_list[listener_refreshed].uc_mac, cmd->output_list[listener_refreshed].uc_bit) < 0)
							{
								update_listener->output_index = get_onif_index(new_onif_desc);
								update_listener->output_port = itf_get_phys_port(new_onif_desc->itf);
#ifdef COMCERTO_100
								{
									U8 dstmac[ETHER_ADDR_LEN];

									/* set destination MAC address
			     						This is all in big-endian format, so be careful in shifting !!
									*/
									*(U16 *)dstmac = MC4_MAC_DEST_MARKER1;
									*(U16 *)(dstmac + 2) = MC4_MAC_DEST_MARKER2 | (this_entry->dst_addr & 0x00007F00);
									*(U16 *)(dstmac + 4) = ((this_entry->dst_addr & 0xFF000000) >> 16) | ((this_entry->dst_addr & 0x00FF0000) >>16);
									update_listener->L2_header_size = l2_precalculate_header(new_onif_desc->itf, update_listener->L2_header, ETH_HDR_SIZE + VLAN_HDR_SIZE, ETHERTYPE_IPV4_END, &update_listener->output_port, dstmac);
									L1_dc_clean(update_listener->L2_header,update_listener->L2_header+sizeof(update_listener->L2_header)-1);
								}
#else
               						if(cmd->output_list[listener_refreshed].uc_bit) { // copy unicast Mac as destination address
									update_listener->uc_bit = 1;
									COPY_MACADDR(update_listener->dstmac, cmd->output_list[listener_refreshed].uc_mac);
               						}
								else
								{
									update_listener->uc_bit = 0;
									*(U16 *)(update_listener->dstmac) = MC4_MAC_DEST_MARKER1;
									*(U16 *)(update_listener->dstmac + 2) = MC4_MAC_DEST_MARKER2 | (this_entry->dst_addr & 0x00007F00);
									*(U16 *)(update_listener->dstmac + 4) = ((this_entry->dst_addr & 0xFF000000) >> 16) | ((this_entry->dst_addr & 0x00FF0000) >>16);
								}
								update_listener->itf = new_onif_desc->itf;
#endif

							}
							else
								return ERR_MC_DUP_LISTENER;
						}
						else
							return ERR_UNKNOWN_INTERFACE;
					}

					update_listener->timer = cmd->output_list[listener_refreshed].timer;
					update_listener->shaper_mask = cmd->output_list[listener_refreshed].shaper_mask;
					if(cmd->output_list[listener_refreshed].q_bit)
                                        	update_listener->queue_base = cmd->output_list[listener_refreshed].queue;
				}	
			}
			else
			{
				this_entry->mcdest.wifi_listener_timer = cmd->output_list[listener_refreshed].timer;
			}
			if ( (cmd->output_list[listener_refreshed].timer != 0xFFFFFFFF) && (cmd->output_list[listener_refreshed].timer > 0))
				timer_add(&mc4_timer, TIMER_TICKS_PER_SEC * 10);
		}		

		MC4_entry_update(this_entry);
	}
	else
		return ERR_MC_ENTRY_NOT_FOUND;

	return NO_ERR;
}


/**
 * MC4_handle_MULTICAST
 *
 *
 */
int MC4_handle_MULTICAST(U16 *p, U16 Length)
{
	MC4Command 	cmd;
	U16 rc = NO_ERR;
	int reset_action = 0;
	
	/* Check length */
	if ((Length > sizeof(MC4Command)) || (Length < MC4_MIN_COMMAND_SIZE))
		return ERR_WRONG_COMMAND_SIZE;

	memset(&cmd, 0, sizeof(MC4Command));
	SFL_memcpy((U8*)&cmd, (U8*)p,  Length);
		
	switch(cmd.action)
	{
		case MC_ACTION_REMOVE: 
			rc =  MC4_command_remove(&cmd);
			break;
	
		case MC_ACTION_ADD:
			rc =  MC4_command_add(&cmd);
			break;

		case MC_ACTION_REFRESH:
			rc =  MC4_command_refresh(&cmd);
			break;
		case ACTION_QUERY:
			reset_action = 1;
		case ACTION_QUERY_CONT:
			rc = MC4_Get_Next_Hash_Entry((MC4Command*)p, reset_action);
			break;
		default :
			rc =  ERR_UNKNOWN_ACTION;
			break;
	} 

	return rc;

}


void MC4_Flush_Entries(void)
{
	PMC4Entry this_entry;
	struct slist_entry *entry;
	int i;
	
	for (i = 0; i < MC4_NUM_HASH_ENTRIES; i++)
	{
		slist_for_each_safe(this_entry, entry, &mc4_table_memory[i], list)
		{
			MC4_entry_remove(this_entry, i);
		}
	}
}

/**
 * MC4_handle_RESET
 *
 *
 */
int MC4_handle_RESET(void)
{
	MC4_Flush_Entries();

	return NO_ERR;
}

/**
 * M_mc4_cmdproc
 *
 *
 *
 */
U16 M_mc4_cmdproc(U16 cmd_code, U16 cmd_len, U16 *pcmd)
{
 /*
 	This code will never get invoked, this is because of having single EVENT_MC6 for control,
 	so the control functions are called from MC6.
 */
	return 0;
}

  
/**
 * M_mc4_init
 *
 *
 *
 */
BOOL mc4_init(void)
{
	int i;
#if defined(COMCERTO_2000)	
	struct pfe_ctrl *ctrl = &pfe->ctrl;
#endif	


	/* module entry point and channels registration */
#if defined(COMCERTO_1000)
	if (multicast_init())
		return 1;
#endif
#if !defined(COMCERTO_2000)
	set_event_handler(EVENT_MC4, M_mc4_entry);
#endif
	set_cmd_handler(EVENT_MC4, M_mc4_cmdproc);

	for (i = 0; i < MC4_NUM_HASH_ENTRIES; i++)
	{
		slist_head_init(&mc4_table_memory[i]);
	}

#if defined(COMCERTO_2000)
	mc4_dma_pool = ctrl->dma_pool_512;

	for (i = 0; i < MC4_NUM_HASH_ENTRIES; i++)
		dlist_head_init(&hw_mc4_active_list[i]);

	dlist_head_init(&hw_mc4_removal_list);

	timer_init(&mc4_delayed_remove_timer, hw_MC4_entry_delayed_remove);
	timer_add(&mc4_delayed_remove_timer, CT_TIMER_INTERVAL);
#endif

	timer_init(&mc4_timer, MC4_timeout);
	return 0;
}

void mc4_exit(void)
{
#if defined(COMCERTO_2000)
	struct dlist_head *entry;
	struct _thw_MC4Entry *hw_entry;

	timer_del(&mc4_timer);
	timer_del(&mc4_delayed_remove_timer);

	MC4_handle_RESET();

	dlist_for_each_safe(hw_entry, entry, &hw_mc4_removal_list, list)
	{
		dlist_remove(&hw_entry->list);
		dma_pool_free(mc4_dma_pool, hw_entry, be32_to_cpu(hw_entry->dma_addr));
	}
#endif
}
