/*
 * 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: wpactl.c
 *
 * Purpose: handle wpa supplicant ioctl input/out functions
 *
 * Author: Lyndon Chen
 *
 * Date: Oct. 20, 2003
 *
 * Functions:
 *
 * Revision History:
 *
 */

#include "wpactl.h"
#include "key.h"
#include "mac.h"
#include "device.h"
#include "wmgr.h"
#include "iocmd.h"
#include "iowpa.h"
#include "rf.h"

/*---------------------  Static Definitions -------------------------*/

#define VIAWGET_WPA_MAX_BUF_SIZE 1024



static const int frequency_list[] = {
	2412, 2417, 2422, 2427, 2432, 2437, 2442,
	2447, 2452, 2457, 2462, 2467, 2472, 2484
};
/*---------------------  Static Classes  ----------------------------*/

/*---------------------  Static Variables  --------------------------*/
//static int          msglevel                =MSG_LEVEL_DEBUG;
static int          msglevel                =MSG_LEVEL_INFO;

/*---------------------  Static Functions  --------------------------*/




/*---------------------  Export Variables  --------------------------*/
static void wpadev_setup(struct net_device *dev)
{
	dev->type               = ARPHRD_IEEE80211;
	dev->hard_header_len    = ETH_HLEN;
	dev->mtu                = 2048;
	dev->addr_len           = ETH_ALEN;
	dev->tx_queue_len       = 1000;

	memset(dev->broadcast,0xFF, ETH_ALEN);

	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
}

/*
 * Description:
 *      register netdev for wpa supplicant deamon
 *
 * Parameters:
 *  In:
 *      pDevice             -
 *      enable              -
 *  Out:
 *
 * Return Value:
 *
 */

static int wpa_init_wpadev(PSDevice pDevice)
{
    PSDevice wpadev_priv;
	struct net_device *dev = pDevice->dev;
         int ret=0;

	pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup);
	if (pDevice->wpadev == NULL)
		return -ENOMEM;

    wpadev_priv = netdev_priv(pDevice->wpadev);
    *wpadev_priv = *pDevice;
	memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, ETH_ALEN);
         pDevice->wpadev->base_addr = dev->base_addr;
	pDevice->wpadev->irq = dev->irq;
	pDevice->wpadev->mem_start = dev->mem_start;
	pDevice->wpadev->mem_end = dev->mem_end;
	ret = register_netdev(pDevice->wpadev);
	if (ret) {
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n",
		       dev->name);
		free_netdev(pDevice->wpadev);
		return -1;
	}

	if (pDevice->skb == NULL) {
        pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
        if (pDevice->skb == NULL)
		    return -ENOMEM;
    }

    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
	       dev->name, pDevice->wpadev->name);

	return 0;
}


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

static int wpa_release_wpadev(PSDevice pDevice)
{
    if (pDevice->skb) {
        dev_kfree_skb(pDevice->skb);
        pDevice->skb = NULL;
    }

    if (pDevice->wpadev) {
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
	       pDevice->dev->name, pDevice->wpadev->name);
	unregister_netdev(pDevice->wpadev);
	free_netdev(pDevice->wpadev);
         pDevice->wpadev = NULL;
    }

	return 0;
}





/*
 * Description:
 *      Set enable/disable dev for wpa supplicant deamon
 *
 * Parameters:
 *  In:
 *      pDevice             -
 *      val                 -
 *  Out:
 *
 * Return Value:
 *
 */

int wpa_set_wpadev(PSDevice pDevice, int val)
{
	if (val)
		return wpa_init_wpadev(pDevice);
	else
		return wpa_release_wpadev(pDevice);
}


