/*
 *  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 "fpp.h"
#include "modules.h"
#include "channels.h"
#include "events.h"
#include "system.h"
#include "fpart.h"
#include "fe.h"
#include "icc.h"
#include "module_hidrv.h"

//#define ICC_DEBUG

#ifdef ICC_DEBUG
#define FUNCTION_ENTRY() do { printk(KERN_INFO "%s: function entered\n", __func__); } while (0)
#define DUMP_ICCTAB() dump_icctab()
#else
#define FUNCTION_ENTRY() do { } while (0)
#define DUMP_ICCTAB() do { } while (0)
#endif

#ifdef ICC_DEBUG
static void dump_icctab(void)
{
	int i;
	int x;
	char buf[256];
	char buf1[128], buf2[128];
	printk(KERN_INFO "ICCTAB:\n");
	printk(KERN_INFO "bmu1_thresh=%d, bmu2_thresh=%d\n", be32_to_cpu(icctab.bmu1_threshold), be32_to_cpu(icctab.bmu2_threshold));
	for (x = 0; x < GEM_PORTS; x++)
	{
		printk(KERN_INFO "**** Interface %d ****\n", x);
		buf[0] = '\0';
		for (i = 0; i < 256 / 8; i++)
			sprintf(buf + strlen(buf), "%02x", icctab.ipproto[x][i]);
		printk(KERN_INFO "ipproto: %s\n", buf);
		buf[0] = '\0';
		for (i = 0; i < 64 / 8; i++)
			sprintf(buf + strlen(buf), "%02x", icctab.dscp[x][i]);
		printk(KERN_INFO "dscp: %s\n", buf);
		buf[0] = '\0';
		for (i = 0; i < icctab.num_ethertype[x]; i++)
			sprintf(buf + strlen(buf), "%04x ", be16_to_cpu(icctab.ethertype[x][i]));
		printk(KERN_INFO "ethertype(%d) %s\n", icctab.num_ethertype[x], buf);
		buf[0] = '\0';
		for (i = 0; i < icctab.num_ipv4addr[x]; i++)
		{
			sprintf(buf1, "%x", be32_to_cpu(icctab.ipv4addr[x][i].addr));
			sprintf(buf2, "%d", icctab.ipv4addr[x][i].masklen);
			sprintf(buf + strlen(buf), "%s/%s/%d ", buf1, buf2, icctab.ipv4addr[x][i].src_dst_flag);
		}
		printk(KERN_INFO "ipv4(%d) %s\n", icctab.num_ipv4addr[x], buf);
		buf[0] = '\0';
		for (i = 0; i < icctab.num_ipv6addr[x]; i++)
		{
			int j;
			buf1[0] = buf2[0] = '\0';
			for (j = 0; j < 4; j++)
			{
				sprintf(buf1 + strlen(buf1), "%x", be32_to_cpu(icctab.ipv6addr[x][i].addr[j]));
				if (j < 3)
					strcat(buf1, ":");
			}
			sprintf(buf2, "%d", icctab.ipv6addr[x][i].masklen);
			sprintf(buf + strlen(buf), "%s/%s/%d ", buf1, buf2, icctab.ipv6addr[x][i].src_dst_flag);
		}
		printk(KERN_INFO "ipv6(%d) %s\n", icctab.num_ipv6addr[x], buf);
		buf[0] = '\0';
		for (i = 0; i < icctab.num_port[x]; i++)
			sprintf(buf + strlen(buf), "%d-%d/%d-%d ",
						be16_to_cpu(icctab.port[x][i].sport_from),
						be16_to_cpu(icctab.port[x][i].sport_to),
						be16_to_cpu(icctab.port[x][i].dport_from),
						be16_to_cpu(icctab.port[x][i].dport_to));
		printk(KERN_INFO "port(%d) %s\n", icctab.num_port[x], buf);
		buf[0] = '\0';
		for (i = 0; i < icctab.num_vlan[x]; i++)
			sprintf(buf + strlen(buf), "%d-%d/%d-%d ",
						be16_to_cpu(icctab.vlan[x][i].vlan_from),
						be16_to_cpu(icctab.vlan[x][i].vlan_to),
						be16_to_cpu(icctab.vlan[x][i].prio_from),
						be16_to_cpu(icctab.vlan[x][i].prio_to));
		printk(KERN_INFO "vlan(%d) %s\n", icctab.num_vlan[x], buf);
	}
}
#endif

static void icc_update_class_pe(void)
{
	struct pfe_ctrl *ctrl = &pfe->ctrl;
	int id;

	FUNCTION_ENTRY();
	DUMP_ICCTAB();

	if (pe_sync_stop(ctrl, CLASS_MASK) < 0)
	{
		printk(KERN_ERR "Error updating ICC tables\n");
		return;
	}

	/* update the DMEM in class-pe */
	for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
	{
		pe_dmem_memcpy_to32(id, virt_to_class_dmem(&icctab), &icctab, sizeof(icctab));
	}

	pe_start(ctrl, CLASS_MASK);
}

