~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to ubuntu/rtl8192se/rtllib/rtllib_softmac_wx.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* IEEE 802.11 SoftMAC layer
2
 
 * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
3
 
 *
4
 
 * Mostly extracted from the rtl8180-sa2400 driver for the 
5
 
 * in-kernel generic ieee802.11 stack.
6
 
 *
7
 
 * Some pieces of code might be stolen from ipw2100 driver
8
 
 * copyright of who own it's copyright ;-)
9
 
 *
10
 
 * PS wx handler mostly stolen from hostap, copyright who
11
 
 * own it's copyright ;-)
12
 
 *
13
 
 * released under the GPL
14
 
 */
15
 
 
16
 
 
17
 
#include "rtllib.h"
18
 
#ifdef ENABLE_DOT11D
19
 
#include "dot11d.h"
20
 
#endif
21
 
/* FIXME: add A freqs */
22
 
 
23
 
const long rtllib_wlan_frequencies[] = {  
24
 
        2412, 2417, 2422, 2427, 
25
 
        2432, 2437, 2442, 2447, 
26
 
        2452, 2457, 2462, 2467, 
27
 
        2472, 2484  
28
 
};
29
 
 
30
 
 
31
 
int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
32
 
                             union iwreq_data *wrqu, char *b)
33
 
{
34
 
        int ret;
35
 
        struct iw_freq *fwrq = & wrqu->freq;
36
 
 
37
 
        down(&ieee->wx_sem);
38
 
        
39
 
        if(ieee->iw_mode == IW_MODE_INFRA){ 
40
 
                ret = 0;
41
 
                goto out;
42
 
        }
43
 
 
44
 
        /* if setting by freq convert to channel */
45
 
        if (fwrq->e == 1) {
46
 
                if ((fwrq->m >= (int) 2.412e8 &&
47
 
                     fwrq->m <= (int) 2.487e8)) {
48
 
                        int f = fwrq->m / 100000;
49
 
                        int c = 0;
50
 
                        
51
 
                        while ((c < 14) && (f != rtllib_wlan_frequencies[c]))
52
 
                                c++;
53
 
                        
54
 
                        /* hack to fall through */
55
 
                        fwrq->e = 0;
56
 
                        fwrq->m = c + 1;
57
 
                }
58
 
        }
59
 
        
60
 
        if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){ 
61
 
                ret = -EOPNOTSUPP;
62
 
                goto out;
63
 
        
64
 
        }else { /* Set the channel */
65
 
                
66
 
#ifdef ENABLE_DOT11D
67
 
                if (ieee->active_channel_map[fwrq->m] != 1) {
68
 
                        ret = -EINVAL;
69
 
                        goto out;
70
 
                }
71
 
#endif
72
 
                ieee->current_network.channel = fwrq->m;
73
 
                ieee->set_chan(ieee->dev, ieee->current_network.channel);
74
 
                
75
 
                if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
76
 
                        if(ieee->state == RTLLIB_LINKED){
77
 
                        
78
 
                        rtllib_stop_send_beacons(ieee);
79
 
                        rtllib_start_send_beacons(ieee);
80
 
                        }
81
 
        }
82
 
 
83
 
        ret = 0;
84
 
out:
85
 
        up(&ieee->wx_sem);
86
 
        return ret;
87
 
}
88
 
 
89
 
 
90
 
#ifdef _RTL8192_EXT_PATCH_      
91
 
int rtllib_wx_get_freq(struct rtllib_device *ieee,
92
 
                             struct iw_request_info *a,
93
 
                             union iwreq_data *wrqu, char *b, u8 is_mesh)
94
 
#else
95
 
int rtllib_wx_get_freq(struct rtllib_device *ieee,
96
 
                             struct iw_request_info *a,
97
 
                             union iwreq_data *wrqu, char *b)
98
 
#endif  
99
 
{
100
 
        struct iw_freq *fwrq = & wrqu->freq;
101
 
 
102
 
#ifdef _RTL8192_EXT_PATCH_      
103
 
        if(is_mesh)
104
 
        {
105
 
                if (ieee->current_mesh_network.channel == 0)
106
 
                        return -1;
107
 
                fwrq->m = rtllib_wlan_frequencies[ieee->current_mesh_network.channel-1] * 100000;
108
 
                fwrq->e = 1;    
109
 
        }
110
 
        else
111
 
#endif  
112
 
        {
113
 
        if (ieee->current_network.channel == 0)
114
 
                return -1;
115
 
        fwrq->m = rtllib_wlan_frequencies[ieee->current_network.channel-1] * 100000;
116
 
        fwrq->e = 1;    
117
 
        }
118
 
        return 0;
119
 
}
120
 
 
121
 