/*
 * Description:
 *      Set WPA algorithm & keys
 *
 * Parameters:
 *  In:
 *      pDevice -
 *      param -
 *  Out:
 *
 * Return Value:
 *
 */

 int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel)
{
    struct viawget_wpa_param *param=ctx;
    PSMgmtObject pMgmt = pDevice->pMgmt;
    unsigned long dwKeyIndex = 0;
    unsigned char abyKey[MAX_KEY_LEN];
    unsigned char abySeq[MAX_KEY_LEN];
    QWORD   KeyRSC;
//    NDIS_802_11_KEY_RSC KeyRSC;
    unsigned char byKeyDecMode = KEY_CTL_WEP;
	int ret = 0;
	int uu, ii;


	if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
		return -EINVAL;

    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name);
	if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
        pDevice->bEncryptionEnable = false;
        pDevice->byKeyIndex = 0;
        pDevice->bTransmitKey = false;
        KeyvRemoveAllWEPKey(&(pDevice->sKey), pDevice->PortOffset);
        for (uu=0; uu<MAX_KEY_TABLE; uu++) {
            MACvDisableKeyEntry(pDevice->PortOffset, uu);
        }
        return ret;
    }

    //spin_unlock_irq(&pDevice->lock);
    if(param->u.wpa_key.key && fcpfkernel) {
       memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
     }
    else {
	spin_unlock_irq(&pDevice->lock);
	if (param->u.wpa_key.key &&
	    copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) {
	    spin_lock_irq(&pDevice->lock);
	    return -EINVAL;
    	}
spin_lock_irq(&pDevice->lock);
    	}

    dwKeyIndex = (unsigned long)(param->u.wpa_key.key_index);

	if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
        if (dwKeyIndex > 3) {
            return -EINVAL;
        }
        else {
            if (param->u.wpa_key.set_tx) {
                pDevice->byKeyIndex = (unsigned char)dwKeyIndex;
                pDevice->bTransmitKey = true;
		        dwKeyIndex |= (1 << 31);
            }
            KeybSetDefaultKey(&(pDevice->sKey),
                                dwKeyIndex & ~(BIT30 | USE_KEYRSC),
                                param->u.wpa_key.key_len,
                                NULL,
                                abyKey,
                                KEY_CTL_WEP,
                                pDevice->PortOffset,
                                pDevice->byLocalID);

        }
        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
        pDevice->bEncryptionEnable = true;
        return ret;
	}

	    //spin_unlock_irq(&pDevice->lock);
        if(param->u.wpa_key.seq && fcpfkernel) {
           memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
        	}
       else {
	   	spin_unlock_irq(&pDevice->lock);
	if (param->u.wpa_key.seq &&
	    copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) {
	    spin_lock_irq(&pDevice->lock);
	    return -EINVAL;
       	}
spin_lock_irq(&pDevice->lock);
}

	if (param->u.wpa_key.seq_len > 0) {
		for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
		     if (ii < 4)
			    LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8));
			 else
			    HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8));
	         //KeyRSC |= (abySeq[ii] << (ii * 8));
		}
		dwKeyIndex |= 1 << 29;
	}

    if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return  dwKeyIndex > 3\n");
        return -EINVAL;
    }

	if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) {
        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
    }

	if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
    }

	if (param->u.wpa_key.set_tx)
		dwKeyIndex |= (1 << 31);


    if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
        byKeyDecMode = KEY_CTL_CCMP;
    else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
        byKeyDecMode = KEY_CTL_TKIP;
    else
        byKeyDecMode = KEY_CTL_WEP;

    // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
    if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
        if (param->u.wpa_key.key_len == MAX_KEY_LEN)
            byKeyDecMode = KEY_CTL_TKIP;
        else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
            byKeyDecMode = KEY_CTL_WEP;
        else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
            byKeyDecMode = KEY_CTL_WEP;
    } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
        if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
            byKeyDecMode = KEY_CTL_WEP;
        else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
            byKeyDecMode = KEY_CTL_WEP;
    }

    // Check TKIP key length
    if ((byKeyDecMode == KEY_CTL_TKIP) &&
        (param->u.wpa_key.key_len != MAX_KEY_LEN)) {
        // TKIP Key must be 256 bits
        //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n"));
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n");
        return -EINVAL;
    }
    // Check AES key length
    if ((byKeyDecMode == KEY_CTL_CCMP) &&
        (param->u.wpa_key.key_len != AES_KEY_LEN)) {
        // AES Key must be 128 bits
        //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - AES Key must be 128 bits\n"));
        return -EINVAL;
    }

   // spin_lock_irq(&pDevice->lock);
    if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) {
        // If is_broadcast_ether_addr, set the key as every key entry's group key.
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");

        if ((KeybSetAllGroupKey(&(pDevice->sKey),
                            dwKeyIndex,
                            param->u.wpa_key.key_len,
                            (PQWORD) &(KeyRSC),
                            (unsigned char *)abyKey,
                            byKeyDecMode,
                            pDevice->PortOffset,
                            pDevice->byLocalID) == true) &&
            (KeybSetDefaultKey(&(pDevice->sKey),
                            dwKeyIndex,
                            param->u.wpa_key.key_len,
                            (PQWORD) &(KeyRSC),
                            (unsigned char *)abyKey,
                            byKeyDecMode,
                            pDevice->PortOffset,
                            pDevice->byLocalID) == true) ) {
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");

        } else {
            //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n"));
           // spin_unlock_irq(&pDevice->lock);
            return -EINVAL;
        }

    } else {
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
        // BSSID not 0xffffffffffff
        // Pairwise Key can't be WEP
        if (byKeyDecMode == KEY_CTL_WEP) {
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
            //spin_unlock_irq(&pDevice->lock);
            return -EINVAL;
        }

        dwKeyIndex |= (1 << 30); // set pairwise key
        if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
            //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
            //spin_unlock_irq(&pDevice->lock);
            return -EINVAL;
        }
        if (KeybSetKey(&(pDevice->sKey),
                       &param->addr[0],
                       dwKeyIndex,
                       param->u.wpa_key.key_len,
                       (PQWORD) &(KeyRSC),
                       (unsigned char *)abyKey,
                        byKeyDecMode,
                        pDevice->PortOffset,
                        pDevice->byLocalID) == true) {
            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");

        } else {
            // Key Table Full
            if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
                //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
                //spin_unlock_irq(&pDevice->lock);
                return -EINVAL;

            } else {
                // Save Key and configure just before associate/reassociate to BSSID
                // we do not implement now
                //spin_unlock_irq(&pDevice->lock);
                return -EINVAL;
            }
        }
    } // BSSID not 0xffffffffffff
    if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
        pDevice->byKeyIndex = (unsigned char)param->u.wpa_key.key_index;
        pDevice->bTransmitKey = true;
    }
    pDevice->bEncryptionEnable = true;
    //spin_unlock_irq(&pDevice->lock);