static void icc_reset(void)
{
	int i;

	FUNCTION_ENTRY();

	memset(&icctab, 0, sizeof(icctab));
	icctab.bmu1_threshold = cpu_to_be32(64);
	icctab.bmu2_threshold = cpu_to_be32(128);
	for (i = 0; i < GEM_PORTS; i++)
	{
		setbit_in_array(icctab.ipproto[i], IPPROTOCOL_ICMP, 1);
		setbit_in_array(icctab.ipproto[i], IPPROTOCOL_IGMP, 1);
		setbit_in_array(icctab.ipproto[i], IPPROTOCOL_ICMPV6, 1);
	}
	icc_update_class_pe();
}

static U16 icc_threshold(icc_threshold_cmd_t *pcmd)
{
	FUNCTION_ENTRY();

	if (pcmd->bmu1_threshold > MAX_BMU1_THRESHOLD || pcmd->bmu2_threshold > MAX_BMU2_THRESHOLD)
		return ERR_ICC_THRESHOLD_OUT_OF_RANGE;
	icctab.bmu1_threshold = cpu_to_be32(pcmd->bmu1_threshold);
	icctab.bmu2_threshold = cpu_to_be32(pcmd->bmu2_threshold);
	icc_update_class_pe();
	return NO_ERR;
}