int rtllib_wx_get_wap(struct rtllib_device *ieee, 
122
 
                            struct iw_request_info *info, 
123
 
                            union iwreq_data *wrqu, char *extra)
124
 
{
125
 
        unsigned long flags;    
126
 
        
127
 
        wrqu->ap_addr.sa_family = ARPHRD_ETHER;
128
 
        
129
 
        if (ieee->iw_mode == IW_MODE_MONITOR)
130
 
                return -1;
131
 
        
132
 
        /* We want avoid to give to the user inconsistent infos*/
133
 
        spin_lock_irqsave(&ieee->lock, flags);
134
 
        
135
 
        if (ieee->state != RTLLIB_LINKED && 
136
 
                ieee->state != RTLLIB_LINKED_SCANNING &&
137
 
                ieee->wap_set == 0)
138
 
                
139
 
                memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
140
 
        else
141
 
                memcpy(wrqu->ap_addr.sa_data, 
142
 
                       ieee->current_network.bssid, ETH_ALEN);
143
 
        
144
 
        spin_unlock_irqrestore(&ieee->lock, flags);
145
 
        
146
 
        return 0;
147
 
}
148
 
 
149
 
 
150
 
int rtllib_wx_set_wap(struct rtllib_device *ieee,
151
 
                         struct iw_request_info *info,
152
 
                         union iwreq_data *awrq,
153
 
                         char *extra)
154
 
{
155
 
        
156
 
        int ret = 0;
157
 
        u8 zero[] = {0,0,0,0,0,0};
158
 
        unsigned long flags;
159
 
        
160
 
        short ifup = ieee->proto_started;
161
 
        struct sockaddr *temp = (struct sockaddr *)awrq;
162
 
 
163
 
        rtllib_stop_scan_syncro(ieee);
164
 
 
165
 
        down(&ieee->wx_sem);
166
 
        /* use ifconfig hw ether */
167
 
        if (ieee->iw_mode == IW_MODE_MASTER){
168
 
                ret = -1;
169
 
                goto out;
170
 
        }
171
 
        
172
 
        if (temp->sa_family != ARPHRD_ETHER){
173
 
                ret = -EINVAL;
174
 
                goto out;
175
 
        }
176
 
        
177
 
        if (memcmp(temp->sa_data, zero,ETH_ALEN) == 0){
178
 
                spin_lock_irqsave(&ieee->lock, flags);
179
 
                memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
180
 
                ieee->wap_set = 0;
181
 
                spin_unlock_irqrestore(&ieee->lock, flags);
182
 
                ret = -1;
183
 
                goto out;
184
 
        }
185
 
 
186
 
        
187
 
        if (ifup)
188
 
                rtllib_stop_protocol(ieee,true);
189
 
        
190
 
        /* just to avoid to give inconsistent infos in the
191
 
         * get wx method. not really needed otherwise 
192
 
         */
193
 
        spin_lock_irqsave(&ieee->lock, flags);
194
 
        
195
 
        ieee->cannot_notify = false;
196
 
        memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); 
197
 
        ieee->wap_set = (memcmp(temp->sa_data, zero,ETH_ALEN)!=0);
198
 
        
199
 
        spin_unlock_irqrestore(&ieee->lock, flags);
200
 
        
201
 
        if (ifup)
202
 
                rtllib_start_protocol(ieee);
203
 
out:
204
 
        up(&ieee->wx_sem);
205
 
        return ret;
206
 
}
207
 
        
208
 
 int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
209
 
