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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60#include <wl_version.h>
61
62#include <linux/if_arp.h>
63#include <linux/ioport.h>
64#include <linux/delay.h>
65#include <asm/uaccess.h>
66
67#include <debug.h>
68#include <hcf.h>
69#include <hcfdef.h>
70
71#include <wl_if.h>
72#include <wl_internal.h>
73#include <wl_util.h>
74#include <wl_main.h>
75#include <wl_wext.h>
76#include <wl_priv.h>
77
78
79
80
81
82
83#ifdef WIRELESS_EXT
84
85#define IWE_STREAM_ADD_EVENT(info, buf, end, iwe, len) \
86 iwe_stream_add_event(info, buf, end, iwe, len)
87#define IWE_STREAM_ADD_POINT(info, buf, end, iwe, msg) \
88 iwe_stream_add_point(info, buf, end, iwe, msg)
89
90
91
92
93
94
95#if DBG
96extern dbg_info_t *DbgInfo;
97#endif
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120static int wireless_commit(struct net_device *dev,
121 struct iw_request_info *info,
122 union iwreq_data *rqu, char *extra)
123{
124 struct wl_private *lp = wl_priv(dev);
125 unsigned long flags;
126 int ret = 0;
127
128
129 DBG_FUNC( "wireless_commit" );
130 DBG_ENTER(DbgInfo);
131
132 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
133 ret = -EBUSY;
134 goto out;
135 }
136
137 wl_lock( lp, &flags );
138
139 wl_act_int_off( lp );
140
141 wl_apply(lp);
142
143 wl_act_int_on( lp );
144
145 wl_unlock(lp, &flags);
146
147out:
148 DBG_LEAVE( DbgInfo );
149 return ret;
150}
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174static int wireless_get_protocol(struct net_device *dev, struct iw_request_info *info, char *name, char *extra)
175{
176 DBG_FUNC( "wireless_get_protocol" );
177 DBG_ENTER( DbgInfo );
178
179
180
181
182
183 strcpy(name, "IEEE 802.11b");
184
185 DBG_LEAVE(DbgInfo);
186 return 0;
187}
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212static int wireless_set_frequency(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra)
213{
214 struct wl_private *lp = wl_priv(dev);
215 unsigned long flags;
216 int channel = 0;
217 int ret = 0;
218
219
220
221 DBG_FUNC( "wireless_set_frequency" );
222 DBG_ENTER( DbgInfo );
223
224 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
225 ret = -EBUSY;
226 goto out;
227 }
228
229 if( !capable( CAP_NET_ADMIN )) {
230 ret = -EPERM;
231 DBG_LEAVE( DbgInfo );
232 return ret;
233 }
234
235
236
237 if( freq->e == 1 ) {
238 int f = freq->m / 100000;
239 channel = wl_get_chan_from_freq( f );
240 }
241
242
243
244 if( freq->e == 0 ) {
245 channel = freq->m;
246 }
247
248
249
250 if( channel > 14 ) {
251 channel = channel | 0x100;
252 }
253
254
255 wl_lock( lp, &flags );
256
257 wl_act_int_off( lp );
258
259 lp->Channel = channel;
260
261
262
263 wl_apply( lp );
264
265
266 wl_wext_event_freq( lp->dev );
267
268 wl_act_int_on( lp );
269
270 wl_unlock(lp, &flags);
271
272out:
273 DBG_LEAVE( DbgInfo );
274 return ret;
275}
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299static int wireless_get_frequency(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra)
300
301{
302 struct wl_private *lp = wl_priv(dev);
303 unsigned long flags;
304 int ret = -1;
305
306
307
308 DBG_FUNC( "wireless_get_frequency" );
309 DBG_ENTER( DbgInfo );
310
311 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
312 ret = -EBUSY;
313 goto out;
314 }
315
316 wl_lock( lp, &flags );
317
318 wl_act_int_off( lp );
319
320 lp->ltvRecord.len = 2;
321 lp->ltvRecord.typ = CFG_CUR_CHANNEL;
322
323 ret = hcf_get_info( &(lp->hcfCtx), (LTVP)&( lp->ltvRecord ));
324 if( ret == HCF_SUCCESS ) {
325 hcf_16 channel = CNV_LITTLE_TO_INT( lp->ltvRecord.u.u16[0] );
326
327#ifdef USE_FREQUENCY
328
329 freq->m = wl_get_freq_from_chan( channel ) * 100000;
330 freq->e = 1;
331#else
332
333 freq->m = channel;
334 freq->e = 0;
335
336#endif
337 }
338
339 wl_act_int_on( lp );
340
341 wl_unlock(lp, &flags);
342
343 ret = (ret == HCF_SUCCESS ? 0 : -EFAULT);
344
345out:
346 DBG_LEAVE( DbgInfo );
347 return ret;
348}
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374static int wireless_get_range(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra)
375{
376 struct wl_private *lp = wl_priv(dev);
377 unsigned long flags;
378 struct iw_range *range = (struct iw_range *) extra;
379 int ret = 0;
380 int status = -1;
381 int count;
382 __u16 *pTxRate;
383 int retries = 0;
384
385
386
387 DBG_FUNC( "wireless_get_range" );
388 DBG_ENTER( DbgInfo );
389
390
391 data->length = sizeof(struct iw_range);
392 memset(range, 0, sizeof(struct iw_range));
393
394 wl_lock( lp, &flags );
395
396 wl_act_int_off( lp );
397
398
399 memset( range, 0, sizeof( struct iw_range ));
400
401retry:
402
403 lp->ltvRecord.len = 1 + (sizeof(*pTxRate) / sizeof(hcf_16));
404 lp->ltvRecord.typ = CFG_CUR_TX_RATE;
405
406 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
407 if( status != HCF_SUCCESS ) {
408
409 DBG_TRACE( DbgInfo, "Get CFG_CUR_TX_RATE failed: 0x%x\n", status );
410
411 if (retries < 10) {
412 retries++;
413
414
415 wl_unlock(lp, &flags);
416 wl_lock( lp, &flags );
417
418 status = wl_reset( dev );
419 if ( status != HCF_SUCCESS ) {
420 DBG_TRACE( DbgInfo, "reset failed: 0x%x\n", status );
421
422 ret = -EFAULT;
423 goto out_unlock;
424 }
425
426
427 wl_unlock(lp, &flags);
428 wl_lock( lp, &flags );
429
430 goto retry;
431
432 } else {
433 DBG_TRACE( DbgInfo, "Get CFG_CUR_TX_RATE failed: %d retries\n", retries );
434 ret = -EFAULT;
435 goto out_unlock;
436 }
437 }
438
439
440 wl_unlock(lp, &flags);
441 wl_lock( lp, &flags );
442
443 pTxRate = (__u16 *)&( lp->ltvRecord.u.u32 );
444
445 range->throughput = CNV_LITTLE_TO_INT( *pTxRate ) * MEGABIT;
446
447 if (retries > 0) {
448 DBG_TRACE( DbgInfo, "Get CFG_CUR_TX_RATE succes: %d retries\n", retries );
449 }
450
451
452
453
454
455 range->num_channels = RADIO_CHANNELS;
456
457
458
459 range->sensitivity = RADIO_SENSITIVITY_LEVELS;
460
461
462
463#ifdef USE_DBM
464
465 range->max_qual.qual = (u_char)HCF_MAX_COMM_QUALITY;
466
467
468
469
470
471 range->max_qual.level = (u_char)( dbm( HCF_MIN_SIGNAL_LEVEL ) - 1 );
472 range->max_qual.noise = (u_char)( dbm( HCF_MIN_NOISE_LEVEL ) - 1 );
473#else
474
475 range->max_qual.qual = 100;
476 range->max_qual.level = 100;
477 range->max_qual.noise = 100;
478
479#endif
480
481
482
483 range->num_bitrates = 0;
484
485 lp->ltvRecord.len = 6;
486 lp->ltvRecord.typ = CFG_SUPPORTED_DATA_RATES;
487
488 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
489 if( status == HCF_SUCCESS ) {
490 for( count = 0; count < MAX_RATES; count++ )
491 if( lp->ltvRecord.u.u8[count+2] != 0 ) {
492 range->bitrate[count] = lp->ltvRecord.u.u8[count+2] * MEGABIT / 2;
493 range->num_bitrates++;
494 }
495 } else {
496 DBG_TRACE( DbgInfo, "CFG_SUPPORTED_DATA_RATES: 0x%x\n", status );
497 ret = -EFAULT;
498 goto out_unlock;
499 }
500
501
502 range->min_rts = MIN_RTS_BYTES;
503 range->max_rts = MAX_RTS_BYTES;
504
505
506
507
508
509
510
511#if WIRELESS_EXT > 8
512
513
514 wl_unlock(lp, &flags);
515 wl_lock( lp, &flags );
516
517
518
519 if( wl_has_wep( &( lp->hcfCtx ))) {
520
521 range->encoding_size[0] = MIN_KEY_SIZE;
522
523
524 range->encoding_size[1] = MAX_KEY_SIZE;
525 range->num_encoding_sizes = 2;
526 range->max_encoding_tokens = MAX_KEYS;
527 }
528
529#endif
530
531
532 range->txpower_capa = IW_TXPOW_MWATT;
533 range->num_txpower = 1;
534 range->txpower[0] = RADIO_TX_POWER_MWATT;
535
536#if WIRELESS_EXT > 10
537
538
539 range->we_version_compiled = WIRELESS_EXT;
540 range->we_version_source = WIRELESS_SUPPORT;
541
542
543
544#endif
545
546
547#if WIRELESS_EXT > 11
548
549
550 wl_unlock(lp, &flags);
551 wl_lock( lp, &flags );
552
553 DBG_TRACE( DbgInfo, "calling wl_wireless_stats\n" );
554 wl_wireless_stats( lp->dev );
555 range->avg_qual = lp->wstats.qual;
556 DBG_TRACE( DbgInfo, "wl_wireless_stats done\n" );
557
558#endif
559
560
561 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
562 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
563 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
564 range->event_capa[1] = IW_EVENT_CAPA_K_1;
565 range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
566 IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
567 IW_EVENT_CAPA_MASK(IWEVEXPIRED));
568
569 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
570
571out_unlock:
572 wl_act_int_on( lp );
573
574 wl_unlock(lp, &flags);
575
576 DBG_LEAVE(DbgInfo);
577 return ret;
578}
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601static int wireless_get_bssid(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra)
602{
603 struct wl_private *lp = wl_priv(dev);
604 unsigned long flags;
605 int ret = 0;
606#if 1
607 int status = -1;
608#endif
609
610
611
612 DBG_FUNC( "wireless_get_bssid" );
613 DBG_ENTER( DbgInfo );
614
615 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
616 ret = -EBUSY;
617 goto out;
618 }
619
620 wl_lock( lp, &flags );
621
622 wl_act_int_off( lp );
623
624 memset( &ap_addr->sa_data, 0, ETH_ALEN );
625
626 ap_addr->sa_family = ARPHRD_ETHER;
627
628
629
630
631 memcpy(&ap_addr->sa_data, lp->dev->dev_addr, ETH_ALEN);
632
633
634#if 1
635
636
637 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
638
639 lp->ltvRecord.typ = CFG_CUR_BSSID;
640 lp->ltvRecord.len = 4;
641 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
642
643 if( status == HCF_SUCCESS ) {
644
645 memcpy(&ap_addr->sa_data, lp->ltvRecord.u.u8, ETH_ALEN);
646 } else {
647 ret = -EFAULT;
648 }
649 }
650
651#endif
652
653 wl_act_int_on( lp );
654
655 wl_unlock(lp, &flags);
656
657out:
658 DBG_LEAVE(DbgInfo);
659 return ret;
660}
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689static int wireless_get_ap_list (struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra)
690{
691 struct wl_private *lp = wl_priv(dev);
692 unsigned long flags;
693 int ret;
694 int num_aps = -1;
695 int sec_count = 0;
696 hcf_32 count;
697 struct sockaddr *hwa = NULL;
698 struct iw_quality *qual = NULL;
699#ifdef WARP
700 ScanResult *p = &lp->scan_results;
701#else
702 ProbeResult *p = &lp->probe_results;
703#endif
704
705
706 DBG_FUNC( "wireless_get_ap_list" );
707 DBG_ENTER( DbgInfo );
708
709 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
710 ret = -EBUSY;
711 goto out;
712 }
713
714 wl_lock( lp, &flags );
715
716 wl_act_int_off( lp );
717
718
719 lp->scan_results.scan_complete = FALSE;
720 lp->probe_results.scan_complete = FALSE;
721
722 lp->ltvRecord.len = 2;
723 lp->ltvRecord.typ = CFG_SCAN_CHANNELS_2GHZ;
724 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x7FFF );
725 ret = hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
726 DBG_TRACE( DbgInfo, "CFG_SCAN_CHANNELS_2GHZ result: 0x%x\n", ret );
727
728
729
730 lp->ltvRecord.len = 2;
731 lp->ltvRecord.typ = CFG_SCAN_SSID;
732 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
733 ret = hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
734 DBG_TRACE( DbgInfo, "CFG_SCAN_SSID to 'any' ret: 0x%x\n", ret );
735
736
737#ifdef WARP
738 ret = hcf_action( &( lp->hcfCtx ), MDD_ACT_SCAN );
739#else
740 ret = hcf_action( &( lp->hcfCtx ), HCF_ACT_ACS_SCAN );
741#endif
742
743 wl_act_int_on( lp );
744
745
746 wl_unlock(lp, &flags);
747
748 if( ret == HCF_SUCCESS ) {
749 DBG_TRACE( DbgInfo, "SUCCESSFULLY INITIATED SCAN...\n" );
750 while( (*p).scan_complete == FALSE && ret == HCF_SUCCESS ) {
751 DBG_TRACE( DbgInfo, "Waiting for scan results...\n" );
752
753 if( sec_count++ > MAX_SCAN_TIME_SEC ) {
754 ret = -EIO;
755 } else {
756
757
758
759 for( count = 0; count < 100; count ++ ) {
760 mdelay( 10 );
761 schedule( );
762 }
763 }
764 }
765
766 rmb();
767
768 if ( ret != HCF_SUCCESS ) {
769 DBG_ERROR( DbgInfo, "timeout waiting for scan results\n" );
770 } else {
771 num_aps = (*p).num_aps;
772 if (num_aps > IW_MAX_AP) {
773 num_aps = IW_MAX_AP;
774 }
775 data->length = num_aps;
776 hwa = (struct sockaddr *)extra;
777 qual = (struct iw_quality *) extra +
778 ( sizeof( struct sockaddr ) * num_aps );
779
780
781
782
783
784
785 data->flags = 0;
786
787 for( count = 0; count < num_aps; count++ ) {
788#ifdef WARP
789 memcpy( hwa[count].sa_data,
790 (*p).APTable[count].bssid, ETH_ALEN );
791#else
792 DBG_PRINT("BSSID: %pM\n",
793 (*p).ProbeTable[count].BSSID);
794 memcpy( hwa[count].sa_data,
795 (*p).ProbeTable[count].BSSID, ETH_ALEN );
796#endif
797 }
798
799
800 (*p).scan_complete = FALSE;
801
802
803 wl_wext_event_scan_complete( lp->dev );
804 }
805 }
806out:
807 DBG_LEAVE( DbgInfo );
808 return ret;
809}
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834static int wireless_set_sensitivity(struct net_device *dev, struct iw_request_info *info, struct iw_param *sens, char *extra)
835{
836 struct wl_private *lp = wl_priv(dev);
837 unsigned long flags;
838 int ret = 0;
839 int dens = sens->value;
840
841
842
843 DBG_FUNC( "wireless_set_sensitivity" );
844 DBG_ENTER( DbgInfo );
845
846 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
847 ret = -EBUSY;
848 goto out;
849 }
850
851 if(( dens < 1 ) || ( dens > 3 )) {
852 ret = -EINVAL;
853 goto out;
854 }
855
856 wl_lock( lp, &flags );
857
858 wl_act_int_off( lp );
859
860 lp->DistanceBetweenAPs = dens;
861 wl_apply( lp );
862
863 wl_act_int_on( lp );
864
865 wl_unlock(lp, &flags);
866
867out:
868 DBG_LEAVE( DbgInfo );
869 return ret;
870}
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895static int wireless_get_sensitivity(struct net_device *dev, struct iw_request_info *info, struct iw_param *sens, char *extra)
896{
897 struct wl_private *lp = wl_priv(dev);
898 int ret = 0;
899
900
901
902
903 DBG_FUNC( "wireless_get_sensitivity" );
904 DBG_ENTER( DbgInfo );
905
906 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
907 ret = -EBUSY;
908 goto out;
909 }
910
911
912 sens->value = lp->DistanceBetweenAPs;
913 sens->fixed = 0;
914out:
915 DBG_LEAVE( DbgInfo );
916 return ret;
917}
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943static int wireless_set_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid)
944{
945 struct wl_private *lp = wl_priv(dev);
946 unsigned long flags;
947 int ret = 0;
948
949 DBG_FUNC( "wireless_set_essid" );
950 DBG_ENTER( DbgInfo );
951
952 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
953 ret = -EBUSY;
954 goto out;
955 }
956
957 if (data->flags != 0 && data->length > HCF_MAX_NAME_LEN + 1) {
958 ret = -EINVAL;
959 goto out;
960 }
961
962 wl_lock( lp, &flags );
963
964 wl_act_int_off( lp );
965
966 memset( lp->NetworkName, 0, sizeof( lp->NetworkName ));
967
968
969 if( data->flags == 0 ) {
970
971
972 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
973 strcpy( lp->NetworkName, "ANY" );
974 } else {
975
976 strcpy( lp->NetworkName, PARM_DEFAULT_SSID );
977 }
978 } else {
979 memcpy( lp->NetworkName, ssid, data->length );
980 }
981
982 DBG_NOTICE( DbgInfo, "set NetworkName: %s\n", ssid );
983
984
985 wl_apply( lp );
986
987
988 wl_wext_event_essid( lp->dev );
989
990 wl_act_int_on( lp );
991
992 wl_unlock(lp, &flags);
993
994out:
995 DBG_LEAVE( DbgInfo );
996 return ret;
997}
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023static int wireless_get_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *essid)
1024
1025{
1026 struct wl_private *lp = wl_priv(dev);
1027 unsigned long flags;
1028 int ret = 0;
1029 int status = -1;
1030 wvName_t *pName;
1031
1032
1033
1034 DBG_FUNC( "wireless_get_essid" );
1035 DBG_ENTER( DbgInfo );
1036
1037 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1038 ret = -EBUSY;
1039 goto out;
1040 }
1041
1042 wl_lock( lp, &flags );
1043
1044 wl_act_int_off( lp );
1045
1046
1047 lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
1048
1049
1050#if 1
1051
1052
1053 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1054
1055#endif
1056
1057
1058#if 1
1059
1060
1061 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1062 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1063 }
1064
1065#endif
1066
1067
1068 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1069 if( status == HCF_SUCCESS ) {
1070 pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
1071
1072
1073 pName->length = CNV_LITTLE_TO_INT( pName->length );
1074
1075
1076 data->length = pName->length;
1077
1078
1079
1080 data->length = pName->length + 1;
1081 if( pName->length < HCF_MAX_NAME_LEN ) {
1082 pName->name[pName->length] = '\0';
1083 }
1084
1085 data->flags = 1;
1086
1087
1088#if 1
1089
1090#ifdef RETURN_CURRENT_NETWORKNAME
1091
1092
1093 if( pName->name[0] == '\0' ) {
1094
1095 lp->ltvRecord.len = 1 + ( sizeof(*pName ) / sizeof( hcf_16 ));
1096 lp->ltvRecord.typ = CFG_CUR_SSID;
1097
1098 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1099
1100 if( status == HCF_SUCCESS ) {
1101 pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
1102
1103
1104 pName->length = CNV_LITTLE_TO_INT( pName->length );
1105
1106
1107 data->length = pName->length + 1;
1108 if( pName->length < HCF_MAX_NAME_LEN ) {
1109 pName->name[pName->length] = '\0';
1110 }
1111
1112 data->flags = 1;
1113 } else {
1114 ret = -EFAULT;
1115 goto out_unlock;
1116 }
1117 }
1118
1119#endif
1120#endif
1121
1122 data->length--;
1123
1124 if (pName->length > IW_ESSID_MAX_SIZE) {
1125 ret = -EFAULT;
1126 goto out_unlock;
1127 }
1128
1129 memcpy(essid, pName->name, pName->length);
1130 } else {
1131 ret = -EFAULT;
1132 goto out_unlock;
1133 }
1134
1135out_unlock:
1136 wl_act_int_on( lp );
1137
1138 wl_unlock(lp, &flags);
1139
1140out:
1141 DBG_LEAVE( DbgInfo );
1142 return ret;
1143}
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168static int wireless_set_encode(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *keybuf)
1169{
1170 struct wl_private *lp = wl_priv(dev);
1171 unsigned long flags;
1172 int ret = 0;
1173
1174#if 1
1175 hcf_8 encryption_state;
1176#endif
1177
1178
1179
1180 DBG_FUNC( "wireless_set_encode" );
1181 DBG_ENTER( DbgInfo );
1182
1183 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1184 ret = -EBUSY;
1185 goto out;
1186 }
1187
1188 wl_lock( lp, &flags );
1189
1190 wl_act_int_off( lp );
1191
1192
1193 if( !wl_has_wep( &( lp->hcfCtx ))) {
1194 DBG_WARNING( DbgInfo, "WEP not supported on this device\n" );
1195 ret = -EOPNOTSUPP;
1196 goto out_unlock;
1197 }
1198
1199 DBG_NOTICE( DbgInfo, "pointer: %p, length: %d, flags: %#x\n",
1200 keybuf, erq->length,
1201 erq->flags);
1202
1203
1204 encryption_state = lp->EnableEncryption;
1205
1206
1207 if((erq->length) != 0) {
1208 int index = ( erq->flags & IW_ENCODE_INDEX ) - 1;
1209 int tk = lp->TransmitKeyID - 1;
1210
1211
1212
1213 switch(erq->length) {
1214 case 0:
1215 break;
1216
1217 case MIN_KEY_SIZE:
1218 case MAX_KEY_SIZE:
1219
1220
1221 if(( index < 0 ) || ( index >= MAX_KEYS )) {
1222 index = tk;
1223 }
1224
1225
1226 memset( lp->DefaultKeys.key[index].key, 0, MAX_KEY_SIZE );
1227
1228
1229 memcpy( lp->DefaultKeys.key[index].key, keybuf, erq->length);
1230
1231
1232 lp->DefaultKeys.key[index].len = erq->length;
1233
1234 DBG_NOTICE( DbgInfo, "encoding.length: %d\n", erq->length );
1235 DBG_NOTICE( DbgInfo, "set key: %s(%d) [%d]\n", lp->DefaultKeys.key[index].key,
1236 lp->DefaultKeys.key[index].len, index );
1237
1238
1239 if(( index == tk ) && ( lp->DefaultKeys.key[tk].len > 0 )) {
1240 lp->EnableEncryption = 1;
1241 }
1242
1243 break;
1244
1245 default:
1246 DBG_WARNING( DbgInfo, "Invalid Key length\n" );
1247 ret = -EINVAL;
1248 goto out_unlock;
1249 }
1250 } else {
1251 int index = ( erq->flags & IW_ENCODE_INDEX ) - 1;
1252
1253
1254
1255 if(( index >= 0 ) && ( index < MAX_KEYS )) {
1256 DBG_NOTICE( DbgInfo, "index: %d; len: %d\n", index,
1257 lp->DefaultKeys.key[index].len );
1258
1259 if( lp->DefaultKeys.key[index].len > 0 ) {
1260 lp->TransmitKeyID = index + 1;
1261 lp->EnableEncryption = 1;
1262 } else {
1263 DBG_WARNING( DbgInfo, "Problem setting the current TxKey\n" );
1264 DBG_LEAVE( DbgInfo );
1265 ret = -EINVAL;
1266 }
1267 }
1268 }
1269
1270
1271 if( erq->flags & IW_ENCODE_DISABLED ) {
1272 lp->EnableEncryption = 0;
1273 } else {
1274 lp->EnableEncryption = 1;
1275 }
1276
1277 if( erq->flags & IW_ENCODE_RESTRICTED ) {
1278 DBG_WARNING( DbgInfo, "IW_ENCODE_RESTRICTED invalid\n" );
1279 ret = -EINVAL;
1280 }
1281
1282 DBG_TRACE( DbgInfo, "encryption_state : %d\n", encryption_state );
1283 DBG_TRACE( DbgInfo, "lp->EnableEncryption : %d\n", lp->EnableEncryption );
1284 DBG_TRACE( DbgInfo, "erq->length : %d\n",
1285 erq->length);
1286 DBG_TRACE( DbgInfo, "erq->flags : 0x%x\n",
1287 erq->flags);
1288
1289
1290 if( ret == 0 ) {
1291 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption,
1292 lp->TransmitKeyID );
1293
1294 if( lp->EnableEncryption == encryption_state ) {
1295 if( erq->length != 0 ) {
1296
1297 wl_set_wep_keys( lp );
1298 }
1299 } else {
1300
1301 wl_apply( lp );
1302 }
1303 }
1304
1305
1306 wl_wext_event_encode( dev );
1307
1308out_unlock:
1309
1310 wl_act_int_on( lp );
1311
1312 wl_unlock(lp, &flags);
1313
1314out:
1315 DBG_LEAVE( DbgInfo );
1316 return ret;
1317}
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342static int wireless_get_encode(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *key)
1343
1344{
1345 struct wl_private *lp = wl_priv(dev);
1346 unsigned long flags;
1347 int ret = 0;
1348 int index;
1349
1350
1351
1352 DBG_FUNC( "wireless_get_encode" );
1353 DBG_ENTER( DbgInfo );
1354 DBG_NOTICE(DbgInfo, "GIWENCODE: encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID);
1355
1356 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1357 ret = -EBUSY;
1358 goto out;
1359 }
1360
1361
1362 if( !capable( CAP_NET_ADMIN )) {
1363 ret = -EPERM;
1364 DBG_LEAVE( DbgInfo );
1365 return ret;
1366 }
1367
1368 wl_lock( lp, &flags );
1369
1370 wl_act_int_off( lp );
1371
1372
1373 if( !wl_has_wep( &( lp->hcfCtx ))) {
1374 ret = -EOPNOTSUPP;
1375 goto out_unlock;
1376 }
1377
1378
1379 index = (erq->flags & IW_ENCODE_INDEX ) - 1;
1380
1381
1382
1383 erq->flags = 0;
1384
1385 if( lp->EnableEncryption == 0 ) {
1386 erq->flags |= IW_ENCODE_DISABLED;
1387 }
1388
1389
1390 if(( index < 0 ) || ( index >= MAX_KEYS )) {
1391 index = lp->TransmitKeyID - 1;
1392 }
1393
1394 erq->flags |= index + 1;
1395
1396
1397 erq->length = lp->DefaultKeys.key[index].len;
1398
1399 memcpy(key, lp->DefaultKeys.key[index].key, erq->length);
1400
1401out_unlock:
1402
1403 wl_act_int_on( lp );
1404
1405 wl_unlock(lp, &flags);
1406
1407out:
1408 DBG_LEAVE( DbgInfo );
1409 return ret;
1410}
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435static int wireless_set_nickname(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *nickname)
1436{
1437 struct wl_private *lp = wl_priv(dev);
1438 unsigned long flags;
1439 int ret = 0;
1440
1441
1442
1443 DBG_FUNC( "wireless_set_nickname" );
1444 DBG_ENTER( DbgInfo );
1445
1446 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1447 ret = -EBUSY;
1448 goto out;
1449 }
1450
1451#if 0
1452 if( !capable(CAP_NET_ADMIN )) {
1453 ret = -EPERM;
1454 DBG_LEAVE( DbgInfo );
1455 return ret;
1456 }
1457#endif
1458
1459
1460 if(data->length > HCF_MAX_NAME_LEN) {
1461 ret = -EINVAL;
1462 goto out;
1463 }
1464
1465 wl_lock( lp, &flags );
1466
1467 wl_act_int_off( lp );
1468
1469 memset( lp->StationName, 0, sizeof( lp->StationName ));
1470
1471 memcpy( lp->StationName, nickname, data->length );
1472
1473
1474 wl_apply( lp );
1475
1476 wl_act_int_on( lp );
1477
1478 wl_unlock(lp, &flags);
1479
1480out:
1481 DBG_LEAVE( DbgInfo );
1482 return ret;
1483}
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508static int wireless_get_nickname(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *nickname)
1509{
1510 struct wl_private *lp = wl_priv(dev);
1511 unsigned long flags;
1512 int ret = 0;
1513 int status = -1;
1514 wvName_t *pName;
1515
1516
1517
1518 DBG_FUNC( "wireless_get_nickname" );
1519 DBG_ENTER( DbgInfo );
1520
1521 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1522 ret = -EBUSY;
1523 goto out;
1524 }
1525
1526 wl_lock( lp, &flags );
1527
1528 wl_act_int_off( lp );
1529
1530
1531 lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
1532 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1533
1534 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1535
1536 if( status == HCF_SUCCESS ) {
1537 pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
1538
1539
1540 pName->length = CNV_LITTLE_TO_INT( pName->length );
1541
1542 if ( pName->length > IW_ESSID_MAX_SIZE ) {
1543 ret = -EFAULT;
1544 } else {
1545
1546 data->length = pName->length;
1547 memcpy(nickname, pName->name, pName->length);
1548 }
1549 } else {
1550 ret = -EFAULT;
1551 }
1552
1553 wl_act_int_on( lp );
1554
1555 wl_unlock(lp, &flags);
1556
1557out:
1558 DBG_LEAVE(DbgInfo);
1559 return ret;
1560}
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585static int wireless_set_porttype(struct net_device *dev, struct iw_request_info *info, __u32 *mode, char *extra)
1586{
1587 struct wl_private *lp = wl_priv(dev);
1588 unsigned long flags;
1589 int ret = 0;
1590 hcf_16 portType;
1591 hcf_16 createIBSS;
1592
1593
1594 DBG_FUNC( "wireless_set_porttype" );
1595 DBG_ENTER( DbgInfo );
1596
1597 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1598 ret = -EBUSY;
1599 goto out;
1600 }
1601
1602 wl_lock( lp, &flags );
1603
1604 wl_act_int_off( lp );
1605
1606
1607 switch( *mode ) {
1608 case IW_MODE_ADHOC:
1609
1610
1611 portType = 1;
1612 createIBSS = 1;
1613
1614 lp->DownloadFirmware = WVLAN_DRV_MODE_STA;
1615
1616 break;
1617
1618
1619 case IW_MODE_AUTO:
1620 case IW_MODE_INFRA:
1621
1622
1623 portType = 1;
1624 createIBSS = 0;
1625
1626 lp->DownloadFirmware = WVLAN_DRV_MODE_STA;
1627
1628 break;
1629
1630
1631#if 0
1632
1633 case IW_MODE_MASTER:
1634
1635
1636 portType = 1;
1637
1638 lp->CreateIBSS = 0;
1639 lp->DownloadFirmware = WVLAN_DRV_MODE_AP;
1640
1641 break;
1642
1643#endif
1644
1645
1646 default:
1647
1648 portType = 0;
1649 createIBSS = 0;
1650 ret = -EINVAL;
1651 }
1652
1653 if( portType != 0 ) {
1654
1655 if( ( lp->PortType != portType ) || (lp->CreateIBSS != createIBSS)) {
1656 lp->PortType = portType;
1657 lp->CreateIBSS = createIBSS;
1658
1659
1660 wl_go( lp );
1661
1662
1663 wl_wext_event_mode( lp->dev );
1664 }
1665 }
1666
1667 wl_act_int_on( lp );
1668
1669 wl_unlock(lp, &flags);
1670
1671out:
1672 DBG_LEAVE( DbgInfo );
1673 return ret;
1674}
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699static int wireless_get_porttype(struct net_device *dev, struct iw_request_info *info, __u32 *mode, char *extra)
1700
1701{
1702 struct wl_private *lp = wl_priv(dev);
1703 unsigned long flags;
1704 int ret = 0;
1705 int status = -1;
1706 hcf_16 *pPortType;
1707
1708
1709
1710 DBG_FUNC( "wireless_get_porttype" );
1711 DBG_ENTER( DbgInfo );
1712
1713 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1714 ret = -EBUSY;
1715 goto out;
1716 }
1717
1718 wl_lock( lp, &flags );
1719
1720 wl_act_int_off( lp );
1721
1722
1723 lp->ltvRecord.len = 1 + ( sizeof( *pPortType ) / sizeof( hcf_16 ));
1724 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1725
1726 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1727
1728 if( status == HCF_SUCCESS ) {
1729 pPortType = (hcf_16 *)&( lp->ltvRecord.u.u32 );
1730
1731 *pPortType = CNV_LITTLE_TO_INT( *pPortType );
1732
1733 switch( *pPortType ) {
1734 case 1:
1735
1736#if 0
1737#if (HCF_TYPE) & HCF_TYPE_AP
1738
1739 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1740 *mode = IW_MODE_MASTER;
1741 } else {
1742 *mode = IW_MODE_INFRA;
1743 }
1744
1745#else
1746
1747 *mode = IW_MODE_INFRA;
1748
1749#endif
1750#endif
1751
1752 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1753 *mode = IW_MODE_MASTER;
1754 } else {
1755 if( lp->CreateIBSS ) {
1756 *mode = IW_MODE_ADHOC;
1757 } else {
1758 *mode = IW_MODE_INFRA;
1759 }
1760 }
1761
1762 break;
1763
1764
1765 case 3:
1766 *mode = IW_MODE_ADHOC;
1767 break;
1768
1769 default:
1770 ret = -EFAULT;
1771 break;
1772 }
1773 } else {
1774 ret = -EFAULT;
1775 }
1776
1777 wl_act_int_on( lp );
1778
1779 wl_unlock(lp, &flags);
1780
1781out:
1782 DBG_LEAVE( DbgInfo );
1783 return ret;
1784}
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809static int wireless_set_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra)
1810{
1811 struct wl_private *lp = wl_priv(dev);
1812 unsigned long flags;
1813 int ret = 0;
1814
1815
1816
1817 DBG_FUNC( "wireless_set_power" );
1818 DBG_ENTER( DbgInfo );
1819
1820 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1821 ret = -EBUSY;
1822 goto out;
1823 }
1824
1825 DBG_PRINT( "THIS CORRUPTS PMEnabled ;?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" );
1826
1827#if 0
1828 if( !capable( CAP_NET_ADMIN )) {
1829 ret = -EPERM;
1830
1831 DBG_LEAVE( DbgInfo );
1832 return ret;
1833 }
1834#endif
1835
1836 wl_lock( lp, &flags );
1837
1838 wl_act_int_off( lp );
1839
1840
1841 if( wrq->disabled ) {
1842 lp->PMEnabled = 0;
1843 } else {
1844 lp->PMEnabled = 1;
1845 }
1846
1847
1848 wl_apply( lp );
1849
1850 wl_act_int_on( lp );
1851
1852 wl_unlock(lp, &flags);
1853
1854out:
1855 DBG_LEAVE( DbgInfo );
1856 return ret;
1857}
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882static int wireless_get_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
1883
1884{
1885 struct wl_private *lp = wl_priv(dev);
1886 unsigned long flags;
1887 int ret = 0;
1888
1889 DBG_FUNC( "wireless_get_power" );
1890 DBG_ENTER( DbgInfo );
1891
1892 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1893 ret = -EBUSY;
1894 goto out;
1895 }
1896
1897 DBG_PRINT( "THIS IS PROBABLY AN OVER-SIMPLIFICATION ;?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" );
1898
1899 wl_lock( lp, &flags );
1900
1901 wl_act_int_off( lp );
1902
1903 rrq->flags = 0;
1904 rrq->value = 0;
1905
1906 if( lp->PMEnabled ) {
1907 rrq->disabled = 0;
1908 } else {
1909 rrq->disabled = 1;
1910 }
1911
1912 wl_act_int_on( lp );
1913
1914 wl_unlock(lp, &flags);
1915
1916out:
1917 DBG_LEAVE( DbgInfo );
1918 return ret;
1919}
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944static int wireless_get_tx_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
1945{
1946 struct wl_private *lp = wl_priv(dev);
1947 unsigned long flags;
1948 int ret = 0;
1949
1950 DBG_FUNC( "wireless_get_tx_power" );
1951 DBG_ENTER( DbgInfo );
1952
1953 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
1954 ret = -EBUSY;
1955 goto out;
1956 }
1957
1958 wl_lock( lp, &flags );
1959
1960 wl_act_int_off( lp );
1961
1962#ifdef USE_POWER_DBM
1963 rrq->value = RADIO_TX_POWER_DBM;
1964 rrq->flags = IW_TXPOW_DBM;
1965#else
1966 rrq->value = RADIO_TX_POWER_MWATT;
1967 rrq->flags = IW_TXPOW_MWATT;
1968#endif
1969 rrq->fixed = 1;
1970 rrq->disabled = 0;
1971
1972 wl_act_int_on( lp );
1973
1974 wl_unlock(lp, &flags);
1975
1976out:
1977 DBG_LEAVE( DbgInfo );
1978 return ret;
1979}
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004static int wireless_set_rts_threshold (struct net_device *dev, struct iw_request_info *info, struct iw_param *rts, char *extra)
2005{
2006 int ret = 0;
2007 struct wl_private *lp = wl_priv(dev);
2008 unsigned long flags;
2009 int rthr = rts->value;
2010
2011
2012
2013 DBG_FUNC( "wireless_set_rts_threshold" );
2014 DBG_ENTER( DbgInfo );
2015
2016 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
2017 ret = -EBUSY;
2018 goto out;
2019 }
2020
2021 if(rts->fixed == 0) {
2022 ret = -EINVAL;
2023 goto out;
2024 }
2025
2026#if WIRELESS_EXT > 8
2027 if( rts->disabled ) {
2028 rthr = 2347;
2029 }
2030#endif
2031
2032 if(( rthr < 256 ) || ( rthr > 2347 )) {
2033 ret = -EINVAL;
2034 goto out;
2035 }
2036
2037 wl_lock( lp, &flags );
2038
2039 wl_act_int_off( lp );
2040
2041 lp->RTSThreshold = rthr;
2042
2043 wl_apply( lp );
2044
2045 wl_act_int_on( lp );
2046
2047 wl_unlock(lp, &flags);
2048
2049out:
2050 DBG_LEAVE( DbgInfo );
2051 return ret;
2052}
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077static int wireless_get_rts_threshold (struct net_device *dev, struct iw_request_info *info, struct iw_param *rts, char *extra)
2078{
2079 int ret = 0;
2080 struct wl_private *lp = wl_priv(dev);
2081 unsigned long flags;
2082
2083
2084 DBG_FUNC( "wireless_get_rts_threshold" );
2085 DBG_ENTER( DbgInfo );
2086
2087 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
2088 ret = -EBUSY;
2089 goto out;
2090 }
2091
2092 wl_lock( lp, &flags );
2093
2094 wl_act_int_off( lp );
2095
2096 rts->value = lp->RTSThreshold;
2097
2098#if WIRELESS_EXT > 8
2099
2100 rts->disabled = ( rts->value == 2347 );
2101
2102#endif
2103
2104 rts->fixed = 1;
2105
2106 wl_act_int_on( lp );
2107
2108 wl_unlock(lp, &flags);
2109
2110out:
2111 DBG_LEAVE( DbgInfo );
2112 return ret;
2113}
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139static int wireless_set_rate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
2140{
2141 struct wl_private *lp = wl_priv(dev);
2142 unsigned long flags;
2143 int ret = 0;
2144#ifdef WARP
2145 int status = -1;
2146 int index = 0;
2147#endif
2148
2149
2150
2151 DBG_FUNC( "wireless_set_rate" );
2152 DBG_ENTER( DbgInfo );
2153
2154 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
2155 ret = -EBUSY;
2156 goto out;
2157 }
2158
2159 wl_lock( lp, &flags );
2160
2161 wl_act_int_off( lp );
2162
2163#ifdef WARP
2164
2165
2166
2167 lp->ltvRecord.len = 2;
2168 lp->ltvRecord.typ = CFG_CUR_CHANNEL;
2169
2170 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
2171
2172 if( status == HCF_SUCCESS ) {
2173 index = ( CNV_LITTLE_TO_INT( lp->ltvRecord.u.u16[0] ) & 0x100 ) ? 1 : 0;
2174
2175 DBG_PRINT( "Index: %d\n", index );
2176 } else {
2177 DBG_ERROR( DbgInfo, "Could not determine radio frequency\n" );
2178 DBG_LEAVE( DbgInfo );
2179 ret = -EINVAL;
2180 goto out_unlock;
2181 }
2182
2183 if( rrq->value > 0 &&
2184 rrq->value <= 1 * MEGABIT ) {
2185 lp->TxRateControl[index] = 0x0001;
2186 }
2187 else if( rrq->value > 1 * MEGABIT &&
2188 rrq->value <= 2 * MEGABIT ) {
2189 if( rrq->fixed == 1 ) {
2190 lp->TxRateControl[index] = 0x0002;
2191 } else {
2192 lp->TxRateControl[index] = 0x0003;
2193 }
2194 }
2195 else if( rrq->value > 2 * MEGABIT &&
2196 rrq->value <= 5 * MEGABIT ) {
2197 if( rrq->fixed == 1 ) {
2198 lp->TxRateControl[index] = 0x0004;
2199 } else {
2200 lp->TxRateControl[index] = 0x0007;
2201 }
2202 }
2203 else if( rrq->value > 5 * MEGABIT &&
2204 rrq->value <= 6 * MEGABIT ) {
2205 if( rrq->fixed == 1 ) {
2206 lp->TxRateControl[index] = 0x0010;
2207 } else {
2208 lp->TxRateControl[index] = 0x0017;
2209 }
2210 }
2211 else if( rrq->value > 6 * MEGABIT &&
2212 rrq->value <= 9 * MEGABIT ) {
2213 if( rrq->fixed == 1 ) {
2214 lp->TxRateControl[index] = 0x0020;
2215 } else {
2216 lp->TxRateControl[index] = 0x0037;
2217 }
2218 }
2219 else if( rrq->value > 9 * MEGABIT &&
2220 rrq->value <= 11 * MEGABIT ) {
2221 if( rrq->fixed == 1 ) {
2222 lp->TxRateControl[index] = 0x0008;
2223 } else {
2224 lp->TxRateControl[index] = 0x003F;
2225 }
2226 }
2227 else if( rrq->value > 11 * MEGABIT &&
2228 rrq->value <= 12 * MEGABIT ) {
2229 if( rrq->fixed == 1 ) {
2230 lp->TxRateControl[index] = 0x0040;
2231 } else {
2232 lp->TxRateControl[index] = 0x007F;
2233 }
2234 }
2235 else if( rrq->value > 12 * MEGABIT &&
2236 rrq->value <= 18 * MEGABIT ) {
2237 if( rrq->fixed == 1 ) {
2238 lp->TxRateControl[index] = 0x0080;
2239 } else {
2240 lp->TxRateControl[index] = 0x00FF;
2241 }
2242 }
2243 else if( rrq->value > 18 * MEGABIT &&
2244 rrq->value <= 24 * MEGABIT ) {
2245 if( rrq->fixed == 1 ) {
2246 lp->TxRateControl[index] = 0x0100;
2247 } else {
2248 lp->TxRateControl[index] = 0x01FF;
2249 }
2250 }
2251 else if( rrq->value > 24 * MEGABIT &&
2252 rrq->value <= 36 * MEGABIT ) {
2253 if( rrq->fixed == 1 ) {
2254 lp->TxRateControl[index] = 0x0200;
2255 } else {
2256 lp->TxRateControl[index] = 0x03FF;
2257 }
2258 }
2259 else if( rrq->value > 36 * MEGABIT &&
2260 rrq->value <= 48 * MEGABIT ) {
2261 if( rrq->fixed == 1 ) {
2262 lp->TxRateControl[index] = 0x0400;
2263 } else {
2264 lp->TxRateControl[index] = 0x07FF;
2265 }
2266 }
2267 else if( rrq->value > 48 * MEGABIT &&
2268 rrq->value <= 54 * MEGABIT ) {
2269 if( rrq->fixed == 1 ) {
2270 lp->TxRateControl[index] = 0x0800;
2271 } else {
2272 lp->TxRateControl[index] = 0x0FFF;
2273 }
2274 }
2275 else if( rrq->fixed == 0 ) {
2276
2277
2278 lp->TxRateControl[index] = PARM_MAX_TX_RATE;
2279 } else {
2280 rrq->value = 0;
2281 ret = -EINVAL;
2282 goto out_unlock;
2283 }
2284
2285
2286#else
2287
2288 if( rrq->value > 0 &&
2289 rrq->value <= 1 * MEGABIT ) {
2290 lp->TxRateControl[0] = 1;
2291 }
2292 else if( rrq->value > 1 * MEGABIT &&
2293 rrq->value <= 2 * MEGABIT ) {
2294 if( rrq->fixed ) {
2295 lp->TxRateControl[0] = 2;
2296 } else {
2297 lp->TxRateControl[0] = 6;
2298 }
2299 }
2300 else if( rrq->value > 2 * MEGABIT &&
2301 rrq->value <= 5 * MEGABIT ) {
2302 if( rrq->fixed ) {
2303 lp->TxRateControl[0] = 4;
2304 } else {
2305 lp->TxRateControl[0] = 7;
2306 }
2307 }
2308 else if( rrq->value > 5 * MEGABIT &&
2309 rrq->value <= 11 * MEGABIT ) {
2310 if( rrq->fixed) {
2311 lp->TxRateControl[0] = 5;
2312 } else {
2313 lp->TxRateControl[0] = 3;
2314 }
2315 }
2316 else if( rrq->fixed == 0 ) {
2317
2318
2319 lp->TxRateControl[0] = 3;
2320 } else {
2321 rrq->value = 0;
2322 ret = -EINVAL;
2323 goto out_unlock;
2324 }
2325
2326#endif
2327
2328
2329
2330 wl_apply( lp );
2331
2332out_unlock:
2333
2334 wl_act_int_on( lp );
2335
2336 wl_unlock(lp, &flags);
2337
2338out:
2339 DBG_LEAVE( DbgInfo );
2340 return ret;
2341}
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366static int wireless_get_rate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra)
2367
2368{
2369 struct wl_private *lp = wl_priv(dev);
2370 unsigned long flags;
2371 int ret = 0;
2372 int status = -1;
2373 hcf_16 txRate;
2374
2375
2376
2377 DBG_FUNC( "wireless_get_rate" );
2378 DBG_ENTER( DbgInfo );
2379
2380 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
2381 ret = -EBUSY;
2382 goto out;
2383 }
2384
2385 wl_lock( lp, &flags );
2386
2387 wl_act_int_off( lp );
2388
2389
2390 lp->ltvRecord.len = 1 + ( sizeof(txRate)/sizeof(hcf_16));
2391 lp->ltvRecord.typ = CFG_CUR_TX_RATE;
2392
2393 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
2394
2395 if( status == HCF_SUCCESS ) {
2396#ifdef WARP
2397
2398 txRate = CNV_LITTLE_TO_INT( lp->ltvRecord.u.u16[0] );
2399
2400 if( txRate & 0x0001 ) {
2401 txRate = 1;
2402 }
2403 else if( txRate & 0x0002 ) {
2404 txRate = 2;
2405 }
2406 else if( txRate & 0x0004 ) {
2407 txRate = 5;
2408 }
2409 else if( txRate & 0x0008 ) {
2410 txRate = 11;
2411 }
2412 else if( txRate & 0x00010 ) {
2413 txRate = 6;
2414 }
2415 else if( txRate & 0x00020 ) {
2416 txRate = 9;
2417 }
2418 else if( txRate & 0x00040 ) {
2419 txRate = 12;
2420 }
2421 else if( txRate & 0x00080 ) {
2422 txRate = 18;
2423 }
2424 else if( txRate & 0x00100 ) {
2425 txRate = 24;
2426 }
2427 else if( txRate & 0x00200 ) {
2428 txRate = 36;
2429 }
2430 else if( txRate & 0x00400 ) {
2431 txRate = 48;
2432 }
2433 else if( txRate & 0x00800 ) {
2434 txRate = 54;
2435 }
2436
2437#else
2438
2439 txRate = (hcf_16)CNV_LITTLE_TO_LONG( lp->ltvRecord.u.u32[0] );
2440
2441#endif
2442
2443 rrq->value = txRate * MEGABIT;
2444 } else {
2445 rrq->value = 0;
2446 ret = -EFAULT;
2447 }
2448
2449 wl_act_int_on( lp );
2450
2451 wl_unlock(lp, &flags);
2452
2453out:
2454 DBG_LEAVE( DbgInfo );
2455 return ret;
2456}
2457
2458
2459
2460
2461
2462#if 0
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483int wireless_get_private_interface( struct iwreq *wrq, struct wl_private *lp )
2484{
2485 int ret = 0;
2486
2487
2488
2489 DBG_FUNC( "wireless_get_private_interface" );
2490 DBG_ENTER( DbgInfo );
2491
2492 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
2493 ret = -EBUSY;
2494 goto out;
2495 }
2496
2497 if( wrq->u.data.pointer != NULL ) {
2498 struct iw_priv_args priv[] =
2499 {
2500 { SIOCSIWNETNAME, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, 0, "snetwork_name" },
2501 { SIOCGIWNETNAME, 0, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, "gnetwork_name" },
2502 { SIOCSIWSTANAME, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, 0, "sstation_name" },
2503 { SIOCGIWSTANAME, 0, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, "gstation_name" },
2504 { SIOCSIWPORTTYPE, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "sport_type" },
2505 { SIOCGIWPORTTYPE, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "gport_type" },
2506 };
2507
2508
2509 ret = verify_area( VERIFY_WRITE, wrq->u.data.pointer, sizeof( priv ));
2510
2511 if( ret != 0 ) {
2512 DBG_LEAVE( DbgInfo );
2513 return ret;
2514 }
2515
2516
2517 wrq->u.data.length = NELEM( priv );
2518 copy_to_user( wrq->u.data.pointer, &priv, sizeof( priv ));
2519 }
2520
2521out:
2522 DBG_LEAVE( DbgInfo );
2523 return ret;
2524}
2525
2526#endif
2527
2528
2529
2530#if WIRELESS_EXT > 13
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551static int wireless_set_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra)
2552{
2553 struct wl_private *lp = wl_priv(dev);
2554 unsigned long flags;
2555 int ret = 0;
2556 int status = -1;
2557 int retries = 0;
2558
2559
2560
2561
2562 DBG_FUNC( "wireless_set_scan" );
2563 DBG_ENTER( DbgInfo );
2564
2565 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
2566 ret = -EBUSY;
2567 goto out;
2568 }
2569
2570 wl_lock( lp, &flags );
2571
2572 wl_act_int_off( lp );
2573
2574
2575
2576
2577
2578
2579
2580
2581 if((lp->hcfCtx.IFB_CardStat & CARD_STAT_DEFUNCT) != 0)
2582 {
2583 DBG_TRACE( DbgInfo, "CARD is in DEFUNCT mode, reset it to bring it back to life\n" );
2584 wl_reset( dev );
2585 }
2586
2587retry:
2588
2589 lp->probe_results.scan_complete = FALSE;
2590
2591
2592
2593#ifdef WARP
2594 lp->ltvRecord.len = 5;
2595 lp->ltvRecord.typ = CFG_SCAN_CHANNEL;
2596 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x3FFF );
2597 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( 0xFFFF );
2598 lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( 0xFFFF );
2599 lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( 0x0007 );
2600#else
2601 lp->ltvRecord.len = 2;
2602 lp->ltvRecord.typ = CFG_SCAN_CHANNEL;
2603 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x7FFF );
2604#endif
2605
2606 status = hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
2607
2608 DBG_TRACE( DbgInfo, "CFG_SCAN_CHANNEL result : 0x%x\n", status );
2609
2610
2611 wl_unlock(lp, &flags);
2612 wl_lock( lp, &flags );
2613
2614 if( status != HCF_SUCCESS ) {
2615
2616 retries++;
2617 if(retries <= 10) {
2618 DBG_TRACE( DbgInfo, "Reset card to recover, attempt: %d\n", retries );
2619 wl_reset( dev );
2620
2621
2622 wl_unlock(lp, &flags);
2623 wl_lock( lp, &flags );
2624
2625 goto retry;
2626 }
2627 }
2628
2629
2630
2631 lp->ltvRecord.len = 18;
2632 lp->ltvRecord.typ = CFG_SCAN_SSID;
2633 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
2634 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( 0 );
2635
2636 status = hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
2637
2638
2639 wl_unlock(lp, &flags);
2640 wl_lock( lp, &flags );
2641
2642 DBG_TRACE( DbgInfo, "CFG_SCAN_SSID to 'any' status: 0x%x\n", status );
2643
2644
2645
2646
2647 status = hcf_action( &( lp->hcfCtx ), HCF_ACT_ACS_SCAN );
2648
2649 if( status == HCF_SUCCESS ) {
2650 DBG_TRACE( DbgInfo, "SUCCESSFULLY INITIATED SCAN...\n" );
2651 } else {
2652 DBG_TRACE( DbgInfo, "INITIATE SCAN FAILED...\n" );
2653 }
2654
2655 wl_act_int_on( lp );
2656
2657 wl_unlock(lp, &flags);
2658
2659out:
2660 DBG_LEAVE(DbgInfo);
2661 return ret;
2662}
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687static int wireless_get_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra)
2688{
2689 struct wl_private *lp = wl_priv(dev);
2690 unsigned long flags;
2691 int ret = 0;
2692 int count;
2693 char *buf;
2694 char *buf_end;
2695 struct iw_event iwe;
2696 PROBE_RESP *probe_resp;
2697 hcf_8 msg[512];
2698 hcf_8 *wpa_ie;
2699 hcf_16 wpa_ie_len;
2700
2701
2702
2703 DBG_FUNC( "wireless_get_scan" );
2704 DBG_ENTER( DbgInfo );
2705
2706 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
2707 ret = -EBUSY;
2708 goto out;
2709 }
2710
2711 wl_lock( lp, &flags );
2712
2713 wl_act_int_off( lp );
2714
2715
2716 if( !lp->probe_results.scan_complete ) {
2717 ret = -EAGAIN;
2718 goto out_unlock;
2719 }
2720
2721 DBG_TRACE( DbgInfo, "SCAN COMPLETE, Num of APs: %d\n",
2722 lp->probe_results.num_aps );
2723
2724 buf = extra;
2725 buf_end = extra + IW_SCAN_MAX_DATA;
2726
2727 for( count = 0; count < lp->probe_results.num_aps; count++ ) {
2728
2729 probe_resp = (PROBE_RESP *)&lp->probe_results.ProbeTable[count];
2730
2731
2732
2733 memset( &iwe, 0, sizeof( iwe ));
2734
2735 iwe.cmd = SIOCGIWAP;
2736 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2737 memcpy( iwe.u.ap_addr.sa_data, probe_resp->BSSID, ETH_ALEN);
2738 iwe.len = IW_EV_ADDR_LEN;
2739
2740 buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_ADDR_LEN);
2741
2742
2743
2744
2745 memset( &iwe, 0, sizeof( iwe ));
2746
2747 iwe.cmd = SIOCGIWMODE;
2748
2749 if( probe_resp->capability & CAPABILITY_IBSS ) {
2750 iwe.u.mode = IW_MODE_INFRA;
2751 } else {
2752 iwe.u.mode = IW_MODE_MASTER;
2753 }
2754
2755 iwe.len = IW_EV_UINT_LEN;
2756
2757 buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_UINT_LEN);
2758
2759
2760
2761 memset(&iwe, 0, sizeof(iwe));
2762
2763 iwe.cmd = IWEVQUAL;
2764 iwe.u.qual.level = dbm(probe_resp->signal);
2765 iwe.u.qual.noise = dbm(probe_resp->silence);
2766 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
2767 iwe.u.qual.updated = lp->probe_results.scan_complete | IW_QUAL_DBM;
2768 iwe.len = IW_EV_QUAL_LEN;
2769
2770 buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_QUAL_LEN);
2771
2772
2773
2774 if( probe_resp->rawData[1] > 0 ) {
2775 memset( &iwe, 0, sizeof( iwe ));
2776
2777 iwe.cmd = SIOCGIWESSID;
2778 iwe.u.data.length = probe_resp->rawData[1];
2779 iwe.u.data.flags = 1;
2780
2781 buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, &probe_resp->rawData[2]);
2782 }
2783
2784
2785
2786 memset( &iwe, 0, sizeof( iwe ));
2787
2788 iwe.cmd = SIOCGIWENCODE;
2789 iwe.u.data.length = 0;
2790
2791
2792
2793 if( probe_resp->capability & CAPABILITY_PRIVACY ) {
2794 iwe.u.data.flags |= IW_ENCODE_ENABLED;
2795 } else {
2796 iwe.u.data.flags |= IW_ENCODE_DISABLED;
2797 }
2798
2799 buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, NULL);
2800
2801
2802
2803 memset( &iwe, 0, sizeof( iwe ));
2804
2805 iwe.cmd = SIOCGIWFREQ;
2806 iwe.len = IW_EV_FREQ_LEN;
2807 iwe.u.freq.m = wl_parse_ds_ie( probe_resp );
2808 iwe.u.freq.e = 0;
2809
2810 buf = IWE_STREAM_ADD_EVENT(info, buf, buf_end, &iwe, IW_EV_FREQ_LEN);
2811
2812
2813#if WIRELESS_EXT > 14
2814
2815 memset( &iwe, 0, sizeof( iwe ));
2816 memset( msg, 0, sizeof( msg ));
2817
2818 iwe.cmd = IWEVCUSTOM;
2819 sprintf( msg, "beacon_interval=%d", probe_resp->beaconInterval );
2820 iwe.u.data.length = strlen( msg );
2821
2822 buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, msg);
2823
2824
2825
2826 wpa_ie = NULL;
2827 wpa_ie_len = 0;
2828
2829 wpa_ie = wl_parse_wpa_ie( probe_resp, &wpa_ie_len );
2830 if( wpa_ie != NULL ) {
2831 memset( &iwe, 0, sizeof( iwe ));
2832 memset( msg, 0, sizeof( msg ));
2833
2834 iwe.cmd = IWEVCUSTOM;
2835 sprintf( msg, "wpa_ie=%s", wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
2836 iwe.u.data.length = strlen( msg );
2837
2838 buf = IWE_STREAM_ADD_POINT(info, buf, buf_end, &iwe, msg);
2839 }
2840
2841
2842#endif
2843 }
2844
2845 data->length = buf - extra;
2846
2847out_unlock:
2848
2849 wl_act_int_on( lp );
2850
2851 wl_unlock(lp, &flags);
2852
2853out:
2854 DBG_LEAVE( DbgInfo );
2855 return ret;
2856}
2857
2858
2859#endif
2860
2861
2862#if WIRELESS_EXT > 17
2863
2864static int wireless_set_auth(struct net_device *dev,
2865 struct iw_request_info *info,
2866 struct iw_param *data, char *extra)
2867{
2868 struct wl_private *lp = wl_priv(dev);
2869 unsigned long flags;
2870 int ret;
2871 int iwa_idx = data->flags & IW_AUTH_INDEX;
2872 int iwa_val = data->value;
2873
2874 DBG_FUNC( "wireless_set_auth" );
2875 DBG_ENTER( DbgInfo );
2876
2877 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
2878 ret = -EBUSY;
2879 goto out;
2880 }
2881
2882 wl_lock( lp, &flags );
2883
2884 wl_act_int_off( lp );
2885
2886 switch (iwa_idx) {
2887 case IW_AUTH_WPA_VERSION:
2888 DBG_TRACE( DbgInfo, "IW_AUTH_WPA_VERSION\n");
2889
2890 if (iwa_val == IW_AUTH_WPA_VERSION_WPA)
2891 ret = 0;
2892 else
2893 ret = -EINVAL;
2894 break;
2895
2896 case IW_AUTH_WPA_ENABLED:
2897 DBG_TRACE( DbgInfo, "IW_AUTH_WPA_ENABLED: val = %d\n", iwa_val);
2898 if (iwa_val)
2899 lp->EnableEncryption = 2;
2900 else
2901 lp->EnableEncryption = 0;
2902 ret = 0;
2903 break;
2904
2905 case IW_AUTH_TKIP_COUNTERMEASURES:
2906 DBG_TRACE( DbgInfo, "IW_AUTH_TKIP_COUNTERMEASURES\n");
2907 lp->driverEnable = !iwa_val;
2908 if(lp->driverEnable)
2909 hcf_cntl(&(lp->hcfCtx), HCF_CNTL_ENABLE | HCF_PORT_0);
2910 else
2911 hcf_cntl(&(lp->hcfCtx), HCF_CNTL_DISABLE | HCF_PORT_0);
2912 ret = 0;
2913 break;
2914
2915 case IW_AUTH_DROP_UNENCRYPTED:
2916 DBG_TRACE( DbgInfo, "IW_AUTH_DROP_UNENCRYPTED\n");
2917
2918
2919 ret = 0;
2920 break;
2921
2922 case IW_AUTH_CIPHER_PAIRWISE:
2923 DBG_TRACE( DbgInfo, "IW_AUTH_CIPHER_PAIRWISE\n");
2924
2925 ret = -EINVAL;
2926 break;
2927
2928 case IW_AUTH_CIPHER_GROUP:
2929 DBG_TRACE( DbgInfo, "IW_AUTH_CIPHER_GROUP\n");
2930
2931 ret = -EINVAL;
2932 break;
2933
2934 case IW_AUTH_KEY_MGMT:
2935 DBG_TRACE( DbgInfo, "IW_AUTH_KEY_MGMT\n");
2936
2937 ret = -EINVAL;
2938 break;
2939
2940 case IW_AUTH_80211_AUTH_ALG:
2941 DBG_TRACE( DbgInfo, "IW_AUTH_80211_AUTH_ALG\n");
2942
2943 ret = -EINVAL;
2944 break;
2945
2946 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2947 DBG_TRACE( DbgInfo, "IW_AUTH_RX_UNENCRYPTED_EAPOL\n");
2948
2949 ret = -EINVAL;
2950 break;
2951
2952 case IW_AUTH_ROAMING_CONTROL:
2953 DBG_TRACE( DbgInfo, "IW_AUTH_ROAMING_CONTROL\n");
2954
2955 ret = -EINVAL;
2956 break;
2957
2958 case IW_AUTH_PRIVACY_INVOKED:
2959 DBG_TRACE( DbgInfo, "IW_AUTH_PRIVACY_INVOKED\n");
2960
2961 ret = -EINVAL;
2962 break;
2963
2964 default:
2965 DBG_TRACE( DbgInfo, "IW_AUTH_?? (%d) unknown\n", iwa_idx);
2966
2967 ret = -EINVAL;
2968 break;
2969 }
2970
2971 wl_act_int_on( lp );
2972
2973 wl_unlock(lp, &flags);
2974
2975out:
2976 DBG_LEAVE( DbgInfo );
2977 return ret;
2978}
2979
2980
2981
2982
2983static int hermes_set_key(ltv_t *ltv, int alg, int key_idx, u8 *addr,
2984 int set_tx, u8 *seq, u8 *key, size_t key_len)
2985{
2986 int ret = -EINVAL;
2987
2988 int buf_idx = 0;
2989 hcf_8 tsc[IW_ENCODE_SEQ_MAX_SIZE] =
2990 { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 };
2991
2992 DBG_FUNC( "hermes_set_key" );
2993 DBG_ENTER( DbgInfo );
2994
2995
2996
2997
2998
2999
3000
3001 switch (alg)
3002 {
3003 case IW_ENCODE_ALG_TKIP:
3004 DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_TKIP: key(%d)\n", key_idx);
3005#if 0
3006
3007
3008
3009
3010
3011
3012
3013 for( count = 0; count < 100; count++ )
3014 {
3015 usleep( 1000 );
3016
3017 ltv.len = 2;
3018 ltv.typ = 0xFD91;
3019 ltv.u.u16[0] = 0;
3020
3021 wl_get_info( sock, <v, ifname );
3022
3023 if( ltv.u.u16[0] == 0 )
3024 {
3025 break;
3026 }
3027 }
3028
3029 if( count == 100 )
3030 {
3031 wpa_printf( MSG_DEBUG, "Timed out waiting for TxQ!" );
3032 }
3033#endif
3034
3035 switch (key_idx) {
3036 case 0:
3037 ltv->len = 28;
3038 ltv->typ = CFG_ADD_TKIP_MAPPED_KEY;
3039
3040
3041 memcpy(<v->u.u8[buf_idx], addr, ETH_ALEN);
3042 buf_idx += ETH_ALEN;
3043
3044
3045 memcpy(<v->u.u8[buf_idx], &key[0], 16);
3046 buf_idx += 16;
3047
3048
3049 memcpy(<v->u.u8[buf_idx], tsc, IW_ENCODE_SEQ_MAX_SIZE);
3050 buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
3051
3052
3053 memcpy(<v->u.u8[buf_idx], seq, IW_ENCODE_SEQ_MAX_SIZE);
3054 buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
3055
3056
3057 memcpy(<v->u.u8[buf_idx], &key[16], 8);
3058 buf_idx += 8;
3059
3060
3061 memcpy(<v->u.u8[buf_idx], &key[24], 8);
3062
3063 ret = 0;
3064 break;
3065 case 1:
3066 case 2:
3067 case 3:
3068 ltv->len = 26;
3069 ltv->typ = CFG_ADD_TKIP_DEFAULT_KEY;
3070
3071
3072 ltv->u.u16[buf_idx] = key_idx;
3073
3074 if(set_tx)
3075 ltv->u.u16[buf_idx] |= 0x8000;
3076 buf_idx += 2;
3077
3078
3079 memcpy(<v->u.u8[buf_idx], seq, IW_ENCODE_SEQ_MAX_SIZE);
3080 buf_idx += IW_ENCODE_SEQ_MAX_SIZE;
3081
3082
3083
3084 memcpy(<v->u.u8[buf_idx], key, key_len);
3085 buf_idx += key_len;
3086
3087
3088 memcpy(<v->u.u8[buf_idx], tsc, IW_ENCODE_SEQ_MAX_SIZE);
3089
3090 ltv->u.u16[0] = CNV_INT_TO_LITTLE(ltv->u.u16[0]);
3091
3092 ret = 0;
3093 break;
3094 default:
3095 break;
3096 }
3097
3098 break;
3099
3100 case IW_ENCODE_ALG_WEP:
3101 DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_WEP: key(%d)\n", key_idx);
3102 break;
3103
3104 case IW_ENCODE_ALG_CCMP:
3105 DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_CCMP: key(%d)\n", key_idx);
3106 break;
3107
3108 case IW_ENCODE_ALG_NONE:
3109 DBG_TRACE( DbgInfo, "IW_ENCODE_ALG_NONE: key(%d)\n", key_idx);
3110 switch (key_idx) {
3111 case 0:
3112 if (memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) {
3113
3114 ltv->len = 7;
3115 ltv->typ = CFG_REMOVE_TKIP_MAPPED_KEY;
3116 memcpy(<v->u.u8[0], addr, ETH_ALEN);
3117 ret = 0;
3118 }
3119 break;
3120 case 1:
3121 case 2:
3122 case 3:
3123
3124 ltv->len = 2;
3125 ltv->typ = CFG_REMOVE_TKIP_DEFAULT_KEY;
3126 ltv->u.u16[0] = key_idx;
3127
3128 ret = 0;
3129 break;
3130 default:
3131 break;
3132 }
3133 break;
3134 default:
3135 DBG_TRACE( DbgInfo, "IW_ENCODE_??: key(%d)\n", key_idx);
3136 break;
3137 }
3138
3139 DBG_LEAVE( DbgInfo );
3140 return ret;
3141}
3142
3143
3144
3145
3146static int wireless_set_encodeext (struct net_device *dev,
3147 struct iw_request_info *info,
3148 struct iw_point *erq, char *keybuf)
3149{
3150 struct wl_private *lp = wl_priv(dev);
3151 unsigned long flags;
3152 int ret;
3153 int key_idx = (erq->flags&IW_ENCODE_INDEX) - 1;
3154 ltv_t ltv;
3155 struct iw_encode_ext *ext = (struct iw_encode_ext *)keybuf;
3156
3157 DBG_FUNC( "wireless_set_encodeext" );
3158 DBG_ENTER( DbgInfo );
3159
3160 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
3161 ret = -EBUSY;
3162 goto out;
3163 }
3164
3165 if (sizeof(ext->rx_seq) != 8) {
3166 DBG_TRACE(DbgInfo, "rz_seq size mismatch\n");
3167 DBG_LEAVE(DbgInfo);
3168 return -EINVAL;
3169 }
3170
3171
3172 if(ext->alg == IW_ENCODE_ALG_WEP) {
3173 struct iw_point wep_erq;
3174 char *wep_keybuf;
3175
3176
3177 wep_erq.flags = erq->flags;
3178 wep_erq.length = ext->key_len;
3179 wep_keybuf = ext->key;
3180
3181
3182 ret = wireless_set_encode(dev, info, &wep_erq, wep_keybuf);
3183 goto out;
3184 }
3185
3186
3187 wl_lock( lp, &flags );
3188
3189 wl_act_int_off( lp );
3190
3191 memset(<v, 0, sizeof(ltv));
3192 ret = hermes_set_key(<v, ext->alg, key_idx, ext->addr.sa_data,
3193 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
3194 ext->rx_seq, ext->key, ext->key_len);
3195
3196 if (ret != 0) {
3197 DBG_TRACE( DbgInfo, "hermes_set_key returned != 0, key not set\n");
3198 goto out_unlock;
3199 }
3200
3201
3202 ret = hcf_put_info(&(lp->hcfCtx), (LTVP)<v);
3203
3204out_unlock:
3205 if(ret == HCF_SUCCESS) {
3206 DBG_TRACE( DbgInfo, "Put key info succes\n");
3207 } else {
3208 DBG_TRACE( DbgInfo, "Put key info failed, key not set\n");
3209 }
3210
3211 wl_act_int_on( lp );
3212
3213 wl_unlock(lp, &flags);
3214
3215out:
3216 DBG_LEAVE( DbgInfo );
3217 return ret;
3218}
3219
3220
3221
3222
3223static int wireless_get_genie(struct net_device *dev,
3224 struct iw_request_info *info,
3225 struct iw_point *data, char *extra)
3226
3227{
3228 struct wl_private *lp = wl_priv(dev);
3229 unsigned long flags;
3230 int ret = 0;
3231 ltv_t ltv;
3232
3233 DBG_FUNC( "wireless_get_genie" );
3234 DBG_ENTER( DbgInfo );
3235
3236 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
3237 ret = -EBUSY;
3238 goto out;
3239 }
3240
3241 wl_lock( lp, &flags );
3242
3243 wl_act_int_off( lp );
3244
3245 memset(<v, 0, sizeof(ltv));
3246 ltv.len = 2;
3247 ltv.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
3248 lp->AuthKeyMgmtSuite = ltv.u.u16[0] = 4;
3249 ltv.u.u16[0] = CNV_INT_TO_LITTLE(ltv.u.u16[0]);
3250
3251 ret = hcf_put_info(&(lp->hcfCtx), (LTVP)<v);
3252
3253 wl_act_int_on( lp );
3254
3255 wl_unlock(lp, &flags);
3256
3257out:
3258 DBG_LEAVE( DbgInfo );
3259 return ret;
3260}
3261
3262
3263
3264#endif
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285struct iw_statistics * wl_wireless_stats( struct net_device *dev )
3286{
3287 struct iw_statistics *pStats;
3288 struct wl_private *lp = wl_priv(dev);
3289
3290
3291
3292 DBG_FUNC( "wl_wireless_stats" );
3293 DBG_ENTER(DbgInfo);
3294 DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
3295
3296 pStats = NULL;
3297
3298
3299 pStats = &( lp->wstats );
3300 pStats->qual.updated = 0x00;
3301
3302 if( !( lp->flags & WVLAN2_UIL_BUSY ))
3303 {
3304 CFG_COMMS_QUALITY_STRCT *pQual;
3305 CFG_HERMES_TALLIES_STRCT tallies;
3306 int status;
3307
3308
3309 pStats->status = 0;
3310
3311
3312 lp->ltvRecord.len = 1 + ( sizeof( *pQual ) / sizeof( hcf_16 ));
3313 lp->ltvRecord.typ = CFG_COMMS_QUALITY;
3314 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
3315
3316 if( status == HCF_SUCCESS ) {
3317 pQual = (CFG_COMMS_QUALITY_STRCT *)&( lp->ltvRecord );
3318
3319#ifdef USE_DBM
3320 pStats->qual.qual = (u_char) CNV_LITTLE_TO_INT( pQual->coms_qual );
3321 pStats->qual.level = (u_char) dbm( CNV_LITTLE_TO_INT( pQual->signal_lvl ));
3322 pStats->qual.noise = (u_char) dbm( CNV_LITTLE_TO_INT( pQual->noise_lvl ));
3323
3324 pStats->qual.updated |= (IW_QUAL_QUAL_UPDATED |
3325 IW_QUAL_LEVEL_UPDATED |
3326 IW_QUAL_NOISE_UPDATED |
3327 IW_QUAL_DBM);
3328#else
3329 pStats->qual.qual = percent( CNV_LITTLE_TO_INT( pQual->coms_qual ),
3330 HCF_MIN_COMM_QUALITY,
3331 HCF_MAX_COMM_QUALITY );
3332
3333 pStats->qual.level = percent( CNV_LITTLE_TO_INT( pQual->signal_lvl ),
3334 HCF_MIN_SIGNAL_LEVEL,
3335 HCF_MAX_SIGNAL_LEVEL );
3336
3337 pStats->qual.noise = percent( CNV_LITTLE_TO_INT( pQual->noise_lvl ),
3338 HCF_MIN_NOISE_LEVEL,
3339 HCF_MAX_NOISE_LEVEL );
3340
3341 pStats->qual.updated |= (IW_QUAL_QUAL_UPDATED |
3342 IW_QUAL_LEVEL_UPDATED |
3343 IW_QUAL_NOISE_UPDATED);
3344#endif
3345 } else {
3346 memset( &( pStats->qual ), 0, sizeof( pStats->qual ));
3347 }
3348
3349
3350
3351 if(lp->portState == WVLAN_PORT_STATE_DISABLED) {
3352 if( wl_get_tallies( lp, &tallies ) == 0 ) {
3353
3354
3355 pStats->discard.nwid = 0L;
3356 pStats->discard.code = tallies.RxWEPUndecryptable;
3357 pStats->discard.misc = tallies.TxDiscards +
3358 tallies.RxFCSErrors +
3359
3360 tallies.TxDiscardsWrongSA;
3361
3362 pStats->discard.retries = tallies.TxRetryLimitExceeded;
3363 pStats->discard.fragment = tallies.RxMsgInBadMsgFragments;
3364 } else {
3365 memset( &( pStats->discard ), 0, sizeof( pStats->discard ));
3366 }
3367 } else {
3368 memset( &( pStats->discard ), 0, sizeof( pStats->discard ));
3369 }
3370 }
3371
3372 DBG_LEAVE( DbgInfo );
3373 return pStats;
3374}
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401struct iw_statistics * wl_get_wireless_stats( struct net_device *dev )
3402{
3403 unsigned long flags;
3404 struct wl_private *lp = wl_priv(dev);
3405 struct iw_statistics *pStats = NULL;
3406
3407
3408 DBG_FUNC( "wl_get_wireless_stats" );
3409 DBG_ENTER(DbgInfo);
3410
3411 wl_lock( lp, &flags );
3412
3413 wl_act_int_off( lp );
3414
3415#ifdef USE_RTS
3416 if( lp->useRTS == 1 ) {
3417 DBG_TRACE( DbgInfo, "Skipping wireless stats, in RTS mode\n" );
3418 } else
3419#endif
3420 {
3421 pStats = wl_wireless_stats( dev );
3422 }
3423 wl_act_int_on( lp );
3424
3425 wl_unlock(lp, &flags);
3426
3427 DBG_LEAVE( DbgInfo );
3428 return pStats;
3429}
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451inline void wl_spy_gather( struct net_device *dev, u_char *mac )
3452{
3453 struct iw_quality wstats;
3454 int status;
3455 u_char stats[2];
3456 DESC_STRCT desc[1];
3457 struct wl_private *lp = wl_priv(dev);
3458
3459
3460
3461 if (!lp->spy_data.spy_number) {
3462 return;
3463 }
3464
3465
3466
3467 memset( stats, 0, sizeof(stats));
3468 memset( desc, 0, sizeof(DESC_STRCT));
3469
3470 desc[0].buf_addr = stats;
3471 desc[0].BUF_SIZE = sizeof(stats);
3472 desc[0].next_desc_addr = 0;
3473
3474 status = hcf_rcv_msg( &( lp->hcfCtx ), &desc[0], 0 );
3475
3476 if( status == HCF_SUCCESS ) {
3477 wstats.level = (u_char) dbm(stats[1]);
3478 wstats.noise = (u_char) dbm(stats[0]);
3479 wstats.qual = wstats.level > wstats.noise ? wstats.level - wstats.noise : 0;
3480
3481 wstats.updated = (IW_QUAL_QUAL_UPDATED |
3482 IW_QUAL_LEVEL_UPDATED |
3483 IW_QUAL_NOISE_UPDATED |
3484 IW_QUAL_DBM);
3485
3486 wireless_spy_update( dev, mac, &wstats );
3487 }
3488}
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513void wl_wext_event_freq( struct net_device *dev )
3514{
3515#if WIRELESS_EXT > 13
3516 union iwreq_data wrqu;
3517 struct wl_private *lp = wl_priv(dev);
3518
3519
3520
3521 memset( &wrqu, 0, sizeof( wrqu ));
3522
3523 wrqu.freq.m = lp->Channel;
3524 wrqu.freq.e = 0;
3525
3526 wireless_send_event( dev, SIOCSIWFREQ, &wrqu, NULL );
3527#endif
3528
3529 return;
3530}
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555void wl_wext_event_mode( struct net_device *dev )
3556{
3557#if WIRELESS_EXT > 13
3558 union iwreq_data wrqu;
3559 struct wl_private *lp = wl_priv(dev);
3560
3561
3562
3563 memset( &wrqu, 0, sizeof( wrqu ));
3564
3565 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
3566 wrqu.mode = IW_MODE_INFRA;
3567 } else {
3568 wrqu.mode = IW_MODE_MASTER;
3569 }
3570
3571 wireless_send_event( dev, SIOCSIWMODE, &wrqu, NULL );
3572#endif
3573
3574 return;
3575}
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600void wl_wext_event_essid( struct net_device *dev )
3601{
3602#if WIRELESS_EXT > 13
3603 union iwreq_data wrqu;
3604 struct wl_private *lp = wl_priv(dev);
3605
3606
3607
3608 memset( &wrqu, 0, sizeof( wrqu ));
3609
3610
3611
3612
3613
3614 wrqu.essid.length = strlen( lp->NetworkName );
3615 wrqu.essid.pointer = (caddr_t)lp->NetworkName;
3616 wrqu.essid.flags = 1;
3617
3618 wireless_send_event( dev, SIOCSIWESSID, &wrqu, lp->NetworkName );
3619#endif
3620
3621 return;
3622}
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647void wl_wext_event_encode( struct net_device *dev )
3648{
3649#if WIRELESS_EXT > 13
3650 union iwreq_data wrqu;
3651 struct wl_private *lp = wl_priv(dev);
3652 int index = 0;
3653
3654
3655
3656 memset( &wrqu, 0, sizeof( wrqu ));
3657
3658 if( lp->EnableEncryption == 0 ) {
3659 wrqu.encoding.flags = IW_ENCODE_DISABLED;
3660 } else {
3661 wrqu.encoding.flags |= lp->TransmitKeyID;
3662
3663 index = lp->TransmitKeyID - 1;
3664
3665
3666
3667#if 1
3668
3669
3670 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3671 if( lp->ExcludeUnencrypted ) {
3672 wrqu.encoding.flags |= IW_ENCODE_RESTRICTED;
3673 } else {
3674 wrqu.encoding.flags |= IW_ENCODE_OPEN;
3675 }
3676 }
3677
3678#endif
3679
3680
3681 if( capable( CAP_NET_ADMIN )) {
3682 wrqu.encoding.pointer = (caddr_t)lp->DefaultKeys.key[index].key;
3683 wrqu.encoding.length = lp->DefaultKeys.key[index].len;
3684 } else {
3685 wrqu.encoding.flags |= IW_ENCODE_NOKEY;
3686 }
3687 }
3688
3689 wireless_send_event( dev, SIOCSIWENCODE, &wrqu,
3690 lp->DefaultKeys.key[index].key );
3691#endif
3692
3693 return;
3694}
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719void wl_wext_event_ap( struct net_device *dev )
3720{
3721#if WIRELESS_EXT > 13
3722 union iwreq_data wrqu;
3723 struct wl_private *lp = wl_priv(dev);
3724 int status;
3725
3726
3727
3728
3729
3730
3731
3732
3733 wl_wext_event_assoc_ie( dev );
3734
3735
3736 lp->ltvRecord.typ = CFG_CUR_BSSID;
3737 lp->ltvRecord.len = 4;
3738
3739 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
3740 if( status == HCF_SUCCESS ) {
3741 memset( &wrqu, 0, sizeof( wrqu ));
3742
3743 memcpy( wrqu.addr.sa_data, lp->ltvRecord.u.u8, ETH_ALEN );
3744
3745 wrqu.addr.sa_family = ARPHRD_ETHER;
3746
3747 wireless_send_event( dev, SIOCGIWAP, &wrqu, NULL );
3748 }
3749
3750#endif
3751
3752 return;
3753}
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777void wl_wext_event_scan_complete( struct net_device *dev )
3778{
3779#if WIRELESS_EXT > 13
3780 union iwreq_data wrqu;
3781
3782
3783
3784 memset( &wrqu, 0, sizeof( wrqu ));
3785
3786 wrqu.addr.sa_family = ARPHRD_ETHER;
3787 wireless_send_event( dev, SIOCGIWSCAN, &wrqu, NULL );
3788#endif
3789
3790 return;
3791}
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816void wl_wext_event_new_sta( struct net_device *dev )
3817{
3818#if WIRELESS_EXT > 14
3819 union iwreq_data wrqu;
3820
3821
3822
3823 memset( &wrqu, 0, sizeof( wrqu ));
3824
3825
3826 memcpy( wrqu.addr.sa_data, dev->dev_addr, ETH_ALEN );
3827 wrqu.addr.sa_family = ARPHRD_ETHER;
3828 wireless_send_event( dev, IWEVREGISTERED, &wrqu, NULL );
3829#endif
3830
3831 return;
3832}
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857void wl_wext_event_expired_sta( struct net_device *dev )
3858{
3859#if WIRELESS_EXT > 14
3860 union iwreq_data wrqu;
3861
3862
3863
3864 memset( &wrqu, 0, sizeof( wrqu ));
3865
3866 memcpy( wrqu.addr.sa_data, dev->dev_addr, ETH_ALEN );
3867 wrqu.addr.sa_family = ARPHRD_ETHER;
3868 wireless_send_event( dev, IWEVEXPIRED, &wrqu, NULL );
3869#endif
3870
3871 return;
3872}
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896void wl_wext_event_mic_failed( struct net_device *dev )
3897{
3898#if WIRELESS_EXT > 14
3899 char msg[512];
3900 union iwreq_data wrqu;
3901 struct wl_private *lp = wl_priv(dev);
3902 int key_idx;
3903 char *addr1;
3904 char *addr2;
3905 WVLAN_RX_WMP_HDR *hdr;
3906
3907
3908
3909 key_idx = lp->lookAheadBuf[HFS_STAT+1] >> 3;
3910 key_idx &= 0x03;
3911
3912
3913 hdr = (WVLAN_RX_WMP_HDR *)&lp->lookAheadBuf[HFS_STAT];
3914
3915
3916
3917 addr1 = (char *)hdr->address1;
3918 addr2 = (char *)hdr->address2;
3919
3920 DBG_PRINT( "MIC FAIL - KEY USED : %d, STATUS : 0x%04x\n", key_idx,
3921 hdr->status );
3922
3923 memset( &wrqu, 0, sizeof( wrqu ));
3924 memset( msg, 0, sizeof( msg ));
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940#if DBG
3941 sprintf(msg, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast "
3942 "addr=%pM)", key_idx, addr1[0] & 0x01 ? "broad" : "uni",
3943 addr2);
3944#endif
3945 wrqu.data.length = strlen( msg );
3946 wireless_send_event( dev, IWEVCUSTOM, &wrqu, msg );
3947#endif
3948
3949 return;
3950}
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975void wl_wext_event_assoc_ie( struct net_device *dev )
3976{
3977#if WIRELESS_EXT > 14
3978 char msg[512];
3979 union iwreq_data wrqu;
3980 struct wl_private *lp = wl_priv(dev);
3981 int status;
3982 PROBE_RESP data;
3983 hcf_16 length;
3984 hcf_8 *wpa_ie;
3985
3986
3987
3988 memset( &wrqu, 0, sizeof( wrqu ));
3989 memset( msg, 0, sizeof( msg ));
3990
3991
3992 lp->ltvRecord.len = 45;
3993 lp->ltvRecord.typ = CFG_CUR_ASSOC_REQ_INFO;
3994
3995 status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
3996 if( status == HCF_SUCCESS )
3997 {
3998 length = 0;
3999 memcpy( &data.rawData, &( lp->ltvRecord.u.u8[1] ), 88 );
4000 wpa_ie = wl_parse_wpa_ie( &data, &length );
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012 if( length != 0 )
4013 {
4014 sprintf( msg, "ASSOCINFO(ReqIEs=%s)", wl_print_wpa_ie( wpa_ie, length ));
4015 wrqu.data.length = strlen( msg );
4016 wireless_send_event( dev, IWEVCUSTOM, &wrqu, msg );
4017 }
4018 }
4019#endif
4020
4021 return;
4022}
4023
4024
4025
4026static const iw_handler wl_handler[] =
4027{
4028 (iw_handler) wireless_commit,
4029 (iw_handler) wireless_get_protocol,
4030 (iw_handler) NULL,
4031 (iw_handler) NULL,
4032 (iw_handler) wireless_set_frequency,
4033 (iw_handler) wireless_get_frequency,
4034 (iw_handler) wireless_set_porttype,
4035 (iw_handler) wireless_get_porttype,
4036 (iw_handler) wireless_set_sensitivity,
4037 (iw_handler) wireless_get_sensitivity,
4038 (iw_handler) NULL ,
4039 (iw_handler) wireless_get_range,
4040 (iw_handler) NULL ,
4041 (iw_handler) NULL ,
4042 (iw_handler) NULL ,
4043 (iw_handler) NULL ,
4044 iw_handler_set_spy,
4045 iw_handler_get_spy,
4046 NULL,
4047 NULL,
4048 (iw_handler) NULL,
4049#if 1
4050 (iw_handler) wireless_get_bssid,
4051#else
4052 (iw_handler) NULL,
4053#endif
4054 (iw_handler) NULL,
4055 (iw_handler) wireless_get_ap_list,
4056 (iw_handler) wireless_set_scan,
4057 (iw_handler) wireless_get_scan,
4058 (iw_handler) wireless_set_essid,
4059 (iw_handler) wireless_get_essid,
4060 (iw_handler) wireless_set_nickname,
4061 (iw_handler) wireless_get_nickname,
4062 (iw_handler) NULL,
4063 (iw_handler) NULL,
4064 (iw_handler) wireless_set_rate,
4065 (iw_handler) wireless_get_rate,
4066 (iw_handler) wireless_set_rts_threshold,
4067 (iw_handler) wireless_get_rts_threshold,
4068 (iw_handler) NULL,
4069 (iw_handler) NULL,
4070 (iw_handler) NULL,
4071 (iw_handler) wireless_get_tx_power,
4072 (iw_handler) NULL,
4073 (iw_handler) NULL,
4074 (iw_handler) wireless_set_encode,
4075 (iw_handler) wireless_get_encode,
4076 (iw_handler) wireless_set_power,
4077 (iw_handler) wireless_get_power,
4078 (iw_handler) NULL,
4079 (iw_handler) NULL,
4080 (iw_handler) wireless_get_genie,
4081 (iw_handler) NULL,
4082 (iw_handler) wireless_set_auth,
4083 (iw_handler) NULL,
4084 (iw_handler) wireless_set_encodeext,
4085 (iw_handler) NULL,
4086 (iw_handler) NULL,
4087 (iw_handler) NULL,
4088};
4089
4090static const iw_handler wl_private_handler[] =
4091{
4092 wvlan_set_netname,
4093 wvlan_get_netname,
4094 wvlan_set_station_nickname,
4095 wvlan_get_station_nickname,
4096#if 1
4097 wvlan_set_porttype,
4098 wvlan_get_porttype,
4099#endif
4100};
4101
4102struct iw_priv_args wl_priv_args[] = {
4103 {SIOCSIWNETNAME, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, 0, "snetwork_name" },
4104 {SIOCGIWNETNAME, 0, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, "gnetwork_name" },
4105 {SIOCSIWSTANAME, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, 0, "sstation_name" },
4106 {SIOCGIWSTANAME, 0, IW_PRIV_TYPE_CHAR | HCF_MAX_NAME_LEN, "gstation_name" },
4107#if 1
4108 {SIOCSIWPORTTYPE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "sport_type" },
4109 {SIOCGIWPORTTYPE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gport_type" },
4110#endif
4111};
4112
4113const struct iw_handler_def wl_iw_handler_def =
4114{
4115 .num_private = sizeof(wl_private_handler) / sizeof(iw_handler),
4116 .private = (iw_handler *) wl_private_handler,
4117 .private_args = (struct iw_priv_args *) wl_priv_args,
4118 .num_private_args = sizeof(wl_priv_args) / sizeof(struct iw_priv_args),
4119 .num_standard = sizeof(wl_handler) / sizeof(iw_handler),
4120 .standard = (iw_handler *) wl_handler,
4121 .get_wireless_stats = wl_get_wireless_stats,
4122};
4123
4124#endif
4125