/*
 *  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_expt.h"
#include "events.h"
#include "module_Rx.h"
#include "fpp.h"
#include "module_ethernet.h"
#include "module_vlan.h"
#include "layer2.h"
#include "module_pppoe.h"
#include "module_hidrv.h"
#include "module_ipv4.h"
#include "module_ipv6.h"
#include "module_ipsec.h"
#include "module_qm.h"
#include "module_wifi.h"

static int M_expt_update_classpe(u8 ctl_flag)
{
	struct pfe_ctrl *ctrl = &pfe->ctrl;
	int id;

	if (pe_sync_stop(ctrl, CLASS_MASK) < 0)
		return CMD_ERR;
	/* update the DMEM in class-pe */
	for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
	{
		if (ctl_flag & EXPT_CTRLQ_CONFIG)
			pe_dmem_writeb(id,  CTRL_to_Q, virt_to_class_dmem(&CTRL_to_Q));
		if (ctl_flag & EXPT_DSCP_CONFIG)
			pe_dmem_memcpy_to32(id, virt_to_class_dmem(DSCP_to_Q), DSCP_to_Q, sizeof (DSCP_to_Q));
	}

	pe_start(ctrl, CLASS_MASK);

	return NO_ERR;
}


int M_expt_queue_reset(void)
{
	int i;

	CTRL_to_Q = EXPT_MAX_QUEUE;  /* control protocol packets assigned to highest priority queue */
	DSCP_to_Q[0] = EXPT_Q0; /* dscp == 0 assigned to lowest priority queue */
	for(i = 1; i <= DSCP_MAX_VALUE; i++)
		DSCP_to_Q[i] = EXPT_MAX_QUEUE; /* dscp > 0 assigned to highest priority queue */
	return M_expt_update_classpe(EXPT_CTRLQ_CONFIG | EXPT_DSCP_CONFIG);
}


static int EXPT_Handle_ExptQueue_DSCP(U16 *p, U16 Length)
{
	ExptQueueDSCPCommand 	cmd;
	int i;

	if (Length > sizeof(ExptQueueDSCPCommand))
		return ERR_WRONG_COMMAND_SIZE;

	SFL_memcpy((U8*)&cmd, (U8*)p,  sizeof(ExptQueueDSCPCommand));

	if(cmd.queue > EXPT_MAX_QUEUE)
		return ERR_EXPT_QUEUE_OUT_OF_RANGE;

	if(cmd.num_dscp > (DSCP_MAX_VALUE + 1))
		return ERR_EXPT_NUM_DSCP_OUT_OF_RANGE;

	for(i = 0; i < cmd.num_dscp; i++)
		if(cmd.dscp[i] > DSCP_MAX_VALUE) 
			return ERR_EXPT_DSCP_OUT_OF_RANGE;

	//the whole command is correct, we can assign dspc to queues
	for(i = 0; i < cmd.num_dscp; i++)
		DSCP_to_Q[cmd.dscp[i]] = cmd.queue;

	return M_expt_update_classpe(EXPT_DSCP_CONFIG);
}

static int EXPT_Handle_ExptQueue_CTRL(U16 *p, U16 Length)
{
	ExptQueueCTRLCommand 	cmd;

	if (Length > sizeof(ExptQueueCTRLCommand))
		return ERR_WRONG_COMMAND_SIZE;

	SFL_memcpy((U8*)&cmd, (U8*)p,  sizeof(ExptQueueCTRLCommand));

	//the whole command is correct, we can assign control protocol packets  to the specified queue
	CTRL_to_Q = cmd.queue;
	return M_expt_update_classpe(EXPT_CTRLQ_CONFIG);

}


static int EXPT_Handle_ExptQueue_RESET(U16 *p, U16 Length)
{
	return M_expt_queue_reset();

}

U16 M_expt_cmdproc(U16 cmd_code, U16 cmd_len, U16 *pcmd)
{
	U16 rtncode;

	switch (cmd_code)
	{
		case CMD_EXPT_QUEUE_DSCP:
			{
				rtncode = EXPT_Handle_ExptQueue_DSCP(pcmd, cmd_len);
				break;
			}

		case CMD_EXPT_QUEUE_CTRL:	
			{
				rtncode = EXPT_Handle_ExptQueue_CTRL(pcmd, cmd_len);
				break;
			}

		case CMD_EXPT_QUEUE_RESET:
			{
				rtncode = EXPT_Handle_ExptQueue_RESET(pcmd, cmd_len);
				break;
			}

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

	*pcmd = rtncode;
	return 2;
}

