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