/*
 *
 *  Copyright (C) 2007 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifdef WIFI_ENABLE
#include "cmm.h"
#include "itf.h"

//#include <net/if.h>
#include <linux/sockios.h>
//#include <linux/wireless.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <module_wifi.h>

#define WIFI_FF_SYSCTL_PATH "/proc/sys/net/"
#define WIFI_FF_SYSCTL_ENTRY "wifi_fast_path_enable"

static int cmmFeWiFiGetBridge( FCI_CLIENT *fci_handle, int fd, struct interface *witf );

//static unsigned char wifi_sysctl[128];	
#define SIOCVAPUPDATE (0x6401)
#define WIFI_FF_MASTER_IF "/dev/vwd0"

extern struct wifi_ff_entry glbl_wifi_ff_ifs[MAX_WIFI_FF_IFS];
void __cmmGetWiFi(int fd, struct interface *itf)
{
	//struct iwreq       pwrq;
	char ifname[IFNAMSIZ];	
	int ii;
		
	itf->itf_flags &= ~ITF_WIFI;
	____itf_get_name(itf, ifname, IFNAMSIZ);

	cmm_print(DEBUG_INFO, "%s: %s  index:%d\n", __func__, ifname, itf->ifindex);
	//strncpy(pwrq.ifr_name, ifname, IFNAMSIZ);
	
	//if( ioctl(fd, SIOCGIWMODE, &pwrq) < 0 )
	//{
	//	return;
	//}

	for( ii = 0; ii < MAX_WIFI_FF_IFS; ii++ )
	{
		if ( glbl_wifi_ff_ifs[ii].used  )
			if( !strcmp(glbl_wifi_ff_ifs[ii].ifname, ifname) )
			{
				cmm_print(DEBUG_INFO, "%s: wifi if is up %s \n", __func__, itf->ifname);
				cmm_print(DEBUG_INFO, "%s: mac:%s:%d %x:%x:%x:%x:%x:%x \n", __func__, 
					itf->ifname, itf->macaddr_len, itf->macaddr[0], itf->macaddr[1], 
					itf->macaddr[2],itf->macaddr[3],itf->macaddr[4],itf->macaddr[5]  );

				itf->itf_flags |= ITF_WIFI;
				itf->wifi_if = &glbl_wifi_ff_ifs[ii];
				memcpy(glbl_wifi_ff_ifs[ii].macaddr, itf->macaddr, 6);
			}
	}
	
	return;		
}

static int cmmResetVWD()
{
        vwd_cmd_t cmd;
	int sfd;

        memset(&cmd, 0, sizeof(cmd));
	sfd = open(WIFI_FF_MASTER_IF, O_RDONLY);

	if ( sfd <= 0 )
	{
		cmm_print(DEBUG_ERROR, "%s: failed to open vwd device: %s\n", __func__, strerror(errno));
		return -1;
	}

        cmd.action = FPP_VWD_VAP_RESET;

        if ( ioctl(sfd, SIOCVAPUPDATE, &cmd) < 0)
        {
		close(sfd);
		cmm_print(DEBUG_ERROR, "%s::%d: ioctl() %s\n", __func__, __LINE__, strerror(errno));
                return -1;
        }

	close(sfd);

        return 0;
}

static int cmmUpdateVWD(struct interface *itf, int req)
{
        vwd_cmd_t cmd;
       // struct ifreq ifr;
	int sfd;

        memset(&cmd, 0, sizeof(cmd));

	sfd = open(WIFI_FF_MASTER_IF, O_RDONLY);
	
	if ( sfd <= 0 )
	{
        	cmm_print(DEBUG_ERROR, "%s: failed to open vwd device: %s\n", __func__, strerror(errno));
		return -1;
	}

        cmd.action = req;
        cmd.ifindex = itf->ifindex;
        memcpy( cmd.ifname, itf->ifname, 12);
        memcpy( cmd.macaddr, itf->macaddr, 6);
	cmd.cmd_flags |= VWD_CMD_MAC_VALID;
	
	cmd.vap_id = itf->wifi_if->vapid;	
        if (itf->wifi_if->direct_path_rx) {
          cmd.cmd_flags |= VWD_CMD_ENABLE_DIRECT_PATH_RX;
        }
        if (itf->wifi_if->direct_path_tx) {
          cmd.cmd_flags |= VWD_CMD_ENABLE_DIRECT_PATH_TX;
        }
        cmm_print(DEBUG_INFO, "%s: mac:%s:%d %x:%x:%x:%x:%x:%x \n", __func__,
                                        itf->ifname, itf->ifindex, itf->macaddr[0], itf->macaddr[1],
                                       itf->macaddr[2],itf->macaddr[3],itf->macaddr[4],itf->macaddr[5]  );

        if ( ioctl(sfd, SIOCVAPUPDATE, &cmd) < 0)
        {
		close(sfd);
                cmm_print(DEBUG_ERROR, "%s::%d: ioctl() %s\n", __func__, __LINE__, strerror(errno));
                return -1;
        }

	close(sfd);

        return 0;
}




int cmmFeWiFiUpdate(FCI_CLIENT *fci_handle, int fd, int request, struct interface *itf)
{
	struct fpp_wifi_cmd cmd;
        short ret = 0;
        int action;

	switch (request)
	{
	default:
	case ADD:
		if ((itf->flags & (FPP_PROGRAMMED | FPP_NEEDS_UPDATE)) == FPP_PROGRAMMED)
			goto out;

		if ((itf->flags & (FPP_PROGRAMMED | FPP_NEEDS_UPDATE)) == (FPP_PROGRAMMED | FPP_NEEDS_UPDATE))
		{
			cmm_print(DEBUG_ERROR, "%s: trying to update wifi interface(%d)\n", __func__, itf->ifindex);
			ret = -1;
			goto out;
		}
		cmmFeWiFiGetBridge( fci_handle,  fd, itf );

		action = FPP_VWD_VAP_ADD;

		break;

	case UPDATE:
		if (!(itf->flags & FPP_PROGRAMMED))
		{
			cmm_print(DEBUG_ERROR, "%s: trying to update non FF iface(%s)\n", __func__, itf->ifname);
			goto out;
		}            

		action = FPP_VWD_VAP_UPDATE;

		break;

	case REMOVE:
		if (!(itf->flags & FPP_PROGRAMMED))
		{
			cmm_print( DEBUG_ERROR, "%s: Called remove, but not programmed\n", __func__);
			goto out;
		}

		action = FPP_VWD_VAP_REMOVE;
		
		break;
	}
	
	cmd.action = action;
	cmd.vap_id = itf->wifi_if->vapid;	
	
	if (____itf_get_name(itf, cmd.ifname, sizeof(cmd.ifname)) < 0)
	{
		cmm_print(DEBUG_ERROR, "%s: ____itf_get_name(%d) failed\n", __func__, itf->ifindex);

		goto out;
	}
        
	memcpy( cmd.mac_addr, itf->macaddr, 6);
	
        //cmm_print(DEBUG_ERROR, "%s: mac:%s:%d %x:%x:%x:%x:%x:%x \n", __func__,
        //                                cmd.ifname, cmd.vap_id,cmd.mac_addr[0], cmd.mac_addr[1],
        //                                cmd.mac_addr[2],cmd.mac_addr[3],cmd.mac_addr[4],cmd.mac_addr[5]  );
	//Send VAP entry command to FPP
	ret = fci_write(fci_handle, FPP_CMD_WIFI_VAP_ENTRY, 
				sizeof(fpp_wifi_cmd_t), (unsigned short *) &cmd); 

	if ( ret != FPP_ERR_OK )
	{	
		cmm_print(DEBUG_ERROR, "%s: Failed command FPP_CMD_WIFI_VAP_ENTRY, action:error %d:%d\n",
                         __func__, action, ret);
		goto out;
	}


	if( ! cmmUpdateVWD(itf, action) )
	{
		switch (action)
		{
			case FPP_VWD_VAP_UPDATE:
			case FPP_VWD_VAP_ADD:
				itf->flags |= FPP_PROGRAMMED;
				itf->flags &= ~FPP_NEEDS_UPDATE;
				break;

			case FPP_VWD_VAP_REMOVE:
				itf->flags &= ~FPP_PROGRAMMED;
				itf->flags &= ~FPP_NEEDS_UPDATE;
				break;
			
	
		}
	}
 	

out:
	return ret;
	
}


int cmmFeWiFiBridgeUpdate( FCI_CLIENT *fci_handle, int fd, int request, struct interface *bitf)
{
	struct list_head *entry;
	struct interface *itf;
	short ret = 0;
	int i, j;
	/* Search through interface table if there are any
 	 * WiFi interface and they are part of bridge then 
 	 * update the WiFi interfce in FPP with bridge MAC 
 	 * MAC address.
 	 */    

	for (i = 0; i < ITF_HASH_TABLE_SIZE; i++)
	{
		for (entry = list_first(&itf_table.hash[i]); entry != &itf_table.hash[i]; entry = list_next(entry))
		{
			itf = container_of(entry, struct interface, list);

			if (!__itf_is_wifi(itf))
				continue;
		
			for( j = 0; j < MAX_PORTS; j++ )
			{
				//cmm_print(DEBUG_ERROR, "%s: index: %d:%d\n ", __func__, 
				//bitf->ifindices[j], itf->ifindex );	 
				if(bitf->ifindices[j] == itf->ifindex )	 
					break;
			}
		
			
			if( (j < MAX_PORTS) && (itf->flags & FPP_PROGRAMMED) && __itf_is_up(itf) )
			{
				cmm_print(DEBUG_INFO, "%s: wifi mac: %x:%x:%x:%x:%x:%x  bridge mac: %x:%x:%x:%x:%x:%x\n ", __func__, 
					itf->macaddr[0], itf->macaddr[1], itf->macaddr[2],
                                        itf->macaddr[3],itf->macaddr[4],itf->macaddr[5],
					bitf->macaddr[0], bitf->macaddr[1], bitf->macaddr[2],
                                        bitf->macaddr[3],bitf->macaddr[4],bitf->macaddr[5]
					  );
				
				if ( (itf->macaddr[0] ^  bitf->macaddr[0]) ||
					(itf->macaddr[1] ^  bitf->macaddr[1]) ||
					(itf->macaddr[2] ^  bitf->macaddr[2]) ||
					(itf->macaddr[3] ^  bitf->macaddr[3]) ||
					(itf->macaddr[4] ^  bitf->macaddr[4]) ||
					(itf->macaddr[5] ^  bitf->macaddr[5]) ) 
				{
					memcpy( itf->macaddr, bitf->macaddr, 6 );
					ret = cmmFeWiFiUpdate(fci_handle, fd, UPDATE, itf);
					
				}
			}
		}
	}

	return ret;
}