{
210
 
        int len,ret = 0;
211
 
        unsigned long flags;
212
 
        
213
 
        if (ieee->iw_mode == IW_MODE_MONITOR)
214
 
                return -1;
215
 
        
216
 
        /* We want avoid to give to the user inconsistent infos*/       
217
 
        spin_lock_irqsave(&ieee->lock, flags);
218
 
        
219
 
        if (ieee->current_network.ssid[0] == '\0' ||
220
 
                ieee->current_network.ssid_len == 0){ 
221
 
                ret = -1;
222
 
                goto out;
223
 
        }
224
 
        
225
 
        if (ieee->state != RTLLIB_LINKED && 
226
 
                ieee->state != RTLLIB_LINKED_SCANNING &&
227
 
                ieee->ssid_set == 0){
228
 
                ret = -1;
229
 
                goto out;
230
 
        }
231
 
        len = ieee->current_network.ssid_len;
232
 
        wrqu->essid.length = len;
233
 
        strncpy(b,ieee->current_network.ssid,len);
234
 
        wrqu->essid.flags = 1;
235
 
 
236
 
out:
237
 
        spin_unlock_irqrestore(&ieee->lock, flags);
238
 
        
239
 
        return ret;
240
 
        
241
 
}
242
 
 
243
 
int rtllib_wx_set_rate(struct rtllib_device *ieee, 
244
 
                             struct iw_request_info *info,
245
 
                             union iwreq_data *wrqu, char *extra)
246
 
{
247
 
 
248
 
        u32 target_rate = wrqu->bitrate.value;
249
 
        
250
 
        ieee->rate = target_rate/100000;
251
 
        return 0; 
252
 
}
253
 
 
254
 
int rtllib_wx_get_rate(struct rtllib_device *ieee, 
255
 
                             struct iw_request_info *info, 
256
 
                             union iwreq_data *wrqu, char *extra)
257
 
{
258
 
        u32 tmp_rate = 0;
259
 
#if defined RTL8192SU
260
 
        if (ieee->mode & (IEEE_A | IEEE_B | IEEE_G))
261
 
                tmp_rate = ieee->rate;
262
 
        else if (ieee->mode & IEEE_N_5G)
263
 
                tmp_rate = 580;
264
 
        else if (ieee->mode & IEEE_N_24G) {
265
 
                if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
266
 
                        tmp_rate = HTHalfMcsToDataRate(ieee, 15);
267
 
                else
268
 
                        tmp_rate = HTMcsToDataRate(ieee, 15);
269
 
        }
270
 
#elif defined RTL8192SE || defined RTL8192CE
271
 
        tmp_rate = ieee->rtl_11n_user_show_rates(ieee->dev);
272
 
#else
273
 
        tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate);
274
 
#endif
275
 
        wrqu->bitrate.value = tmp_rate * 500000;
276
 
        
277
 
        return 0;
278
 
}
279
 
 
280
 
 
281
 
int rtllib_wx_set_rts(struct rtllib_device *ieee, 
282
 
                             struct iw_request_info *info,
283
 
                             union iwreq_data *wrqu, char *extra)
284
 
{
285
 
        if (wrqu->rts.disabled || !wrqu->rts.fixed)
286
 
                ieee->rts = DEFAULT_RTS_THRESHOLD;
287
 
        else
288
 
        {
289
 
                if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
290
 
                                wrqu->rts.value > MAX_RTS_THRESHOLD) 
291
 
                        return -EINVAL;
292
 
                ieee->rts = wrqu->rts.value;
293
 
        }
294
 
        return 0;
295
 
}
296
 
 
297
 
int rtllib_wx_get_rts(struct rtllib_device *ieee, 
298
 
                             struct iw_request_info *info, 
299
 
                             union iwreq_data *wrqu, char *extra)
300
 
{
301
 
        wrqu->rts.value = ieee->rts;
302
 
        wrqu->rts.fixed = 0;    /* no auto select */
303
 
        wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
304
 
        return 0;
305
 
}
306
 
 
307
 
int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
308
 
                             union iwreq_data *wrqu, char *b)
309
 
