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