static int cmmFeWiFiGetBridge( FCI_CLIENT *fci_handle, int fd, struct interface *witf )
{
	struct list_head *entry;
	struct interface *itf;
	int i, j;

	/* Search through interface table if there are any
 	 * bridge interface and it has given WiFi interface 
 	 * as one of its port and they are part of bridge then 
 	 * update the WiFi interfce in FPP with bridge MAC 
 	 * MAC address.
 	 */    

	for (i = 0; i < ITF_HASH_TABLE_SIZE; i++)
	{
		for (entry = list_first(&itf_table.hash[i]); entry != &itf_table.hash[i]; entry = list_next(entry))
		{
			itf = container_of(entry, struct interface, list);

			if (!__itf_is_bridge(itf->ifindex))
				continue;
		
			for( j = 0; j < MAX_PORTS; j++ )
			{
				//cmm_print(DEBUG_ERROR, "%s: index: %d:%d\n ", __func__, 
				//bitf->ifindices[j], itf->ifindex );	 
				if(itf->ifindices[j] == witf->ifindex )	 
					break;
			}
		
			
			if( (j < MAX_PORTS) &&  __itf_is_up(witf) )
			{
				cmm_print(DEBUG_INFO, "%s: wifi mac: %x:%x:%x:%x:%x:%x  bridge mac: %x:%x:%x:%x:%x:%x\n ", __func__, 
					witf->macaddr[0], witf->macaddr[1], witf->macaddr[2],
                                        witf->macaddr[3],witf->macaddr[4],witf->macaddr[5],
					itf->macaddr[0], itf->macaddr[1], itf->macaddr[2],
                                        itf->macaddr[3],itf->macaddr[4],itf->macaddr[5]
					  );
				
				if ( (itf->macaddr[0] ^  witf->macaddr[0]) ||
					(itf->macaddr[1] ^  witf->macaddr[1]) ||
					(itf->macaddr[2] ^  witf->macaddr[2]) ||
					(itf->macaddr[3] ^  witf->macaddr[3]) ||
					(itf->macaddr[4] ^  witf->macaddr[4]) ||
					(itf->macaddr[5] ^  witf->macaddr[5]) ) 
				{
					memcpy( witf->macaddr, itf->macaddr, 6 );
					
				}
			}

		}
	}

	return 0;
}

