/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * 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.
 *
 * File: hostap.c
 *
 * Purpose: handle hostap daemon ioctl input/out functions
 *
 * Author: Lyndon Chen
 *
 * Date: Oct. 20, 2003
 *
 * Functions:
 *
 * Revision History:
 *
 */

#include "hostap.h"
#include "iocmd.h"
#include "mac.h"
#include "card.h"
#include "baseband.h"
#include "wpactl.h"
#include "key.h"
#include "datarate.h"

#define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024
#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT0
#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5

static int          msglevel                =MSG_LEVEL_INFO;

/*
 * Description:
 *      register net_device (AP) for hostap daemon
 *
 * Parameters:
 *  In:
 *      pDevice             -
 *      rtnl_locked         -
 *  Out:
 *
 * Return Value:
 *
 */

static int hostap_enable_hostapd(struct vnt_private *pDevice, int rtnl_locked)
{
	struct vnt_private *apdev_priv;
	struct net_device *dev = pDevice->dev;
	int ret;
	const struct net_device_ops apdev_netdev_ops = {
		.ndo_start_xmit = pDevice->tx_80211,
	};

    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name);

	pDevice->apdev = kzalloc(sizeof(struct net_device), GFP_KERNEL);
	if (pDevice->apdev == NULL)
		return -ENOMEM;

    apdev_priv = netdev_priv(pDevice->apdev);
    *apdev_priv = *pDevice;
	memcpy(pDevice->apdev->dev_addr, dev->dev_addr, ETH_ALEN);

	pDevice->apdev->netdev_ops = &apdev_netdev_ops;

	pDevice->apdev->type = ARPHRD_IEEE80211;

	pDevice->apdev->base_addr = dev->base_addr;
	pDevice->apdev->irq = dev->irq;
	pDevice->apdev->mem_start = dev->mem_start;
	pDevice->apdev->mem_end = dev->mem_end;
	sprintf(pDevice->apdev->name, "%sap", dev->name);
	if (rtnl_locked)
		ret = register_netdevice(pDevice->apdev);
	else
		ret = register_netdev(pDevice->apdev);
	if (ret) {
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
		       dev->name);
		return -1;
	}

    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
	       dev->name, pDevice->apdev->name);

    KeyvInitTable(pDevice,&pDevice->sKey);

	return 0;
}

/*
 * Description:
 *      unregister net_device(AP)
 *
 * Parameters:
 *  In:
 *      pDevice             -
 *      rtnl_locked         -
 *  Out:
 *
 * Return Value:
 *
 */

static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked)
{

    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name);

    if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) {
		if (rtnl_locked)
			unregister_netdevice(pDevice->apdev);
		else
			unregister_netdev(pDevice->apdev);
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
		       pDevice->dev->name, pDevice->apdev->name);
	}
	free_netdev(pDevice->apdev);
	pDevice->apdev = NULL;
    pDevice->bEnable8021x = false;
    pDevice->bEnableHostWEP = false;
    pDevice->bEncryptionEnable = false;

	return 0;
}

/*
 * Description:
 *      Set enable/disable hostapd mode
 *
 * Parameters:
 *  In:
 *      pDevice             -
 *      rtnl_locked         -
 *  Out:
 *
 * Return Value:
 *
 */

int vt6656_hostap_set_hostapd(struct vnt_private *pDevice,
	int val, int rtnl_locked)
{
	if (val < 0 || val > 1)
		return -EINVAL;

	if (pDevice->bEnableHostapd == val)
		return 0;

	pDevice->bEnableHostapd = val;

	if (val)
		return hostap_enable_hostapd(pDevice, rtnl_locked);
	else
		return hostap_disable_hostapd(pDevice, rtnl_locked);
}

/*
 * Description:
 *      remove station function supported for hostap daemon
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */
static int hostap_remove_sta(struct vnt_private *pDevice,
	struct viawget_hostapd_param *param)
{
	unsigned int uNodeIndex;

    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
        BSSvRemoveOneNode(pDevice, uNodeIndex);
    }
    else {
        return -ENOENT;
    }
	return 0;
}

