/*
 *  Copyright (c) 2011 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_tx.h"
#include "module_hidrv.h"
#include "control_bridge.h"


char IF0_NAME[10] = TOSTR(DEFAULT_NAME_0);
char IF1_NAME[10] = TOSTR(DEFAULT_NAME_1);
char IF2_NAME[10] = TOSTR(DEFAULT_NAME_2);


static void M_tx_port_update(PPortUpdateCommand cmd)
{
	char *if_name = get_onif_name(phy_port[cmd->portid].itf.index);

	strncpy(if_name, cmd->ifname, INTERFACE_NAME_LENGTH);
	if_name[INTERFACE_NAME_LENGTH - 1] = '\0';
}

static U16 M_tx_cmdproc(U16 cmd_code, U16 cmd_len, U16 *pcmd)
{
	U32 portid;
	U16 rc;
	U16 retlen = 2;
	int id;

	portid = *pcmd;

	if (portid >= GEM_PORTS) {
		rc = CMD_ERR;
		goto out;
	}

	switch (cmd_code)
	{
	case CMD_TX_ENABLE:

//		M_tx_enable(portid);

		if (cmd_len > 2) {
			if (cmd_len > 14) {
				memcpy(phy_port[portid].mac_addr, &(((U8*)pcmd)[14]), 6);
				/* Set tx enable flag in Class */
				phy_port[portid].flags |= TX_ENABLED;

				for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
					pe_dmem_memcpy_to32(id, virt_to_class_dmem(&phy_port[portid].mac_addr), phy_port[portid].mac_addr, 6);
					/*Set tx enable flag in class and Util for this physical port*/
					pe_dmem_writeb(id, phy_port[portid].flags,
							virt_to_class_dmem(&phy_port[portid].flags));
				}
				/*Set tx enable flag in Util for this physical port*/
				pe_dmem_writeb(UTIL_ID, phy_port[portid].flags, virt_to_util_dmem(&util_phy_port[portid].flags));
			}
		}

//		M_expt_tx_enable(portid);

		rc = CMD_OK;
		break;

	case CMD_TX_DISABLE:

//		M_expt_tx_disable(portid);
//		M_tx_disable(portid);

		/*Reset tx enable flag in class and Util for this physical port*/
		phy_port[portid].flags &= ~TX_ENABLED;
		for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
			pe_dmem_writeb(id, phy_port[portid].flags, virt_to_class_dmem(&phy_port[portid].flags));

		pe_dmem_writeb(UTIL_ID, phy_port[portid].flags, virt_to_util_dmem(&util_phy_port[portid].flags));

		rc = CMD_OK;
		break;

	case CMD_PORT_UPDATE:

		/* Update the port info in the onif */
		M_tx_port_update((PPortUpdateCommand)pcmd);
		rc = CMD_OK;
		break;

	default:
		rc = CMD_ERR;
		break;
	}

out:
	*pcmd = rc;
	return retlen;
}


int tx_init(void)
{
	int i, id;

	set_cmd_handler(EVENT_PKT_TX, M_tx_cmdproc);

	add_onif((U8 *)IF0_NAME, &phy_port[0].itf, NULL, IF_TYPE_ETHERNET | IF_TYPE_PHYSICAL); /* FIXME check result */
	add_onif((U8 *)IF1_NAME, &phy_port[1].itf, NULL, IF_TYPE_ETHERNET | IF_TYPE_PHYSICAL); /* FIXME check result */
	add_onif((U8 *)IF2_NAME, &phy_port[2].itf, NULL, IF_TYPE_ETHERNET | IF_TYPE_PHYSICAL); /* FIXME check result */

	for (i = 0; i < GEM_PORTS; i++) {
		phy_port[i].id = i;

		for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
			pe_dmem_writeb(id, phy_port[i].itf.index, virt_to_class_dmem(&phy_port[i].itf.index));
	}

	/* Register interfaces with bridge */
	bridge_interface_register((U8 *) IF0_NAME, 0);
	bridge_interface_register((U8 *) IF1_NAME, 1);
	bridge_interface_register((U8 *) IF2_NAME, 2);

	return 0;
}

void tx_exit(void)
{
	int i;

	for (i = 0; i < GEM_PORTS; i++)
		remove_onif_by_index(phy_port[i].itf.index);
}