/*****************************************************************
* cmmWiFiReset
* 
*
*
******************************************************************/
void cmmWiFiReset(FCI_CLIENT *fci_handle)
{
	struct list_head *entry;
	struct interface *itf;
	short ret;
	int i;

	// Send message to forward engine
	cmm_print(DEBUG_COMMAND, "Send CMD_WIFI_VAP_RESET\n");

	__pthread_mutex_lock(&itf_table.lock);

	ret = fci_write(fci_handle, FPP_CMD_WIFI_VAP_RESET, 0, NULL); 
	if (ret == FPP_ERR_OK)
	{
		if (cmmResetVWD())
			cmm_print(DEBUG_ERROR, "%s: Failed to reset VAPs with VWD\n", __func__);

		for (i = 0; i < ITF_HASH_TABLE_SIZE; i++)
		{
			for (entry = list_first(&itf_table.hash[i]); entry != &itf_table.hash[i]; entry = list_next(entry))
			{
				itf = container_of(entry, struct interface, list);

				if (!__itf_is_wifi(itf))
					continue;

				itf->flags &= ~FPP_PROGRAMMED;
			}
		}
	}
	else
	{
		cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_WIFI_VAP_RESET\n", __func__, ret);
	}

	__pthread_mutex_unlock(&itf_table.lock);
}

#endif //WIFI_ENABLE