{
310
 
        int set_mode_status = 0;
311
 
 
312
 
        rtllib_stop_scan_syncro(ieee);
313
 
        down(&ieee->wx_sem);
314
 
        switch (wrqu->mode) {
315
 
        case IW_MODE_MONITOR:
316
 
        case IW_MODE_ADHOC:
317
 
        case IW_MODE_INFRA:
318
 
#ifdef _RTL8192_EXT_PATCH_
319
 
        case IW_MODE_MESH:
320
 
#endif
321
 
                break;
322
 
        case IW_MODE_AUTO:
323
 
                wrqu->mode = IW_MODE_INFRA;
324
 
                break;
325
 
        default:
326
 
                set_mode_status = -EINVAL;
327
 
                goto out;
328
 
        }
329
 
 
330
 
        if (wrqu->mode == ieee->iw_mode)
331
 
                goto out;
332
 
        
333
 
        if (wrqu->mode == IW_MODE_MONITOR) {
334
 
#if defined(RTLLIB_RADIOTAP) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) 
335
 
                ieee->dev->type = ARPHRD_IEEE80211_RADIOTAP;
336
 
#else
337
 
                ieee->dev->type = ARPHRD_IEEE80211;
338
 
#endif
339
 
                rtllib_EnableNetMonitorMode(ieee->dev,false);   
340
 
                
341
 
        } else {
342
 
                ieee->dev->type = ARPHRD_ETHER;
343
 
                if (ieee->iw_mode == IW_MODE_MONITOR)
344
 
                        rtllib_DisableNetMonitorMode(ieee->dev,false);
345
 
        }
346
 
        
347
 
        if (!ieee->proto_started) {
348
 
                ieee->iw_mode = wrqu->mode;
349
 
        } else {
350
 
                rtllib_stop_protocol(ieee,true);
351
 
                ieee->iw_mode = wrqu->mode;
352
 
#if defined (RTL8192S_WAPI_SUPPORT)
353
 
                if(ieee->iw_mode == IW_MODE_ADHOC)
354
 
                        ieee->wapiInfo.bWapiPSK = true;
355
 
#endif
356
 
                rtllib_start_protocol(ieee);
357
 
        }
358
 
 
359
 
out:
360
 
        up(&ieee->wx_sem);
361
 
        return set_mode_status;
362
 
}
363
 
 
364
 
void rtllib_wx_sync_scan_wq(void *data)
365
 
{
366
 
        struct rtllib_device *ieee = container_of_work_rsl(data, struct rtllib_device, wx_sync_scan_wq);
367
 
        short chan;
368
 
        HT_EXTCHNL_OFFSET chan_offset=0;
369
 
        HT_CHANNEL_WIDTH bandwidth=0;
370
 
        int b40M = 0;
371
 
        static int count = 0;
372
 
 
373
 
        if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)){     
374
 
                rtllib_start_scan_syncro(ieee, 0);
375
 
                goto out;
376
 
        }
377
 
 
378
 
        chan = ieee->current_network.channel;
379
 
 
380
 
#ifdef ENABLE_LPS
381
 
        if (ieee->LeisurePSLeave) {
382
 
                ieee->LeisurePSLeave(ieee->dev);
383
 
        }
384
 
        /* notify AP to be in PS mode */
385
 
        rtllib_sta_ps_send_null_frame(ieee, 1);
386
 
        rtllib_sta_ps_send_null_frame(ieee, 1);
387
 
#endif
388
 
 
389
 
        rtllib_stop_all_queues(ieee);
390
 
 
391
 
        if (ieee->data_hard_stop)
392
 
                ieee->data_hard_stop(ieee->dev);
393
 
        rtllib_stop_send_beacons(ieee);
394
 
        ieee->state = RTLLIB_LINKED_SCANNING;
395
 
        ieee->link_change(ieee->dev);
396
 
        /* wait for ps packet to be kicked out successfully */
397
 
        msleep(50);
398
 
 
399
 
        if(ieee->ScanOperationBackupHandler)
400
 
                ieee->ScanOperationBackupHandler(ieee->dev,SCAN_OPT_BACKUP);
401
 
 
402
 
        if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) {
403
 
                b40M = 1;
404
 
                chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset;
405
 
                bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz;
406
 
                printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth);
407
 
                ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
408
 
                }
409
 
 
410
 
        rtllib_start_scan_syncro(ieee, 0);
411
 
 
412
 
        if (b40M) {
413
 
                printk("Scan in 20M, back to 40M\n");
414
 
                if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
415
 
                        ieee->set_chan(ieee->dev, chan + 2);
416
 
                else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
417
 
                        ieee->set_chan(ieee->dev, chan - 2);
418
 
                else
419
 
                        ieee->set_chan(ieee->dev, chan);
420
 
                ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
421
 
        } else {
422
 
                ieee->set_chan(ieee->dev, chan);
423
 
        }
424
 
        
425
 
        if(ieee->ScanOperationBackupHandler)
426
 
                ieee->ScanOperationBackupHandler(ieee->dev,SCAN_OPT_RESTORE);
427
 
        
428
 
        ieee->state = RTLLIB_LINKED;
429
 
        ieee->link_change(ieee->dev);
430
 
 
431
 