static U16 icc_add(icc_add_delete_cmd_t *pcmd)
{
	int i, n;
	U32 interface;
	U16 rtncode;

	FUNCTION_ENTRY();

	interface = pcmd->interface;
	if (interface >= GEM_PORTS)
		return ERR_UNKNOWN_INTERFACE;
	switch (pcmd->table_type)
	{
		case ICC_TABLETYPE_ETHERTYPE:
		{
			U16 ethertype;
			n = icctab.num_ethertype[interface];
			if (n == MAX_ICC_ETHERTYPE)
				return ERR_ICC_TOO_MANY_ENTRIES;
			ethertype = cpu_to_be16(pcmd->ethertype.type);
			for (i = 0; i < n; i++)
			{
				if (icctab.ethertype[interface][i] == ethertype)
					return ERR_ICC_ENTRY_ALREADY_EXISTS;
			}
			icctab.ethertype[interface][n] = ethertype;
			icctab.num_ethertype[interface]++;
			break;
		}
		case ICC_TABLETYPE_PROTOCOL:
		{
			for (i = 0; i < 256 / 8; i++)
				icctab.ipproto[interface][i] |= pcmd->protocol.ipproto[i];
			break;
		}
		case ICC_TABLETYPE_DSCP:
		{
			for (i = 0; i < 64 / 8; i++)
				icctab.dscp[interface][i] |= pcmd->dscp.dscp_value[i];
			break;
		}
		case ICC_TABLETYPE_SADDR:
		case ICC_TABLETYPE_DADDR:
		{
			U8 src_dst_flag;
			U32 addr;
			U8 masklen;
			n = icctab.num_ipv4addr[interface];
			if (n == MAX_ICC_IPV4ADDR)
				return ERR_ICC_TOO_MANY_ENTRIES;
			src_dst_flag = pcmd->table_type == ICC_TABLETYPE_SADDR ? 0 : 1;
			addr = pcmd->ipaddr.v4_addr;
			masklen = pcmd->ipaddr.v4_masklen;
			if (masklen == 0 || masklen > 32)
				return ERR_ICC_INVALID_MASKLEN;
			for (i = 0; i < n; i++)
			{
				if (icctab.ipv4addr[interface][i].src_dst_flag == src_dst_flag &&
						icctab.ipv4addr[interface][i].addr == addr &&
						icctab.ipv4addr[interface][i].masklen == masklen)
					return ERR_ICC_ENTRY_ALREADY_EXISTS;
			}
			icctab.ipv4addr[interface][n].src_dst_flag = src_dst_flag;
			icctab.ipv4addr[interface][n].addr = addr;
			icctab.ipv4addr[interface][n].masklen = masklen;
			icctab.num_ipv4addr[interface]++;
			break;
		}
		case ICC_TABLETYPE_SADDR6:
		case ICC_TABLETYPE_DADDR6:
		{
			U8 src_dst_flag;
			U32 *addr;
			U8 masklen;
			n = icctab.num_ipv6addr[interface];
			if (n == MAX_ICC_IPV6ADDR)
				return ERR_ICC_TOO_MANY_ENTRIES;
			src_dst_flag = pcmd->table_type == ICC_TABLETYPE_SADDR6 ? 0 : 1;
			addr = pcmd->ipv6addr.v6_addr;
			masklen = pcmd->ipv6addr.v6_masklen;
			if (masklen == 0 || masklen > 128)
				return ERR_ICC_INVALID_MASKLEN;
			for (i = 0; i < n; i++)
			{
				if (icctab.ipv6addr[interface][i].src_dst_flag == src_dst_flag &&
						icctab.ipv6addr[interface][i].addr[0] == addr[0] &&
						icctab.ipv6addr[interface][i].addr[1] == addr[1] &&
						icctab.ipv6addr[interface][i].addr[2] == addr[2] &&
						icctab.ipv6addr[interface][i].addr[3] == addr[3] &&
						icctab.ipv6addr[interface][i].masklen == masklen)
					return ERR_ICC_ENTRY_ALREADY_EXISTS;
			}
			icctab.ipv6addr[interface][n].src_dst_flag = src_dst_flag;
			icctab.ipv6addr[interface][n].addr[0] = addr[0];
			icctab.ipv6addr[interface][n].addr[1] = addr[1];
			icctab.ipv6addr[interface][n].addr[2] = addr[2];
			icctab.ipv6addr[interface][n].addr[3] = addr[3];
			icctab.ipv6addr[interface][n].masklen = masklen;
			icctab.num_ipv6addr[interface]++;
			break;
		}
		case ICC_TABLETYPE_PORT:
		{
			U16 sport_from, sport_to, dport_from, dport_to;
			n = icctab.num_port[interface];
			if (n == MAX_ICC_PORT)
				return ERR_ICC_TOO_MANY_ENTRIES;
			sport_from = cpu_to_be16(pcmd->port.sport_from);
			sport_to = cpu_to_be16(pcmd->port.sport_to);
			dport_from = cpu_to_be16(pcmd->port.dport_from);
			dport_to = cpu_to_be16(pcmd->port.dport_to);
			for (i = 0; i < n; i++)
			{
				if (icctab.port[interface][i].sport_from == sport_from &&
						icctab.port[interface][i].sport_to == sport_to &&
						icctab.port[interface][i].dport_from == dport_from &&
						icctab.port[interface][i].dport_to == dport_to)
					return ERR_ICC_ENTRY_ALREADY_EXISTS;
			}
			icctab.port[interface][n].sport_from = sport_from;
			icctab.port[interface][n].sport_to = sport_to;
			icctab.port[interface][n].dport_from = dport_from;
			icctab.port[interface][n].dport_to = dport_to;
			icctab.num_port[interface]++;
			break;
		}
		case ICC_TABLETYPE_VLAN:
		{
			U16 vlan_from, vlan_to, prio_from, prio_to;
			n = icctab.num_vlan[interface];
			if (n == MAX_ICC_VLAN)
				return ERR_ICC_TOO_MANY_ENTRIES;
			vlan_from = cpu_to_be16(pcmd->vlan.vlan_from);
			vlan_to = cpu_to_be16(pcmd->vlan.vlan_to);
			prio_from = cpu_to_be16(pcmd->vlan.prio_from);
			prio_to = cpu_to_be16(pcmd->vlan.prio_to);
			for (i = 0; i < n; i++)
			{
				if (icctab.vlan[interface][i].vlan_from == vlan_from &&
						icctab.vlan[interface][i].vlan_to == vlan_to &&
						icctab.vlan[interface][i].prio_from == prio_from &&
						icctab.vlan[interface][i].prio_to == prio_to)
					return ERR_ICC_ENTRY_ALREADY_EXISTS;
			}
			icctab.vlan[interface][n].vlan_from = vlan_from;
			icctab.vlan[interface][n].vlan_to = vlan_to;
			icctab.vlan[interface][n].prio_from = prio_from;
			icctab.vlan[interface][n].prio_to = prio_to;
			icctab.num_vlan[interface]++;
			break;
		}
	}
	icc_update_class_pe();
	rtncode = NO_ERR;
	return rtncode;
}

