1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
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.
9  *
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.
14  *
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.
18  *
19  *
20  * File: wpactl.c
21  *
22  * Purpose: handle wpa supplicant ioctl input/out functions
23  *
24  * Author: Lyndon Chen
25  *
26  * Date: Oct. 20, 2003
27  *
28  * Functions:
29  *
30  * Revision History:
31  *
32  */
33 
34 #include "wpactl.h"
35 #include "key.h"
36 #include "mac.h"
37 #include "device.h"
38 #include "wmgr.h"
39 #include "iocmd.h"
40 #include "iowpa.h"
41 #include "rf.h"
42 
43 /*---------------------  Static Definitions -------------------------*/
44 
45 #define VIAWGET_WPA_MAX_BUF_SIZE 1024
46 
47 
48 
49 static const int frequency_list[] = {
50 	2412, 2417, 2422, 2427, 2432, 2437, 2442,
51 	2447, 2452, 2457, 2462, 2467, 2472, 2484
52 };
53 /*---------------------  Static Classes  ----------------------------*/
54 
55 /*---------------------  Static Variables  --------------------------*/
56 //static int          msglevel                =MSG_LEVEL_DEBUG;
57 static int          msglevel                =MSG_LEVEL_INFO;
58 
59 /*---------------------  Static Functions  --------------------------*/
60 
61 
62 
63 
64 /*---------------------  Export Variables  --------------------------*/
wpadev_setup(struct net_device * dev)65 static void wpadev_setup(struct net_device *dev)
66 {
67 	dev->type               = ARPHRD_IEEE80211;
68 	dev->hard_header_len    = ETH_HLEN;
69 	dev->mtu                = 2048;
70 	dev->addr_len           = ETH_ALEN;
71 	dev->tx_queue_len       = 1000;
72 
73 	memset(dev->broadcast,0xFF, ETH_ALEN);
74 
75 	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
76 }
77 
78 /*
79  * Description:
80  *      register netdev for wpa supplicant deamon
81  *
82  * Parameters:
83  *  In:
84  *      pDevice             -
85  *      enable              -
86  *  Out:
87  *
88  * Return Value:
89  *
90  */
91 
wpa_init_wpadev(PSDevice pDevice)92 static int wpa_init_wpadev(PSDevice pDevice)
93 {
94     PSDevice wpadev_priv;
95 	struct net_device *dev = pDevice->dev;
96          int ret=0;
97 
98 	pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup);
99 	if (pDevice->wpadev == NULL)
100 		return -ENOMEM;
101 
102     wpadev_priv = netdev_priv(pDevice->wpadev);
103     *wpadev_priv = *pDevice;
104 	memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, ETH_ALEN);
105          pDevice->wpadev->base_addr = dev->base_addr;
106 	pDevice->wpadev->irq = dev->irq;
107 	pDevice->wpadev->mem_start = dev->mem_start;
108 	pDevice->wpadev->mem_end = dev->mem_end;
109 	ret = register_netdev(pDevice->wpadev);
110 	if (ret) {
111 		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n",
112 		       dev->name);
113 		free_netdev(pDevice->wpadev);
114 		return -1;
115 	}
116 
117 	if (pDevice->skb == NULL) {
118         pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
119         if (pDevice->skb == NULL)
120 		    return -ENOMEM;
121     }
122 
123     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
124 	       dev->name, pDevice->wpadev->name);
125 
126 	return 0;
127 }
128 
129 
130 /*
131  * Description:
132  *      unregister net_device (wpadev)
133  *
134  * Parameters:
135  *  In:
136  *      pDevice             -
137  *  Out:
138  *
139  * Return Value:
140  *
141  */
142 
wpa_release_wpadev(PSDevice pDevice)143 static int wpa_release_wpadev(PSDevice pDevice)
144 {
145     if (pDevice->skb) {
146         dev_kfree_skb(pDevice->skb);
147         pDevice->skb = NULL;
148     }
149 
150     if (pDevice->wpadev) {
151         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
152 	       pDevice->dev->name, pDevice->wpadev->name);
153 	unregister_netdev(pDevice->wpadev);
154 	free_netdev(pDevice->wpadev);
155          pDevice->wpadev = NULL;
156     }
157 
158 	return 0;
159 }
160 
161 
162 
163 
164 
165 /*
166  * Description:
167  *      Set enable/disable dev for wpa supplicant deamon
168  *
169  * Parameters:
170  *  In:
171  *      pDevice             -
172  *      val                 -
173  *  Out:
174  *
175  * Return Value:
176  *
177  */
178 
wpa_set_wpadev(PSDevice pDevice,int val)179 int wpa_set_wpadev(PSDevice pDevice, int val)
180 {
181 	if (val)
182 		return wpa_init_wpadev(pDevice);
183 	else
184 		return wpa_release_wpadev(pDevice);
185 }
186 
187 
188 /*
189  * Description:
190  *      Set WPA algorithm & keys
191  *
192  * Parameters:
193  *  In:
194  *      pDevice -
195  *      param -
196  *  Out:
197  *
198  * Return Value:
199  *
200  */
201 
wpa_set_keys(PSDevice pDevice,void * ctx,bool fcpfkernel)202  int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel)
203 {
204     struct viawget_wpa_param *param=ctx;
205     PSMgmtObject pMgmt = pDevice->pMgmt;
206     unsigned long dwKeyIndex = 0;
207     unsigned char abyKey[MAX_KEY_LEN];
208     unsigned char abySeq[MAX_KEY_LEN];
209     QWORD   KeyRSC;
210 //    NDIS_802_11_KEY_RSC KeyRSC;
211     unsigned char byKeyDecMode = KEY_CTL_WEP;
212 	int ret = 0;
213 	int uu, ii;
214 
215 
216 	if (param->u.wpa_key.alg_name > WPA_ALG_CCMP ||
217 			param->u.wpa_key.key_len >= MAX_KEY_LEN ||
218 			param->u.wpa_key.seq_len >= MAX_KEY_LEN)
219 		return -EINVAL;
220 
221     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name);
222 	if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
223         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
224         pDevice->bEncryptionEnable = false;
225         pDevice->byKeyIndex = 0;
226         pDevice->bTransmitKey = false;
227         KeyvRemoveAllWEPKey(&(pDevice->sKey), pDevice->PortOffset);
228         for (uu=0; uu<MAX_KEY_TABLE; uu++) {
229             MACvDisableKeyEntry(pDevice->PortOffset, uu);
230         }
231         return ret;
232     }
233 
234     //spin_unlock_irq(&pDevice->lock);
235     if(param->u.wpa_key.key && fcpfkernel) {
236        memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
237      }
238     else {
239 	spin_unlock_irq(&pDevice->lock);
240 	if (param->u.wpa_key.key &&
241 	    copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) {
242 	    spin_lock_irq(&pDevice->lock);
243 	    return -EINVAL;
244     	}
245 spin_lock_irq(&pDevice->lock);
246     	}
247 
248     dwKeyIndex = (unsigned long)(param->u.wpa_key.key_index);
249 
250 	if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
251         if (dwKeyIndex > 3) {
252             return -EINVAL;
253         }
254         else {
255             if (param->u.wpa_key.set_tx) {
256                 pDevice->byKeyIndex = (unsigned char)dwKeyIndex;
257                 pDevice->bTransmitKey = true;
258 		        dwKeyIndex |= (1 << 31);
259             }
260             KeybSetDefaultKey(&(pDevice->sKey),
261                                 dwKeyIndex & ~(BIT30 | USE_KEYRSC),
262                                 param->u.wpa_key.key_len,
263                                 NULL,
264                                 abyKey,
265                                 KEY_CTL_WEP,
266                                 pDevice->PortOffset,
267                                 pDevice->byLocalID);
268 
269         }
270         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
271         pDevice->bEncryptionEnable = true;
272         return ret;
273 	}
274 
275 	    //spin_unlock_irq(&pDevice->lock);
276         if(param->u.wpa_key.seq && fcpfkernel) {
277            memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
278         	}
279        else {
280 	   	spin_unlock_irq(&pDevice->lock);
281 	if (param->u.wpa_key.seq &&
282 	    copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) {
283 	    spin_lock_irq(&pDevice->lock);
284 	    return -EINVAL;
285        	}
286 spin_lock_irq(&pDevice->lock);
287 }
288 
289 	if (param->u.wpa_key.seq_len > 0) {
290 		for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
291 		     if (ii < 4)
292 			    LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8));
293 			 else
294 			    HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8));
295 	         //KeyRSC |= (abySeq[ii] << (ii * 8));
296 		}
297 		dwKeyIndex |= 1 << 29;
298 	}
299 
300     if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
301         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return  dwKeyIndex > 3\n");
302         return -EINVAL;
303     }
304 
305 	if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) {
306         pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
307     }
308 
309 	if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
310         pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
311     }
312 
313 	if (param->u.wpa_key.set_tx)
314 		dwKeyIndex |= (1 << 31);
315 
316 
317     if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
318         byKeyDecMode = KEY_CTL_CCMP;
319     else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
320         byKeyDecMode = KEY_CTL_TKIP;
321     else
322         byKeyDecMode = KEY_CTL_WEP;
323 
324     // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
325     if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
326         if (param->u.wpa_key.key_len == MAX_KEY_LEN)
327             byKeyDecMode = KEY_CTL_TKIP;
328         else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
329             byKeyDecMode = KEY_CTL_WEP;
330         else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
331             byKeyDecMode = KEY_CTL_WEP;
332     } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
333         if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
334             byKeyDecMode = KEY_CTL_WEP;
335         else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
336             byKeyDecMode = KEY_CTL_WEP;
337     }
338 
339     // Check TKIP key length
340     if ((byKeyDecMode == KEY_CTL_TKIP) &&
341         (param->u.wpa_key.key_len != MAX_KEY_LEN)) {
342         // TKIP Key must be 256 bits
343         //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n"));
344         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n");
345         return -EINVAL;
346     }
347     // Check AES key length
348     if ((byKeyDecMode == KEY_CTL_CCMP) &&
349         (param->u.wpa_key.key_len != AES_KEY_LEN)) {
350         // AES Key must be 128 bits
351         //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - AES Key must be 128 bits\n"));
352         return -EINVAL;
353     }
354 
355    // spin_lock_irq(&pDevice->lock);
356     if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) {
357         // If is_broadcast_ether_addr, set the key as every key entry's group key.
358         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
359 
360         if ((KeybSetAllGroupKey(&(pDevice->sKey),
361                             dwKeyIndex,
362                             param->u.wpa_key.key_len,
363                             (PQWORD) &(KeyRSC),
364                             (unsigned char *)abyKey,
365                             byKeyDecMode,
366                             pDevice->PortOffset,
367                             pDevice->byLocalID) == true) &&
368             (KeybSetDefaultKey(&(pDevice->sKey),
369                             dwKeyIndex,
370                             param->u.wpa_key.key_len,
371                             (PQWORD) &(KeyRSC),
372                             (unsigned char *)abyKey,
373                             byKeyDecMode,
374                             pDevice->PortOffset,
375                             pDevice->byLocalID) == true) ) {
376              DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
377 
378         } else {
379             //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n"));
380            // spin_unlock_irq(&pDevice->lock);
381             return -EINVAL;
382         }
383 
384     } else {
385         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
386         // BSSID not 0xffffffffffff
387         // Pairwise Key can't be WEP
388         if (byKeyDecMode == KEY_CTL_WEP) {
389             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
390             //spin_unlock_irq(&pDevice->lock);
391             return -EINVAL;
392         }
393 
394         dwKeyIndex |= (1 << 30); // set pairwise key
395         if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
396             //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
397             //spin_unlock_irq(&pDevice->lock);
398             return -EINVAL;
399         }
400         if (KeybSetKey(&(pDevice->sKey),
401                        &param->addr[0],
402                        dwKeyIndex,
403                        param->u.wpa_key.key_len,
404                        (PQWORD) &(KeyRSC),
405                        (unsigned char *)abyKey,
406                         byKeyDecMode,
407                         pDevice->PortOffset,
408                         pDevice->byLocalID) == true) {
409             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
410 
411         } else {
412             // Key Table Full
413             if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
414                 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
415                 //spin_unlock_irq(&pDevice->lock);
416                 return -EINVAL;
417 
418             } else {
419                 // Save Key and configure just before associate/reassociate to BSSID
420                 // we do not implement now
421                 //spin_unlock_irq(&pDevice->lock);
422                 return -EINVAL;
423             }
424         }
425     } // BSSID not 0xffffffffffff
426     if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
427         pDevice->byKeyIndex = (unsigned char)param->u.wpa_key.key_index;
428         pDevice->bTransmitKey = true;
429     }
430     pDevice->bEncryptionEnable = true;
431     //spin_unlock_irq(&pDevice->lock);
432 
433 /*
434     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
435                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0],
436                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1],
437                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2],
438                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3],
439                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4]
440               );
441 */
442 
443 	return ret;
444 
445 }
446 
447 
448 /*
449  * Description:
450  *      enable wpa auth & mode
451  *
452  * Parameters:
453  *  In:
454  *      pDevice   -
455  *      param     -
456  *  Out:
457  *
458  * Return Value:
459  *
460  */
461 
wpa_set_wpa(PSDevice pDevice,struct viawget_wpa_param * param)462 static int wpa_set_wpa(PSDevice pDevice,
463 				     struct viawget_wpa_param *param)
464 {
465 
466     PSMgmtObject    pMgmt = pDevice->pMgmt;
467 	int ret = 0;
468 
469     pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
470     pMgmt->bShareKeyAlgorithm = false;
471 
472     return ret;
473 }
474 
475 
476 
477 
478  /*
479  * Description:
480  *      set disassociate
481  *
482  * Parameters:
483  *  In:
484  *      pDevice   -
485  *      param     -
486  *  Out:
487  *
488  * Return Value:
489  *
490  */
491 
wpa_set_disassociate(PSDevice pDevice,struct viawget_wpa_param * param)492 static int wpa_set_disassociate(PSDevice pDevice,
493 				     struct viawget_wpa_param *param)
494 {
495     PSMgmtObject    pMgmt = pDevice->pMgmt;
496 	int ret = 0;
497 
498     spin_lock_irq(&pDevice->lock);
499     if (pDevice->bLinkPass) {
500         if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6))
501             bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
502     }
503     spin_unlock_irq(&pDevice->lock);
504 
505     return ret;
506 }
507 
508 
509 
510 /*
511  * Description:
512  *      enable scan process
513  *
514  * Parameters:
515  *  In:
516  *      pDevice   -
517  *      param     -
518  *  Out:
519  *
520  * Return Value:
521  *
522  */
523 
wpa_set_scan(PSDevice pDevice,struct viawget_wpa_param * param)524 static int wpa_set_scan(PSDevice pDevice,
525 				     struct viawget_wpa_param *param)
526 {
527 	int ret = 0;
528 
529     spin_lock_irq(&pDevice->lock);
530     BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
531     bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
532     spin_unlock_irq(&pDevice->lock);
533 
534     return ret;
535 }
536 
537 
538 
539 /*
540  * Description:
541  *      get bssid
542  *
543  * Parameters:
544  *  In:
545  *      pDevice   -
546  *      param     -
547  *  Out:
548  *
549  * Return Value:
550  *
551  */
552 
wpa_get_bssid(PSDevice pDevice,struct viawget_wpa_param * param)553 static int wpa_get_bssid(PSDevice pDevice,
554 				     struct viawget_wpa_param *param)
555 {
556     PSMgmtObject        pMgmt = pDevice->pMgmt;
557 	int ret = 0;
558 
559 	memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6);
560 
561     return ret;
562 
563 }
564 
565 
566 /*
567  * Description:
568  *      get bssid
569  *
570  * Parameters:
571  *  In:
572  *      pDevice   -
573  *      param     -
574  *  Out:
575  *
576  * Return Value:
577  *
578  */
579 
wpa_get_ssid(PSDevice pDevice,struct viawget_wpa_param * param)580 static int wpa_get_ssid(PSDevice pDevice,
581 				     struct viawget_wpa_param *param)
582 {
583     PSMgmtObject        pMgmt = pDevice->pMgmt;
584 	PWLAN_IE_SSID       pItemSSID;
585 	int ret = 0;
586 
587     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
588 
589 	memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len);
590 	param->u.wpa_associate.ssid_len = pItemSSID->len;
591 
592     return ret;
593 }
594 
595 
596 
597 /*
598  * Description:
599  *      get scan results
600  *
601  * Parameters:
602  *  In:
603  *      pDevice   -
604  *      param     -
605  *  Out:
606  *
607  * Return Value:
608  *
609  */
610 
wpa_get_scan(PSDevice pDevice,struct viawget_wpa_param * param)611 static int wpa_get_scan(PSDevice pDevice,
612 				     struct viawget_wpa_param *param)
613 {
614 	struct viawget_scan_result *scan_buf;
615     PSMgmtObject    pMgmt = pDevice->pMgmt;
616     PWLAN_IE_SSID   pItemSSID;
617     PKnownBSS pBSS;
618 	unsigned char *pBuf;
619 	int ret = 0;
620 	u16 count = 0;
621 	u16 ii, jj;
622 #if 1
623 
624     unsigned char *ptempBSS;
625 
626 
627 
628     ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC);
629 
630     if (ptempBSS == NULL) {
631 
632        printk("bubble sort kmalloc memory fail@@@\n");
633 
634         ret = -ENOMEM;
635 
636         return ret;
637 
638     }
639 
640     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
641 
642          for(jj=0;jj<MAX_BSS_NUM-ii-1;jj++) {
643 
644            if((pMgmt->sBSSList[jj].bActive!=true) ||
645 
646                 ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=false))) {
647 
648                  memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS));
649 
650                  memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS));
651 
652                  memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS));
653 
654               }
655 
656          }
657 
658     }
659 
660   kfree(ptempBSS);
661 
662  // printk("bubble sort result:\n");
663 
664   //for (ii = 0; ii < MAX_BSS_NUM; ii++)
665 
666   //    printk("%d [%s]:RSSI=%d\n",ii,((PWLAN_IE_SSID)(pMgmt->sBSSList[ii].abySSID))->abySSID,
667 
668   //                                                                 pMgmt->sBSSList[ii].uRSSI);
669 
670  #endif
671 
672 //******mike:bubble sort by stronger RSSI*****//
673 
674 
675 
676 
677 	count = 0;
678 	pBSS = &(pMgmt->sBSSList[0]);
679     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
680         pBSS = &(pMgmt->sBSSList[ii]);
681         if (!pBSS->bActive)
682             continue;
683         count++;
684     }
685 
686     pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC);
687 
688     if (pBuf == NULL) {
689         ret = -ENOMEM;
690         return ret;
691     }
692     scan_buf = (struct viawget_scan_result *)pBuf;
693 	pBSS = &(pMgmt->sBSSList[0]);
694     for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) {
695         pBSS = &(pMgmt->sBSSList[ii]);
696         if (pBSS->bActive) {
697             if (jj >= count)
698                 break;
699             memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN);
700             pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
701    		    memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len);
702    		    scan_buf->ssid_len = pItemSSID->len;
703             scan_buf->freq = frequency_list[pBSS->uChannel-1];
704 	  scan_buf->caps = pBSS->wCapInfo;
705             //scan_buf->caps = pBSS->wCapInfo;
706             //scan_buf->qual =
707             //scan_buf->noise =
708             //scan_buf->level =
709             //scan_buf->maxrate =
710             if (pBSS->wWPALen != 0) {
711                 scan_buf->wpa_ie_len = pBSS->wWPALen;
712                 memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen);
713             }
714             if (pBSS->wRSNLen != 0) {
715                 scan_buf->rsn_ie_len = pBSS->wRSNLen;
716                 memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
717             }
718             scan_buf = (struct viawget_scan_result *)((unsigned char *)scan_buf + sizeof(struct viawget_scan_result));
719             jj ++;
720         }
721     }
722 
723     if (jj < count)
724         count = jj;
725 
726     if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) {
727 		ret = -EFAULT;
728 	}
729 	param->u.scan_results.scan_count = count;
730     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
731 
732     kfree(pBuf);
733     return ret;
734 }
735 
736 
737 
738 /*
739  * Description:
740  *      set associate with AP
741  *
742  * Parameters:
743  *  In:
744  *      pDevice   -
745  *      param     -
746  *  Out:
747  *
748  * Return Value:
749  *
750  */
751 
wpa_set_associate(PSDevice pDevice,struct viawget_wpa_param * param)752 static int wpa_set_associate(PSDevice pDevice,
753 				     struct viawget_wpa_param *param)
754 {
755     PSMgmtObject    pMgmt = pDevice->pMgmt;
756     PWLAN_IE_SSID   pItemSSID;
757     unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
758     unsigned char abyWPAIE[64];
759     int ret = 0;
760     bool bWepEnabled=false;
761 
762 	// set key type & algorithm
763     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
764     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
765     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
766     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
767     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
768     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
769 
770 
771 	if (param->u.wpa_associate.wpa_ie_len) {
772 		if (!param->u.wpa_associate.wpa_ie)
773 			return -EINVAL;
774 		if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE))
775 			return -EINVAL;
776 		if (copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
777 			return -EFAULT;
778 	}
779 
780 	if (param->u.wpa_associate.mode == 1)
781 	    pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
782 	else
783 	    pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
784     // set ssid
785 	memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
786     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
787     pItemSSID->byElementID = WLAN_EID_SSID;
788 	pItemSSID->len = param->u.wpa_associate.ssid_len;
789 	memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len);
790 	// set bssid
791     if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0)
792         memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6);
793 else
794 {
795    bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID);
796 }
797 
798     if (param->u.wpa_associate.wpa_ie_len == 0) {
799 	    if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY)
800             pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
801 	    else
802             pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
803 	} else if (abyWPAIE[0] == RSN_INFO_ELEM) {
804 		if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
805 			pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
806 		else
807 			pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
808 	} else {
809 		if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE)
810 			pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
811 		else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
812 		    pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
813 		else
814 		    pMgmt->eAuthenMode = WMAC_AUTH_WPA;
815 	}
816 
817 	switch (param->u.wpa_associate.pairwise_suite) {
818 	case CIPHER_CCMP:
819 		pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
820 		break;
821 	case CIPHER_TKIP:
822 		pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
823 		break;
824 	case CIPHER_WEP40:
825 	case CIPHER_WEP104:
826 		pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
827 		bWepEnabled=true;
828 		break;
829 	case CIPHER_NONE:
830 		if (param->u.wpa_associate.group_suite == CIPHER_CCMP)
831 			pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
832 		else
833 			pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
834 		break;
835 	default:
836 		pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
837 	}
838 
839 //DavidWang add for WPA_supplicant support open/share mode
840 
841       if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) {
842             pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
843             //pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
844             pMgmt->bShareKeyAlgorithm = true;
845              }
846      else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) {
847           if(!bWepEnabled)  pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
848 	else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
849             //pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
850             //pMgmt->bShareKeyAlgorithm = false; //20080717-06,<Modify> by chester//Fix Open mode, WEP encrytion
851            }
852 //mike save old encryption status
853 	pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus;
854 
855     if (pDevice->eEncryptionStatus !=  Ndis802_11EncryptionDisabled)
856         pDevice->bEncryptionEnable = true;
857     else
858         pDevice->bEncryptionEnable = false;
859 if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
860       ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled==true))) )  //DavidWang  //20080717-06,<Modify> by chester//Not to initial WEP
861     KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
862     spin_lock_irq(&pDevice->lock);
863     pDevice->bLinkPass = false;
864     memset(pMgmt->abyCurrBSSID, 0, 6);
865     pMgmt->eCurrState = WMAC_STATE_IDLE;
866     netif_stop_queue(pDevice->dev);
867 	//20080701-02,<Add> by Mike Liu
868 /*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/
869 {
870    PKnownBSS       pCurr = NULL;
871     pCurr = BSSpSearchBSSList(pDevice,
872                               pMgmt->abyDesireBSSID,
873                               pMgmt->abyDesireSSID,
874                               pMgmt->eConfigPHYMode
875                               );
876 
877     if (pCurr == NULL){
878     printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
879     bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
880   }
881 }
882 /****************************************************************/
883     bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL);
884     spin_unlock_irq(&pDevice->lock);
885 
886     return ret;
887 }
888 
889 
890 /*
891  * Description:
892  *      wpa_ioctl main function supported for wpa supplicant
893  *
894  * Parameters:
895  *  In:
896  *      pDevice   -
897  *      iw_point  -
898  *  Out:
899  *
900  * Return Value:
901  *
902  */
903 
wpa_ioctl(PSDevice pDevice,struct iw_point * p)904 int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
905 {
906 	struct viawget_wpa_param *param;
907 	int ret = 0;
908 	int wpa_ioctl = 0;
909 
910 	if (p->length < sizeof(struct viawget_wpa_param) ||
911 	    p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
912 		return -EINVAL;
913 
914 	param = kmalloc((int)p->length, (int)GFP_KERNEL);
915 	if (param == NULL)
916 		return -ENOMEM;
917 
918 	if (copy_from_user(param, p->pointer, p->length)) {
919 		ret = -EFAULT;
920 		goto out;
921 	}
922 
923 	switch (param->cmd) {
924 	case VIAWGET_SET_WPA:
925         ret = wpa_set_wpa(pDevice, param);
926 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
927 		break;
928 
929 	case VIAWGET_SET_KEY:
930 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
931 	    spin_lock_irq(&pDevice->lock);
932         ret = wpa_set_keys(pDevice, param, false);
933         spin_unlock_irq(&pDevice->lock);
934 		break;
935 
936 	case VIAWGET_SET_SCAN:
937 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
938         ret = wpa_set_scan(pDevice, param);
939 		break;
940 
941 	case VIAWGET_GET_SCAN:
942 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
943         ret = wpa_get_scan(pDevice, param);
944 		wpa_ioctl = 1;
945 		break;
946 
947 	case VIAWGET_GET_SSID:
948 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
949         ret = wpa_get_ssid(pDevice, param);
950 		wpa_ioctl = 1;
951 		break;
952 
953 	case VIAWGET_GET_BSSID:
954 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
955         ret = wpa_get_bssid(pDevice, param);
956 		wpa_ioctl = 1;
957 		break;
958 
959 	case VIAWGET_SET_ASSOCIATE:
960 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
961         ret = wpa_set_associate(pDevice, param);
962 		break;
963 
964 	case VIAWGET_SET_DISASSOCIATE:
965 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
966         ret = wpa_set_disassociate(pDevice, param);
967 		break;
968 
969 	case VIAWGET_SET_DROP_UNENCRYPT:
970 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
971 		break;
972 
973     case VIAWGET_SET_DEAUTHENTICATE:
974 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
975 		break;
976 
977 	default:
978 	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
979 		       param->cmd);
980 		return -EOPNOTSUPP;
981 		break;
982 	}
983 
984 	if ((ret == 0) && wpa_ioctl) {
985 		if (copy_to_user(p->pointer, param, p->length)) {
986 			ret = -EFAULT;
987 			goto out;
988 		}
989 	}
990 
991 out:
992 	kfree(param);
993 
994 	return ret;
995 }
996 
997