#ifdef ENABLE_LPS
432
 
        /* Notify AP that I wake up again */
433
 
        rtllib_sta_ps_send_null_frame(ieee, 0);
434
 
#endif
435
 
 
436
 
        if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || 
437
 
                        ieee->LinkDetectInfo.NumRecvDataInPeriod == 0 ) {
438
 
                ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
439
 
                ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;    
440
 
        }
441
 
 
442
 
        if (ieee->data_hard_resume)
443
 
                ieee->data_hard_resume(ieee->dev);
444
 
        
445
 
        if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
446
 
                rtllib_start_send_beacons(ieee);
447
 
        
448
 
        rtllib_wake_all_queues(ieee);
449
 
 
450
 
        count = 0;      
451
 
out:
452
 
        up(&ieee->wx_sem);
453
 
        
454
 
}
455
 
 
456
 
int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a,
457
 
                             union iwreq_data *wrqu, char *b)
458
 
{
459
 
        int ret = 0;
460
 
        
461
 
        down(&ieee->wx_sem);
462
 
        
463
 
        if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){ 
464
 
                ret = -1;
465
 
                goto out;
466
 
        }
467
 
        
468
 
        if ( ieee->state == RTLLIB_LINKED){
469
 
                queue_work_rsl(ieee->wq, &ieee->wx_sync_scan_wq);
470
 
                /* intentionally forget to up sem */
471
 
                return 0;
472
 
        }
473
 
                
474
 
out:
475
 
        up(&ieee->wx_sem);
476
 
        return ret;
477
 
}
478
 
 
479
 
int rtllib_wx_set_essid(struct rtllib_device *ieee, 
480
 
                              struct iw_request_info *a,
481
 
                              union iwreq_data *wrqu, char *extra)
482
 
{
483
 
        
484
 
        int ret=0,len,i;
485
 
        short proto_started;
486
 
        unsigned long flags;
487
 
        
488
 
        rtllib_stop_scan_syncro(ieee);
489
 
        down(&ieee->wx_sem);
490
 
        
491
 
        proto_started = ieee->proto_started;
492
 
        
493
 
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
494
 
        len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
495
 
#else
496
 
        len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
497
 
#endif
498
 
 
499
 
        if (len > IW_ESSID_MAX_SIZE){
500
 
                ret= -E2BIG;
501
 
                goto out;
502
 
        }
503
 
        
504
 
        if (ieee->iw_mode == IW_MODE_MONITOR){
505
 
                ret= -1;
506
 
                goto out;
507
 
        }
508
 
        
509
 
        for (i=0; i<len; i++){
510
 
                if(extra[i] < 0){
511
 
                        ret= -1;
512
 
                        goto out;
513
 
                }
514
 
        }
515
 
        
516
 
        if(proto_started)
517
 
                rtllib_stop_protocol(ieee,true);
518
 
        
519
 
        
520
 
        /* this is just to be sure that the GET wx callback
521
 
         * has consisten infos. not needed otherwise
522
 
         */
523
 
        spin_lock_irqsave(&ieee->lock, flags);
524
 
        
525
 
        if (wrqu->essid.flags && wrqu->essid.length) {
526
 
                strncpy(ieee->current_network.ssid, extra, len);
527
 
                ieee->current_network.ssid_len = len;
528
 
#if 0
529
 
                {
530
 
                        int i;
531
 
                        for (i=0; i<len; i++)
532
 
                                printk("%c:%d ", extra[i], extra[i]);
533
 
                        printk("\n");
534
 
                }
535
 
#endif
536
 
                ieee->cannot_notify = false;
537
 
                ieee->ssid_set = 1;
538
 
        }
539
 
        else{ 
540
 
                ieee->ssid_set = 0;
541
 
                ieee->current_network.ssid[0] = '\0';
542
 
                ieee->current_network.ssid_len = 0;
543
 
        }
544
 
        spin_unlock_irqrestore(&ieee->lock, flags);
545
 
        
546
 
        if (proto_started)
547
 
                rtllib_start_protocol(ieee);
548
 
out:
549
 
        up(&ieee->wx_sem);
550
 
        return ret;
551
 
}
552
 
 
553
 
 int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a,
554
 
                             union iwreq_data *wrqu, char *b)
555
 
