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