/*
 * Description:
 *      add a station from hostap daemon
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */
static int hostap_add_sta(struct vnt_private *pDevice,
	struct viawget_hostapd_param *param)
{
	struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
	unsigned int uNodeIndex;

	if (!BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex))
		BSSvCreateOneNode(pDevice, &uNodeIndex);

    memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN);
    pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
    pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability;
// TODO listenInterval
//    pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = 1;
    pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = false;
    pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates;

    // set max tx rate
    pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
           pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
    // set max basic rate
    pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M;
    // Todo: check sta preamble, if ap can't support, set status code
    pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
            WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo);

    pMgmt->sNodeDBTable[uNodeIndex].wAID = (u16)param->u.add_sta.aid;

    pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;

    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
               param->sta_addr[0],
               param->sta_addr[1],
               param->sta_addr[2],
               param->sta_addr[3],
               param->sta_addr[4],
               param->sta_addr[5]
              ) ;
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n",
               pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);

	return 0;
}

/*
 * Description:
 *      get station info
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */

static int hostap_get_info_sta(struct vnt_private *pDevice,
	struct viawget_hostapd_param *param)
{
	struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
	unsigned int uNodeIndex;

    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
	    param->u.get_info_sta.inactive_sec =
	        (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;

	    //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts;
	}
	else {
	    return -ENOENT;
	}

	return 0;
}

/*
 * Description:
 *      set station flag
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */
static int hostap_set_flags_sta(struct vnt_private *pDevice,
		struct viawget_hostapd_param *param)
{
	struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
	unsigned int uNodeIndex;

    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
		pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or;
		pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and;
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x\n",
			(unsigned int) pMgmt->sNodeDBTable[uNodeIndex].dwFlags);
	}
	else {
	    return -ENOENT;
	}

	return 0;
}

/*
 * Description:
 *      set generic element (wpa ie)
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */
static int hostap_set_generic_element(struct vnt_private *pDevice,
					struct viawget_hostapd_param *param)
{
	struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;

    memcpy( pMgmt->abyWPAIE,
            param->u.generic_elem.data,
            param->u.generic_elem.len
           );

    pMgmt->wWPAIELen = 	param->u.generic_elem.len;

    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n",  pMgmt->wWPAIELen);

    // disable wpa
    if (pMgmt->wWPAIELen == 0) {
        pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n");
    } else  {
        // enable wpa
        if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) ||
             (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) {
              pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n");
        } else
            return -EINVAL;
    }

	return 0;
}

/*
 * Description:
 *      flush station nodes table.
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *  Out:
 *
 * Return Value:
 *
 */

static void hostap_flush_sta(struct vnt_private *pDevice)
{
    // reserved node index =0 for multicast node.
    BSSvClearNodeDBTable(pDevice, 1);
    pDevice->uAssocCount = 0;

    return;
}

/*
 * Description:
 *      set each stations encryption key
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */
static int hostap_set_encryption(struct vnt_private *pDevice,
	struct viawget_hostapd_param *param, int param_len)
{
	struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
	u32 dwKeyIndex = 0;
	u8 abyKey[MAX_KEY_LEN];
	u8 abySeq[MAX_KEY_LEN];
	NDIS_802_11_KEY_RSC   KeyRSC;
	u8 byKeyDecMode = KEY_CTL_WEP;
	int ret = 0;
	s32 iNodeIndex = -1;
	int ii;
	bool bKeyTableFull = false;
	u16 wKeyCtl = 0;

	param->u.crypt.err = 0;

	if (param->u.crypt.alg > WPA_ALG_CCMP)
		return -EINVAL;

