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/net/mac80211/mlme.c (Version 2.6.31.13) and /linux/net/mac80211/mlme.c (Version 2.6.25)


  1 /*                                                  1 
  2  * BSS client mode implementation                 
  3  * Copyright 2003-2008, Jouni Malinen <j@w1.fi    
  4  * Copyright 2004, Instant802 Networks, Inc.      
  5  * Copyright 2005, Devicescape Software, Inc.     
  6  * Copyright 2006-2007  Jiri Benc <jbenc@suse.    
  7  * Copyright 2007, Michael Wu <flamingice@sour    
  8  *                                                
  9  * This program is free software; you can redi    
 10  * it under the terms of the GNU General Publi    
 11  * published by the Free Software Foundation.     
 12  */                                               
 13                                                   
 14 #include <linux/delay.h>                          
 15 #include <linux/if_ether.h>                       
 16 #include <linux/skbuff.h>                         
 17 #include <linux/if_arp.h>                         
 18 #include <linux/etherdevice.h>                    
 19 #include <linux/rtnetlink.h>                      
 20 #include <linux/pm_qos_params.h>                  
 21 #include <linux/crc32.h>                          
 22 #include <net/mac80211.h>                         
 23 #include <asm/unaligned.h>                        
 24                                                   
 25 #include "ieee80211_i.h"                          
 26 #include "driver-ops.h"                           
 27 #include "rate.h"                                 
 28 #include "led.h"                                  
 29                                                   
 30 #define IEEE80211_ASSOC_SCANS_MAX_TRIES 2         
 31 #define IEEE80211_AUTH_TIMEOUT (HZ / 5)           
 32 #define IEEE80211_AUTH_MAX_TRIES 3                
 33 #define IEEE80211_ASSOC_TIMEOUT (HZ / 5)          
 34 #define IEEE80211_ASSOC_MAX_TRIES 3               
 35 #define IEEE80211_MONITORING_INTERVAL (2 * HZ)    
 36 #define IEEE80211_PROBE_WAIT (HZ / 5)             
 37 #define IEEE80211_PROBE_IDLE_TIME (60 * HZ)       
 38 #define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)    
 39                                                   
 40 #define TMR_RUNNING_TIMER       0                 
 41 #define TMR_RUNNING_CHANSW      1                 
 42                                                   
 43 /* utils */                                       
 44 static int ecw2cw(int ecw)                        
 45 {                                                 
 46         return (1 << ecw) - 1;                    
 47 }                                                 
 48                                                   
 49 static u8 *ieee80211_bss_get_ie(struct ieee802    
 50 {                                                 
 51         u8 *end, *pos;                            
 52                                                   
 53         pos = bss->cbss.information_elements;     
 54         if (pos == NULL)                          
 55                 return NULL;                      
 56         end = pos + bss->cbss.len_information_    
 57                                                   
 58         while (pos + 1 < end) {                   
 59                 if (pos + 2 + pos[1] > end)       
 60                         break;                    
 61                 if (pos[0] == ie)                 
 62                         return pos;               
 63                 pos += 2 + pos[1];                
 64         }                                         
 65                                                   
 66         return NULL;                              
 67 }                                                 
 68                                                   
 69 static int ieee80211_compatible_rates(struct i    
 70                                       struct i    
 71                                       u32 *rat    
 72 {                                                 
 73         int i, j, count;                          
 74         *rates = 0;                               
 75         count = 0;                                
 76         for (i = 0; i < bss->supp_rates_len; i    
 77                 int rate = (bss->supp_rates[i]    
 78                                                   
 79                 for (j = 0; j < sband->n_bitra    
 80                         if (sband->bitrates[j]    
 81                                 *rates |= BIT(    
 82                                 count++;          
 83                                 break;            
 84                         }                         
 85         }                                         
 86                                                   
 87         return count;                             
 88 }                                                 
 89                                                   
 90 /*                                                
 91  * ieee80211_enable_ht should be called only a    
 92  * has been determined as ht configuration dep    
 93  * HT abilities for a specific band.              
 94  */                                               
 95 static u32 ieee80211_enable_ht(struct ieee8021    
 96                                struct ieee8021    
 97                                u16 ap_ht_cap_f    
 98 {                                                 
 99         struct ieee80211_local *local = sdata-    
100         struct ieee80211_supported_band *sband    
101         struct ieee80211_if_managed *ifmgd = &    
102         struct sta_info *sta;                     
103         u32 changed = 0;                          
104         u16 ht_opmode;                            
105         bool enable_ht = true, ht_changed;        
106         enum nl80211_channel_type channel_type    
107                                                   
108         sband = local->hw.wiphy->bands[local->    
109                                                   
110         /* HT is not supported */                 
111         if (!sband->ht_cap.ht_supported)          
112                 enable_ht = false;                
113                                                   
114         /* check that channel matches the righ    
115         if (local->hw.conf.channel->center_fre    
116             ieee80211_channel_to_frequency(hti    
117                 enable_ht = false;                
118                                                   
119         if (enable_ht) {                          
120                 channel_type = NL80211_CHAN_HT    
121                                                   
122                 if (!(ap_ht_cap_flags & IEEE80    
123                     (sband->ht_cap.cap & IEEE8    
124                     (hti->ht_param & IEEE80211    
125                         switch(hti->ht_param &    
126                         case IEEE80211_HT_PARA    
127                                 if (!(local->h    
128                                     IEEE80211_    
129                                         channe    
130                                 break;            
131                         case IEEE80211_HT_PARA    
132                                 if (!(local->h    
133                                     IEEE80211_    
134                                         channe    
135                                 break;            
136                         }                         
137                 }                                 
138         }                                         
139                                                   
140         ht_changed = conf_is_ht(&local->hw.con    
141                      channel_type != local->hw    
142                                                   
143         local->oper_channel_type = channel_typ    
144                                                   
145         if (ht_changed) {                         
146                 /* channel_type change automat    
147                 ieee80211_hw_config(local, 0);    
148                                                   
149                 rcu_read_lock();                  
150                                                   
151                 sta = sta_info_get(local, ifmg    
152                 if (sta)                          
153                         rate_control_rate_upda    
154                                                   
155                                                   
156                 rcu_read_unlock();                
157         }                                         
158                                                   
159         /* disable HT */                          
160         if (!enable_ht)                           
161                 return 0;                         
162                                                   
163         ht_opmode = le16_to_cpu(hti->operation    
164                                                   
165         /* if bss configuration changed store     
166         if (!sdata->ht_opmode_valid ||            
167             sdata->vif.bss_conf.ht_operation_m    
168                 changed |= BSS_CHANGED_HT;        
169                 sdata->vif.bss_conf.ht_operati    
170                 sdata->ht_opmode_valid = true;    
171         }                                         
172                                                   
173         return changed;                           
174 }                                                 
175                                                   
176 /* frame sending functions */                     
177                                                   
178 static void ieee80211_send_assoc(struct ieee80    
179 {                                                 
180         struct ieee80211_if_managed *ifmgd = &    
181         struct ieee80211_local *local = sdata-    
182         struct sk_buff *skb;                      
183         struct ieee80211_mgmt *mgmt;              
184         u8 *pos, *ies, *ht_ie;                    
185         int i, len, count, rates_len, supp_rat    
186         u16 capab;                                
187         struct ieee80211_bss *bss;                
188         int wmm = 0;                              
189         struct ieee80211_supported_band *sband    
190         u32 rates = 0;                            
191                                                   
192         skb = dev_alloc_skb(local->hw.extra_tx    
193                             sizeof(*mgmt) + 20    
194                             ifmgd->ssid_len);     
195         if (!skb) {                               
196                 printk(KERN_DEBUG "%s: failed     
197                        "frame\n", sdata->dev->    
198                 return;                           
199         }                                         
200         skb_reserve(skb, local->hw.extra_tx_he    
201                                                   
202         sband = local->hw.wiphy->bands[local->    
203                                                   
204         capab = ifmgd->capab;                     
205                                                   
206         if (local->hw.conf.channel->band == IE    
207                 if (!(local->hw.flags & IEEE80    
208                         capab |= WLAN_CAPABILI    
209                 if (!(local->hw.flags & IEEE80    
210                         capab |= WLAN_CAPABILI    
211         }                                         
212                                                   
213         bss = ieee80211_rx_bss_get(local, ifmg    
214                                    local->hw.c    
215                                    ifmgd->ssid    
216         if (bss) {                                
217                 if (bss->cbss.capability & WLA    
218                         capab |= WLAN_CAPABILI    
219                 if (bss->wmm_used)                
220                         wmm = 1;                  
221                                                   
222                 /* get all rates supported by     
223                  * some APs don't like getting    
224                  * in the association request     
225                  * b-only mode) */                
226                 rates_len = ieee80211_compatib    
227                                                   
228                 if ((bss->cbss.capability & WL    
229                     (local->hw.flags & IEEE802    
230                         capab |= WLAN_CAPABILI    
231                                                   
232                 ieee80211_rx_bss_put(local, bs    
233         } else {                                  
234                 rates = ~0;                       
235                 rates_len = sband->n_bitrates;    
236         }                                         
237                                                   
238         mgmt = (struct ieee80211_mgmt *) skb_p    
239         memset(mgmt, 0, 24);                      
240         memcpy(mgmt->da, ifmgd->bssid, ETH_ALE    
241         memcpy(mgmt->sa, sdata->dev->dev_addr,    
242         memcpy(mgmt->bssid, ifmgd->bssid, ETH_    
243                                                   
244         if (ifmgd->flags & IEEE80211_STA_PREV_    
245                 skb_put(skb, 10);                 
246                 mgmt->frame_control = cpu_to_l    
247                                                   
248                 mgmt->u.reassoc_req.capab_info    
249                 mgmt->u.reassoc_req.listen_int    
250                                 cpu_to_le16(lo    
251                 memcpy(mgmt->u.reassoc_req.cur    
252                        ETH_ALEN);                 
253         } else {                                  
254                 skb_put(skb, 4);                  
255                 mgmt->frame_control = cpu_to_l    
256                                                   
257                 mgmt->u.assoc_req.capab_info =    
258                 mgmt->u.assoc_req.listen_inter    
259                                 cpu_to_le16(lo    
260         }                                         
261                                                   
262         /* SSID */                                
263         ies = pos = skb_put(skb, 2 + ifmgd->ss    
264         *pos++ = WLAN_EID_SSID;                   
265         *pos++ = ifmgd->ssid_len;                 
266         memcpy(pos, ifmgd->ssid, ifmgd->ssid_l    
267                                                   
268         /* add all rates which were marked to     
269         supp_rates_len = rates_len;               
270         if (supp_rates_len > 8)                   
271                 supp_rates_len = 8;               
272                                                   
273         len = sband->n_bitrates;                  
274         pos = skb_put(skb, supp_rates_len + 2)    
275         *pos++ = WLAN_EID_SUPP_RATES;             
276         *pos++ = supp_rates_len;                  
277                                                   
278         count = 0;                                
279         for (i = 0; i < sband->n_bitrates; i++    
280                 if (BIT(i) & rates) {             
281                         int rate = sband->bitr    
282                         *pos++ = (u8) (rate /     
283                         if (++count == 8)         
284                                 break;            
285                 }                                 
286         }                                         
287                                                   
288         if (rates_len > count) {                  
289                 pos = skb_put(skb, rates_len -    
290                 *pos++ = WLAN_EID_EXT_SUPP_RAT    
291                 *pos++ = rates_len - count;       
292                                                   
293                 for (i++; i < sband->n_bitrate    
294                         if (BIT(i) & rates) {     
295                                 int rate = sba    
296                                 *pos++ = (u8)     
297                         }                         
298                 }                                 
299         }                                         
300                                                   
301         if (capab & WLAN_CAPABILITY_SPECTRUM_M    
302                 /* 1. power capabilities */       
303                 pos = skb_put(skb, 4);            
304                 *pos++ = WLAN_EID_PWR_CAPABILI    
305                 *pos++ = 2;                       
306                 *pos++ = 0; /* min tx power */    
307                 *pos++ = local->hw.conf.channe    
308                                                   
309                 /* 2. supported channels */       
310                 /* TODO: get this in reg domai    
311                 pos = skb_put(skb, 2 * sband->    
312                 *pos++ = WLAN_EID_SUPPORTED_CH    
313                 *pos++ = 2 * sband->n_channels    
314                 for (i = 0; i < sband->n_chann    
315                         *pos++ = ieee80211_fre    
316                                         sband-    
317                         *pos++ = 1; /* one cha    
318                 }                                 
319         }                                         
320                                                   
321         if (ifmgd->extra_ie) {                    
322                 pos = skb_put(skb, ifmgd->extr    
323                 memcpy(pos, ifmgd->extra_ie, i    
324         }                                         
325                                                   
326         if (wmm && (ifmgd->flags & IEEE80211_S    
327                 pos = skb_put(skb, 9);            
328                 *pos++ = WLAN_EID_VENDOR_SPECI    
329                 *pos++ = 7; /* len */             
330                 *pos++ = 0x00; /* Microsoft OU    
331                 *pos++ = 0x50;                    
332                 *pos++ = 0xf2;                    
333                 *pos++ = 2; /* WME */             
334                 *pos++ = 0; /* WME info */        
335                 *pos++ = 1; /* WME ver */         
336                 *pos++ = 0;                       
337         }                                         
338                                                   
339         /* wmm support is a must to HT */         
340         /*                                        
341          * IEEE802.11n does not allow TKIP/WEP    
342          * ciphers in HT mode. We still associ    
343          * mode (11a/b/g) if any one of these     
344          * configured as pairwise.                
345          */                                       
346         if (wmm && (ifmgd->flags & IEEE80211_S    
347             sband->ht_cap.ht_supported &&         
348             (ht_ie = ieee80211_bss_get_ie(bss,    
349             ht_ie[1] >= sizeof(struct ieee8021    
350             (!(ifmgd->flags & IEEE80211_STA_TK    
351                 struct ieee80211_ht_info *ht_i    
352                         (struct ieee80211_ht_i    
353                 u16 cap = sband->ht_cap.cap;      
354                 __le16 tmp;                       
355                 u32 flags = local->hw.conf.cha    
356                                                   
357                 switch (ht_info->ht_param & IE    
358                 case IEEE80211_HT_PARAM_CHA_SE    
359                         if (flags & IEEE80211_    
360                                 cap &= ~IEEE80    
361                                 cap &= ~IEEE80    
362                         }                         
363                         break;                    
364                 case IEEE80211_HT_PARAM_CHA_SE    
365                         if (flags & IEEE80211_    
366                                 cap &= ~IEEE80    
367                                 cap &= ~IEEE80    
368                         }                         
369                         break;                    
370                 }                                 
371                                                   
372                 tmp = cpu_to_le16(cap);           
373                 pos = skb_put(skb, sizeof(stru    
374                 *pos++ = WLAN_EID_HT_CAPABILIT    
375                 *pos++ = sizeof(struct ieee802    
376                 memset(pos, 0, sizeof(struct i    
377                 memcpy(pos, &tmp, sizeof(u16))    
378                 pos += sizeof(u16);               
379                 /* TODO: needs a define here f    
380                 *pos++ = sband->ht_cap.ampdu_f    
381                          (sband->ht_cap.ampdu_    
382                 memcpy(pos, &sband->ht_cap.mcs    
383         }                                         
384                                                   
385         kfree(ifmgd->assocreq_ies);               
386         ifmgd->assocreq_ies_len = (skb->data +    
387         ifmgd->assocreq_ies = kmalloc(ifmgd->a    
388         if (ifmgd->assocreq_ies)                  
389                 memcpy(ifmgd->assocreq_ies, ie    
390                                                   
391         ieee80211_tx_skb(sdata, skb, 0);          
392 }                                                 
393                                                   
394                                                   
395 static void ieee80211_send_deauth_disassoc(str    
396                                            u16    
397 {                                                 
398         struct ieee80211_local *local = sdata-    
399         struct ieee80211_if_managed *ifmgd = &    
400         struct sk_buff *skb;                      
401         struct ieee80211_mgmt *mgmt;              
402                                                   
403         skb = dev_alloc_skb(local->hw.extra_tx    
404         if (!skb) {                               
405                 printk(KERN_DEBUG "%s: failed     
406                        "deauth/disassoc frame\    
407                 return;                           
408         }                                         
409         skb_reserve(skb, local->hw.extra_tx_he    
410                                                   
411         mgmt = (struct ieee80211_mgmt *) skb_p    
412         memset(mgmt, 0, 24);                      
413         memcpy(mgmt->da, ifmgd->bssid, ETH_ALE    
414         memcpy(mgmt->sa, sdata->dev->dev_addr,    
415         memcpy(mgmt->bssid, ifmgd->bssid, ETH_    
416         mgmt->frame_control = cpu_to_le16(IEEE    
417         skb_put(skb, 2);                          
418         /* u.deauth.reason_code == u.disassoc.    
419         mgmt->u.deauth.reason_code = cpu_to_le    
420                                                   
421         if (stype == IEEE80211_STYPE_DEAUTH)      
422                 cfg80211_send_deauth(sdata->de    
423         else                                      
424                 cfg80211_send_disassoc(sdata->    
425         ieee80211_tx_skb(sdata, skb, ifmgd->fl    
426 }                                                 
427                                                   
428 void ieee80211_send_pspoll(struct ieee80211_lo    
429                            struct ieee80211_su    
430 {                                                 
431         struct ieee80211_if_managed *ifmgd = &    
432         struct ieee80211_pspoll *pspoll;          
433         struct sk_buff *skb;                      
434         u16 fc;                                   
435                                                   
436         skb = dev_alloc_skb(local->hw.extra_tx    
437         if (!skb) {                               
438                 printk(KERN_DEBUG "%s: failed     
439                        "pspoll frame\n", sdata    
440                 return;                           
441         }                                         
442         skb_reserve(skb, local->hw.extra_tx_he    
443                                                   
444         pspoll = (struct ieee80211_pspoll *) s    
445         memset(pspoll, 0, sizeof(*pspoll));       
446         fc = IEEE80211_FTYPE_CTL | IEEE80211_S    
447         pspoll->frame_control = cpu_to_le16(fc    
448         pspoll->aid = cpu_to_le16(ifmgd->aid);    
449                                                   
450         /* aid in PS-Poll has its two MSBs eac    
451         pspoll->aid |= cpu_to_le16(1 << 15 | 1    
452                                                   
453         memcpy(pspoll->bssid, ifmgd->bssid, ET    
454         memcpy(pspoll->ta, sdata->dev->dev_add    
455                                                   
456         ieee80211_tx_skb(sdata, skb, 0);          
457 }                                                 
458                                                   
459 void ieee80211_send_nullfunc(struct ieee80211_    
460                              struct ieee80211_    
461                              int powersave)       
462 {                                                 
463         struct sk_buff *skb;                      
464         struct ieee80211_hdr *nullfunc;           
465         __le16 fc;                                
466                                                   
467         if (WARN_ON(sdata->vif.type != NL80211    
468                 return;                           
469                                                   
470         skb = dev_alloc_skb(local->hw.extra_tx    
471         if (!skb) {                               
472                 printk(KERN_DEBUG "%s: failed     
473                        "frame\n", sdata->dev->    
474                 return;                           
475         }                                         
476         skb_reserve(skb, local->hw.extra_tx_he    
477                                                   
478         nullfunc = (struct ieee80211_hdr *) sk    
479         memset(nullfunc, 0, 24);                  
480         fc = cpu_to_le16(IEEE80211_FTYPE_DATA     
481                          IEEE80211_FCTL_TODS);    
482         if (powersave)                            
483                 fc |= cpu_to_le16(IEEE80211_FC    
484         nullfunc->frame_control = fc;             
485         memcpy(nullfunc->addr1, sdata->u.mgd.b    
486         memcpy(nullfunc->addr2, sdata->dev->de    
487         memcpy(nullfunc->addr3, sdata->u.mgd.b    
488                                                   
489         ieee80211_tx_skb(sdata, skb, 0);          
490 }                                                 
491                                                   
492 /* spectrum management related things */          
493 static void ieee80211_chswitch_work(struct wor    
494 {                                                 
495         struct ieee80211_sub_if_data *sdata =     
496                 container_of(work, struct ieee    
497         struct ieee80211_bss *bss;                
498         struct ieee80211_if_managed *ifmgd = &    
499                                                   
500         if (!netif_running(sdata->dev))           
501                 return;                           
502                                                   
503         bss = ieee80211_rx_bss_get(sdata->loca    
504                                    sdata->loca    
505                                    ifmgd->ssid    
506         if (!bss)                                 
507                 goto exit;                        
508                                                   
509         sdata->local->oper_channel = sdata->lo    
510         /* XXX: shouldn't really modify cfg802    
511         if (!ieee80211_hw_config(sdata->local,    
512                 bss->cbss.channel = sdata->loc    
513                                                   
514         ieee80211_rx_bss_put(sdata->local, bss    
515 exit:                                             
516         ifmgd->flags &= ~IEEE80211_STA_CSA_REC    
517         ieee80211_wake_queues_by_reason(&sdata    
518                                         IEEE80    
519 }                                                 
520                                                   
521 static void ieee80211_chswitch_timer(unsigned     
522 {                                                 
523         struct ieee80211_sub_if_data *sdata =     
524                 (struct ieee80211_sub_if_data     
525         struct ieee80211_if_managed *ifmgd = &    
526                                                   
527         if (sdata->local->quiescing) {            
528                 set_bit(TMR_RUNNING_CHANSW, &i    
529                 return;                           
530         }                                         
531                                                   
532         queue_work(sdata->local->hw.workqueue,    
533 }                                                 
534                                                   
535 void ieee80211_sta_process_chanswitch(struct i    
536                                       struct i    
537                                       struct i    
538 {                                                 
539         struct ieee80211_channel *new_ch;         
540         struct ieee80211_if_managed *ifmgd = &    
541         int new_freq = ieee80211_channel_to_fr    
542                                                   
543         if (ifmgd->state != IEEE80211_STA_MLME    
544                 return;                           
545                                                   
546         if (sdata->local->sw_scanning || sdata    
547                 return;                           
548                                                   
549         /* Disregard subsequent beacons if we     
550            processing a CSA */                    
551                                                   
552         if (ifmgd->flags & IEEE80211_STA_CSA_R    
553                 return;                           
554                                                   
555         new_ch = ieee80211_get_channel(sdata->    
556         if (!new_ch || new_ch->flags & IEEE802    
557                 return;                           
558                                                   
559         sdata->local->csa_channel = new_ch;       
560                                                   
561         if (sw_elem->count <= 1) {                
562                 queue_work(sdata->local->hw.wo    
563         } else {                                  
564                 ieee80211_stop_queues_by_reaso    
565                                         IEEE80    
566                 ifmgd->flags |= IEEE80211_STA_    
567                 mod_timer(&ifmgd->chswitch_tim    
568                           jiffies +               
569                           msecs_to_jiffies(sw_    
570                                            bss    
571         }                                         
572 }                                                 
573                                                   
574 static void ieee80211_handle_pwr_constr(struct    
575                                         u16 ca    
576                                         u8 pwr    
577 {                                                 
578         struct ieee80211_conf *conf = &sdata->    
579                                                   
580         if (!(capab_info & WLAN_CAPABILITY_SPE    
581                 return;                           
582                                                   
583         /* Power constraint IE length should b    
584         if (pwr_constr_elem_len != 1)             
585                 return;                           
586                                                   
587         if ((*pwr_constr_elem <= conf->channel    
588             (*pwr_constr_elem != sdata->local-    
589                 sdata->local->power_constr_lev    
590                 ieee80211_hw_config(sdata->loc    
591         }                                         
592 }                                                 
593                                                   
594 /* powersave */                                   
595 static void ieee80211_enable_ps(struct ieee802    
596                                 struct ieee802    
597 {                                                 
598         struct ieee80211_conf *conf = &local->    
599                                                   
600         /*                                        
601          * If we are scanning right now then t    
602          * take effect when scan finishes.        
603          */                                       
604         if (local->hw_scanning || local->sw_sc    
605                 return;                           
606                                                   
607         if (conf->dynamic_ps_timeout > 0 &&       
608             !(local->hw.flags & IEEE80211_HW_S    
609                 mod_timer(&local->dynamic_ps_t    
610                           msecs_to_jiffies(con    
611         } else {                                  
612                 if (local->hw.flags & IEEE8021    
613                         ieee80211_send_nullfun    
614                 conf->flags |= IEEE80211_CONF_    
615                 ieee80211_hw_config(local, IEE    
616         }                                         
617 }                                                 
618                                                   
619 static void ieee80211_change_ps(struct ieee802    
620 {                                                 
621         struct ieee80211_conf *conf = &local->    
622                                                   
623         if (local->ps_sdata) {                    
624                 ieee80211_enable_ps(local, loc    
625         } else if (conf->flags & IEEE80211_CON    
626                 conf->flags &= ~IEEE80211_CONF    
627                 ieee80211_hw_config(local, IEE    
628                 del_timer_sync(&local->dynamic    
629                 cancel_work_sync(&local->dynam    
630         }                                         
631 }                                                 
632                                                   
633 /* need to hold RTNL or interface lock */         
634 void ieee80211_recalc_ps(struct ieee80211_loca    
635 {                                                 
636         struct ieee80211_sub_if_data *sdata, *    
637         int count = 0;                            
638                                                   
639         if (!(local->hw.flags & IEEE80211_HW_S    
640                 local->ps_sdata = NULL;           
641                 return;                           
642         }                                         
643                                                   
644         list_for_each_entry(sdata, &local->int    
645                 if (!netif_running(sdata->dev)    
646                         continue;                 
647                 if (sdata->vif.type != NL80211    
648                         continue;                 
649                 found = sdata;                    
650                 count++;                          
651         }                                         
652                                                   
653         if (count == 1 && found->u.mgd.powersa    
654             (found->u.mgd.flags & IEEE80211_ST    
655             !(found->u.mgd.flags & IEEE80211_S    
656                 s32 beaconint_us;                 
657                                                   
658                 if (latency < 0)                  
659                         latency = pm_qos_requi    
660                                                   
661                 beaconint_us = ieee80211_tu_to    
662                                         found-    
663                                                   
664                 if (beaconint_us > latency) {     
665                         local->ps_sdata = NULL    
666                 } else {                          
667                         u8 dtimper = found->vi    
668                         int maxslp = 1;           
669                                                   
670                         if (dtimper > 1)          
671                                 maxslp = min_t    
672                                                   
673                                                   
674                         local->hw.conf.max_sle    
675                         local->ps_sdata = foun    
676                 }                                 
677         } else {                                  
678                 local->ps_sdata = NULL;           
679         }                                         
680                                                   
681         ieee80211_change_ps(local);               
682 }                                                 
683                                                   
684 void ieee80211_dynamic_ps_disable_work(struct     
685 {                                                 
686         struct ieee80211_local *local =           
687                 container_of(work, struct ieee    
688                              dynamic_ps_disabl    
689                                                   
690         if (local->hw.conf.flags & IEEE80211_C    
691                 local->hw.conf.flags &= ~IEEE8    
692                 ieee80211_hw_config(local, IEE    
693         }                                         
694                                                   
695         ieee80211_wake_queues_by_reason(&local    
696                                         IEEE80    
697 }                                                 
698                                                   
699 void ieee80211_dynamic_ps_enable_work(struct w    
700 {                                                 
701         struct ieee80211_local *local =           
702                 container_of(work, struct ieee    
703                              dynamic_ps_enable    
704         struct ieee80211_sub_if_data *sdata =     
705                                                   
706         /* can only happen when PS was just di    
707         if (!sdata)                               
708                 return;                           
709                                                   
710         if (local->hw.conf.flags & IEEE80211_C    
711                 return;                           
712                                                   
713         if (local->hw.flags & IEEE80211_HW_PS_    
714                 ieee80211_send_nullfunc(local,    
715                                                   
716         local->hw.conf.flags |= IEEE80211_CONF    
717         ieee80211_hw_config(local, IEEE80211_C    
718 }                                                 
719                                                   
720 void ieee80211_dynamic_ps_timer(unsigned long     
721 {                                                 
722         struct ieee80211_local *local = (void     
723                                                   
724         if (local->quiescing || local->suspend    
725                 return;                           
726                                                   
727         queue_work(local->hw.workqueue, &local    
728 }                                                 
729                                                   
730 /* MLME */                                        
731 static void ieee80211_sta_wmm_params(struct ie    
732                                      struct ie    
733                                      u8 *wmm_p    
734 {                                                 
735         struct ieee80211_tx_queue_params param    
736         size_t left;                              
737         int count;                                
738         u8 *pos;                                  
739                                                   
740         if (!(ifmgd->flags & IEEE80211_STA_WMM    
741                 return;                           
742                                                   
743         if (!wmm_param)                           
744                 return;                           
745                                                   
746         if (wmm_param_len < 8 || wmm_param[5]     
747                 return;                           
748         count = wmm_param[6] & 0x0f;              
749         if (count == ifmgd->wmm_last_param_set    
750                 return;                           
751         ifmgd->wmm_last_param_set = count;        
752                                                   
753         pos = wmm_param + 8;                      
754         left = wmm_param_len - 8;                 
755                                                   
756         memset(&params, 0, sizeof(params));       
757                                                   
758         local->wmm_acm = 0;                       
759         for (; left >= 4; left -= 4, pos += 4)    
760                 int aci = (pos[0] >> 5) & 0x03    
761                 int acm = (pos[0] >> 4) & 0x01    
762                 int queue;                        
763                                                   
764                 switch (aci) {                    
765                 case 1: /* AC_BK */               
766                         queue = 3;                
767                         if (acm)                  
768                                 local->wmm_acm    
769                         break;                    
770                 case 2: /* AC_VI */               
771                         queue = 1;                
772                         if (acm)                  
773                                 local->wmm_acm    
774                         break;                    
775                 case 3: /* AC_VO */               
776                         queue = 0;                
777                         if (acm)                  
778                                 local->wmm_acm    
779                         break;                    
780                 case 0: /* AC_BE */               
781                 default:                          
782                         queue = 2;                
783                         if (acm)                  
784                                 local->wmm_acm    
785                         break;                    
786                 }                                 
787                                                   
788                 params.aifs = pos[0] & 0x0f;      
789                 params.cw_max = ecw2cw((pos[1]    
790                 params.cw_min = ecw2cw(pos[1]     
791                 params.txop = get_unaligned_le    
792 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG              
793                 printk(KERN_DEBUG "%s: WMM que    
794                        "cWmin=%d cWmax=%d txop    
795                        wiphy_name(local->hw.wi    
796                        params.aifs, params.cw_    
797 #endif                                            
798                 if (drv_conf_tx(local, queue,     
799                         printk(KERN_DEBUG "%s:    
800                                "parameters for    
801                                wiphy_name(loca    
802         }                                         
803 }                                                 
804                                                   
805 static u32 ieee80211_handle_bss_capability(str    
806                                            u16    
807 {                                                 
808         struct ieee80211_bss_conf *bss_conf =     
809 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG              
810         struct ieee80211_if_managed *ifmgd = &    
811 #endif                                            
812         u32 changed = 0;                          
813         bool use_protection;                      
814         bool use_short_preamble;                  
815         bool use_short_slot;                      
816                                                   
817         if (erp_valid) {                          
818                 use_protection = (erp & WLAN_E    
819                 use_short_preamble = (erp & WL    
820         } else {                                  
821                 use_protection = false;           
822                 use_short_preamble = !!(capab     
823         }                                         
824                                                   
825         use_short_slot = !!(capab & WLAN_CAPAB    
826                                                   
827         if (use_protection != bss_conf->use_ct    
828 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG              
829                 if (net_ratelimit()) {            
830                         printk(KERN_DEBUG "%s:    
831                                sdata->dev->nam    
832                                use_protection     
833                                ifmgd->bssid);     
834                 }                                 
835 #endif                                            
836                 bss_conf->use_cts_prot = use_p    
837                 changed |= BSS_CHANGED_ERP_CTS    
838         }                                         
839                                                   
840         if (use_short_preamble != bss_conf->us    
841 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG              
842                 if (net_ratelimit()) {            
843                         printk(KERN_DEBUG "%s:    
844                                " (BSSID=%pM)\n    
845                                sdata->dev->nam    
846                                use_short_pream    
847                                ifmgd->bssid);     
848                 }                                 
849 #endif                                            
850                 bss_conf->use_short_preamble =    
851                 changed |= BSS_CHANGED_ERP_PRE    
852         }                                         
853                                                   
854         if (use_short_slot != bss_conf->use_sh    
855 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG              
856                 if (net_ratelimit()) {            
857                         printk(KERN_DEBUG "%s:    
858                                " (BSSID=%pM)\n    
859                                sdata->dev->nam    
860                                use_short_slot     
861                                ifmgd->bssid);     
862                 }                                 
863 #endif                                            
864                 bss_conf->use_short_slot = use    
865                 changed |= BSS_CHANGED_ERP_SLO    
866         }                                         
867                                                   
868         return changed;                           
869 }                                                 
870                                                   
871 static void ieee80211_sta_send_apinfo(struct i    
872 {                                                 
873         union iwreq_data wrqu;                    
874                                                   
875         memset(&wrqu, 0, sizeof(wrqu));           
876         if (sdata->u.mgd.flags & IEEE80211_STA    
877                 memcpy(wrqu.ap_addr.sa_data, s    
878         wrqu.ap_addr.sa_family = ARPHRD_ETHER;    
879         wireless_send_event(sdata->dev, SIOCGI    
880 }                                                 
881                                                   
882 static void ieee80211_sta_send_associnfo(struc    
883 {                                                 
884         struct ieee80211_if_managed *ifmgd = &    
885         char *buf;                                
886         size_t len;                               
887         int i;                                    
888         union iwreq_data wrqu;                    
889                                                   
890         if (!ifmgd->assocreq_ies && !ifmgd->as    
891                 return;                           
892                                                   
893         buf = kmalloc(50 + 2 * (ifmgd->assocre    
894                                 ifmgd->assocre    
895         if (!buf)                                 
896                 return;                           
897                                                   
898         len = sprintf(buf, "ASSOCINFO(");         
899         if (ifmgd->assocreq_ies) {                
900                 len += sprintf(buf + len, "Req    
901                 for (i = 0; i < ifmgd->assocre    
902                         len += sprintf(buf + l    
903                                        ifmgd->    
904                 }                                 
905         }                                         
906         if (ifmgd->assocresp_ies) {               
907                 if (ifmgd->assocreq_ies)          
908                         len += sprintf(buf + l    
909                 len += sprintf(buf + len, "Res    
910                 for (i = 0; i < ifmgd->assocre    
911                         len += sprintf(buf + l    
912                                        ifmgd->    
913                 }                                 
914         }                                         
915         len += sprintf(buf + len, ")");           
916                                                   
917         if (len > IW_CUSTOM_MAX) {                
918                 len = sprintf(buf, "ASSOCRESPI    
919                 for (i = 0; i < ifmgd->assocre    
920                         len += sprintf(buf + l    
921                                        ifmgd->    
922                 }                                 
923         }                                         
924                                                   
925         if (len <= IW_CUSTOM_MAX) {               
926                 memset(&wrqu, 0, sizeof(wrqu))    
927                 wrqu.data.length = len;           
928                 wireless_send_event(sdata->dev    
929         }                                         
930                                                   
931         kfree(buf);                               
932 }                                                 
933                                                   
934                                                   
935 static void ieee80211_set_associated(struct ie    
936                                      u32 bss_i    
937 {                                                 
938         struct ieee80211_if_managed *ifmgd = &    
939         struct ieee80211_local *local = sdata-    
940         struct ieee80211_conf *conf = &local_t    
941                                                   
942         struct ieee80211_bss *bss;                
943                                                   
944         bss_info_changed |= BSS_CHANGED_ASSOC;    
945         ifmgd->flags |= IEEE80211_STA_ASSOCIAT    
946                                                   
947         bss = ieee80211_rx_bss_get(local, ifmg    
948                                    conf->chann    
949                                    ifmgd->ssid    
950         if (bss) {                                
951                 /* set timing information */      
952                 sdata->vif.bss_conf.beacon_int    
953                 sdata->vif.bss_conf.timestamp     
954                 sdata->vif.bss_conf.dtim_perio    
955                                                   
956                 bss_info_changed |= BSS_CHANGE    
957                 bss_info_changed |= ieee80211_    
958                         bss->cbss.capability,     
959                                                   
960                 cfg80211_hold_bss(&bss->cbss);    
961                                                   
962                 ieee80211_rx_bss_put(local, bs    
963         }                                         
964                                                   
965         ifmgd->flags |= IEEE80211_STA_PREV_BSS    
966         memcpy(ifmgd->prev_bssid, sdata->u.mgd    
967         ieee80211_sta_send_associnfo(sdata);      
968                                                   
969         ifmgd->last_probe = jiffies;              
970         ieee80211_led_assoc(local, 1);            
971                                                   
972         sdata->vif.bss_conf.assoc = 1;            
973         /*                                        
974          * For now just always ask the driver     
975          * when we have associated, we aren't     
976          * changed or not.                        
977          */                                       
978         bss_info_changed |= BSS_CHANGED_BASIC_    
979                                                   
980         /* And the BSSID changed - we're assoc    
981         bss_info_changed |= BSS_CHANGED_BSSID;    
982                                                   
983         ieee80211_bss_info_change_notify(sdata    
984                                                   
985         /* will be same as sdata */               
986         if (local->ps_sdata) {                    
987                 mutex_lock(&local->iflist_mtx)    
988                 ieee80211_recalc_ps(local, -1)    
989                 mutex_unlock(&local->iflist_mt    
990         }                                         
991                                                   
992         netif_tx_start_all_queues(sdata->dev);    
993         netif_carrier_on(sdata->dev);             
994                                                   
995         ieee80211_sta_send_apinfo(sdata);         
996 }                                                 
997                                                   
998 static void ieee80211_direct_probe(struct ieee    
999 {                                                 
1000         struct ieee80211_if_managed *ifmgd =     
1001         struct ieee80211_local *local = sdata    
1002                                                  
1003         ifmgd->direct_probe_tries++;             
1004         if (ifmgd->direct_probe_tries > IEEE8    
1005                 printk(KERN_DEBUG "%s: direct    
1006                        sdata->dev->name, ifmg    
1007                 ifmgd->state = IEEE80211_STA_    
1008                 ieee80211_recalc_idle(local);    
1009                 cfg80211_send_auth_timeout(sd    
1010                                                  
1011                 /*                               
1012                  * Most likely AP is not in t    
1013                  * bss information associated    
1014                  */                              
1015                 ieee80211_rx_bss_remove(sdata    
1016                                 sdata->local-    
1017                                 ifmgd->ssid,     
1018                                                  
1019                 /*                               
1020                  * We might have a pending sc    
1021                  * due to state == IEEE80211_    
1022                  * Hence, queue the STAs work    
1023                  */                              
1024                 queue_work(local->hw.workqueu    
1025                 return;                          
1026         }                                        
1027                                                  
1028         printk(KERN_DEBUG "%s: direct probe t    
1029                         sdata->dev->name, ifm    
1030                         ifmgd->direct_probe_t    
1031                                                  
1032         ifmgd->state = IEEE80211_STA_MLME_DIR    
1033                                                  
1034         /* Direct probe is sent to broadcast     
1035          * will not answer to direct packet i    
1036          */                                      
1037         ieee80211_send_probe_req(sdata, NULL,    
1038                                  ifmgd->ssid,    
1039                                                  
1040         mod_timer(&ifmgd->timer, jiffies + IE    
1041 }                                                
1042                                                  
1043                                                  
1044 static void ieee80211_authenticate(struct iee    
1045 {                                                
1046         struct ieee80211_if_managed *ifmgd =     
1047         struct ieee80211_local *local = sdata    
1048         u8 *ies;                                 
1049         size_t ies_len;                          
1050                                                  
1051         ifmgd->auth_tries++;                     
1052         if (ifmgd->auth_tries > IEEE80211_AUT    
1053                 printk(KERN_DEBUG "%s: authen    
1054                        " timed out\n",           
1055                        sdata->dev->name, ifmg    
1056                 ifmgd->state = IEEE80211_STA_    
1057                 ieee80211_recalc_idle(local);    
1058                 cfg80211_send_auth_timeout(sd    
1059                 ieee80211_rx_bss_remove(sdata    
1060                                 sdata->local-    
1061                                 ifmgd->ssid,     
1062                                                  
1063                 /*                               
1064                  * We might have a pending sc    
1065                  * due to state == IEEE80211_    
1066                  * Hence, queue the STAs work    
1067                  */                              
1068                 queue_work(local->hw.workqueu    
1069                 return;                          
1070         }                                        
1071                                                  
1072         ifmgd->state = IEEE80211_STA_MLME_AUT    
1073         printk(KERN_DEBUG "%s: authenticate w    
1074                sdata->dev->name, ifmgd->bssid    
1075                                                  
1076         if (ifmgd->flags & IEEE80211_STA_EXT_    
1077                 ies = ifmgd->sme_auth_ie;        
1078                 ies_len = ifmgd->sme_auth_ie_    
1079         } else {                                 
1080                 ies = NULL;                      
1081                 ies_len = 0;                     
1082         }                                        
1083         ieee80211_send_auth(sdata, 1, ifmgd->    
1084                             ifmgd->bssid, 0);    
1085         ifmgd->auth_transaction = 2;             
1086                                                  
1087         mod_timer(&ifmgd->timer, jiffies + IE    
1088 }                                                
1089                                                  
1090 /*                                               
1091  * The disassoc 'reason' argument can be eith    
1092  * if self disconnected or a reason code from    
1093  */                                              
1094 static void ieee80211_set_disassoc(struct iee    
1095                                    bool deaut    
1096                                    u16 reason    
1097 {                                                
1098         struct ieee80211_if_managed *ifmgd =     
1099         struct ieee80211_local *local = sdata    
1100         struct ieee80211_conf *conf = &local_    
1101         struct ieee80211_bss *bss;               
1102         struct sta_info *sta;                    
1103         u32 changed = 0, config_changed = 0;     
1104                                                  
1105         if (deauth) {                            
1106                 ifmgd->direct_probe_tries = 0    
1107                 ifmgd->auth_tries = 0;           
1108         }                                        
1109         ifmgd->assoc_scan_tries = 0;             
1110         ifmgd->assoc_tries = 0;                  
1111                                                  
1112         netif_tx_stop_all_queues(sdata->dev);    
1113         netif_carrier_off(sdata->dev);           
1114                                                  
1115         rcu_read_lock();                         
1116         sta = sta_info_get(local, ifmgd->bssi    
1117         if (sta)                                 
1118                 ieee80211_sta_tear_down_BA_se    
1119         rcu_read_unlock();                       
1120                                                  
1121         bss = ieee80211_rx_bss_get(local, ifm    
1122                                    conf->chan    
1123                                    ifmgd->ssi    
1124                                                  
1125         if (bss) {                               
1126                 cfg80211_unhold_bss(&bss->cbs    
1127                 ieee80211_rx_bss_put(local, b    
1128         }                                        
1129                                                  
1130         if (self_disconnected) {                 
1131                 if (deauth)                      
1132                         ieee80211_send_deauth    
1133                                 IEEE80211_STY    
1134                 else                             
1135                         ieee80211_send_deauth    
1136                                 IEEE80211_STY    
1137         }                                        
1138                                                  
1139         ifmgd->flags &= ~IEEE80211_STA_ASSOCI    
1140         changed |= ieee80211_reset_erp_info(s    
1141                                                  
1142         ieee80211_led_assoc(local, 0);           
1143         changed |= BSS_CHANGED_ASSOC;            
1144         sdata->vif.bss_conf.assoc = false;       
1145                                                  
1146         ieee80211_sta_send_apinfo(sdata);        
1147                                                  
1148         if (self_disconnected || reason == WL    
1149                 ifmgd->state = IEEE80211_STA_    
1150                 ieee80211_rx_bss_remove(sdata    
1151                                 sdata->local-    
1152                                 ifmgd->ssid,     
1153         }                                        
1154                                                  
1155         ieee80211_set_wmm_default(sdata);        
1156                                                  
1157         ieee80211_recalc_idle(local);            
1158                                                  
1159         /* channel(_type) changes are handled    
1160         local->oper_channel_type = NL80211_CH    
1161                                                  
1162         /* on the next assoc, re-program HT p    
1163         sdata->ht_opmode_valid = false;          
1164                                                  
1165         local->power_constr_level = 0;           
1166                                                  
1167         del_timer_sync(&local->dynamic_ps_tim    
1168         cancel_work_sync(&local->dynamic_ps_e    
1169                                                  
1170         if (local->hw.conf.flags & IEEE80211_    
1171                 local->hw.conf.flags &= ~IEEE    
1172                 config_changed |= IEEE80211_C    
1173         }                                        
1174                                                  
1175         ieee80211_hw_config(local, config_cha    
1176                                                  
1177         /* And the BSSID changed -- not very     
1178         changed |= BSS_CHANGED_BSSID;            
1179         ieee80211_bss_info_change_notify(sdat    
1180                                                  
1181         rcu_read_lock();                         
1182                                                  
1183         sta = sta_info_get(local, ifmgd->bssi    
1184         if (!sta) {                              
1185                 rcu_read_unlock();               
1186                 return;                          
1187         }                                        
1188                                                  
1189         sta_info_unlink(&sta);                   
1190                                                  
1191         rcu_read_unlock();                       
1192                                                  
1193         sta_info_destroy(sta);                   
1194 }                                                
1195                                                  
1196 static int ieee80211_sta_wep_configured(struc    
1197 {                                                
1198         if (!sdata || !sdata->default_key ||     
1199             sdata->default_key->conf.alg != A    
1200                 return 0;                        
1201         return 1;                                
1202 }                                                
1203                                                  
1204 static int ieee80211_privacy_mismatch(struct     
1205 {                                                
1206         struct ieee80211_if_managed *ifmgd =     
1207         struct ieee80211_local *local = sdata    
1208         struct ieee80211_bss *bss;               
1209         int bss_privacy;                         
1210         int wep_privacy;                         
1211         int privacy_invoked;                     
1212                                                  
1213         if (!ifmgd || (ifmgd->flags & IEEE802    
1214                 return 0;                        
1215                                                  
1216         bss = ieee80211_rx_bss_get(local, ifm    
1217                                    local->hw.    
1218                                    ifmgd->ssi    
1219         if (!bss)                                
1220                 return 0;                        
1221                                                  
1222         bss_privacy = !!(bss->cbss.capability    
1223         wep_privacy = !!ieee80211_sta_wep_con    
1224         privacy_invoked = !!(ifmgd->flags & I    
1225                                                  
1226         ieee80211_rx_bss_put(local, bss);        
1227                                                  
1228         if ((bss_privacy == wep_privacy) || (    
1229                 return 0;                        
1230                                                  
1231         return 1;                                
1232 }                                                
1233                                                  
1234 static void ieee80211_associate(struct ieee80    
1235 {                                                
1236         struct ieee80211_if_managed *ifmgd =     
1237         struct ieee80211_local *local = sdata    
1238                                                  
1239         ifmgd->assoc_tries++;                    
1240         if (ifmgd->assoc_tries > IEEE80211_AS    
1241                 printk(KERN_DEBUG "%s: associ    
1242                        " timed out\n",           
1243                        sdata->dev->name, ifmg    
1244                 ifmgd->state = IEEE80211_STA_    
1245                 ieee80211_recalc_idle(local);    
1246                 cfg80211_send_assoc_timeout(s    
1247                 ieee80211_rx_bss_remove(sdata    
1248                                 sdata->local-    
1249                                 ifmgd->ssid,     
1250                 /*                               
1251                  * We might have a pending sc    
1252                  * due to state == IEEE80211_    
1253                  * Hence, queue the STAs work    
1254                  */                              
1255                 queue_work(local->hw.workqueu    
1256                 return;                          
1257         }                                        
1258                                                  
1259         ifmgd->state = IEEE80211_STA_MLME_ASS    
1260         printk(KERN_DEBUG "%s: associate with    
1261                sdata->dev->name, ifmgd->bssid    
1262         if (ieee80211_privacy_mismatch(sdata)    
1263                 printk(KERN_DEBUG "%s: mismat    
1264                        "mixed-cell disabled -    
1265                 ifmgd->state = IEEE80211_STA_    
1266                 ieee80211_recalc_idle(local);    
1267                 return;                          
1268         }                                        
1269                                                  
1270         ieee80211_send_assoc(sdata);             
1271                                                  
1272         mod_timer(&ifmgd->timer, jiffies + IE    
1273 }                                                
1274                                                  
1275 void ieee80211_sta_rx_notify(struct ieee80211    
1276                              struct ieee80211    
1277 {                                                
1278         /*                                       
1279          * We can postpone the mgd.timer when    
1280          * from AP because we know that the c    
1281          * at that time. But multicast frames    
1282          * be ignored here, because we need t    
1283          * data idle periods for sending the     
1284          * the AP.                               
1285          */                                      
1286         if (!is_multicast_ether_addr(hdr->add    
1287                 mod_timer(&sdata->u.mgd.timer    
1288                           jiffies + IEEE80211    
1289 }                                                
1290                                                  
1291 void ieee80211_beacon_loss_work(struct work_s    
1292 {                                                
1293         struct ieee80211_sub_if_data *sdata =    
1294                 container_of(work, struct iee    
1295                              u.mgd.beacon_los    
1296         struct ieee80211_if_managed *ifmgd =     
1297                                                  
1298         /*                                       
1299          * The driver has already reported th    
1300          * already sent a probe request. Mayb    
1301          * driver keeps reporting until we di    
1302          * to ignore that because otherwise w    
1303          * reset the timer and never check wh    
1304          * probe response!                       
1305          */                                      
1306         if (ifmgd->flags & IEEE80211_STA_PROB    
1307                 return;                          
1308                                                  
1309 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG             
1310         if (net_ratelimit()) {                   
1311                 printk(KERN_DEBUG "%s: driver    
1312                        "- sending probe reque    
1313                        sdata->u.mgd.bssid);      
1314         }                                        
1315 #endif                                           
1316                                                  
1317         ifmgd->flags |= IEEE80211_STA_PROBERE    
1318                                                  
1319         mutex_lock(&sdata->local->iflist_mtx)    
1320         ieee80211_recalc_ps(sdata->local, -1)    
1321         mutex_unlock(&sdata->local->iflist_mt    
1322                                                  
1323         ieee80211_send_probe_req(sdata, ifmgd    
1324                                  ifmgd->ssid_    
1325                                                  
1326         mod_timer(&ifmgd->timer, jiffies + IE    
1327 }                                                
1328                                                  
1329 void ieee80211_beacon_loss(struct ieee80211_v    
1330 {                                                
1331         struct ieee80211_sub_if_data *sdata =    
1332                                                  
1333         queue_work(sdata->local->hw.workqueue    
1334                    &sdata->u.mgd.beacon_loss_    
1335 }                                                
1336 EXPORT_SYMBOL(ieee80211_beacon_loss);            
1337                                                  
1338 static void ieee80211_associated(struct ieee8    
1339 {                                                
1340         struct ieee80211_if_managed *ifmgd =     
1341         struct ieee80211_local *local = sdata    
1342         struct sta_info *sta;                    
1343         unsigned long last_rx;                   
1344         bool disassoc = false;                   
1345                                                  
1346         /* TODO: start monitoring current AP     
1347          * missed beacons. Scan other channel    
1348          * for better APs. */                    
1349         /* TODO: remove expired BSSes */         
1350                                                  
1351         ifmgd->state = IEEE80211_STA_MLME_ASS    
1352                                                  
1353         rcu_read_lock();                         
1354                                                  
1355         sta = sta_info_get(local, ifmgd->bssi    
1356         if (!sta) {                              
1357                 printk(KERN_DEBUG "%s: No STA    
1358                        sdata->dev->name, ifmg    
1359                 disassoc = true;                 
1360                 rcu_read_unlock();               
1361                 goto out;                        
1362         }                                        
1363                                                  
1364         last_rx = sta->last_rx;                  
1365         rcu_read_unlock();                       
1366                                                  
1367         if ((ifmgd->flags & IEEE80211_STA_PRO    
1368             time_after(jiffies, last_rx + IEE    
1369                 printk(KERN_DEBUG "%s: no pro    
1370                        "- disassociating\n",     
1371                        sdata->dev->name, ifmg    
1372                 disassoc = true;                 
1373                 ifmgd->flags &= ~IEEE80211_ST    
1374                 goto out;                        
1375         }                                        
1376                                                  
1377         /*                                       
1378          * Beacon filtering is only enabled w    
1379          * stack should not check for beacon     
1380          */                                      
1381         if (!((local->hw.flags & IEEE80211_HW    
1382               (local->hw.conf.flags & IEEE802    
1383             time_after(jiffies,                  
1384                        ifmgd->last_beacon + I    
1385 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG             
1386                 if (net_ratelimit()) {           
1387                         printk(KERN_DEBUG "%s    
1388                                "- sending pro    
1389                                sdata->dev->na    
1390                 }                                
1391 #endif                                           
1392                 ifmgd->flags |= IEEE80211_STA    
1393                 mutex_lock(&local->iflist_mtx    
1394                 ieee80211_recalc_ps(local, -1    
1395                 mutex_unlock(&local->iflist_m    
1396                 ieee80211_send_probe_req(sdat    
1397                                          ifmg    
1398                 mod_timer(&ifmgd->timer, jiff    
1399                 goto out;                        
1400         }                                        
1401                                                  
1402         if (time_after(jiffies, last_rx + IEE    
1403                 ifmgd->flags |= IEEE80211_STA    
1404                 mutex_lock(&local->iflist_mtx    
1405                 ieee80211_recalc_ps(local, -1    
1406                 mutex_unlock(&local->iflist_m    
1407                 ieee80211_send_probe_req(sdat    
1408                                          ifmg    
1409         }                                        
1410                                                  
1411  out:                                            
1412         if (!disassoc)                           
1413                 mod_timer(&ifmgd->timer,         
1414                           jiffies + IEEE80211    
1415         else                                     
1416                 ieee80211_set_disassoc(sdata,    
1417                                         WLAN_    
1418 }                                                
1419                                                  
1420                                                  
1421 static void ieee80211_auth_completed(struct i    
1422 {                                                
1423         struct ieee80211_if_managed *ifmgd =     
1424                                                  
1425         printk(KERN_DEBUG "%s: authenticated\    
1426         ifmgd->flags |= IEEE80211_STA_AUTHENT    
1427         if (ifmgd->flags & IEEE80211_STA_EXT_    
1428                 /* Wait for SME to request as    
1429                 ifmgd->state = IEEE80211_STA_    
1430                 ieee80211_recalc_idle(sdata->    
1431         } else                                   
1432                 ieee80211_associate(sdata);      
1433 }                                                
1434                                                  
1435                                                  
1436 static void ieee80211_auth_challenge(struct i    
1437                                      struct i    
1438                                      size_t l    
1439 {                                                
1440         u8 *pos;                                 
1441         struct ieee802_11_elems elems;           
1442                                                  
1443         pos = mgmt->u.auth.variable;             
1444         ieee802_11_parse_elems(pos, len - (po    
1445         if (!elems.challenge)                    
1446                 return;                          
1447         ieee80211_send_auth(sdata, 3, sdata->    
1448                             elems.challenge -    
1449                             sdata->u.mgd.bssi    
1450         sdata->u.mgd.auth_transaction = 4;       
1451 }                                                
1452                                                  
1453 static void ieee80211_rx_mgmt_auth(struct iee    
1454                                    struct iee    
1455                                    size_t len    
1456 {                                                
1457         struct ieee80211_if_managed *ifmgd =     
1458         u16 auth_alg, auth_transaction, statu    
1459                                                  
1460         if (ifmgd->state != IEEE80211_STA_MLM    
1461                 return;                          
1462                                                  
1463         if (len < 24 + 6)                        
1464                 return;                          
1465                                                  
1466         if (memcmp(ifmgd->bssid, mgmt->sa, ET    
1467                 return;                          
1468                                                  
1469         if (memcmp(ifmgd->bssid, mgmt->bssid,    
1470                 return;                          
1471                                                  
1472         auth_alg = le16_to_cpu(mgmt->u.auth.a    
1473         auth_transaction = le16_to_cpu(mgmt->    
1474         status_code = le16_to_cpu(mgmt->u.aut    
1475                                                  
1476         if (auth_alg != ifmgd->auth_alg ||       
1477             auth_transaction != ifmgd->auth_t    
1478                 return;                          
1479                                                  
1480         if (status_code != WLAN_STATUS_SUCCES    
1481                 if (status_code == WLAN_STATU    
1482                         u8 algs[3];              
1483                         const int num_algs =     
1484                         int i, pos;              
1485                         algs[0] = algs[1] = a    
1486                         if (ifmgd->auth_algs     
1487                                 algs[0] = WLA    
1488                         if (ifmgd->auth_algs     
1489                                 algs[1] = WLA    
1490                         if (ifmgd->auth_algs     
1491                                 algs[2] = WLA    
1492                         if (ifmgd->auth_alg =    
1493                                 pos = 0;         
1494                         else if (ifmgd->auth_    
1495                                 pos = 1;         
1496                         else                     
1497                                 pos = 2;         
1498                         for (i = 0; i < num_a    
1499                                 pos++;           
1500                                 if (pos >= nu    
1501                                         pos =    
1502                                 if (algs[pos]    
1503                                     algs[pos]    
1504                                         conti    
1505                                 if (algs[pos]    
1506                                     !ieee8021    
1507                                         conti    
1508                                 ifmgd->auth_a    
1509                                 break;           
1510                         }                        
1511                 }                                
1512                 return;                          
1513         }                                        
1514                                                  
1515         switch (ifmgd->auth_alg) {               
1516         case WLAN_AUTH_OPEN:                     
1517         case WLAN_AUTH_LEAP:                     
1518         case WLAN_AUTH_FT:                       
1519                 ieee80211_auth_completed(sdat    
1520                 cfg80211_send_rx_auth(sdata->    
1521                 break;                           
1522         case WLAN_AUTH_SHARED_KEY:               
1523                 if (ifmgd->auth_transaction =    
1524                         ieee80211_auth_comple    
1525                         cfg80211_send_rx_auth    
1526                 } else                           
1527                         ieee80211_auth_challe    
1528                 break;                           
1529         }                                        
1530 }                                                
1531                                                  
1532                                                  
1533 static void ieee80211_rx_mgmt_deauth(struct i    
1534                                      struct i    
1535                                      size_t l    
1536 {                                                
1537         struct ieee80211_if_managed *ifmgd =     
1538         u16 reason_code;                         
1539                                                  
1540         if (len < 24 + 2)                        
1541                 return;                          
1542                                                  
1543         if (memcmp(ifmgd->bssid, mgmt->sa, ET    
1544                 return;                          
1545                                                  
1546         reason_code = le16_to_cpu(mgmt->u.dea    
1547                                                  
1548         if (ifmgd->flags & IEEE80211_STA_AUTH    
1549                 printk(KERN_DEBUG "%s: deauth    
1550                                 sdata->dev->n    
1551                                                  
1552         if (!(ifmgd->flags & IEEE80211_STA_EX    
1553             (ifmgd->state == IEEE80211_STA_ML    
1554              ifmgd->state == IEEE80211_STA_ML    
1555              ifmgd->state == IEEE80211_STA_ML    
1556                 ifmgd->state = IEEE80211_STA_    
1557                 mod_timer(&ifmgd->timer, jiff    
1558                                       IEEE802    
1559         }                                        
1560                                                  
1561         ieee80211_set_disassoc(sdata, true, f    
1562         ifmgd->flags &= ~IEEE80211_STA_AUTHEN    
1563         cfg80211_send_deauth(sdata->dev, (u8     
1564 }                                                
1565                                                  
1566                                                  
1567 static void ieee80211_rx_mgmt_disassoc(struct    
1568                                        struct    
1569                                        size_t    
1570 {                                                
1571         struct ieee80211_if_managed *ifmgd =     
1572         u16 reason_code;                         
1573                                                  
1574         if (len < 24 + 2)                        
1575                 return;                          
1576                                                  
1577         if (memcmp(ifmgd->bssid, mgmt->sa, ET    
1578                 return;                          
1579                                                  
1580         reason_code = le16_to_cpu(mgmt->u.dis    
1581                                                  
1582         if (ifmgd->flags & IEEE80211_STA_ASSO    
1583                 printk(KERN_DEBUG "%s: disass    
1584                                 sdata->dev->n    
1585                                                  
1586         if (!(ifmgd->flags & IEEE80211_STA_EX    
1587             ifmgd->state == IEEE80211_STA_MLM    
1588                 ifmgd->state = IEEE80211_STA_    
1589                 mod_timer(&ifmgd->timer, jiff    
1590                                       IEEE802    
1591         }                                        
1592                                                  
1593         ieee80211_set_disassoc(sdata, false,     
1594         cfg80211_send_disassoc(sdata->dev, (u    
1595 }                                                
1596                                                  
1597                                                  
1598 static void ieee80211_rx_mgmt_assoc_resp(stru    
1599                                          stru    
1600                                          size    
1601                                          int     
1602 {                                                
1603         struct ieee80211_if_managed *ifmgd =     
1604         struct ieee80211_local *local = sdata    
1605         struct ieee80211_supported_band *sban    
1606         struct sta_info *sta;                    
1607         u32 rates, basic_rates;                  
1608         u16 capab_info, status_code, aid;        
1609         struct ieee802_11_elems elems;           
1610         struct ieee80211_bss_conf *bss_conf =    
1611         u8 *pos;                                 
1612         u32 changed = 0;                         
1613         int i, j;                                
1614         bool have_higher_than_11mbit = false,    
1615         u16 ap_ht_cap_flags;                     
1616                                                  
1617         /* AssocResp and ReassocResp have ide    
1618          * of them in this function. */          
1619                                                  
1620         if (ifmgd->state != IEEE80211_STA_MLM    
1621                 return;                          
1622                                                  
1623         if (len < 24 + 6)                        
1624                 return;                          
1625                                                  
1626         if (memcmp(ifmgd->bssid, mgmt->sa, ET    
1627                 return;                          
1628                                                  
1629         capab_info = le16_to_cpu(mgmt->u.asso    
1630         status_code = le16_to_cpu(mgmt->u.ass    
1631         aid = le16_to_cpu(mgmt->u.assoc_resp.    
1632                                                  
1633         printk(KERN_DEBUG "%s: RX %sssocResp     
1634                "status=%d aid=%d)\n",            
1635                sdata->dev->name, reassoc ? "R    
1636                capab_info, status_code, (u16)    
1637                                                  
1638         pos = mgmt->u.assoc_resp.variable;       
1639         ieee802_11_parse_elems(pos, len - (po    
1640                                                  
1641         if (status_code == WLAN_STATUS_ASSOC_    
1642             elems.timeout_int && elems.timeou    
1643             elems.timeout_int[0] == WLAN_TIME    
1644                 u32 tu, ms;                      
1645                 tu = get_unaligned_le32(elems    
1646                 ms = tu * 1024 / 1000;           
1647                 printk(KERN_DEBUG "%s: AP rej    
1648                        "comeback duration %u     
1649                        sdata->dev->name, tu,     
1650                 if (ms > IEEE80211_ASSOC_TIME    
1651                         mod_timer(&ifmgd->tim    
1652                                   jiffies + m    
1653                 return;                          
1654         }                                        
1655                                                  
1656         if (status_code != WLAN_STATUS_SUCCES    
1657                 printk(KERN_DEBUG "%s: AP den    
1658                        sdata->dev->name, stat    
1659                 /* if this was a reassociatio    
1660                  * association next time. Thi    
1661                  * which do not correctly rej    
1662                 ifmgd->flags &= ~IEEE80211_ST    
1663                 cfg80211_send_rx_assoc(sdata-    
1664                 if (ifmgd->flags & IEEE80211_    
1665                         /* Wait for SME to de    
1666                         ifmgd->state = IEEE80    
1667                         ieee80211_recalc_idle    
1668                 }                                
1669                 return;                          
1670         }                                        
1671                                                  
1672         if ((aid & (BIT(15) | BIT(14))) != (B    
1673                 printk(KERN_DEBUG "%s: invali    
1674                        "set\n", sdata->dev->n    
1675         aid &= ~(BIT(15) | BIT(14));             
1676                                                  
1677         if (!elems.supp_rates) {                 
1678                 printk(KERN_DEBUG "%s: no Sup    
1679                        sdata->dev->name);        
1680                 return;                          
1681         }                                        
1682                                                  
1683         printk(KERN_DEBUG "%s: associated\n",    
1684         ifmgd->aid = aid;                        
1685         ifmgd->ap_capab = capab_info;            
1686                                                  
1687         kfree(ifmgd->assocresp_ies);             
1688         ifmgd->assocresp_ies_len = len - (pos    
1689         ifmgd->assocresp_ies = kmalloc(ifmgd-    
1690         if (ifmgd->assocresp_ies)                
1691                 memcpy(ifmgd->assocresp_ies,     
1692                                                  
1693         rcu_read_lock();                         
1694                                                  
1695         /* Add STA entry for the AP */           
1696         sta = sta_info_get(local, ifmgd->bssi    
1697         if (!sta) {                              
1698                 newsta = true;                   
1699                                                  
1700                 sta = sta_info_alloc(sdata, i    
1701                 if (!sta) {                      
1702                         printk(KERN_DEBUG "%s    
1703                                " the AP\n", s    
1704                         rcu_read_unlock();       
1705                         return;                  
1706                 }                                
1707                                                  
1708                 /* update new sta with its la    
1709                 sta->last_rx = jiffies;          
1710         }                                        
1711                                                  
1712         /*                                       
1713          * FIXME: Do we really need to update    
1714          *        We already know about the A    
1715          *        should already be filled wi    
1716          *        As is stands, all this is r    
1717          *        the information that is fil    
1718          *        change while a STA structur    
1719          *        to between the sta_info_all    
1720          */                                      
1721                                                  
1722         set_sta_flags(sta, WLAN_STA_AUTH | WL    
1723         if (!(ifmgd->flags & IEEE80211_STA_CO    
1724                 set_sta_flags(sta, WLAN_STA_A    
1725                                                  
1726         rates = 0;                               
1727         basic_rates = 0;                         
1728         sband = local->hw.wiphy->bands[local-    
1729                                                  
1730         for (i = 0; i < elems.supp_rates_len;    
1731                 int rate = (elems.supp_rates[    
1732                 bool is_basic = !!(elems.supp    
1733                                                  
1734                 if (rate > 110)                  
1735                         have_higher_than_11mb    
1736                                                  
1737                 for (j = 0; j < sband->n_bitr    
1738                         if (sband->bitrates[j    
1739                                 rates |= BIT(    
1740                                 if (is_basic)    
1741                                         basic    
1742                                 break;           
1743                         }                        
1744                 }                                
1745         }                                        
1746                                                  
1747         for (i = 0; i < elems.ext_supp_rates_    
1748                 int rate = (elems.ext_supp_ra    
1749                 bool is_basic = !!(elems.ext_    
1750                                                  
1751                 if (rate > 110)                  
1752                         have_higher_than_11mb    
1753                                                  
1754                 for (j = 0; j < sband->n_bitr    
1755                         if (sband->bitrates[j    
1756                                 rates |= BIT(    
1757                                 if (is_basic)    
1758                                         basic    
1759                                 break;           
1760                         }                        
1761                 }                                
1762         }                                        
1763                                                  
1764         sta->sta.supp_rates[local->hw.conf.ch    
1765         sdata->vif.bss_conf.basic_rates = bas    
1766                                                  
1767         /* cf. IEEE 802.11 9.2.12 */             
1768         if (local->hw.conf.channel->band == I    
1769             have_higher_than_11mbit)             
1770                 sdata->flags |= IEEE80211_SDA    
1771         else                                     
1772                 sdata->flags &= ~IEEE80211_SD    
1773                                                  
1774         /* If TKIP/WEP is used, no need to pa    
1775         if (elems.ht_cap_elem && !(ifmgd->fla    
1776                 ieee80211_ht_cap_ie_to_sta_ht    
1777                                 elems.ht_cap_    
1778                                                  
1779         ap_ht_cap_flags = sta->sta.ht_cap.cap    
1780                                                  
1781         rate_control_rate_init(sta);             
1782                                                  
1783         if (ifmgd->flags & IEEE80211_STA_MFP_    
1784                 set_sta_flags(sta, WLAN_STA_M    
1785                                                  
1786         if (elems.wmm_param)                     
1787                 set_sta_flags(sta, WLAN_STA_W    
1788                                                  
1789         if (newsta) {                            
1790                 int err = sta_info_insert(sta    
1791                 if (err) {                       
1792                         printk(KERN_DEBUG "%s    
1793                                " the AP (erro    
1794                         rcu_read_unlock();       
1795                         return;                  
1796                 }                                
1797         }                                        
1798                                                  
1799         rcu_read_unlock();                       
1800                                                  
1801         if (elems.wmm_param)                     
1802                 ieee80211_sta_wmm_params(loca    
1803                                          elem    
1804         else                                     
1805                 ieee80211_set_wmm_default(sda    
1806                                                  
1807         if (elems.ht_info_elem && elems.wmm_p    
1808             (ifmgd->flags & IEEE80211_STA_WMM    
1809             !(ifmgd->flags & IEEE80211_STA_TK    
1810                 changed |= ieee80211_enable_h    
1811                                                  
1812                                                  
1813         /* set AID and assoc capability,         
1814          * ieee80211_set_associated() will te    
1815         bss_conf->aid = aid;                     
1816         bss_conf->assoc_capability = capab_in    
1817         ieee80211_set_associated(sdata, chang    
1818                                                  
1819         /*                                       
1820          * initialise the time of last beacon    
1821          * otherwise beacon loss check will t    
1822          */                                      
1823         ifmgd->last_beacon = jiffies;            
1824                                                  
1825         ieee80211_associated(sdata);             
1826         cfg80211_send_rx_assoc(sdata->dev, (u    
1827 }                                                
1828                                                  
1829                                                  
1830 static void ieee80211_rx_bss_info(struct ieee    
1831                                   struct ieee    
1832                                   size_t len,    
1833                                   struct ieee    
1834                                   struct ieee    
1835                                   bool beacon    
1836 {                                                
1837         struct ieee80211_local *local = sdata    
1838         int freq;                                
1839         struct ieee80211_bss *bss;               
1840         struct ieee80211_channel *channel;       
1841                                                  
1842         if (elems->ds_params && elems->ds_par    
1843                 freq = ieee80211_channel_to_f    
1844         else                                     
1845                 freq = rx_status->freq;          
1846                                                  
1847         channel = ieee80211_get_channel(local    
1848                                                  
1849         if (!channel || channel->flags & IEEE    
1850                 return;                          
1851                                                  
1852         bss = ieee80211_bss_info_update(local    
1853                                         chann    
1854         if (!bss)                                
1855                 return;                          
1856                                                  
1857         if (elems->ch_switch_elem && (elems->    
1858             (memcmp(mgmt->bssid, sdata->u.mgd    
1859                 struct ieee80211_channel_sw_i    
1860                         (struct ieee80211_cha    
1861                 ieee80211_sta_process_chanswi    
1862         }                                        
1863                                                  
1864         ieee80211_rx_bss_put(local, bss);        
1865 }                                                
1866                                                  
1867                                                  
1868 static void ieee80211_rx_mgmt_probe_resp(stru    
1869                                          stru    
1870                                          size    
1871                                          stru    
1872 {                                                
1873         struct ieee80211_if_managed *ifmgd;      
1874         size_t baselen;                          
1875         struct ieee802_11_elems elems;           
1876                                                  
1877         ifmgd = &sdata->u.mgd;                   
1878                                                  
1879         if (memcmp(mgmt->da, sdata->dev->dev_    
1880                 return; /* ignore ProbeResp t    
1881                                                  
1882         baselen = (u8 *) mgmt->u.probe_resp.v    
1883         if (baselen > len)                       
1884                 return;                          
1885                                                  
1886         ieee802_11_parse_elems(mgmt->u.probe_    
1887                                 &elems);         
1888                                                  
1889         ieee80211_rx_bss_info(sdata, mgmt, le    
1890                                                  
1891         /* direct probe may be part of the as    
1892         if (ifmgd->state == IEEE80211_STA_MLM    
1893                 printk(KERN_DEBUG "%s direct     
1894                        sdata->dev->name);        
1895                 ieee80211_authenticate(sdata)    
1896         }                                        
1897                                                  
1898         if (ifmgd->flags & IEEE80211_STA_PROB    
1899                 ifmgd->flags &= ~IEEE80211_ST    
1900                 mutex_lock(&sdata->local->ifl    
1901                 ieee80211_recalc_ps(sdata->lo    
1902                 mutex_unlock(&sdata->local->i    
1903         }                                        
1904 }                                                
1905                                                  
1906 /*                                               
1907  * This is the canonical list of information     
1908  * the filter code also gives us all changes     
1909  * (00:50:F2) vendor IE which is used for WMM    
1910  *                                               
1911  * We implement beacon filtering in software     
1912  * avoid processing the frame here and in cfg    
1913  * will not be able to tell whether the hardw    
1914  *                                               
1915  * XXX: This list needs to be dynamic -- user    
1916  *      add items it requires. It also needs     
1917  *      look out for other vendor IEs.           
1918  */                                              
1919 static const u64 care_about_ies =                
1920         (1ULL << WLAN_EID_COUNTRY) |             
1921         (1ULL << WLAN_EID_ERP_INFO) |            
1922         (1ULL << WLAN_EID_CHANNEL_SWITCH) |      
1923         (1ULL << WLAN_EID_PWR_CONSTRAINT) |      
1924         (1ULL << WLAN_EID_HT_CAPABILITY) |       
1925         (1ULL << WLAN_EID_HT_INFORMATION);       
1926                                                  
1927 static void ieee80211_rx_mgmt_beacon(struct i    
1928                                      struct i    
1929                                      size_t l    
1930                                      struct i    
1931 {                                                
1932         struct ieee80211_if_managed *ifmgd =     
1933         size_t baselen;                          
1934         struct ieee802_11_elems elems;           
1935         struct ieee80211_local *local = sdata    
1936         u32 changed = 0;                         
1937         bool erp_valid, directed_tim = false;    
1938         u8 erp_value = 0;                        
1939         u32 ncrc;                                
1940                                                  
1941         /* Process beacon from the current BS    
1942         baselen = (u8 *) mgmt->u.beacon.varia    
1943         if (baselen > len)                       
1944                 return;                          
1945                                                  
1946         if (rx_status->freq != local->hw.conf    
1947                 return;                          
1948                                                  
1949         if (!(ifmgd->flags & IEEE80211_STA_AS    
1950             memcmp(ifmgd->bssid, mgmt->bssid,    
1951                 return;                          
1952                                                  
1953         if (ifmgd->flags & IEEE80211_STA_PROB    
1954 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG             
1955                 if (net_ratelimit()) {           
1956                         printk(KERN_DEBUG "%s    
1957                                "to a received    
1958                 }                                
1959 #endif                                           
1960                 ifmgd->flags &= ~IEEE80211_ST    
1961                 mutex_lock(&local->iflist_mtx    
1962                 ieee80211_recalc_ps(local, -1    
1963                 mutex_unlock(&local->iflist_m    
1964         }                                        
1965                                                  
1966         ncrc = crc32_be(0, (void *)&mgmt->u.b    
1967         ncrc = ieee802_11_parse_elems_crc(mgm    
1968                                           len    
1969                                           car    
1970                                                  
1971         if (local->hw.flags & IEEE80211_HW_PS    
1972                 directed_tim = ieee80211_chec    
1973                                                  
1974                                                  
1975         if (ncrc != ifmgd->beacon_crc) {         
1976                 ieee80211_rx_bss_info(sdata,     
1977                                       true);     
1978                                                  
1979                 ieee80211_sta_wmm_params(loca    
1980                                          elem    
1981         }                                        
1982                                                  
1983         if (local->hw.flags & IEEE80211_HW_PS    
1984                 if (directed_tim) {              
1985                         if (local->hw.conf.dy    
1986                                 local->hw.con    
1987                                 ieee80211_hw_    
1988                                                  
1989                                 ieee80211_sen    
1990                         } else {                 
1991                                 local->pspoll    
1992                                                  
1993                                 /*               
1994                                  * Here is as    
1995                                  * able to se    
1996                                  * response e    
1997                                  * enabled, b    
1998                                  * to disable    
1999                                  * to be inve    
2000                                  */              
2001                                 ieee80211_sen    
2002                         }                        
2003                 }                                
2004         }                                        
2005                                                  
2006         if (ncrc == ifmgd->beacon_crc)           
2007                 return;                          
2008         ifmgd->beacon_crc = ncrc;                
2009                                                  
2010         if (elems.erp_info && elems.erp_info_    
2011                 erp_valid = true;                
2012                 erp_value = elems.erp_info[0]    
2013         } else {                                 
2014                 erp_valid = false;               
2015         }                                        
2016         changed |= ieee80211_handle_bss_capab    
2017                         le16_to_cpu(mgmt->u.b    
2018                         erp_valid, erp_value)    
2019                                                  
2020                                                  
2021         if (elems.ht_cap_elem && elems.ht_inf    
2022             !(ifmgd->flags & IEEE80211_STA_TK    
2023                 struct sta_info *sta;            
2024                 struct ieee80211_supported_ba    
2025                 u16 ap_ht_cap_flags;             
2026                                                  
2027                 rcu_read_lock();                 
2028                                                  
2029                 sta = sta_info_get(local, ifm    
2030                 if (!sta) {                      
2031                         rcu_read_unlock();       
2032                         return;                  
2033                 }                                
2034                                                  
2035                 sband = local->hw.wiphy->band    
2036                                                  
2037                 ieee80211_ht_cap_ie_to_sta_ht    
2038                                 elems.ht_cap_    
2039                                                  
2040                 ap_ht_cap_flags = sta->sta.ht    
2041                                                  
2042                 rcu_read_unlock();               
2043                                                  
2044                 changed |= ieee80211_enable_h    
2045                                                  
2046         }                                        
2047                                                  
2048         if (elems.country_elem) {                
2049                 /* Note we are only reviewing    
2050                  * for the BSSID we are assoc    
2051                 regulatory_hint_11d(local->hw    
2052                         elems.country_elem, e    
2053                                                  
2054                 /* TODO: IBSS also needs this    
2055                 if (elems.pwr_constr_elem)       
2056                         ieee80211_handle_pwr_    
2057                                 le16_to_cpu(m    
2058                                 elems.pwr_con    
2059                                 elems.pwr_con    
2060         }                                        
2061                                                  
2062         ieee80211_bss_info_change_notify(sdat    
2063 }                                                
2064                                                  
2065 ieee80211_rx_result ieee80211_sta_rx_mgmt(str    
2066                                           str    
2067                                           str    
2068 {                                                
2069         struct ieee80211_local *local = sdata    
2070         struct ieee80211_mgmt *mgmt;             
2071         u16 fc;                                  
2072                                                  
2073         if (skb->len < 24)                       
2074                 return RX_DROP_MONITOR;          
2075                                                  
2076         mgmt = (struct ieee80211_mgmt *) skb-    
2077         fc = le16_to_cpu(mgmt->frame_control)    
2078                                                  
2079         switch (fc & IEEE80211_FCTL_STYPE) {     
2080         case IEEE80211_STYPE_PROBE_REQ:          
2081         case IEEE80211_STYPE_PROBE_RESP:         
2082         case IEEE80211_STYPE_BEACON:             
2083                 memcpy(skb->cb, rx_status, si    
2084         case IEEE80211_STYPE_AUTH:               
2085         case IEEE80211_STYPE_ASSOC_RESP:         
2086         case IEEE80211_STYPE_REASSOC_RESP:       
2087         case IEEE80211_STYPE_DEAUTH:             
2088         case IEEE80211_STYPE_DISASSOC:           
2089                 skb_queue_tail(&sdata->u.mgd.    
2090                 queue_work(local->hw.workqueu    
2091                 return RX_QUEUED;                
2092         }                                        
2093                                                  
2094         return RX_DROP_MONITOR;                  
2095 }                                                
2096                                                  
2097 static void ieee80211_sta_rx_queued_mgmt(stru    
2098                                          stru    
2099 {                                                
2100         struct ieee80211_rx_status *rx_status    
2101         struct ieee80211_mgmt *mgmt;             
2102         u16 fc;                                  
2103                                                  
2104         rx_status = (struct ieee80211_rx_stat    
2105         mgmt = (struct ieee80211_mgmt *) skb-    
2106         fc = le16_to_cpu(mgmt->frame_control)    
2107                                                  
2108         switch (fc & IEEE80211_FCTL_STYPE) {     
2109         case IEEE80211_STYPE_PROBE_RESP:         
2110                 ieee80211_rx_mgmt_probe_resp(    
2111                                                  
2112                 break;                           
2113         case IEEE80211_STYPE_BEACON:             
2114                 ieee80211_rx_mgmt_beacon(sdat    
2115                                          rx_s    
2116                 break;                           
2117         case IEEE80211_STYPE_AUTH:               
2118                 ieee80211_rx_mgmt_auth(sdata,    
2119                 break;                           
2120         case IEEE80211_STYPE_ASSOC_RESP:         
2121                 ieee80211_rx_mgmt_assoc_resp(    
2122                 break;                           
2123         case IEEE80211_STYPE_REASSOC_RESP:       
2124                 ieee80211_rx_mgmt_assoc_resp(    
2125                 break;                           
2126         case IEEE80211_STYPE_DEAUTH:             
2127                 ieee80211_rx_mgmt_deauth(sdat    
2128                 break;                           
2129         case IEEE80211_STYPE_DISASSOC:           
2130                 ieee80211_rx_mgmt_disassoc(sd    
2131                 break;                           
2132         }                                        
2133                                                  
2134         kfree_skb(skb);                          
2135 }                                                
2136                                                  
2137 static void ieee80211_sta_timer(unsigned long    
2138 {                                                
2139         struct ieee80211_sub_if_data *sdata =    
2140                 (struct ieee80211_sub_if_data    
2141         struct ieee80211_if_managed *ifmgd =     
2142         struct ieee80211_local *local = sdata    
2143                                                  
2144         if (local->quiescing) {                  
2145                 set_bit(TMR_RUNNING_TIMER, &i    
2146                 return;                          
2147         }                                        
2148                                                  
2149         set_bit(IEEE80211_STA_REQ_RUN, &ifmgd    
2150         queue_work(local->hw.workqueue, &ifmg    
2151 }                                                
2152                                                  
2153 static void ieee80211_sta_reset_auth(struct i    
2154 {                                                
2155         struct ieee80211_if_managed *ifmgd =     
2156         struct ieee80211_local *local = sdata    
2157                                                  
2158         /* Reset own TSF to allow time synchr    
2159         drv_reset_tsf(local);                    
2160                                                  
2161         ifmgd->wmm_last_param_set = -1; /* al    
2162                                                  
2163                                                  
2164         if (ifmgd->auth_algs & IEEE80211_AUTH    
2165                 ifmgd->auth_alg = WLAN_AUTH_O    
2166         else if (ifmgd->auth_algs & IEEE80211    
2167                 ifmgd->auth_alg = WLAN_AUTH_S    
2168         else if (ifmgd->auth_algs & IEEE80211    
2169                 ifmgd->auth_alg = WLAN_AUTH_L    
2170         else if (ifmgd->auth_algs & IEEE80211    
2171                 ifmgd->auth_alg = WLAN_AUTH_F    
2172         else                                     
2173                 ifmgd->auth_alg = WLAN_AUTH_O    
2174         ifmgd->auth_transaction = -1;            
2175         ifmgd->flags &= ~IEEE80211_STA_ASSOCI    
2176         ifmgd->assoc_scan_tries = 0;             
2177         ifmgd->direct_probe_tries = 0;           
2178         ifmgd->auth_tries = 0;                   
2179         ifmgd->assoc_tries = 0;                  
2180         netif_tx_stop_all_queues(sdata->dev);    
2181         netif_carrier_off(sdata->dev);           
2182 }                                                
2183                                                  
2184 static int ieee80211_sta_config_auth(struct i    
2185 {                                                
2186         struct ieee80211_if_managed *ifmgd =     
2187         struct ieee80211_local *local = sdata    
2188         struct ieee80211_bss *bss;               
2189         u8 *bssid = ifmgd->bssid, *ssid = ifm    
2190         u8 ssid_len = ifmgd->ssid_len;           
2191         u16 capa_mask = WLAN_CAPABILITY_ESS;     
2192         u16 capa_val = WLAN_CAPABILITY_ESS;      
2193         struct ieee80211_channel *chan = loca    
2194                                                  
2195         if (!(ifmgd->flags & IEEE80211_STA_EX    
2196             ifmgd->flags & (IEEE80211_STA_AUT    
2197                             IEEE80211_STA_AUT    
2198                             IEEE80211_STA_AUT    
2199                 capa_mask |= WLAN_CAPABILITY_    
2200                 if (sdata->default_key)          
2201                         capa_val |= WLAN_CAPA    
2202         }                                        
2203                                                  
2204         if (ifmgd->flags & IEEE80211_STA_AUTO    
2205                 chan = NULL;                     
2206                                                  
2207         if (ifmgd->flags & IEEE80211_STA_AUTO    
2208                 bssid = NULL;                    
2209                                                  
2210         if (ifmgd->flags & IEEE80211_STA_AUTO    
2211                 ssid = NULL;                     
2212                 ssid_len = 0;                    
2213         }                                        
2214                                                  
2215         bss = (void *)cfg80211_get_bss(local-    
2216                                        bssid,    
2217                                        capa_m    
2218                                                  
2219         if (bss) {                               
2220                 local->oper_channel = bss->cb    
2221                 local->oper_channel_type = NL    
2222                 ieee80211_hw_config(local, 0)    
2223                                                  
2224                 if (!(ifmgd->flags & IEEE8021    
2225                         ieee80211_sta_set_ssi    
2226                                                  
2227                 ieee80211_sta_set_bssid(sdata    
2228                 ieee80211_sta_def_wmm_params(    
2229                                                  
2230                 if (sdata->u.mgd.mfp == IEEE8    
2231                         sdata->u.mgd.flags |=    
2232                 else                             
2233                         sdata->u.mgd.flags &=    
2234                                                  
2235                 /* Send out direct probe if n    
2236                  * the one we have is outdate    
2237                  */                              
2238                 if (!bss->last_probe_resp ||     
2239                     time_after(jiffies, bss->    
2240                                         + IEE    
2241                         ifmgd->state = IEEE80    
2242                 else                             
2243                         ifmgd->state = IEEE80    
2244                                                  
2245                 ieee80211_rx_bss_put(local, b    
2246                 ieee80211_sta_reset_auth(sdat    
2247                 return 0;                        
2248         } else {                                 
2249                 if (ifmgd->assoc_scan_tries <    
2250                                                  
2251                         ifmgd->assoc_scan_tri    
2252                                                  
2253                         ieee80211_request_int    
2254                                                  
2255                                                  
2256                         ifmgd->state = IEEE80    
2257                         set_bit(IEEE80211_STA    
2258                 } else {                         
2259                         ifmgd->assoc_scan_tri    
2260                         ifmgd->state = IEEE80    
2261                         ieee80211_recalc_idle    
2262                 }                                
2263         }                                        
2264         return -1;                               
2265 }                                                
2266                                                  
2267                                                  
2268 static void ieee80211_sta_work(struct work_st    
2269 {                                                
2270         struct ieee80211_sub_if_data *sdata =    
2271                 container_of(work, struct iee    
2272         struct ieee80211_local *local = sdata    
2273         struct ieee80211_if_managed *ifmgd;      
2274         struct sk_buff *skb;                     
2275                                                  
2276         if (!netif_running(sdata->dev))          
2277                 return;                          
2278                                                  
2279         if (local->sw_scanning || local->hw_s    
2280                 return;                          
2281                                                  
2282         if (WARN_ON(sdata->vif.type != NL8021    
2283                 return;                          
2284                                                  
2285         /*                                       
2286          * Nothing should have been stuffed i    
2287          * the suspend->resume cycle. If this    
2288          * is a bug with either the driver su    
2289          * mac80211 stuffing into the workque    
2290          * cleared during mac80211's suspend     
2291          */                                      
2292         if (WARN_ON(local->suspended))           
2293                 return;                          
2294                                                  
2295         ifmgd = &sdata->u.mgd;                   
2296                                                  
2297         while ((skb = skb_dequeue(&ifmgd->skb    
2298                 ieee80211_sta_rx_queued_mgmt(    
2299                                                  
2300         if (ifmgd->state != IEEE80211_STA_MLM    
2301             ifmgd->state != IEEE80211_STA_MLM    
2302             ifmgd->state != IEEE80211_STA_MLM    
2303             test_and_clear_bit(IEEE80211_STA_    
2304                 queue_delayed_work(local->hw.    
2305                                    round_jiff    
2306                 return;                          
2307         }                                        
2308                                                  
2309         if (test_and_clear_bit(IEEE80211_STA_    
2310                 if (ieee80211_sta_config_auth    
2311                         return;                  
2312                 clear_bit(IEEE80211_STA_REQ_R    
2313         } else if (!test_and_clear_bit(IEEE80    
2314                 return;                          
2315                                                  
2316         ieee80211_recalc_idle(local);            
2317                                                  
2318         switch (ifmgd->state) {                  
2319         case IEEE80211_STA_MLME_DISABLED:        
2320                 break;                           
2321         case IEEE80211_STA_MLME_DIRECT_PROBE:    
2322                 ieee80211_direct_probe(sdata)    
2323                 break;                           
2324         case IEEE80211_STA_MLME_AUTHENTICATE:    
2325                 ieee80211_authenticate(sdata)    
2326                 break;                           
2327         case IEEE80211_STA_MLME_ASSOCIATE:       
2328                 ieee80211_associate(sdata);      
2329                 break;                           
2330         case IEEE80211_STA_MLME_ASSOCIATED:      
2331                 ieee80211_associated(sdata);     
2332                 break;                           
2333         default:                                 
2334                 WARN_ON(1);                      
2335                 break;                           
2336         }                                        
2337                                                  
2338         if (ieee80211_privacy_mismatch(sdata)    
2339                 printk(KERN_DEBUG "%s: privac    
2340                        "mixed-cell disabled -    
2341                                                  
2342                 ieee80211_set_disassoc(sdata,    
2343                                         WLAN_    
2344         }                                        
2345 }                                                
2346                                                  
2347 static void ieee80211_restart_sta_timer(struc    
2348 {                                                
2349         if (sdata->vif.type == NL80211_IFTYPE    
2350                 /*                               
2351                  * Need to update last_beacon    
2352                  * test to trigger.              
2353                  */                              
2354                 sdata->u.mgd.last_beacon = ji    
2355                                                  
2356                                                  
2357                 queue_work(sdata->local->hw.w    
2358                            &sdata->u.mgd.work    
2359         }                                        
2360 }                                                
2361                                                  
2362 #ifdef CONFIG_PM                                 
2363 void ieee80211_sta_quiesce(struct ieee80211_s    
2364 {                                                
2365         struct ieee80211_if_managed *ifmgd =     
2366                                                  
2367         /*                                       
2368          * we need to use atomic bitops for t    
2369          * only because both timers might fir    
2370          * time -- the code here is properly     
2371          */                                      
2372                                                  
2373         cancel_work_sync(&ifmgd->work);          
2374         cancel_work_sync(&ifmgd->beacon_loss_    
2375         if (del_timer_sync(&ifmgd->timer))       
2376                 set_bit(TMR_RUNNING_TIMER, &i    
2377                                                  
2378         cancel_work_sync(&ifmgd->chswitch_wor    
2379         if (del_timer_sync(&ifmgd->chswitch_t    
2380                 set_bit(TMR_RUNNING_CHANSW, &    
2381 }                                                
2382                                                  
2383 void ieee80211_sta_restart(struct ieee80211_s    
2384 {                                                
2385         struct ieee80211_if_managed *ifmgd =     
2386                                                  
2387         if (test_and_clear_bit(TMR_RUNNING_TI    
2388                 add_timer(&ifmgd->timer);        
2389         if (test_and_clear_bit(TMR_RUNNING_CH    
2390                 add_timer(&ifmgd->chswitch_ti    
2391 }                                                
2392 #endif                                           
2393                                                  
2394 /* interface setup */                            
2395 void ieee80211_sta_setup_sdata(struct ieee802    
2396 {                                                
2397         struct ieee80211_if_managed *ifmgd;      
2398         u32 hw_flags;                            
2399                                                  
2400         ifmgd = &sdata->u.mgd;                   
2401         INIT_WORK(&ifmgd->work, ieee80211_sta    
2402         INIT_WORK(&ifmgd->chswitch_work, ieee    
2403         INIT_WORK(&ifmgd->beacon_loss_work, i    
2404         setup_timer(&ifmgd->timer, ieee80211_    
2405                     (unsigned long) sdata);      
2406         setup_timer(&ifmgd->chswitch_timer, i    
2407                     (unsigned long) sdata);      
2408         skb_queue_head_init(&ifmgd->skb_queue    
2409                                                  
2410         ifmgd->capab = WLAN_CAPABILITY_ESS;      
2411         ifmgd->auth_algs = IEEE80211_AUTH_ALG    
2412                 IEEE80211_AUTH_ALG_SHARED_KEY    
2413         ifmgd->flags |= IEEE80211_STA_CREATE_    
2414                 IEEE80211_STA_AUTO_BSSID_SEL     
2415                 IEEE80211_STA_AUTO_CHANNEL_SE    
2416         if (sdata->local->hw.queues >= 4)        
2417                 ifmgd->flags |= IEEE80211_STA    
2418                                                  
2419         hw_flags = sdata->local->hw.flags;       
2420                                                  
2421         if (hw_flags & IEEE80211_HW_SUPPORTS_    
2422                 ifmgd->powersave = CONFIG_MAC    
2423                 sdata->local->hw.conf.dynamic    
2424         }                                        
2425 }                                                
2426                                                  
2427 /* configuration hooks */                        
2428 void ieee80211_sta_req_auth(struct ieee80211_    
2429 {                                                
2430         struct ieee80211_if_managed *ifmgd =     
2431         struct ieee80211_local *local = sdata    
2432                                                  
2433         if (WARN_ON(sdata->vif.type != NL8021    
2434                 return;                          
2435                                                  
2436         if ((ifmgd->flags & (IEEE80211_STA_BS    
2437                              IEEE80211_STA_AU    
2438             (ifmgd->flags & (IEEE80211_STA_SS    
2439                              IEEE80211_STA_AU    
2440                                                  
2441                 if (ifmgd->state == IEEE80211    
2442                         ieee80211_set_disasso    
2443                                                  
2444                                                  
2445                 if (ifmgd->ssid_len == 0) {      
2446                         /*                       
2447                          * Only allow associa    
2448                          * is configured.        
2449                          */                      
2450                         return;                  
2451                 }                                
2452                                                  
2453                 if (!(ifmgd->flags & IEEE8021    
2454                     ifmgd->state != IEEE80211    
2455                         set_bit(IEEE80211_STA    
2456                 else if (ifmgd->flags & IEEE8    
2457                         set_bit(IEEE80211_STA    
2458                 queue_work(local->hw.workqueu    
2459         }                                        
2460 }                                                
2461                                                  
2462 int ieee80211_sta_commit(struct ieee80211_sub    
2463 {                                                
2464         struct ieee80211_if_managed *ifmgd =     
2465                                                  
2466         if (ifmgd->ssid_len)                     
2467                 ifmgd->flags |= IEEE80211_STA    
2468         else                                     
2469                 ifmgd->flags &= ~IEEE80211_ST    
2470                                                  
2471         return 0;                                
2472 }                                                
2473                                                  
2474 int ieee80211_sta_set_ssid(struct ieee80211_s    
2475 {                                                
2476         struct ieee80211_if_managed *ifmgd;      
2477                                                  
2478         if (len > IEEE80211_MAX_SSID_LEN)        
2479                 return -EINVAL;                  
2480                                                  
2481         ifmgd = &sdata->u.mgd;                   
2482                                                  
2483         if (ifmgd->ssid_len != len || memcmp(    
2484                 if (ifmgd->state == IEEE80211    
2485                         ieee80211_set_disasso    
2486                                                  
2487                                                  
2488                 /*                               
2489                  * Do not use reassociation i    
2490                  */                              
2491                 ifmgd->flags &= ~IEEE80211_ST    
2492                 memset(ifmgd->ssid, 0, sizeof    
2493                 memcpy(ifmgd->ssid, ssid, len    
2494                 ifmgd->ssid_len = len;           
2495         }                                        
2496                                                  
2497         return ieee80211_sta_commit(sdata);      
2498 }                                                
2499                                                  
2500 int ieee80211_sta_get_ssid(struct ieee80211_s    
2501 {                                                
2502         struct ieee80211_if_managed *ifmgd =     
2503         memcpy(ssid, ifmgd->ssid, ifmgd->ssid    
2504         *len = ifmgd->ssid_len;                  
2505         return 0;                                
2506 }                                                
2507                                                  
2508 int ieee80211_sta_set_bssid(struct ieee80211_    
2509 {                                                
2510         struct ieee80211_if_managed *ifmgd =     
2511                                                  
2512         if (compare_ether_addr(bssid, ifmgd->    
2513             ifmgd->state == IEEE80211_STA_MLM    
2514                 ieee80211_set_disassoc(sdata,    
2515                                        WLAN_R    
2516                                                  
2517         if (is_valid_ether_addr(bssid)) {        
2518                 memcpy(ifmgd->bssid, bssid, E    
2519                 ifmgd->flags |= IEEE80211_STA    
2520         } else {                                 
2521                 memset(ifmgd->bssid, 0, ETH_A    
2522                 ifmgd->flags &= ~IEEE80211_ST    
2523         }                                        
2524                                                  
2525         return ieee80211_sta_commit(sdata);      
2526 }                                                
2527                                                  
2528 int ieee80211_sta_set_extra_ie(struct ieee802    
2529                                const char *ie    
2530 {                                                
2531         struct ieee80211_if_managed *ifmgd =     
2532                                                  
2533         if (len == 0 && ifmgd->extra_ie_len =    
2534                 return -EALREADY;                
2535                                                  
2536         if (len == ifmgd->extra_ie_len && ifm    
2537             memcmp(ifmgd->extra_ie, ie, len)     
2538                 return -EALREADY;                
2539                                                  
2540         kfree(ifmgd->extra_ie);                  
2541         if (len == 0) {                          
2542                 ifmgd->extra_ie = NULL;          
2543                 ifmgd->extra_ie_len = 0;         
2544                 return 0;                        
2545         }                                        
2546         ifmgd->extra_ie = kmalloc(len, GFP_KE    
2547         if (!ifmgd->extra_ie) {                  
2548                 ifmgd->extra_ie_len = 0;         
2549                 return -ENOMEM;                  
2550         }                                        
2551         memcpy(ifmgd->extra_ie, ie, len);        
2552         ifmgd->extra_ie_len = len;               
2553         return 0;                                
2554 }                                                
2555                                                  
2556 int ieee80211_sta_deauthenticate(struct ieee8    
2557 {                                                
2558         printk(KERN_DEBUG "%s: deauthenticati    
2559                sdata->dev->name, reason);        
2560                                                  
2561         ieee80211_set_disassoc(sdata, true, t    
2562         return 0;                                
2563 }                                                
2564                                                  
2565 int ieee80211_sta_disassociate(struct ieee802    
2566 {                                                
2567         struct ieee80211_if_managed *ifmgd =     
2568                                                  
2569         printk(KERN_DEBUG "%s: disassociating    
2570                sdata->dev->name, reason);        
2571                                                  
2572         if (!(ifmgd->flags & IEEE80211_STA_AS    
2573                 return -ENOLINK;                 
2574                                                  
2575         ieee80211_set_disassoc(sdata, false,     
2576         return 0;                                
2577 }                                                
2578                                                  
2579 /* scan finished notification */                 
2580 void ieee80211_mlme_notify_scan_completed(str    
2581 {                                                
2582         struct ieee80211_sub_if_data *sdata =    
2583                                                  
2584         /* Restart STA timers */                 
2585         rcu_read_lock();                         
2586         list_for_each_entry_rcu(sdata, &local    
2587                 ieee80211_restart_sta_timer(s    
2588         rcu_read_unlock();                       
2589 }                                                
2590                                                  
2591 int ieee80211_max_network_latency(struct noti    
2592                                   unsigned lo    
2593 {                                                
2594         s32 latency_usec = (s32) data;           
2595         struct ieee80211_local *local =          
2596                 container_of(nb, struct ieee8    
2597                              network_latency_    
2598                                                  
2599         mutex_lock(&local->iflist_mtx);          
2600         ieee80211_recalc_ps(local, latency_us    
2601         mutex_unlock(&local->iflist_mtx);        
2602                                                  
2603         return 0;                                
2604 }                                                
2605                                                  
  This page was automatically generated by the LXR engine.