/*
 *  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_wifi.h"
#include "fpp_globals.h"
#include "events.h"
#include "module_Rx.h"
#include "module_tx.h"

#include "gemac.h"
#include "xdma.h"
#include "fpool.h"
#include "fpp.h"
#include "module_ethernet.h"
#include "module_hidrv.h"
#include "module_timer.h"
#include "module_expt.h"
#include "module_pppoe.h"
#include "module_stat.h"
#include "fe.h"
#include "channels.h"
//#include "scc.h"
#include "module_ipv4.h"
#include "module_bridge.h"
#include "control_bridge.h"

#ifdef CFG_WIFI_OFFLOAD

struct 	tWifiIfDesc wifiDesc[MAX_WIFI_VAPS];

struct tRX_wifi_context gWifiRxCtx;

#if defined(COMCERTO_2000_CONTROL) || defined(COMCERTO_1000)

static int wifi_vap_entry( U16 *ptr, U16 len )
{
	struct wifiCmd cmd;
	struct tRX_wifi_context *rxc;
	int id;
	int portid;
	struct physical_port	*port;

	rxc = &gWifiRxCtx;
	printk("%s:%d\n", __func__, __LINE__);

	if (len != sizeof(struct wifiCmd))
		return ERR_WRONG_COMMAND_SIZE;

	SFL_memcpy( &cmd, ptr, sizeof(struct wifiCmd));

	if( cmd.VAPID >= MAX_WIFI_VAPS )
		return ERR_UNKNOWN_ACTION;

	portid = PORT_WIFI_IDX + cmd.VAPID;
	port = phy_port_get(portid);

	switch (cmd.action)
	{
		case WIFI_REMOVE_VAP:
			printk("%s:%d Remove entry\n", __func__, __LINE__);
			if( wifiDesc[cmd.VAPID].VAPID == 0XFFFF )
				return ERR_WLAN_DUPLICATE_OPERATION;
			printk("%s: PHYID:%d vapid:%d\n", __func__, portid, cmd.VAPID);

			wifiDesc[cmd.VAPID].VAPID = 0xFFFF;

			bridge_interface_deregister(portid);

			remove_onif_by_index(port->itf.index);

			if ( rxc->users  )
				rxc->users--;

			break;

		case WIFI_ADD_VAP:
			if ( rxc->users >= MAX_WIFI_VAPS )
				return CMD_ERR;

			printk("%s:%d ADD entry\n", __func__, __LINE__);
			if( wifiDesc[cmd.VAPID].VAPID != 0XFFFF )
				return ERR_WLAN_DUPLICATE_OPERATION;

			if(!add_onif(cmd.ifname, &port->itf, NULL, IF_TYPE_WLAN | IF_TYPE_PHYSICAL))
			{
				return CMD_ERR;
			}

			wifiDesc[cmd.VAPID].VAPID = cmd.VAPID;
			bridge_interface_register(cmd.ifname, portid);

			SFL_memcpy(port->mac_addr, cmd.mac_addr, 6);
#if defined(COMCERTO_2000_CONTROL)
			printk("%s: PHYID:%d vapid:%d mac_addr: %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, portid, cmd.VAPID,
									port->mac_addr[0],
									port->mac_addr[1],
									port->mac_addr[2],
									port->mac_addr[3],
									port->mac_addr[4],
									port->mac_addr[5]);
			if( portid < MAX_PHY_PORTS_FAST) {
				for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
					pe_dmem_memcpy_to32(id, virt_to_class_dmem(&port->mac_addr),
							port->mac_addr, 6);
					pe_dmem_writeb(id, port->itf.index, virt_to_class_dmem(&port->itf.index));
				}
			} else {
				class_pe_lmem_memcpy_to32(virt_to_class_pe_lmem(&port->mac_addr),
						&port->mac_addr[0], 6);
				class_bus_writeb(port->itf.index, virt_to_class_pe_lmem(&port->itf.index));
			}
#endif

			if ( rxc->users < MAX_WIFI_VAPS )
				rxc->users++;

			break;

		case WIFI_UPDATE_VAP:
			printk("%s:%d Update Entry\n", __func__, __LINE__);
			if( wifiDesc[cmd.VAPID].VAPID == 0XFFFF )
				return CMD_ERR;

			SFL_memcpy(port->mac_addr, cmd.mac_addr, 6);
#if defined(COMCERTO_2000_CONTROL)
			printk("%s: PHYID:%d vapid:%d mac_addr: %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, portid, cmd.VAPID,
									port->mac_addr[0],
									port->mac_addr[1],
									port->mac_addr[2],
									port->mac_addr[3],
									port->mac_addr[4],
									port->mac_addr[5]);
			if( portid < MAX_PHY_PORTS_FAST) {
				for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
					pe_dmem_memcpy_to32(id, virt_to_class_dmem(&port->mac_addr),
							port->mac_addr, 6);
			} else {
				class_pe_lmem_memcpy_to32(virt_to_class_pe_lmem(&port->mac_addr),
						&port->mac_addr[0], 6);
			}
#endif
			break;

		default:
			return ERR_UNKNOWN_ACTION;


	}

	return NO_ERR;


}


static U16 M_wifi_rx_cmdproc(U16 cmd_code, U16 cmd_len, U16 *pcmd)
{
	U16 acklen;
	U16 ackstatus;
	U16 i;
	struct tRX_wifi_context *rxc;
	struct physical_port	*port;

	rxc = &gWifiRxCtx;

	acklen = 2;
	ackstatus = CMD_OK;
	printk("%s:%d\n", __func__, __LINE__);

	switch (cmd_code)
	{
		case CMD_WIFI_VAP_ENTRY:
			ackstatus = wifi_vap_entry(pcmd, cmd_len);
			break;

#if defined(COMCERTO_1000)
		case CMD_CFG_WIFI_OFFLOAD:
			if( !rxc->enabled )
			{
				M_expt_rx_enable(PORT_WIFI_IDX);
				M_wifi_rx_enable();
			}
			else
				ackstatus = CMD_ERR;
			break;

		case CMD_WIFI_DISABLE:
			if( rxc->enabled )
			{
				M_expt_rx_disable(PORT_WIFI_IDX);
				M_wifi_rx_flush();
				M_wifi_rx_disable();
			}
			else
				ackstatus = CMD_ERR;
			break;
#endif

		case CMD_WIFI_VAP_QUERY: {
						 wifi_vap_query_response_t *vaps;
						 vaps = (wifi_vap_query_response_t *)pcmd;
						 printk("%s:%d\n", __func__, __LINE__);

						 for (i = 0; i < MAX_WIFI_VAPS; i++)
						 {
							 vaps[i].vap_id = wifiDesc[i].VAPID;
							 if( vaps[i].vap_id != 0xFFFF )
								 vaps[i].phy_port_id = PORT_WIFI_IDX + i;
							 port = phy_port_get(PORT_WIFI_IDX + i);

							 SFL_memcpy(vaps[i].ifname, get_onif_name(port->itf.index), 12);
						 }

						 acklen += ( MAX_WIFI_VAPS * sizeof(wifi_vap_query_response_t));
						 break;
					 }

		case CMD_WIFI_VAP_RESET:
					 printk("%s:%d\n", __func__, __LINE__);
					 for (i = 0; i < MAX_WIFI_VAPS; i++)
					 {
						 if( wifiDesc[i].VAPID != 0XFFFF )
						 {
							 wifiDesc[i].VAPID = 0xFFFF;
							 port = phy_port_get(PORT_WIFI_IDX + i);

							 remove_onif_by_index(port->itf.index);

							 if ( rxc->users  )
								 rxc->users--;
						 }
					 }
					 break;

		default:
					 ackstatus = CMD_ERR;
					 break;
	}

	*pcmd = ackstatus;
	return acklen;
}

int onif_is_wifi( POnifDesc pOnif )
{
	int i;
	PWifiIfDesc pWifi;

	for( i = 0; i < MAX_WIFI_VAPS; i++ )
	{
		pWifi = (PWifiIfDesc)&wifiDesc[i];

		if( ( pWifi->VAPID != 0xFFFF ) && ((void *)pWifi == pOnif->itf)  )
		{
			return 1;
		}
	}

	return 0;
}
#endif

#if defined(COMCERTO_1000)
//	M_wifi_rx_enable
//	Enables WiFi fast path queue from ACP->FPP
static void M_wifi_rx_enable(void)
{
	struct tRX_wifi_context *rxc;

	DISABLE_INTERRUPTS();

	rxc = &gWifiRxCtx;

	rxc->rxToCleanIndex = 0;

	HAL_arm1_fiq_enable_1(rxc->PKTTX_irqm);

	// program expt path ring buffer base address
	rxc->rxRing_baseaddr = *(U32*)(rxc->SMI_baseaddr + FPP_SMI_WIFI_RXBASE);

	rxc->enabled = 1;

	//Initialize Rx Offset value, this used by VWD
	*(U32 *)(rxc->SMI_baseaddr + FPP_SMI_WIFI_RX_OFFSET) = BaseOffset;

	ENABLE_INTERRUPTS();


	return ;

}


//	M_wifi_rx_disable
//	Disables WiFi fast path queue from ACP->FPP
static void M_wifi_rx_disable(void)
{
	struct tRX_wifi_context *rxc;

	DISABLE_INTERRUPTS();

	rxc = &gWifiRxCtx;

	HAL_arm1_fiq_disable_1(rxc->PKTTX_irqm);

	rxc->enabled = 0;

	ENABLE_INTERRUPTS();


	return ;

}


static void M_wifi_rx_flush(void)
{
	struct tRX_wifi_context *rxc;
	struct tWiFiRXdesc ThisRXdesc;
	U8* bptr;
	U16 boffset;
	U16 rtc;

	rxc = &gWifiRxCtx;
	rtc = rxc->rxToCleanIndex;

	if ((*(V32*)(rxc->SMI_baseaddr + FPP_SMI_CTRL ) & WIFI_RX_EN) == 0)
		return;

	DISABLE_INTERRUPTS();
	L1_dc_linefill_disable();
	// something from wifi
	*((U64*) &ThisRXdesc) = Read64((U64*)(rxc->rxRing_baseaddr + sizeof(struct tWiFiRXdesc)*rtc));
	L1_dc_linefill_enable();
	ENABLE_INTERRUPTS();

	while ((ThisRXdesc.rx_status0 & WIFIRX_USED_MASK) == 0) {
		bptr = (U8*)ThisRXdesc.rx_data;
		boffset = (ThisRXdesc.rx_status0 & WIFIRX_OFFSET_MASK) >> WIFIRX_OFFSET_SHIFT;

		buffer_put(bptr - boffset, POOLB, 0);
		COUNTER_INCREMENT(packets_dropped_poolB);

		if (ThisRXdesc.rx_status0 & WIFIRX_WRAP)
			rtc = 0;
		else
			rtc++;


		DISABLE_INTERRUPTS();
		L1_dc_linefill_disable();
		*((U64*) &ThisRXdesc) = Read64((U64*)(rxc->rxRing_baseaddr + sizeof(struct tWiFiRXdesc)*rtc));
		L1_dc_linefill_enable();
		ENABLE_INTERRUPTS();
	}

	// re-enable interrupt
	DISABLE_INTERRUPTS();
	HAL_arm1_fiq_enable_1(rxc->PKTTX_irqm);
	ENABLE_INTERRUPTS();

	rxc->rxToCleanIndex = rtc;
}
#endif


void M_wifi_init_rx(void)
{
	int i;
	struct physical_port	*port;

#if defined(COMCERTO_1000)
	struct tRX_wifi_context *rxc;
	rxc = &gWifiRxCtx;

	rxc->SMI_baseaddr = SMI_WIFI_BASE;    //Shared memory base address
	rxc->PKTTX_irqm        = IRQM_CSPVWDTX;
	rxc->PKTRX_irqm        = IRQM_CSPVWDRX;

	set_event_handler(EVENT_PKT_WIFIRX, M_wifi_rx_entry);
#endif

	set_cmd_handler(EVENT_PKT_WIFIRX, M_wifi_rx_cmdproc);

	for ( i = 0; i < MAX_WIFI_VAPS; i++ )
	{
		wifiDesc[i].VAPID = 0xFFFF;
#if defined(COMCERTO_1000)
		tx_channel[PORT_WIFI_IDX + i] = EVENT_EXPT;
#endif
		port = phy_port_get(PORT_WIFI_IDX + i);
		port->id = PORT_WIFI_IDX + i;
	}
}

int wifi_init(void)
{
	M_wifi_init_rx();

	return 0;
}

void wifi_exit(void)
{
}
#endif /* CFG_WIFI_OFFLOAD */