static U16 icc_delete(icc_add_delete_cmd_t *pcmd)
{
	int i, n;
	U32 interface;
	U16 rtncode;

	FUNCTION_ENTRY();

	interface = pcmd->interface;
	if (interface >= GEM_PORTS)
		return ERR_UNKNOWN_INTERFACE;
	switch (pcmd->table_type)
	{
		case ICC_TABLETYPE_ETHERTYPE:
		{
			U16 ethertype;
			n = icctab.num_ethertype[interface];
			ethertype = cpu_to_be16(pcmd->ethertype.type);
			for (i = 0; i < n; i++)
			{
				if (icctab.ethertype[interface][i] == ethertype)
					break;
			}
			if (i == n)
				return ERR_ICC_ENTRY_NOT_FOUND;
			for (i++; i < n; i++)
			{
				icctab.ethertype[interface][i - 1] = icctab.ethertype[interface][i];
			}
			icctab.num_ethertype[interface]--;
			break;
		}
		case ICC_TABLETYPE_PROTOCOL:
		{
			for (i = 0; i < 256 / 8; i++)
				icctab.ipproto[interface][i] &= ~pcmd->protocol.ipproto[i];
			break;
		}
		case ICC_TABLETYPE_DSCP:
		{
			for (i = 0; i < 64 / 8; i++)
				icctab.dscp[interface][i] &= ~pcmd->dscp.dscp_value[i];
			break;
		}
		case ICC_TABLETYPE_SADDR:
		case ICC_TABLETYPE_DADDR:
		{
			U8 src_dst_flag;
			U32 addr;
			U8 masklen;
			n = icctab.num_ipv4addr[interface];
			src_dst_flag = pcmd->table_type == ICC_TABLETYPE_SADDR ? 0 : 1;
			addr = pcmd->ipaddr.v4_addr;
			masklen = pcmd->ipaddr.v4_masklen;
			for (i = 0; i < n; i++)
			{
				if (icctab.ipv4addr[interface][i].src_dst_flag == src_dst_flag &&
						icctab.ipv4addr[interface][i].addr == addr &&
						icctab.ipv4addr[interface][i].masklen == masklen)
					break;
			}
			if (i == n)
				return ERR_ICC_ENTRY_NOT_FOUND;
			for (i++; i < n; i++)
			{
				icctab.ipv4addr[interface][i - 1] = icctab.ipv4addr[interface][i];
			}
			icctab.num_ipv4addr[interface]--;
			break;
		}
		case ICC_TABLETYPE_SADDR6:
		case ICC_TABLETYPE_DADDR6:
		{
			U8 src_dst_flag;
			U32 *addr;
			U8 masklen;
			n = icctab.num_ipv6addr[interface];
			src_dst_flag = pcmd->table_type == ICC_TABLETYPE_SADDR6 ? 0 : 1;
			addr = pcmd->ipv6addr.v6_addr;
			masklen = pcmd->ipv6addr.v6_masklen;
			for (i = 0; i < n; i++)
			{
				if (icctab.ipv6addr[interface][i].src_dst_flag == src_dst_flag &&
						icctab.ipv6addr[interface][i].addr[0] == addr[0] &&
						icctab.ipv6addr[interface][i].addr[1] == addr[1] &&
						icctab.ipv6addr[interface][i].addr[2] == addr[2] &&
						icctab.ipv6addr[interface][i].addr[3] == addr[3] &&
						icctab.ipv6addr[interface][i].masklen == masklen)
					break;
			}
			if (i == n)
				return ERR_ICC_ENTRY_NOT_FOUND;
			for (i++; i < n; i++)
			{
				icctab.ipv6addr[interface][i - 1] = icctab.ipv6addr[interface][i];
			}
			icctab.num_ipv6addr[interface]--;
			break;
		}
		case ICC_TABLETYPE_PORT:
		{
			U16 sport_from, sport_to, dport_from, dport_to;
			n = icctab.num_port[interface];
			sport_from = cpu_to_be16(pcmd->port.sport_from);
			sport_to = cpu_to_be16(pcmd->port.sport_to);
			dport_from = cpu_to_be16(pcmd->port.dport_from);
			dport_to = cpu_to_be16(pcmd->port.dport_to);
			for (i = 0; i < n; i++)
			{
				if (icctab.port[interface][i].sport_from == sport_from &&
						icctab.port[interface][i].sport_to == sport_to &&
						icctab.port[interface][i].dport_from == dport_from &&
						icctab.port[interface][i].dport_to == dport_to)
					break;
			}
			if (i == n)
				return ERR_ICC_ENTRY_NOT_FOUND;
			for (i++; i < n; i++)
			{
				icctab.port[interface][i - 1] = icctab.port[interface][i];
			}
			icctab.num_port[interface]--;
			break;
		}
		case ICC_TABLETYPE_VLAN:
		{
			U16 vlan_from, vlan_to, prio_from, prio_to;
			n = icctab.num_vlan[interface];
			vlan_from = cpu_to_be16(pcmd->vlan.vlan_from);
			vlan_to = cpu_to_be16(pcmd->vlan.vlan_to);
			prio_from = cpu_to_be16(pcmd->vlan.prio_from);
			prio_to = cpu_to_be16(pcmd->vlan.prio_to);
			for (i = 0; i < n; i++)
			{
				if (icctab.vlan[interface][i].vlan_from == vlan_from &&
						icctab.vlan[interface][i].vlan_to == vlan_to &&
						icctab.vlan[interface][i].prio_from == prio_from &&
						icctab.vlan[interface][i].prio_to == prio_to)
					break;
			}
			if (i == n)
				return ERR_ICC_ENTRY_NOT_FOUND;
			for (i++; i < n; i++)
			{
				icctab.vlan[interface][i - 1] = icctab.vlan[interface][i];
			}
			icctab.num_vlan[interface]--;
			break;
		}
	}
	icc_update_class_pe();
	rtncode = NO_ERR;
	return rtncode;
}