	if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) {
		param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n");
		return -EINVAL;
	}

	if (is_broadcast_ether_addr(param->sta_addr)) {
		if (param->u.crypt.idx >= MAX_GROUP_KEY)
			return -EINVAL;
        iNodeIndex = 0;

	} else {
	    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == false) {
	        param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
	        return -EINVAL;
	    }
	}
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex);
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg);

	if (param->u.crypt.alg == WPA_ALG_NONE) {

        if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == true) {
            if (KeybRemoveKey( pDevice,
                               &(pDevice->sKey),
                               param->sta_addr,
                               pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex
                              ) == false) {
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
            }
            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
        }
        pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0;
        pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0;
        pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0;
        pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0;
        pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
        pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;
        pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0;
        memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
                0,
                MAX_KEY_LEN
               );

        return ret;
	}

    memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len);
    // copy to node key tbl
    pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx;
    pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len;
    memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
            param->u.crypt.key,
            param->u.crypt.key_len
           );

    dwKeyIndex = (u32)(param->u.crypt.idx);
    if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
        pDevice->byKeyIndex = (u8)dwKeyIndex;
        pDevice->bTransmitKey = true;
        dwKeyIndex |= (1 << 31);
    }

	if (param->u.crypt.alg == WPA_ALG_WEP) {

        if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) {
            KeybSetDefaultKey(  pDevice,
                                &(pDevice->sKey),
                                dwKeyIndex & ~(BIT30 | USE_KEYRSC),
                                param->u.crypt.key_len,
                                NULL,
                                abyKey,
                                KEY_CTL_WEP
                             );

        } else {
            // 8021x enable, individual key
            dwKeyIndex |= (1 << 30); // set pairwise key
		if (KeybSetKey(pDevice, &(pDevice->sKey),
			&param->sta_addr[0],
			dwKeyIndex & ~(USE_KEYRSC),
			param->u.crypt.key_len,
			&KeyRSC, (u8 *)abyKey,
			KEY_CTL_WEP
                           ) == true) {

                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;

            } else {
                // Key Table Full
                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
                bKeyTableFull = true;
            }
        }
        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
        pDevice->bEncryptionEnable = true;
        pMgmt->byCSSPK = KEY_CTL_WEP;
        pMgmt->byCSSGK = KEY_CTL_WEP;
        pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP;
        pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
        return ret;
	}

	if (param->u.crypt.seq) {
	    memcpy(&abySeq, param->u.crypt.seq, 8);
		for (ii = 0 ; ii < 8 ; ii++)
			KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8);

		dwKeyIndex |= 1 << 29;
		pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC;
	}

	if (param->u.crypt.alg == WPA_ALG_TKIP) {
	    if (param->u.crypt.key_len != MAX_KEY_LEN)
	        return -EINVAL;
	    pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
        byKeyDecMode = KEY_CTL_TKIP;
        pMgmt->byCSSPK = KEY_CTL_TKIP;
        pMgmt->byCSSGK = KEY_CTL_TKIP;
	}

	if (param->u.crypt.alg == WPA_ALG_CCMP) {
	    if ((param->u.crypt.key_len != AES_KEY_LEN) ||
	        (pDevice->byLocalID <= REV_ID_VT3253_A1))
	        return -EINVAL;
        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
        byKeyDecMode = KEY_CTL_CCMP;
        pMgmt->byCSSPK = KEY_CTL_CCMP;
        pMgmt->byCSSGK = KEY_CTL_CCMP;
    }

    if (iNodeIndex == 0) {
       KeybSetDefaultKey(  pDevice,
                           &(pDevice->sKey),
                           dwKeyIndex,
                           param->u.crypt.key_len,
			&KeyRSC,
                           abyKey,
                           byKeyDecMode
                          );
       pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;

    } else {
        dwKeyIndex |= (1 << 30); // set pairwise key
        if (KeybSetKey(pDevice,
                       &(pDevice->sKey),
                       &param->sta_addr[0],
                       dwKeyIndex,
                       param->u.crypt.key_len,
			&KeyRSC,
                       (u8 *)abyKey,
                        byKeyDecMode
                       ) == true) {

            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true;

        } else {
            // Key Table Full
            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
            bKeyTableFull = true;
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n");
        }

    }

    if (bKeyTableFull == true) {
        wKeyCtl &= 0x7F00;              // clear all key control filed
        wKeyCtl |= (byKeyDecMode << 4);
        wKeyCtl |= (byKeyDecMode);
        wKeyCtl |= 0x0044;              // use group key for all address
        wKeyCtl |= 0x4000;              // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int
// Todo.. xxxxxx
        //MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID);
    }

    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex);
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx,
               param->u.crypt.key_len );
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1],
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2],
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3],
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4]
              );

	// set wep key
    pDevice->bEncryptionEnable = true;
    pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode;
    pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
    pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
    pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;

	return ret;
}