{
556
 
#ifdef _RTL8192_EXT_PATCH_
557
 
        if(ieee->iw_mode == IW_MODE_MESH) {
558
 
                /* WEXT could not show mesh mode properly,
559
 
                 * just disable it */
560
 
                if(ieee->only_mesh) {
561
 
                        return -1;
562
 
                } else {
563
 
                        wrqu->mode = IW_MODE_INFRA;
564
 
                }
565
 
        }
566
 
        else
567
 
#endif
568
 
                wrqu->mode = ieee->iw_mode;
569
 
        return 0;
570
 
}
571
 
 
572
 
 int rtllib_wx_set_rawtx(struct rtllib_device *ieee, 
573
 
                               struct iw_request_info *info, 
574
 
                               union iwreq_data *wrqu, char *extra)
575
 
{
576
 
        
577
 
        int *parms = (int *)extra;
578
 
        int enable = (parms[0] > 0);
579
 
        short prev = ieee->raw_tx;
580
 
 
581
 
        down(&ieee->wx_sem);
582
 
        
583
 
        if(enable) 
584
 
                ieee->raw_tx = 1;
585
 
        else 
586
 
                ieee->raw_tx = 0;
587
 
 
588
 
        printk(KERN_INFO"raw TX is %s\n", 
589
 
              ieee->raw_tx ? "enabled" : "disabled");
590
 
 
591
 
        if(ieee->iw_mode == IW_MODE_MONITOR)
592
 
        {
593
 
                if(prev == 0 && ieee->raw_tx){
594
 
                        if (ieee->data_hard_resume)
595
 
                                ieee->data_hard_resume(ieee->dev);
596
 
        
597
 
                        netif_carrier_on(ieee->dev);    
598
 
                }
599
 
                
600
 
                if(prev && ieee->raw_tx == 1)
601
 
                        netif_carrier_off(ieee->dev); 
602
 
        }
603
 
        
604
 
        up(&ieee->wx_sem);
605
 
        
606
 
        return 0;
607
 
}
608
 
 
609
 
int rtllib_wx_get_name(struct rtllib_device *ieee, 
610
 
                             struct iw_request_info *info, 
611
 
                             union iwreq_data *wrqu, char *extra)
612
 
{
613
 
        strcpy(wrqu->name, "802.11");
614
 
 
615
 
        if (ieee->modulation & RTLLIB_CCK_MODULATION)
616
 
                strcat(wrqu->name, "b");
617
 
        if (ieee->modulation & RTLLIB_OFDM_MODULATION)
618
 
                strcat(wrqu->name, "g");
619
 
        if (ieee->mode & (IEEE_N_24G | IEEE_N_5G))
620
 
                strcat(wrqu->name, "n");
621
 
#if 0   
622
 
        if((ieee->state == RTLLIB_LINKED) || 
623
 
                (ieee->state == RTLLIB_LINKED_SCANNING))
624
 
                strcat(wrqu->name," linked");
625
 
        else if(ieee->state != RTLLIB_NOLINK)
626
 
                strcat(wrqu->name," link..");
627
 
#endif  
628
 
        return 0;
629
 
}
630
 
 
631
 
 
632
 
/* this is mostly stolen from hostap */
633
 
int rtllib_wx_set_power(struct rtllib_device *ieee,
634
 
                                 struct iw_request_info *info,
635
 
                                 union iwreq_data *wrqu, char *extra)
636
 