static U16 icc_query(icc_query_cmd_t *pcmd)
{
	int i;
	U16 action;
	U32 interface;
	U16 query_result = 0;
	icc_query_reply_t *prsp;
	U8 flag;
	static U8 table_type = 0xFF, table_index;

	FUNCTION_ENTRY();

	action = pcmd->action;
	interface = pcmd->interface;
	if (interface >= GEM_PORTS)
		return ERR_UNKNOWN_INTERFACE;

	prsp = (icc_query_reply_t *)pcmd;
	memset(prsp, 0, sizeof(icc_query_reply_t));
	prsp->interface = interface;
	if (action == 0 || table_type == 0xFF)
	{
		table_type = 0;
		table_index = 0;
	}
	while (1)
	{
		if (table_type >= ICC_MAX_TABLETYPE)
		{
			query_result = 1;
			table_type = 0xFF;
			goto done;
		}
		prsp->table_type = table_type;
		switch(table_type)
		{
			case ICC_TABLETYPE_ETHERTYPE:
			{
				if (table_index < icctab.num_ethertype[interface])
				{
					prsp->ethertype.type = be16_to_cpu(icctab.ethertype[interface][table_index]);
					goto done;
				}
				break;
			}
			case ICC_TABLETYPE_PROTOCOL:
			{
				if (table_index == 0)
				{
					flag = 0;
					for (i = 0; i < 256 / 8; i++)
					{
						prsp->protocol.ipproto[i] = icctab.ipproto[interface][i];
						flag |= prsp->protocol.ipproto[i];
					}
					if (flag)
						goto done;
				}
				break;
			}
			case ICC_TABLETYPE_DSCP:
			{
				if (table_index == 0)
				{
					flag = 0;
					for (i = 0; i < 64 / 8; i++)
					{
						prsp->dscp.dscp_value[i] = icctab.dscp[interface][i];
						flag |= prsp->dscp.dscp_value[i];
					}
					if (flag)
						goto done;
				}
				break;
			}
			case ICC_TABLETYPE_SADDR:
			{
				while (table_index < icctab.num_ipv4addr[interface])
				{
					if (icctab.ipv4addr[interface][table_index].src_dst_flag == 0)
					{
						prsp->ipaddr.v4_addr = icctab.ipv4addr[interface][table_index].addr;
						prsp->ipaddr.v4_masklen = icctab.ipv4addr[interface][table_index].masklen;
						goto done;
					}
					table_index++;
				}
				break;
			}
			case ICC_TABLETYPE_DADDR:
			{
				while (table_index < icctab.num_ipv4addr[interface])
				{
					if (icctab.ipv4addr[interface][table_index].src_dst_flag != 0)
					{
						prsp->ipaddr.v4_addr = icctab.ipv4addr[interface][table_index].addr;
						prsp->ipaddr.v4_masklen = icctab.ipv4addr[interface][table_index].masklen;
						goto done;
					}
					table_index++;
				}
				break;
			}
			case ICC_TABLETYPE_SADDR6:
			{
				while (table_index < icctab.num_ipv6addr[interface])
				{
					if (icctab.ipv6addr[interface][table_index].src_dst_flag == 0)
					{
						prsp->ipv6addr.v6_addr[0] = icctab.ipv6addr[interface][table_index].addr[0];
						prsp->ipv6addr.v6_addr[1] = icctab.ipv6addr[interface][table_index].addr[1];
						prsp->ipv6addr.v6_addr[2] = icctab.ipv6addr[interface][table_index].addr[2];
						prsp->ipv6addr.v6_addr[3] = icctab.ipv6addr[interface][table_index].addr[3];
						prsp->ipv6addr.v6_masklen = icctab.ipv6addr[interface][table_index].masklen;
						goto done;
					}
					table_index++;
				}
				break;
			}
			case ICC_TABLETYPE_DADDR6:
			{
				while (table_index < icctab.num_ipv6addr[interface])
				{
					if (icctab.ipv6addr[interface][table_index].src_dst_flag != 0)
					{
						prsp->ipv6addr.v6_addr[0] = icctab.ipv6addr[interface][table_index].addr[0];
						prsp->ipv6addr.v6_addr[1] = icctab.ipv6addr[interface][table_index].addr[1];
						prsp->ipv6addr.v6_addr[2] = icctab.ipv6addr[interface][table_index].addr[2];
						prsp->ipv6addr.v6_addr[3] = icctab.ipv6addr[interface][table_index].addr[3];
						prsp->ipv6addr.v6_masklen = icctab.ipv6addr[interface][table_index].masklen;
						goto done;
					}
					table_index++;
				}
				break;
			}
			case ICC_TABLETYPE_PORT:
			{
				if (table_index < icctab.num_port[interface])
				{
					prsp->port.sport_from = be16_to_cpu(icctab.port[interface][table_index].sport_from);
					prsp->port.sport_to = be16_to_cpu(icctab.port[interface][table_index].sport_to);
					prsp->port.dport_from = be16_to_cpu(icctab.port[interface][table_index].dport_from);
					prsp->port.dport_to = be16_to_cpu(icctab.port[interface][table_index].dport_to);
					goto done;
				}
				break;
			}
			case ICC_TABLETYPE_VLAN:
			{
				if (table_index < icctab.num_vlan[interface])
				{
					prsp->vlan.vlan_from = be16_to_cpu(icctab.vlan[interface][table_index].vlan_from);
					prsp->vlan.vlan_to = be16_to_cpu(icctab.vlan[interface][table_index].vlan_to);
					prsp->vlan.prio_from = be16_to_cpu(icctab.vlan[interface][table_index].prio_from);
					prsp->vlan.prio_to = be16_to_cpu(icctab.vlan[interface][table_index].prio_to);
					goto done;
				}
				break;
			}
		}
		table_type++;
		table_index = 0;
	}

done:
	table_index++;
	prsp->query_result = query_result;
	return NO_ERR;
}

