Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/net/wireless/bcm43xx/bcm43xx_wx.c (Version 2.6.25) and /linux/drivers/net/wireless/bcm43xx/bcm43xx_wx.c (Version 2.6.11.8)


  1 /*                                                  1 
  2                                                   
  3   Broadcom BCM43xx wireless driver                
  4                                                   
  5   Copyright (c) 2005 Martin Langer <martin-lan    
  6                      Stefano Brivio <st3@riseu    
  7                      Michael Buesch <mbuesch@f    
  8                      Danny van Dyk <kugelfang@    
  9                      Andreas Jaggi <andreas.ja    
 10                                                   
 11   Some parts of the code in this file are deri    
 12   driver  Copyright(c) 2003 - 2004 Intel Corpo    
 13                                                   
 14   This program is free software; you can redis    
 15   it under the terms of the GNU General Public    
 16   the Free Software Foundation; either version    
 17   (at your option) any later version.             
 18                                                   
 19   This program is distributed in the hope that    
 20   but WITHOUT ANY WARRANTY; without even the i    
 21   MERCHANTABILITY or FITNESS FOR A PARTICULAR     
 22   GNU General Public License for more details.    
 23                                                   
 24   You should have received a copy of the GNU G    
 25   along with this program; see the file COPYIN    
 26   the Free Software Foundation, Inc., 51 Frank    
 27   Boston, MA 02110-1301, USA.                     
 28                                                   
 29 */                                                
 30                                                   
 31 #include <linux/wireless.h>                       
 32 #include <net/iw_handler.h>                       
 33 #include <net/ieee80211softmac.h>                 
 34 #include <net/ieee80211softmac_wx.h>              
 35 #include <linux/capability.h>                     
 36 #include <linux/delay.h>                          
 37                                                   
 38 #include "bcm43xx.h"                              
 39 #include "bcm43xx_wx.h"                           
 40 #include "bcm43xx_main.h"                         
 41 #include "bcm43xx_radio.h"                        
 42 #include "bcm43xx_phy.h"                          
 43                                                   
 44                                                   
 45 /* The WIRELESS_EXT version, which is implemen    
 46 #define BCM43xx_WX_VERSION      18                
 47                                                   
 48 #define MAX_WX_STRING           80                
 49                                                   
 50 static int bcm43xx_wx_get_name(struct net_devi    
 51                                struct iw_reque    
 52                                union iwreq_dat    
 53                                char *extra)       
 54 {                                                 
 55         struct bcm43xx_private *bcm = bcm43xx_    
 56         int i;                                    
 57         struct bcm43xx_phyinfo *phy;              
 58         char suffix[7] = { 0 };                   
 59         int have_a = 0, have_b = 0, have_g = 0    
 60                                                   
 61         mutex_lock(&bcm->mutex);                  
 62         for (i = 0; i < bcm->nr_80211_availabl    
 63                 phy = &(bcm->core_80211_ext[i]    
 64                 switch (phy->type) {              
 65                 case BCM43xx_PHYTYPE_A:           
 66                         have_a = 1;               
 67                         break;                    
 68                 case BCM43xx_PHYTYPE_G:           
 69                         have_g = 1;               
 70                 case BCM43xx_PHYTYPE_B:           
 71                         have_b = 1;               
 72                         break;                    
 73                 default:                          
 74                         assert(0);                
 75                 }                                 
 76         }                                         
 77         mutex_unlock(&bcm->mutex);                
 78                                                   
 79         i = 0;                                    
 80         if (have_a) {                             
 81                 suffix[i++] = 'a';                
 82                 suffix[i++] = '/';                
 83         }                                         
 84         if (have_b) {                             
 85                 suffix[i++] = 'b';                
 86                 suffix[i++] = '/';                
 87         }                                         
 88         if (have_g) {                             
 89                 suffix[i++] = 'g';                
 90                 suffix[i++] = '/';                
 91         }                                         
 92         if (i != 0)                               
 93                 suffix[i - 1] = '\0';             
 94                                                   
 95         snprintf(data->name, IFNAMSIZ, "IEEE 8    
 96                                                   
 97         return 0;                                 
 98 }                                                 
 99                                                   
100 static int bcm43xx_wx_set_channelfreq(struct n    
101                                       struct i    
102                                       union iw    
103                                       char *ex    
104 {                                                 
105         struct bcm43xx_private *bcm = bcm43xx_    
106         unsigned long flags;                      
107         u8 channel;                               
108         s8 expon;                                 
109         int freq;                                 
110         int err = -EINVAL;                        
111                                                   
112         mutex_lock(&bcm->mutex);                  
113         spin_lock_irqsave(&bcm->irq_lock, flag    
114                                                   
115         if ((data->freq.e == 0) &&                
116             (data->freq.m >= 0) && (data->freq    
117                 channel = data->freq.m;           
118                 freq = bcm43xx_channel_to_freq    
119         } else {                                  
120                 freq = data->freq.m;              
121                 expon = 6 - data->freq.e;         
122                 while (--expon >= 0)    /* sca    
123                         freq /= 10;               
124                 assert(freq > 1000);              
125                 channel = bcm43xx_freq_to_chan    
126         }                                         
127         if (!ieee80211_is_valid_channel(bcm->i    
128                 goto out_unlock;                  
129         if (bcm43xx_status(bcm) == BCM43xx_STA    
130                 //ieee80211softmac_disassoc(so    
131                 bcm43xx_mac_suspend(bcm);         
132                 err = bcm43xx_radio_selectchan    
133                 bcm43xx_mac_enable(bcm);          
134         } else {                                  
135                 bcm43xx_current_radio(bcm)->in    
136                 err = 0;                          
137         }                                         
138 out_unlock:                                       
139         spin_unlock_irqrestore(&bcm->irq_lock,    
140         mutex_unlock(&bcm->mutex);                
141                                                   
142         return err;                               
143 }                                                 
144                                                   
145 static int bcm43xx_wx_get_channelfreq(struct n    
146                                       struct i    
147                                       union iw    
148                                       char *ex    
149 {                                                 
150         struct bcm43xx_private *bcm = bcm43xx_    
151         struct bcm43xx_radioinfo *radio;          
152         int err = -ENODEV;                        
153         u16 channel;                              
154                                                   
155         mutex_lock(&bcm->mutex);                  
156         radio = bcm43xx_current_radio(bcm);       
157         channel = radio->channel;                 
158         if (channel == 0xFF) {                    
159                 channel = radio->initial_chann    
160                 if (channel == 0xFF)              
161                         goto out_unlock;          
162         }                                         
163         assert(channel > 0 && channel <= 1000)    
164         data->freq.e = 1;                         
165         data->freq.m = bcm43xx_channel_to_freq    
166         data->freq.flags = 1;                     
167                                                   
168         err = 0;                                  
169 out_unlock:                                       
170         mutex_unlock(&bcm->mutex);                
171                                                   
172         return err;                               
173 }                                                 
174                                                   
175 static int bcm43xx_wx_set_mode(struct net_devi    
176                                struct iw_reque    
177                                union iwreq_dat    
178                                char *extra)       
179 {                                                 
180         struct bcm43xx_private *bcm = bcm43xx_    
181         unsigned long flags;                      
182         int mode;                                 
183                                                   
184         mode = data->mode;                        
185         if (mode == IW_MODE_AUTO)                 
186                 mode = BCM43xx_INITIAL_IWMODE;    
187                                                   
188         mutex_lock(&bcm->mutex);                  
189         spin_lock_irqsave(&bcm->irq_lock, flag    
190         if (bcm43xx_status(bcm) == BCM43xx_STA    
191                 if (bcm->ieee->iw_mode != mode    
192                         bcm43xx_set_iwmode(bcm    
193         } else                                    
194                 bcm->ieee->iw_mode = mode;        
195         spin_unlock_irqrestore(&bcm->irq_lock,    
196         mutex_unlock(&bcm->mutex);                
197                                                   
198         return 0;                                 
199 }                                                 
200                                                   
201 static int bcm43xx_wx_get_mode(struct net_devi    
202                                struct iw_reque    
203                                union iwreq_dat    
204                                char *extra)       
205 {                                                 
206         struct bcm43xx_private *bcm = bcm43xx_    
207                                                   
208         mutex_lock(&bcm->mutex);                  
209         data->mode = bcm->ieee->iw_mode;          
210         mutex_unlock(&bcm->mutex);                
211                                                   
212         return 0;                                 
213 }                                                 
214                                                   
215 static int bcm43xx_wx_get_rangeparams(struct n    
216                                       struct i    
217                                       union iw    
218                                       char *ex    
219 {                                                 
220         struct bcm43xx_private *bcm = bcm43xx_    
221         struct iw_range *range = (struct iw_ra    
222         const struct ieee80211_geo *geo;          
223         int i, j;                                 
224         struct bcm43xx_phyinfo *phy;              
225                                                   
226         data->data.length = sizeof(*range);       
227         memset(range, 0, sizeof(*range));         
228                                                   
229         //TODO: What about 802.11b?               
230         /* 54Mb/s == ~27Mb/s payload throughpu    
231         range->throughput = 27 * 1000 * 1000;     
232                                                   
233         range->max_qual.qual = 100;               
234         range->max_qual.level = 146; /* set fl    
235         range->max_qual.noise = 146;              
236         range->max_qual.updated = IW_QUAL_ALL_    
237                                                   
238         range->avg_qual.qual = 50;                
239         range->avg_qual.level = 0;                
240         range->avg_qual.noise = 0;                
241         range->avg_qual.updated = IW_QUAL_ALL_    
242                                                   
243         range->min_rts = BCM43xx_MIN_RTS_THRES    
244         range->max_rts = BCM43xx_MAX_RTS_THRES    
245         range->min_frag = MIN_FRAG_THRESHOLD;     
246         range->max_frag = MAX_FRAG_THRESHOLD;     
247                                                   
248         range->encoding_size[0] = 5;              
249         range->encoding_size[1] = 13;             
250         range->num_encoding_sizes = 2;            
251         range->max_encoding_tokens = WEP_KEYS;    
252                                                   
253         range->we_version_compiled = WIRELESS_    
254         range->we_version_source = BCM43xx_WX_    
255                                                   
256         range->enc_capa = IW_ENC_CAPA_WPA |       
257                           IW_ENC_CAPA_WPA2 |      
258                           IW_ENC_CAPA_CIPHER_T    
259                           IW_ENC_CAPA_CIPHER_C    
260                                                   
261         mutex_lock(&bcm->mutex);                  
262         phy = bcm43xx_current_phy(bcm);           
263                                                   
264         range->num_bitrates = 0;                  
265         i = 0;                                    
266         if (phy->type == BCM43xx_PHYTYPE_A ||     
267             phy->type == BCM43xx_PHYTYPE_G) {     
268                 range->num_bitrates = 8;          
269                 range->bitrate[i++] = IEEE8021    
270                 range->bitrate[i++] = IEEE8021    
271                 range->bitrate[i++] = IEEE8021    
272                 range->bitrate[i++] = IEEE8021    
273                 range->bitrate[i++] = IEEE8021    
274                 range->bitrate[i++] = IEEE8021    
275                 range->bitrate[i++] = IEEE8021    
276                 range->bitrate[i++] = IEEE8021    
277         }                                         
278         if (phy->type == BCM43xx_PHYTYPE_B ||     
279             phy->type == BCM43xx_PHYTYPE_G) {     
280                 range->num_bitrates += 4;         
281                 range->bitrate[i++] = IEEE8021    
282                 range->bitrate[i++] = IEEE8021    
283                 range->bitrate[i++] = IEEE8021    
284                 range->bitrate[i++] = IEEE8021    
285         }                                         
286                                                   
287         geo = ieee80211_get_geo(bcm->ieee);       
288         range->num_channels = geo->a_channels     
289         j = 0;                                    
290         for (i = 0; i < geo->a_channels; i++)     
291                 if (j == IW_MAX_FREQUENCIES)      
292                         break;                    
293                 range->freq[j].i = j + 1;         
294                 range->freq[j].m = geo->a[i].f    
295                 range->freq[j].e = 1;             
296                 j++;                              
297         }                                         
298         for (i = 0; i < geo->bg_channels; i++)    
299                 if (j == IW_MAX_FREQUENCIES)      
300                         break;                    
301                 range->freq[j].i = j + 1;         
302                 range->freq[j].m = geo->bg[i].    
303                 range->freq[j].e = 1;             
304                 j++;                              
305         }                                         
306         range->num_frequency = j;                 
307                                                   
308         mutex_unlock(&bcm->mutex);                
309                                                   
310         return 0;                                 
311 }                                                 
312                                                   
313 static int bcm43xx_wx_set_nick(struct net_devi    
314                                struct iw_reque    
315                                union iwreq_dat    
316                                char *extra)       
317 {                                                 
318         struct bcm43xx_private *bcm = bcm43xx_    
319         size_t len;                               
320                                                   
321         mutex_lock(&bcm->mutex);                  
322         len =  min((size_t)data->data.length,     
323         memcpy(bcm->nick, extra, len);            
324         bcm->nick[len] = '\0';                    
325         mutex_unlock(&bcm->mutex);                
326                                                   
327         return 0;                                 
328 }                                                 
329                                                   
330 static int bcm43xx_wx_get_nick(struct net_devi    
331                                struct iw_reque    
332                                union iwreq_dat    
333                                char *extra)       
334 {                                                 
335         struct bcm43xx_private *bcm = bcm43xx_    
336         size_t len;                               
337                                                   
338         mutex_lock(&bcm->mutex);                  
339         len = strlen(bcm->nick);                  
340         memcpy(extra, bcm->nick, len);            
341         data->data.length = (__u16)len;           
342         data->data.flags = 1;                     
343         mutex_unlock(&bcm->mutex);                
344                                                   
345         return 0;                                 
346 }                                                 
347                                                   
348 static int bcm43xx_wx_set_rts(struct net_devic    
349                               struct iw_reques    
350                               union iwreq_data    
351                               char *extra)        
352 {                                                 
353         struct bcm43xx_private *bcm = bcm43xx_    
354         unsigned long flags;                      
355         int err = -EINVAL;                        
356                                                   
357         mutex_lock(&bcm->mutex);                  
358         spin_lock_irqsave(&bcm->irq_lock, flag    
359         if (data->rts.disabled) {                 
360                 bcm->rts_threshold = BCM43xx_M    
361                 err = 0;                          
362         } else {                                  
363                 if (data->rts.value >= BCM43xx    
364                     data->rts.value <= BCM43xx    
365                         bcm->rts_threshold = d    
366                         err = 0;                  
367                 }                                 
368         }                                         
369         spin_unlock_irqrestore(&bcm->irq_lock,    
370         mutex_unlock(&bcm->mutex);                
371                                                   
372         return err;                               
373 }                                                 
374                                                   
375 static int bcm43xx_wx_get_rts(struct net_devic    
376                               struct iw_reques    
377                               union iwreq_data    
378                               char *extra)        
379 {                                                 
380         struct bcm43xx_private *bcm = bcm43xx_    
381                                                   
382         mutex_lock(&bcm->mutex);                  
383         data->rts.value = bcm->rts_threshold;     
384         data->rts.fixed = 0;                      
385         data->rts.disabled = (bcm->rts_thresho    
386         mutex_unlock(&bcm->mutex);                
387                                                   
388         return 0;                                 
389 }                                                 
390                                                   
391 static int bcm43xx_wx_set_frag(struct net_devi    
392                                struct iw_reque    
393                                union iwreq_dat    
394                                char *extra)       
395 {                                                 
396         struct bcm43xx_private *bcm = bcm43xx_    
397         unsigned long flags;                      
398         int err = -EINVAL;                        
399                                                   
400         mutex_lock(&bcm->mutex);                  
401         spin_lock_irqsave(&bcm->irq_lock, flag    
402         if (data->frag.disabled) {                
403                 bcm->ieee->fts = MAX_FRAG_THRE    
404                 err = 0;                          
405         } else {                                  
406                 if (data->frag.value >= MIN_FR    
407                     data->frag.value <= MAX_FR    
408                         bcm->ieee->fts = data-    
409                         err = 0;                  
410                 }                                 
411         }                                         
412         spin_unlock_irqrestore(&bcm->irq_lock,    
413         mutex_unlock(&bcm->mutex);                
414                                                   
415         return err;                               
416 }                                                 
417                                                   
418 static int bcm43xx_wx_get_frag(struct net_devi    
419                                struct iw_reque    
420                                union iwreq_dat    
421                                char *extra)       
422 {                                                 
423         struct bcm43xx_private *bcm = bcm43xx_    
424                                                   
425         mutex_lock(&bcm->mutex);                  
426         data->frag.value = bcm->ieee->fts;        
427         data->frag.fixed = 0;                     
428         data->frag.disabled = (bcm->ieee->fts     
429         mutex_unlock(&bcm->mutex);                
430                                                   
431         return 0;                                 
432 }                                                 
433                                                   
434 static int bcm43xx_wx_set_xmitpower(struct net    
435                                     struct iw_    
436                                     union iwre    
437                                     char *extr    
438 {                                                 
439         struct bcm43xx_private *bcm = bcm43xx_    
440         struct bcm43xx_radioinfo *radio;          
441         struct bcm43xx_phyinfo *phy;              
442         unsigned long flags;                      
443         int err = -ENODEV;                        
444         u16 maxpower;                             
445                                                   
446         if ((data->txpower.flags & IW_TXPOW_TY    
447                 printk(KERN_ERR PFX "TX power     
448                 return -EOPNOTSUPP;               
449         }                                         
450                                                   
451         mutex_lock(&bcm->mutex);                  
452         spin_lock_irqsave(&bcm->irq_lock, flag    
453         if (bcm43xx_status(bcm) != BCM43xx_STA    
454                 goto out_unlock;                  
455         radio = bcm43xx_current_radio(bcm);       
456         phy = bcm43xx_current_phy(bcm);           
457         if (data->txpower.disabled != (!(radio    
458                 if (data->txpower.disabled)       
459                         bcm43xx_radio_turn_off    
460                 else                              
461                         bcm43xx_radio_turn_on(    
462         }                                         
463         if (data->txpower.value > 0) {            
464                 /* desired and maxpower dBm va    
465                 if (phy->type == BCM43xx_PHYTY    
466                         maxpower = bcm->sprom.    
467                 else                              
468                         maxpower = bcm->sprom.    
469                 radio->txpower_desired = limit    
470                                                   
471                 bcm43xx_phy_xmitpower(bcm);       
472         }                                         
473         err = 0;                                  
474                                                   
475 out_unlock:                                       
476         spin_unlock_irqrestore(&bcm->irq_lock,    
477         mutex_unlock(&bcm->mutex);                
478                                                   
479         return err;                               
480 }                                                 
481                                                   
482 static int bcm43xx_wx_get_xmitpower(struct net    
483                                     struct iw_    
484                                     union iwre    
485                                     char *extr    
486 {                                                 
487         struct bcm43xx_private *bcm = bcm43xx_    
488         struct bcm43xx_radioinfo *radio;          
489         int err = -ENODEV;                        
490                                                   
491         mutex_lock(&bcm->mutex);                  
492         if (bcm43xx_status(bcm) != BCM43xx_STA    
493                 goto out_unlock;                  
494         radio = bcm43xx_current_radio(bcm);       
495         /* desired dBm value is in Q5.2 */        
496         data->txpower.value = radio->txpower_d    
497         data->txpower.fixed = 1;                  
498         data->txpower.flags = IW_TXPOW_DBM;       
499         data->txpower.disabled = !(radio->enab    
500                                                   
501         err = 0;                                  
502 out_unlock:                                       
503         mutex_unlock(&bcm->mutex);                
504                                                   
505         return err;                               
506 }                                                 
507                                                   
508 static int bcm43xx_wx_set_encoding(struct net_    
509                                    struct iw_r    
510                                    union iwreq    
511                                    char *extra    
512 {                                                 
513         struct bcm43xx_private *bcm = bcm43xx_    
514         int err;                                  
515                                                   
516         err = ieee80211_wx_set_encode(bcm->iee    
517                                                   
518         return err;                               
519 }                                                 
520                                                   
521 static int bcm43xx_wx_set_encodingext(struct n    
522                                    struct iw_r    
523                                    union iwreq    
524                                    char *extra    
525 {                                                 
526         struct bcm43xx_private *bcm = bcm43xx_    
527         int err;                                  
528                                                   
529         err = ieee80211_wx_set_encodeext(bcm->    
530                                                   
531         return err;                               
532 }                                                 
533                                                   
534 static int bcm43xx_wx_get_encoding(struct net_    
535                                    struct iw_r    
536                                    union iwreq    
537                                    char *extra    
538 {                                                 
539         struct bcm43xx_private *bcm = bcm43xx_    
540         int err;                                  
541                                                   
542         err = ieee80211_wx_get_encode(bcm->iee    
543                                                   
544         return err;                               
545 }                                                 
546                                                   
547 static int bcm43xx_wx_get_encodingext(struct n    
548                                    struct iw_r    
549                                    union iwreq    
550                                    char *extra    
551 {                                                 
552         struct bcm43xx_private *bcm = bcm43xx_    
553         int err;                                  
554                                                   
555         err = ieee80211_wx_get_encodeext(bcm->    
556                                                   
557         return err;                               
558 }                                                 
559                                                   
560 static int bcm43xx_wx_set_interfmode(struct ne    
561                                      struct iw    
562                                      union iwr    
563                                      char *ext    
564 {                                                 
565         struct bcm43xx_private *bcm = bcm43xx_    
566         unsigned long flags;                      
567         int mode, err = 0;                        
568                                                   
569         mode = *((int *)extra);                   
570         switch (mode) {                           
571         case 0:                                   
572                 mode = BCM43xx_RADIO_INTERFMOD    
573                 break;                            
574         case 1:                                   
575                 mode = BCM43xx_RADIO_INTERFMOD    
576                 break;                            
577         case 2:                                   
578                 mode = BCM43xx_RADIO_INTERFMOD    
579                 break;                            
580         case 3:                                   
581                 mode = BCM43xx_RADIO_INTERFMOD    
582                 break;                            
583         default:                                  
584                 printk(KERN_ERR PFX "set_inter    
585                                     "0 => None    
586                                     "3 => Auto    
587                 return -EINVAL;                   
588         }                                         
589                                                   
590         mutex_lock(&bcm->mutex);                  
591         spin_lock_irqsave(&bcm->irq_lock, flag    
592         if (bcm43xx_status(bcm) == BCM43xx_STA    
593                 err = bcm43xx_radio_set_interf    
594                 if (err) {                        
595                         printk(KERN_ERR PFX "I    
596                                             "s    
597                 }                                 
598         } else {                                  
599                 if (mode == BCM43xx_RADIO_INTE    
600                         printk(KERN_ERR PFX "I    
601                                             "n    
602                         err = -ENODEV;            
603                 } else                            
604                         bcm43xx_current_radio(    
605         }                                         
606         spin_unlock_irqrestore(&bcm->irq_lock,    
607         mutex_unlock(&bcm->mutex);                
608                                                   
609         return err;                               
610 }                                                 
611                                                   
612 static int bcm43xx_wx_get_interfmode(struct ne    
613                                      struct iw    
614                                      union iwr    
615                                      char *ext    
616 {                                                 
617         struct bcm43xx_private *bcm = bcm43xx_    
618         int mode;                                 
619                                                   
620         mutex_lock(&bcm->mutex);                  
621         mode = bcm43xx_current_radio(bcm)->int    
622         mutex_unlock(&bcm->mutex);                
623                                                   
624         switch (mode) {                           
625         case BCM43xx_RADIO_INTERFMODE_NONE:       
626                 strncpy(extra, "0 (No Interfer    
627                 break;                            
628         case BCM43xx_RADIO_INTERFMODE_NONWLAN:    
629                 strncpy(extra, "1 (Non-WLAN In    
630                 break;                            
631         case BCM43xx_RADIO_INTERFMODE_MANUALWL    
632                 strncpy(extra, "2 (WLAN Interf    
633                 break;                            
634         default:                                  
635                 assert(0);                        
636         }                                         
637         data->data.length = strlen(extra) + 1;    
638                                                   
639         return 0;                                 
640 }                                                 
641                                                   
642 static int bcm43xx_wx_set_shortpreamble(struct    
643                                         struct    
644                                         union     
645                                         char *    
646 {                                                 
647         struct bcm43xx_private *bcm = bcm43xx_    
648         unsigned long flags;                      
649         int on;                                   
650                                                   
651         on = *((int *)extra);                     
652         mutex_lock(&bcm->mutex);                  
653         spin_lock_irqsave(&bcm->irq_lock, flag    
654         bcm->short_preamble = !!on;               
655         spin_unlock_irqrestore(&bcm->irq_lock,    
656         mutex_unlock(&bcm->mutex);                
657                                                   
658         return 0;                                 
659 }                                                 
660                                                   
661 static int bcm43xx_wx_get_shortpreamble(struct    
662                                         struct    
663                                         union     
664                                         char *    
665 {                                                 
666         struct bcm43xx_private *bcm = bcm43xx_    
667         int on;                                   
668                                                   
669         mutex_lock(&bcm->mutex);                  
670         on = bcm->short_preamble;                 
671         mutex_unlock(&bcm->mutex);                
672                                                   
673         if (on)                                   
674                 strncpy(extra, "1 (Short Pream    
675         else                                      
676                 strncpy(extra, "0 (Short Pream    
677         data->data.length = strlen(extra) + 1;    
678                                                   
679         return 0;                                 
680 }                                                 
681                                                   
682 static int bcm43xx_wx_set_swencryption(struct     
683                                        struct     
684                                        union i    
685                                        char *e    
686 {                                                 
687         struct bcm43xx_private *bcm = bcm43xx_    
688         unsigned long flags;                      
689         int on;                                   
690                                                   
691         on = *((int *)extra);                     
692                                                   
693         mutex_lock(&bcm->mutex);                  
694         spin_lock_irqsave(&bcm->irq_lock, flag    
695         bcm->ieee->host_encrypt = !!on;           
696         bcm->ieee->host_decrypt = !!on;           
697         bcm->ieee->host_build_iv = !on;           
698         bcm->ieee->host_strip_iv_icv = !on;       
699         spin_unlock_irqrestore(&bcm->irq_lock,    
700         mutex_unlock(&bcm->mutex);                
701                                                   
702         return 0;                                 
703 }                                                 
704                                                   
705 static int bcm43xx_wx_get_swencryption(struct     
706                                        struct     
707                                        union i    
708                                        char *e    
709 {                                                 
710         struct bcm43xx_private *bcm = bcm43xx_    
711         int on;                                   
712                                                   
713         mutex_lock(&bcm->mutex);                  
714         on = bcm->ieee->host_encrypt;             
715         mutex_unlock(&bcm->mutex);                
716                                                   
717         if (on)                                   
718                 strncpy(extra, "1 (SW encrypti    
719         else                                      
720                 strncpy(extra, "0 (SW encrypti    
721         data->data.length = strlen(extra + 1);    
722                                                   
723         return 0;                                 
724 }                                                 
725                                                   
726 /* Enough buffer to hold a hexdump of the spro    
727 #define SPROM_BUFFERSIZE        512               
728                                                   
729 static int sprom2hex(const u16 *sprom, char *d    
730 {                                                 
731         int i, pos = 0;                           
732                                                   
733         for (i = 0; i < BCM43xx_SPROM_SIZE; i+    
734                 pos += snprintf(dump + pos, SP    
735                                 "%04X", swab16    
736         }                                         
737                                                   
738         return pos + 1;                           
739 }                                                 
740                                                   
741 static int hex2sprom(u16 *sprom, const char *d    
742 {                                                 
743         char tmp[5] = { 0 };                      
744         int cnt = 0;                              
745         unsigned long parsed;                     
746                                                   
747         if (len < BCM43xx_SPROM_SIZE * sizeof(    
748                 return -EINVAL;                   
749         while (cnt < BCM43xx_SPROM_SIZE) {        
750                 memcpy(tmp, dump, 4);             
751                 dump += 4;                        
752                 parsed = simple_strtoul(tmp, N    
753                 sprom[cnt++] = swab16((u16)par    
754         }                                         
755                                                   
756         return 0;                                 
757 }                                                 
758                                                   
759 static int bcm43xx_wx_sprom_read(struct net_de    
760                                  struct iw_req    
761                                  union iwreq_d    
762                                  char *extra)     
763 {                                                 
764         struct bcm43xx_private *bcm = bcm43xx_    
765         int err = -EPERM;                         
766         u16 *sprom;                               
767         unsigned long flags;                      
768                                                   
769         if (!capable(CAP_SYS_RAWIO))              
770                 goto out;                         
771                                                   
772         err = -ENOMEM;                            
773         sprom = kmalloc(BCM43xx_SPROM_SIZE * s    
774                         GFP_KERNEL);              
775         if (!sprom)                               
776                 goto out;                         
777                                                   
778         mutex_lock(&bcm->mutex);                  
779         spin_lock_irqsave(&bcm->irq_lock, flag    
780         err = -ENODEV;                            
781         if (bcm43xx_status(bcm) == BCM43xx_STA    
782                 err = bcm43xx_sprom_read(bcm,     
783         spin_unlock_irqrestore(&bcm->irq_lock,    
784         mutex_unlock(&bcm->mutex);                
785         if (!err)                                 
786                 data->data.length = sprom2hex(    
787         kfree(sprom);                             
788 out:                                              
789         return err;                               
790 }                                                 
791                                                   
792 static int bcm43xx_wx_sprom_write(struct net_d    
793                                   struct iw_re    
794                                   union iwreq_    
795                                   char *extra)    
796 {                                                 
797         struct bcm43xx_private *bcm = bcm43xx_    
798         int err = -EPERM;                         
799         u16 *sprom;                               
800         unsigned long flags;                      
801         char *input;                              
802         unsigned int len;                         
803                                                   
804         if (!capable(CAP_SYS_RAWIO))              
805                 goto out;                         
806                                                   
807         err = -ENOMEM;                            
808         sprom = kmalloc(BCM43xx_SPROM_SIZE * s    
809                         GFP_KERNEL);              
810         if (!sprom)                               
811                 goto out;                         
812                                                   
813         len = data->data.length;                  
814         extra[len - 1] = '\0';                    
815         input = strchr(extra, ':');               
816         if (input) {                              
817                 input++;                          
818                 len -= input - extra;             
819         } else                                    
820                 input = extra;                    
821         err = hex2sprom(sprom, input, len);       
822         if (err)                                  
823                 goto out_kfree;                   
824                                                   
825         mutex_lock(&bcm->mutex);                  
826         spin_lock_irqsave(&bcm->irq_lock, flag    
827         spin_lock(&bcm->leds_lock);               
828         err = -ENODEV;                            
829         if (bcm43xx_status(bcm) == BCM43xx_STA    
830                 err = bcm43xx_sprom_write(bcm,    
831         spin_unlock(&bcm->leds_lock);             
832         spin_unlock_irqrestore(&bcm->irq_lock,    
833         mutex_unlock(&bcm->mutex);                
834 out_kfree:                                        
835         kfree(sprom);                             
836 out:                                              
837         return err;                               
838 }                                                 
839                                                   
840 /* Get wireless statistics.  Called by /proc/n    
841                                                   
842 static struct iw_statistics *bcm43xx_get_wirel    
843 {                                                 
844         struct bcm43xx_private *bcm = bcm43xx_    
845         struct ieee80211softmac_device *mac =     
846         struct iw_statistics *wstats;             
847         struct ieee80211_network *network = NU    
848         static int tmp_level = 0;                 
849         static int tmp_qual = 0;                  
850         unsigned long flags;                      
851                                                   
852         wstats = &bcm->stats.wstats;              
853         if (!mac->associnfo.associated) {         
854                 wstats->miss.beacon = 0;          
855 //              bcm->ieee->ieee_stats.tx_retry    
856                 wstats->discard.retries = 0;      
857 //              bcm->ieee->ieee_stats.tx_disca    
858                 wstats->discard.nwid = 0;         
859 //              bcm->ieee->ieee_stats.rx_disca    
860                 wstats->discard.code = 0;         
861 //              bcm->ieee->ieee_stats.rx_fragm    
862                 wstats->discard.fragment = 0;     
863                 wstats->discard.misc = 0;         
864                 wstats->qual.qual = 0;            
865                 wstats->qual.level = 0;           
866                 wstats->qual.noise = 0;           
867                 wstats->qual.updated = 7;         
868                 wstats->qual.updated |= IW_QUA    
869                 return wstats;                    
870         }                                         
871         /* fill in the real statistics when if    
872         spin_lock_irqsave(&mac->ieee->lock, fl    
873         list_for_each_entry(network, &mac->iee    
874                 if (!memcmp(mac->associnfo.bss    
875                         if (!tmp_level) {         
876                                 tmp_level = ne    
877                                 tmp_qual = net    
878                         } else {                  
879                                 tmp_level = (1    
880                                 tmp_qual = (15    
881                         }                         
882                         break;                    
883                 }                                 
884         }                                         
885         spin_unlock_irqrestore(&mac->ieee->loc    
886         wstats->qual.level = tmp_level;           
887         wstats->qual.qual = 100 * tmp_qual / R    
888         wstats->qual.noise = bcm->stats.noise;    
889         wstats->qual.updated = IW_QUAL_ALL_UPD    
890         wstats->discard.code = bcm->ieee->ieee    
891         wstats->discard.retries = bcm->ieee->i    
892         wstats->discard.nwid = bcm->ieee->ieee    
893         wstats->discard.fragment = bcm->ieee->    
894         wstats->discard.misc = 0;       // FIX    
895         wstats->miss.beacon = 0;        // FIX    
896         return wstats;                            
897 }                                                 
898                                                   
899                                                   
900 #ifdef WX                                         
901 # undef WX                                        
902 #endif                                            
903 #define WX(ioctl)  [(ioctl) - SIOCSIWCOMMIT]      
904 static const iw_handler bcm43xx_wx_handlers[]     
905         /* Wireless Identification */             
906         WX(SIOCGIWNAME)         = bcm43xx_wx_g    
907         /* Basic operations */                    
908         WX(SIOCSIWFREQ)         = bcm43xx_wx_s    
909         WX(SIOCGIWFREQ)         = bcm43xx_wx_g    
910         WX(SIOCSIWMODE)         = bcm43xx_wx_s    
911         WX(SIOCGIWMODE)         = bcm43xx_wx_g    
912         /* Informative stuff */                   
913         WX(SIOCGIWRANGE)        = bcm43xx_wx_g    
914         /* Access Point manipulation */           
915         WX(SIOCSIWAP)           = ieee80211sof    
916         WX(SIOCGIWAP)           = ieee80211sof    
917         WX(SIOCSIWSCAN)         = ieee80211sof    
918         WX(SIOCGIWSCAN)         = ieee80211sof    
919         /* 802.11 specific support */             
920         WX(SIOCSIWESSID)        = ieee80211sof    
921         WX(SIOCGIWESSID)        = ieee80211sof    
922         WX(SIOCSIWNICKN)        = bcm43xx_wx_s    
923         WX(SIOCGIWNICKN)        = bcm43xx_wx_g    
924         /* Other parameters */                    
925         WX(SIOCSIWRATE)         = ieee80211sof    
926         WX(SIOCGIWRATE)         = ieee80211sof    
927         WX(SIOCSIWRTS)          = bcm43xx_wx_s    
928         WX(SIOCGIWRTS)          = bcm43xx_wx_g    
929         WX(SIOCSIWFRAG)         = bcm43xx_wx_s    
930         WX(SIOCGIWFRAG)         = bcm43xx_wx_g    
931         WX(SIOCSIWTXPOW)        = bcm43xx_wx_s    
932         WX(SIOCGIWTXPOW)        = bcm43xx_wx_g    
933 //TODO  WX(SIOCSIWRETRY)        = bcm43xx_wx_s    
934 //TODO  WX(SIOCGIWRETRY)        = bcm43xx_wx_g    
935         /* Encoding */                            
936         WX(SIOCSIWENCODE)       = bcm43xx_wx_s    
937         WX(SIOCGIWENCODE)       = bcm43xx_wx_g    
938         WX(SIOCSIWENCODEEXT)    = bcm43xx_wx_s    
939         WX(SIOCGIWENCODEEXT)    = bcm43xx_wx_g    
940         /* Power saving */                        
941 //TODO  WX(SIOCSIWPOWER)        = bcm43xx_wx_s    
942 //TODO  WX(SIOCGIWPOWER)        = bcm43xx_wx_g    
943         WX(SIOCSIWGENIE)        = ieee80211sof    
944         WX(SIOCGIWGENIE)        = ieee80211sof    
945         WX(SIOCSIWAUTH)         = ieee80211_wx    
946         WX(SIOCGIWAUTH)         = ieee80211_wx    
947 };                                                
948 #undef WX                                         
949                                                   
950 static const iw_handler bcm43xx_priv_wx_handle    
951         /* Set Interference Mitigation Mode. *    
952         bcm43xx_wx_set_interfmode,                
953         /* Get Interference Mitigation Mode. *    
954         bcm43xx_wx_get_interfmode,                
955         /* Enable/Disable Short Preamble mode.    
956         bcm43xx_wx_set_shortpreamble,             
957         /* Get Short Preamble mode. */            
958         bcm43xx_wx_get_shortpreamble,             
959         /* Enable/Disable Software Encryption     
960         bcm43xx_wx_set_swencryption,              
961         /* Get Software Encryption mode */        
962         bcm43xx_wx_get_swencryption,              
963         /* Write SRPROM data. */                  
964         bcm43xx_wx_sprom_write,                   
965         /* Read SPROM data. */                    
966         bcm43xx_wx_sprom_read,                    
967 };                                                
968                                                   
969 #define PRIV_WX_SET_INTERFMODE          (SIOCI    
970 #define PRIV_WX_GET_INTERFMODE          (SIOCI    
971 #define PRIV_WX_SET_SHORTPREAMBLE       (SIOCI    
972 #define PRIV_WX_GET_SHORTPREAMBLE       (SIOCI    
973 #define PRIV_WX_SET_SWENCRYPTION        (SIOCI    
974 #define PRIV_WX_GET_SWENCRYPTION        (SIOCI    
975 #define PRIV_WX_SPROM_WRITE             (SIOCI    
976 #define PRIV_WX_SPROM_READ              (SIOCI    
977                                                   
978 #define PRIV_WX_DUMMY(ioctl)    \                 
979         {                                         
980                 .cmd            = (ioctl),        
981                 .name           = "__unused"      
982         }                                         
983                                                   
984 static const struct iw_priv_args bcm43xx_priv_    
985         {                                         
986                 .cmd            = PRIV_WX_SET_    
987                 .set_args       = IW_PRIV_TYPE    
988                 .name           = "set_interfm    
989         },                                        
990         {                                         
991                 .cmd            = PRIV_WX_GET_    
992                 .get_args       = IW_PRIV_TYPE    
993                 .name           = "get_interfm    
994         },                                        
995         {                                         
996                 .cmd            = PRIV_WX_SET_    
997                 .set_args       = IW_PRIV_TYPE    
998                 .name           = "set_shortpr    
999         },                                        
1000         {                                        
1001                 .cmd            = PRIV_WX_GET    
1002                 .get_args       = IW_PRIV_TYP    
1003                 .name           = "get_shortp    
1004         },                                       
1005         {                                        
1006                 .cmd            = PRIV_WX_SET    
1007                 .set_args       = IW_PRIV_TYP    
1008                 .name           = "set_swencr    
1009         },                                       
1010         {                                        
1011                 .cmd            = PRIV_WX_GET    
1012                 .get_args       = IW_PRIV_TYP    
1013                 .name           = "get_swencr    
1014         },                                       
1015         {                                        
1016                 .cmd            = PRIV_WX_SPR    
1017                 .set_args       = IW_PRIV_TYP    
1018                 .name           = "write_spro    
1019         },                                       
1020         {                                        
1021                 .cmd            = PRIV_WX_SPR    
1022                 .get_args       = IW_PRIV_TYP    
1023                 .name           = "read_sprom    
1024         },                                       
1025 };                                               
1026                                                  
1027 const struct iw_handler_def bcm43xx_wx_handle    
1028         .standard               = bcm43xx_wx_    
1029         .num_standard           = ARRAY_SIZE(    
1030         .num_private            = ARRAY_SIZE(    
1031         .num_private_args       = ARRAY_SIZE(    
1032         .private                = bcm43xx_pri    
1033         .private_args           = bcm43xx_pri    
1034         .get_wireless_stats     = bcm43xx_get    
1035 };                                               
1036                                                  
  This page was automatically generated by the LXR engine.