/*
 *
 *  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.vap_id = itf->wifi_if->vapid;	
	cmd.direct_path_rx = itf->wifi_if->direct_path_rx;	
        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
