Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wpactl.c
Go to the documentation of this file.
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 --------------------------*/
65 static void wpadev_setup(struct net_device *dev)
66 {
67  dev->type = ARPHRD_IEEE80211;
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 
76 }
77 
78 /*
79  * Description:
80  * register netdev for wpa supplicant daemon
81  *
82  * Parameters:
83  * In:
84  * pDevice -
85  * enable -
86  * Out:
87  *
88  * Return Value:
89  *
90  */
91 
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 
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 daemon
168  *
169  * Parameters:
170  * In:
171  * pDevice -
172  * val -
173  * Out:
174  *
175  * Return Value:
176  *
177  */
178 
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 
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) {
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  }
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) {
307  }
308 
309  if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
311  }
312 
313  if (param->u.wpa_key.set_tx)
314  dwKeyIndex |= (1 << 31);
315 
316 
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
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 
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 
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 
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 
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 
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 
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 
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)
782  else
784  // set ssid
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)
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)
806  else
807  pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
808  } else {
809  if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE)
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 encryption
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 
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) ||
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 
960  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
961  ret = wpa_set_associate(pDevice, param);
962  break;
963 
965  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
966  ret = wpa_set_disassociate(pDevice, param);
967  break;
968 
970  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
971  break;
972 
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