/*
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0],
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1],
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2],
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3],
               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4]
              );
*/

	return ret;

}


/*
 * Description:
 *      enable wpa auth & mode
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */

static int wpa_set_wpa(PSDevice pDevice,
				     struct viawget_wpa_param *param)
{

    PSMgmtObject    pMgmt = pDevice->pMgmt;
	int ret = 0;

    pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
    pMgmt->bShareKeyAlgorithm = false;

    return ret;
}




 /*
 * Description:
 *      set disassociate
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */

static int wpa_set_disassociate(PSDevice pDevice,
				     struct viawget_wpa_param *param)
{
    PSMgmtObject    pMgmt = pDevice->pMgmt;
	int ret = 0;

    spin_lock_irq(&pDevice->lock);
    if (pDevice->bLinkPass) {
        if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6))
            bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
    }
    spin_unlock_irq(&pDevice->lock);

    return ret;
}



/*
 * Description:
 *      enable scan process
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */

static int wpa_set_scan(PSDevice pDevice,
				     struct viawget_wpa_param *param)
{
	int ret = 0;

    spin_lock_irq(&pDevice->lock);
    BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
    bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
    spin_unlock_irq(&pDevice->lock);

    return ret;
}



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

static int wpa_get_bssid(PSDevice pDevice,
				     struct viawget_wpa_param *param)
{
    PSMgmtObject        pMgmt = pDevice->pMgmt;
	int ret = 0;

	memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6);

    return ret;

}


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

static int wpa_get_ssid(PSDevice pDevice,
				     struct viawget_wpa_param *param)
{
    PSMgmtObject        pMgmt = pDevice->pMgmt;
	PWLAN_IE_SSID       pItemSSID;
	int ret = 0;

    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;

	memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len);
	param->u.wpa_associate.ssid_len = pItemSSID->len;

    return ret;
}



/*
 * Description:
 *      get scan results
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */

static int wpa_get_scan(PSDevice pDevice,
				     struct viawget_wpa_param *param)
{
	struct viawget_scan_result *scan_buf;
    PSMgmtObject    pMgmt = pDevice->pMgmt;
    PWLAN_IE_SSID   pItemSSID;
    PKnownBSS pBSS;
	unsigned char *pBuf;
	int ret = 0;
	u16 count = 0;
	u16 ii, jj;
#if 1

    unsigned char *ptempBSS;



    ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC);

    if (ptempBSS == NULL) {

       printk("bubble sort kmalloc memory fail@@@\n");

        ret = -ENOMEM;

        return ret;

    }

    for (ii = 0; ii < MAX_BSS_NUM; ii++) {

         for(jj=0;jj<MAX_BSS_NUM-ii-1;jj++) {

           if((pMgmt->sBSSList[jj].bActive!=true) ||

                ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=false))) {

                 memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS));

                 memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS));

                 memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS));

              }

         }

    };

  kfree(ptempBSS);

 // printk("bubble sort result:\n");

  //for (ii = 0; ii < MAX_BSS_NUM; ii++)

  //    printk("%d [%s]:RSSI=%d\n",ii,((PWLAN_IE_SSID)(pMgmt->sBSSList[ii].abySSID))->abySSID,

  //                                                                 pMgmt->sBSSList[ii].uRSSI);

 #endif

//******mike:bubble sort by stronger RSSI*****//




	count = 0;
	pBSS = &(pMgmt->sBSSList[0]);
    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
        pBSS = &(pMgmt->sBSSList[ii]);
        if (!pBSS->bActive)
            continue;
        count++;
    };

    pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC);

    if (pBuf == NULL) {
        ret = -ENOMEM;
        return ret;
    }
    scan_buf = (struct viawget_scan_result *)pBuf;
	pBSS = &(pMgmt->sBSSList[0]);
    for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) {
        pBSS = &(pMgmt->sBSSList[ii]);
        if (pBSS->bActive) {
            if (jj >= count)
                break;
            memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN);
            pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
   		    memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len);
   		    scan_buf->ssid_len = pItemSSID->len;
            scan_buf->freq = frequency_list[pBSS->uChannel-1];
	  scan_buf->caps = pBSS->wCapInfo;
            //scan_buf->caps = pBSS->wCapInfo;
            //scan_buf->qual =
            //scan_buf->noise =
            //scan_buf->level =
            //scan_buf->maxrate =
            if (pBSS->wWPALen != 0) {
                scan_buf->wpa_ie_len = pBSS->wWPALen;
                memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen);
            }
            if (pBSS->wRSNLen != 0) {
                scan_buf->rsn_ie_len = pBSS->wRSNLen;
                memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
            }
            scan_buf = (struct viawget_scan_result *)((unsigned char *)scan_buf + sizeof(struct viawget_scan_result));
            jj ++;
        }
    }

    if (jj < count)
        count = jj;

    if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) {
		ret = -EFAULT;
	};
	param->u.scan_results.scan_count = count;
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)

    kfree(pBuf);
    return ret;
}



/*
 * Description:
 *      set associate with AP
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      param     -
 *  Out:
 *
 * Return Value:
 *
 */

static int wpa_set_associate(PSDevice pDevice,
				     struct viawget_wpa_param *param)
{
    PSMgmtObject    pMgmt = pDevice->pMgmt;
    PWLAN_IE_SSID   pItemSSID;
    unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    unsigned char abyWPAIE[64];
    int ret = 0;
    bool bWepEnabled=false;

	// set key type & algorithm
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);


	if (param->u.wpa_associate.wpa_ie &&
	    copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
	    return -EINVAL;

	if (param->u.wpa_associate.mode == 1)
	    pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
	else
	    pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
    // set ssid
	memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
    pItemSSID->byElementID = WLAN_EID_SSID;
	pItemSSID->len = param->u.wpa_associate.ssid_len;
	memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len);
	// set bssid
    if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0)
        memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6);
