Staging: vt665x: Text janitor in prep for driver merge, part 2
[linux-2.6/mini2440.git] / drivers / staging / vt6655 / wpactl.c
blob460182c74a3e1549ca4e3973eebe7c693fea91bf
1 /*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * File: wpactl.c
22 * Purpose: handle wpa supplicant ioctl input/out functions
24 * Author: Lyndon Chen
26 * Date: Oct. 20, 2003
28 * Functions:
30 * Revision History:
35 #if !defined(__WPACTL_H__)
36 #include "wpactl.h"
37 #endif
38 #if !defined(__KEY_H__)
39 #include "key.h"
40 #endif
41 #if !defined(__MAC_H__)
42 #include "mac.h"
43 #endif
44 #if !defined(__DEVICE_H__)
45 #include "device.h"
46 #endif
47 #if !defined(__WMGR_H__)
48 #include "wmgr.h"
49 #endif
50 #if !defined(__IOCMD_H__)
51 #include "iocmd.h"
52 #endif
53 #if !defined(__IOWPA_H__)
54 #include "iowpa.h"
55 #endif
56 //2008-0717-05, <Add> by James
57 #if !defined(__RF_H__)
58 #include "rf.h"
59 #endif
61 /*--------------------- Static Definitions -------------------------*/
63 #define VIAWGET_WPA_MAX_BUF_SIZE 1024
67 static const int frequency_list[] = {
68 2412, 2417, 2422, 2427, 2432, 2437, 2442,
69 2447, 2452, 2457, 2462, 2467, 2472, 2484
71 /*--------------------- Static Classes ----------------------------*/
73 /*--------------------- Static Variables --------------------------*/
74 //static int msglevel =MSG_LEVEL_DEBUG;
75 static int msglevel =MSG_LEVEL_INFO;
77 /*--------------------- Static Functions --------------------------*/
82 /*--------------------- Export Variables --------------------------*/
83 static void wpadev_setup(struct net_device *dev)
85 dev->type = ARPHRD_IEEE80211;
86 dev->hard_header_len = ETH_HLEN;
87 dev->mtu = 2048;
88 dev->addr_len = ETH_ALEN;
89 dev->tx_queue_len = 1000;
91 memset(dev->broadcast,0xFF, ETH_ALEN);
93 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
97 * Description:
98 * register netdev for wpa supplicant deamon
100 * Parameters:
101 * In:
102 * pDevice -
103 * enable -
104 * Out:
106 * Return Value:
110 static int wpa_init_wpadev(PSDevice pDevice)
112 PSDevice wpadev_priv;
113 struct net_device *dev = pDevice->dev;
114 int ret=0;
116 pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup);
117 if (pDevice->wpadev == NULL)
118 return -ENOMEM;
120 wpadev_priv = netdev_priv(pDevice->wpadev);
121 *wpadev_priv = *pDevice;
122 memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, U_ETHER_ADDR_LEN);
123 pDevice->wpadev->base_addr = dev->base_addr;
124 pDevice->wpadev->irq = dev->irq;
125 pDevice->wpadev->mem_start = dev->mem_start;
126 pDevice->wpadev->mem_end = dev->mem_end;
127 ret = register_netdev(pDevice->wpadev);
128 if (ret) {
129 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n",
130 dev->name);
131 free_netdev(pDevice->wpadev);
132 return -1;
135 if (pDevice->skb == NULL) {
136 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
137 if (pDevice->skb == NULL)
138 return -ENOMEM;
141 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
142 dev->name, pDevice->wpadev->name);
144 return 0;
149 * Description:
150 * unregister net_device (wpadev)
152 * Parameters:
153 * In:
154 * pDevice -
155 * Out:
157 * Return Value:
161 static int wpa_release_wpadev(PSDevice pDevice)
163 if (pDevice->skb) {
164 dev_kfree_skb(pDevice->skb);
165 pDevice->skb = NULL;
168 if (pDevice->wpadev) {
169 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
170 pDevice->dev->name, pDevice->wpadev->name);
171 unregister_netdev(pDevice->wpadev);
172 free_netdev(pDevice->wpadev);
173 pDevice->wpadev = NULL;
176 return 0;
184 * Description:
185 * Set enable/disable dev for wpa supplicant deamon
187 * Parameters:
188 * In:
189 * pDevice -
190 * val -
191 * Out:
193 * Return Value:
197 int wpa_set_wpadev(PSDevice pDevice, int val)
199 if (val)
200 return wpa_init_wpadev(pDevice);
201 else
202 return wpa_release_wpadev(pDevice);
207 * Description:
208 * Set WPA algorithm & keys
210 * Parameters:
211 * In:
212 * pDevice -
213 * param -
214 * Out:
216 * Return Value:
220 int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL fcpfkernel)
222 struct viawget_wpa_param *param=ctx;
223 PSMgmtObject pMgmt = pDevice->pMgmt;
224 DWORD dwKeyIndex = 0;
225 BYTE abyKey[MAX_KEY_LEN];
226 BYTE abySeq[MAX_KEY_LEN];
227 QWORD KeyRSC;
228 // NDIS_802_11_KEY_RSC KeyRSC;
229 BYTE byKeyDecMode = KEY_CTL_WEP;
230 int ret = 0;
231 int uu, ii;
234 if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
235 return -EINVAL;
237 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name);
238 if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
239 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
240 pDevice->bEncryptionEnable = FALSE;
241 pDevice->byKeyIndex = 0;
242 pDevice->bTransmitKey = FALSE;
243 KeyvRemoveAllWEPKey(&(pDevice->sKey), pDevice->PortOffset);
244 for (uu=0; uu<MAX_KEY_TABLE; uu++) {
245 MACvDisableKeyEntry(pDevice->PortOffset, uu);
247 return ret;
250 //spin_unlock_irq(&pDevice->lock);
251 if(param->u.wpa_key.key && fcpfkernel) {
252 memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
254 else {
255 spin_unlock_irq(&pDevice->lock);
256 if (param->u.wpa_key.key &&
257 copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) {
258 spin_lock_irq(&pDevice->lock);
259 return -EINVAL;
261 spin_lock_irq(&pDevice->lock);
264 dwKeyIndex = (DWORD)(param->u.wpa_key.key_index);
266 if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
267 if (dwKeyIndex > 3) {
268 return -EINVAL;
270 else {
271 if (param->u.wpa_key.set_tx) {
272 pDevice->byKeyIndex = (BYTE)dwKeyIndex;
273 pDevice->bTransmitKey = TRUE;
274 dwKeyIndex |= (1 << 31);
276 KeybSetDefaultKey(&(pDevice->sKey),
277 dwKeyIndex & ~(BIT30 | USE_KEYRSC),
278 param->u.wpa_key.key_len,
279 NULL,
280 abyKey,
281 KEY_CTL_WEP,
282 pDevice->PortOffset,
283 pDevice->byLocalID);
286 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
287 pDevice->bEncryptionEnable = TRUE;
288 return ret;
291 //spin_unlock_irq(&pDevice->lock);
292 if(param->u.wpa_key.seq && fcpfkernel) {
293 memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
295 else {
296 spin_unlock_irq(&pDevice->lock);
297 if (param->u.wpa_key.seq &&
298 copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) {
299 spin_lock_irq(&pDevice->lock);
300 return -EINVAL;
302 spin_lock_irq(&pDevice->lock);
305 if (param->u.wpa_key.seq_len > 0) {
306 for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
307 if (ii < 4)
308 LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8));
309 else
310 HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8));
311 //KeyRSC |= (abySeq[ii] << (ii * 8));
313 dwKeyIndex |= 1 << 29;
316 if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
317 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n");
318 return -EINVAL;
321 if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) {
322 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
325 if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
326 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
329 if (param->u.wpa_key.set_tx)
330 dwKeyIndex |= (1 << 31);
333 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
334 byKeyDecMode = KEY_CTL_CCMP;
335 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
336 byKeyDecMode = KEY_CTL_TKIP;
337 else
338 byKeyDecMode = KEY_CTL_WEP;
340 // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
341 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
342 if (param->u.wpa_key.key_len == MAX_KEY_LEN)
343 byKeyDecMode = KEY_CTL_TKIP;
344 else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
345 byKeyDecMode = KEY_CTL_WEP;
346 else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
347 byKeyDecMode = KEY_CTL_WEP;
348 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
349 if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
350 byKeyDecMode = KEY_CTL_WEP;
351 else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
352 byKeyDecMode = KEY_CTL_WEP;
355 // Check TKIP key length
356 if ((byKeyDecMode == KEY_CTL_TKIP) &&
357 (param->u.wpa_key.key_len != MAX_KEY_LEN)) {
358 // TKIP Key must be 256 bits
359 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n"));
360 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n");
361 return -EINVAL;
363 // Check AES key length
364 if ((byKeyDecMode == KEY_CTL_CCMP) &&
365 (param->u.wpa_key.key_len != AES_KEY_LEN)) {
366 // AES Key must be 128 bits
367 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - AES Key must be 128 bits\n"));
368 return -EINVAL;
371 // spin_lock_irq(&pDevice->lock);
372 if (IS_BROADCAST_ADDRESS(&param->addr[0]) || (param->addr == NULL)) {
373 // If IS_BROADCAST_ADDRESS, set the key as every key entry's group key.
374 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
376 if ((KeybSetAllGroupKey(&(pDevice->sKey),
377 dwKeyIndex,
378 param->u.wpa_key.key_len,
379 (PQWORD) &(KeyRSC),
380 (PBYTE)abyKey,
381 byKeyDecMode,
382 pDevice->PortOffset,
383 pDevice->byLocalID) == TRUE) &&
384 (KeybSetDefaultKey(&(pDevice->sKey),
385 dwKeyIndex,
386 param->u.wpa_key.key_len,
387 (PQWORD) &(KeyRSC),
388 (PBYTE)abyKey,
389 byKeyDecMode,
390 pDevice->PortOffset,
391 pDevice->byLocalID) == TRUE) ) {
392 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
394 } else {
395 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n"));
396 // spin_unlock_irq(&pDevice->lock);
397 return -EINVAL;
400 } else {
401 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
402 // BSSID not 0xffffffffffff
403 // Pairwise Key can't be WEP
404 if (byKeyDecMode == KEY_CTL_WEP) {
405 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
406 //spin_unlock_irq(&pDevice->lock);
407 return -EINVAL;
410 dwKeyIndex |= (1 << 30); // set pairwise key
411 if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
412 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
413 //spin_unlock_irq(&pDevice->lock);
414 return -EINVAL;
416 if (KeybSetKey(&(pDevice->sKey),
417 &param->addr[0],
418 dwKeyIndex,
419 param->u.wpa_key.key_len,
420 (PQWORD) &(KeyRSC),
421 (PBYTE)abyKey,
422 byKeyDecMode,
423 pDevice->PortOffset,
424 pDevice->byLocalID) == TRUE) {
425 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
427 } else {
428 // Key Table Full
429 if (IS_ETH_ADDRESS_EQUAL(&param->addr[0], pDevice->abyBSSID)) {
430 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
431 //spin_unlock_irq(&pDevice->lock);
432 return -EINVAL;
434 } else {
435 // Save Key and configure just before associate/reassociate to BSSID
436 // we do not implement now
437 //spin_unlock_irq(&pDevice->lock);
438 return -EINVAL;
441 } // BSSID not 0xffffffffffff
442 if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
443 pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index;
444 pDevice->bTransmitKey = TRUE;
446 pDevice->bEncryptionEnable = TRUE;
447 //spin_unlock_irq(&pDevice->lock);
450 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
451 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0],
452 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1],
453 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2],
454 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3],
455 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4]
459 return ret;
465 * Description:
466 * enable wpa auth & mode
468 * Parameters:
469 * In:
470 * pDevice -
471 * param -
472 * Out:
474 * Return Value:
478 static int wpa_set_wpa(PSDevice pDevice,
479 struct viawget_wpa_param *param)
482 PSMgmtObject pMgmt = pDevice->pMgmt;
483 int ret = 0;
485 pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
486 pMgmt->bShareKeyAlgorithm = FALSE;
488 return ret;
495 * Description:
496 * set disassociate
498 * Parameters:
499 * In:
500 * pDevice -
501 * param -
502 * Out:
504 * Return Value:
508 static int wpa_set_disassociate(PSDevice pDevice,
509 struct viawget_wpa_param *param)
511 PSMgmtObject pMgmt = pDevice->pMgmt;
512 int ret = 0;
514 spin_lock_irq(&pDevice->lock);
515 if (pDevice->bLinkPass) {
516 if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6))
517 bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
519 spin_unlock_irq(&pDevice->lock);
521 return ret;
527 * Description:
528 * enable scan process
530 * Parameters:
531 * In:
532 * pDevice -
533 * param -
534 * Out:
536 * Return Value:
540 static int wpa_set_scan(PSDevice pDevice,
541 struct viawget_wpa_param *param)
543 int ret = 0;
545 spin_lock_irq(&pDevice->lock);
546 BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
547 bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
548 spin_unlock_irq(&pDevice->lock);
550 return ret;
556 * Description:
557 * get bssid
559 * Parameters:
560 * In:
561 * pDevice -
562 * param -
563 * Out:
565 * Return Value:
569 static int wpa_get_bssid(PSDevice pDevice,
570 struct viawget_wpa_param *param)
572 PSMgmtObject pMgmt = pDevice->pMgmt;
573 int ret = 0;
575 memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6);
577 return ret;
583 * Description:
584 * get bssid
586 * Parameters:
587 * In:
588 * pDevice -
589 * param -
590 * Out:
592 * Return Value:
596 static int wpa_get_ssid(PSDevice pDevice,
597 struct viawget_wpa_param *param)
599 PSMgmtObject pMgmt = pDevice->pMgmt;
600 PWLAN_IE_SSID pItemSSID;
601 int ret = 0;
603 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
605 memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len);
606 param->u.wpa_associate.ssid_len = pItemSSID->len;
608 return ret;
614 * Description:
615 * get scan results
617 * Parameters:
618 * In:
619 * pDevice -
620 * param -
621 * Out:
623 * Return Value:
627 static int wpa_get_scan(PSDevice pDevice,
628 struct viawget_wpa_param *param)
630 struct viawget_scan_result *scan_buf;
631 PSMgmtObject pMgmt = pDevice->pMgmt;
632 PWLAN_IE_SSID pItemSSID;
633 PKnownBSS pBSS;
634 PBYTE pBuf;
635 int ret = 0;
636 u16 count = 0;
637 u16 ii, jj;
638 #if 1
640 PBYTE ptempBSS;
644 ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC);
646 if (ptempBSS == NULL) {
648 printk("bubble sort kmalloc memory fail@@@\n");
650 ret = -ENOMEM;
652 return ret;
656 for (ii = 0; ii < MAX_BSS_NUM; ii++) {
658 for(jj=0;jj<MAX_BSS_NUM-ii-1;jj++) {
660 if((pMgmt->sBSSList[jj].bActive!=TRUE) ||
662 ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=FALSE))) {
664 memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS));
666 memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS));
668 memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS));
676 kfree(ptempBSS);
678 // printk("bubble sort result:\n");
680 //for (ii = 0; ii < MAX_BSS_NUM; ii++)
682 // printk("%d [%s]:RSSI=%d\n",ii,((PWLAN_IE_SSID)(pMgmt->sBSSList[ii].abySSID))->abySSID,
684 // pMgmt->sBSSList[ii].uRSSI);
686 #endif
688 //******mike:bubble sort by stronger RSSI*****//
693 count = 0;
694 pBSS = &(pMgmt->sBSSList[0]);
695 for (ii = 0; ii < MAX_BSS_NUM; ii++) {
696 pBSS = &(pMgmt->sBSSList[ii]);
697 if (!pBSS->bActive)
698 continue;
699 count++;
702 pBuf = kmalloc(sizeof(struct viawget_scan_result) * count, (int)GFP_ATOMIC);
704 if (pBuf == NULL) {
705 ret = -ENOMEM;
706 return ret;
708 memset(pBuf, 0, sizeof(struct viawget_scan_result) * count);
709 scan_buf = (struct viawget_scan_result *)pBuf;
710 pBSS = &(pMgmt->sBSSList[0]);
711 for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) {
712 pBSS = &(pMgmt->sBSSList[ii]);
713 if (pBSS->bActive) {
714 if (jj >= count)
715 break;
716 memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN);
717 pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
718 memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len);
719 scan_buf->ssid_len = pItemSSID->len;
720 scan_buf->freq = frequency_list[pBSS->uChannel-1];
721 scan_buf->caps = pBSS->wCapInfo;
722 //scan_buf->caps = pBSS->wCapInfo;
723 //scan_buf->qual =
724 //scan_buf->noise =
725 //scan_buf->level =
726 //scan_buf->maxrate =
727 if (pBSS->wWPALen != 0) {
728 scan_buf->wpa_ie_len = pBSS->wWPALen;
729 memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen);
731 if (pBSS->wRSNLen != 0) {
732 scan_buf->rsn_ie_len = pBSS->wRSNLen;
733 memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
735 scan_buf = (struct viawget_scan_result *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result));
736 jj ++;
740 if (jj < count)
741 count = jj;
743 if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) {
744 ret = -EFAULT;
746 param->u.scan_results.scan_count = count;
747 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
749 kfree(pBuf);
750 return ret;
756 * Description:
757 * set associate with AP
759 * Parameters:
760 * In:
761 * pDevice -
762 * param -
763 * Out:
765 * Return Value:
769 static int wpa_set_associate(PSDevice pDevice,
770 struct viawget_wpa_param *param)
772 PSMgmtObject pMgmt = pDevice->pMgmt;
773 PWLAN_IE_SSID pItemSSID;
774 BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
775 BYTE abyWPAIE[64];
776 int ret = 0;
777 BOOL bWepEnabled=FALSE;
779 // set key type & algorithm
780 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
781 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
782 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
783 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
784 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
785 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
788 if (param->u.wpa_associate.wpa_ie &&
789 copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
790 return -EINVAL;
792 if (param->u.wpa_associate.mode == 1)
793 pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
794 else
795 pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
796 // set ssid
797 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
798 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
799 pItemSSID->byElementID = WLAN_EID_SSID;
800 pItemSSID->len = param->u.wpa_associate.ssid_len;
801 memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len);
802 // set bssid
803 if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0)
804 memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6);
805 else
807 bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID);
810 if (param->u.wpa_associate.wpa_ie_len == 0) {
811 if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY)
812 pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
813 else
814 pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
815 } else if (abyWPAIE[0] == RSN_INFO_ELEM) {
816 if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
817 pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
818 else
819 pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
820 } else {
821 if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE)
822 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
823 else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
824 pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
825 else
826 pMgmt->eAuthenMode = WMAC_AUTH_WPA;
829 switch (param->u.wpa_associate.pairwise_suite) {
830 case CIPHER_CCMP:
831 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
832 break;
833 case CIPHER_TKIP:
834 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
835 break;
836 case CIPHER_WEP40:
837 case CIPHER_WEP104:
838 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
839 bWepEnabled=TRUE;
840 break;
841 case CIPHER_NONE:
842 if (param->u.wpa_associate.group_suite == CIPHER_CCMP)
843 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
844 else
845 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
846 break;
847 default:
848 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
851 //DavidWang add for WPA_supplicant support open/share mode
853 if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) {
854 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
855 //pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
856 pMgmt->bShareKeyAlgorithm = TRUE;
858 else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) {
859 if(!bWepEnabled) pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
860 else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
861 //pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
862 //pMgmt->bShareKeyAlgorithm = FALSE; //20080717-06,<Modify> by chester//Fix Open mode, WEP encrytion
864 //mike save old encryption status
865 pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus;
867 if (pDevice->eEncryptionStatus != Ndis802_11EncryptionDisabled)
868 pDevice->bEncryptionEnable = TRUE;
869 else
870 pDevice->bEncryptionEnable = FALSE;
871 if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
872 ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled==TRUE))) ) //DavidWang //20080717-06,<Modify> by chester//Not to initial WEP
873 KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
874 spin_lock_irq(&pDevice->lock);
875 pDevice->bLinkPass = FALSE;
876 memset(pMgmt->abyCurrBSSID, 0, 6);
877 pMgmt->eCurrState = WMAC_STATE_IDLE;
878 netif_stop_queue(pDevice->dev);
879 //20080701-02,<Add> by Mike Liu
880 /*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/
882 PKnownBSS pCurr = NULL;
883 pCurr = BSSpSearchBSSList(pDevice,
884 pMgmt->abyDesireBSSID,
885 pMgmt->abyDesireSSID,
886 pMgmt->eConfigPHYMode
889 if (pCurr == NULL){
890 printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
891 bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
894 /****************************************************************/
895 bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
896 spin_unlock_irq(&pDevice->lock);
898 return ret;
903 * Description:
904 * wpa_ioctl main function supported for wpa supplicant
906 * Parameters:
907 * In:
908 * pDevice -
909 * iw_point -
910 * Out:
912 * Return Value:
916 int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
918 struct viawget_wpa_param *param;
919 int ret = 0;
920 int wpa_ioctl = 0;
922 if (p->length < sizeof(struct viawget_wpa_param) ||
923 p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
924 return -EINVAL;
926 param = (struct viawget_wpa_param *) kmalloc((int)p->length, (int)GFP_KERNEL);
927 if (param == NULL)
928 return -ENOMEM;
930 if (copy_from_user(param, p->pointer, p->length)) {
931 ret = -EFAULT;
932 goto out;
935 switch (param->cmd) {
936 case VIAWGET_SET_WPA:
937 ret = wpa_set_wpa(pDevice, param);
938 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
939 break;
941 case VIAWGET_SET_KEY:
942 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
943 spin_lock_irq(&pDevice->lock);
944 ret = wpa_set_keys(pDevice, param, FALSE);
945 spin_unlock_irq(&pDevice->lock);
946 break;
948 case VIAWGET_SET_SCAN:
949 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
950 ret = wpa_set_scan(pDevice, param);
951 break;
953 case VIAWGET_GET_SCAN:
954 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
955 ret = wpa_get_scan(pDevice, param);
956 wpa_ioctl = 1;
957 break;
959 case VIAWGET_GET_SSID:
960 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
961 ret = wpa_get_ssid(pDevice, param);
962 wpa_ioctl = 1;
963 break;
965 case VIAWGET_GET_BSSID:
966 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
967 ret = wpa_get_bssid(pDevice, param);
968 wpa_ioctl = 1;
969 break;
971 case VIAWGET_SET_ASSOCIATE:
972 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
973 ret = wpa_set_associate(pDevice, param);
974 break;
976 case VIAWGET_SET_DISASSOCIATE:
977 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
978 ret = wpa_set_disassociate(pDevice, param);
979 break;
981 case VIAWGET_SET_DROP_UNENCRYPT:
982 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
983 break;
985 case VIAWGET_SET_DEAUTHENTICATE:
986 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
987 break;
989 default:
990 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
991 param->cmd);
992 return -EOPNOTSUPP;
993 break;
996 if ((ret == 0) && wpa_ioctl) {
997 if (copy_to_user(p->pointer, param, p->length)) {
998 ret = -EFAULT;
999 goto out;
1003 out:
1004 if (param != NULL)
1005 kfree(param);
1007 return ret;