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