Staging: Use kcalloc or kzalloc
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / vt6656 / hostap.c
CommitLineData
92b96797
FB
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 * File: hostap.c
20 *
21 * Purpose: handle hostap deamon ioctl input/out functions
22 *
23 * Author: Lyndon Chen
24 *
25 * Date: Oct. 20, 2003
26 *
27 * Functions:
28 *
29 * Revision History:
30 *
31 */
32
92b96797 33#include "hostap.h"
92b96797 34#include "iocmd.h"
92b96797 35#include "mac.h"
92b96797 36#include "card.h"
92b96797 37#include "baseband.h"
92b96797 38#include "wpactl.h"
92b96797 39#include "key.h"
92b96797 40#include "datarate.h"
92b96797
FB
41
42#define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024
43#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT0
44#define HOSTAP_CRYPT_FLAG_PERMANENT BIT1
45#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2
46#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
47#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4
48#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5
49#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6
50#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7
51
52
53/*--------------------- Static Definitions -------------------------*/
54
55/*--------------------- Static Classes ----------------------------*/
56
57/*--------------------- Static Variables --------------------------*/
58//static int msglevel =MSG_LEVEL_DEBUG;
59static int msglevel =MSG_LEVEL_INFO;
60
61/*--------------------- Static Functions --------------------------*/
62
63
64
65
66/*--------------------- Export Variables --------------------------*/
67
68
69/*
70 * Description:
71 * register net_device (AP) for hostap deamon
72 *
73 * Parameters:
74 * In:
75 * pDevice -
76 * rtnl_locked -
77 * Out:
78 *
79 * Return Value:
80 *
81 */
82
83static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked)
84{
1e28efa3 85 PSDevice apdev_priv;
92b96797
FB
86 struct net_device *dev = pDevice->dev;
87 int ret;
d899d403
JL
88 const struct net_device_ops apdev_netdev_ops = {
89 .ndo_start_xmit = pDevice->tx_80211,
90 };
92b96797
FB
91
92 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name);
93
7a6cb0d5 94 pDevice->apdev = kzalloc(sizeof(struct net_device), GFP_KERNEL);
77f58b13 95 if (pDevice->apdev == NULL)
92b96797 96 return -ENOMEM;
92b96797 97
1e28efa3
FB
98 apdev_priv = netdev_priv(pDevice->apdev);
99 *apdev_priv = *pDevice;
92b96797 100 memcpy(pDevice->apdev->dev_addr, dev->dev_addr, ETH_ALEN);
dd8db704 101
dd8db704
FB
102 pDevice->apdev->netdev_ops = &apdev_netdev_ops;
103
92b96797
FB
104 pDevice->apdev->type = ARPHRD_IEEE80211;
105
106 pDevice->apdev->base_addr = dev->base_addr;
107 pDevice->apdev->irq = dev->irq;
108 pDevice->apdev->mem_start = dev->mem_start;
109 pDevice->apdev->mem_end = dev->mem_end;
110 sprintf(pDevice->apdev->name, "%sap", dev->name);
111 if (rtnl_locked)
112 ret = register_netdevice(pDevice->apdev);
113 else
114 ret = register_netdev(pDevice->apdev);
115 if (ret) {
116 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
117 dev->name);
118 return -1;
119 }
120
121 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
122 dev->name, pDevice->apdev->name);
123
124 KeyvInitTable(pDevice,&pDevice->sKey);
125
126 return 0;
127}
128
129/*
130 * Description:
131 * unregister net_device(AP)
132 *
133 * Parameters:
134 * In:
135 * pDevice -
136 * rtnl_locked -
137 * Out:
138 *
139 * Return Value:
140 *
141 */
142
143static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked)
144{
145
146 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name);
147
148 if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) {
149 if (rtnl_locked)
150 unregister_netdevice(pDevice->apdev);
151 else
152 unregister_netdev(pDevice->apdev);
153 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
154 pDevice->dev->name, pDevice->apdev->name);
155 }
156 kfree(pDevice->apdev);
157 pDevice->apdev = NULL;
158 pDevice->bEnable8021x = FALSE;
159 pDevice->bEnableHostWEP = FALSE;
160 pDevice->bEncryptionEnable = FALSE;
161
162 return 0;
163}
164
165
166/*
167 * Description:
168 * Set enable/disable hostapd mode
169 *
170 * Parameters:
171 * In:
172 * pDevice -
173 * rtnl_locked -
174 * Out:
175 *
176 * Return Value:
177 *
178 */
179
c30d7973 180int vt6656_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked)
92b96797
FB
181{
182 if (val < 0 || val > 1)
183 return -EINVAL;
184
185 if (pDevice->bEnableHostapd == val)
186 return 0;
187
188 pDevice->bEnableHostapd = val;
189
190 if (val)
191 return hostap_enable_hostapd(pDevice, rtnl_locked);
192 else
193 return hostap_disable_hostapd(pDevice, rtnl_locked);
194}
195
196
197/*
198 * Description:
199 * remove station function supported for hostap deamon
200 *
201 * Parameters:
202 * In:
203 * pDevice -
204 * param -
205 * Out:
206 *
207 * Return Value:
208 *
209 */
210static int hostap_remove_sta(PSDevice pDevice,
211 struct viawget_hostapd_param *param)
212{
213 UINT uNodeIndex;
214
215
216 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
217 BSSvRemoveOneNode(pDevice, uNodeIndex);
218 }
219 else {
220 return -ENOENT;
221 }
222 return 0;
223}
224
225/*
226 * Description:
227 * add a station from hostap deamon
228 *
229 * Parameters:
230 * In:
231 * pDevice -
232 * param -
233 * Out:
234 *
235 * Return Value:
236 *
237 */
238static int hostap_add_sta(PSDevice pDevice,
239 struct viawget_hostapd_param *param)
240{
241 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
242 UINT uNodeIndex;
243
244
245 if (!BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
246 BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
247 }
248 memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN);
249 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
250 pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability;
251// TODO listenInterval
252// pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = 1;
253 pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = FALSE;
254 pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates;
255
256 // set max tx rate
257 pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
258 pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
259 // set max basic rate
260 pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M;
261 // Todo: check sta preamble, if ap can't support, set status code
262 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
263 WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo);
264
265 pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)param->u.add_sta.aid;
266
267 pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;
268
269 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
270 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
271 param->sta_addr[0],
272 param->sta_addr[1],
273 param->sta_addr[2],
274 param->sta_addr[3],
275 param->sta_addr[4],
276 param->sta_addr[5]
277 ) ;
278 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n",
279 pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
280
281 return 0;
282}
283
284/*
285 * Description:
286 * get station info
287 *
288 * Parameters:
289 * In:
290 * pDevice -
291 * param -
292 * Out:
293 *
294 * Return Value:
295 *
296 */
297
298static int hostap_get_info_sta(PSDevice pDevice,
299 struct viawget_hostapd_param *param)
300{
301 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
302 UINT uNodeIndex;
303
304 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
305 param->u.get_info_sta.inactive_sec =
306 (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;
307
308 //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts;
309 }
310 else {
311 return -ENOENT;
312 }
313
314 return 0;
315}
316
317/*
318 * Description:
319 * reset txexec
320 *
321 * Parameters:
322 * In:
323 * pDevice -
324 * param -
325 * Out:
326 * TURE, FALSE
327 *
328 * Return Value:
329 *
330 */
331/*
332static int hostap_reset_txexc_sta(PSDevice pDevice,
333 struct viawget_hostapd_param *param)
334{
335 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
336 UINT uNodeIndex;
337
338 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
339 pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts = 0;
340 }
341 else {
342 return -ENOENT;
343 }
344
345 return 0;
346}
347*/
348
349/*
350 * Description:
351 * set station flag
352 *
353 * Parameters:
354 * In:
355 * pDevice -
356 * param -
357 * Out:
358 *
359 * Return Value:
360 *
361 */
362static int hostap_set_flags_sta(PSDevice pDevice,
363 struct viawget_hostapd_param *param)
364{
365 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
366 UINT uNodeIndex;
367
368 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
369 pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or;
370 pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and;
371 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n",
372 (UINT)pMgmt->sNodeDBTable[uNodeIndex].dwFlags);
373 }
374 else {
375 return -ENOENT;
376 }
377
378 return 0;
379}
380
381
382
383/*
384 * Description:
385 * set generic element (wpa ie)
386 *
387 * Parameters:
388 * In:
389 * pDevice -
390 * param -
391 * Out:
392 *
393 * Return Value:
394 *
395 */
396static int hostap_set_generic_element(PSDevice pDevice,
397 struct viawget_hostapd_param *param)
398{
399 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
400
401
402
403 memcpy( pMgmt->abyWPAIE,
404 param->u.generic_elem.data,
405 param->u.generic_elem.len
406 );
407
408 pMgmt->wWPAIELen = param->u.generic_elem.len;
409
410 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen);
411
412 // disable wpa
413 if (pMgmt->wWPAIELen == 0) {
414 pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
415 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n");
416 } else {
417 // enable wpa
418 if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) ||
419 (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) {
420 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
421 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n");
422 } else
423 return -EINVAL;
424 }
425
426 return 0;
427}
428
429/*
430 * Description:
431 * flush station nodes table.
432 *
433 * Parameters:
434 * In:
435 * pDevice -
436 * Out:
437 *
438 * Return Value:
439 *
440 */
441
442static void hostap_flush_sta(PSDevice pDevice)
443{
444 // reserved node index =0 for multicast node.
445 BSSvClearNodeDBTable(pDevice, 1);
446 pDevice->uAssocCount = 0;
447
448 return;
449}
450
451/*
452 * Description:
453 * set each stations encryption key
454 *
455 * Parameters:
456 * In:
457 * pDevice -
458 * param -
459 * Out:
460 *
461 * Return Value:
462 *
463 */
464static int hostap_set_encryption(PSDevice pDevice,
465 struct viawget_hostapd_param *param,
466 int param_len)
467{
468 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
469 DWORD dwKeyIndex = 0;
470 BYTE abyKey[MAX_KEY_LEN];
471 BYTE abySeq[MAX_KEY_LEN];
472 NDIS_802_11_KEY_RSC KeyRSC;
473 BYTE byKeyDecMode = KEY_CTL_WEP;
474 int ret = 0;
475 int iNodeIndex = -1;
476 int ii;
477 BOOL bKeyTableFull = FALSE;
478 WORD wKeyCtl = 0;
479
480
481 param->u.crypt.err = 0;
482/*
483 if (param_len !=
484 (int) ((char *) param->u.crypt.key - (char *) param) +
485 param->u.crypt.key_len)
486 return -EINVAL;
487*/
488
489 if (param->u.crypt.alg > WPA_ALG_CCMP)
490 return -EINVAL;
491
492
493 if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) {
494 param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
495 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n");
496 return -EINVAL;
497 }
498
499 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
500 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
501 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
502 if (param->u.crypt.idx >= MAX_GROUP_KEY)
503 return -EINVAL;
504 iNodeIndex = 0;
505
506 } else {
507 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) {
508 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
509 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
510 return -EINVAL;
511 }
512 }
513 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex);
514 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg);
515
516 if (param->u.crypt.alg == WPA_ALG_NONE) {
517
518 if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == TRUE) {
519 if (KeybRemoveKey( pDevice,
520 &(pDevice->sKey),
521 param->sta_addr,
522 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex
523 ) == FALSE) {
524 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
525 }
526 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
527 }
528 pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0;
529 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0;
530 pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0;
531 pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0;
532 pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
533 pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;
534 pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0;
535 memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
536 0,
537 MAX_KEY_LEN
538 );
539
540 return ret;
541 }
542
543 memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len);
544 // copy to node key tbl
545 pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx;
546 pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len;
547 memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
548 param->u.crypt.key,
549 param->u.crypt.key_len
550 );
551
552 dwKeyIndex = (DWORD)(param->u.crypt.idx);
553 if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
554 pDevice->byKeyIndex = (BYTE)dwKeyIndex;
555 pDevice->bTransmitKey = TRUE;
556 dwKeyIndex |= (1 << 31);
557 }
558
559 if (param->u.crypt.alg == WPA_ALG_WEP) {
560
561 if ((pDevice->bEnable8021x == FALSE) || (iNodeIndex == 0)) {
562 KeybSetDefaultKey( pDevice,
563 &(pDevice->sKey),
564 dwKeyIndex & ~(BIT30 | USE_KEYRSC),
565 param->u.crypt.key_len,
566 NULL,
567 abyKey,
568 KEY_CTL_WEP
569 );
570
571 } else {
572 // 8021x enable, individual key
573 dwKeyIndex |= (1 << 30); // set pairwise key
574 if (KeybSetKey(pDevice,
575 &(pDevice->sKey),
576 &param->sta_addr[0],
577 dwKeyIndex & ~(USE_KEYRSC),
578 param->u.crypt.key_len,
579 (PQWORD) &(KeyRSC),
580 (PBYTE)abyKey,
581 KEY_CTL_WEP
582 ) == TRUE) {
583
584
585 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
586
587 } else {
588 // Key Table Full
589 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
590 bKeyTableFull = TRUE;
591 }
592 }
593 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
594 pDevice->bEncryptionEnable = TRUE;
595 pMgmt->byCSSPK = KEY_CTL_WEP;
596 pMgmt->byCSSGK = KEY_CTL_WEP;
597 pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP;
598 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
599 return ret;
600 }
601
602 if (param->u.crypt.seq) {
603 memcpy(&abySeq, param->u.crypt.seq, 8);
604 for (ii = 0 ; ii < 8 ; ii++) {
605 KeyRSC |= (abySeq[ii] << (ii * 8));
606 }
607 dwKeyIndex |= 1 << 29;
608 pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC;
609 }
610
611 if (param->u.crypt.alg == WPA_ALG_TKIP) {
612 if (param->u.crypt.key_len != MAX_KEY_LEN)
613 return -EINVAL;
614 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
615 byKeyDecMode = KEY_CTL_TKIP;
616 pMgmt->byCSSPK = KEY_CTL_TKIP;
617 pMgmt->byCSSGK = KEY_CTL_TKIP;
618 }
619
620 if (param->u.crypt.alg == WPA_ALG_CCMP) {
621 if ((param->u.crypt.key_len != AES_KEY_LEN) ||
622 (pDevice->byLocalID <= REV_ID_VT3253_A1))
623 return -EINVAL;
624 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
625 byKeyDecMode = KEY_CTL_CCMP;
626 pMgmt->byCSSPK = KEY_CTL_CCMP;
627 pMgmt->byCSSGK = KEY_CTL_CCMP;
628 }
629
630
631 if (iNodeIndex == 0) {
632 KeybSetDefaultKey( pDevice,
633 &(pDevice->sKey),
634 dwKeyIndex,
635 param->u.crypt.key_len,
636 (PQWORD) &(KeyRSC),
637 abyKey,
638 byKeyDecMode
639 );
640 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
641
642 } else {
643 dwKeyIndex |= (1 << 30); // set pairwise key
644 if (KeybSetKey(pDevice,
645 &(pDevice->sKey),
646 &param->sta_addr[0],
647 dwKeyIndex,
648 param->u.crypt.key_len,
649 (PQWORD) &(KeyRSC),
650 (PBYTE)abyKey,
651 byKeyDecMode
652 ) == TRUE) {
653
654 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
655
656 } else {
657 // Key Table Full
658 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
659 bKeyTableFull = TRUE;
660 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n");
661 }
662
663 }
664
665 if (bKeyTableFull == TRUE) {
666 wKeyCtl &= 0x7F00; // clear all key control filed
667 wKeyCtl |= (byKeyDecMode << 4);
668 wKeyCtl |= (byKeyDecMode);
669 wKeyCtl |= 0x0044; // use group key for all address
670 wKeyCtl |= 0x4000; // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int
671// Todo.. xxxxxx
672 //MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID);
673 }
674
675 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex);
676 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx,
677 param->u.crypt.key_len );
678 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
679 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
680 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1],
681 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2],
682 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3],
683 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4]
684 );
685
686 // set wep key
687 pDevice->bEncryptionEnable = TRUE;
688 pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode;
689 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
690 pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
691 pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;
692
693 return ret;
694}
695
696
697
698/*
699 * Description:
700 * get each stations encryption key
701 *
702 * Parameters:
703 * In:
704 * pDevice -
705 * param -
706 * Out:
707 *
708 * Return Value:
709 *
710 */
711static int hostap_get_encryption(PSDevice pDevice,
712 struct viawget_hostapd_param *param,
713 int param_len)
714{
715 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
716 int ret = 0;
717 int ii;
718 int iNodeIndex =0;
719
720
721 param->u.crypt.err = 0;
722
723 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
724 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
725 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
726 iNodeIndex = 0;
727 } else {
728 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) {
729 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
730 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
731 return -EINVAL;
732 }
733 }
734 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex);
735 memset(param->u.crypt.seq, 0, 8);
736 for (ii = 0 ; ii < 8 ; ii++) {
737 param->u.crypt.seq[ii] = (BYTE)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8);
738 }
739
740 return ret;
741}
742
743
744/*
745 * Description:
c30d7973 746 * vt6656_hostap_ioctl main function supported for hostap deamon.
92b96797
FB
747 *
748 * Parameters:
749 * In:
750 * pDevice -
751 * iw_point -
752 * Out:
753 *
754 * Return Value:
755 *
756 */
757
c30d7973 758int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
92b96797
FB
759{
760 struct viawget_hostapd_param *param;
761 int ret = 0;
762 int ap_ioctl = 0;
763
764 if (p->length < sizeof(struct viawget_hostapd_param) ||
765 p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
766 return -EINVAL;
767
32414878 768 param = kmalloc((int)p->length, (int)GFP_KERNEL);
92b96797
FB
769 if (param == NULL)
770 return -ENOMEM;
771
772 if (copy_from_user(param, p->pointer, p->length)) {
773 ret = -EFAULT;
774 goto out;
775 }
776
777 switch (param->cmd) {
778 case VIAWGET_HOSTAPD_SET_ENCRYPTION:
779 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n");
780 spin_lock_irq(&pDevice->lock);
781 ret = hostap_set_encryption(pDevice, param, p->length);
782 spin_unlock_irq(&pDevice->lock);
783 break;
784 case VIAWGET_HOSTAPD_GET_ENCRYPTION:
785 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n");
786 spin_lock_irq(&pDevice->lock);
787 ret = hostap_get_encryption(pDevice, param, p->length);
788 spin_unlock_irq(&pDevice->lock);
789 break;
790 case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
791 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
792 return -EOPNOTSUPP;
793 break;
794 case VIAWGET_HOSTAPD_FLUSH:
795 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
796 spin_lock_irq(&pDevice->lock);
797 hostap_flush_sta(pDevice);
798 spin_unlock_irq(&pDevice->lock);
799 break;
800 case VIAWGET_HOSTAPD_ADD_STA:
801 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n");
802 spin_lock_irq(&pDevice->lock);
803 ret = hostap_add_sta(pDevice, param);
804 spin_unlock_irq(&pDevice->lock);
805 break;
806 case VIAWGET_HOSTAPD_REMOVE_STA:
807 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n");
808 spin_lock_irq(&pDevice->lock);
809 ret = hostap_remove_sta(pDevice, param);
810 spin_unlock_irq(&pDevice->lock);
811 break;
812 case VIAWGET_HOSTAPD_GET_INFO_STA:
813 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n");
814 ret = hostap_get_info_sta(pDevice, param);
815 ap_ioctl = 1;
816 break;
817/*
818 case VIAWGET_HOSTAPD_RESET_TXEXC_STA:
819 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_RESET_TXEXC_STA \n");
820 ret = hostap_reset_txexc_sta(pDevice, param);
821 break;
822*/
823 case VIAWGET_HOSTAPD_SET_FLAGS_STA:
824 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
825 ret = hostap_set_flags_sta(pDevice, param);
826 break;
827
828 case VIAWGET_HOSTAPD_MLME:
829 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
830 return -EOPNOTSUPP;
831
832 case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
833 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
834 ret = hostap_set_generic_element(pDevice, param);
835 break;
836
837 case VIAWGET_HOSTAPD_SCAN_REQ:
838 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
839 return -EOPNOTSUPP;
840
841 case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
842 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
843 return -EOPNOTSUPP;
844
845 default:
c30d7973 846 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6656_hostap_ioctl: unknown cmd=%d\n",
92b96797
FB
847 (int)param->cmd);
848 return -EOPNOTSUPP;
849 break;
850 }
851
852
853 if ((ret == 0) && ap_ioctl) {
854 if (copy_to_user(p->pointer, param, p->length)) {
855 ret = -EFAULT;
856 goto out;
857 }
858 }
859
860 out:
861 if (param != NULL)
862 kfree(param);
863
864 return ret;
865}
866