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