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