{
637
 
        int ret = 0;
638
 
#if 1
639
 
        if(
640
 
                (!ieee->sta_wake_up) ||
641
 
                (!ieee->enter_sleep_state) ||
642
 
                (!ieee->ps_is_queue_empty)){
643
 
                
644
 
                RTLLIB_DEBUG(RTLLIB_DL_ERR,"%s(): PS mode is tryied to be use but driver missed a callback\n\n",__FUNCTION__);  
645
 
        
646
 
                return -1;
647
 
        }
648
 
#endif  
649
 
        down(&ieee->wx_sem);
650
 
        
651
 
        if (wrqu->power.disabled){
652
 
                printk("===>%s(): power disable\n",__FUNCTION__);
653
 
                ieee->ps = RTLLIB_PS_DISABLED;
654
 
                goto exit;
655
 
        }
656
 
        if (wrqu->power.flags & IW_POWER_TIMEOUT) {
657
 
                ieee->ps_timeout = wrqu->power.value / 1000;
658
 
                printk("===>%s():ps_timeout is %d\n",__FUNCTION__,ieee->ps_timeout);
659
 
        }
660
 
        
661
 
        if (wrqu->power.flags & IW_POWER_PERIOD) {
662
 
                
663
 
                ieee->ps_period = wrqu->power.value / 1000;
664
 
                
665
 
        }
666
 
        switch (wrqu->power.flags & IW_POWER_MODE) {
667
 
        case IW_POWER_UNICAST_R:
668
 
                ieee->ps = RTLLIB_PS_UNICAST;
669
 
                break;
670
 
        case IW_POWER_MULTICAST_R:
671
 
                ieee->ps = RTLLIB_PS_MBCAST;
672
 
                break;
673
 
        case IW_POWER_ALL_R:
674
 
                ieee->ps = RTLLIB_PS_UNICAST | RTLLIB_PS_MBCAST;        
675
 
                break;
676
 
                
677
 
        case IW_POWER_ON:
678
 
                break;
679
 
                
680
 
        default:
681
 
                ret = -EINVAL;
682
 
                goto exit;
683
 
                
684
 
        }
685
 
exit:
686
 
        up(&ieee->wx_sem);
687
 
        return ret;
688
 
 
689
 
}
690
 
 
691
 
/* this is stolen from hostap */
692
 
int rtllib_wx_get_power(struct rtllib_device *ieee,
693
 
                                 struct iw_request_info *info,
694
 
                                 union iwreq_data *wrqu, char *extra)
695
 
{
696
 
        int ret =0;
697
 
        
698
 
        down(&ieee->wx_sem);
699
 
        
700
 
        if(ieee->ps == RTLLIB_PS_DISABLED){     
701
 
                wrqu->power.disabled = 1;
702
 
                goto exit;
703
 
        }
704
 
 
705
 
        wrqu->power.disabled = 0;
706
 
 
707
 
        if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
708
 
                wrqu->power.flags = IW_POWER_TIMEOUT;
709
 
                wrqu->power.value = ieee->ps_timeout * 1000;
710
 
        } else {
711
 
                wrqu->power.flags = IW_POWER_PERIOD;
712
 
                wrqu->power.value = ieee->ps_period * 1000; 
713
 
        }
714
 
 
715
 
       if ((ieee->ps & (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) == (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST))
716
 
                wrqu->power.flags |= IW_POWER_ALL_R;
717
 
        else if (ieee->ps & RTLLIB_PS_MBCAST)
718
 
                wrqu->power.flags |= IW_POWER_MULTICAST_R;
719
 
        else
720
 
                wrqu->power.flags |= IW_POWER_UNICAST_R;
721
 
 
722
 
exit:
723
 
        up(&ieee->wx_sem);
724
 
        return ret;
725
 
 
726
 
}
727
 
 
728
 
#ifndef BUILT_IN_RTLLIB
729
 
EXPORT_SYMBOL_RSL(rtllib_wx_get_essid);
730
 
EXPORT_SYMBOL_RSL(rtllib_wx_set_essid);
731
 
EXPORT_SYMBOL_RSL(rtllib_wx_set_rate);
732
 
EXPORT_SYMBOL_RSL(rtllib_wx_get_rate);
733
 
EXPORT_SYMBOL_RSL(rtllib_wx_set_wap);
734
 
EXPORT_SYMBOL_RSL(rtllib_wx_get_wap);
735
 
EXPORT_SYMBOL_RSL(rtllib_wx_set_mode);
736
 
EXPORT_SYMBOL_RSL(rtllib_wx_get_mode);
737
 
EXPORT_SYMBOL_RSL(rtllib_wx_set_scan);
738
 
EXPORT_SYMBOL_RSL(rtllib_wx_get_freq);
739
 
EXPORT_SYMBOL_RSL(rtllib_wx_set_freq);
740
 
EXPORT_SYMBOL_RSL(rtllib_wx_set_rawtx);
741
 
EXPORT_SYMBOL_RSL(rtllib_wx_get_name);
742
 
EXPORT_SYMBOL_RSL(rtllib_wx_set_power);
743
 
EXPORT_SYMBOL_RSL(rtllib_wx_get_power);
744
 
EXPORT_SYMBOL_RSL(rtllib_wlan_frequencies);
745
 
EXPORT_SYMBOL_RSL(rtllib_wx_set_rts);
746
 
EXPORT_SYMBOL_RSL(rtllib_wx_get_rts);
747
 
#endif