static U16 M_icc_cmdproc(U16 cmd_code, U16 cmd_len, U16 *p)
{
	U16 rtncode;
	U16 retlen = 2;

	FUNCTION_ENTRY();

	rtncode = NO_ERR;
	switch (cmd_code)
	{
		case CMD_ICC_RESET:
		{
			icc_reset();
			break;
		}

		case CMD_ICC_THRESHOLD:
		{
			icc_threshold_cmd_t *pcmd = (icc_threshold_cmd_t *)p;
			rtncode = icc_threshold(pcmd);
			break;
		}

		case CMD_ICC_ADD_DELETE:
		{
			icc_add_delete_cmd_t *pcmd = (icc_add_delete_cmd_t *)p;
			if (pcmd->action == ICC_ACTION_ADD)
			{
				rtncode = icc_add(pcmd);
			}
			else if (pcmd->action == ICC_ACTION_DELETE)
			{
				rtncode = icc_delete(pcmd);
			}
			else
			{
				rtncode = ERR_UNKNOWN_ACTION;
			}
			break;
		}

		case CMD_ICC_QUERY:
		{
			icc_query_cmd_t *pcmd = (icc_query_cmd_t *)p;
			rtncode = icc_query(pcmd);
			retlen = sizeof(icc_query_reply_t);
			break;
		}

		// unknown command code
		default:
		{
			rtncode = ERR_UNKNOWN_COMMAND;
			break;
		}
	}

	*p = rtncode;
	return retlen;
}

/** ICC init function.
 * This function initializes the ICC control context with default configuration
 * and sends the same configuration to each class PE.
 *
 */
int icc_control_init(void)
{
	int rtn_code = NO_ERR;

	FUNCTION_ENTRY();

	set_cmd_handler(EVENT_ICC, M_icc_cmdproc);

	icc_reset();

	return rtn_code;
}

/** ICC exit function.
*/
void icc_control_exit(void)
{

	FUNCTION_ENTRY();

}

