blob: eea5b060b091141c350914280737647a0bc492f2 [file] [log] [blame]
/*
* 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;
}