/*
 * Description:
 *      get each stations encryption key
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */
static int hostap_get_encryption(struct vnt_private *pDevice,
				       struct viawget_hostapd_param *param,
				       int param_len)
{
	struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
	int ret = 0;
	int ii;
	s32 iNodeIndex = 0;

	param->u.crypt.err = 0;

	if (is_broadcast_ether_addr(param->sta_addr)) {
        iNodeIndex = 0;
	} else {
	    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == false) {
	        param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
	        return -EINVAL;
	    }
	}
	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex);
    memset(param->u.crypt.seq, 0, 8);
    for (ii = 0 ; ii < 8 ; ii++) {
        param->u.crypt.seq[ii] = (u8)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8);
    }

	return ret;
}

/*
 * Description:
 *      vt6656_hostap_ioctl main function supported for hostap daemon.
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      iw_point  -
 *  Out:
 *
 * Return Value:
 *
 */

int vt6656_hostap_ioctl(struct vnt_private *pDevice, struct iw_point *p)
{
	struct viawget_hostapd_param *param;
	int ret = 0;
	int ap_ioctl = 0;

	if (p->length < sizeof(struct viawget_hostapd_param) ||
	    p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
		return -EINVAL;

	param = kmalloc((int)p->length, GFP_KERNEL);
	if (param == NULL)
		return -ENOMEM;

	if (copy_from_user(param, p->pointer, p->length)) {
		ret = -EFAULT;
		goto out;
	}

	switch (param->cmd) {
	case VIAWGET_HOSTAPD_SET_ENCRYPTION:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n");
        spin_lock_irq(&pDevice->lock);
		ret = hostap_set_encryption(pDevice, param, p->length);
        spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_GET_ENCRYPTION:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n");
        spin_lock_irq(&pDevice->lock);
		ret = hostap_get_encryption(pDevice, param, p->length);
        spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
		ret = -EOPNOTSUPP;
		goto out;
	case VIAWGET_HOSTAPD_FLUSH:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
        spin_lock_irq(&pDevice->lock);
    	hostap_flush_sta(pDevice);
        spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_ADD_STA:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n");
         spin_lock_irq(&pDevice->lock);
		 ret = hostap_add_sta(pDevice, param);
         spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_REMOVE_STA:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n");
         spin_lock_irq(&pDevice->lock);
		 ret = hostap_remove_sta(pDevice, param);
         spin_unlock_irq(&pDevice->lock);
		break;
	case VIAWGET_HOSTAPD_GET_INFO_STA:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n");
		 ret = hostap_get_info_sta(pDevice, param);
		 ap_ioctl = 1;
		break;
	case VIAWGET_HOSTAPD_SET_FLAGS_STA:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
		 ret = hostap_set_flags_sta(pDevice, param);
		break;

	case VIAWGET_HOSTAPD_MLME:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
	    return -EOPNOTSUPP;

	case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
		ret = hostap_set_generic_element(pDevice, param);
		break;

	case VIAWGET_HOSTAPD_SCAN_REQ:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
	    return -EOPNOTSUPP;

	case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
	    ret = -EOPNOTSUPP;
	    goto out;
	default:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6656_hostap_ioctl: unknown cmd=%d\n",
		       (int)param->cmd);
		ret = -EOPNOTSUPP;
		goto out;
	}

	if ((ret == 0) && ap_ioctl) {
		if (copy_to_user(p->pointer, param, p->length)) {
			ret = -EFAULT;
			goto out;
		}
	}

 out:
	kfree(param);

	return ret;
}

