alpha: fix several security issues
[linux/fpc-iii.git] / drivers / staging / vt6656 / hostap.c
blob51b5adf365775e236e6f71de064c15664352315e
1 /*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
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.
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.
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.
19 * File: hostap.c
21 * Purpose: handle hostap deamon ioctl input/out functions
23 * Author: Lyndon Chen
25 * Date: Oct. 20, 2003
27 * Functions:
29 * Revision History:
33 #include "hostap.h"
34 #include "iocmd.h"
35 #include "mac.h"
36 #include "card.h"
37 #include "baseband.h"
38 #include "wpactl.h"
39 #include "key.h"
40 #include "datarate.h"
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
53 /*--------------------- Static Definitions -------------------------*/
55 /*--------------------- Static Classes ----------------------------*/
57 /*--------------------- Static Variables --------------------------*/
58 //static int msglevel =MSG_LEVEL_DEBUG;
59 static int msglevel =MSG_LEVEL_INFO;
61 /*--------------------- Static Functions --------------------------*/
66 /*--------------------- Export Variables --------------------------*/
70 * Description:
71 * register net_device (AP) for hostap deamon
73 * Parameters:
74 * In:
75 * pDevice -
76 * rtnl_locked -
77 * Out:
79 * Return Value:
83 static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked)
85 PSDevice apdev_priv;
86 struct net_device *dev = pDevice->dev;
87 int ret;
88 const struct net_device_ops apdev_netdev_ops = {
89 .ndo_start_xmit = pDevice->tx_80211,
92 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name);
94 pDevice->apdev = kzalloc(sizeof(struct net_device), GFP_KERNEL);
95 if (pDevice->apdev == NULL)
96 return -ENOMEM;
98 apdev_priv = netdev_priv(pDevice->apdev);
99 *apdev_priv = *pDevice;
100 memcpy(pDevice->apdev->dev_addr, dev->dev_addr, ETH_ALEN);
102 pDevice->apdev->netdev_ops = &apdev_netdev_ops;
104 pDevice->apdev->type = ARPHRD_IEEE80211;
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;
121 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
122 dev->name, pDevice->apdev->name);
124 KeyvInitTable(pDevice,&pDevice->sKey);
126 return 0;
130 * Description:
131 * unregister net_device(AP)
133 * Parameters:
134 * In:
135 * pDevice -
136 * rtnl_locked -
137 * Out:
139 * Return Value:
143 static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked)
146 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name);
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);
156 kfree(pDevice->apdev);
157 pDevice->apdev = NULL;
158 pDevice->bEnable8021x = FALSE;
159 pDevice->bEnableHostWEP = FALSE;
160 pDevice->bEncryptionEnable = FALSE;
162 return 0;
167 * Description:
168 * Set enable/disable hostapd mode
170 * Parameters:
171 * In:
172 * pDevice -
173 * rtnl_locked -
174 * Out:
176 * Return Value:
180 int vt6656_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked)
182 if (val < 0 || val > 1)
183 return -EINVAL;
185 if (pDevice->bEnableHostapd == val)
186 return 0;
188 pDevice->bEnableHostapd = val;
190 if (val)
191 return hostap_enable_hostapd(pDevice, rtnl_locked);
192 else
193 return hostap_disable_hostapd(pDevice, rtnl_locked);
198 * Description:
199 * remove station function supported for hostap deamon
201 * Parameters:
202 * In:
203 * pDevice -
204 * param -
205 * Out:
207 * Return Value:
210 static int hostap_remove_sta(PSDevice pDevice,
211 struct viawget_hostapd_param *param)
213 unsigned int uNodeIndex;
216 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
217 BSSvRemoveOneNode(pDevice, uNodeIndex);
219 else {
220 return -ENOENT;
222 return 0;
226 * Description:
227 * add a station from hostap deamon
229 * Parameters:
230 * In:
231 * pDevice -
232 * param -
233 * Out:
235 * Return Value:
238 static int hostap_add_sta(PSDevice pDevice,
239 struct viawget_hostapd_param *param)
241 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
242 unsigned int uNodeIndex;
245 if (!BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
246 BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
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;
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);
265 pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)param->u.add_sta.aid;
267 pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;
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]
278 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n",
279 pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
281 return 0;
285 * Description:
286 * get station info
288 * Parameters:
289 * In:
290 * pDevice -
291 * param -
292 * Out:
294 * Return Value:
298 static int hostap_get_info_sta(PSDevice pDevice,
299 struct viawget_hostapd_param *param)
301 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
302 unsigned int uNodeIndex;
304 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
305 param->u.get_info_sta.inactive_sec =
306 (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;
308 //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts;
310 else {
311 return -ENOENT;
314 return 0;
318 * Description:
319 * reset txexec
321 * Parameters:
322 * In:
323 * pDevice -
324 * param -
325 * Out:
326 * TURE, FALSE
328 * Return Value:
332 static int hostap_reset_txexc_sta(PSDevice pDevice,
333 struct viawget_hostapd_param *param)
335 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
336 unsigned int uNodeIndex;
338 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
339 pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts = 0;
341 else {
342 return -ENOENT;
345 return 0;
350 * Description:
351 * set station flag
353 * Parameters:
354 * In:
355 * pDevice -
356 * param -
357 * Out:
359 * Return Value:
362 static int hostap_set_flags_sta(PSDevice pDevice,
363 struct viawget_hostapd_param *param)
365 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
366 unsigned int uNodeIndex;
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 (unsigned int) pMgmt->sNodeDBTable[uNodeIndex].dwFlags);
374 else {
375 return -ENOENT;
378 return 0;
384 * Description:
385 * set generic element (wpa ie)
387 * Parameters:
388 * In:
389 * pDevice -
390 * param -
391 * Out:
393 * Return Value:
396 static int hostap_set_generic_element(PSDevice pDevice,
397 struct viawget_hostapd_param *param)
399 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
403 memcpy( pMgmt->abyWPAIE,
404 param->u.generic_elem.data,
405 param->u.generic_elem.len
408 pMgmt->wWPAIELen = param->u.generic_elem.len;
410 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen);
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;
426 return 0;
430 * Description:
431 * flush station nodes table.
433 * Parameters:
434 * In:
435 * pDevice -
436 * Out:
438 * Return Value:
442 static void hostap_flush_sta(PSDevice pDevice)
444 // reserved node index =0 for multicast node.
445 BSSvClearNodeDBTable(pDevice, 1);
446 pDevice->uAssocCount = 0;
448 return;
452 * Description:
453 * set each stations encryption key
455 * Parameters:
456 * In:
457 * pDevice -
458 * param -
459 * Out:
461 * Return Value:
464 static int hostap_set_encryption(PSDevice pDevice,
465 struct viawget_hostapd_param *param,
466 int param_len)
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;
481 param->u.crypt.err = 0;
483 if (param_len !=
484 (int) ((char *) param->u.crypt.key - (char *) param) +
485 param->u.crypt.key_len)
486 return -EINVAL;
489 if (param->u.crypt.alg > WPA_ALG_CCMP)
490 return -EINVAL;
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;
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;
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;
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);
516 if (param->u.crypt.alg == WPA_ALG_NONE) {
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");
526 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
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],
537 MAX_KEY_LEN
540 return ret;
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
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);
559 if (param->u.crypt.alg == WPA_ALG_WEP) {
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
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) {
585 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
587 } else {
588 // Key Table Full
589 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
590 bKeyTableFull = TRUE;
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;
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));
607 dwKeyIndex |= 1 << 29;
608 pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC;
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;
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;
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
640 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
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) {
654 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
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");
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);
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]
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;
693 return ret;
699 * Description:
700 * get each stations encryption key
702 * Parameters:
703 * In:
704 * pDevice -
705 * param -
706 * Out:
708 * Return Value:
711 static int hostap_get_encryption(PSDevice pDevice,
712 struct viawget_hostapd_param *param,
713 int param_len)
715 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
716 int ret = 0;
717 int ii;
718 int iNodeIndex =0;
721 param->u.crypt.err = 0;
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;
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);
740 return ret;
745 * Description:
746 * vt6656_hostap_ioctl main function supported for hostap deamon.
748 * Parameters:
749 * In:
750 * pDevice -
751 * iw_point -
752 * Out:
754 * Return Value:
758 int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
760 struct viawget_hostapd_param *param;
761 int ret = 0;
762 int ap_ioctl = 0;
764 if (p->length < sizeof(struct viawget_hostapd_param) ||
765 p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
766 return -EINVAL;
768 param = kmalloc((int)p->length, (int)GFP_KERNEL);
769 if (param == NULL)
770 return -ENOMEM;
772 if (copy_from_user(param, p->pointer, p->length)) {
773 ret = -EFAULT;
774 goto out;
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;
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;
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;
828 case VIAWGET_HOSTAPD_MLME:
829 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
830 return -EOPNOTSUPP;
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;
837 case VIAWGET_HOSTAPD_SCAN_REQ:
838 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
839 return -EOPNOTSUPP;
841 case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
842 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
843 return -EOPNOTSUPP;
845 default:
846 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6656_hostap_ioctl: unknown cmd=%d\n",
847 (int)param->cmd);
848 return -EOPNOTSUPP;
849 break;
853 if ((ret == 0) && ap_ioctl) {
854 if (copy_to_user(p->pointer, param, p->length)) {
855 ret = -EFAULT;
856 goto out;
860 out:
861 kfree(param);
863 return ret;