aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-05-08 15:46:17 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-08 15:46:17 -0400
commita8679be2073392cf22a910bc25da0c7d36459845 (patch)
tree0d25750ea4ba3a85fe683f285261083d77080976 /net
parent22f6dacdfcfdc792d068e9c41234808860498d04 (diff)
parent9dfd6ba353b993d648dcda72480c7ce92cd27c7e (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/agg-rx.c19
-rw-r--r--net/mac80211/agg-tx.c13
-rw-r--r--net/mac80211/cfg.c49
-rw-r--r--net/mac80211/debugfs.c20
-rw-r--r--net/mac80211/driver-ops.h184
-rw-r--r--net/mac80211/ibss.c102
-rw-r--r--net/mac80211/ieee80211_i.h14
-rw-r--r--net/mac80211/iface.c100
-rw-r--r--net/mac80211/key.c8
-rw-r--r--net/mac80211/main.c165
-rw-r--r--net/mac80211/mesh.c6
-rw-r--r--net/mac80211/mlme.c74
-rw-r--r--net/mac80211/pm.c9
-rw-r--r--net/mac80211/rc80211_minstrel.c8
-rw-r--r--net/mac80211/rc80211_pid_algo.c8
-rw-r--r--net/mac80211/rx.c138
-rw-r--r--net/mac80211/scan.c414
-rw-r--r--net/mac80211/sta_info.c26
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/tkip.c6
-rw-r--r--net/mac80211/tx.c9
-rw-r--r--net/mac80211/util.c31
-rw-r--r--net/mac80211/wext.c2
-rw-r--r--net/rfkill/rfkill.c5
-rw-r--r--net/wireless/nl80211.c6
-rw-r--r--net/wireless/reg.c8
-rw-r--r--net/wireless/scan.c10
27 files changed, 876 insertions, 560 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 07656d830bc4..bc064d7933ff 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -16,12 +16,12 @@
16#include <linux/ieee80211.h> 16#include <linux/ieee80211.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18#include "ieee80211_i.h" 18#include "ieee80211_i.h"
19#include "driver-ops.h"
19 20
20void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 21void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
21 u16 initiator, u16 reason) 22 u16 initiator, u16 reason)
22{ 23{
23 struct ieee80211_local *local = sta->local; 24 struct ieee80211_local *local = sta->local;
24 struct ieee80211_hw *hw = &local->hw;
25 int i; 25 int i;
26 26
27 /* check if TID is in operational state */ 27 /* check if TID is in operational state */
@@ -41,8 +41,8 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
41 sta->sta.addr, tid); 41 sta->sta.addr, tid);
42#endif /* CONFIG_MAC80211_HT_DEBUG */ 42#endif /* CONFIG_MAC80211_HT_DEBUG */
43 43
44 if (local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, 44 if (drv_ampdu_action(local, IEEE80211_AMPDU_RX_STOP,
45 &sta->sta, tid, NULL)) 45 &sta->sta, tid, NULL))
46 printk(KERN_DEBUG "HW problem - can not stop rx " 46 printk(KERN_DEBUG "HW problem - can not stop rx "
47 "aggregation for tid %d\n", tid); 47 "aggregation for tid %d\n", tid);
48 48
@@ -68,6 +68,7 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
68 spin_lock_bh(&sta->lock); 68 spin_lock_bh(&sta->lock);
69 /* free resources */ 69 /* free resources */
70 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf); 70 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
71 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_time);
71 72
72 if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) { 73 if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) {
73 kfree(sta->ampdu_mlme.tid_rx[tid]); 74 kfree(sta->ampdu_mlme.tid_rx[tid]);
@@ -268,19 +269,23 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
268 /* prepare reordering buffer */ 269 /* prepare reordering buffer */
269 tid_agg_rx->reorder_buf = 270 tid_agg_rx->reorder_buf =
270 kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC); 271 kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
271 if (!tid_agg_rx->reorder_buf) { 272 tid_agg_rx->reorder_time =
273 kcalloc(buf_size, sizeof(unsigned long), GFP_ATOMIC);
274 if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) {
272#ifdef CONFIG_MAC80211_HT_DEBUG 275#ifdef CONFIG_MAC80211_HT_DEBUG
273 if (net_ratelimit()) 276 if (net_ratelimit())
274 printk(KERN_ERR "can not allocate reordering buffer " 277 printk(KERN_ERR "can not allocate reordering buffer "
275 "to tid %d\n", tid); 278 "to tid %d\n", tid);
276#endif 279#endif
280 kfree(tid_agg_rx->reorder_buf);
281 kfree(tid_agg_rx->reorder_time);
277 kfree(sta->ampdu_mlme.tid_rx[tid]); 282 kfree(sta->ampdu_mlme.tid_rx[tid]);
283 sta->ampdu_mlme.tid_rx[tid] = NULL;
278 goto end; 284 goto end;
279 } 285 }
280 286
281 if (local->ops->ampdu_action) 287 ret = drv_ampdu_action(local, IEEE80211_AMPDU_RX_START,
282 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, 288 &sta->sta, tid, &start_seq_num);
283 &sta->sta, tid, &start_seq_num);
284#ifdef CONFIG_MAC80211_HT_DEBUG 289#ifdef CONFIG_MAC80211_HT_DEBUG
285 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); 290 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
286#endif /* CONFIG_MAC80211_HT_DEBUG */ 291#endif /* CONFIG_MAC80211_HT_DEBUG */
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 947aaaad35d2..43d00ffd3988 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -16,6 +16,7 @@
16#include <linux/ieee80211.h> 16#include <linux/ieee80211.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18#include "ieee80211_i.h" 18#include "ieee80211_i.h"
19#include "driver-ops.h"
19#include "wme.h" 20#include "wme.h"
20 21
21/** 22/**
@@ -134,8 +135,8 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
134 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 135 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
135 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 136 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
136 137
137 ret = local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_STOP, 138 ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP,
138 &sta->sta, tid, NULL); 139 &sta->sta, tid, NULL);
139 140
140 /* HW shall not deny going back to legacy */ 141 /* HW shall not deny going back to legacy */
141 if (WARN_ON(ret)) { 142 if (WARN_ON(ret)) {
@@ -306,8 +307,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
306 307
307 start_seq_num = sta->tid_seq[tid]; 308 start_seq_num = sta->tid_seq[tid];
308 309
309 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START, 310 ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START,
310 &sta->sta, tid, &start_seq_num); 311 &sta->sta, tid, &start_seq_num);
311 312
312 if (ret) { 313 if (ret) {
313#ifdef CONFIG_MAC80211_HT_DEBUG 314#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -418,8 +419,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
418 ieee80211_agg_splice_finish(local, sta, tid); 419 ieee80211_agg_splice_finish(local, sta, tid);
419 spin_unlock(&local->ampdu_lock); 420 spin_unlock(&local->ampdu_lock);
420 421
421 local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_OPERATIONAL, 422 drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL,
422 &sta->sta, tid, NULL); 423 &sta->sta, tid, NULL);
423} 424}
424 425
425void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) 426void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 5e1c230744b5..d0ca6da33ca9 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -13,6 +13,7 @@
13#include <linux/rcupdate.h> 13#include <linux/rcupdate.h>
14#include <net/cfg80211.h> 14#include <net/cfg80211.h>
15#include "ieee80211_i.h" 15#include "ieee80211_i.h"
16#include "driver-ops.h"
16#include "cfg.h" 17#include "cfg.h"
17#include "rate.h" 18#include "rate.h"
18#include "mesh.h" 19#include "mesh.h"
@@ -245,12 +246,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
245 iv32 = key->u.tkip.tx.iv32; 246 iv32 = key->u.tkip.tx.iv32;
246 iv16 = key->u.tkip.tx.iv16; 247 iv16 = key->u.tkip.tx.iv16;
247 248
248 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && 249 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
249 sdata->local->ops->get_tkip_seq) 250 drv_get_tkip_seq(sdata->local,
250 sdata->local->ops->get_tkip_seq( 251 key->conf.hw_key_idx,
251 local_to_hw(sdata->local), 252 &iv32, &iv16);
252 key->conf.hw_key_idx,
253 &iv32, &iv16);
254 253
255 seq[0] = iv16 & 0xff; 254 seq[0] = iv16 & 0xff;
256 seq[1] = (iv16 >> 8) & 0xff; 255 seq[1] = (iv16 >> 8) & 0xff;
@@ -451,18 +450,11 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
451 * This is a kludge. beacon interval should really be part 450 * This is a kludge. beacon interval should really be part
452 * of the beacon information. 451 * of the beacon information.
453 */ 452 */
454 if (params->interval && (sdata->local->hw.conf.beacon_int != 453 if (params->interval &&
455 params->interval)) { 454 (sdata->vif.bss_conf.beacon_int != params->interval)) {
456 sdata->local->hw.conf.beacon_int = params->interval; 455 sdata->vif.bss_conf.beacon_int = params->interval;
457 err = ieee80211_hw_config(sdata->local, 456 ieee80211_bss_info_change_notify(sdata,
458 IEEE80211_CONF_CHANGE_BEACON_INTERVAL); 457 BSS_CHANGED_BEACON_INT);
459 if (err < 0)
460 return err;
461 /*
462 * We updated some parameter so if below bails out
463 * it's not an error.
464 */
465 err = 0;
466 } 458 }
467 459
468 /* Need to have a beacon head if we don't have one yet */ 460 /* Need to have a beacon head if we don't have one yet */
@@ -528,8 +520,9 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
528 520
529 kfree(old); 521 kfree(old);
530 522
531 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 523 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
532 IEEE80211_IFCC_BEACON_ENABLED); 524 BSS_CHANGED_BEACON);
525 return 0;
533} 526}
534 527
535static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 528static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
@@ -580,7 +573,8 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
580 synchronize_rcu(); 573 synchronize_rcu();
581 kfree(old); 574 kfree(old);
582 575
583 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED); 576 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
577 return 0;
584} 578}
585 579
586/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ 580/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
@@ -1120,7 +1114,7 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1120 p.cw_max = params->cwmax; 1114 p.cw_max = params->cwmax;
1121 p.cw_min = params->cwmin; 1115 p.cw_min = params->cwmin;
1122 p.txop = params->txop; 1116 p.txop = params->txop;
1123 if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) { 1117 if (drv_conf_tx(local, params->queue, &p)) {
1124 printk(KERN_DEBUG "%s: failed to set TX queue " 1118 printk(KERN_DEBUG "%s: failed to set TX queue "
1125 "parameters for queue %d\n", local->mdev->name, 1119 "parameters for queue %d\n", local->mdev->name,
1126 params->queue); 1120 params->queue);
@@ -1301,16 +1295,13 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1301static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1295static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1302{ 1296{
1303 struct ieee80211_local *local = wiphy_priv(wiphy); 1297 struct ieee80211_local *local = wiphy_priv(wiphy);
1298 int err;
1304 1299
1305 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 1300 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1306 int err; 1301 err = drv_set_rts_threshold(local, wiphy->rts_threshold);
1307 1302
1308 if (local->ops->set_rts_threshold) { 1303 if (err)
1309 err = local->ops->set_rts_threshold( 1304 return err;
1310 local_to_hw(local), wiphy->rts_threshold);
1311 if (err)
1312 return err;
1313 }
1314 } 1305 }
1315 1306
1316 if (changed & WIPHY_PARAM_RETRY_SHORT) 1307 if (changed & WIPHY_PARAM_RETRY_SHORT)
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 5001328be46b..ac793201b701 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -10,6 +10,7 @@
10#include <linux/debugfs.h> 10#include <linux/debugfs.h>
11#include <linux/rtnetlink.h> 11#include <linux/rtnetlink.h>
12#include "ieee80211_i.h" 12#include "ieee80211_i.h"
13#include "driver-ops.h"
13#include "rate.h" 14#include "rate.h"
14#include "debugfs.h" 15#include "debugfs.h"
15 16
@@ -70,11 +71,10 @@ static ssize_t tsf_read(struct file *file, char __user *user_buf,
70 size_t count, loff_t *ppos) 71 size_t count, loff_t *ppos)
71{ 72{
72 struct ieee80211_local *local = file->private_data; 73 struct ieee80211_local *local = file->private_data;
73 u64 tsf = 0; 74 u64 tsf;
74 char buf[100]; 75 char buf[100];
75 76
76 if (local->ops->get_tsf) 77 tsf = drv_get_tsf(local);
77 tsf = local->ops->get_tsf(local_to_hw(local));
78 78
79 snprintf(buf, sizeof(buf), "0x%016llx\n", (unsigned long long) tsf); 79 snprintf(buf, sizeof(buf), "0x%016llx\n", (unsigned long long) tsf);
80 80
@@ -97,13 +97,13 @@ static ssize_t tsf_write(struct file *file,
97 97
98 if (strncmp(buf, "reset", 5) == 0) { 98 if (strncmp(buf, "reset", 5) == 0) {
99 if (local->ops->reset_tsf) { 99 if (local->ops->reset_tsf) {
100 local->ops->reset_tsf(local_to_hw(local)); 100 drv_reset_tsf(local);
101 printk(KERN_INFO "%s: debugfs reset TSF\n", wiphy_name(local->hw.wiphy)); 101 printk(KERN_INFO "%s: debugfs reset TSF\n", wiphy_name(local->hw.wiphy));
102 } 102 }
103 } else { 103 } else {
104 tsf = simple_strtoul(buf, NULL, 0); 104 tsf = simple_strtoul(buf, NULL, 0);
105 if (local->ops->set_tsf) { 105 if (local->ops->set_tsf) {
106 local->ops->set_tsf(local_to_hw(local), tsf); 106 drv_set_tsf(local, tsf);
107 printk(KERN_INFO "%s: debugfs set TSF to %#018llx\n", wiphy_name(local->hw.wiphy), tsf); 107 printk(KERN_INFO "%s: debugfs set TSF to %#018llx\n", wiphy_name(local->hw.wiphy), tsf);
108 } 108 }
109 } 109 }
@@ -150,14 +150,12 @@ static ssize_t format_devstat_counter(struct ieee80211_local *local,
150 char buf[20]; 150 char buf[20];
151 int res; 151 int res;
152 152
153 if (!local->ops->get_stats)
154 return -EOPNOTSUPP;
155
156 rtnl_lock(); 153 rtnl_lock();
157 res = local->ops->get_stats(local_to_hw(local), &stats); 154 res = drv_get_stats(local, &stats);
158 rtnl_unlock(); 155 rtnl_unlock();
159 if (!res) 156 if (res)
160 res = printvalue(&stats, buf, sizeof(buf)); 157 return res;
158 res = printvalue(&stats, buf, sizeof(buf));
161 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 159 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
162} 160}
163 161
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
new file mode 100644
index 000000000000..3912b5334b9c
--- /dev/null
+++ b/net/mac80211/driver-ops.h
@@ -0,0 +1,184 @@
1#ifndef __MAC80211_DRIVER_OPS
2#define __MAC80211_DRIVER_OPS
3
4#include <net/mac80211.h>
5#include "ieee80211_i.h"
6
7static inline int drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
8{
9 return local->ops->tx(&local->hw, skb);
10}
11
12static inline int drv_start(struct ieee80211_local *local)
13{
14 return local->ops->start(&local->hw);
15}
16
17static inline void drv_stop(struct ieee80211_local *local)
18{
19 local->ops->stop(&local->hw);
20}
21
22static inline int drv_add_interface(struct ieee80211_local *local,
23 struct ieee80211_if_init_conf *conf)
24{
25 return local->ops->add_interface(&local->hw, conf);
26}
27
28static inline void drv_remove_interface(struct ieee80211_local *local,
29 struct ieee80211_if_init_conf *conf)
30{
31 local->ops->remove_interface(&local->hw, conf);
32}
33
34static inline int drv_config(struct ieee80211_local *local, u32 changed)
35{
36 return local->ops->config(&local->hw, changed);
37}
38
39static inline void drv_bss_info_changed(struct ieee80211_local *local,
40 struct ieee80211_vif *vif,
41 struct ieee80211_bss_conf *info,
42 u32 changed)
43{
44 if (local->ops->bss_info_changed)
45 local->ops->bss_info_changed(&local->hw, vif, info, changed);
46}
47
48static inline void drv_configure_filter(struct ieee80211_local *local,
49 unsigned int changed_flags,
50 unsigned int *total_flags,
51 int mc_count,
52 struct dev_addr_list *mc_list)
53{
54 local->ops->configure_filter(&local->hw, changed_flags, total_flags,
55 mc_count, mc_list);
56}
57
58static inline int drv_set_tim(struct ieee80211_local *local,
59 struct ieee80211_sta *sta, bool set)
60{
61 if (local->ops->set_tim)
62 return local->ops->set_tim(&local->hw, sta, set);
63 return 0;
64}
65
66static inline int drv_set_key(struct ieee80211_local *local,
67 enum set_key_cmd cmd, struct ieee80211_vif *vif,
68 struct ieee80211_sta *sta,
69 struct ieee80211_key_conf *key)
70{
71 return local->ops->set_key(&local->hw, cmd, vif, sta, key);
72}
73
74static inline void drv_update_tkip_key(struct ieee80211_local *local,
75 struct ieee80211_key_conf *conf,
76 const u8 *address, u32 iv32,
77 u16 *phase1key)
78{
79 if (local->ops->update_tkip_key)
80 local->ops->update_tkip_key(&local->hw, conf, address,
81 iv32, phase1key);
82}
83
84static inline int drv_hw_scan(struct ieee80211_local *local,
85 struct cfg80211_scan_request *req)
86{
87 return local->ops->hw_scan(&local->hw, req);
88}
89
90static inline void drv_sw_scan_start(struct ieee80211_local *local)
91{
92 if (local->ops->sw_scan_start)
93 local->ops->sw_scan_start(&local->hw);
94}
95
96static inline void drv_sw_scan_complete(struct ieee80211_local *local)
97{
98 if (local->ops->sw_scan_complete)
99 local->ops->sw_scan_complete(&local->hw);
100}
101
102static inline int drv_get_stats(struct ieee80211_local *local,
103 struct ieee80211_low_level_stats *stats)
104{
105 if (!local->ops->get_stats)
106 return -EOPNOTSUPP;
107 return local->ops->get_stats(&local->hw, stats);
108}
109
110static inline void drv_get_tkip_seq(struct ieee80211_local *local,
111 u8 hw_key_idx, u32 *iv32, u16 *iv16)
112{
113 if (local->ops->get_tkip_seq)
114 local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
115}
116
117static inline int drv_set_rts_threshold(struct ieee80211_local *local,
118 u32 value)
119{
120 if (local->ops->set_rts_threshold)
121 return local->ops->set_rts_threshold(&local->hw, value);
122 return 0;
123}
124
125static inline void drv_sta_notify(struct ieee80211_local *local,
126 struct ieee80211_vif *vif,
127 enum sta_notify_cmd cmd,
128 struct ieee80211_sta *sta)
129{
130 if (local->ops->sta_notify)
131 local->ops->sta_notify(&local->hw, vif, cmd, sta);
132}
133
134static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
135 const struct ieee80211_tx_queue_params *params)
136{
137 if (local->ops->conf_tx)
138 return local->ops->conf_tx(&local->hw, queue, params);
139 return -EOPNOTSUPP;
140}
141
142static inline int drv_get_tx_stats(struct ieee80211_local *local,
143 struct ieee80211_tx_queue_stats *stats)
144{
145 return local->ops->get_tx_stats(&local->hw, stats);
146}
147
148static inline u64 drv_get_tsf(struct ieee80211_local *local)
149{
150 if (local->ops->get_tsf)
151 return local->ops->get_tsf(&local->hw);
152 return -1ULL;
153}
154
155static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf)
156{
157 if (local->ops->set_tsf)
158 local->ops->set_tsf(&local->hw, tsf);
159}
160
161static inline void drv_reset_tsf(struct ieee80211_local *local)
162{
163 if (local->ops->reset_tsf)
164 local->ops->reset_tsf(&local->hw);
165}
166
167static inline int drv_tx_last_beacon(struct ieee80211_local *local)
168{
169 if (local->ops->tx_last_beacon)
170 return local->ops->tx_last_beacon(&local->hw);
171 return 1;
172}
173
174static inline int drv_ampdu_action(struct ieee80211_local *local,
175 enum ieee80211_ampdu_mlme_action action,
176 struct ieee80211_sta *sta, u16 tid,
177 u16 *ssn)
178{
179 if (local->ops->ampdu_action)
180 return local->ops->ampdu_action(&local->hw, action,
181 sta, tid, ssn);
182 return -EOPNOTSUPP;
183}
184#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 6030e003180c..aa537681f87c 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -22,6 +22,7 @@
22#include <asm/unaligned.h> 22#include <asm/unaligned.h>
23 23
24#include "ieee80211_i.h" 24#include "ieee80211_i.h"
25#include "driver-ops.h"
25#include "rate.h" 26#include "rate.h"
26 27
27#define IEEE80211_SCAN_INTERVAL (2 * HZ) 28#define IEEE80211_SCAN_INTERVAL (2 * HZ)
@@ -73,11 +74,11 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
73 struct ieee80211_mgmt *mgmt; 74 struct ieee80211_mgmt *mgmt;
74 u8 *pos; 75 u8 *pos;
75 struct ieee80211_supported_band *sband; 76 struct ieee80211_supported_band *sband;
77 u32 bss_change;
76 78
77 if (local->ops->reset_tsf) { 79
78 /* Reset own TSF to allow time synchronization work. */ 80 /* Reset own TSF to allow time synchronization work. */
79 local->ops->reset_tsf(local_to_hw(local)); 81 drv_reset_tsf(local);
80 }
81 82
82 skb = ifibss->skb; 83 skb = ifibss->skb;
83 rcu_assign_pointer(ifibss->presp, NULL); 84 rcu_assign_pointer(ifibss->presp, NULL);
@@ -92,15 +93,12 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
92 93
93 memcpy(ifibss->bssid, bssid, ETH_ALEN); 94 memcpy(ifibss->bssid, bssid, ETH_ALEN);
94 95
95 local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
96
97 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; 96 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
98 97
99 ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
100
101 local->oper_channel = chan; 98 local->oper_channel = chan;
102 local->oper_channel_type = NL80211_CHAN_NO_HT; 99 local->oper_channel_type = NL80211_CHAN_NO_HT;
103 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 100 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
101
104 sband = local->hw.wiphy->bands[chan->band]; 102 sband = local->hw.wiphy->bands[chan->band];
105 103
106 /* Build IBSS probe response */ 104 /* Build IBSS probe response */
@@ -111,7 +109,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
111 memset(mgmt->da, 0xff, ETH_ALEN); 109 memset(mgmt->da, 0xff, ETH_ALEN);
112 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 110 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
113 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); 111 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
114 mgmt->u.beacon.beacon_int = cpu_to_le16(local->hw.conf.beacon_int); 112 mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int);
115 mgmt->u.beacon.timestamp = cpu_to_le64(tsf); 113 mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
116 mgmt->u.beacon.capab_info = cpu_to_le16(capability); 114 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
117 115
@@ -156,8 +154,13 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
156 154
157 rcu_assign_pointer(ifibss->presp, skb); 155 rcu_assign_pointer(ifibss->presp, skb);
158 156
159 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 157 sdata->vif.bss_conf.beacon_int = beacon_int;
160 IEEE80211_IFCC_BEACON_ENABLED); 158 bss_change = BSS_CHANGED_BEACON_INT;
159 bss_change |= ieee80211_reset_erp_info(sdata);
160 bss_change |= BSS_CHANGED_BSSID;
161 bss_change |= BSS_CHANGED_BEACON;
162 bss_change |= BSS_CHANGED_BEACON_ENABLED;
163 ieee80211_bss_info_change_notify(sdata, bss_change);
161 164
162 rates = 0; 165 rates = 0;
163 for (i = 0; i < supp_rates_len; i++) { 166 for (i = 0; i < supp_rates_len; i++) {
@@ -181,8 +184,13 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
181static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 184static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
182 struct ieee80211_bss *bss) 185 struct ieee80211_bss *bss)
183{ 186{
187 u16 beacon_int = bss->cbss.beacon_interval;
188
189 if (beacon_int < 10)
190 beacon_int = 10;
191
184 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid, 192 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
185 bss->cbss.beacon_interval, 193 beacon_int,
186 bss->cbss.channel, 194 bss->cbss.channel,
187 bss->supp_rates_len, bss->supp_rates, 195 bss->supp_rates_len, bss->supp_rates,
188 bss->cbss.capability, 196 bss->cbss.capability,
@@ -307,12 +315,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
307 bitrates[rx_status->rate_idx].bitrate; 315 bitrates[rx_status->rate_idx].bitrate;
308 316
309 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); 317 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
310 } else if (local && local->ops && local->ops->get_tsf) 318 } else {
311 /* second best option: get current TSF */ 319 /*
312 rx_timestamp = local->ops->get_tsf(local_to_hw(local)); 320 * second best option: get current TSF
313 else 321 * (will return -1 if not supported)
314 /* can't merge without knowing the TSF */ 322 */
315 rx_timestamp = -1LLU; 323 rx_timestamp = drv_get_tsf(local);
324 }
316 325
317#ifdef CONFIG_MAC80211_IBSS_DEBUG 326#ifdef CONFIG_MAC80211_IBSS_DEBUG
318 printk(KERN_DEBUG "RX beacon SA=%pM BSSID=" 327 printk(KERN_DEBUG "RX beacon SA=%pM BSSID="
@@ -432,14 +441,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
432 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " 441 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
433 "IBSS networks with same SSID (merge)\n", sdata->dev->name); 442 "IBSS networks with same SSID (merge)\n", sdata->dev->name);
434 443
435 /* XXX maybe racy? */ 444 ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len);
436 if (sdata->local->scan_req)
437 return;
438
439 memcpy(sdata->local->int_scan_req.ssids[0].ssid,
440 ifibss->ssid, IEEE80211_MAX_SSID_LEN);
441 sdata->local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len;
442 ieee80211_request_scan(sdata, &sdata->local->int_scan_req);
443} 445}
444 446
445static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) 447static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -471,9 +473,6 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
471 473
472 sband = local->hw.wiphy->bands[ifibss->channel->band]; 474 sband = local->hw.wiphy->bands[ifibss->channel->band];
473 475
474 if (local->hw.conf.beacon_int == 0)
475 local->hw.conf.beacon_int = 100;
476
477 capability = WLAN_CAPABILITY_IBSS; 476 capability = WLAN_CAPABILITY_IBSS;
478 477
479 if (sdata->default_key) 478 if (sdata->default_key)
@@ -487,7 +486,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
487 *pos++ = (u8) (rate / 5); 486 *pos++ = (u8) (rate / 5);
488 } 487 }
489 488
490 __ieee80211_sta_join_ibss(sdata, bssid, local->hw.conf.beacon_int, 489 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
491 ifibss->channel, sband->n_bitrates, 490 ifibss->channel, sband->n_bitrates,
492 supp_rates, capability, 0); 491 supp_rates, capability, 0);
493} 492}
@@ -552,15 +551,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
552 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 551 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
553 "join\n", sdata->dev->name); 552 "join\n", sdata->dev->name);
554 553
555 /* XXX maybe racy? */ 554 ieee80211_request_internal_scan(sdata, ifibss->ssid,
556 if (local->scan_req) 555 ifibss->ssid_len);
557 return;
558
559 memcpy(local->int_scan_req.ssids[0].ssid,
560 ifibss->ssid, IEEE80211_MAX_SSID_LEN);
561 local->int_scan_req.ssids[0].ssid_len =
562 ifibss->ssid_len;
563 ieee80211_request_scan(sdata, &local->int_scan_req);
564 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) { 556 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) {
565 int interval = IEEE80211_SCAN_INTERVAL; 557 int interval = IEEE80211_SCAN_INTERVAL;
566 558
@@ -600,10 +592,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
600 len < 24 + 2 || !ifibss->presp) 592 len < 24 + 2 || !ifibss->presp)
601 return; 593 return;
602 594
603 if (local->ops->tx_last_beacon) 595 tx_last_beacon = drv_tx_last_beacon(local);
604 tx_last_beacon = local->ops->tx_last_beacon(local_to_hw(local));
605 else
606 tx_last_beacon = 1;
607 596
608#ifdef CONFIG_MAC80211_IBSS_DEBUG 597#ifdef CONFIG_MAC80211_IBSS_DEBUG
609 printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM" 598 printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM"
@@ -786,8 +775,12 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
786 775
787 mutex_lock(&local->iflist_mtx); 776 mutex_lock(&local->iflist_mtx);
788 list_for_each_entry(sdata, &local->interfaces, list) { 777 list_for_each_entry(sdata, &local->interfaces, list) {
778 if (!netif_running(sdata->dev))
779 continue;
789 if (sdata->vif.type != NL80211_IFTYPE_ADHOC) 780 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
790 continue; 781 continue;
782 if (!sdata->u.ibss.ssid_len)
783 continue;
791 sdata->u.ibss.last_scan_completed = jiffies; 784 sdata->u.ibss.last_scan_completed = jiffies;
792 ieee80211_sta_find_ibss(sdata); 785 ieee80211_sta_find_ibss(sdata);
793 } 786 }
@@ -827,15 +820,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
827{ 820{
828 struct sk_buff *skb; 821 struct sk_buff *skb;
829 822
830 memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
831 sdata->u.ibss.ssid_len = params->ssid_len;
832
833 if (params->bssid) { 823 if (params->bssid) {
834 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); 824 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
835 sdata->u.ibss.fixed_bssid = true; 825 sdata->u.ibss.fixed_bssid = true;
836 } else 826 } else
837 sdata->u.ibss.fixed_bssid = false; 827 sdata->u.ibss.fixed_bssid = false;
838 828
829 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
830
839 sdata->u.ibss.channel = params->channel; 831 sdata->u.ibss.channel = params->channel;
840 sdata->u.ibss.fixed_channel = params->channel_fixed; 832 sdata->u.ibss.fixed_channel = params->channel_fixed;
841 833
@@ -859,6 +851,19 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
859 sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; 851 sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
860 sdata->u.ibss.ibss_join_req = jiffies; 852 sdata->u.ibss.ibss_join_req = jiffies;
861 853
854 memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
855
856 /*
857 * The ssid_len setting below is used to see whether
858 * we are active, and we need all other settings
859 * before that may get visible.
860 */
861 mb();
862
863 sdata->u.ibss.ssid_len = params->ssid_len;
864
865 ieee80211_recalc_idle(sdata->local);
866
862 set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); 867 set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
863 queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work); 868 queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);
864 869
@@ -880,12 +885,15 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
880 kfree(sdata->u.ibss.ie); 885 kfree(sdata->u.ibss.ie);
881 skb = sdata->u.ibss.presp; 886 skb = sdata->u.ibss.presp;
882 rcu_assign_pointer(sdata->u.ibss.presp, NULL); 887 rcu_assign_pointer(sdata->u.ibss.presp, NULL);
883 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED); 888 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
884 synchronize_rcu(); 889 synchronize_rcu();
885 kfree_skb(skb); 890 kfree_skb(skb);
886 891
887 skb_queue_purge(&sdata->u.ibss.skb_queue); 892 skb_queue_purge(&sdata->u.ibss.skb_queue);
888 memset(sdata->u.ibss.bssid, 0, ETH_ALEN); 893 memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
894 sdata->u.ibss.ssid_len = 0;
895
896 ieee80211_recalc_idle(sdata->local);
889 897
890 return 0; 898 return 0;
891} 899}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 1579bc92c88d..03e0d22603c8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -248,9 +248,8 @@ struct mesh_preq_queue {
248#define IEEE80211_STA_EXT_SME BIT(17) 248#define IEEE80211_STA_EXT_SME BIT(17)
249/* flags for MLME request */ 249/* flags for MLME request */
250#define IEEE80211_STA_REQ_SCAN 0 250#define IEEE80211_STA_REQ_SCAN 0
251#define IEEE80211_STA_REQ_DIRECT_PROBE 1 251#define IEEE80211_STA_REQ_AUTH 1
252#define IEEE80211_STA_REQ_AUTH 2 252#define IEEE80211_STA_REQ_RUN 2
253#define IEEE80211_STA_REQ_RUN 3
254 253
255/* bitfield of allowed auth algs */ 254/* bitfield of allowed auth algs */
256#define IEEE80211_AUTH_ALG_OPEN BIT(0) 255#define IEEE80211_AUTH_ALG_OPEN BIT(0)
@@ -659,6 +658,7 @@ struct ieee80211_local {
659 658
660 659
661 /* Scanning and BSS list */ 660 /* Scanning and BSS list */
661 struct mutex scan_mtx;
662 bool sw_scanning, hw_scanning; 662 bool sw_scanning, hw_scanning;
663 struct cfg80211_ssid scan_ssid; 663 struct cfg80211_ssid scan_ssid;
664 struct cfg80211_scan_request int_scan_req; 664 struct cfg80211_scan_request int_scan_req;
@@ -905,7 +905,6 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
905 905
906 906
907int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); 907int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
908int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
909void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); 908void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
910void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 909void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
911 u32 changed); 910 u32 changed);
@@ -947,6 +946,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
947 946
948/* scan/BSS handling */ 947/* scan/BSS handling */
949void ieee80211_scan_work(struct work_struct *work); 948void ieee80211_scan_work(struct work_struct *work);
949int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
950 const u8 *ssid, u8 ssid_len);
950int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 951int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
951 struct cfg80211_scan_request *req); 952 struct cfg80211_scan_request *req);
952int ieee80211_scan_results(struct ieee80211_local *local, 953int ieee80211_scan_results(struct ieee80211_local *local,
@@ -960,9 +961,6 @@ int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
960 const char *ie, size_t len); 961 const char *ie, size_t len);
961 962
962void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); 963void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
963void ieee80211_scan_failed(struct ieee80211_local *local);
964int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
965 struct cfg80211_scan_request *req);
966struct ieee80211_bss * 964struct ieee80211_bss *
967ieee80211_bss_info_update(struct ieee80211_local *local, 965ieee80211_bss_info_update(struct ieee80211_local *local,
968 struct ieee80211_rx_status *rx_status, 966 struct ieee80211_rx_status *rx_status,
@@ -987,6 +985,8 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
987 enum nl80211_iftype type); 985 enum nl80211_iftype type);
988void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); 986void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
989void ieee80211_remove_interfaces(struct ieee80211_local *local); 987void ieee80211_remove_interfaces(struct ieee80211_local *local);
988u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
989void ieee80211_recalc_idle(struct ieee80211_local *local);
990 990
991/* tx handling */ 991/* tx handling */
992void ieee80211_clear_tx_pending(struct ieee80211_local *local); 992void ieee80211_clear_tx_pending(struct ieee80211_local *local);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 52425975bbbe..8b6daf0219f4 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -20,6 +20,7 @@
20#include "debugfs_netdev.h" 20#include "debugfs_netdev.h"
21#include "mesh.h" 21#include "mesh.h"
22#include "led.h" 22#include "led.h"
23#include "driver-ops.h"
23 24
24/** 25/**
25 * DOC: Interface list locking 26 * DOC: Interface list locking
@@ -164,9 +165,7 @@ static int ieee80211_open(struct net_device *dev)
164 } 165 }
165 166
166 if (local->open_count == 0) { 167 if (local->open_count == 0) {
167 res = 0; 168 res = drv_start(local);
168 if (local->ops->start)
169 res = local->ops->start(local_to_hw(local));
170 if (res) 169 if (res)
171 goto err_del_bss; 170 goto err_del_bss;
172 /* we're brought up, everything changes */ 171 /* we're brought up, everything changes */
@@ -199,8 +198,8 @@ static int ieee80211_open(struct net_device *dev)
199 * Validate the MAC address for this device. 198 * Validate the MAC address for this device.
200 */ 199 */
201 if (!is_valid_ether_addr(dev->dev_addr)) { 200 if (!is_valid_ether_addr(dev->dev_addr)) {
202 if (!local->open_count && local->ops->stop) 201 if (!local->open_count)
203 local->ops->stop(local_to_hw(local)); 202 drv_stop(local);
204 return -EADDRNOTAVAIL; 203 return -EADDRNOTAVAIL;
205 } 204 }
206 205
@@ -241,7 +240,7 @@ static int ieee80211_open(struct net_device *dev)
241 conf.vif = &sdata->vif; 240 conf.vif = &sdata->vif;
242 conf.type = sdata->vif.type; 241 conf.type = sdata->vif.type;
243 conf.mac_addr = dev->dev_addr; 242 conf.mac_addr = dev->dev_addr;
244 res = local->ops->add_interface(local_to_hw(local), &conf); 243 res = drv_add_interface(local, &conf);
245 if (res) 244 if (res)
246 goto err_stop; 245 goto err_stop;
247 246
@@ -302,6 +301,8 @@ static int ieee80211_open(struct net_device *dev)
302 if (sdata->flags & IEEE80211_SDATA_PROMISC) 301 if (sdata->flags & IEEE80211_SDATA_PROMISC)
303 atomic_inc(&local->iff_promiscs); 302 atomic_inc(&local->iff_promiscs);
304 303
304 hw_reconf_flags |= __ieee80211_recalc_idle(local);
305
305 local->open_count++; 306 local->open_count++;
306 if (hw_reconf_flags) { 307 if (hw_reconf_flags) {
307 ieee80211_hw_config(local, hw_reconf_flags); 308 ieee80211_hw_config(local, hw_reconf_flags);
@@ -328,10 +329,10 @@ static int ieee80211_open(struct net_device *dev)
328 329
329 return 0; 330 return 0;
330 err_del_interface: 331 err_del_interface:
331 local->ops->remove_interface(local_to_hw(local), &conf); 332 drv_remove_interface(local, &conf);
332 err_stop: 333 err_stop:
333 if (!local->open_count && local->ops->stop) 334 if (!local->open_count)
334 local->ops->stop(local_to_hw(local)); 335 drv_stop(local);
335 err_del_bss: 336 err_del_bss:
336 sdata->bss = NULL; 337 sdata->bss = NULL;
337 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 338 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -544,17 +545,20 @@ static int ieee80211_stop(struct net_device *dev)
544 conf.mac_addr = dev->dev_addr; 545 conf.mac_addr = dev->dev_addr;
545 /* disable all keys for as long as this netdev is down */ 546 /* disable all keys for as long as this netdev is down */
546 ieee80211_disable_keys(sdata); 547 ieee80211_disable_keys(sdata);
547 local->ops->remove_interface(local_to_hw(local), &conf); 548 drv_remove_interface(local, &conf);
548 } 549 }
549 550
550 sdata->bss = NULL; 551 sdata->bss = NULL;
551 552
553 hw_reconf_flags |= __ieee80211_recalc_idle(local);
554
555 ieee80211_recalc_ps(local, -1);
556
552 if (local->open_count == 0) { 557 if (local->open_count == 0) {
553 if (netif_running(local->mdev)) 558 if (netif_running(local->mdev))
554 dev_close(local->mdev); 559 dev_close(local->mdev);
555 560
556 if (local->ops->stop) 561 drv_stop(local);
557 local->ops->stop(local_to_hw(local));
558 562
559 ieee80211_led_radio(local, 0); 563 ieee80211_led_radio(local, 0);
560 564
@@ -567,8 +571,6 @@ static int ieee80211_stop(struct net_device *dev)
567 hw_reconf_flags = 0; 571 hw_reconf_flags = 0;
568 } 572 }
569 573
570 ieee80211_recalc_ps(local, -1);
571
572 /* do after stop to avoid reconfiguring when we stop anyway */ 574 /* do after stop to avoid reconfiguring when we stop anyway */
573 if (hw_reconf_flags) 575 if (hw_reconf_flags)
574 ieee80211_hw_config(local, hw_reconf_flags); 576 ieee80211_hw_config(local, hw_reconf_flags);
@@ -894,3 +896,73 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
894 unregister_netdevice(sdata->dev); 896 unregister_netdevice(sdata->dev);
895 } 897 }
896} 898}
899
900static u32 ieee80211_idle_off(struct ieee80211_local *local,
901 const char *reason)
902{
903 if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
904 return 0;
905
906#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
907 printk(KERN_DEBUG "%s: device no longer idle - %s\n",
908 wiphy_name(local->hw.wiphy), reason);
909#endif
910
911 local->hw.conf.flags &= ~IEEE80211_CONF_IDLE;
912 return IEEE80211_CONF_CHANGE_IDLE;
913}
914
915static u32 ieee80211_idle_on(struct ieee80211_local *local)
916{
917 if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
918 return 0;
919
920#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
921 printk(KERN_DEBUG "%s: device now idle\n",
922 wiphy_name(local->hw.wiphy));
923#endif
924
925 local->hw.conf.flags |= IEEE80211_CONF_IDLE;
926 return IEEE80211_CONF_CHANGE_IDLE;
927}
928
929u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
930{
931 struct ieee80211_sub_if_data *sdata;
932 int count = 0;
933
934 if (local->hw_scanning || local->sw_scanning)
935 return ieee80211_idle_off(local, "scanning");
936
937 list_for_each_entry(sdata, &local->interfaces, list) {
938 if (!netif_running(sdata->dev))
939 continue;
940 /* do not count disabled managed interfaces */
941 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
942 sdata->u.mgd.state == IEEE80211_STA_MLME_DISABLED)
943 continue;
944 /* do not count unused IBSS interfaces */
945 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
946 !sdata->u.ibss.ssid_len)
947 continue;
948 /* count everything else */
949 count++;
950 }
951
952 if (!count)
953 return ieee80211_idle_on(local);
954 else
955 return ieee80211_idle_off(local, "in use");
956
957 return 0;
958}
959
960void ieee80211_recalc_idle(struct ieee80211_local *local)
961{
962 u32 chg;
963
964 mutex_lock(&local->iflist_mtx);
965 chg = __ieee80211_recalc_idle(local);
966 mutex_unlock(&local->iflist_mtx);
967 ieee80211_hw_config(local, chg);
968}
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 687acf23054d..b7e1350273bb 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -16,6 +16,7 @@
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18#include "ieee80211_i.h" 18#include "ieee80211_i.h"
19#include "driver-ops.h"
19#include "debugfs_key.h" 20#include "debugfs_key.h"
20#include "aes_ccm.h" 21#include "aes_ccm.h"
21#include "aes_cmac.h" 22#include "aes_cmac.h"
@@ -136,8 +137,7 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
136 struct ieee80211_sub_if_data, 137 struct ieee80211_sub_if_data,
137 u.ap); 138 u.ap);
138 139
139 ret = key->local->ops->set_key(local_to_hw(key->local), SET_KEY, 140 ret = drv_set_key(key->local, SET_KEY, &sdata->vif, sta, &key->conf);
140 &sdata->vif, sta, &key->conf);
141 141
142 if (!ret) { 142 if (!ret) {
143 spin_lock(&todo_lock); 143 spin_lock(&todo_lock);
@@ -179,8 +179,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
179 struct ieee80211_sub_if_data, 179 struct ieee80211_sub_if_data,
180 u.ap); 180 u.ap);
181 181
182 ret = key->local->ops->set_key(local_to_hw(key->local), DISABLE_KEY, 182 ret = drv_set_key(key->local, DISABLE_KEY, &sdata->vif,
183 &sdata->vif, sta, &key->conf); 183 sta, &key->conf);
184 184
185 if (ret) 185 if (ret)
186 printk(KERN_ERR "mac80211-%s: failed to remove key " 186 printk(KERN_ERR "mac80211-%s: failed to remove key "
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5ca62ea15079..b80bc80e46cf 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -26,6 +26,7 @@
26#include <net/cfg80211.h> 26#include <net/cfg80211.h>
27 27
28#include "ieee80211_i.h" 28#include "ieee80211_i.h"
29#include "driver-ops.h"
29#include "rate.h" 30#include "rate.h"
30#include "mesh.h" 31#include "mesh.h"
31#include "wep.h" 32#include "wep.h"
@@ -81,10 +82,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
81 /* be a bit nasty */ 82 /* be a bit nasty */
82 new_flags |= (1<<31); 83 new_flags |= (1<<31);
83 84
84 local->ops->configure_filter(local_to_hw(local), 85 drv_configure_filter(local, changed_flags, &new_flags,
85 changed_flags, &new_flags, 86 local->mdev->mc_count,
86 local->mdev->mc_count, 87 local->mdev->mc_list);
87 local->mdev->mc_list);
88 88
89 WARN_ON(new_flags & (1<<31)); 89 WARN_ON(new_flags & (1<<31));
90 90
@@ -152,82 +152,6 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev)
152 ieee80211_configure_filter(local); 152 ieee80211_configure_filter(local);
153} 153}
154 154
155/* everything else */
156
157int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
158{
159 struct ieee80211_local *local = sdata->local;
160 struct ieee80211_if_conf conf;
161
162 if (WARN_ON(!netif_running(sdata->dev)))
163 return 0;
164
165 memset(&conf, 0, sizeof(conf));
166
167 if (sdata->vif.type == NL80211_IFTYPE_STATION)
168 conf.bssid = sdata->u.mgd.bssid;
169 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
170 conf.bssid = sdata->u.ibss.bssid;
171 else if (sdata->vif.type == NL80211_IFTYPE_AP)
172 conf.bssid = sdata->dev->dev_addr;
173 else if (ieee80211_vif_is_mesh(&sdata->vif)) {
174 static const u8 zero[ETH_ALEN] = { 0 };
175 conf.bssid = zero;
176 } else {
177 WARN_ON(1);
178 return -EINVAL;
179 }
180
181 if (!local->ops->config_interface)
182 return 0;
183
184 switch (sdata->vif.type) {
185 case NL80211_IFTYPE_AP:
186 case NL80211_IFTYPE_ADHOC:
187 case NL80211_IFTYPE_MESH_POINT:
188 break;
189 default:
190 /* do not warn to simplify caller in scan.c */
191 changed &= ~IEEE80211_IFCC_BEACON_ENABLED;
192 if (WARN_ON(changed & IEEE80211_IFCC_BEACON))
193 return -EINVAL;
194 changed &= ~IEEE80211_IFCC_BEACON;
195 break;
196 }
197
198 if (changed & IEEE80211_IFCC_BEACON_ENABLED) {
199 if (local->sw_scanning) {
200 conf.enable_beacon = false;
201 } else {
202 /*
203 * Beacon should be enabled, but AP mode must
204 * check whether there is a beacon configured.
205 */
206 switch (sdata->vif.type) {
207 case NL80211_IFTYPE_AP:
208 conf.enable_beacon =
209 !!rcu_dereference(sdata->u.ap.beacon);
210 break;
211 case NL80211_IFTYPE_ADHOC:
212 conf.enable_beacon = !!sdata->u.ibss.presp;
213 break;
214 case NL80211_IFTYPE_MESH_POINT:
215 conf.enable_beacon = true;
216 break;
217 default:
218 /* not reached */
219 WARN_ON(1);
220 break;
221 }
222 }
223 }
224
225 conf.changed = changed;
226
227 return local->ops->config_interface(local_to_hw(local),
228 &sdata->vif, &conf);
229}
230
231int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 155int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
232{ 156{
233 struct ieee80211_channel *chan; 157 struct ieee80211_channel *chan;
@@ -268,7 +192,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
268 } 192 }
269 193
270 if (changed && local->open_count) { 194 if (changed && local->open_count) {
271 ret = local->ops->config(local_to_hw(local), changed); 195 ret = drv_config(local, changed);
272 /* 196 /*
273 * Goal: 197 * Goal:
274 * HW reconfiguration should never fail, the driver has told 198 * HW reconfiguration should never fail, the driver has told
@@ -294,17 +218,77 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
294{ 218{
295 struct ieee80211_local *local = sdata->local; 219 struct ieee80211_local *local = sdata->local;
296 220
297 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) 221 if (!changed)
298 return; 222 return;
299 223
300 if (!changed) 224 if (sdata->vif.type == NL80211_IFTYPE_STATION)
225 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
226 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
227 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
228 else if (sdata->vif.type == NL80211_IFTYPE_AP)
229 sdata->vif.bss_conf.bssid = sdata->dev->dev_addr;
230 else if (ieee80211_vif_is_mesh(&sdata->vif)) {
231 static const u8 zero[ETH_ALEN] = { 0 };
232 sdata->vif.bss_conf.bssid = zero;
233 } else {
234 WARN_ON(1);
301 return; 235 return;
236 }
237
238 switch (sdata->vif.type) {
239 case NL80211_IFTYPE_AP:
240 case NL80211_IFTYPE_ADHOC:
241 case NL80211_IFTYPE_MESH_POINT:
242 break;
243 default:
244 /* do not warn to simplify caller in scan.c */
245 changed &= ~BSS_CHANGED_BEACON_ENABLED;
246 if (WARN_ON(changed & BSS_CHANGED_BEACON))
247 return;
248 break;
249 }
250
251 if (changed & BSS_CHANGED_BEACON_ENABLED) {
252 if (local->sw_scanning) {
253 sdata->vif.bss_conf.enable_beacon = false;
254 } else {
255 /*
256 * Beacon should be enabled, but AP mode must
257 * check whether there is a beacon configured.
258 */
259 switch (sdata->vif.type) {
260 case NL80211_IFTYPE_AP:
261 sdata->vif.bss_conf.enable_beacon =
262 !!rcu_dereference(sdata->u.ap.beacon);
263 break;
264 case NL80211_IFTYPE_ADHOC:
265 sdata->vif.bss_conf.enable_beacon =
266 !!rcu_dereference(sdata->u.ibss.presp);
267 break;
268 case NL80211_IFTYPE_MESH_POINT:
269 sdata->vif.bss_conf.enable_beacon = true;
270 break;
271 default:
272 /* not reached */
273 WARN_ON(1);
274 break;
275 }
276 }
277 }
302 278
303 if (local->ops->bss_info_changed) 279 drv_bss_info_changed(local, &sdata->vif,
304 local->ops->bss_info_changed(local_to_hw(local), 280 &sdata->vif.bss_conf, changed);
305 &sdata->vif, 281
306 &sdata->vif.bss_conf, 282 /*
307 changed); 283 * DEPRECATED
284 *
285 * ~changed is just there to not do this at resume time
286 */
287 if (changed & BSS_CHANGED_BEACON_INT && ~changed) {
288 local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int;
289 ieee80211_hw_config(local,
290 _IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
291 }
308} 292}
309 293
310u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) 294u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
@@ -783,6 +767,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
783 767
784 INIT_LIST_HEAD(&local->interfaces); 768 INIT_LIST_HEAD(&local->interfaces);
785 mutex_init(&local->iflist_mtx); 769 mutex_init(&local->iflist_mtx);
770 mutex_init(&local->scan_mtx);
786 771
787 spin_lock_init(&local->key_lock); 772 spin_lock_init(&local->key_lock);
788 773
@@ -970,9 +955,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
970 955
971 debugfs_hw_add(local); 956 debugfs_hw_add(local);
972 957
973 if (local->hw.conf.beacon_int < 10)
974 local->hw.conf.beacon_int = 100;
975
976 if (local->hw.max_listen_interval == 0) 958 if (local->hw.max_listen_interval == 0)
977 local->hw.max_listen_interval = 1; 959 local->hw.max_listen_interval = 1;
978 960
@@ -1126,6 +1108,7 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
1126 struct ieee80211_local *local = hw_to_local(hw); 1108 struct ieee80211_local *local = hw_to_local(hw);
1127 1109
1128 mutex_destroy(&local->iflist_mtx); 1110 mutex_destroy(&local->iflist_mtx);
1111 mutex_destroy(&local->scan_mtx);
1129 1112
1130 wiphy_free(local->hw.wiphy); 1113 wiphy_free(local->hw.wiphy);
1131} 1114}
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9a3e5de0410a..9000b01a1671 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -417,7 +417,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
417 417
418 free_plinks = mesh_plink_availables(sdata); 418 free_plinks = mesh_plink_availables(sdata);
419 if (free_plinks != sdata->u.mesh.accepting_plinks) 419 if (free_plinks != sdata->u.mesh.accepting_plinks)
420 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); 420 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
421 421
422 ifmsh->housekeeping = false; 422 ifmsh->housekeeping = false;
423 mod_timer(&ifmsh->housekeeping_timer, 423 mod_timer(&ifmsh->housekeeping_timer,
@@ -432,8 +432,8 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
432 432
433 ifmsh->housekeeping = true; 433 ifmsh->housekeeping = true;
434 queue_work(local->hw.workqueue, &ifmsh->work); 434 queue_work(local->hw.workqueue, &ifmsh->work);
435 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 435 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
436 IEEE80211_IFCC_BEACON_ENABLED); 436 BSS_CHANGED_BEACON_ENABLED);
437} 437}
438 438
439void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) 439void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 3610c11286bc..75c487229f2e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -23,6 +23,7 @@
23#include <asm/unaligned.h> 23#include <asm/unaligned.h>
24 24
25#include "ieee80211_i.h" 25#include "ieee80211_i.h"
26#include "driver-ops.h"
26#include "rate.h" 27#include "rate.h"
27#include "led.h" 28#include "led.h"
28 29
@@ -487,6 +488,13 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
487{ 488{
488 struct ieee80211_conf *conf = &local->hw.conf; 489 struct ieee80211_conf *conf = &local->hw.conf;
489 490
491 /*
492 * If we are scanning right now then the parameters will
493 * take effect when scan finishes.
494 */
495 if (local->hw_scanning || local->sw_scanning)
496 return;
497
490 if (conf->dynamic_ps_timeout > 0 && 498 if (conf->dynamic_ps_timeout > 0 &&
491 !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) { 499 !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
492 mod_timer(&local->dynamic_ps_timer, jiffies + 500 mod_timer(&local->dynamic_ps_timer, jiffies +
@@ -555,7 +563,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
555 maxslp = min_t(int, dtimper, 563 maxslp = min_t(int, dtimper,
556 latency / beaconint_us); 564 latency / beaconint_us);
557 565
558 local->hw.conf.max_sleep_interval = maxslp; 566 local->hw.conf.max_sleep_period = maxslp;
559 local->ps_sdata = found; 567 local->ps_sdata = found;
560 } 568 }
561 } else { 569 } else {
@@ -676,11 +684,10 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
676 local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, 684 local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
677 params.cw_max, params.txop); 685 params.cw_max, params.txop);
678#endif 686#endif
679 if (local->ops->conf_tx && 687 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx)
680 local->ops->conf_tx(local_to_hw(local), queue, &params)) {
681 printk(KERN_DEBUG "%s: failed to set TX queue " 688 printk(KERN_DEBUG "%s: failed to set TX queue "
682 "parameters for queue %d\n", local->mdev->name, queue); 689 "parameters for queue %d\n", local->mdev->name,
683 } 690 queue);
684 } 691 }
685} 692}
686 693
@@ -835,6 +842,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
835 sdata->vif.bss_conf.timestamp = bss->cbss.tsf; 842 sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
836 sdata->vif.bss_conf.dtim_period = bss->dtim_period; 843 sdata->vif.bss_conf.dtim_period = bss->dtim_period;
837 844
845 bss_info_changed |= BSS_CHANGED_BEACON_INT;
838 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 846 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
839 bss->cbss.capability, bss->has_erp_value, bss->erp_value); 847 bss->cbss.capability, bss->has_erp_value, bss->erp_value);
840 848
@@ -882,7 +890,8 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
882 printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", 890 printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
883 sdata->dev->name, ifmgd->bssid); 891 sdata->dev->name, ifmgd->bssid);
884 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 892 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
885 ieee80211_sta_send_apinfo(sdata); 893 ieee80211_recalc_idle(local);
894 cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
886 895
887 /* 896 /*
888 * Most likely AP is not in the range so remove the 897 * Most likely AP is not in the range so remove the
@@ -907,8 +916,6 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
907 916
908 ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE; 917 ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
909 918
910 set_bit(IEEE80211_STA_REQ_DIRECT_PROBE, &ifmgd->request);
911
912 /* Direct probe is sent to broadcast address as some APs 919 /* Direct probe is sent to broadcast address as some APs
913 * will not answer to direct packet in unassociated state. 920 * will not answer to direct packet in unassociated state.
914 */ 921 */
@@ -932,6 +939,7 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
932 " timed out\n", 939 " timed out\n",
933 sdata->dev->name, ifmgd->bssid); 940 sdata->dev->name, ifmgd->bssid);
934 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 941 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
942 ieee80211_recalc_idle(local);
935 cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid); 943 cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
936 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 944 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
937 sdata->local->hw.conf.channel->center_freq, 945 sdata->local->hw.conf.channel->center_freq,
@@ -1035,6 +1043,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1035 1043
1036 rcu_read_unlock(); 1044 rcu_read_unlock();
1037 1045
1046 ieee80211_recalc_idle(local);
1047
1038 /* channel(_type) changes are handled by ieee80211_hw_config */ 1048 /* channel(_type) changes are handled by ieee80211_hw_config */
1039 local->oper_channel_type = NL80211_CHAN_NO_HT; 1049 local->oper_channel_type = NL80211_CHAN_NO_HT;
1040 1050
@@ -1115,6 +1125,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
1115 " timed out\n", 1125 " timed out\n",
1116 sdata->dev->name, ifmgd->bssid); 1126 sdata->dev->name, ifmgd->bssid);
1117 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 1127 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1128 ieee80211_recalc_idle(local);
1118 cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid); 1129 cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid);
1119 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 1130 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
1120 sdata->local->hw.conf.channel->center_freq, 1131 sdata->local->hw.conf.channel->center_freq,
@@ -1135,6 +1146,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
1135 printk(KERN_DEBUG "%s: mismatch in privacy configuration and " 1146 printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
1136 "mixed-cell disabled - abort association\n", sdata->dev->name); 1147 "mixed-cell disabled - abort association\n", sdata->dev->name);
1137 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 1148 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1149 ieee80211_recalc_idle(local);
1138 return; 1150 return;
1139 } 1151 }
1140 1152
@@ -1273,6 +1285,7 @@ static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata)
1273 if (ifmgd->flags & IEEE80211_STA_EXT_SME) { 1285 if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
1274 /* Wait for SME to request association */ 1286 /* Wait for SME to request association */
1275 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 1287 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1288 ieee80211_recalc_idle(sdata->local);
1276 } else 1289 } else
1277 ieee80211_associate(sdata); 1290 ieee80211_associate(sdata);
1278} 1291}
@@ -1509,6 +1522,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1509 if (ifmgd->flags & IEEE80211_STA_EXT_SME) { 1522 if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
1510 /* Wait for SME to decide what to do next */ 1523 /* Wait for SME to decide what to do next */
1511 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 1524 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1525 ieee80211_recalc_idle(local);
1512 } 1526 }
1513 return; 1527 return;
1514 } 1528 }
@@ -1730,8 +1744,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1730 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); 1744 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
1731 1745
1732 /* direct probe may be part of the association flow */ 1746 /* direct probe may be part of the association flow */
1733 if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE, 1747 if (ifmgd->state == IEEE80211_STA_MLME_DIRECT_PROBE) {
1734 &ifmgd->request)) {
1735 printk(KERN_DEBUG "%s direct probe responded\n", 1748 printk(KERN_DEBUG "%s direct probe responded\n",
1736 sdata->dev->name); 1749 sdata->dev->name);
1737 ieee80211_authenticate(sdata); 1750 ieee80211_authenticate(sdata);
@@ -1974,10 +1987,8 @@ static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata)
1974 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1987 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1975 struct ieee80211_local *local = sdata->local; 1988 struct ieee80211_local *local = sdata->local;
1976 1989
1977 if (local->ops->reset_tsf) { 1990 /* Reset own TSF to allow time synchronization work. */
1978 /* Reset own TSF to allow time synchronization work. */ 1991 drv_reset_tsf(local);
1979 local->ops->reset_tsf(local_to_hw(local));
1980 }
1981 1992
1982 ifmgd->wmm_last_param_set = -1; /* allow any WMM update */ 1993 ifmgd->wmm_last_param_set = -1; /* allow any WMM update */
1983 1994
@@ -2065,25 +2076,18 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
2065 return 0; 2076 return 0;
2066 } else { 2077 } else {
2067 if (ifmgd->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) { 2078 if (ifmgd->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
2079
2068 ifmgd->assoc_scan_tries++; 2080 ifmgd->assoc_scan_tries++;
2069 /* XXX maybe racy? */
2070 if (local->scan_req)
2071 return -1;
2072 memcpy(local->int_scan_req.ssids[0].ssid,
2073 ifmgd->ssid, IEEE80211_MAX_SSID_LEN);
2074 if (ifmgd->flags & IEEE80211_STA_AUTO_SSID_SEL)
2075 local->int_scan_req.ssids[0].ssid_len = 0;
2076 else
2077 local->int_scan_req.ssids[0].ssid_len = ifmgd->ssid_len;
2078 2081
2079 if (ieee80211_start_scan(sdata, &local->int_scan_req)) 2082 ieee80211_request_internal_scan(sdata, ifmgd->ssid,
2080 ieee80211_scan_failed(local); 2083 ssid_len);
2081 2084
2082 ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE; 2085 ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
2083 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); 2086 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
2084 } else { 2087 } else {
2085 ifmgd->assoc_scan_tries = 0; 2088 ifmgd->assoc_scan_tries = 0;
2086 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 2089 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
2090 ieee80211_recalc_idle(local);
2087 } 2091 }
2088 } 2092 }
2089 return -1; 2093 return -1;
@@ -2115,14 +2119,8 @@ static void ieee80211_sta_work(struct work_struct *work)
2115 ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE && 2119 ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE &&
2116 ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE && 2120 ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE &&
2117 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) { 2121 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) {
2118 /* 2122 queue_delayed_work(local->hw.workqueue, &local->scan_work,
2119 * The call to ieee80211_start_scan can fail but ieee80211_request_scan 2123 round_jiffies_relative(0));
2120 * (which queued ieee80211_sta_work) did not return an error. Thus, call
2121 * ieee80211_scan_failed here if ieee80211_start_scan fails in order to
2122 * notify the scan requester.
2123 */
2124 if (ieee80211_start_scan(sdata, local->scan_req))
2125 ieee80211_scan_failed(local);
2126 return; 2124 return;
2127 } 2125 }
2128 2126
@@ -2133,6 +2131,8 @@ static void ieee80211_sta_work(struct work_struct *work)
2133 } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request)) 2131 } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request))
2134 return; 2132 return;
2135 2133
2134 ieee80211_recalc_idle(local);
2135
2136 switch (ifmgd->state) { 2136 switch (ifmgd->state) {
2137 case IEEE80211_STA_MLME_DISABLED: 2137 case IEEE80211_STA_MLME_DISABLED:
2138 break; 2138 break;
@@ -2291,12 +2291,8 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
2291 ifmgd->flags &= ~IEEE80211_STA_BSSID_SET; 2291 ifmgd->flags &= ~IEEE80211_STA_BSSID_SET;
2292 } 2292 }
2293 2293
2294 if (netif_running(sdata->dev)) { 2294 if (netif_running(sdata->dev))
2295 if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) { 2295 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
2296 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
2297 "the low-level driver\n", sdata->dev->name);
2298 }
2299 }
2300 2296
2301 return ieee80211_sta_commit(sdata); 2297 return ieee80211_sta_commit(sdata);
2302} 2298}
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index b38986c9deef..9d3d89abbb57 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -2,6 +2,7 @@
2#include <net/rtnetlink.h> 2#include <net/rtnetlink.h>
3 3
4#include "ieee80211_i.h" 4#include "ieee80211_i.h"
5#include "driver-ops.h"
5#include "led.h" 6#include "led.h"
6 7
7int __ieee80211_suspend(struct ieee80211_hw *hw) 8int __ieee80211_suspend(struct ieee80211_hw *hw)
@@ -43,8 +44,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
43 struct ieee80211_sub_if_data, 44 struct ieee80211_sub_if_data,
44 u.ap); 45 u.ap);
45 46
46 local->ops->sta_notify(hw, &sdata->vif, 47 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
47 STA_NOTIFY_REMOVE, &sta->sta); 48 &sta->sta);
48 } 49 }
49 spin_unlock_irqrestore(&local->sta_lock, flags); 50 spin_unlock_irqrestore(&local->sta_lock, flags);
50 } 51 }
@@ -57,7 +58,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
57 conf.vif = &sdata->vif; 58 conf.vif = &sdata->vif;
58 conf.type = sdata->vif.type; 59 conf.type = sdata->vif.type;
59 conf.mac_addr = sdata->dev->dev_addr; 60 conf.mac_addr = sdata->dev->dev_addr;
60 local->ops->remove_interface(hw, &conf); 61 drv_remove_interface(local, &conf);
61 } 62 }
62 } 63 }
63 64
@@ -67,7 +68,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
67 /* stop hardware */ 68 /* stop hardware */
68 if (local->open_count) { 69 if (local->open_count) {
69 ieee80211_led_radio(local, false); 70 ieee80211_led_radio(local, false);
70 local->ops->stop(hw); 71 drv_stop(local);
71 } 72 }
72 return 0; 73 return 0;
73} 74}
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 70df3dcc3cf6..efaf38349731 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -80,8 +80,7 @@ use_low_rate(struct sk_buff *skb)
80 fc = le16_to_cpu(hdr->frame_control); 80 fc = le16_to_cpu(hdr->frame_control);
81 81
82 return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || 82 return ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
83 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || 83 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA);
84 is_multicast_ether_addr(hdr->addr1));
85} 84}
86 85
87 86
@@ -245,7 +244,10 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
245 244
246 if (!sta || !mi || use_low_rate(skb)) { 245 if (!sta || !mi || use_low_rate(skb)) {
247 ar[0].idx = rate_lowest_index(sband, sta); 246 ar[0].idx = rate_lowest_index(sband, sta);
248 ar[0].count = mp->max_retry; 247 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
248 ar[0].count = 1;
249 else
250 ar[0].count = mp->max_retry;
249 return; 251 return;
250 } 252 }
251 253
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 01d59a8e334c..6704fb55c6b2 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -289,13 +289,15 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
289 info->control.rates[0].count = 289 info->control.rates[0].count =
290 txrc->hw->conf.short_frame_max_tx_count; 290 txrc->hw->conf.short_frame_max_tx_count;
291 291
292 /* Send management frames and broadcast/multicast data using lowest 292 /* Send management frames and NO_ACK data using lowest rate. */
293 * rate. */
294 fc = le16_to_cpu(hdr->frame_control); 293 fc = le16_to_cpu(hdr->frame_control);
295 if (!sta || !spinfo || 294 if (!sta || !spinfo ||
296 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || 295 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
297 is_multicast_ether_addr(hdr->addr1)) { 296 info->flags & IEEE80211_TX_CTL_NO_ACK) {
298 info->control.rates[0].idx = rate_lowest_index(sband, sta); 297 info->control.rates[0].idx = rate_lowest_index(sband, sta);
298 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
299 info->control.rates[0].count = 1;
300
299 return; 301 return;
300 } 302 }
301 303
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a5afb79dab6e..d052f4004829 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -19,6 +19,7 @@
19#include <net/ieee80211_radiotap.h> 19#include <net/ieee80211_radiotap.h>
20 20
21#include "ieee80211_i.h" 21#include "ieee80211_i.h"
22#include "driver-ops.h"
22#include "led.h" 23#include "led.h"
23#include "mesh.h" 24#include "mesh.h"
24#include "wep.h" 25#include "wep.h"
@@ -773,9 +774,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
773 774
774 atomic_inc(&sdata->bss->num_sta_ps); 775 atomic_inc(&sdata->bss->num_sta_ps);
775 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); 776 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
776 if (local->ops->sta_notify) 777 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta);
777 local->ops->sta_notify(local_to_hw(local), &sdata->vif,
778 STA_NOTIFY_SLEEP, &sta->sta);
779#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 778#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
780 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", 779 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
781 sdata->dev->name, sta->sta.addr, sta->sta.aid); 780 sdata->dev->name, sta->sta.addr, sta->sta.aid);
@@ -792,9 +791,7 @@ static int ap_sta_ps_end(struct sta_info *sta)
792 atomic_dec(&sdata->bss->num_sta_ps); 791 atomic_dec(&sdata->bss->num_sta_ps);
793 792
794 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); 793 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
795 if (local->ops->sta_notify) 794 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta);
796 local->ops->sta_notify(local_to_hw(local), &sdata->vif,
797 STA_NOTIFY_AWAKE, &sta->sta);
798 795
799 if (!skb_queue_empty(&sta->ps_tx_buf)) 796 if (!skb_queue_empty(&sta->ps_tx_buf))
800 sta_info_clear_tim_bit(sta); 797 sta_info_clear_tim_bit(sta);
@@ -2287,6 +2284,43 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
2287} 2284}
2288 2285
2289 2286
2287static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
2288 struct tid_ampdu_rx *tid_agg_rx,
2289 int index)
2290{
2291 struct ieee80211_supported_band *sband;
2292 struct ieee80211_rate *rate;
2293 struct ieee80211_rx_status status;
2294
2295 if (!tid_agg_rx->reorder_buf[index])
2296 goto no_frame;
2297
2298 /* release the reordered frames to stack */
2299 memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, sizeof(status));
2300 sband = hw->wiphy->bands[status.band];
2301 if (status.flag & RX_FLAG_HT)
2302 rate = sband->bitrates; /* TODO: HT rates */
2303 else
2304 rate = &sband->bitrates[status.rate_idx];
2305 __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
2306 &status, rate);
2307 tid_agg_rx->stored_mpdu_num--;
2308 tid_agg_rx->reorder_buf[index] = NULL;
2309
2310no_frame:
2311 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
2312}
2313
2314
2315/*
2316 * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
2317 * the skb was added to the buffer longer than this time ago, the earlier
2318 * frames that have not yet been received are assumed to be lost and the skb
2319 * can be released for processing. This may also release other skb's from the
2320 * reorder buffer if there are no additional gaps between the frames.
2321 */
2322#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
2323
2290/* 2324/*
2291 * As it function blongs to Rx path it must be called with 2325 * As it function blongs to Rx path it must be called with
2292 * the proper rcu_read_lock protection for its flow. 2326 * the proper rcu_read_lock protection for its flow.
@@ -2298,12 +2332,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2298 u16 mpdu_seq_num, 2332 u16 mpdu_seq_num,
2299 int bar_req) 2333 int bar_req)
2300{ 2334{
2301 struct ieee80211_local *local = hw_to_local(hw);
2302 struct ieee80211_rx_status status;
2303 u16 head_seq_num, buf_size; 2335 u16 head_seq_num, buf_size;
2304 int index; 2336 int index;
2305 struct ieee80211_supported_band *sband;
2306 struct ieee80211_rate *rate;
2307 2337
2308 buf_size = tid_agg_rx->buf_size; 2338 buf_size = tid_agg_rx->buf_size;
2309 head_seq_num = tid_agg_rx->head_seq_num; 2339 head_seq_num = tid_agg_rx->head_seq_num;
@@ -2328,28 +2358,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2328 index = seq_sub(tid_agg_rx->head_seq_num, 2358 index = seq_sub(tid_agg_rx->head_seq_num,
2329 tid_agg_rx->ssn) 2359 tid_agg_rx->ssn)
2330 % tid_agg_rx->buf_size; 2360 % tid_agg_rx->buf_size;
2331 2361 ieee80211_release_reorder_frame(hw, tid_agg_rx,
2332 if (tid_agg_rx->reorder_buf[index]) { 2362 index);
2333 /* release the reordered frames to stack */
2334 memcpy(&status,
2335 tid_agg_rx->reorder_buf[index]->cb,
2336 sizeof(status));
2337 sband = local->hw.wiphy->bands[status.band];
2338 if (status.flag & RX_FLAG_HT) {
2339 /* TODO: HT rates */
2340 rate = sband->bitrates;
2341 } else {
2342 rate = &sband->bitrates
2343 [status.rate_idx];
2344 }
2345 __ieee80211_rx_handle_packet(hw,
2346 tid_agg_rx->reorder_buf[index],
2347 &status, rate);
2348 tid_agg_rx->stored_mpdu_num--;
2349 tid_agg_rx->reorder_buf[index] = NULL;
2350 }
2351 tid_agg_rx->head_seq_num =
2352 seq_inc(tid_agg_rx->head_seq_num);
2353 } 2363 }
2354 if (bar_req) 2364 if (bar_req)
2355 return 1; 2365 return 1;
@@ -2376,26 +2386,50 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2376 2386
2377 /* put the frame in the reordering buffer */ 2387 /* put the frame in the reordering buffer */
2378 tid_agg_rx->reorder_buf[index] = skb; 2388 tid_agg_rx->reorder_buf[index] = skb;
2389 tid_agg_rx->reorder_time[index] = jiffies;
2379 memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus, 2390 memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus,
2380 sizeof(*rxstatus)); 2391 sizeof(*rxstatus));
2381 tid_agg_rx->stored_mpdu_num++; 2392 tid_agg_rx->stored_mpdu_num++;
2382 /* release the buffer until next missing frame */ 2393 /* release the buffer until next missing frame */
2383 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) 2394 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn)
2384 % tid_agg_rx->buf_size; 2395 % tid_agg_rx->buf_size;
2385 while (tid_agg_rx->reorder_buf[index]) { 2396 if (!tid_agg_rx->reorder_buf[index] &&
2386 /* release the reordered frame back to stack */ 2397 tid_agg_rx->stored_mpdu_num > 1) {
2387 memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, 2398 /*
2388 sizeof(status)); 2399 * No buffers ready to be released, but check whether any
2389 sband = local->hw.wiphy->bands[status.band]; 2400 * frames in the reorder buffer have timed out.
2390 if (status.flag & RX_FLAG_HT) 2401 */
2391 rate = sband->bitrates; /* TODO: HT rates */ 2402 int j;
2392 else 2403 int skipped = 1;
2393 rate = &sband->bitrates[status.rate_idx]; 2404 for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
2394 __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], 2405 j = (j + 1) % tid_agg_rx->buf_size) {
2395 &status, rate); 2406 if (tid_agg_rx->reorder_buf[j] == NULL) {
2396 tid_agg_rx->stored_mpdu_num--; 2407 skipped++;
2397 tid_agg_rx->reorder_buf[index] = NULL; 2408 continue;
2398 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); 2409 }
2410 if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
2411 HZ / 10))
2412 break;
2413
2414#ifdef CONFIG_MAC80211_HT_DEBUG
2415 if (net_ratelimit())
2416 printk(KERN_DEBUG "%s: release an RX reorder "
2417 "frame due to timeout on earlier "
2418 "frames\n",
2419 wiphy_name(hw->wiphy));
2420#endif
2421 ieee80211_release_reorder_frame(hw, tid_agg_rx, j);
2422
2423 /*
2424 * Increment the head seq# also for the skipped slots.
2425 */
2426 tid_agg_rx->head_seq_num =
2427 (tid_agg_rx->head_seq_num + skipped) &
2428 SEQ_MASK;
2429 skipped = 0;
2430 }
2431 } else while (tid_agg_rx->reorder_buf[index]) {
2432 ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
2399 index = seq_sub(tid_agg_rx->head_seq_num, 2433 index = seq_sub(tid_agg_rx->head_seq_num,
2400 tid_agg_rx->ssn) % tid_agg_rx->buf_size; 2434 tid_agg_rx->ssn) % tid_agg_rx->buf_size;
2401 } 2435 }
@@ -2517,6 +2551,18 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
2517 return; 2551 return;
2518 } 2552 }
2519 2553
2554 /*
2555 * In theory, the block ack reordering should happen after duplicate
2556 * removal (ieee80211_rx_h_check(), which is an RX handler). As such,
2557 * the call to ieee80211_rx_reorder_ampdu() should really be moved to
2558 * happen as a new RX handler between ieee80211_rx_h_check and
2559 * ieee80211_rx_h_decrypt. This cleanup may eventually happen, but for
2560 * the time being, the call can be here since RX reorder buf processing
2561 * will implicitly skip duplicates. We could, in theory at least,
2562 * process frames that ieee80211_rx_h_passive_scan would drop (e.g.,
2563 * frames from other than operational channel), but that should not
2564 * happen in normal networks.
2565 */
2520 if (!ieee80211_rx_reorder_ampdu(local, skb, status)) 2566 if (!ieee80211_rx_reorder_ampdu(local, skb, status))
2521 __ieee80211_rx_handle_packet(hw, skb, status, rate); 2567 __ieee80211_rx_handle_packet(hw, skb, status, rate);
2522 2568
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index f25b07feabf9..c99ef8d04d3d 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -21,6 +21,7 @@
21#include <net/iw_handler.h> 21#include <net/iw_handler.h>
22 22
23#include "ieee80211_i.h" 23#include "ieee80211_i.h"
24#include "driver-ops.h"
24#include "mesh.h" 25#include "mesh.h"
25 26
26#define IEEE80211_PROBE_DELAY (HZ / 33) 27#define IEEE80211_PROBE_DELAY (HZ / 33)
@@ -202,18 +203,6 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
202 return RX_QUEUED; 203 return RX_QUEUED;
203} 204}
204 205
205void ieee80211_scan_failed(struct ieee80211_local *local)
206{
207 if (WARN_ON(!local->scan_req))
208 return;
209
210 /* notify cfg80211 about the failed scan */
211 if (local->scan_req != &local->int_scan_req)
212 cfg80211_scan_done(local->scan_req, true);
213
214 local->scan_req = NULL;
215}
216
217/* 206/*
218 * inform AP that we will go to sleep so that it will buffer the frames 207 * inform AP that we will go to sleep so that it will buffer the frames
219 * while we scan 208 * while we scan
@@ -274,55 +263,61 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
274 } 263 }
275} 264}
276 265
266static void ieee80211_restore_scan_ies(struct ieee80211_local *local)
267{
268 kfree(local->scan_req->ie);
269 local->scan_req->ie = local->orig_ies;
270 local->scan_req->ie_len = local->orig_ies_len;
271}
272
277void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 273void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
278{ 274{
279 struct ieee80211_local *local = hw_to_local(hw); 275 struct ieee80211_local *local = hw_to_local(hw);
280 struct ieee80211_sub_if_data *sdata; 276 struct ieee80211_sub_if_data *sdata;
277 bool was_hw_scan;
281 278
282 if (WARN_ON(!local->hw_scanning && !local->sw_scanning)) 279 mutex_lock(&local->scan_mtx);
283 return;
284 280
285 if (WARN_ON(!local->scan_req)) 281 if (WARN_ON(!local->hw_scanning && !local->sw_scanning)) {
282 mutex_unlock(&local->scan_mtx);
286 return; 283 return;
284 }
287 285
288 if (local->hw_scanning) { 286 if (WARN_ON(!local->scan_req)) {
289 kfree(local->scan_req->ie); 287 mutex_unlock(&local->scan_mtx);
290 local->scan_req->ie = local->orig_ies; 288 return;
291 local->scan_req->ie_len = local->orig_ies_len;
292 } 289 }
293 290
291 if (local->hw_scanning)
292 ieee80211_restore_scan_ies(local);
293
294 if (local->scan_req != &local->int_scan_req) 294 if (local->scan_req != &local->int_scan_req)
295 cfg80211_scan_done(local->scan_req, aborted); 295 cfg80211_scan_done(local->scan_req, aborted);
296 local->scan_req = NULL; 296 local->scan_req = NULL;
297 297
298 if (local->hw_scanning) { 298 was_hw_scan = local->hw_scanning;
299 local->hw_scanning = false; 299 local->hw_scanning = false;
300 /*
301 * Somebody might have requested channel change during scan
302 * that we won't have acted upon, try now. ieee80211_hw_config
303 * will set the flag based on actual changes.
304 */
305 ieee80211_hw_config(local, 0);
306 goto done;
307 }
308
309 local->sw_scanning = false; 300 local->sw_scanning = false;
301
302 /* we only have to protect scan_req and hw/sw scan */
303 mutex_unlock(&local->scan_mtx);
304
310 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 305 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
306 if (was_hw_scan)
307 goto done;
311 308
312 netif_tx_lock_bh(local->mdev); 309 netif_tx_lock_bh(local->mdev);
313 netif_addr_lock(local->mdev); 310 netif_addr_lock(local->mdev);
314 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC; 311 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
315 local->ops->configure_filter(local_to_hw(local), 312 drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
316 FIF_BCN_PRBRESP_PROMISC, 313 &local->filter_flags,
317 &local->filter_flags, 314 local->mdev->mc_count,
318 local->mdev->mc_count, 315 local->mdev->mc_list);
319 local->mdev->mc_list);
320 316
321 netif_addr_unlock(local->mdev); 317 netif_addr_unlock(local->mdev);
322 netif_tx_unlock_bh(local->mdev); 318 netif_tx_unlock_bh(local->mdev);
323 319
324 if (local->ops->sw_scan_complete) 320 drv_sw_scan_complete(local);
325 local->ops->sw_scan_complete(local_to_hw(local));
326 321
327 mutex_lock(&local->iflist_mtx); 322 mutex_lock(&local->iflist_mtx);
328 list_for_each_entry(sdata, &local->interfaces, list) { 323 list_for_each_entry(sdata, &local->interfaces, list) {
@@ -342,18 +337,160 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
342 if (sdata->vif.type == NL80211_IFTYPE_AP || 337 if (sdata->vif.type == NL80211_IFTYPE_AP ||
343 sdata->vif.type == NL80211_IFTYPE_ADHOC || 338 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
344 sdata->vif.type == NL80211_IFTYPE_MESH_POINT) 339 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
345 ieee80211_if_config(sdata, 340 ieee80211_bss_info_change_notify(
346 IEEE80211_IFCC_BEACON_ENABLED); 341 sdata, BSS_CHANGED_BEACON_ENABLED);
347 } 342 }
348 mutex_unlock(&local->iflist_mtx); 343 mutex_unlock(&local->iflist_mtx);
349 344
350 done: 345 done:
346 ieee80211_recalc_idle(local);
351 ieee80211_mlme_notify_scan_completed(local); 347 ieee80211_mlme_notify_scan_completed(local);
352 ieee80211_ibss_notify_scan_completed(local); 348 ieee80211_ibss_notify_scan_completed(local);
353 ieee80211_mesh_notify_scan_completed(local); 349 ieee80211_mesh_notify_scan_completed(local);
354} 350}
355EXPORT_SYMBOL(ieee80211_scan_completed); 351EXPORT_SYMBOL(ieee80211_scan_completed);
356 352
353static int ieee80211_start_sw_scan(struct ieee80211_local *local)
354{
355 struct ieee80211_sub_if_data *sdata;
356
357 /*
358 * Hardware/driver doesn't support hw_scan, so use software
359 * scanning instead. First send a nullfunc frame with power save
360 * bit on so that AP will buffer the frames for us while we are not
361 * listening, then send probe requests to each channel and wait for
362 * the responses. After all channels are scanned, tune back to the
363 * original channel and send a nullfunc frame with power save bit
364 * off to trigger the AP to send us all the buffered frames.
365 *
366 * Note that while local->sw_scanning is true everything else but
367 * nullfunc frames and probe requests will be dropped in
368 * ieee80211_tx_h_check_assoc().
369 */
370 drv_sw_scan_start(local);
371
372 mutex_lock(&local->iflist_mtx);
373 list_for_each_entry(sdata, &local->interfaces, list) {
374 if (!netif_running(sdata->dev))
375 continue;
376
377 /* disable beaconing */
378 if (sdata->vif.type == NL80211_IFTYPE_AP ||
379 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
380 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
381 ieee80211_bss_info_change_notify(
382 sdata, BSS_CHANGED_BEACON_ENABLED);
383
384 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
385 if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
386 netif_tx_stop_all_queues(sdata->dev);
387 ieee80211_scan_ps_enable(sdata);
388 }
389 } else
390 netif_tx_stop_all_queues(sdata->dev);
391 }
392 mutex_unlock(&local->iflist_mtx);
393
394 local->scan_state = SCAN_SET_CHANNEL;
395 local->scan_channel_idx = 0;
396
397 netif_addr_lock_bh(local->mdev);
398 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
399 drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
400 &local->filter_flags,
401 local->mdev->mc_count,
402 local->mdev->mc_list);
403 netif_addr_unlock_bh(local->mdev);
404
405 /* TODO: start scan as soon as all nullfunc frames are ACKed */
406 queue_delayed_work(local->hw.workqueue, &local->scan_work,
407 IEEE80211_CHANNEL_TIME);
408
409 return 0;
410}
411
412
413static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
414 struct cfg80211_scan_request *req)
415{
416 struct ieee80211_local *local = sdata->local;
417 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
418 int rc;
419
420 if (local->scan_req)
421 return -EBUSY;
422
423 if (local->ops->hw_scan) {
424 u8 *ies;
425 int ielen;
426
427 ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN +
428 local->scan_ies_len + req->ie_len, GFP_KERNEL);
429 if (!ies)
430 return -ENOMEM;
431
432 ielen = ieee80211_build_preq_ies(local, ies,
433 req->ie, req->ie_len);
434 local->orig_ies = req->ie;
435 local->orig_ies_len = req->ie_len;
436 req->ie = ies;
437 req->ie_len = ielen;
438 }
439
440 local->scan_req = req;
441 local->scan_sdata = sdata;
442
443 if (req != &local->int_scan_req &&
444 sdata->vif.type == NL80211_IFTYPE_STATION &&
445 (ifmgd->state == IEEE80211_STA_MLME_DIRECT_PROBE ||
446 ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE ||
447 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE)) {
448 /* actually wait for the assoc to finish/time out */
449 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
450 return 0;
451 }
452
453 if (local->ops->hw_scan)
454 local->hw_scanning = true;
455 else
456 local->sw_scanning = true;
457 /*
458 * Kicking off the scan need not be protected,
459 * only the scan variable stuff, since now
460 * local->scan_req is assigned and other callers
461 * will abort their scan attempts.
462 *
463 * This avoids getting a scan_mtx -> iflist_mtx
464 * dependency, so that the scan completed calls
465 * have more locking freedom.
466 */
467
468 ieee80211_recalc_idle(local);
469 mutex_unlock(&local->scan_mtx);
470
471 if (local->ops->hw_scan)
472 rc = drv_hw_scan(local, local->scan_req);
473 else
474 rc = ieee80211_start_sw_scan(local);
475
476 mutex_lock(&local->scan_mtx);
477
478 if (rc) {
479 if (local->ops->hw_scan) {
480 local->hw_scanning = false;
481 ieee80211_restore_scan_ies(local);
482 } else
483 local->sw_scanning = false;
484
485 ieee80211_recalc_idle(local);
486
487 local->scan_req = NULL;
488 local->scan_sdata = NULL;
489 }
490
491 return rc;
492}
493
357void ieee80211_scan_work(struct work_struct *work) 494void ieee80211_scan_work(struct work_struct *work)
358{ 495{
359 struct ieee80211_local *local = 496 struct ieee80211_local *local =
@@ -363,17 +500,41 @@ void ieee80211_scan_work(struct work_struct *work)
363 int skip, i; 500 int skip, i;
364 unsigned long next_delay = 0; 501 unsigned long next_delay = 0;
365 502
503 mutex_lock(&local->scan_mtx);
504 if (!sdata || !local->scan_req) {
505 mutex_unlock(&local->scan_mtx);
506 return;
507 }
508
509 if (local->scan_req && !(local->sw_scanning || local->hw_scanning)) {
510 struct cfg80211_scan_request *req = local->scan_req;
511 int rc;
512
513 local->scan_req = NULL;
514
515 rc = __ieee80211_start_scan(sdata, req);
516 mutex_unlock(&local->scan_mtx);
517
518 if (rc)
519 ieee80211_scan_completed(&local->hw, true);
520 return;
521 }
522
523 mutex_unlock(&local->scan_mtx);
524
366 /* 525 /*
367 * Avoid re-scheduling when the sdata is going away. 526 * Avoid re-scheduling when the sdata is going away.
368 */ 527 */
369 if (!netif_running(sdata->dev)) 528 if (!netif_running(sdata->dev)) {
529 ieee80211_scan_completed(&local->hw, true);
370 return; 530 return;
531 }
371 532
372 switch (local->scan_state) { 533 switch (local->scan_state) {
373 case SCAN_SET_CHANNEL: 534 case SCAN_SET_CHANNEL:
374 /* if no more bands/channels left, complete scan */ 535 /* if no more bands/channels left, complete scan */
375 if (local->scan_channel_idx >= local->scan_req->n_channels) { 536 if (local->scan_channel_idx >= local->scan_req->n_channels) {
376 ieee80211_scan_completed(local_to_hw(local), false); 537 ieee80211_scan_completed(&local->hw, false);
377 return; 538 return;
378 } 539 }
379 skip = 0; 540 skip = 0;
@@ -422,166 +583,35 @@ void ieee80211_scan_work(struct work_struct *work)
422 next_delay); 583 next_delay);
423} 584}
424 585
425 586int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
426int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata, 587 struct cfg80211_scan_request *req)
427 struct cfg80211_scan_request *req)
428{ 588{
429 struct ieee80211_local *local = scan_sdata->local; 589 int res;
430 struct ieee80211_sub_if_data *sdata;
431
432 if (!req)
433 return -EINVAL;
434
435 if (local->scan_req && local->scan_req != req)
436 return -EBUSY;
437
438 local->scan_req = req;
439 590
440 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1) 591 mutex_lock(&sdata->local->scan_mtx);
441 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS 592 res = __ieee80211_start_scan(sdata, req);
442 * BSSID: MACAddress 593 mutex_unlock(&sdata->local->scan_mtx);
443 * SSID
444 * ScanType: ACTIVE, PASSIVE
445 * ProbeDelay: delay (in microseconds) to be used prior to transmitting
446 * a Probe frame during active scanning
447 * ChannelList
448 * MinChannelTime (>= ProbeDelay), in TU
449 * MaxChannelTime: (>= MinChannelTime), in TU
450 */
451 594
452 /* MLME-SCAN.confirm 595 return res;
453 * BSSDescriptionSet
454 * ResultCode: SUCCESS, INVALID_PARAMETERS
455 */
456
457 if (local->sw_scanning || local->hw_scanning) {
458 if (local->scan_sdata == scan_sdata)
459 return 0;
460 return -EBUSY;
461 }
462
463 if (local->ops->hw_scan) {
464 u8 *ies;
465 int rc, ielen;
466
467 ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN +
468 local->scan_ies_len + req->ie_len, GFP_KERNEL);
469 if (!ies)
470 return -ENOMEM;
471
472 ielen = ieee80211_build_preq_ies(local, ies,
473 req->ie, req->ie_len);
474 local->orig_ies = req->ie;
475 local->orig_ies_len = req->ie_len;
476 req->ie = ies;
477 req->ie_len = ielen;
478
479 local->hw_scanning = true;
480 rc = local->ops->hw_scan(local_to_hw(local), req);
481 if (rc) {
482 local->hw_scanning = false;
483 kfree(ies);
484 req->ie_len = local->orig_ies_len;
485 req->ie = local->orig_ies;
486 return rc;
487 }
488 local->scan_sdata = scan_sdata;
489 return 0;
490 }
491
492 /*
493 * Hardware/driver doesn't support hw_scan, so use software
494 * scanning instead. First send a nullfunc frame with power save
495 * bit on so that AP will buffer the frames for us while we are not
496 * listening, then send probe requests to each channel and wait for
497 * the responses. After all channels are scanned, tune back to the
498 * original channel and send a nullfunc frame with power save bit
499 * off to trigger the AP to send us all the buffered frames.
500 *
501 * Note that while local->sw_scanning is true everything else but
502 * nullfunc frames and probe requests will be dropped in
503 * ieee80211_tx_h_check_assoc().
504 */
505 local->sw_scanning = true;
506 if (local->ops->sw_scan_start)
507 local->ops->sw_scan_start(local_to_hw(local));
508
509 mutex_lock(&local->iflist_mtx);
510 list_for_each_entry(sdata, &local->interfaces, list) {
511 if (!netif_running(sdata->dev))
512 continue;
513
514 /* disable beaconing */
515 if (sdata->vif.type == NL80211_IFTYPE_AP ||
516 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
517 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
518 ieee80211_if_config(sdata,
519 IEEE80211_IFCC_BEACON_ENABLED);
520
521 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
522 if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
523 netif_tx_stop_all_queues(sdata->dev);
524 ieee80211_scan_ps_enable(sdata);
525 }
526 } else
527 netif_tx_stop_all_queues(sdata->dev);
528 }
529 mutex_unlock(&local->iflist_mtx);
530
531 local->scan_state = SCAN_SET_CHANNEL;
532 local->scan_channel_idx = 0;
533 local->scan_sdata = scan_sdata;
534 local->scan_req = req;
535
536 netif_addr_lock_bh(local->mdev);
537 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
538 local->ops->configure_filter(local_to_hw(local),
539 FIF_BCN_PRBRESP_PROMISC,
540 &local->filter_flags,
541 local->mdev->mc_count,
542 local->mdev->mc_list);
543 netif_addr_unlock_bh(local->mdev);
544
545 /* TODO: start scan as soon as all nullfunc frames are ACKed */
546 queue_delayed_work(local->hw.workqueue, &local->scan_work,
547 IEEE80211_CHANNEL_TIME);
548
549 return 0;
550} 596}
551 597
552 598int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
553int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 599 const u8 *ssid, u8 ssid_len)
554 struct cfg80211_scan_request *req)
555{ 600{
556 struct ieee80211_local *local = sdata->local; 601 struct ieee80211_local *local = sdata->local;
557 struct ieee80211_if_managed *ifmgd; 602 int ret = -EBUSY;
558
559 if (!req)
560 return -EINVAL;
561
562 if (local->scan_req && local->scan_req != req)
563 return -EBUSY;
564
565 local->scan_req = req;
566 603
567 if (sdata->vif.type != NL80211_IFTYPE_STATION) 604 mutex_lock(&local->scan_mtx);
568 return ieee80211_start_scan(sdata, req);
569 605
570 /* 606 /* busy scanning */
571 * STA has a state machine that might need to defer scanning 607 if (local->scan_req)
572 * while it's trying to associate/authenticate, therefore we 608 goto unlock;
573 * queue it up to the state machine in that case.
574 */
575 609
576 if (local->sw_scanning || local->hw_scanning) { 610 memcpy(local->int_scan_req.ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
577 if (local->scan_sdata == sdata) 611 local->int_scan_req.ssids[0].ssid_len = ssid_len;
578 return 0;
579 return -EBUSY;
580 }
581
582 ifmgd = &sdata->u.mgd;
583 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
584 queue_work(local->hw.workqueue, &ifmgd->work);
585 612
586 return 0; 613 ret = __ieee80211_start_scan(sdata, &sdata->local->int_scan_req);
614 unlock:
615 mutex_unlock(&local->scan_mtx);
616 return ret;
587} 617}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 654a8e963ccb..a98ea273a155 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -19,6 +19,7 @@
19 19
20#include <net/mac80211.h> 20#include <net/mac80211.h>
21#include "ieee80211_i.h" 21#include "ieee80211_i.h"
22#include "driver-ops.h"
22#include "rate.h" 23#include "rate.h"
23#include "sta_info.h" 24#include "sta_info.h"
24#include "debugfs_sta.h" 25#include "debugfs_sta.h"
@@ -346,8 +347,7 @@ int sta_info_insert(struct sta_info *sta)
346 struct ieee80211_sub_if_data, 347 struct ieee80211_sub_if_data,
347 u.ap); 348 u.ap);
348 349
349 local->ops->sta_notify(local_to_hw(local), &sdata->vif, 350 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta);
350 STA_NOTIFY_ADD, &sta->sta);
351 } 351 }
352 352
353#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 353#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -405,8 +405,7 @@ static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss,
405 405
406 if (sta->local->ops->set_tim) { 406 if (sta->local->ops->set_tim) {
407 sta->local->tim_in_locked_section = true; 407 sta->local->tim_in_locked_section = true;
408 sta->local->ops->set_tim(local_to_hw(sta->local), 408 drv_set_tim(sta->local, &sta->sta, true);
409 &sta->sta, true);
410 sta->local->tim_in_locked_section = false; 409 sta->local->tim_in_locked_section = false;
411 } 410 }
412} 411}
@@ -431,8 +430,7 @@ static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss,
431 430
432 if (sta->local->ops->set_tim) { 431 if (sta->local->ops->set_tim) {
433 sta->local->tim_in_locked_section = true; 432 sta->local->tim_in_locked_section = true;
434 sta->local->ops->set_tim(local_to_hw(sta->local), 433 drv_set_tim(sta->local, &sta->sta, false);
435 &sta->sta, false);
436 sta->local->tim_in_locked_section = false; 434 sta->local->tim_in_locked_section = false;
437 } 435 }
438} 436}
@@ -482,8 +480,8 @@ static void __sta_info_unlink(struct sta_info **sta)
482 struct ieee80211_sub_if_data, 480 struct ieee80211_sub_if_data,
483 u.ap); 481 u.ap);
484 482
485 local->ops->sta_notify(local_to_hw(local), &sdata->vif, 483 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
486 STA_NOTIFY_REMOVE, &(*sta)->sta); 484 &(*sta)->sta);
487 } 485 }
488 486
489 if (ieee80211_vif_is_mesh(&sdata->vif)) { 487 if (ieee80211_vif_is_mesh(&sdata->vif)) {
@@ -543,9 +541,8 @@ void sta_info_unlink(struct sta_info **sta)
543 spin_unlock_irqrestore(&local->sta_lock, flags); 541 spin_unlock_irqrestore(&local->sta_lock, flags);
544} 542}
545 543
546static inline int sta_info_buffer_expired(struct ieee80211_local *local, 544static int sta_info_buffer_expired(struct sta_info *sta,
547 struct sta_info *sta, 545 struct sk_buff *skb)
548 struct sk_buff *skb)
549{ 546{
550 struct ieee80211_tx_info *info; 547 struct ieee80211_tx_info *info;
551 int timeout; 548 int timeout;
@@ -556,8 +553,9 @@ static inline int sta_info_buffer_expired(struct ieee80211_local *local,
556 info = IEEE80211_SKB_CB(skb); 553 info = IEEE80211_SKB_CB(skb);
557 554
558 /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ 555 /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */
559 timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / 556 timeout = (sta->listen_interval *
560 15625) * HZ; 557 sta->sdata->vif.bss_conf.beacon_int *
558 32 / 15625) * HZ;
561 if (timeout < STA_TX_BUFFER_EXPIRE) 559 if (timeout < STA_TX_BUFFER_EXPIRE)
562 timeout = STA_TX_BUFFER_EXPIRE; 560 timeout = STA_TX_BUFFER_EXPIRE;
563 return time_after(jiffies, info->control.jiffies + timeout); 561 return time_after(jiffies, info->control.jiffies + timeout);
@@ -577,7 +575,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
577 for (;;) { 575 for (;;) {
578 spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); 576 spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
579 skb = skb_peek(&sta->ps_tx_buf); 577 skb = skb_peek(&sta->ps_tx_buf);
580 if (sta_info_buffer_expired(local, sta, skb)) 578 if (sta_info_buffer_expired(sta, skb))
581 skb = __skb_dequeue(&sta->ps_tx_buf); 579 skb = __skb_dequeue(&sta->ps_tx_buf);
582 else 580 else
583 skb = NULL; 581 skb = NULL;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 31a8990ce401..164b16cbe0a5 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -88,6 +88,7 @@ struct tid_ampdu_tx {
88 * struct tid_ampdu_rx - TID aggregation information (Rx). 88 * struct tid_ampdu_rx - TID aggregation information (Rx).
89 * 89 *
90 * @reorder_buf: buffer to reorder incoming aggregated MPDUs 90 * @reorder_buf: buffer to reorder incoming aggregated MPDUs
91 * @reorder_time: jiffies when skb was added
91 * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value) 92 * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
92 * @head_seq_num: head sequence number in reordering buffer. 93 * @head_seq_num: head sequence number in reordering buffer.
93 * @stored_mpdu_num: number of MPDUs in reordering buffer 94 * @stored_mpdu_num: number of MPDUs in reordering buffer
@@ -99,6 +100,7 @@ struct tid_ampdu_tx {
99 */ 100 */
100struct tid_ampdu_rx { 101struct tid_ampdu_rx {
101 struct sk_buff **reorder_buf; 102 struct sk_buff **reorder_buf;
103 unsigned long *reorder_time;
102 struct timer_list session_timer; 104 struct timer_list session_timer;
103 u16 head_seq_num; 105 u16 head_seq_num;
104 u16 stored_mpdu_num; 106 u16 stored_mpdu_num;
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 38fa111d2dc6..964b7faa7f17 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -13,6 +13,7 @@
13#include <asm/unaligned.h> 13#include <asm/unaligned.h>
14 14
15#include <net/mac80211.h> 15#include <net/mac80211.h>
16#include "driver-ops.h"
16#include "key.h" 17#include "key.h"
17#include "tkip.h" 18#include "tkip.h"
18#include "wep.h" 19#include "wep.h"
@@ -307,9 +308,8 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
307 if (is_multicast_ether_addr(ra)) 308 if (is_multicast_ether_addr(ra))
308 sta_addr = bcast; 309 sta_addr = bcast;
309 310
310 key->local->ops->update_tkip_key( 311 drv_update_tkip_key(key->local, &key->conf, sta_addr,
311 local_to_hw(key->local), &key->conf, 312 iv32, key->u.tkip.rx[queue].p1k);
312 sta_addr, iv32, key->u.tkip.rx[queue].p1k);
313 } 313 }
314 } 314 }
315 315
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e5b148fe24bb..5f9a8d7af83d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -25,6 +25,7 @@
25#include <asm/unaligned.h> 25#include <asm/unaligned.h>
26 26
27#include "ieee80211_i.h" 27#include "ieee80211_i.h"
28#include "driver-ops.h"
28#include "led.h" 29#include "led.h"
29#include "mesh.h" 30#include "mesh.h"
30#include "wep.h" 31#include "wep.h"
@@ -557,6 +558,10 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
557 if (unlikely(!info->control.rates[0].count)) 558 if (unlikely(!info->control.rates[0].count))
558 info->control.rates[0].count = 1; 559 info->control.rates[0].count = 1;
559 560
561 if (WARN_ON_ONCE((info->control.rates[0].count > 1) &&
562 (info->flags & IEEE80211_TX_CTL_NO_ACK)))
563 info->control.rates[0].count = 1;
564
560 if (is_multicast_ether_addr(hdr->addr1)) { 565 if (is_multicast_ether_addr(hdr->addr1)) {
561 /* 566 /*
562 * XXX: verify the rate is in the basic rateset 567 * XXX: verify the rate is in the basic rateset
@@ -1162,7 +1167,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1162 1167
1163 next = skb->next; 1168 next = skb->next;
1164 len = skb->len; 1169 len = skb->len;
1165 ret = local->ops->tx(local_to_hw(local), skb); 1170 ret = drv_tx(local, skb);
1166 if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { 1171 if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
1167 dev_kfree_skb(skb); 1172 dev_kfree_skb(skb);
1168 ret = NETDEV_TX_OK; 1173 ret = NETDEV_TX_OK;
@@ -2132,7 +2137,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
2132 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 2137 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
2133 /* BSSID is left zeroed, wildcard value */ 2138 /* BSSID is left zeroed, wildcard value */
2134 mgmt->u.beacon.beacon_int = 2139 mgmt->u.beacon.beacon_int =
2135 cpu_to_le16(local->hw.conf.beacon_int); 2140 cpu_to_le16(sdata->vif.bss_conf.beacon_int);
2136 mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */ 2141 mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */
2137 2142
2138 pos = skb_put(skb, 2); 2143 pos = skb_put(skb, 2);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 61876eb50b49..97b613affe08 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -26,6 +26,7 @@
26#include <net/rtnetlink.h> 26#include <net/rtnetlink.h>
27 27
28#include "ieee80211_i.h" 28#include "ieee80211_i.h"
29#include "driver-ops.h"
29#include "rate.h" 30#include "rate.h"
30#include "mesh.h" 31#include "mesh.h"
31#include "wme.h" 32#include "wme.h"
@@ -726,7 +727,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
726 qparam.txop = 0; 727 qparam.txop = 0;
727 728
728 for (i = 0; i < local_to_hw(local)->queues; i++) 729 for (i = 0; i < local_to_hw(local)->queues; i++)
729 local->ops->conf_tx(local_to_hw(local), i, &qparam); 730 drv_conf_tx(local, i, &qparam);
730} 731}
731 732
732void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 733void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
@@ -1000,7 +1001,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1000 1001
1001 /* restart hardware */ 1002 /* restart hardware */
1002 if (local->open_count) { 1003 if (local->open_count) {
1003 res = local->ops->start(hw); 1004 res = drv_start(local);
1004 1005
1005 ieee80211_led_radio(local, hw->conf.radio_enabled); 1006 ieee80211_led_radio(local, hw->conf.radio_enabled);
1006 } 1007 }
@@ -1013,7 +1014,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1013 conf.vif = &sdata->vif; 1014 conf.vif = &sdata->vif;
1014 conf.type = sdata->vif.type; 1015 conf.type = sdata->vif.type;
1015 conf.mac_addr = sdata->dev->dev_addr; 1016 conf.mac_addr = sdata->dev->dev_addr;
1016 res = local->ops->add_interface(hw, &conf); 1017 res = drv_add_interface(local, &conf);
1017 } 1018 }
1018 } 1019 }
1019 1020
@@ -1026,8 +1027,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1026 struct ieee80211_sub_if_data, 1027 struct ieee80211_sub_if_data,
1027 u.ap); 1028 u.ap);
1028 1029
1029 local->ops->sta_notify(hw, &sdata->vif, 1030 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD,
1030 STA_NOTIFY_ADD, &sta->sta); 1031 &sta->sta);
1031 } 1032 }
1032 spin_unlock_irqrestore(&local->sta_lock, flags); 1033 spin_unlock_irqrestore(&local->sta_lock, flags);
1033 } 1034 }
@@ -1045,8 +1046,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1045 rcu_read_unlock(); 1046 rcu_read_unlock();
1046 1047
1047 /* setup RTS threshold */ 1048 /* setup RTS threshold */
1048 if (local->ops->set_rts_threshold) 1049 drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
1049 local->ops->set_rts_threshold(hw, hw->wiphy->rts_threshold);
1050 1050
1051 /* reconfigure hardware */ 1051 /* reconfigure hardware */
1052 ieee80211_hw_config(local, ~0); 1052 ieee80211_hw_config(local, ~0);
@@ -1063,24 +1063,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1063 switch (sdata->vif.type) { 1063 switch (sdata->vif.type) {
1064 case NL80211_IFTYPE_STATION: 1064 case NL80211_IFTYPE_STATION:
1065 /* disable beacon change bits */ 1065 /* disable beacon change bits */
1066 changed &= ~IEEE80211_IFCC_BEACON; 1066 changed &= ~(BSS_CHANGED_BEACON |
1067 BSS_CHANGED_BEACON_ENABLED);
1067 /* fall through */ 1068 /* fall through */
1068 case NL80211_IFTYPE_ADHOC: 1069 case NL80211_IFTYPE_ADHOC:
1069 case NL80211_IFTYPE_AP: 1070 case NL80211_IFTYPE_AP:
1070 case NL80211_IFTYPE_MESH_POINT: 1071 case NL80211_IFTYPE_MESH_POINT:
1071 /* 1072 ieee80211_bss_info_change_notify(sdata, changed);
1072 * Driver's config_interface can fail if rfkill is
1073 * enabled. Accommodate this return code.
1074 * FIXME: When mac80211 has knowledge of rfkill
1075 * state the code below can change back to:
1076 * WARN(ieee80211_if_config(sdata, changed));
1077 * ieee80211_bss_info_change_notify(sdata, ~0);
1078 */
1079 if (ieee80211_if_config(sdata, changed))
1080 printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
1081 sdata->dev->name);
1082 else
1083 ieee80211_bss_info_change_notify(sdata, ~0);
1084 break; 1073 break;
1085 case NL80211_IFTYPE_WDS: 1074 case NL80211_IFTYPE_WDS:
1086 break; 1075 break;
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 1a649da42c41..6b4eb8d43a4e 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -185,7 +185,7 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev,
185 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 185 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
186 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); 186 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
187 187
188 freq->m = local->hw.conf.channel->center_freq; 188 freq->m = local->oper_channel->center_freq;
189 freq->e = 6; 189 freq->e = 6;
190 190
191 return 0; 191 return 0;
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index e2d4510623f2..4f5a83183c95 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -75,6 +75,11 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
75 75
76 rfkill_led_trigger(rfkill, rfkill->state); 76 rfkill_led_trigger(rfkill, rfkill->state);
77} 77}
78#else
79static inline void rfkill_led_trigger(struct rfkill *rfkill,
80 enum rfkill_state state)
81{
82}
78#endif /* CONFIG_RFKILL_LEDS */ 83#endif /* CONFIG_RFKILL_LEDS */
79 84
80static void rfkill_uevent(struct rfkill *rfkill) 85static void rfkill_uevent(struct rfkill *rfkill)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b1fc98225fd1..3c53c5cbc3a9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3696,9 +3696,9 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
3696 NL80211_CMD_DISASSOCIATE); 3696 NL80211_CMD_DISASSOCIATE);
3697} 3697}
3698 3698
3699void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, 3699static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
3700 struct net_device *netdev, int cmd, 3700 struct net_device *netdev, int cmd,
3701 const u8 *addr) 3701 const u8 *addr)
3702{ 3702{
3703 struct sk_buff *msg; 3703 struct sk_buff *msg;
3704 void *hdr; 3704 void *hdr;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 139d13fdc94f..537af62ec42b 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2113,14 +2113,14 @@ void reg_device_remove(struct wiphy *wiphy)
2113 2113
2114 assert_cfg80211_lock(); 2114 assert_cfg80211_lock();
2115 2115
2116 kfree(wiphy->regd);
2117
2116 if (last_request) 2118 if (last_request)
2117 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 2119 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
2118 2120
2119 kfree(wiphy->regd); 2121 if (!request_wiphy || request_wiphy != wiphy)
2120 if (!last_request || !request_wiphy)
2121 return;
2122 if (request_wiphy != wiphy)
2123 return; 2122 return;
2123
2124 last_request->wiphy_idx = WIPHY_IDX_STALE; 2124 last_request->wiphy_idx = WIPHY_IDX_STALE;
2125 last_request->country_ie_env = ENVIRON_ANY; 2125 last_request->country_ie_env = ENVIRON_ANY;
2126} 2126}
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index dfb53d19fd77..df59440290e5 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -377,18 +377,16 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
377 size_t used = dev->wiphy.bss_priv_size + sizeof(*res); 377 size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
378 size_t ielen = res->pub.len_information_elements; 378 size_t ielen = res->pub.len_information_elements;
379 379
380 if (ksize(found) >= used + ielen) { 380 if (!found->ies_allocated && ksize(found) >= used + ielen) {
381 memcpy(found->pub.information_elements, 381 memcpy(found->pub.information_elements,
382 res->pub.information_elements, ielen); 382 res->pub.information_elements, ielen);
383 found->pub.len_information_elements = ielen; 383 found->pub.len_information_elements = ielen;
384 } else { 384 } else {
385 u8 *ies = found->pub.information_elements; 385 u8 *ies = found->pub.information_elements;
386 386
387 if (found->ies_allocated) { 387 if (found->ies_allocated)
388 if (ksize(ies) < ielen) 388 ies = krealloc(ies, ielen, GFP_ATOMIC);
389 ies = krealloc(ies, ielen, 389 else
390 GFP_ATOMIC);
391 } else
392 ies = kmalloc(ielen, GFP_ATOMIC); 390 ies = kmalloc(ielen, GFP_ATOMIC);
393 391
394 if (ies) { 392 if (ies) {