else
{
   bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID);
}

    if (param->u.wpa_associate.wpa_ie_len == 0) {
	    if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY)
            pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
	    else
            pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
	} else if (abyWPAIE[0] == RSN_INFO_ELEM) {
		if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
			pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
		else
			pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
	} else {
		if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE)
			pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
		else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
		    pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
		else
		    pMgmt->eAuthenMode = WMAC_AUTH_WPA;
	}

	switch (param->u.wpa_associate.pairwise_suite) {
	case CIPHER_CCMP:
		pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
		break;
	case CIPHER_TKIP:
		pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
		break;
	case CIPHER_WEP40:
	case CIPHER_WEP104:
		pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
		bWepEnabled=true;
		break;
	case CIPHER_NONE:
		if (param->u.wpa_associate.group_suite == CIPHER_CCMP)
			pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
		else
			pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
		break;
	default:
		pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
	};

//DavidWang add for WPA_supplicant support open/share mode

      if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) {
            pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
            //pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
            pMgmt->bShareKeyAlgorithm = true;
             }
     else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) {
          if(!bWepEnabled)  pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
	else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
            //pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
            //pMgmt->bShareKeyAlgorithm = false; //20080717-06,<Modify> by chester//Fix Open mode, WEP encrytion
           }
//mike save old encryption status
	pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus;

    if (pDevice->eEncryptionStatus !=  Ndis802_11EncryptionDisabled)
        pDevice->bEncryptionEnable = true;
    else
        pDevice->bEncryptionEnable = false;
if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
      ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled==true))) )  //DavidWang  //20080717-06,<Modify> by chester//Not to initial WEP
    KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
    spin_lock_irq(&pDevice->lock);
    pDevice->bLinkPass = false;
    memset(pMgmt->abyCurrBSSID, 0, 6);
    pMgmt->eCurrState = WMAC_STATE_IDLE;
    netif_stop_queue(pDevice->dev);
	//20080701-02,<Add> by Mike Liu
/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/
{
   PKnownBSS       pCurr = NULL;
    pCurr = BSSpSearchBSSList(pDevice,
                              pMgmt->abyDesireBSSID,
                              pMgmt->abyDesireSSID,
                              pMgmt->eConfigPHYMode
                              );

    if (pCurr == NULL){
    printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
    bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
  };
}
/****************************************************************/
    bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL);
    spin_unlock_irq(&pDevice->lock);

    return ret;
}


/*
 * Description:
 *      wpa_ioctl main function supported for wpa supplicant
 *
 * Parameters:
 *  In:
 *      pDevice   -
 *      iw_point  -
 *  Out:
 *
 * Return Value:
 *
 */

int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
{
	struct viawget_wpa_param *param;
	int ret = 0;
	int wpa_ioctl = 0;

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

	param = kmalloc((int)p->length, (int)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_SET_WPA:
        ret = wpa_set_wpa(pDevice, param);
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
		break;

	case VIAWGET_SET_KEY:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
	    spin_lock_irq(&pDevice->lock);
        ret = wpa_set_keys(pDevice, param, false);
        spin_unlock_irq(&pDevice->lock);
		break;

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

	case VIAWGET_GET_SCAN:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
        ret = wpa_get_scan(pDevice, param);
		wpa_ioctl = 1;
		break;

	case VIAWGET_GET_SSID:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
        ret = wpa_get_ssid(pDevice, param);
		wpa_ioctl = 1;
		break;

	case VIAWGET_GET_BSSID:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
        ret = wpa_get_bssid(pDevice, param);
		wpa_ioctl = 1;
		break;

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

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

	case VIAWGET_SET_DROP_UNENCRYPT:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
		break;

    case VIAWGET_SET_DEAUTHENTICATE:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
		break;

	default:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
		       param->cmd);
		return -EOPNOTSUPP;
		break;
	}

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

out:
	if (param != NULL)
		kfree(param);

	return ret;
}

