aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-04 11:58:14 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-04 11:58:14 -0500
commit10be7eb36b93364b98688831ee7d26f58402bb96 (patch)
treeeb13ae80fcaa8baacd804a721c5a4962a501a2a4 /net
parent90c30335a70e96b8b8493b7deb15e6b30e6d9fce (diff)
parent5ffaf8a361b4c9025963959a744f21d8173c7669 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/debugfs_sta.c26
-rw-r--r--net/mac80211/driver-ops.h14
-rw-r--r--net/mac80211/driver-trace.h15
-rw-r--r--net/mac80211/ibss.c22
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/mac80211/mlme.c27
-rw-r--r--net/mac80211/rate.h4
-rw-r--r--net/mac80211/rc80211_pid_algo.c8
-rw-r--r--net/mac80211/rx.c45
-rw-r--r--net/mac80211/scan.c4
-rw-r--r--net/mac80211/status.c35
-rw-r--r--net/mac80211/tkip.c23
-rw-r--r--net/mac80211/tx.c50
-rw-r--r--net/mac80211/wep.c17
-rw-r--r--net/mac80211/work.c19
-rw-r--r--net/mac80211/wpa.c57
-rw-r--r--net/wireless/core.c38
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/lib80211_crypt_ccmp.c2
-rw-r--r--net/wireless/lib80211_crypt_tkip.c23
-rw-r--r--net/wireless/nl80211.c4
-rw-r--r--net/wireless/reg.c161
-rw-r--r--net/wireless/reg.h18
-rw-r--r--net/wireless/scan.c38
-rw-r--r--net/wireless/sme.c40
-rw-r--r--net/wireless/sysfs.c20
-rw-r--r--net/wireless/util.c5
-rw-r--r--net/wireless/wext-compat.c2
29 files changed, 503 insertions, 224 deletions
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 0d4a759ba72c..d92800bb2d2f 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -120,36 +120,38 @@ STA_OPS(last_seq_ctrl);
120static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, 120static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
121 size_t count, loff_t *ppos) 121 size_t count, loff_t *ppos)
122{ 122{
123 char buf[30 + STA_TID_NUM * 70], *p = buf; 123 char buf[64 + STA_TID_NUM * 40], *p = buf;
124 int i; 124 int i;
125 struct sta_info *sta = file->private_data; 125 struct sta_info *sta = file->private_data;
126 126
127 spin_lock_bh(&sta->lock); 127 spin_lock_bh(&sta->lock);
128 p += scnprintf(p, sizeof(buf)+buf-p, "next dialog_token is %#02x\n", 128 p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n",
129 sta->ampdu_mlme.dialog_token_allocator + 1); 129 sta->ampdu_mlme.dialog_token_allocator + 1);
130 p += scnprintf(p, sizeof(buf) + buf - p,
131 "TID\t\tRX\tDTKN\tSSN\t\tTX\tDTKN\tSSN\tpending\n");
130 for (i = 0; i < STA_TID_NUM; i++) { 132 for (i = 0; i < STA_TID_NUM; i++) {
131 p += scnprintf(p, sizeof(buf)+buf-p, "TID %02d:", i); 133 p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i);
132 p += scnprintf(p, sizeof(buf)+buf-p, " RX=%x", 134 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
133 sta->ampdu_mlme.tid_state_rx[i]); 135 sta->ampdu_mlme.tid_state_rx[i]);
134 p += scnprintf(p, sizeof(buf)+buf-p, "/DTKN=%#.2x", 136 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
135 sta->ampdu_mlme.tid_state_rx[i] ? 137 sta->ampdu_mlme.tid_state_rx[i] ?
136 sta->ampdu_mlme.tid_rx[i]->dialog_token : 0); 138 sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
137 p += scnprintf(p, sizeof(buf)+buf-p, "/SSN=%#.3x", 139 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
138 sta->ampdu_mlme.tid_state_rx[i] ? 140 sta->ampdu_mlme.tid_state_rx[i] ?
139 sta->ampdu_mlme.tid_rx[i]->ssn : 0); 141 sta->ampdu_mlme.tid_rx[i]->ssn : 0);
140 142
141 p += scnprintf(p, sizeof(buf)+buf-p, " TX=%x", 143 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
142 sta->ampdu_mlme.tid_state_tx[i]); 144 sta->ampdu_mlme.tid_state_tx[i]);
143 p += scnprintf(p, sizeof(buf)+buf-p, "/DTKN=%#.2x", 145 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
144 sta->ampdu_mlme.tid_state_tx[i] ? 146 sta->ampdu_mlme.tid_state_tx[i] ?
145 sta->ampdu_mlme.tid_tx[i]->dialog_token : 0); 147 sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
146 p += scnprintf(p, sizeof(buf)+buf-p, "/SSN=%#.3x", 148 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
147 sta->ampdu_mlme.tid_state_tx[i] ? 149 sta->ampdu_mlme.tid_state_tx[i] ?
148 sta->ampdu_mlme.tid_tx[i]->ssn : 0); 150 sta->ampdu_mlme.tid_tx[i]->ssn : 0);
149 p += scnprintf(p, sizeof(buf)+buf-p, "/pending=%03d", 151 p += scnprintf(p, sizeof(buf) + buf - p, "\t%03d",
150 sta->ampdu_mlme.tid_state_tx[i] ? 152 sta->ampdu_mlme.tid_state_tx[i] ?
151 skb_queue_len(&sta->ampdu_mlme.tid_tx[i]->pending) : 0); 153 skb_queue_len(&sta->ampdu_mlme.tid_tx[i]->pending) : 0);
152 p += scnprintf(p, sizeof(buf)+buf-p, "\n"); 154 p += scnprintf(p, sizeof(buf) + buf - p, "\n");
153 } 155 }
154 spin_unlock_bh(&sta->lock); 156 spin_unlock_bh(&sta->lock);
155 157
@@ -165,7 +167,7 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
165 if (_cond) \ 167 if (_cond) \
166 p += scnprintf(p, sizeof(buf)+buf-p, "\t" _str "\n"); \ 168 p += scnprintf(p, sizeof(buf)+buf-p, "\t" _str "\n"); \
167 } while (0) 169 } while (0)
168 char buf[1024], *p = buf; 170 char buf[512], *p = buf;
169 int i; 171 int i;
170 struct sta_info *sta = file->private_data; 172 struct sta_info *sta = file->private_data;
171 struct ieee80211_sta_ht_cap *htc = &sta->sta.ht_cap; 173 struct ieee80211_sta_ht_cap *htc = &sta->sta.ht_cap;
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index de91d39e0276..6c31f38ac7f5 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -137,16 +137,20 @@ static inline int drv_set_key(struct ieee80211_local *local,
137} 137}
138 138
139static inline void drv_update_tkip_key(struct ieee80211_local *local, 139static inline void drv_update_tkip_key(struct ieee80211_local *local,
140 struct ieee80211_sub_if_data *sdata,
140 struct ieee80211_key_conf *conf, 141 struct ieee80211_key_conf *conf,
141 const u8 *address, u32 iv32, 142 struct sta_info *sta, u32 iv32,
142 u16 *phase1key) 143 u16 *phase1key)
143{ 144{
144 might_sleep(); 145 struct ieee80211_sta *ista = NULL;
146
147 if (sta)
148 ista = &sta->sta;
145 149
146 if (local->ops->update_tkip_key) 150 if (local->ops->update_tkip_key)
147 local->ops->update_tkip_key(&local->hw, conf, address, 151 local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
148 iv32, phase1key); 152 ista, iv32, phase1key);
149 trace_drv_update_tkip_key(local, conf, address, iv32); 153 trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
150} 154}
151 155
152static inline int drv_hw_scan(struct ieee80211_local *local, 156static inline int drv_hw_scan(struct ieee80211_local *local,
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index d6bd9f517401..502424b2538a 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -331,26 +331,29 @@ TRACE_EVENT(drv_set_key,
331 331
332TRACE_EVENT(drv_update_tkip_key, 332TRACE_EVENT(drv_update_tkip_key,
333 TP_PROTO(struct ieee80211_local *local, 333 TP_PROTO(struct ieee80211_local *local,
334 struct ieee80211_sub_if_data *sdata,
334 struct ieee80211_key_conf *conf, 335 struct ieee80211_key_conf *conf,
335 const u8 *address, u32 iv32), 336 struct ieee80211_sta *sta, u32 iv32),
336 337
337 TP_ARGS(local, conf, address, iv32), 338 TP_ARGS(local, sdata, conf, sta, iv32),
338 339
339 TP_STRUCT__entry( 340 TP_STRUCT__entry(
340 LOCAL_ENTRY 341 LOCAL_ENTRY
341 __array(u8, addr, 6) 342 VIF_ENTRY
343 STA_ENTRY
342 __field(u32, iv32) 344 __field(u32, iv32)
343 ), 345 ),
344 346
345 TP_fast_assign( 347 TP_fast_assign(
346 LOCAL_ASSIGN; 348 LOCAL_ASSIGN;
347 memcpy(__entry->addr, address, 6); 349 VIF_ASSIGN;
350 STA_ASSIGN;
348 __entry->iv32 = iv32; 351 __entry->iv32 = iv32;
349 ), 352 ),
350 353
351 TP_printk( 354 TP_printk(
352 LOCAL_PR_FMT " addr:%pM iv32:%#x", 355 LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " iv32:%#x",
353 LOCAL_PR_ARG, __entry->addr, __entry->iv32 356 LOCAL_PR_ARG,VIF_PR_ARG,STA_PR_ARG, __entry->iv32
354 ) 357 )
355); 358);
356 359
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 5bcde4c3fba1..f95750b423e3 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -293,12 +293,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
293 293
294 /* check if we need to merge IBSS */ 294 /* check if we need to merge IBSS */
295 295
296 /* merge only on beacons (???) */
297 if (!beacon)
298 goto put_bss;
299
300 /* we use a fixed BSSID */ 296 /* we use a fixed BSSID */
301 if (sdata->u.ibss.bssid) 297 if (sdata->u.ibss.fixed_bssid)
302 goto put_bss; 298 goto put_bss;
303 299
304 /* not an IBSS */ 300 /* not an IBSS */
@@ -454,6 +450,9 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
454 return active; 450 return active;
455} 451}
456 452
453/*
454 * This function is called with state == IEEE80211_IBSS_MLME_JOINED
455 */
457 456
458static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) 457static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
459{ 458{
@@ -519,6 +518,10 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
519 capability, 0); 518 capability, 0);
520} 519}
521 520
521/*
522 * This function is called with state == IEEE80211_IBSS_MLME_SEARCH
523 */
524
522static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) 525static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
523{ 526{
524 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 527 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
@@ -575,18 +578,14 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
575#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 578#endif /* CONFIG_MAC80211_IBSS_DEBUG */
576 579
577 /* Selected IBSS not found in current scan results - try to scan */ 580 /* Selected IBSS not found in current scan results - try to scan */
578 if (ifibss->state == IEEE80211_IBSS_MLME_JOINED && 581 if (time_after(jiffies, ifibss->last_scan_completed +
579 !ieee80211_sta_active_ibss(sdata)) {
580 mod_timer(&ifibss->timer,
581 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
582 } else if (time_after(jiffies, ifibss->last_scan_completed +
583 IEEE80211_SCAN_INTERVAL)) { 582 IEEE80211_SCAN_INTERVAL)) {
584 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 583 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
585 "join\n", sdata->name); 584 "join\n", sdata->name);
586 585
587 ieee80211_request_internal_scan(sdata, ifibss->ssid, 586 ieee80211_request_internal_scan(sdata, ifibss->ssid,
588 ifibss->ssid_len); 587 ifibss->ssid_len);
589 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) { 588 } else {
590 int interval = IEEE80211_SCAN_INTERVAL; 589 int interval = IEEE80211_SCAN_INTERVAL;
591 590
592 if (time_after(jiffies, ifibss->ibss_join_req + 591 if (time_after(jiffies, ifibss->ibss_join_req +
@@ -604,7 +603,6 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
604 interval = IEEE80211_SCAN_INTERVAL_SLOW; 603 interval = IEEE80211_SCAN_INTERVAL_SLOW;
605 } 604 }
606 605
607 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
608 mod_timer(&ifibss->timer, 606 mod_timer(&ifibss->timer,
609 round_jiffies(jiffies + interval)); 607 round_jiffies(jiffies + interval));
610 } 608 }
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c18f576f1848..3067fbd69d63 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -299,7 +299,6 @@ struct ieee80211_work {
299 } assoc; 299 } assoc;
300 struct { 300 struct {
301 u32 duration; 301 u32 duration;
302 bool started;
303 } remain; 302 } remain;
304 }; 303 };
305 304
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index edf21cebeee8..09fff4662e80 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -695,10 +695,14 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
695 695
696 hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); 696 hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
697 697
698 if (!ieee80211_is_data_qos(hdr->frame_control)) { 698 if (!ieee80211_is_data(hdr->frame_control)) {
699 skb->priority = 7; 699 skb->priority = 7;
700 return ieee802_1d_to_ac[skb->priority]; 700 return ieee802_1d_to_ac[skb->priority];
701 } 701 }
702 if (!ieee80211_is_data_qos(hdr->frame_control)) {
703 skb->priority = 0;
704 return ieee802_1d_to_ac[skb->priority];
705 }
702 706
703 p = ieee80211_get_qos_ctl(hdr); 707 p = ieee80211_get_qos_ctl(hdr);
704 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; 708 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1e1d16c55ee5..86c6ad1b058d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -484,6 +484,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
484 484
485 if (count == 1 && found->u.mgd.powersave && 485 if (count == 1 && found->u.mgd.powersave &&
486 found->u.mgd.associated && 486 found->u.mgd.associated &&
487 found->u.mgd.associated->beacon_ies &&
487 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL | 488 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
488 IEEE80211_STA_CONNECTION_POLL))) { 489 IEEE80211_STA_CONNECTION_POLL))) {
489 s32 beaconint_us; 490 s32 beaconint_us;
@@ -497,14 +498,22 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
497 if (beaconint_us > latency) { 498 if (beaconint_us > latency) {
498 local->ps_sdata = NULL; 499 local->ps_sdata = NULL;
499 } else { 500 } else {
500 u8 dtimper = found->vif.bss_conf.dtim_period; 501 struct ieee80211_bss *bss;
501 int maxslp = 1; 502 int maxslp = 1;
503 u8 dtimper;
502 504
503 if (dtimper > 1) 505 bss = (void *)found->u.mgd.associated->priv;
506 dtimper = bss->dtim_period;
507
508 /* If the TIM IE is invalid, pretend the value is 1 */
509 if (!dtimper)
510 dtimper = 1;
511 else if (dtimper > 1)
504 maxslp = min_t(int, dtimper, 512 maxslp = min_t(int, dtimper,
505 latency / beaconint_us); 513 latency / beaconint_us);
506 514
507 local->hw.conf.max_sleep_period = maxslp; 515 local->hw.conf.max_sleep_period = maxslp;
516 local->hw.conf.ps_dtim_period = dtimper;
508 local->ps_sdata = found; 517 local->ps_sdata = found;
509 } 518 }
510 } else { 519 } else {
@@ -702,7 +711,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
702 /* set timing information */ 711 /* set timing information */
703 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; 712 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
704 sdata->vif.bss_conf.timestamp = cbss->tsf; 713 sdata->vif.bss_conf.timestamp = cbss->tsf;
705 sdata->vif.bss_conf.dtim_period = bss->dtim_period;
706 714
707 bss_info_changed |= BSS_CHANGED_BEACON_INT; 715 bss_info_changed |= BSS_CHANGED_BEACON_INT;
708 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 716 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
@@ -1168,6 +1176,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1168 int freq; 1176 int freq;
1169 struct ieee80211_bss *bss; 1177 struct ieee80211_bss *bss;
1170 struct ieee80211_channel *channel; 1178 struct ieee80211_channel *channel;
1179 bool need_ps = false;
1180
1181 if (sdata->u.mgd.associated) {
1182 bss = (void *)sdata->u.mgd.associated->priv;
1183 /* not previously set so we may need to recalc */
1184 need_ps = !bss->dtim_period;
1185 }
1171 1186
1172 if (elems->ds_params && elems->ds_params_len == 1) 1187 if (elems->ds_params && elems->ds_params_len == 1)
1173 freq = ieee80211_channel_to_frequency(elems->ds_params[0]); 1188 freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
@@ -1187,6 +1202,12 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1187 if (!sdata->u.mgd.associated) 1202 if (!sdata->u.mgd.associated)
1188 return; 1203 return;
1189 1204
1205 if (need_ps) {
1206 mutex_lock(&local->iflist_mtx);
1207 ieee80211_recalc_ps(local, -1);
1208 mutex_unlock(&local->iflist_mtx);
1209 }
1210
1190 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) && 1211 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
1191 (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, 1212 (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
1192 ETH_ALEN) == 0)) { 1213 ETH_ALEN) == 0)) {
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 669dddd40521..998cf7a935b6 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -44,6 +44,10 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
44 struct rate_control_ref *ref = local->rate_ctrl; 44 struct rate_control_ref *ref = local->rate_ctrl;
45 struct ieee80211_sta *ista = &sta->sta; 45 struct ieee80211_sta *ista = &sta->sta;
46 void *priv_sta = sta->rate_ctrl_priv; 46 void *priv_sta = sta->rate_ctrl_priv;
47
48 if (!ref)
49 return;
50
47 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb); 51 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
48} 52}
49 53
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 29bc4c516238..2652a374974e 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -157,9 +157,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
157 157
158 /* In case nothing happened during the previous control interval, turn 158 /* In case nothing happened during the previous control interval, turn
159 * the sharpening factor on. */ 159 * the sharpening factor on. */
160 period = (HZ * pinfo->sampling_period + 500) / 1000; 160 period = msecs_to_jiffies(pinfo->sampling_period);
161 if (!period)
162 period = 1;
163 if (jiffies - spinfo->last_sample > 2 * period) 161 if (jiffies - spinfo->last_sample > 2 * period)
164 spinfo->sharp_cnt = pinfo->sharpen_duration; 162 spinfo->sharp_cnt = pinfo->sharpen_duration;
165 163
@@ -252,9 +250,7 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba
252 } 250 }
253 251
254 /* Update PID controller state. */ 252 /* Update PID controller state. */
255 period = (HZ * pinfo->sampling_period + 500) / 1000; 253 period = msecs_to_jiffies(pinfo->sampling_period);
256 if (!period)
257 period = 1;
258 if (time_after(jiffies, spinfo->last_sample + period)) 254 if (time_after(jiffies, spinfo->last_sample + period))
259 rate_control_pid_sample(pinfo, sband, sta, spinfo); 255 rate_control_pid_sample(pinfo, sband, sta, spinfo);
260} 256}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a8e15b84c05b..5709307fcb9b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2348,22 +2348,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2348 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 2348 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
2349 continue; 2349 continue;
2350 2350
2351 rx.sta = sta_info_get(sdata, hdr->addr2);
2352
2353 rx.flags |= IEEE80211_RX_RA_MATCH;
2354 prepares = prepare_for_handlers(sdata, &rx, hdr);
2355
2356 if (!prepares)
2357 continue;
2358
2359 if (status->flag & RX_FLAG_MMIC_ERROR) {
2360 rx.sdata = sdata;
2361 if (rx.flags & IEEE80211_RX_RA_MATCH)
2362 ieee80211_rx_michael_mic_report(hdr,
2363 &rx);
2364 continue;
2365 }
2366
2367 /* 2351 /*
2368 * frame is destined for this interface, but if it's 2352 * frame is destined for this interface, but if it's
2369 * not also for the previous one we handle that after 2353 * not also for the previous one we handle that after
@@ -2375,6 +2359,22 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2375 continue; 2359 continue;
2376 } 2360 }
2377 2361
2362 rx.sta = sta_info_get_bss(prev, hdr->addr2);
2363
2364 rx.flags |= IEEE80211_RX_RA_MATCH;
2365 prepares = prepare_for_handlers(prev, &rx, hdr);
2366
2367 if (!prepares)
2368 goto next;
2369
2370 if (status->flag & RX_FLAG_MMIC_ERROR) {
2371 rx.sdata = prev;
2372 if (rx.flags & IEEE80211_RX_RA_MATCH)
2373 ieee80211_rx_michael_mic_report(hdr,
2374 &rx);
2375 goto next;
2376 }
2377
2378 /* 2378 /*
2379 * frame was destined for the previous interface 2379 * frame was destined for the previous interface
2380 * so invoke RX handlers for it 2380 * so invoke RX handlers for it
@@ -2387,11 +2387,22 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2387 "multicast frame for %s\n", 2387 "multicast frame for %s\n",
2388 wiphy_name(local->hw.wiphy), 2388 wiphy_name(local->hw.wiphy),
2389 prev->name); 2389 prev->name);
2390 continue; 2390 goto next;
2391 } 2391 }
2392 ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate); 2392 ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
2393next:
2393 prev = sdata; 2394 prev = sdata;
2394 } 2395 }
2396
2397 if (prev) {
2398 rx.sta = sta_info_get_bss(prev, hdr->addr2);
2399
2400 rx.flags |= IEEE80211_RX_RA_MATCH;
2401 prepares = prepare_for_handlers(prev, &rx, hdr);
2402
2403 if (!prepares)
2404 prev = NULL;
2405 }
2395 } 2406 }
2396 if (prev) 2407 if (prev)
2397 ieee80211_invoke_rx_handlers(prev, &rx, skb, rate); 2408 ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 9afe2f9885dc..bc061f629674 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -111,10 +111,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
111 bss->dtim_period = tim_ie->dtim_period; 111 bss->dtim_period = tim_ie->dtim_period;
112 } 112 }
113 113
114 /* set default value for buggy AP/no TIM element */
115 if (bss->dtim_period == 0)
116 bss->dtim_period = 1;
117
118 bss->supp_rates_len = 0; 114 bss->supp_rates_len = 0;
119 if (elems->supp_rates) { 115 if (elems->supp_rates) {
120 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; 116 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 0ebcdda24200..e57ad6b1d7ea 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -45,29 +45,19 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
45 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 45 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
46 46
47 /* 47 /*
48 * XXX: This is temporary! 48 * This skb 'survived' a round-trip through the driver, and
49 * 49 * hopefully the driver didn't mangle it too badly. However,
50 * The problem here is that when we get here, the driver will 50 * we can definitely not rely on the the control information
51 * quite likely have pretty much overwritten info->control by 51 * being correct. Clear it so we don't get junk there, and
52 * using info->driver_data or info->rate_driver_data. Thus, 52 * indicate that it needs new processing, but must not be
53 * when passing out the frame to the driver again, we would be 53 * modified/encrypted again.
54 * passing completely bogus data since the driver would then
55 * expect a properly filled info->control. In mac80211 itself
56 * the same problem occurs, since we need info->control.vif
57 * internally.
58 *
59 * To fix this, we should send the frame through TX processing
60 * again. However, it's not that simple, since the frame will
61 * have been software-encrypted (if applicable) already, and
62 * encrypting it again doesn't do much good. So to properly do
63 * that, we not only have to skip the actual 'raw' encryption
64 * (key selection etc. still has to be done!) but also the
65 * sequence number assignment since that impacts the crypto
66 * encapsulation, of course.
67 *
68 * Hence, for now, fix the bug by just dropping the frame.
69 */ 54 */
70 goto drop; 55 memset(&info->control, 0, sizeof(info->control));
56
57 info->control.jiffies = jiffies;
58 info->control.vif = &sta->sdata->vif;
59 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING |
60 IEEE80211_TX_INTFL_RETRANSMISSION;
71 61
72 sta->tx_filtered_count++; 62 sta->tx_filtered_count++;
73 63
@@ -122,7 +112,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
122 return; 112 return;
123 } 113 }
124 114
125 drop:
126#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 115#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
127 if (net_ratelimit()) 116 if (net_ratelimit())
128 printk(KERN_DEBUG "%s: dropped TX filtered frame, " 117 printk(KERN_DEBUG "%s: dropped TX filtered frame, "
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index b73454a507f9..7ef491e9d66d 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -195,11 +195,13 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
195} 195}
196EXPORT_SYMBOL(ieee80211_get_tkip_key); 196EXPORT_SYMBOL(ieee80211_get_tkip_key);
197 197
198/* Encrypt packet payload with TKIP using @key. @pos is a pointer to the 198/*
199 * Encrypt packet payload with TKIP using @key. @pos is a pointer to the
199 * beginning of the buffer containing payload. This payload must include 200 * beginning of the buffer containing payload. This payload must include
200 * headroom of eight octets for IV and Ext. IV and taildroom of four octets 201 * the IV/Ext.IV and space for (taildroom) four octets for ICV.
201 * for ICV. @payload_len is the length of payload (_not_ including extra 202 * @payload_len is the length of payload (_not_ including IV/ICV length).
202 * headroom and tailroom). @ta is the transmitter addresses. */ 203 * @ta is the transmitter addresses.
204 */
203void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, 205void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
204 struct ieee80211_key *key, 206 struct ieee80211_key *key,
205 u8 *pos, size_t payload_len, u8 *ta) 207 u8 *pos, size_t payload_len, u8 *ta)
@@ -214,7 +216,6 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
214 216
215 tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); 217 tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
216 218
217 pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
218 ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); 219 ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
219} 220}
220 221
@@ -303,14 +304,12 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
303 if (key->local->ops->update_tkip_key && 304 if (key->local->ops->update_tkip_key &&
304 key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && 305 key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
305 key->u.tkip.rx[queue].state != TKIP_STATE_PHASE1_HW_UPLOADED) { 306 key->u.tkip.rx[queue].state != TKIP_STATE_PHASE1_HW_UPLOADED) {
306 static const u8 bcast[ETH_ALEN] = 307 struct ieee80211_sub_if_data *sdata = key->sdata;
307 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
308 const u8 *sta_addr = key->sta->sta.addr;
309
310 if (is_multicast_ether_addr(ra))
311 sta_addr = bcast;
312 308
313 drv_update_tkip_key(key->local, &key->conf, sta_addr, 309 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
310 sdata = container_of(key->sdata->bss,
311 struct ieee80211_sub_if_data, u.ap);
312 drv_update_tkip_key(key->local, sdata, &key->conf, key->sta,
314 iv32, key->u.tkip.rx[queue].p1k); 313 iv32, key->u.tkip.rx[queue].p1k);
315 key->u.tkip.rx[queue].state = TKIP_STATE_PHASE1_HW_UPLOADED; 314 key->u.tkip.rx[queue].state = TKIP_STATE_PHASE1_HW_UPLOADED;
316 } 315 }
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index daf81048c1f7..85e382aa894e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -529,6 +529,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
529 tx->key = NULL; 529 tx->key = NULL;
530 530
531 if (tx->key) { 531 if (tx->key) {
532 bool skip_hw = false;
533
532 tx->key->tx_rx_count++; 534 tx->key->tx_rx_count++;
533 /* TODO: add threshold stuff again */ 535 /* TODO: add threshold stuff again */
534 536
@@ -545,16 +547,32 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
545 !ieee80211_use_mfp(hdr->frame_control, tx->sta, 547 !ieee80211_use_mfp(hdr->frame_control, tx->sta,
546 tx->skb)) 548 tx->skb))
547 tx->key = NULL; 549 tx->key = NULL;
550 else
551 skip_hw = (tx->key->conf.flags &
552 IEEE80211_KEY_FLAG_SW_MGMT) &&
553 ieee80211_is_mgmt(hdr->frame_control);
548 break; 554 break;
549 case ALG_AES_CMAC: 555 case ALG_AES_CMAC:
550 if (!ieee80211_is_mgmt(hdr->frame_control)) 556 if (!ieee80211_is_mgmt(hdr->frame_control))
551 tx->key = NULL; 557 tx->key = NULL;
552 break; 558 break;
553 } 559 }
560
561 if (!skip_hw && tx->key &&
562 tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
563 info->control.hw_key = &tx->key->conf;
554 } 564 }
555 565
556 if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) 566 return TX_CONTINUE;
557 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 567}
568
569static ieee80211_tx_result debug_noinline
570ieee80211_tx_h_sta(struct ieee80211_tx_data *tx)
571{
572 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
573
574 if (tx->sta)
575 info->control.sta = &tx->sta->sta;
558 576
559 return TX_CONTINUE; 577 return TX_CONTINUE;
560} 578}
@@ -734,17 +752,6 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
734} 752}
735 753
736static ieee80211_tx_result debug_noinline 754static ieee80211_tx_result debug_noinline
737ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
738{
739 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
740
741 if (tx->sta)
742 info->control.sta = &tx->sta->sta;
743
744 return TX_CONTINUE;
745}
746
747static ieee80211_tx_result debug_noinline
748ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) 755ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
749{ 756{
750 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 757 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
@@ -1101,7 +1108,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1101 tx->flags |= IEEE80211_TX_FRAGMENTED; 1108 tx->flags |= IEEE80211_TX_FRAGMENTED;
1102 1109
1103 /* process and remove the injection radiotap header */ 1110 /* process and remove the injection radiotap header */
1104 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { 1111 if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) {
1105 if (!__ieee80211_parse_tx_radiotap(tx, skb)) 1112 if (!__ieee80211_parse_tx_radiotap(tx, skb))
1106 return TX_DROP; 1113 return TX_DROP;
1107 1114
@@ -1110,6 +1117,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1110 * the radiotap header that was present and pre-filled 1117 * the radiotap header that was present and pre-filled
1111 * 'tx' with tx control information. 1118 * 'tx' with tx control information.
1112 */ 1119 */
1120 info->flags &= ~IEEE80211_TX_INTFL_HAS_RADIOTAP;
1113 } 1121 }
1114 1122
1115 /* 1123 /*
@@ -1125,6 +1133,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1125 tx->sta = rcu_dereference(sdata->u.vlan.sta); 1133 tx->sta = rcu_dereference(sdata->u.vlan.sta);
1126 if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) 1134 if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
1127 return TX_DROP; 1135 return TX_DROP;
1136 } else if (info->flags & IEEE80211_TX_CTL_INJECTED) {
1137 tx->sta = sta_info_get_bss(sdata, hdr->addr1);
1128 } 1138 }
1129 if (!tx->sta) 1139 if (!tx->sta)
1130 tx->sta = sta_info_get(sdata, hdr->addr1); 1140 tx->sta = sta_info_get(sdata, hdr->addr1);
@@ -1279,6 +1289,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1279static int invoke_tx_handlers(struct ieee80211_tx_data *tx) 1289static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1280{ 1290{
1281 struct sk_buff *skb = tx->skb; 1291 struct sk_buff *skb = tx->skb;
1292 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1282 ieee80211_tx_result res = TX_DROP; 1293 ieee80211_tx_result res = TX_DROP;
1283 1294
1284#define CALL_TXH(txh) \ 1295#define CALL_TXH(txh) \
@@ -1292,10 +1303,14 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1292 CALL_TXH(ieee80211_tx_h_check_assoc); 1303 CALL_TXH(ieee80211_tx_h_check_assoc);
1293 CALL_TXH(ieee80211_tx_h_ps_buf); 1304 CALL_TXH(ieee80211_tx_h_ps_buf);
1294 CALL_TXH(ieee80211_tx_h_select_key); 1305 CALL_TXH(ieee80211_tx_h_select_key);
1295 CALL_TXH(ieee80211_tx_h_michael_mic_add); 1306 CALL_TXH(ieee80211_tx_h_sta);
1296 if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) 1307 if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
1297 CALL_TXH(ieee80211_tx_h_rate_ctrl); 1308 CALL_TXH(ieee80211_tx_h_rate_ctrl);
1298 CALL_TXH(ieee80211_tx_h_misc); 1309
1310 if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION))
1311 goto txh_done;
1312
1313 CALL_TXH(ieee80211_tx_h_michael_mic_add);
1299 CALL_TXH(ieee80211_tx_h_sequence); 1314 CALL_TXH(ieee80211_tx_h_sequence);
1300 CALL_TXH(ieee80211_tx_h_fragment); 1315 CALL_TXH(ieee80211_tx_h_fragment);
1301 /* handlers after fragment must be aware of tx info fragmentation! */ 1316 /* handlers after fragment must be aware of tx info fragmentation! */
@@ -1487,7 +1502,8 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1487 int hdrlen; 1502 int hdrlen;
1488 u16 len_rthdr; 1503 u16 len_rthdr;
1489 1504
1490 info->flags |= IEEE80211_TX_CTL_INJECTED; 1505 info->flags |= IEEE80211_TX_CTL_INJECTED |
1506 IEEE80211_TX_INTFL_HAS_RADIOTAP;
1491 1507
1492 len_rthdr = ieee80211_get_radiotap_len(skb->data); 1508 len_rthdr = ieee80211_get_radiotap_len(skb->data);
1493 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); 1509 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 247123fe1a7a..5d745f2d7236 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -305,20 +305,19 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
305{ 305{
306 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 306 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
307 307
308 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { 308 if (!info->control.hw_key) {
309 if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, 309 if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key,
310 tx->key->conf.keylen, 310 tx->key->conf.keylen,
311 tx->key->conf.keyidx)) 311 tx->key->conf.keyidx))
312 return -1; 312 return -1;
313 } else { 313 } else if (info->control.hw_key->flags &
314 info->control.hw_key = &tx->key->conf; 314 IEEE80211_KEY_FLAG_GENERATE_IV) {
315 if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { 315 if (!ieee80211_wep_add_iv(tx->local, skb,
316 if (!ieee80211_wep_add_iv(tx->local, skb, 316 tx->key->conf.keylen,
317 tx->key->conf.keylen, 317 tx->key->conf.keyidx))
318 tx->key->conf.keyidx)) 318 return -1;
319 return -1;
320 }
321 } 319 }
320
322 return 0; 321 return 0;
323} 322}
324 323
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 81bd5d592bb4..7e708d5c88b4 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -535,8 +535,7 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
535 * First time we run, do nothing -- the generic code will 535 * First time we run, do nothing -- the generic code will
536 * have switched to the right channel etc. 536 * have switched to the right channel etc.
537 */ 537 */
538 if (!wk->remain.started) { 538 if (!wk->started) {
539 wk->remain.started = true;
540 wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration); 539 wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration);
541 540
542 cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk, 541 cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk,
@@ -821,15 +820,17 @@ static void ieee80211_work_work(struct work_struct *work)
821 mutex_lock(&local->work_mtx); 820 mutex_lock(&local->work_mtx);
822 821
823 list_for_each_entry_safe(wk, tmp, &local->work_list, list) { 822 list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
823 bool started = wk->started;
824
824 /* mark work as started if it's on the current off-channel */ 825 /* mark work as started if it's on the current off-channel */
825 if (!wk->started && local->tmp_channel && 826 if (!started && local->tmp_channel &&
826 wk->chan == local->tmp_channel && 827 wk->chan == local->tmp_channel &&
827 wk->chan_type == local->tmp_channel_type) { 828 wk->chan_type == local->tmp_channel_type) {
828 wk->started = true; 829 started = true;
829 wk->timeout = jiffies; 830 wk->timeout = jiffies;
830 } 831 }
831 832
832 if (!wk->started && !local->tmp_channel) { 833 if (!started && !local->tmp_channel) {
833 /* 834 /*
834 * TODO: could optimize this by leaving the 835 * TODO: could optimize this by leaving the
835 * station vifs in awake mode if they 836 * station vifs in awake mode if they
@@ -842,12 +843,12 @@ static void ieee80211_work_work(struct work_struct *work)
842 local->tmp_channel = wk->chan; 843 local->tmp_channel = wk->chan;
843 local->tmp_channel_type = wk->chan_type; 844 local->tmp_channel_type = wk->chan_type;
844 ieee80211_hw_config(local, 0); 845 ieee80211_hw_config(local, 0);
845 wk->started = true; 846 started = true;
846 wk->timeout = jiffies; 847 wk->timeout = jiffies;
847 } 848 }
848 849
849 /* don't try to work with items that aren't started */ 850 /* don't try to work with items that aren't started */
850 if (!wk->started) 851 if (!started)
851 continue; 852 continue;
852 853
853 if (time_is_after_jiffies(wk->timeout)) { 854 if (time_is_after_jiffies(wk->timeout)) {
@@ -882,6 +883,8 @@ static void ieee80211_work_work(struct work_struct *work)
882 break; 883 break;
883 } 884 }
884 885
886 wk->started = started;
887
885 switch (rma) { 888 switch (rma) {
886 case WORK_ACT_NONE: 889 case WORK_ACT_NONE:
887 /* might have changed the timeout */ 890 /* might have changed the timeout */
@@ -1022,8 +1025,6 @@ ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1022 case IEEE80211_STYPE_PROBE_RESP: 1025 case IEEE80211_STYPE_PROBE_RESP:
1023 case IEEE80211_STYPE_ASSOC_RESP: 1026 case IEEE80211_STYPE_ASSOC_RESP:
1024 case IEEE80211_STYPE_REASSOC_RESP: 1027 case IEEE80211_STYPE_REASSOC_RESP:
1025 case IEEE80211_STYPE_DEAUTH:
1026 case IEEE80211_STYPE_DISASSOC:
1027 skb_queue_tail(&local->work_skb_queue, skb); 1028 skb_queue_tail(&local->work_skb_queue, skb);
1028 ieee80211_queue_work(&local->hw, &local->work_work); 1029 ieee80211_queue_work(&local->hw, &local->work_work);
1029 return RX_QUEUED; 1030 return RX_QUEUED;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 5332014cb229..f4971cd45c64 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -31,8 +31,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
31 unsigned int hdrlen; 31 unsigned int hdrlen;
32 struct ieee80211_hdr *hdr; 32 struct ieee80211_hdr *hdr;
33 struct sk_buff *skb = tx->skb; 33 struct sk_buff *skb = tx->skb;
34 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
34 int authenticator; 35 int authenticator;
35 int wpa_test = 0;
36 int tail; 36 int tail;
37 37
38 hdr = (struct ieee80211_hdr *)skb->data; 38 hdr = (struct ieee80211_hdr *)skb->data;
@@ -47,16 +47,15 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
47 data = skb->data + hdrlen; 47 data = skb->data + hdrlen;
48 data_len = skb->len - hdrlen; 48 data_len = skb->len - hdrlen;
49 49
50 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 50 if (info->control.hw_key &&
51 !(tx->flags & IEEE80211_TX_FRAGMENTED) && 51 !(tx->flags & IEEE80211_TX_FRAGMENTED) &&
52 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && 52 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
53 !wpa_test) { 53 /* hwaccel - with no need for SW-generated MMIC */
54 /* hwaccel - with no need for preallocated room for MMIC */
55 return TX_CONTINUE; 54 return TX_CONTINUE;
56 } 55 }
57 56
58 tail = MICHAEL_MIC_LEN; 57 tail = MICHAEL_MIC_LEN;
59 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) 58 if (!info->control.hw_key)
60 tail += TKIP_ICV_LEN; 59 tail += TKIP_ICV_LEN;
61 60
62 if (WARN_ON(skb_tailroom(skb) < tail || 61 if (WARN_ON(skb_tailroom(skb) < tail ||
@@ -147,17 +146,16 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
147 int len, tail; 146 int len, tail;
148 u8 *pos; 147 u8 *pos;
149 148
150 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 149 if (info->control.hw_key &&
151 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { 150 !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
152 /* hwaccel - with no need for preallocated room for IV/ICV */ 151 /* hwaccel - with no need for software-generated IV */
153 info->control.hw_key = &tx->key->conf;
154 return 0; 152 return 0;
155 } 153 }
156 154
157 hdrlen = ieee80211_hdrlen(hdr->frame_control); 155 hdrlen = ieee80211_hdrlen(hdr->frame_control);
158 len = skb->len - hdrlen; 156 len = skb->len - hdrlen;
159 157
160 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 158 if (info->control.hw_key)
161 tail = 0; 159 tail = 0;
162 else 160 else
163 tail = TKIP_ICV_LEN; 161 tail = TKIP_ICV_LEN;
@@ -175,13 +173,11 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
175 if (key->u.tkip.tx.iv16 == 0) 173 if (key->u.tkip.tx.iv16 == 0)
176 key->u.tkip.tx.iv32++; 174 key->u.tkip.tx.iv32++;
177 175
178 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 176 pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
179 /* hwaccel - with preallocated room for IV */
180 ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
181 177
182 info->control.hw_key = &tx->key->conf; 178 /* hwaccel - with software IV */
179 if (info->control.hw_key)
183 return 0; 180 return 0;
184 }
185 181
186 /* Add room for ICV */ 182 /* Add room for ICV */
187 skb_put(skb, TKIP_ICV_LEN); 183 skb_put(skb, TKIP_ICV_LEN);
@@ -363,24 +359,20 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
363 int hdrlen, len, tail; 359 int hdrlen, len, tail;
364 u8 *pos, *pn; 360 u8 *pos, *pn;
365 int i; 361 int i;
366 bool skip_hw;
367
368 skip_hw = (tx->key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT) &&
369 ieee80211_is_mgmt(hdr->frame_control);
370 362
371 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 363 if (info->control.hw_key &&
372 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) && 364 !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
373 !skip_hw) { 365 /*
374 /* hwaccel - with no need for preallocated room for CCMP 366 * hwaccel has no need for preallocated room for CCMP
375 * header or MIC fields */ 367 * header or MIC fields
376 info->control.hw_key = &tx->key->conf; 368 */
377 return 0; 369 return 0;
378 } 370 }
379 371
380 hdrlen = ieee80211_hdrlen(hdr->frame_control); 372 hdrlen = ieee80211_hdrlen(hdr->frame_control);
381 len = skb->len - hdrlen; 373 len = skb->len - hdrlen;
382 374
383 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 375 if (info->control.hw_key)
384 tail = 0; 376 tail = 0;
385 else 377 else
386 tail = CCMP_MIC_LEN; 378 tail = CCMP_MIC_LEN;
@@ -405,11 +397,9 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
405 397
406 ccmp_pn2hdr(pos, pn, key->conf.keyidx); 398 ccmp_pn2hdr(pos, pn, key->conf.keyidx);
407 399
408 if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) { 400 /* hwaccel - with software CCMP header */
409 /* hwaccel - with preallocated room for CCMP header */ 401 if (info->control.hw_key)
410 info->control.hw_key = &tx->key->conf;
411 return 0; 402 return 0;
412 }
413 403
414 pos += CCMP_HDR_LEN; 404 pos += CCMP_HDR_LEN;
415 ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); 405 ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0);
@@ -525,11 +515,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
525 u8 *pn, aad[20]; 515 u8 *pn, aad[20];
526 int i; 516 int i;
527 517
528 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 518 if (info->control.hw_key)
529 /* hwaccel */
530 info->control.hw_key = &tx->key->conf;
531 return 0; 519 return 0;
532 }
533 520
534 if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) 521 if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
535 return TX_DROP; 522 return TX_DROP;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 20db90246de5..71b6b3a9cf1f 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This is the linux wireless configuration interface. 2 * This is the linux wireless configuration interface.
3 * 3 *
4 * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6 6
7#include <linux/if.h> 7#include <linux/if.h>
@@ -31,15 +31,10 @@ MODULE_AUTHOR("Johannes Berg");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_DESCRIPTION("wireless configuration support"); 32MODULE_DESCRIPTION("wireless configuration support");
33 33
34/* RCU might be appropriate here since we usually 34/* RCU-protected (and cfg80211_mutex for writers) */
35 * only read the list, and that can happen quite
36 * often because we need to do it for each command */
37LIST_HEAD(cfg80211_rdev_list); 35LIST_HEAD(cfg80211_rdev_list);
38int cfg80211_rdev_list_generation; 36int cfg80211_rdev_list_generation;
39 37
40/*
41 * This is used to protect the cfg80211_rdev_list
42 */
43DEFINE_MUTEX(cfg80211_mutex); 38DEFINE_MUTEX(cfg80211_mutex);
44 39
45/* for debugfs */ 40/* for debugfs */
@@ -418,6 +413,18 @@ int wiphy_register(struct wiphy *wiphy)
418 int i; 413 int i;
419 u16 ifmodes = wiphy->interface_modes; 414 u16 ifmodes = wiphy->interface_modes;
420 415
416 if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
417 return -EINVAL;
418
419 if (WARN_ON(wiphy->addresses &&
420 !is_zero_ether_addr(wiphy->perm_addr) &&
421 memcmp(wiphy->perm_addr, wiphy->addresses[0].addr,
422 ETH_ALEN)))
423 return -EINVAL;
424
425 if (wiphy->addresses)
426 memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);
427
421 /* sanity check ifmodes */ 428 /* sanity check ifmodes */
422 WARN_ON(!ifmodes); 429 WARN_ON(!ifmodes);
423 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; 430 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
@@ -477,7 +484,7 @@ int wiphy_register(struct wiphy *wiphy)
477 /* set up regulatory info */ 484 /* set up regulatory info */
478 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); 485 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
479 486
480 list_add(&rdev->list, &cfg80211_rdev_list); 487 list_add_rcu(&rdev->list, &cfg80211_rdev_list);
481 cfg80211_rdev_list_generation++; 488 cfg80211_rdev_list_generation++;
482 489
483 mutex_unlock(&cfg80211_mutex); 490 mutex_unlock(&cfg80211_mutex);
@@ -554,7 +561,8 @@ void wiphy_unregister(struct wiphy *wiphy)
554 * it impossible to find from userspace. 561 * it impossible to find from userspace.
555 */ 562 */
556 debugfs_remove_recursive(rdev->wiphy.debugfsdir); 563 debugfs_remove_recursive(rdev->wiphy.debugfsdir);
557 list_del(&rdev->list); 564 list_del_rcu(&rdev->list);
565 synchronize_rcu();
558 566
559 /* 567 /*
560 * Try to grab rdev->mtx. If a command is still in progress, 568 * Try to grab rdev->mtx. If a command is still in progress,
@@ -670,7 +678,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
670 INIT_LIST_HEAD(&wdev->event_list); 678 INIT_LIST_HEAD(&wdev->event_list);
671 spin_lock_init(&wdev->event_lock); 679 spin_lock_init(&wdev->event_lock);
672 mutex_lock(&rdev->devlist_mtx); 680 mutex_lock(&rdev->devlist_mtx);
673 list_add(&wdev->list, &rdev->netdev_list); 681 list_add_rcu(&wdev->list, &rdev->netdev_list);
674 rdev->devlist_generation++; 682 rdev->devlist_generation++;
675 /* can only change netns with wiphy */ 683 /* can only change netns with wiphy */
676 dev->features |= NETIF_F_NETNS_LOCAL; 684 dev->features |= NETIF_F_NETNS_LOCAL;
@@ -782,13 +790,21 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
782 */ 790 */
783 if (!list_empty(&wdev->list)) { 791 if (!list_empty(&wdev->list)) {
784 sysfs_remove_link(&dev->dev.kobj, "phy80211"); 792 sysfs_remove_link(&dev->dev.kobj, "phy80211");
785 list_del_init(&wdev->list); 793 list_del_rcu(&wdev->list);
786 rdev->devlist_generation++; 794 rdev->devlist_generation++;
787#ifdef CONFIG_CFG80211_WEXT 795#ifdef CONFIG_CFG80211_WEXT
788 kfree(wdev->wext.keys); 796 kfree(wdev->wext.keys);
789#endif 797#endif
790 } 798 }
791 mutex_unlock(&rdev->devlist_mtx); 799 mutex_unlock(&rdev->devlist_mtx);
800 /*
801 * synchronise (so that we won't find this netdev
802 * from other code any more) and then clear the list
803 * head so that the above code can safely check for
804 * !list_empty() to avoid double-cleanup.
805 */
806 synchronize_rcu();
807 INIT_LIST_HEAD(&wdev->list);
792 break; 808 break;
793 case NETDEV_PRE_UP: 809 case NETDEV_PRE_UP:
794 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) 810 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 2d6a6b9c0c43..c326a667022a 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Wireless configuration interface internals. 2 * Wireless configuration interface internals.
3 * 3 *
4 * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6#ifndef __NET_WIRELESS_CORE_H 6#ifndef __NET_WIRELESS_CORE_H
7#define __NET_WIRELESS_CORE_H 7#define __NET_WIRELESS_CORE_H
@@ -48,6 +48,7 @@ struct cfg80211_registered_device {
48 48
49 /* associate netdev list */ 49 /* associate netdev list */
50 struct mutex devlist_mtx; 50 struct mutex devlist_mtx;
51 /* protected by devlist_mtx or RCU */
51 struct list_head netdev_list; 52 struct list_head netdev_list;
52 int devlist_generation; 53 int devlist_generation;
53 int opencount; /* also protected by devlist_mtx */ 54 int opencount; /* also protected by devlist_mtx */
diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c
index 2301dc1edc4c..b7fa31d5fd13 100644
--- a/net/wireless/lib80211_crypt_ccmp.c
+++ b/net/wireless/lib80211_crypt_ccmp.c
@@ -237,7 +237,6 @@ static int lib80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
237 return -1; 237 return -1;
238 238
239 pos = skb->data + hdr_len + CCMP_HDR_LEN; 239 pos = skb->data + hdr_len + CCMP_HDR_LEN;
240 mic = skb_put(skb, CCMP_MIC_LEN);
241 hdr = (struct ieee80211_hdr *)skb->data; 240 hdr = (struct ieee80211_hdr *)skb->data;
242 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); 241 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
243 242
@@ -257,6 +256,7 @@ static int lib80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
257 pos += len; 256 pos += len;
258 } 257 }
259 258
259 mic = skb_put(skb, CCMP_MIC_LEN);
260 for (i = 0; i < CCMP_MIC_LEN; i++) 260 for (i = 0; i < CCMP_MIC_LEN; i++)
261 mic[i] = b[i] ^ s0[i]; 261 mic[i] = b[i] ^ s0[i];
262 262
diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c
index c36287399d7e..8cbdb32ff316 100644
--- a/net/wireless/lib80211_crypt_tkip.c
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -36,6 +36,8 @@ MODULE_AUTHOR("Jouni Malinen");
36MODULE_DESCRIPTION("lib80211 crypt: TKIP"); 36MODULE_DESCRIPTION("lib80211 crypt: TKIP");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38 38
39#define TKIP_HDR_LEN 8
40
39struct lib80211_tkip_data { 41struct lib80211_tkip_data {
40#define TKIP_KEY_LEN 32 42#define TKIP_KEY_LEN 32
41 u8 key[TKIP_KEY_LEN]; 43 u8 key[TKIP_KEY_LEN];
@@ -314,13 +316,12 @@ static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
314 u8 * rc4key, int keylen, void *priv) 316 u8 * rc4key, int keylen, void *priv)
315{ 317{
316 struct lib80211_tkip_data *tkey = priv; 318 struct lib80211_tkip_data *tkey = priv;
317 int len;
318 u8 *pos; 319 u8 *pos;
319 struct ieee80211_hdr *hdr; 320 struct ieee80211_hdr *hdr;
320 321
321 hdr = (struct ieee80211_hdr *)skb->data; 322 hdr = (struct ieee80211_hdr *)skb->data;
322 323
323 if (skb_headroom(skb) < 8 || skb->len < hdr_len) 324 if (skb_headroom(skb) < TKIP_HDR_LEN || skb->len < hdr_len)
324 return -1; 325 return -1;
325 326
326 if (rc4key == NULL || keylen < 16) 327 if (rc4key == NULL || keylen < 16)
@@ -333,9 +334,8 @@ static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
333 } 334 }
334 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); 335 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
335 336
336 len = skb->len - hdr_len; 337 pos = skb_push(skb, TKIP_HDR_LEN);
337 pos = skb_push(skb, 8); 338 memmove(pos, pos + TKIP_HDR_LEN, hdr_len);
338 memmove(pos, pos + 8, hdr_len);
339 pos += hdr_len; 339 pos += hdr_len;
340 340
341 *pos++ = *rc4key; 341 *pos++ = *rc4key;
@@ -353,7 +353,7 @@ static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
353 tkey->tx_iv32++; 353 tkey->tx_iv32++;
354 } 354 }
355 355
356 return 8; 356 return TKIP_HDR_LEN;
357} 357}
358 358
359static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 359static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
@@ -384,9 +384,8 @@ static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
384 if ((lib80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0) 384 if ((lib80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
385 return -1; 385 return -1;
386 386
387 icv = skb_put(skb, 4);
388
389 crc = ~crc32_le(~0, pos, len); 387 crc = ~crc32_le(~0, pos, len);
388 icv = skb_put(skb, 4);
390 icv[0] = crc; 389 icv[0] = crc;
391 icv[1] = crc >> 8; 390 icv[1] = crc >> 8;
392 icv[2] = crc >> 16; 391 icv[2] = crc >> 16;
@@ -434,7 +433,7 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
434 return -1; 433 return -1;
435 } 434 }
436 435
437 if (skb->len < hdr_len + 8 + 4) 436 if (skb->len < hdr_len + TKIP_HDR_LEN + 4)
438 return -1; 437 return -1;
439 438
440 pos = skb->data + hdr_len; 439 pos = skb->data + hdr_len;
@@ -462,7 +461,7 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
462 } 461 }
463 iv16 = (pos[0] << 8) | pos[2]; 462 iv16 = (pos[0] << 8) | pos[2];
464 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); 463 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
465 pos += 8; 464 pos += TKIP_HDR_LEN;
466 465
467 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { 466 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
468#ifdef CONFIG_LIB80211_DEBUG 467#ifdef CONFIG_LIB80211_DEBUG
@@ -523,8 +522,8 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
523 tkey->rx_iv16_new = iv16; 522 tkey->rx_iv16_new = iv16;
524 523
525 /* Remove IV and ICV */ 524 /* Remove IV and ICV */
526 memmove(skb->data + 8, skb->data, hdr_len); 525 memmove(skb->data + TKIP_HDR_LEN, skb->data, hdr_len);
527 skb_pull(skb, 8); 526 skb_pull(skb, TKIP_HDR_LEN);
528 skb_trim(skb, skb->len - 4); 527 skb_trim(skb, skb->len - 4);
529 528
530 return keyidx; 529 return keyidx;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4af7991a9ec8..5b79ecf17bea 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3571,6 +3571,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3571{ 3571{
3572 struct cfg80211_registered_device *rdev; 3572 struct cfg80211_registered_device *rdev;
3573 struct net_device *dev; 3573 struct net_device *dev;
3574 struct wireless_dev *wdev;
3574 struct cfg80211_crypto_settings crypto; 3575 struct cfg80211_crypto_settings crypto;
3575 struct ieee80211_channel *chan, *fixedchan; 3576 struct ieee80211_channel *chan, *fixedchan;
3576 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; 3577 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
@@ -3616,7 +3617,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3616 } 3617 }
3617 3618
3618 mutex_lock(&rdev->devlist_mtx); 3619 mutex_lock(&rdev->devlist_mtx);
3619 fixedchan = rdev_fixed_channel(rdev, NULL); 3620 wdev = dev->ieee80211_ptr;
3621 fixedchan = rdev_fixed_channel(rdev, wdev);
3620 if (fixedchan && chan != fixedchan) { 3622 if (fixedchan && chan != fixedchan) {
3621 err = -EBUSY; 3623 err = -EBUSY;
3622 mutex_unlock(&rdev->devlist_mtx); 3624 mutex_unlock(&rdev->devlist_mtx);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 5f8071de7950..ed89c59bb431 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -134,6 +134,7 @@ static const struct ieee80211_regdomain *cfg80211_world_regdom =
134 &world_regdom; 134 &world_regdom;
135 135
136static char *ieee80211_regdom = "00"; 136static char *ieee80211_regdom = "00";
137static char user_alpha2[2];
137 138
138module_param(ieee80211_regdom, charp, 0444); 139module_param(ieee80211_regdom, charp, 0444);
139MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 140MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
@@ -252,6 +253,27 @@ static bool regdom_changes(const char *alpha2)
252 return true; 253 return true;
253} 254}
254 255
256/*
257 * The NL80211_REGDOM_SET_BY_USER regdom alpha2 is cached, this lets
258 * you know if a valid regulatory hint with NL80211_REGDOM_SET_BY_USER
259 * has ever been issued.
260 */
261static bool is_user_regdom_saved(void)
262{
263 if (user_alpha2[0] == '9' && user_alpha2[1] == '7')
264 return false;
265
266 /* This would indicate a mistake on the design */
267 if (WARN((!is_world_regdom(user_alpha2) &&
268 !is_an_alpha2(user_alpha2)),
269 "Unexpected user alpha2: %c%c\n",
270 user_alpha2[0],
271 user_alpha2[1]))
272 return false;
273
274 return true;
275}
276
255/** 277/**
256 * country_ie_integrity_changes - tells us if the country IE has changed 278 * country_ie_integrity_changes - tells us if the country IE has changed
257 * @checksum: checksum of country IE of fields we are interested in 279 * @checksum: checksum of country IE of fields we are interested in
@@ -1646,7 +1668,7 @@ static int ignore_request(struct wiphy *wiphy,
1646 1668
1647 switch (pending_request->initiator) { 1669 switch (pending_request->initiator) {
1648 case NL80211_REGDOM_SET_BY_CORE: 1670 case NL80211_REGDOM_SET_BY_CORE:
1649 return -EINVAL; 1671 return 0;
1650 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 1672 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
1651 1673
1652 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 1674 last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
@@ -1785,6 +1807,11 @@ new_request:
1785 1807
1786 pending_request = NULL; 1808 pending_request = NULL;
1787 1809
1810 if (last_request->initiator == NL80211_REGDOM_SET_BY_USER) {
1811 user_alpha2[0] = last_request->alpha2[0];
1812 user_alpha2[1] = last_request->alpha2[1];
1813 }
1814
1788 /* When r == REG_INTERSECT we do need to call CRDA */ 1815 /* When r == REG_INTERSECT we do need to call CRDA */
1789 if (r < 0) { 1816 if (r < 0) {
1790 /* 1817 /*
@@ -1904,12 +1931,16 @@ static void queue_regulatory_request(struct regulatory_request *request)
1904 schedule_work(&reg_work); 1931 schedule_work(&reg_work);
1905} 1932}
1906 1933
1907/* Core regulatory hint -- happens once during cfg80211_init() */ 1934/*
1935 * Core regulatory hint -- happens during cfg80211_init()
1936 * and when we restore regulatory settings.
1937 */
1908static int regulatory_hint_core(const char *alpha2) 1938static int regulatory_hint_core(const char *alpha2)
1909{ 1939{
1910 struct regulatory_request *request; 1940 struct regulatory_request *request;
1911 1941
1912 BUG_ON(last_request); 1942 kfree(last_request);
1943 last_request = NULL;
1913 1944
1914 request = kzalloc(sizeof(struct regulatory_request), 1945 request = kzalloc(sizeof(struct regulatory_request),
1915 GFP_KERNEL); 1946 GFP_KERNEL);
@@ -1920,14 +1951,12 @@ static int regulatory_hint_core(const char *alpha2)
1920 request->alpha2[1] = alpha2[1]; 1951 request->alpha2[1] = alpha2[1];
1921 request->initiator = NL80211_REGDOM_SET_BY_CORE; 1952 request->initiator = NL80211_REGDOM_SET_BY_CORE;
1922 1953
1923 queue_regulatory_request(request);
1924
1925 /* 1954 /*
1926 * This ensures last_request is populated once modules 1955 * This ensures last_request is populated once modules
1927 * come swinging in and calling regulatory hints and 1956 * come swinging in and calling regulatory hints and
1928 * wiphy_apply_custom_regulatory(). 1957 * wiphy_apply_custom_regulatory().
1929 */ 1958 */
1930 flush_scheduled_work(); 1959 reg_process_hint(request);
1931 1960
1932 return 0; 1961 return 0;
1933} 1962}
@@ -2109,6 +2138,123 @@ out:
2109 mutex_unlock(&reg_mutex); 2138 mutex_unlock(&reg_mutex);
2110} 2139}
2111 2140
2141static void restore_alpha2(char *alpha2, bool reset_user)
2142{
2143 /* indicates there is no alpha2 to consider for restoration */
2144 alpha2[0] = '9';
2145 alpha2[1] = '7';
2146
2147 /* The user setting has precedence over the module parameter */
2148 if (is_user_regdom_saved()) {
2149 /* Unless we're asked to ignore it and reset it */
2150 if (reset_user) {
2151 REG_DBG_PRINT("cfg80211: Restoring regulatory settings "
2152 "including user preference\n");
2153 user_alpha2[0] = '9';
2154 user_alpha2[1] = '7';
2155
2156 /*
2157 * If we're ignoring user settings, we still need to
2158 * check the module parameter to ensure we put things
2159 * back as they were for a full restore.
2160 */
2161 if (!is_world_regdom(ieee80211_regdom)) {
2162 REG_DBG_PRINT("cfg80211: Keeping preference on "
2163 "module parameter ieee80211_regdom: %c%c\n",
2164 ieee80211_regdom[0],
2165 ieee80211_regdom[1]);
2166 alpha2[0] = ieee80211_regdom[0];
2167 alpha2[1] = ieee80211_regdom[1];
2168 }
2169 } else {
2170 REG_DBG_PRINT("cfg80211: Restoring regulatory settings "
2171 "while preserving user preference for: %c%c\n",
2172 user_alpha2[0],
2173 user_alpha2[1]);
2174 alpha2[0] = user_alpha2[0];
2175 alpha2[1] = user_alpha2[1];
2176 }
2177 } else if (!is_world_regdom(ieee80211_regdom)) {
2178 REG_DBG_PRINT("cfg80211: Keeping preference on "
2179 "module parameter ieee80211_regdom: %c%c\n",
2180 ieee80211_regdom[0],
2181 ieee80211_regdom[1]);
2182 alpha2[0] = ieee80211_regdom[0];
2183 alpha2[1] = ieee80211_regdom[1];
2184 } else
2185 REG_DBG_PRINT("cfg80211: Restoring regulatory settings\n");
2186}
2187
2188/*
2189 * Restoring regulatory settings involves ingoring any
2190 * possibly stale country IE information and user regulatory
2191 * settings if so desired, this includes any beacon hints
2192 * learned as we could have traveled outside to another country
2193 * after disconnection. To restore regulatory settings we do
2194 * exactly what we did at bootup:
2195 *
2196 * - send a core regulatory hint
2197 * - send a user regulatory hint if applicable
2198 *
2199 * Device drivers that send a regulatory hint for a specific country
2200 * keep their own regulatory domain on wiphy->regd so that does does
2201 * not need to be remembered.
2202 */
2203static void restore_regulatory_settings(bool reset_user)
2204{
2205 char alpha2[2];
2206 struct reg_beacon *reg_beacon, *btmp;
2207
2208 mutex_lock(&cfg80211_mutex);
2209 mutex_lock(&reg_mutex);
2210
2211 reset_regdomains();
2212 restore_alpha2(alpha2, reset_user);
2213
2214 /* Clear beacon hints */
2215 spin_lock_bh(&reg_pending_beacons_lock);
2216 if (!list_empty(&reg_pending_beacons)) {
2217 list_for_each_entry_safe(reg_beacon, btmp,
2218 &reg_pending_beacons, list) {
2219 list_del(&reg_beacon->list);
2220 kfree(reg_beacon);
2221 }
2222 }
2223 spin_unlock_bh(&reg_pending_beacons_lock);
2224
2225 if (!list_empty(&reg_beacon_list)) {
2226 list_for_each_entry_safe(reg_beacon, btmp,
2227 &reg_beacon_list, list) {
2228 list_del(&reg_beacon->list);
2229 kfree(reg_beacon);
2230 }
2231 }
2232
2233 /* First restore to the basic regulatory settings */
2234 cfg80211_regdomain = cfg80211_world_regdom;
2235
2236 mutex_unlock(&reg_mutex);
2237 mutex_unlock(&cfg80211_mutex);
2238
2239 regulatory_hint_core(cfg80211_regdomain->alpha2);
2240
2241 /*
2242 * This restores the ieee80211_regdom module parameter
2243 * preference or the last user requested regulatory
2244 * settings, user regulatory settings takes precedence.
2245 */
2246 if (is_an_alpha2(alpha2))
2247 regulatory_hint_user(user_alpha2);
2248}
2249
2250
2251void regulatory_hint_disconnect(void)
2252{
2253 REG_DBG_PRINT("cfg80211: All devices are disconnected, going to "
2254 "restore regulatory settings\n");
2255 restore_regulatory_settings(false);
2256}
2257
2112static bool freq_is_chan_12_13_14(u16 freq) 2258static bool freq_is_chan_12_13_14(u16 freq)
2113{ 2259{
2114 if (freq == ieee80211_channel_to_frequency(12) || 2260 if (freq == ieee80211_channel_to_frequency(12) ||
@@ -2498,6 +2644,9 @@ int regulatory_init(void)
2498 2644
2499 cfg80211_regdomain = cfg80211_world_regdom; 2645 cfg80211_regdomain = cfg80211_world_regdom;
2500 2646
2647 user_alpha2[0] = '9';
2648 user_alpha2[1] = '7';
2649
2501 /* We always try to get an update for the static regdomain */ 2650 /* We always try to get an update for the static regdomain */
2502 err = regulatory_hint_core(cfg80211_regdomain->alpha2); 2651 err = regulatory_hint_core(cfg80211_regdomain->alpha2);
2503 if (err) { 2652 if (err) {
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 3018508226ab..b26224a9f3bc 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -63,4 +63,22 @@ void regulatory_hint_11d(struct wiphy *wiphy,
63 u8 *country_ie, 63 u8 *country_ie,
64 u8 country_ie_len); 64 u8 country_ie_len);
65 65
66/**
67 * regulatory_hint_disconnect - informs all devices have been disconneted
68 *
69 * Regulotory rules can be enhanced further upon scanning and upon
70 * connection to an AP. These rules become stale if we disconnect
71 * and go to another country, whether or not we suspend and resume.
72 * If we suspend, go to another country and resume we'll automatically
73 * get disconnected shortly after resuming and things will be reset as well.
74 * This routine is a helper to restore regulatory settings to how they were
75 * prior to our first connect attempt. This includes ignoring country IE and
76 * beacon regulatory hints. The ieee80211_regdom module parameter will always
77 * be respected but if a user had set the regulatory domain that will take
78 * precedence.
79 *
80 * Must be called from process context.
81 */
82void regulatory_hint_disconnect(void);
83
66#endif /* __NET_WIRELESS_REG_H */ 84#endif /* __NET_WIRELESS_REG_H */
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 06b0231ee5e3..978cac3414b5 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -143,9 +143,9 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
143 dev->bss_generation++; 143 dev->bss_generation++;
144} 144}
145 145
146static u8 *find_ie(u8 num, u8 *ies, int len) 146const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
147{ 147{
148 while (len > 2 && ies[0] != num) { 148 while (len > 2 && ies[0] != eid) {
149 len -= ies[1] + 2; 149 len -= ies[1] + 2;
150 ies += ies[1] + 2; 150 ies += ies[1] + 2;
151 } 151 }
@@ -155,11 +155,12 @@ static u8 *find_ie(u8 num, u8 *ies, int len)
155 return NULL; 155 return NULL;
156 return ies; 156 return ies;
157} 157}
158EXPORT_SYMBOL(cfg80211_find_ie);
158 159
159static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) 160static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
160{ 161{
161 const u8 *ie1 = find_ie(num, ies1, len1); 162 const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
162 const u8 *ie2 = find_ie(num, ies2, len2); 163 const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
163 int r; 164 int r;
164 165
165 if (!ie1 && !ie2) 166 if (!ie1 && !ie2)
@@ -185,9 +186,9 @@ static bool is_bss(struct cfg80211_bss *a,
185 if (!ssid) 186 if (!ssid)
186 return true; 187 return true;
187 188
188 ssidie = find_ie(WLAN_EID_SSID, 189 ssidie = cfg80211_find_ie(WLAN_EID_SSID,
189 a->information_elements, 190 a->information_elements,
190 a->len_information_elements); 191 a->len_information_elements);
191 if (!ssidie) 192 if (!ssidie)
192 return false; 193 return false;
193 if (ssidie[1] != ssid_len) 194 if (ssidie[1] != ssid_len)
@@ -204,9 +205,9 @@ static bool is_mesh(struct cfg80211_bss *a,
204 if (!is_zero_ether_addr(a->bssid)) 205 if (!is_zero_ether_addr(a->bssid))
205 return false; 206 return false;
206 207
207 ie = find_ie(WLAN_EID_MESH_ID, 208 ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
208 a->information_elements, 209 a->information_elements,
209 a->len_information_elements); 210 a->len_information_elements);
210 if (!ie) 211 if (!ie)
211 return false; 212 return false;
212 if (ie[1] != meshidlen) 213 if (ie[1] != meshidlen)
@@ -214,9 +215,9 @@ static bool is_mesh(struct cfg80211_bss *a,
214 if (memcmp(ie + 2, meshid, meshidlen)) 215 if (memcmp(ie + 2, meshid, meshidlen))
215 return false; 216 return false;
216 217
217 ie = find_ie(WLAN_EID_MESH_CONFIG, 218 ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
218 a->information_elements, 219 a->information_elements,
219 a->len_information_elements); 220 a->len_information_elements);
220 if (!ie) 221 if (!ie)
221 return false; 222 return false;
222 if (ie[1] != sizeof(struct ieee80211_meshconf_ie)) 223 if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
@@ -395,11 +396,12 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
395 396
396 if (is_zero_ether_addr(res->pub.bssid)) { 397 if (is_zero_ether_addr(res->pub.bssid)) {
397 /* must be mesh, verify */ 398 /* must be mesh, verify */
398 meshid = find_ie(WLAN_EID_MESH_ID, res->pub.information_elements, 399 meshid = cfg80211_find_ie(WLAN_EID_MESH_ID,
399 res->pub.len_information_elements); 400 res->pub.information_elements,
400 meshcfg = find_ie(WLAN_EID_MESH_CONFIG, 401 res->pub.len_information_elements);
401 res->pub.information_elements, 402 meshcfg = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
402 res->pub.len_information_elements); 403 res->pub.information_elements,
404 res->pub.len_information_elements);
403 if (!meshid || !meshcfg || 405 if (!meshid || !meshcfg ||
404 meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) { 406 meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) {
405 /* bogus mesh */ 407 /* bogus mesh */
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 745c37e7992e..17fde0da1b08 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -34,6 +34,44 @@ struct cfg80211_conn {
34 bool auto_auth, prev_bssid_valid; 34 bool auto_auth, prev_bssid_valid;
35}; 35};
36 36
37bool cfg80211_is_all_idle(void)
38{
39 struct cfg80211_registered_device *rdev;
40 struct wireless_dev *wdev;
41 bool is_all_idle = true;
42
43 mutex_lock(&cfg80211_mutex);
44
45 /*
46 * All devices must be idle as otherwise if you are actively
47 * scanning some new beacon hints could be learned and would
48 * count as new regulatory hints.
49 */
50 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
51 cfg80211_lock_rdev(rdev);
52 list_for_each_entry(wdev, &rdev->netdev_list, list) {
53 wdev_lock(wdev);
54 if (wdev->sme_state != CFG80211_SME_IDLE)
55 is_all_idle = false;
56 wdev_unlock(wdev);
57 }
58 cfg80211_unlock_rdev(rdev);
59 }
60
61 mutex_unlock(&cfg80211_mutex);
62
63 return is_all_idle;
64}
65
66static void disconnect_work(struct work_struct *work)
67{
68 if (!cfg80211_is_all_idle())
69 return;
70
71 regulatory_hint_disconnect();
72}
73
74static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
37 75
38static int cfg80211_conn_scan(struct wireless_dev *wdev) 76static int cfg80211_conn_scan(struct wireless_dev *wdev)
39{ 77{
@@ -658,6 +696,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
658 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); 696 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
659 wdev->wext.connect.ssid_len = 0; 697 wdev->wext.connect.ssid_len = 0;
660#endif 698#endif
699
700 schedule_work(&cfg80211_disconnect_work);
661} 701}
662 702
663void cfg80211_disconnected(struct net_device *dev, u16 reason, 703void cfg80211_disconnected(struct net_device *dev, u16 reason,
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index efe3c5c92b2d..9f2cef3e0ca0 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -33,10 +33,30 @@ static ssize_t name ## _show(struct device *dev, \
33 33
34SHOW_FMT(index, "%d", wiphy_idx); 34SHOW_FMT(index, "%d", wiphy_idx);
35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); 35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
36SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
37
38static ssize_t addresses_show(struct device *dev,
39 struct device_attribute *attr,
40 char *buf)
41{
42 struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
43 char *start = buf;
44 int i;
45
46 if (!wiphy->addresses)
47 return sprintf(buf, "%pM\n", wiphy->perm_addr);
48
49 for (i = 0; i < wiphy->n_addresses; i++)
50 buf += sprintf(buf, "%pM\n", &wiphy->addresses[i].addr);
51
52 return buf - start;
53}
36 54
37static struct device_attribute ieee80211_dev_attrs[] = { 55static struct device_attribute ieee80211_dev_attrs[] = {
38 __ATTR_RO(index), 56 __ATTR_RO(index),
39 __ATTR_RO(macaddress), 57 __ATTR_RO(macaddress),
58 __ATTR_RO(address_mask),
59 __ATTR_RO(addresses),
40 {} 60 {}
41}; 61};
42 62
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 23557c1d0a9c..be2ab8c59e3a 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -227,8 +227,11 @@ unsigned int ieee80211_hdrlen(__le16 fc)
227 if (ieee80211_is_data(fc)) { 227 if (ieee80211_is_data(fc)) {
228 if (ieee80211_has_a4(fc)) 228 if (ieee80211_has_a4(fc))
229 hdrlen = 30; 229 hdrlen = 30;
230 if (ieee80211_is_data_qos(fc)) 230 if (ieee80211_is_data_qos(fc)) {
231 hdrlen += IEEE80211_QOS_CTL_LEN; 231 hdrlen += IEEE80211_QOS_CTL_LEN;
232 if (ieee80211_has_order(fc))
233 hdrlen += IEEE80211_HT_CTL_LEN;
234 }
232 goto out; 235 goto out;
233 } 236 }
234 237
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 966d2f01beac..b17eeae448d5 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1214,7 +1214,7 @@ int cfg80211_wext_siwrate(struct net_device *dev,
1214 1214
1215 memset(&mask, 0, sizeof(mask)); 1215 memset(&mask, 0, sizeof(mask));
1216 fixed = 0; 1216 fixed = 0;
1217 maxrate = 0; 1217 maxrate = (u32)-1;
1218 1218
1219 if (rate->value < 0) { 1219 if (rate->value < 0) {
1220 /* nothing */ 1220 /* nothing */