aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-12-30 16:51:29 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-30 16:51:29 -0500
commit3a999e6eb5d277cd6a321dcda3fc43c3d9e4e4b8 (patch)
treeb0ad8d03710ee556e97515ba1c949233859391ce /net
parent6cd9b49d7328c4656bfc17fcb47fb814955d40d2 (diff)
parent891dc5e73783eeabd2a704a9425e2a199b39c9f9 (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/Makefile4
-rw-r--r--net/mac80211/cfg.c32
-rw-r--r--net/mac80211/debugfs_netdev.c2
-rw-r--r--net/mac80211/driver-ops.h77
-rw-r--r--net/mac80211/driver-trace.h21
-rw-r--r--net/mac80211/ibss.c53
-rw-r--r--net/mac80211/ieee80211_i.h141
-rw-r--r--net/mac80211/iface.c37
-rw-r--r--net/mac80211/key.c4
-rw-r--r--net/mac80211/main.c11
-rw-r--r--net/mac80211/mesh.c2
-rw-r--r--net/mac80211/mlme.c1081
-rw-r--r--net/mac80211/offchannel.c168
-rw-r--r--net/mac80211/pm.c8
-rw-r--r--net/mac80211/rx.c11
-rw-r--r--net/mac80211/scan.c208
-rw-r--r--net/mac80211/sta_info.c7
-rw-r--r--net/mac80211/status.c2
-rw-r--r--net/mac80211/tx.c6
-rw-r--r--net/mac80211/util.c163
-rw-r--r--net/mac80211/work.c1086
-rw-r--r--net/wireless/Kconfig15
-rw-r--r--net/wireless/chan.c41
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/mlme.c50
-rw-r--r--net/wireless/nl80211.c245
-rw-r--r--net/wireless/nl80211.h15
-rw-r--r--net/wireless/reg.c89
-rw-r--r--net/wireless/scan.c13
29 files changed, 2295 insertions, 1300 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 298cfcc1bf8d..04420291e7ad 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -6,10 +6,10 @@ mac80211-y := \
6 sta_info.o \ 6 sta_info.o \
7 wep.o \ 7 wep.o \
8 wpa.o \ 8 wpa.o \
9 scan.o \ 9 scan.o offchannel.o \
10 ht.o agg-tx.o agg-rx.o \ 10 ht.o agg-tx.o agg-rx.o \
11 ibss.o \ 11 ibss.o \
12 mlme.o \ 12 mlme.o work.o \
13 iface.o \ 13 iface.o \
14 rate.o \ 14 rate.o \
15 michael.o \ 15 michael.o \
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 63843e3e576a..2e5e841e9b7b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -78,17 +78,15 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
78 enum nl80211_iftype type, u32 *flags, 78 enum nl80211_iftype type, u32 *flags,
79 struct vif_params *params) 79 struct vif_params *params)
80{ 80{
81 struct ieee80211_sub_if_data *sdata; 81 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
82 int ret; 82 int ret;
83 83
84 if (netif_running(dev)) 84 if (ieee80211_sdata_running(sdata))
85 return -EBUSY; 85 return -EBUSY;
86 86
87 if (!nl80211_params_check(type, params)) 87 if (!nl80211_params_check(type, params))
88 return -EINVAL; 88 return -EINVAL;
89 89
90 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
91
92 ret = ieee80211_if_change_type(sdata, type); 90 ret = ieee80211_if_change_type(sdata, type);
93 if (ret) 91 if (ret)
94 return ret; 92 return ret;
@@ -1345,7 +1343,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1345 return 0; 1343 return 0;
1346 } 1344 }
1347 1345
1348 ap = sdata->u.mgd.associated->cbss.bssid; 1346 ap = sdata->u.mgd.associated->bssid;
1349 1347
1350 if (smps_mode == IEEE80211_SMPS_AUTOMATIC) { 1348 if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
1351 if (sdata->u.mgd.powersave) 1349 if (sdata->u.mgd.powersave)
@@ -1443,6 +1441,28 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1443 return -EINVAL; 1441 return -EINVAL;
1444} 1442}
1445 1443
1444static int ieee80211_remain_on_channel(struct wiphy *wiphy,
1445 struct net_device *dev,
1446 struct ieee80211_channel *chan,
1447 enum nl80211_channel_type channel_type,
1448 unsigned int duration,
1449 u64 *cookie)
1450{
1451 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1452
1453 return ieee80211_wk_remain_on_channel(sdata, chan, channel_type,
1454 duration, cookie);
1455}
1456
1457static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
1458 struct net_device *dev,
1459 u64 cookie)
1460{
1461 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1462
1463 return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);
1464}
1465
1446struct cfg80211_ops mac80211_config_ops = { 1466struct cfg80211_ops mac80211_config_ops = {
1447 .add_virtual_intf = ieee80211_add_iface, 1467 .add_virtual_intf = ieee80211_add_iface,
1448 .del_virtual_intf = ieee80211_del_iface, 1468 .del_virtual_intf = ieee80211_del_iface,
@@ -1489,4 +1509,6 @@ struct cfg80211_ops mac80211_config_ops = {
1489 CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) 1509 CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
1490 .set_power_mgmt = ieee80211_set_power_mgmt, 1510 .set_power_mgmt = ieee80211_set_power_mgmt,
1491 .set_bitrate_mask = ieee80211_set_bitrate_mask, 1511 .set_bitrate_mask = ieee80211_set_bitrate_mask,
1512 .remain_on_channel = ieee80211_remain_on_channel,
1513 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1492}; 1514};
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 355983503885..59f6e3bcbd09 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -133,7 +133,6 @@ IEEE80211_IF_FILE(max_ratectrl_rateidx, max_ratectrl_rateidx, DEC);
133/* STA attributes */ 133/* STA attributes */
134IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 134IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
135IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); 135IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
136IEEE80211_IF_FILE(capab, u.mgd.capab, HEX);
137 136
138static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, 137static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
139 enum ieee80211_smps_mode smps_mode) 138 enum ieee80211_smps_mode smps_mode)
@@ -270,7 +269,6 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
270 269
271 DEBUGFS_ADD(bssid, sta); 270 DEBUGFS_ADD(bssid, sta);
272 DEBUGFS_ADD(aid, sta); 271 DEBUGFS_ADD(aid, sta);
273 DEBUGFS_ADD(capab, sta);
274 DEBUGFS_ADD_MODE(smps, 0600); 272 DEBUGFS_ADD_MODE(smps, 0600);
275} 273}
276 274
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 727e4cf7b8a6..8757ea73d544 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -14,6 +14,8 @@ static inline int drv_start(struct ieee80211_local *local)
14{ 14{
15 int ret; 15 int ret;
16 16
17 might_sleep();
18
17 local->started = true; 19 local->started = true;
18 smp_mb(); 20 smp_mb();
19 ret = local->ops->start(&local->hw); 21 ret = local->ops->start(&local->hw);
@@ -23,6 +25,8 @@ static inline int drv_start(struct ieee80211_local *local)
23 25
24static inline void drv_stop(struct ieee80211_local *local) 26static inline void drv_stop(struct ieee80211_local *local)
25{ 27{
28 might_sleep();
29
26 local->ops->stop(&local->hw); 30 local->ops->stop(&local->hw);
27 trace_drv_stop(local); 31 trace_drv_stop(local);
28 32
@@ -36,23 +40,33 @@ static inline void drv_stop(struct ieee80211_local *local)
36} 40}
37 41
38static inline int drv_add_interface(struct ieee80211_local *local, 42static inline int drv_add_interface(struct ieee80211_local *local,
39 struct ieee80211_if_init_conf *conf) 43 struct ieee80211_vif *vif)
40{ 44{
41 int ret = local->ops->add_interface(&local->hw, conf); 45 int ret;
42 trace_drv_add_interface(local, vif_to_sdata(conf->vif), ret); 46
47 might_sleep();
48
49 ret = local->ops->add_interface(&local->hw, vif);
50 trace_drv_add_interface(local, vif_to_sdata(vif), ret);
43 return ret; 51 return ret;
44} 52}
45 53
46static inline void drv_remove_interface(struct ieee80211_local *local, 54static inline void drv_remove_interface(struct ieee80211_local *local,
47 struct ieee80211_if_init_conf *conf) 55 struct ieee80211_vif *vif)
48{ 56{
49 local->ops->remove_interface(&local->hw, conf); 57 might_sleep();
50 trace_drv_remove_interface(local, vif_to_sdata(conf->vif)); 58
59 local->ops->remove_interface(&local->hw, vif);
60 trace_drv_remove_interface(local, vif_to_sdata(vif));
51} 61}
52 62
53static inline int drv_config(struct ieee80211_local *local, u32 changed) 63static inline int drv_config(struct ieee80211_local *local, u32 changed)
54{ 64{
55 int ret = local->ops->config(&local->hw, changed); 65 int ret;
66
67 might_sleep();
68
69 ret = local->ops->config(&local->hw, changed);
56 trace_drv_config(local, changed, ret); 70 trace_drv_config(local, changed, ret);
57 return ret; 71 return ret;
58} 72}
@@ -62,6 +76,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
62 struct ieee80211_bss_conf *info, 76 struct ieee80211_bss_conf *info,
63 u32 changed) 77 u32 changed)
64{ 78{
79 might_sleep();
80
65 if (local->ops->bss_info_changed) 81 if (local->ops->bss_info_changed)
66 local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); 82 local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
67 trace_drv_bss_info_changed(local, sdata, info, changed); 83 trace_drv_bss_info_changed(local, sdata, info, changed);
@@ -111,7 +127,11 @@ static inline int drv_set_key(struct ieee80211_local *local,
111 struct ieee80211_sta *sta, 127 struct ieee80211_sta *sta,
112 struct ieee80211_key_conf *key) 128 struct ieee80211_key_conf *key)
113{ 129{
114 int ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); 130 int ret;
131
132 might_sleep();
133
134 ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
115 trace_drv_set_key(local, cmd, sdata, sta, key, ret); 135 trace_drv_set_key(local, cmd, sdata, sta, key, ret);
116 return ret; 136 return ret;
117} 137}
@@ -121,6 +141,8 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local,
121 const u8 *address, u32 iv32, 141 const u8 *address, u32 iv32,
122 u16 *phase1key) 142 u16 *phase1key)
123{ 143{
144 might_sleep();
145
124 if (local->ops->update_tkip_key) 146 if (local->ops->update_tkip_key)
125 local->ops->update_tkip_key(&local->hw, conf, address, 147 local->ops->update_tkip_key(&local->hw, conf, address,
126 iv32, phase1key); 148 iv32, phase1key);
@@ -130,13 +152,19 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local,
130static inline int drv_hw_scan(struct ieee80211_local *local, 152static inline int drv_hw_scan(struct ieee80211_local *local,
131 struct cfg80211_scan_request *req) 153 struct cfg80211_scan_request *req)
132{ 154{
133 int ret = local->ops->hw_scan(&local->hw, req); 155 int ret;
156
157 might_sleep();
158
159 ret = local->ops->hw_scan(&local->hw, req);
134 trace_drv_hw_scan(local, req, ret); 160 trace_drv_hw_scan(local, req, ret);
135 return ret; 161 return ret;
136} 162}
137 163
138static inline void drv_sw_scan_start(struct ieee80211_local *local) 164static inline void drv_sw_scan_start(struct ieee80211_local *local)
139{ 165{
166 might_sleep();
167
140 if (local->ops->sw_scan_start) 168 if (local->ops->sw_scan_start)
141 local->ops->sw_scan_start(&local->hw); 169 local->ops->sw_scan_start(&local->hw);
142 trace_drv_sw_scan_start(local); 170 trace_drv_sw_scan_start(local);
@@ -144,6 +172,8 @@ static inline void drv_sw_scan_start(struct ieee80211_local *local)
144 172
145static inline void drv_sw_scan_complete(struct ieee80211_local *local) 173static inline void drv_sw_scan_complete(struct ieee80211_local *local)
146{ 174{
175 might_sleep();
176
147 if (local->ops->sw_scan_complete) 177 if (local->ops->sw_scan_complete)
148 local->ops->sw_scan_complete(&local->hw); 178 local->ops->sw_scan_complete(&local->hw);
149 trace_drv_sw_scan_complete(local); 179 trace_drv_sw_scan_complete(local);
@@ -154,6 +184,8 @@ static inline int drv_get_stats(struct ieee80211_local *local,
154{ 184{
155 int ret = -EOPNOTSUPP; 185 int ret = -EOPNOTSUPP;
156 186
187 might_sleep();
188
157 if (local->ops->get_stats) 189 if (local->ops->get_stats)
158 ret = local->ops->get_stats(&local->hw, stats); 190 ret = local->ops->get_stats(&local->hw, stats);
159 trace_drv_get_stats(local, stats, ret); 191 trace_drv_get_stats(local, stats, ret);
@@ -173,6 +205,9 @@ static inline int drv_set_rts_threshold(struct ieee80211_local *local,
173 u32 value) 205 u32 value)
174{ 206{
175 int ret = 0; 207 int ret = 0;
208
209 might_sleep();
210
176 if (local->ops->set_rts_threshold) 211 if (local->ops->set_rts_threshold)
177 ret = local->ops->set_rts_threshold(&local->hw, value); 212 ret = local->ops->set_rts_threshold(&local->hw, value);
178 trace_drv_set_rts_threshold(local, value, ret); 213 trace_drv_set_rts_threshold(local, value, ret);
@@ -193,6 +228,9 @@ static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
193 const struct ieee80211_tx_queue_params *params) 228 const struct ieee80211_tx_queue_params *params)
194{ 229{
195 int ret = -EOPNOTSUPP; 230 int ret = -EOPNOTSUPP;
231
232 might_sleep();
233
196 if (local->ops->conf_tx) 234 if (local->ops->conf_tx)
197 ret = local->ops->conf_tx(&local->hw, queue, params); 235 ret = local->ops->conf_tx(&local->hw, queue, params);
198 trace_drv_conf_tx(local, queue, params, ret); 236 trace_drv_conf_tx(local, queue, params, ret);
@@ -210,6 +248,9 @@ static inline int drv_get_tx_stats(struct ieee80211_local *local,
210static inline u64 drv_get_tsf(struct ieee80211_local *local) 248static inline u64 drv_get_tsf(struct ieee80211_local *local)
211{ 249{
212 u64 ret = -1ULL; 250 u64 ret = -1ULL;
251
252 might_sleep();
253
213 if (local->ops->get_tsf) 254 if (local->ops->get_tsf)
214 ret = local->ops->get_tsf(&local->hw); 255 ret = local->ops->get_tsf(&local->hw);
215 trace_drv_get_tsf(local, ret); 256 trace_drv_get_tsf(local, ret);
@@ -218,6 +259,8 @@ static inline u64 drv_get_tsf(struct ieee80211_local *local)
218 259
219static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf) 260static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf)
220{ 261{
262 might_sleep();
263
221 if (local->ops->set_tsf) 264 if (local->ops->set_tsf)
222 local->ops->set_tsf(&local->hw, tsf); 265 local->ops->set_tsf(&local->hw, tsf);
223 trace_drv_set_tsf(local, tsf); 266 trace_drv_set_tsf(local, tsf);
@@ -225,6 +268,8 @@ static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf)
225 268
226static inline void drv_reset_tsf(struct ieee80211_local *local) 269static inline void drv_reset_tsf(struct ieee80211_local *local)
227{ 270{
271 might_sleep();
272
228 if (local->ops->reset_tsf) 273 if (local->ops->reset_tsf)
229 local->ops->reset_tsf(&local->hw); 274 local->ops->reset_tsf(&local->hw);
230 trace_drv_reset_tsf(local); 275 trace_drv_reset_tsf(local);
@@ -233,6 +278,9 @@ static inline void drv_reset_tsf(struct ieee80211_local *local)
233static inline int drv_tx_last_beacon(struct ieee80211_local *local) 278static inline int drv_tx_last_beacon(struct ieee80211_local *local)
234{ 279{
235 int ret = 1; 280 int ret = 1;
281
282 might_sleep();
283
236 if (local->ops->tx_last_beacon) 284 if (local->ops->tx_last_beacon)
237 ret = local->ops->tx_last_beacon(&local->hw); 285 ret = local->ops->tx_last_beacon(&local->hw);
238 trace_drv_tx_last_beacon(local, ret); 286 trace_drv_tx_last_beacon(local, ret);
@@ -256,7 +304,18 @@ static inline int drv_ampdu_action(struct ieee80211_local *local,
256 304
257static inline void drv_rfkill_poll(struct ieee80211_local *local) 305static inline void drv_rfkill_poll(struct ieee80211_local *local)
258{ 306{
307 might_sleep();
308
259 if (local->ops->rfkill_poll) 309 if (local->ops->rfkill_poll)
260 local->ops->rfkill_poll(&local->hw); 310 local->ops->rfkill_poll(&local->hw);
261} 311}
312
313static inline void drv_flush(struct ieee80211_local *local, bool drop)
314{
315 might_sleep();
316
317 trace_drv_flush(local, drop);
318 if (local->ops->flush)
319 local->ops->flush(&local->hw, drop);
320}
262#endif /* __MAC80211_DRIVER_OPS */ 321#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 7a849b920165..977cc7528bc6 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -690,6 +690,27 @@ TRACE_EVENT(drv_ampdu_action,
690 LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret 690 LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret
691 ) 691 )
692); 692);
693
694TRACE_EVENT(drv_flush,
695 TP_PROTO(struct ieee80211_local *local, bool drop),
696
697 TP_ARGS(local, drop),
698
699 TP_STRUCT__entry(
700 LOCAL_ENTRY
701 __field(bool, drop)
702 ),
703
704 TP_fast_assign(
705 LOCAL_ASSIGN;
706 __entry->drop = drop;
707 ),
708
709 TP_printk(
710 LOCAL_PR_FMT " drop:%d",
711 LOCAL_PR_ARG, __entry->drop
712 )
713);
693#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ 714#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
694 715
695#undef TRACE_INCLUDE_PATH 716#undef TRACE_INCLUDE_PATH
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index ef6c6b2401d1..5bcde4c3fba1 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -187,15 +187,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
187static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 187static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
188 struct ieee80211_bss *bss) 188 struct ieee80211_bss *bss)
189{ 189{
190 struct cfg80211_bss *cbss =
191 container_of((void *)bss, struct cfg80211_bss, priv);
190 struct ieee80211_supported_band *sband; 192 struct ieee80211_supported_band *sband;
191 u32 basic_rates; 193 u32 basic_rates;
192 int i, j; 194 int i, j;
193 u16 beacon_int = bss->cbss.beacon_interval; 195 u16 beacon_int = cbss->beacon_interval;
194 196
195 if (beacon_int < 10) 197 if (beacon_int < 10)
196 beacon_int = 10; 198 beacon_int = 10;
197 199
198 sband = sdata->local->hw.wiphy->bands[bss->cbss.channel->band]; 200 sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
199 201
200 basic_rates = 0; 202 basic_rates = 0;
201 203
@@ -212,12 +214,12 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
212 } 214 }
213 } 215 }
214 216
215 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid, 217 __ieee80211_sta_join_ibss(sdata, cbss->bssid,
216 beacon_int, 218 beacon_int,
217 bss->cbss.channel, 219 cbss->channel,
218 basic_rates, 220 basic_rates,
219 bss->cbss.capability, 221 cbss->capability,
220 bss->cbss.tsf); 222 cbss->tsf);
221} 223}
222 224
223static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 225static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -229,6 +231,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
229{ 231{
230 struct ieee80211_local *local = sdata->local; 232 struct ieee80211_local *local = sdata->local;
231 int freq; 233 int freq;
234 struct cfg80211_bss *cbss;
232 struct ieee80211_bss *bss; 235 struct ieee80211_bss *bss;
233 struct sta_info *sta; 236 struct sta_info *sta;
234 struct ieee80211_channel *channel; 237 struct ieee80211_channel *channel;
@@ -283,8 +286,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
283 if (!bss) 286 if (!bss)
284 return; 287 return;
285 288
289 cbss = container_of((void *)bss, struct cfg80211_bss, priv);
290
286 /* was just updated in ieee80211_bss_info_update */ 291 /* was just updated in ieee80211_bss_info_update */
287 beacon_timestamp = bss->cbss.tsf; 292 beacon_timestamp = cbss->tsf;
288 293
289 /* check if we need to merge IBSS */ 294 /* check if we need to merge IBSS */
290 295
@@ -297,11 +302,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
297 goto put_bss; 302 goto put_bss;
298 303
299 /* not an IBSS */ 304 /* not an IBSS */
300 if (!(bss->cbss.capability & WLAN_CAPABILITY_IBSS)) 305 if (!(cbss->capability & WLAN_CAPABILITY_IBSS))
301 goto put_bss; 306 goto put_bss;
302 307
303 /* different channel */ 308 /* different channel */
304 if (bss->cbss.channel != local->oper_channel) 309 if (cbss->channel != local->oper_channel)
305 goto put_bss; 310 goto put_bss;
306 311
307 /* different SSID */ 312 /* different SSID */
@@ -311,7 +316,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
311 goto put_bss; 316 goto put_bss;
312 317
313 /* same BSSID */ 318 /* same BSSID */
314 if (memcmp(bss->cbss.bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) 319 if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0)
315 goto put_bss; 320 goto put_bss;
316 321
317 if (rx_status->flag & RX_FLAG_TSFT) { 322 if (rx_status->flag & RX_FLAG_TSFT) {
@@ -382,6 +387,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
382struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 387struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
383 u8 *bssid,u8 *addr, u32 supp_rates) 388 u8 *bssid,u8 *addr, u32 supp_rates)
384{ 389{
390 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
385 struct ieee80211_local *local = sdata->local; 391 struct ieee80211_local *local = sdata->local;
386 struct sta_info *sta; 392 struct sta_info *sta;
387 int band = local->hw.conf.channel->band; 393 int band = local->hw.conf.channel->band;
@@ -397,6 +403,9 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
397 return NULL; 403 return NULL;
398 } 404 }
399 405
406 if (ifibss->state == IEEE80211_IBSS_MLME_SEARCH)
407 return NULL;
408
400 if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) 409 if (compare_ether_addr(bssid, sdata->u.ibss.bssid))
401 return NULL; 410 return NULL;
402 411
@@ -514,7 +523,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
514{ 523{
515 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 524 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
516 struct ieee80211_local *local = sdata->local; 525 struct ieee80211_local *local = sdata->local;
517 struct ieee80211_bss *bss; 526 struct cfg80211_bss *cbss;
518 struct ieee80211_channel *chan = NULL; 527 struct ieee80211_channel *chan = NULL;
519 const u8 *bssid = NULL; 528 const u8 *bssid = NULL;
520 int active_ibss; 529 int active_ibss;
@@ -538,21 +547,23 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
538 chan = ifibss->channel; 547 chan = ifibss->channel;
539 if (!is_zero_ether_addr(ifibss->bssid)) 548 if (!is_zero_ether_addr(ifibss->bssid))
540 bssid = ifibss->bssid; 549 bssid = ifibss->bssid;
541 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid, 550 cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid,
542 ifibss->ssid, ifibss->ssid_len, 551 ifibss->ssid, ifibss->ssid_len,
543 WLAN_CAPABILITY_IBSS | 552 WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_PRIVACY,
544 WLAN_CAPABILITY_PRIVACY, 553 capability);
545 capability); 554
555 if (cbss) {
556 struct ieee80211_bss *bss;
546 557
547 if (bss) { 558 bss = (void *)cbss->priv;
548#ifdef CONFIG_MAC80211_IBSS_DEBUG 559#ifdef CONFIG_MAC80211_IBSS_DEBUG
549 printk(KERN_DEBUG " sta_find_ibss: selected %pM current " 560 printk(KERN_DEBUG " sta_find_ibss: selected %pM current "
550 "%pM\n", bss->cbss.bssid, ifibss->bssid); 561 "%pM\n", cbss->bssid, ifibss->bssid);
551#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 562#endif /* CONFIG_MAC80211_IBSS_DEBUG */
552 563
553 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" 564 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
554 " based on configured SSID\n", 565 " based on configured SSID\n",
555 sdata->name, bss->cbss.bssid); 566 sdata->name, cbss->bssid);
556 567
557 ieee80211_sta_join_ibss(sdata, bss); 568 ieee80211_sta_join_ibss(sdata, bss);
558 ieee80211_rx_bss_put(local, bss); 569 ieee80211_rx_bss_put(local, bss);
@@ -744,7 +755,7 @@ static void ieee80211_ibss_work(struct work_struct *work)
744 if (WARN_ON(local->suspended)) 755 if (WARN_ON(local->suspended))
745 return; 756 return;
746 757
747 if (!netif_running(sdata->dev)) 758 if (!ieee80211_sdata_running(sdata))
748 return; 759 return;
749 760
750 if (local->scanning) 761 if (local->scanning)
@@ -827,7 +838,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
827 838
828 mutex_lock(&local->iflist_mtx); 839 mutex_lock(&local->iflist_mtx);
829 list_for_each_entry(sdata, &local->interfaces, list) { 840 list_for_each_entry(sdata, &local->interfaces, list) {
830 if (!netif_running(sdata->dev)) 841 if (!ieee80211_sdata_running(sdata))
831 continue; 842 continue;
832 if (sdata->vif.type != NL80211_IFTYPE_ADHOC) 843 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
833 continue; 844 continue;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 88b0ba6c7484..a27921ee6e63 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -71,9 +71,6 @@ struct ieee80211_fragment_entry {
71 71
72 72
73struct ieee80211_bss { 73struct ieee80211_bss {
74 /* Yes, this is a hack */
75 struct cfg80211_bss cbss;
76
77 /* don't want to look up all the time */ 74 /* don't want to look up all the time */
78 size_t ssid_len; 75 size_t ssid_len;
79 u8 ssid[IEEE80211_MAX_SSID_LEN]; 76 u8 ssid[IEEE80211_MAX_SSID_LEN];
@@ -227,31 +224,78 @@ struct mesh_preq_queue {
227 u8 flags; 224 u8 flags;
228}; 225};
229 226
230enum ieee80211_mgd_state { 227enum ieee80211_work_type {
231 IEEE80211_MGD_STATE_IDLE, 228 IEEE80211_WORK_ABORT,
232 IEEE80211_MGD_STATE_PROBE, 229 IEEE80211_WORK_DIRECT_PROBE,
233 IEEE80211_MGD_STATE_AUTH, 230 IEEE80211_WORK_AUTH,
234 IEEE80211_MGD_STATE_ASSOC, 231 IEEE80211_WORK_ASSOC,
232 IEEE80211_WORK_REMAIN_ON_CHANNEL,
235}; 233};
236 234
237struct ieee80211_mgd_work { 235/**
236 * enum work_done_result - indicates what to do after work was done
237 *
238 * @WORK_DONE_DESTROY: This work item is no longer needed, destroy.
239 * @WORK_DONE_REQUEUE: This work item was reset to be reused, and
240 * should be requeued.
241 */
242enum work_done_result {
243 WORK_DONE_DESTROY,
244 WORK_DONE_REQUEUE,
245};
246
247struct ieee80211_work {
238 struct list_head list; 248 struct list_head list;
239 struct ieee80211_bss *bss; 249
240 int ie_len; 250 struct rcu_head rcu_head;
241 u8 prev_bssid[ETH_ALEN]; 251
242 u8 ssid[IEEE80211_MAX_SSID_LEN]; 252 struct ieee80211_sub_if_data *sdata;
243 u8 ssid_len; 253
254 enum work_done_result (*done)(struct ieee80211_work *wk,
255 struct sk_buff *skb);
256
257 struct ieee80211_channel *chan;
258 enum nl80211_channel_type chan_type;
259
244 unsigned long timeout; 260 unsigned long timeout;
245 enum ieee80211_mgd_state state; 261 enum ieee80211_work_type type;
246 u16 auth_alg, auth_transaction;
247 262
248 int tries; 263 u8 filter_ta[ETH_ALEN];
264
265 bool started;
249 266
250 u8 key[WLAN_KEY_LEN_WEP104]; 267 union {
251 u8 key_len, key_idx; 268 struct {
269 int tries;
270 u16 algorithm, transaction;
271 u8 ssid[IEEE80211_MAX_SSID_LEN];
272 u8 ssid_len;
273 u8 key[WLAN_KEY_LEN_WEP104];
274 u8 key_len, key_idx;
275 bool privacy;
276 } probe_auth;
277 struct {
278 struct cfg80211_bss *bss;
279 const u8 *supp_rates;
280 const u8 *ht_information_ie;
281 enum ieee80211_smps_mode smps;
282 int tries;
283 u16 capability;
284 u8 prev_bssid[ETH_ALEN];
285 u8 ssid[IEEE80211_MAX_SSID_LEN];
286 u8 ssid_len;
287 u8 supp_rates_len;
288 bool wmm_used, use_11n;
289 } assoc;
290 struct {
291 u32 duration;
292 bool started;
293 } remain;
294 };
252 295
296 int ie_len;
253 /* must be last */ 297 /* must be last */
254 u8 ie[0]; /* for auth or assoc frame, not probe */ 298 u8 ie[0];
255}; 299};
256 300
257/* flags used in struct ieee80211_if_managed.flags */ 301/* flags used in struct ieee80211_if_managed.flags */
@@ -259,17 +303,11 @@ enum ieee80211_sta_flags {
259 IEEE80211_STA_BEACON_POLL = BIT(0), 303 IEEE80211_STA_BEACON_POLL = BIT(0),
260 IEEE80211_STA_CONNECTION_POLL = BIT(1), 304 IEEE80211_STA_CONNECTION_POLL = BIT(1),
261 IEEE80211_STA_CONTROL_PORT = BIT(2), 305 IEEE80211_STA_CONTROL_PORT = BIT(2),
262 IEEE80211_STA_WMM_ENABLED = BIT(3),
263 IEEE80211_STA_DISABLE_11N = BIT(4), 306 IEEE80211_STA_DISABLE_11N = BIT(4),
264 IEEE80211_STA_CSA_RECEIVED = BIT(5), 307 IEEE80211_STA_CSA_RECEIVED = BIT(5),
265 IEEE80211_STA_MFP_ENABLED = BIT(6), 308 IEEE80211_STA_MFP_ENABLED = BIT(6),
266}; 309};
267 310
268/* flags for MLME request */
269enum ieee80211_sta_request {
270 IEEE80211_STA_REQ_SCAN,
271};
272
273struct ieee80211_if_managed { 311struct ieee80211_if_managed {
274 struct timer_list timer; 312 struct timer_list timer;
275 struct timer_list conn_mon_timer; 313 struct timer_list conn_mon_timer;
@@ -284,14 +322,11 @@ struct ieee80211_if_managed {
284 int probe_send_count; 322 int probe_send_count;
285 323
286 struct mutex mtx; 324 struct mutex mtx;
287 struct ieee80211_bss *associated; 325 struct cfg80211_bss *associated;
288 struct ieee80211_mgd_work *old_associate_work;
289 struct list_head work_list;
290 326
291 u8 bssid[ETH_ALEN]; 327 u8 bssid[ETH_ALEN];
292 328
293 u16 aid; 329 u16 aid;
294 u16 capab;
295 330
296 struct sk_buff_head skb_queue; 331 struct sk_buff_head skb_queue;
297 332
@@ -300,8 +335,6 @@ struct ieee80211_if_managed {
300 enum ieee80211_smps_mode req_smps, /* requested smps mode */ 335 enum ieee80211_smps_mode req_smps, /* requested smps mode */
301 ap_smps; /* smps mode AP thinks we're in */ 336 ap_smps; /* smps mode AP thinks we're in */
302 337
303 unsigned long request;
304
305 unsigned int flags; 338 unsigned int flags;
306 339
307 u32 beacon_crc; 340 u32 beacon_crc;
@@ -568,6 +601,15 @@ struct ieee80211_local {
568 const struct ieee80211_ops *ops; 601 const struct ieee80211_ops *ops;
569 602
570 /* 603 /*
604 * work stuff, potentially off-channel (in the future)
605 */
606 struct mutex work_mtx;
607 struct list_head work_list;
608 struct timer_list work_timer;
609 struct work_struct work_work;
610 struct sk_buff_head work_skb_queue;
611
612 /*
571 * private workqueue to mac80211. mac80211 makes this accessible 613 * private workqueue to mac80211. mac80211 makes this accessible
572 * via ieee80211_queue_work() 614 * via ieee80211_queue_work()
573 */ 615 */
@@ -695,6 +737,10 @@ struct ieee80211_local {
695 enum nl80211_channel_type oper_channel_type; 737 enum nl80211_channel_type oper_channel_type;
696 struct ieee80211_channel *oper_channel, *csa_channel; 738 struct ieee80211_channel *oper_channel, *csa_channel;
697 739
740 /* Temporary remain-on-channel for off-channel operations */
741 struct ieee80211_channel *tmp_channel;
742 enum nl80211_channel_type tmp_channel_type;
743
698 /* SNMP counters */ 744 /* SNMP counters */
699 /* dot11CountersTable */ 745 /* dot11CountersTable */
700 u32 dot11TransmittedFragmentCount; 746 u32 dot11TransmittedFragmentCount;
@@ -752,7 +798,7 @@ struct ieee80211_local {
752 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ 798 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
753 799
754 bool pspolling; 800 bool pspolling;
755 bool scan_ps_enabled; 801 bool offchannel_ps_enabled;
756 /* 802 /*
757 * PS can only be enabled when we have exactly one managed 803 * PS can only be enabled when we have exactly one managed
758 * interface (and monitors) in PS, this then points there. 804 * interface (and monitors) in PS, this then points there.
@@ -947,6 +993,12 @@ ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
947void ieee80211_rx_bss_put(struct ieee80211_local *local, 993void ieee80211_rx_bss_put(struct ieee80211_local *local,
948 struct ieee80211_bss *bss); 994 struct ieee80211_bss *bss);
949 995
996/* off-channel helpers */
997void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local);
998void ieee80211_offchannel_stop_station(struct ieee80211_local *local);
999void ieee80211_offchannel_return(struct ieee80211_local *local,
1000 bool enable_beaconing);
1001
950/* interface handling */ 1002/* interface handling */
951int ieee80211_iface_init(void); 1003int ieee80211_iface_init(void);
952void ieee80211_iface_exit(void); 1004void ieee80211_iface_exit(void);
@@ -960,6 +1012,11 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local);
960u32 __ieee80211_recalc_idle(struct ieee80211_local *local); 1012u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
961void ieee80211_recalc_idle(struct ieee80211_local *local); 1013void ieee80211_recalc_idle(struct ieee80211_local *local);
962 1014
1015static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
1016{
1017 return netif_running(sdata->dev);
1018}
1019
963/* tx handling */ 1020/* tx handling */
964void ieee80211_clear_tx_pending(struct ieee80211_local *local); 1021void ieee80211_clear_tx_pending(struct ieee80211_local *local);
965void ieee80211_tx_pending(unsigned long data); 1022void ieee80211_tx_pending(unsigned long data);
@@ -1106,6 +1163,24 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1106void ieee80211_recalc_smps(struct ieee80211_local *local, 1163void ieee80211_recalc_smps(struct ieee80211_local *local,
1107 struct ieee80211_sub_if_data *forsdata); 1164 struct ieee80211_sub_if_data *forsdata);
1108 1165
1166size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
1167 const u8 *ids, int n_ids, size_t offset);
1168size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
1169
1170/* internal work items */
1171void ieee80211_work_init(struct ieee80211_local *local);
1172void ieee80211_add_work(struct ieee80211_work *wk);
1173void free_work(struct ieee80211_work *wk);
1174void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata);
1175ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1176 struct sk_buff *skb);
1177int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1178 struct ieee80211_channel *chan,
1179 enum nl80211_channel_type channel_type,
1180 unsigned int duration, u64 *cookie);
1181int ieee80211_wk_cancel_remain_on_channel(
1182 struct ieee80211_sub_if_data *sdata, u64 cookie);
1183
1109#ifdef CONFIG_MAC80211_NOINLINE 1184#ifdef CONFIG_MAC80211_NOINLINE
1110#define debug_noinline noinline 1185#define debug_noinline noinline
1111#else 1186#else
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index a6e6da3cab70..00a1f4ccdaf1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -65,7 +65,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
65 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 65 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
66 int ret; 66 int ret;
67 67
68 if (netif_running(dev)) 68 if (ieee80211_sdata_running(sdata))
69 return -EBUSY; 69 return -EBUSY;
70 70
71 ret = eth_mac_addr(dev, addr); 71 ret = eth_mac_addr(dev, addr);
@@ -96,7 +96,6 @@ static int ieee80211_open(struct net_device *dev)
96 struct ieee80211_sub_if_data *nsdata; 96 struct ieee80211_sub_if_data *nsdata;
97 struct ieee80211_local *local = sdata->local; 97 struct ieee80211_local *local = sdata->local;
98 struct sta_info *sta; 98 struct sta_info *sta;
99 struct ieee80211_if_init_conf conf;
100 u32 changed = 0; 99 u32 changed = 0;
101 int res; 100 int res;
102 u32 hw_reconf_flags = 0; 101 u32 hw_reconf_flags = 0;
@@ -111,7 +110,7 @@ static int ieee80211_open(struct net_device *dev)
111 list_for_each_entry(nsdata, &local->interfaces, list) { 110 list_for_each_entry(nsdata, &local->interfaces, list) {
112 struct net_device *ndev = nsdata->dev; 111 struct net_device *ndev = nsdata->dev;
113 112
114 if (ndev != dev && netif_running(ndev)) { 113 if (ndev != dev && ieee80211_sdata_running(nsdata)) {
115 /* 114 /*
116 * Allow only a single IBSS interface to be up at any 115 * Allow only a single IBSS interface to be up at any
117 * time. This is restricted because beacon distribution 116 * time. This is restricted because beacon distribution
@@ -197,7 +196,7 @@ static int ieee80211_open(struct net_device *dev)
197 struct net_device *ndev = nsdata->dev; 196 struct net_device *ndev = nsdata->dev;
198 197
199 /* 198 /*
200 * No need to check netif_running since we do not allow 199 * No need to check running since we do not allow
201 * it to start up with this invalid address. 200 * it to start up with this invalid address.
202 */ 201 */
203 if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) { 202 if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) {
@@ -248,10 +247,7 @@ static int ieee80211_open(struct net_device *dev)
248 ieee80211_configure_filter(local); 247 ieee80211_configure_filter(local);
249 break; 248 break;
250 default: 249 default:
251 conf.vif = &sdata->vif; 250 res = drv_add_interface(local, &sdata->vif);
252 conf.type = sdata->vif.type;
253 conf.mac_addr = sdata->vif.addr;
254 res = drv_add_interface(local, &conf);
255 if (res) 251 if (res)
256 goto err_stop; 252 goto err_stop;
257 253
@@ -334,7 +330,7 @@ static int ieee80211_open(struct net_device *dev)
334 330
335 return 0; 331 return 0;
336 err_del_interface: 332 err_del_interface:
337 drv_remove_interface(local, &conf); 333 drv_remove_interface(local, &sdata->vif);
338 err_stop: 334 err_stop:
339 if (!local->open_count) 335 if (!local->open_count)
340 drv_stop(local); 336 drv_stop(local);
@@ -349,7 +345,6 @@ static int ieee80211_stop(struct net_device *dev)
349{ 345{
350 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 346 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
351 struct ieee80211_local *local = sdata->local; 347 struct ieee80211_local *local = sdata->local;
352 struct ieee80211_if_init_conf conf;
353 struct sta_info *sta; 348 struct sta_info *sta;
354 unsigned long flags; 349 unsigned long flags;
355 struct sk_buff *skb, *tmp; 350 struct sk_buff *skb, *tmp;
@@ -362,6 +357,11 @@ static int ieee80211_stop(struct net_device *dev)
362 netif_stop_queue(dev); 357 netif_stop_queue(dev);
363 358
364 /* 359 /*
360 * Purge work for this interface.
361 */
362 ieee80211_work_purge(sdata);
363
364 /*
365 * Now delete all active aggregation sessions. 365 * Now delete all active aggregation sessions.
366 */ 366 */
367 rcu_read_lock(); 367 rcu_read_lock();
@@ -528,12 +528,9 @@ static int ieee80211_stop(struct net_device *dev)
528 BSS_CHANGED_BEACON_ENABLED); 528 BSS_CHANGED_BEACON_ENABLED);
529 } 529 }
530 530
531 conf.vif = &sdata->vif;
532 conf.type = sdata->vif.type;
533 conf.mac_addr = sdata->vif.addr;
534 /* disable all keys for as long as this netdev is down */ 531 /* disable all keys for as long as this netdev is down */
535 ieee80211_disable_keys(sdata); 532 ieee80211_disable_keys(sdata);
536 drv_remove_interface(local, &conf); 533 drv_remove_interface(local, &sdata->vif);
537 } 534 }
538 535
539 sdata->bss = NULL; 536 sdata->bss = NULL;
@@ -756,7 +753,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
756 * and goes into the requested mode. 753 * and goes into the requested mode.
757 */ 754 */
758 755
759 if (netif_running(sdata->dev)) 756 if (ieee80211_sdata_running(sdata))
760 return -EBUSY; 757 return -EBUSY;
761 758
762 /* Purge and reset type-dependent state. */ 759 /* Purge and reset type-dependent state. */
@@ -917,6 +914,8 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local)
917 wiphy_name(local->hw.wiphy)); 914 wiphy_name(local->hw.wiphy));
918#endif 915#endif
919 916
917 drv_flush(local, false);
918
920 local->hw.conf.flags |= IEEE80211_CONF_IDLE; 919 local->hw.conf.flags |= IEEE80211_CONF_IDLE;
921 return IEEE80211_CONF_CHANGE_IDLE; 920 return IEEE80211_CONF_CHANGE_IDLE;
922} 921}
@@ -926,16 +925,18 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
926 struct ieee80211_sub_if_data *sdata; 925 struct ieee80211_sub_if_data *sdata;
927 int count = 0; 926 int count = 0;
928 927
928 if (!list_empty(&local->work_list))
929 return ieee80211_idle_off(local, "working");
930
929 if (local->scanning) 931 if (local->scanning)
930 return ieee80211_idle_off(local, "scanning"); 932 return ieee80211_idle_off(local, "scanning");
931 933
932 list_for_each_entry(sdata, &local->interfaces, list) { 934 list_for_each_entry(sdata, &local->interfaces, list) {
933 if (!netif_running(sdata->dev)) 935 if (!ieee80211_sdata_running(sdata))
934 continue; 936 continue;
935 /* do not count disabled managed interfaces */ 937 /* do not count disabled managed interfaces */
936 if (sdata->vif.type == NL80211_IFTYPE_STATION && 938 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
937 !sdata->u.mgd.associated && 939 !sdata->u.mgd.associated)
938 list_empty(&sdata->u.mgd.work_list))
939 continue; 940 continue;
940 /* do not count unused IBSS interfaces */ 941 /* do not count unused IBSS interfaces */
941 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && 942 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 32ee6d0ee34d..8160d9c5372e 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -443,7 +443,7 @@ void ieee80211_key_link(struct ieee80211_key *key,
443 add_todo(old_key, KEY_FLAG_TODO_DELETE); 443 add_todo(old_key, KEY_FLAG_TODO_DELETE);
444 444
445 add_todo(key, KEY_FLAG_TODO_ADD_DEBUGFS); 445 add_todo(key, KEY_FLAG_TODO_ADD_DEBUGFS);
446 if (netif_running(sdata->dev)) 446 if (ieee80211_sdata_running(sdata))
447 add_todo(key, KEY_FLAG_TODO_HWACCEL_ADD); 447 add_todo(key, KEY_FLAG_TODO_HWACCEL_ADD);
448 448
449 spin_unlock_irqrestore(&sdata->local->key_lock, flags); 449 spin_unlock_irqrestore(&sdata->local->key_lock, flags);
@@ -509,7 +509,7 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
509{ 509{
510 ASSERT_RTNL(); 510 ASSERT_RTNL();
511 511
512 if (WARN_ON(!netif_running(sdata->dev))) 512 if (WARN_ON(!ieee80211_sdata_running(sdata)))
513 return; 513 return;
514 514
515 ieee80211_todo_for_each_key(sdata, KEY_FLAG_TODO_HWACCEL_ADD); 515 ieee80211_todo_for_each_key(sdata, KEY_FLAG_TODO_HWACCEL_ADD);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d4426748ab10..d0a14d953f08 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -107,6 +107,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
107 if (scan_chan) { 107 if (scan_chan) {
108 chan = scan_chan; 108 chan = scan_chan;
109 channel_type = NL80211_CHAN_NO_HT; 109 channel_type = NL80211_CHAN_NO_HT;
110 } else if (local->tmp_channel) {
111 chan = scan_chan = local->tmp_channel;
112 channel_type = local->tmp_channel_type;
110 } else { 113 } else {
111 chan = local->oper_channel; 114 chan = local->oper_channel;
112 channel_type = local->oper_channel_type; 115 channel_type = local->oper_channel_type;
@@ -212,7 +215,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
212 } 215 }
213 216
214 if (changed & BSS_CHANGED_BEACON_ENABLED) { 217 if (changed & BSS_CHANGED_BEACON_ENABLED) {
215 if (local->quiescing || !netif_running(sdata->dev) || 218 if (local->quiescing || !ieee80211_sdata_running(sdata) ||
216 test_bit(SCAN_SW_SCANNING, &local->scanning)) { 219 test_bit(SCAN_SW_SCANNING, &local->scanning)) {
217 sdata->vif.bss_conf.enable_beacon = false; 220 sdata->vif.bss_conf.enable_beacon = false;
218 } else { 221 } else {
@@ -359,9 +362,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
359 WIPHY_FLAG_4ADDR_STATION; 362 WIPHY_FLAG_4ADDR_STATION;
360 wiphy->privid = mac80211_wiphy_privid; 363 wiphy->privid = mac80211_wiphy_privid;
361 364
362 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ 365 wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
363 wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
364 sizeof(struct cfg80211_bss);
365 366
366 local = wiphy_priv(wiphy); 367 local = wiphy_priv(wiphy);
367 368
@@ -395,6 +396,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
395 396
396 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); 397 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
397 398
399 ieee80211_work_init(local);
400
398 INIT_WORK(&local->restart_work, ieee80211_restart_work); 401 INIT_WORK(&local->restart_work, ieee80211_restart_work);
399 402
400 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); 403 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index e0bd85e3d4b6..61080c5fad50 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -645,7 +645,7 @@ static void ieee80211_mesh_work(struct work_struct *work)
645 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 645 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
646 struct sk_buff *skb; 646 struct sk_buff *skb;
647 647
648 if (!netif_running(sdata->dev)) 648 if (!ieee80211_sdata_running(sdata))
649 return; 649 return;
650 650
651 if (local->scanning) 651 if (local->scanning)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2f9ed8b9c3f0..72920ee07885 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -77,12 +77,6 @@ enum rx_mgmt_action {
77 77
78 /* caller must tell cfg80211 about internal error */ 78 /* caller must tell cfg80211 about internal error */
79 RX_MGMT_CFG80211_ASSOC_ERROR, 79 RX_MGMT_CFG80211_ASSOC_ERROR,
80
81 /* caller must call cfg80211_auth_timeout() & free work */
82 RX_MGMT_CFG80211_AUTH_TO,
83
84 /* caller must call cfg80211_assoc_timeout() & free work */
85 RX_MGMT_CFG80211_ASSOC_TO,
86}; 80};
87 81
88/* utils */ 82/* utils */
@@ -125,27 +119,6 @@ static int ecw2cw(int ecw)
125 return (1 << ecw) - 1; 119 return (1 << ecw) - 1;
126} 120}
127 121
128static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
129 struct ieee80211_supported_band *sband,
130 u32 *rates)
131{
132 int i, j, count;
133 *rates = 0;
134 count = 0;
135 for (i = 0; i < bss->supp_rates_len; i++) {
136 int rate = (bss->supp_rates[i] & 0x7F) * 5;
137
138 for (j = 0; j < sband->n_bitrates; j++)
139 if (sband->bitrates[j].bitrate == rate) {
140 *rates |= BIT(j);
141 count++;
142 break;
143 }
144 }
145
146 return count;
147}
148
149/* 122/*
150 * ieee80211_enable_ht should be called only after the operating band 123 * ieee80211_enable_ht should be called only after the operating band
151 * has been determined as ht configuration depends on the hw's 124 * has been determined as ht configuration depends on the hw's
@@ -231,264 +204,6 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
231 204
232/* frame sending functions */ 205/* frame sending functions */
233 206
234static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
235 struct ieee80211_mgd_work *wk)
236{
237 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
238 struct ieee80211_local *local = sdata->local;
239 struct sk_buff *skb;
240 struct ieee80211_mgmt *mgmt;
241 u8 *pos;
242 const u8 *ies, *ht_ie;
243 int i, len, count, rates_len, supp_rates_len;
244 u16 capab;
245 int wmm = 0;
246 struct ieee80211_supported_band *sband;
247 u32 rates = 0;
248
249 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
250 sizeof(*mgmt) + 200 + wk->ie_len +
251 wk->ssid_len);
252 if (!skb) {
253 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
254 "frame\n", sdata->name);
255 return;
256 }
257 skb_reserve(skb, local->hw.extra_tx_headroom);
258
259 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
260
261 capab = ifmgd->capab;
262
263 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) {
264 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
265 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
266 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
267 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
268 }
269
270 if (wk->bss->cbss.capability & WLAN_CAPABILITY_PRIVACY)
271 capab |= WLAN_CAPABILITY_PRIVACY;
272 if (wk->bss->wmm_used)
273 wmm = 1;
274
275 /* get all rates supported by the device and the AP as
276 * some APs don't like getting a superset of their rates
277 * in the association request (e.g. D-Link DAP 1353 in
278 * b-only mode) */
279 rates_len = ieee80211_compatible_rates(wk->bss, sband, &rates);
280
281 if ((wk->bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
282 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
283 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
284
285 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
286 memset(mgmt, 0, 24);
287 memcpy(mgmt->da, wk->bss->cbss.bssid, ETH_ALEN);
288 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
289 memcpy(mgmt->bssid, wk->bss->cbss.bssid, ETH_ALEN);
290
291 if (!is_zero_ether_addr(wk->prev_bssid)) {
292 skb_put(skb, 10);
293 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
294 IEEE80211_STYPE_REASSOC_REQ);
295 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
296 mgmt->u.reassoc_req.listen_interval =
297 cpu_to_le16(local->hw.conf.listen_interval);
298 memcpy(mgmt->u.reassoc_req.current_ap, wk->prev_bssid,
299 ETH_ALEN);
300 } else {
301 skb_put(skb, 4);
302 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
303 IEEE80211_STYPE_ASSOC_REQ);
304 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
305 mgmt->u.assoc_req.listen_interval =
306 cpu_to_le16(local->hw.conf.listen_interval);
307 }
308
309 /* SSID */
310 ies = pos = skb_put(skb, 2 + wk->ssid_len);
311 *pos++ = WLAN_EID_SSID;
312 *pos++ = wk->ssid_len;
313 memcpy(pos, wk->ssid, wk->ssid_len);
314
315 /* add all rates which were marked to be used above */
316 supp_rates_len = rates_len;
317 if (supp_rates_len > 8)
318 supp_rates_len = 8;
319
320 len = sband->n_bitrates;
321 pos = skb_put(skb, supp_rates_len + 2);
322 *pos++ = WLAN_EID_SUPP_RATES;
323 *pos++ = supp_rates_len;
324
325 count = 0;
326 for (i = 0; i < sband->n_bitrates; i++) {
327 if (BIT(i) & rates) {
328 int rate = sband->bitrates[i].bitrate;
329 *pos++ = (u8) (rate / 5);
330 if (++count == 8)
331 break;
332 }
333 }
334
335 if (rates_len > count) {
336 pos = skb_put(skb, rates_len - count + 2);
337 *pos++ = WLAN_EID_EXT_SUPP_RATES;
338 *pos++ = rates_len - count;
339
340 for (i++; i < sband->n_bitrates; i++) {
341 if (BIT(i) & rates) {
342 int rate = sband->bitrates[i].bitrate;
343 *pos++ = (u8) (rate / 5);
344 }
345 }
346 }
347
348 if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
349 /* 1. power capabilities */
350 pos = skb_put(skb, 4);
351 *pos++ = WLAN_EID_PWR_CAPABILITY;
352 *pos++ = 2;
353 *pos++ = 0; /* min tx power */
354 *pos++ = local->hw.conf.channel->max_power; /* max tx power */
355
356 /* 2. supported channels */
357 /* TODO: get this in reg domain format */
358 pos = skb_put(skb, 2 * sband->n_channels + 2);
359 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
360 *pos++ = 2 * sband->n_channels;
361 for (i = 0; i < sband->n_channels; i++) {
362 *pos++ = ieee80211_frequency_to_channel(
363 sband->channels[i].center_freq);
364 *pos++ = 1; /* one channel in the subband*/
365 }
366 }
367
368 if (wk->ie_len && wk->ie) {
369 pos = skb_put(skb, wk->ie_len);
370 memcpy(pos, wk->ie, wk->ie_len);
371 }
372
373 if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED)) {
374 pos = skb_put(skb, 9);
375 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
376 *pos++ = 7; /* len */
377 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
378 *pos++ = 0x50;
379 *pos++ = 0xf2;
380 *pos++ = 2; /* WME */
381 *pos++ = 0; /* WME info */
382 *pos++ = 1; /* WME ver */
383 *pos++ = 0;
384 }
385
386 /* wmm support is a must to HT */
387 /*
388 * IEEE802.11n does not allow TKIP/WEP as pairwise
389 * ciphers in HT mode. We still associate in non-ht
390 * mode (11a/b/g) if any one of these ciphers is
391 * configured as pairwise.
392 */
393 if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
394 sband->ht_cap.ht_supported &&
395 (ht_ie = ieee80211_bss_get_ie(&wk->bss->cbss, WLAN_EID_HT_INFORMATION)) &&
396 ht_ie[1] >= sizeof(struct ieee80211_ht_info) &&
397 (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) {
398 struct ieee80211_ht_info *ht_info =
399 (struct ieee80211_ht_info *)(ht_ie + 2);
400 u16 cap = sband->ht_cap.cap;
401 __le16 tmp;
402 u32 flags = local->hw.conf.channel->flags;
403
404 /* determine capability flags */
405
406 if (ieee80211_disable_40mhz_24ghz &&
407 sband->band == IEEE80211_BAND_2GHZ) {
408 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
409 cap &= ~IEEE80211_HT_CAP_SGI_40;
410 }
411
412 switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
413 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
414 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
415 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
416 cap &= ~IEEE80211_HT_CAP_SGI_40;
417 }
418 break;
419 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
420 if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
421 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
422 cap &= ~IEEE80211_HT_CAP_SGI_40;
423 }
424 break;
425 }
426
427 /* set SM PS mode properly */
428 cap &= ~IEEE80211_HT_CAP_SM_PS;
429 /* new association always uses requested smps mode */
430 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
431 if (ifmgd->powersave)
432 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
433 else
434 ifmgd->ap_smps = IEEE80211_SMPS_OFF;
435 } else
436 ifmgd->ap_smps = ifmgd->req_smps;
437
438 switch (ifmgd->ap_smps) {
439 case IEEE80211_SMPS_AUTOMATIC:
440 case IEEE80211_SMPS_NUM_MODES:
441 WARN_ON(1);
442 case IEEE80211_SMPS_OFF:
443 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
444 IEEE80211_HT_CAP_SM_PS_SHIFT;
445 break;
446 case IEEE80211_SMPS_STATIC:
447 cap |= WLAN_HT_CAP_SM_PS_STATIC <<
448 IEEE80211_HT_CAP_SM_PS_SHIFT;
449 break;
450 case IEEE80211_SMPS_DYNAMIC:
451 cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
452 IEEE80211_HT_CAP_SM_PS_SHIFT;
453 break;
454 }
455
456 /* reserve and fill IE */
457
458 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
459 *pos++ = WLAN_EID_HT_CAPABILITY;
460 *pos++ = sizeof(struct ieee80211_ht_cap);
461 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
462
463 /* capability flags */
464 tmp = cpu_to_le16(cap);
465 memcpy(pos, &tmp, sizeof(u16));
466 pos += sizeof(u16);
467
468 /* AMPDU parameters */
469 *pos++ = sband->ht_cap.ampdu_factor |
470 (sband->ht_cap.ampdu_density <<
471 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
472
473 /* MCS set */
474 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
475 pos += sizeof(sband->ht_cap.mcs);
476
477 /* extended capabilities */
478 pos += sizeof(__le16);
479
480 /* BF capabilities */
481 pos += sizeof(__le32);
482
483 /* antenna selection */
484 pos += sizeof(u8);
485 }
486
487 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
488 ieee80211_tx_skb(sdata, skb);
489}
490
491
492static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 207static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
493 const u8 *bssid, u16 stype, u16 reason, 208 const u8 *bssid, u16 stype, u16 reason,
494 void *cookie) 209 void *cookie)
@@ -604,7 +319,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
604 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work); 319 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
605 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 320 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
606 321
607 if (!netif_running(sdata->dev)) 322 if (!ieee80211_sdata_running(sdata))
608 return; 323 return;
609 324
610 mutex_lock(&ifmgd->mtx); 325 mutex_lock(&ifmgd->mtx);
@@ -615,7 +330,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
615 ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL); 330 ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL);
616 331
617 /* XXX: shouldn't really modify cfg80211-owned data! */ 332 /* XXX: shouldn't really modify cfg80211-owned data! */
618 ifmgd->associated->cbss.channel = sdata->local->oper_channel; 333 ifmgd->associated->channel = sdata->local->oper_channel;
619 334
620 ieee80211_wake_queues_by_reason(&sdata->local->hw, 335 ieee80211_wake_queues_by_reason(&sdata->local->hw,
621 IEEE80211_QUEUE_STOP_REASON_CSA); 336 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -642,6 +357,8 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
642 struct ieee80211_channel_sw_ie *sw_elem, 357 struct ieee80211_channel_sw_ie *sw_elem,
643 struct ieee80211_bss *bss) 358 struct ieee80211_bss *bss)
644{ 359{
360 struct cfg80211_bss *cbss =
361 container_of((void *)bss, struct cfg80211_bss, priv);
645 struct ieee80211_channel *new_ch; 362 struct ieee80211_channel *new_ch;
646 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 363 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
647 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num); 364 int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
@@ -675,7 +392,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
675 mod_timer(&ifmgd->chswitch_timer, 392 mod_timer(&ifmgd->chswitch_timer,
676 jiffies + 393 jiffies +
677 msecs_to_jiffies(sw_elem->count * 394 msecs_to_jiffies(sw_elem->count *
678 bss->cbss.beacon_interval)); 395 cbss->beacon_interval));
679 } 396 }
680} 397}
681 398
@@ -749,8 +466,13 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
749 return; 466 return;
750 } 467 }
751 468
469 if (!list_empty(&local->work_list)) {
470 local->ps_sdata = NULL;
471 goto change;
472 }
473
752 list_for_each_entry(sdata, &local->interfaces, list) { 474 list_for_each_entry(sdata, &local->interfaces, list) {
753 if (!netif_running(sdata->dev)) 475 if (!ieee80211_sdata_running(sdata))
754 continue; 476 continue;
755 if (sdata->vif.type != NL80211_IFTYPE_STATION) 477 if (sdata->vif.type != NL80211_IFTYPE_STATION)
756 continue; 478 continue;
@@ -759,7 +481,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
759 } 481 }
760 482
761 if (count == 1 && found->u.mgd.powersave && 483 if (count == 1 && found->u.mgd.powersave &&
762 found->u.mgd.associated && list_empty(&found->u.mgd.work_list) && 484 found->u.mgd.associated &&
763 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL | 485 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
764 IEEE80211_STA_CONNECTION_POLL))) { 486 IEEE80211_STA_CONNECTION_POLL))) {
765 s32 beaconint_us; 487 s32 beaconint_us;
@@ -787,6 +509,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
787 local->ps_sdata = NULL; 509 local->ps_sdata = NULL;
788 } 510 }
789 511
512 change:
790 ieee80211_change_ps(local); 513 ieee80211_change_ps(local);
791} 514}
792 515
@@ -846,7 +569,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
846 int count; 569 int count;
847 u8 *pos; 570 u8 *pos;
848 571
849 if (!(ifmgd->flags & IEEE80211_STA_WMM_ENABLED)) 572 if (local->hw.queues < 4)
850 return; 573 return;
851 574
852 if (!wmm_param) 575 if (!wmm_param)
@@ -949,25 +672,24 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
949} 672}
950 673
951static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, 674static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
952 struct ieee80211_mgd_work *wk, 675 struct cfg80211_bss *cbss,
953 u32 bss_info_changed) 676 u32 bss_info_changed)
954{ 677{
678 struct ieee80211_bss *bss = (void *)cbss->priv;
955 struct ieee80211_local *local = sdata->local; 679 struct ieee80211_local *local = sdata->local;
956 struct ieee80211_bss *bss = wk->bss;
957 680
958 bss_info_changed |= BSS_CHANGED_ASSOC; 681 bss_info_changed |= BSS_CHANGED_ASSOC;
959 /* set timing information */ 682 /* set timing information */
960 sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval; 683 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
961 sdata->vif.bss_conf.timestamp = bss->cbss.tsf; 684 sdata->vif.bss_conf.timestamp = cbss->tsf;
962 sdata->vif.bss_conf.dtim_period = bss->dtim_period; 685 sdata->vif.bss_conf.dtim_period = bss->dtim_period;
963 686
964 bss_info_changed |= BSS_CHANGED_BEACON_INT; 687 bss_info_changed |= BSS_CHANGED_BEACON_INT;
965 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 688 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
966 bss->cbss.capability, bss->has_erp_value, bss->erp_value); 689 cbss->capability, bss->has_erp_value, bss->erp_value);
967 690
968 sdata->u.mgd.associated = bss; 691 sdata->u.mgd.associated = cbss;
969 sdata->u.mgd.old_associate_work = wk; 692 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
970 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN);
971 693
972 /* just to be sure */ 694 /* just to be sure */
973 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | 695 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
@@ -1005,93 +727,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1005 netif_carrier_on(sdata->dev); 727 netif_carrier_on(sdata->dev);
1006} 728}
1007 729
1008static enum rx_mgmt_action __must_check 730static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
1009ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
1010 struct ieee80211_mgd_work *wk)
1011{
1012 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1013 struct ieee80211_local *local = sdata->local;
1014
1015 wk->tries++;
1016 if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
1017 printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
1018 sdata->name, wk->bss->cbss.bssid);
1019
1020 /*
1021 * Most likely AP is not in the range so remove the
1022 * bss struct for that AP.
1023 */
1024 cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
1025
1026 /*
1027 * We might have a pending scan which had no chance to run yet
1028 * due to work needing to be done. Hence, queue the STAs work
1029 * again for that.
1030 */
1031 ieee80211_queue_work(&local->hw, &ifmgd->work);
1032 return RX_MGMT_CFG80211_AUTH_TO;
1033 }
1034
1035 printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n",
1036 sdata->name, wk->bss->cbss.bssid,
1037 wk->tries);
1038
1039 /*
1040 * Direct probe is sent to broadcast address as some APs
1041 * will not answer to direct packet in unassociated state.
1042 */
1043 ieee80211_send_probe_req(sdata, NULL, wk->ssid, wk->ssid_len, NULL, 0);
1044
1045 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
1046 run_again(ifmgd, wk->timeout);
1047
1048 return RX_MGMT_NONE;
1049}
1050
1051
1052static enum rx_mgmt_action __must_check
1053ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
1054 struct ieee80211_mgd_work *wk)
1055{
1056 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1057 struct ieee80211_local *local = sdata->local;
1058
1059 wk->tries++;
1060 if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
1061 printk(KERN_DEBUG "%s: authentication with AP %pM"
1062 " timed out\n",
1063 sdata->name, wk->bss->cbss.bssid);
1064
1065 /*
1066 * Most likely AP is not in the range so remove the
1067 * bss struct for that AP.
1068 */
1069 cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
1070
1071 /*
1072 * We might have a pending scan which had no chance to run yet
1073 * due to work needing to be done. Hence, queue the STAs work
1074 * again for that.
1075 */
1076 ieee80211_queue_work(&local->hw, &ifmgd->work);
1077 return RX_MGMT_CFG80211_AUTH_TO;
1078 }
1079
1080 printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n",
1081 sdata->name, wk->bss->cbss.bssid, wk->tries);
1082
1083 ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len,
1084 wk->bss->cbss.bssid, NULL, 0, 0);
1085 wk->auth_transaction = 2;
1086
1087 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
1088 run_again(ifmgd, wk->timeout);
1089
1090 return RX_MGMT_NONE;
1091}
1092
1093static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1094 bool deauth)
1095{ 731{
1096 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 732 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1097 struct ieee80211_local *local = sdata->local; 733 struct ieee80211_local *local = sdata->local;
@@ -1104,21 +740,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1104 if (WARN_ON(!ifmgd->associated)) 740 if (WARN_ON(!ifmgd->associated))
1105 return; 741 return;
1106 742
1107 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); 743 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1108 744
1109 ifmgd->associated = NULL; 745 ifmgd->associated = NULL;
1110 memset(ifmgd->bssid, 0, ETH_ALEN); 746 memset(ifmgd->bssid, 0, ETH_ALEN);
1111 747
1112 if (deauth) {
1113 kfree(ifmgd->old_associate_work);
1114 ifmgd->old_associate_work = NULL;
1115 } else {
1116 struct ieee80211_mgd_work *wk = ifmgd->old_associate_work;
1117
1118 wk->state = IEEE80211_MGD_STATE_IDLE;
1119 list_add(&wk->list, &ifmgd->work_list);
1120 }
1121
1122 /* 748 /*
1123 * we need to commit the associated = NULL change because the 749 * we need to commit the associated = NULL change because the
1124 * scan code uses that to determine whether this iface should 750 * scan code uses that to determine whether this iface should
@@ -1187,44 +813,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1187 sta_info_destroy(sta); 813 sta_info_destroy(sta);
1188} 814}
1189 815
1190static enum rx_mgmt_action __must_check
1191ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1192 struct ieee80211_mgd_work *wk)
1193{
1194 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1195 struct ieee80211_local *local = sdata->local;
1196
1197 wk->tries++;
1198 if (wk->tries > IEEE80211_ASSOC_MAX_TRIES) {
1199 printk(KERN_DEBUG "%s: association with AP %pM"
1200 " timed out\n",
1201 sdata->name, wk->bss->cbss.bssid);
1202
1203 /*
1204 * Most likely AP is not in the range so remove the
1205 * bss struct for that AP.
1206 */
1207 cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
1208
1209 /*
1210 * We might have a pending scan which had no chance to run yet
1211 * due to work needing to be done. Hence, queue the STAs work
1212 * again for that.
1213 */
1214 ieee80211_queue_work(&local->hw, &ifmgd->work);
1215 return RX_MGMT_CFG80211_ASSOC_TO;
1216 }
1217
1218 printk(KERN_DEBUG "%s: associate with AP %pM (try %d)\n",
1219 sdata->name, wk->bss->cbss.bssid, wk->tries);
1220 ieee80211_send_assoc(sdata, wk);
1221
1222 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
1223 run_again(ifmgd, wk->timeout);
1224
1225 return RX_MGMT_NONE;
1226}
1227
1228void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 816void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1229 struct ieee80211_hdr *hdr) 817 struct ieee80211_hdr *hdr)
1230{ 818{
@@ -1248,8 +836,8 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1248 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 836 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1249 const u8 *ssid; 837 const u8 *ssid;
1250 838
1251 ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); 839 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
1252 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, 840 ieee80211_send_probe_req(sdata, ifmgd->associated->bssid,
1253 ssid + 2, ssid[1], NULL, 0); 841 ssid + 2, ssid[1], NULL, 0);
1254 842
1255 ifmgd->probe_send_count++; 843 ifmgd->probe_send_count++;
@@ -1263,12 +851,15 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1263 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 851 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1264 bool already = false; 852 bool already = false;
1265 853
1266 if (!netif_running(sdata->dev)) 854 if (!ieee80211_sdata_running(sdata))
1267 return; 855 return;
1268 856
1269 if (sdata->local->scanning) 857 if (sdata->local->scanning)
1270 return; 858 return;
1271 859
860 if (sdata->local->tmp_channel)
861 return;
862
1272 mutex_lock(&ifmgd->mtx); 863 mutex_lock(&ifmgd->mtx);
1273 864
1274 if (!ifmgd->associated) 865 if (!ifmgd->associated)
@@ -1330,88 +921,8 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
1330} 921}
1331EXPORT_SYMBOL(ieee80211_beacon_loss); 922EXPORT_SYMBOL(ieee80211_beacon_loss);
1332 923
1333static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
1334 struct ieee80211_mgd_work *wk)
1335{
1336 wk->state = IEEE80211_MGD_STATE_IDLE;
1337 printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
1338}
1339
1340
1341static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1342 struct ieee80211_mgd_work *wk,
1343 struct ieee80211_mgmt *mgmt,
1344 size_t len)
1345{
1346 u8 *pos;
1347 struct ieee802_11_elems elems;
1348
1349 pos = mgmt->u.auth.variable;
1350 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1351 if (!elems.challenge)
1352 return;
1353 ieee80211_send_auth(sdata, 3, wk->auth_alg,
1354 elems.challenge - 2, elems.challenge_len + 2,
1355 wk->bss->cbss.bssid,
1356 wk->key, wk->key_len, wk->key_idx);
1357 wk->auth_transaction = 4;
1358}
1359
1360static enum rx_mgmt_action __must_check
1361ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1362 struct ieee80211_mgd_work *wk,
1363 struct ieee80211_mgmt *mgmt, size_t len)
1364{
1365 u16 auth_alg, auth_transaction, status_code;
1366
1367 if (wk->state != IEEE80211_MGD_STATE_AUTH)
1368 return RX_MGMT_NONE;
1369
1370 if (len < 24 + 6)
1371 return RX_MGMT_NONE;
1372
1373 if (memcmp(wk->bss->cbss.bssid, mgmt->sa, ETH_ALEN) != 0)
1374 return RX_MGMT_NONE;
1375
1376 if (memcmp(wk->bss->cbss.bssid, mgmt->bssid, ETH_ALEN) != 0)
1377 return RX_MGMT_NONE;
1378
1379 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
1380 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
1381 status_code = le16_to_cpu(mgmt->u.auth.status_code);
1382
1383 if (auth_alg != wk->auth_alg ||
1384 auth_transaction != wk->auth_transaction)
1385 return RX_MGMT_NONE;
1386
1387 if (status_code != WLAN_STATUS_SUCCESS) {
1388 list_del(&wk->list);
1389 kfree(wk);
1390 return RX_MGMT_CFG80211_AUTH;
1391 }
1392
1393 switch (wk->auth_alg) {
1394 case WLAN_AUTH_OPEN:
1395 case WLAN_AUTH_LEAP:
1396 case WLAN_AUTH_FT:
1397 ieee80211_auth_completed(sdata, wk);
1398 return RX_MGMT_CFG80211_AUTH;
1399 case WLAN_AUTH_SHARED_KEY:
1400 if (wk->auth_transaction == 4) {
1401 ieee80211_auth_completed(sdata, wk);
1402 return RX_MGMT_CFG80211_AUTH;
1403 } else
1404 ieee80211_auth_challenge(sdata, wk, mgmt, len);
1405 break;
1406 }
1407
1408 return RX_MGMT_NONE;
1409}
1410
1411
1412static enum rx_mgmt_action __must_check 924static enum rx_mgmt_action __must_check
1413ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 925ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1414 struct ieee80211_mgd_work *wk,
1415 struct ieee80211_mgmt *mgmt, size_t len) 926 struct ieee80211_mgmt *mgmt, size_t len)
1416{ 927{
1417 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 928 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -1423,23 +934,15 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1423 934
1424 ASSERT_MGD_MTX(ifmgd); 935 ASSERT_MGD_MTX(ifmgd);
1425 936
1426 if (wk) 937 bssid = ifmgd->associated->bssid;
1427 bssid = wk->bss->cbss.bssid;
1428 else
1429 bssid = ifmgd->associated->cbss.bssid;
1430 938
1431 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 939 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
1432 940
1433 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", 941 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
1434 sdata->name, bssid, reason_code); 942 sdata->name, bssid, reason_code);
1435 943
1436 if (!wk) { 944 ieee80211_set_disassoc(sdata);
1437 ieee80211_set_disassoc(sdata, true); 945 ieee80211_recalc_idle(sdata->local);
1438 ieee80211_recalc_idle(sdata->local);
1439 } else {
1440 list_del(&wk->list);
1441 kfree(wk);
1442 }
1443 946
1444 return RX_MGMT_CFG80211_DEAUTH; 947 return RX_MGMT_CFG80211_DEAUTH;
1445} 948}
@@ -1460,7 +963,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1460 if (WARN_ON(!ifmgd->associated)) 963 if (WARN_ON(!ifmgd->associated))
1461 return RX_MGMT_NONE; 964 return RX_MGMT_NONE;
1462 965
1463 if (WARN_ON(memcmp(ifmgd->associated->cbss.bssid, mgmt->sa, ETH_ALEN))) 966 if (WARN_ON(memcmp(ifmgd->associated->bssid, mgmt->sa, ETH_ALEN)))
1464 return RX_MGMT_NONE; 967 return RX_MGMT_NONE;
1465 968
1466 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 969 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
@@ -1468,96 +971,57 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1468 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", 971 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
1469 sdata->name, mgmt->sa, reason_code); 972 sdata->name, mgmt->sa, reason_code);
1470 973
1471 ieee80211_set_disassoc(sdata, false); 974 ieee80211_set_disassoc(sdata);
1472 ieee80211_recalc_idle(sdata->local); 975 ieee80211_recalc_idle(sdata->local);
1473 return RX_MGMT_CFG80211_DISASSOC; 976 return RX_MGMT_CFG80211_DISASSOC;
1474} 977}
1475 978
1476 979
1477static enum rx_mgmt_action __must_check 980static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1478ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, 981 struct ieee80211_mgmt *mgmt, size_t len)
1479 struct ieee80211_mgd_work *wk,
1480 struct ieee80211_mgmt *mgmt, size_t len,
1481 bool reassoc)
1482{ 982{
983 struct ieee80211_sub_if_data *sdata = wk->sdata;
1483 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 984 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1484 struct ieee80211_local *local = sdata->local; 985 struct ieee80211_local *local = sdata->local;
1485 struct ieee80211_supported_band *sband; 986 struct ieee80211_supported_band *sband;
1486 struct sta_info *sta; 987 struct sta_info *sta;
988 struct cfg80211_bss *cbss = wk->assoc.bss;
989 u8 *pos;
1487 u32 rates, basic_rates; 990 u32 rates, basic_rates;
1488 u16 capab_info, status_code, aid; 991 u16 capab_info, aid;
1489 struct ieee802_11_elems elems; 992 struct ieee802_11_elems elems;
1490 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 993 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1491 u8 *pos;
1492 u32 changed = 0; 994 u32 changed = 0;
1493 int i, j, err; 995 int i, j, err;
1494 bool have_higher_than_11mbit = false; 996 bool have_higher_than_11mbit = false;
1495 u16 ap_ht_cap_flags; 997 u16 ap_ht_cap_flags;
1496 998
1497 /* 999 /* AssocResp and ReassocResp have identical structure */
1498 * AssocResp and ReassocResp have identical structure, so process both
1499 * of them in this function.
1500 */
1501
1502 if (len < 24 + 6)
1503 return RX_MGMT_NONE;
1504 1000
1505 if (memcmp(wk->bss->cbss.bssid, mgmt->sa, ETH_ALEN) != 0)
1506 return RX_MGMT_NONE;
1507
1508 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
1509 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
1510 aid = le16_to_cpu(mgmt->u.assoc_resp.aid); 1001 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
1511 1002 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
1512 printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
1513 "status=%d aid=%d)\n",
1514 sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
1515 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
1516
1517 pos = mgmt->u.assoc_resp.variable;
1518 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1519
1520 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
1521 elems.timeout_int && elems.timeout_int_len == 5 &&
1522 elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
1523 u32 tu, ms;
1524 tu = get_unaligned_le32(elems.timeout_int + 1);
1525 ms = tu * 1024 / 1000;
1526 printk(KERN_DEBUG "%s: AP rejected association temporarily; "
1527 "comeback duration %u TU (%u ms)\n",
1528 sdata->name, tu, ms);
1529 wk->timeout = jiffies + msecs_to_jiffies(ms);
1530 if (ms > IEEE80211_ASSOC_TIMEOUT)
1531 run_again(ifmgd, jiffies + msecs_to_jiffies(ms));
1532 return RX_MGMT_NONE;
1533 }
1534
1535 if (status_code != WLAN_STATUS_SUCCESS) {
1536 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
1537 sdata->name, status_code);
1538 wk->state = IEEE80211_MGD_STATE_IDLE;
1539 return RX_MGMT_CFG80211_ASSOC;
1540 }
1541 1003
1542 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) 1004 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
1543 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " 1005 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1544 "set\n", sdata->name, aid); 1006 "set\n", sdata->name, aid);
1545 aid &= ~(BIT(15) | BIT(14)); 1007 aid &= ~(BIT(15) | BIT(14));
1546 1008
1009 pos = mgmt->u.assoc_resp.variable;
1010 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1011
1547 if (!elems.supp_rates) { 1012 if (!elems.supp_rates) {
1548 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", 1013 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1549 sdata->name); 1014 sdata->name);
1550 return RX_MGMT_NONE; 1015 return false;
1551 } 1016 }
1552 1017
1553 printk(KERN_DEBUG "%s: associated\n", sdata->name);
1554 ifmgd->aid = aid; 1018 ifmgd->aid = aid;
1555 1019
1556 sta = sta_info_alloc(sdata, wk->bss->cbss.bssid, GFP_KERNEL); 1020 sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL);
1557 if (!sta) { 1021 if (!sta) {
1558 printk(KERN_DEBUG "%s: failed to alloc STA entry for" 1022 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1559 " the AP\n", sdata->name); 1023 " the AP\n", sdata->name);
1560 return RX_MGMT_CFG80211_ASSOC_ERROR; 1024 return false;
1561 } 1025 }
1562 1026
1563 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | 1027 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
@@ -1641,22 +1105,19 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1641 else 1105 else
1642 ieee80211_set_wmm_default(sdata); 1106 ieee80211_set_wmm_default(sdata);
1643 1107
1108 local->oper_channel = wk->chan;
1109
1644 if (elems.ht_info_elem && elems.wmm_param && 1110 if (elems.ht_info_elem && elems.wmm_param &&
1645 (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) && 1111 (sdata->local->hw.queues >= 4) &&
1646 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 1112 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
1647 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, 1113 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
1648 wk->bss->cbss.bssid, 1114 cbss->bssid, ap_ht_cap_flags);
1649 ap_ht_cap_flags);
1650
1651 /* delete work item -- must be before set_associated for PS */
1652 list_del(&wk->list);
1653 1115
1654 /* set AID and assoc capability, 1116 /* set AID and assoc capability,
1655 * ieee80211_set_associated() will tell the driver */ 1117 * ieee80211_set_associated() will tell the driver */
1656 bss_conf->aid = aid; 1118 bss_conf->aid = aid;
1657 bss_conf->assoc_capability = capab_info; 1119 bss_conf->assoc_capability = capab_info;
1658 /* this will take ownership of wk */ 1120 ieee80211_set_associated(sdata, cbss, changed);
1659 ieee80211_set_associated(sdata, wk, changed);
1660 1121
1661 /* 1122 /*
1662 * Start timer to probe the connection to the AP now. 1123 * Start timer to probe the connection to the AP now.
@@ -1665,7 +1126,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1665 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); 1126 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1666 mod_beacon_timer(sdata); 1127 mod_beacon_timer(sdata);
1667 1128
1668 return RX_MGMT_CFG80211_ASSOC; 1129 return true;
1669} 1130}
1670 1131
1671 1132
@@ -1700,7 +1161,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1700 return; 1161 return;
1701 1162
1702 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) && 1163 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
1703 (memcmp(mgmt->bssid, sdata->u.mgd.associated->cbss.bssid, 1164 (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
1704 ETH_ALEN) == 0)) { 1165 ETH_ALEN) == 0)) {
1705 struct ieee80211_channel_sw_ie *sw_elem = 1166 struct ieee80211_channel_sw_ie *sw_elem =
1706 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem; 1167 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
@@ -1710,12 +1171,12 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1710 1171
1711 1172
1712static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, 1173static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1713 struct ieee80211_mgd_work *wk, 1174 struct sk_buff *skb)
1714 struct ieee80211_mgmt *mgmt, size_t len,
1715 struct ieee80211_rx_status *rx_status)
1716{ 1175{
1176 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1717 struct ieee80211_if_managed *ifmgd; 1177 struct ieee80211_if_managed *ifmgd;
1718 size_t baselen; 1178 struct ieee80211_rx_status *rx_status = (void *) skb->cb;
1179 size_t baselen, len = skb->len;
1719 struct ieee802_11_elems elems; 1180 struct ieee802_11_elems elems;
1720 1181
1721 ifmgd = &sdata->u.mgd; 1182 ifmgd = &sdata->u.mgd;
@@ -1734,17 +1195,8 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1734 1195
1735 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); 1196 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
1736 1197
1737 /* direct probe may be part of the association flow */
1738 if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) {
1739 printk(KERN_DEBUG "%s: direct probe responded\n",
1740 sdata->name);
1741 wk->tries = 0;
1742 wk->state = IEEE80211_MGD_STATE_AUTH;
1743 WARN_ON(ieee80211_authenticate(sdata, wk) != RX_MGMT_NONE);
1744 }
1745
1746 if (ifmgd->associated && 1198 if (ifmgd->associated &&
1747 memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 && 1199 memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 &&
1748 ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 1200 ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
1749 IEEE80211_STA_CONNECTION_POLL)) { 1201 IEEE80211_STA_CONNECTION_POLL)) {
1750 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | 1202 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
@@ -1817,7 +1269,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1817 if (!ifmgd->associated) 1269 if (!ifmgd->associated)
1818 return; 1270 return;
1819 1271
1820 bssid = ifmgd->associated->cbss.bssid; 1272 bssid = ifmgd->associated->bssid;
1821 1273
1822 /* 1274 /*
1823 * And in theory even frames from a different AP we were just 1275 * And in theory even frames from a different AP we were just
@@ -1956,9 +1408,6 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1956 switch (fc & IEEE80211_FCTL_STYPE) { 1408 switch (fc & IEEE80211_FCTL_STYPE) {
1957 case IEEE80211_STYPE_PROBE_RESP: 1409 case IEEE80211_STYPE_PROBE_RESP:
1958 case IEEE80211_STYPE_BEACON: 1410 case IEEE80211_STYPE_BEACON:
1959 case IEEE80211_STYPE_AUTH:
1960 case IEEE80211_STYPE_ASSOC_RESP:
1961 case IEEE80211_STYPE_REASSOC_RESP:
1962 case IEEE80211_STYPE_DEAUTH: 1411 case IEEE80211_STYPE_DEAUTH:
1963 case IEEE80211_STYPE_DISASSOC: 1412 case IEEE80211_STYPE_DISASSOC:
1964 case IEEE80211_STYPE_ACTION: 1413 case IEEE80211_STYPE_ACTION:
@@ -1976,7 +1425,6 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1976 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1425 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1977 struct ieee80211_rx_status *rx_status; 1426 struct ieee80211_rx_status *rx_status;
1978 struct ieee80211_mgmt *mgmt; 1427 struct ieee80211_mgmt *mgmt;
1979 struct ieee80211_mgd_work *wk;
1980 enum rx_mgmt_action rma = RX_MGMT_NONE; 1428 enum rx_mgmt_action rma = RX_MGMT_NONE;
1981 u16 fc; 1429 u16 fc;
1982 1430
@@ -1987,20 +1435,17 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1987 mutex_lock(&ifmgd->mtx); 1435 mutex_lock(&ifmgd->mtx);
1988 1436
1989 if (ifmgd->associated && 1437 if (ifmgd->associated &&
1990 memcmp(ifmgd->associated->cbss.bssid, mgmt->bssid, 1438 memcmp(ifmgd->associated->bssid, mgmt->bssid, ETH_ALEN) == 0) {
1991 ETH_ALEN) == 0) {
1992 switch (fc & IEEE80211_FCTL_STYPE) { 1439 switch (fc & IEEE80211_FCTL_STYPE) {
1993 case IEEE80211_STYPE_BEACON: 1440 case IEEE80211_STYPE_BEACON:
1994 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, 1441 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
1995 rx_status); 1442 rx_status);
1996 break; 1443 break;
1997 case IEEE80211_STYPE_PROBE_RESP: 1444 case IEEE80211_STYPE_PROBE_RESP:
1998 ieee80211_rx_mgmt_probe_resp(sdata, NULL, mgmt, 1445 ieee80211_rx_mgmt_probe_resp(sdata, skb);
1999 skb->len, rx_status);
2000 break; 1446 break;
2001 case IEEE80211_STYPE_DEAUTH: 1447 case IEEE80211_STYPE_DEAUTH:
2002 rma = ieee80211_rx_mgmt_deauth(sdata, NULL, 1448 rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
2003 mgmt, skb->len);
2004 break; 1449 break;
2005 case IEEE80211_STYPE_DISASSOC: 1450 case IEEE80211_STYPE_DISASSOC:
2006 rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); 1451 rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
@@ -2009,7 +1454,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2009 /* XXX: differentiate, can only happen for CSA now! */ 1454 /* XXX: differentiate, can only happen for CSA now! */
2010 ieee80211_sta_process_chanswitch(sdata, 1455 ieee80211_sta_process_chanswitch(sdata,
2011 &mgmt->u.action.u.chan_switch.sw_elem, 1456 &mgmt->u.action.u.chan_switch.sw_elem,
2012 ifmgd->associated); 1457 (void *)ifmgd->associated->priv);
2013 break; 1458 break;
2014 } 1459 }
2015 mutex_unlock(&ifmgd->mtx); 1460 mutex_unlock(&ifmgd->mtx);
@@ -2030,62 +1475,11 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2030 goto out; 1475 goto out;
2031 } 1476 }
2032 1477
2033 list_for_each_entry(wk, &ifmgd->work_list, list) {
2034 if (memcmp(wk->bss->cbss.bssid, mgmt->bssid, ETH_ALEN) != 0)
2035 continue;
2036
2037 switch (fc & IEEE80211_FCTL_STYPE) {
2038 case IEEE80211_STYPE_PROBE_RESP:
2039 ieee80211_rx_mgmt_probe_resp(sdata, wk, mgmt, skb->len,
2040 rx_status);
2041 break;
2042 case IEEE80211_STYPE_AUTH:
2043 rma = ieee80211_rx_mgmt_auth(sdata, wk, mgmt, skb->len);
2044 break;
2045 case IEEE80211_STYPE_ASSOC_RESP:
2046 rma = ieee80211_rx_mgmt_assoc_resp(sdata, wk, mgmt,
2047 skb->len, false);
2048 break;
2049 case IEEE80211_STYPE_REASSOC_RESP:
2050 rma = ieee80211_rx_mgmt_assoc_resp(sdata, wk, mgmt,
2051 skb->len, true);
2052 break;
2053 case IEEE80211_STYPE_DEAUTH:
2054 rma = ieee80211_rx_mgmt_deauth(sdata, wk, mgmt,
2055 skb->len);
2056 break;
2057 }
2058 /*
2059 * We've processed this frame for that work, so it can't
2060 * belong to another work struct.
2061 * NB: this is also required for correctness because the
2062 * called functions can free 'wk', and for 'rma'!
2063 */
2064 break;
2065 }
2066
2067 mutex_unlock(&ifmgd->mtx); 1478 mutex_unlock(&ifmgd->mtx);
2068 1479
2069 switch (rma) { 1480 if (skb->len >= 24 + 2 /* mgmt + deauth reason */ &&
2070 case RX_MGMT_NONE: 1481 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH)
2071 /* no action */
2072 break;
2073 case RX_MGMT_CFG80211_AUTH:
2074 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, skb->len);
2075 break;
2076 case RX_MGMT_CFG80211_ASSOC:
2077 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len);
2078 break;
2079 case RX_MGMT_CFG80211_DEAUTH:
2080 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); 1482 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
2081 break;
2082 case RX_MGMT_CFG80211_ASSOC_ERROR:
2083 /* an internal error -- pretend timeout for now */
2084 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
2085 break;
2086 default:
2087 WARN(1, "unexpected: %d", rma);
2088 }
2089 1483
2090 out: 1484 out:
2091 kfree_skb(skb); 1485 kfree_skb(skb);
@@ -2113,12 +1507,8 @@ static void ieee80211_sta_work(struct work_struct *work)
2113 struct ieee80211_local *local = sdata->local; 1507 struct ieee80211_local *local = sdata->local;
2114 struct ieee80211_if_managed *ifmgd; 1508 struct ieee80211_if_managed *ifmgd;
2115 struct sk_buff *skb; 1509 struct sk_buff *skb;
2116 struct ieee80211_mgd_work *wk, *tmp;
2117 LIST_HEAD(free_work);
2118 enum rx_mgmt_action rma;
2119 bool anybusy = false;
2120 1510
2121 if (!netif_running(sdata->dev)) 1511 if (!ieee80211_sdata_running(sdata))
2122 return; 1512 return;
2123 1513
2124 if (local->scanning) 1514 if (local->scanning)
@@ -2149,7 +1539,7 @@ static void ieee80211_sta_work(struct work_struct *work)
2149 ifmgd->associated) { 1539 ifmgd->associated) {
2150 u8 bssid[ETH_ALEN]; 1540 u8 bssid[ETH_ALEN];
2151 1541
2152 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); 1542 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
2153 if (time_is_after_jiffies(ifmgd->probe_timeout)) 1543 if (time_is_after_jiffies(ifmgd->probe_timeout))
2154 run_again(ifmgd, ifmgd->probe_timeout); 1544 run_again(ifmgd, ifmgd->probe_timeout);
2155 1545
@@ -2171,7 +1561,7 @@ static void ieee80211_sta_work(struct work_struct *work)
2171 printk(KERN_DEBUG "No probe response from AP %pM" 1561 printk(KERN_DEBUG "No probe response from AP %pM"
2172 " after %dms, disconnecting.\n", 1562 " after %dms, disconnecting.\n",
2173 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1563 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
2174 ieee80211_set_disassoc(sdata, true); 1564 ieee80211_set_disassoc(sdata);
2175 ieee80211_recalc_idle(local); 1565 ieee80211_recalc_idle(local);
2176 mutex_unlock(&ifmgd->mtx); 1566 mutex_unlock(&ifmgd->mtx);
2177 /* 1567 /*
@@ -2186,87 +1576,7 @@ static void ieee80211_sta_work(struct work_struct *work)
2186 } 1576 }
2187 } 1577 }
2188 1578
2189
2190 ieee80211_recalc_idle(local);
2191
2192 list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) {
2193 if (time_is_after_jiffies(wk->timeout)) {
2194 /*
2195 * This work item isn't supposed to be worked on
2196 * right now, but take care to adjust the timer
2197 * properly.
2198 */
2199 run_again(ifmgd, wk->timeout);
2200 continue;
2201 }
2202
2203 switch (wk->state) {
2204 default:
2205 WARN_ON(1);
2206 /* fall through */
2207 case IEEE80211_MGD_STATE_IDLE:
2208 /* nothing */
2209 rma = RX_MGMT_NONE;
2210 break;
2211 case IEEE80211_MGD_STATE_PROBE:
2212 rma = ieee80211_direct_probe(sdata, wk);
2213 break;
2214 case IEEE80211_MGD_STATE_AUTH:
2215 rma = ieee80211_authenticate(sdata, wk);
2216 break;
2217 case IEEE80211_MGD_STATE_ASSOC:
2218 rma = ieee80211_associate(sdata, wk);
2219 break;
2220 }
2221
2222 switch (rma) {
2223 case RX_MGMT_NONE:
2224 /* no action required */
2225 break;
2226 case RX_MGMT_CFG80211_AUTH_TO:
2227 case RX_MGMT_CFG80211_ASSOC_TO:
2228 list_del(&wk->list);
2229 list_add(&wk->list, &free_work);
2230 wk->tries = rma; /* small abuse but only local */
2231 break;
2232 default:
2233 WARN(1, "unexpected: %d", rma);
2234 }
2235 }
2236
2237 list_for_each_entry(wk, &ifmgd->work_list, list) {
2238 if (wk->state != IEEE80211_MGD_STATE_IDLE) {
2239 anybusy = true;
2240 break;
2241 }
2242 }
2243 if (!anybusy &&
2244 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request))
2245 ieee80211_queue_delayed_work(&local->hw,
2246 &local->scan_work,
2247 round_jiffies_relative(0));
2248
2249 mutex_unlock(&ifmgd->mtx); 1579 mutex_unlock(&ifmgd->mtx);
2250
2251 list_for_each_entry_safe(wk, tmp, &free_work, list) {
2252 switch (wk->tries) {
2253 case RX_MGMT_CFG80211_AUTH_TO:
2254 cfg80211_send_auth_timeout(sdata->dev,
2255 wk->bss->cbss.bssid);
2256 break;
2257 case RX_MGMT_CFG80211_ASSOC_TO:
2258 cfg80211_send_assoc_timeout(sdata->dev,
2259 wk->bss->cbss.bssid);
2260 break;
2261 default:
2262 WARN(1, "unexpected: %d", wk->tries);
2263 }
2264
2265 list_del(&wk->list);
2266 kfree(wk);
2267 }
2268
2269 ieee80211_recalc_idle(local);
2270} 1580}
2271 1581
2272static void ieee80211_sta_bcn_mon_timer(unsigned long data) 1582static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -2375,12 +1685,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2375 (unsigned long) sdata); 1685 (unsigned long) sdata);
2376 skb_queue_head_init(&ifmgd->skb_queue); 1686 skb_queue_head_init(&ifmgd->skb_queue);
2377 1687
2378 INIT_LIST_HEAD(&ifmgd->work_list);
2379
2380 ifmgd->capab = WLAN_CAPABILITY_ESS;
2381 ifmgd->flags = 0; 1688 ifmgd->flags = 0;
2382 if (sdata->local->hw.queues >= 4)
2383 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
2384 1689
2385 mutex_init(&ifmgd->mtx); 1690 mutex_init(&ifmgd->mtx);
2386 1691
@@ -2418,12 +1723,34 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
2418} 1723}
2419 1724
2420/* config hooks */ 1725/* config hooks */
1726static enum work_done_result
1727ieee80211_probe_auth_done(struct ieee80211_work *wk,
1728 struct sk_buff *skb)
1729{
1730 if (!skb) {
1731 cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
1732 return WORK_DONE_DESTROY;
1733 }
1734
1735 if (wk->type == IEEE80211_WORK_AUTH) {
1736 cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
1737 return WORK_DONE_DESTROY;
1738 }
1739
1740 mutex_lock(&wk->sdata->u.mgd.mtx);
1741 ieee80211_rx_mgmt_probe_resp(wk->sdata, skb);
1742 mutex_unlock(&wk->sdata->u.mgd.mtx);
1743
1744 wk->type = IEEE80211_WORK_AUTH;
1745 wk->probe_auth.tries = 0;
1746 return WORK_DONE_REQUEUE;
1747}
1748
2421int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 1749int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2422 struct cfg80211_auth_request *req) 1750 struct cfg80211_auth_request *req)
2423{ 1751{
2424 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2425 const u8 *ssid; 1752 const u8 *ssid;
2426 struct ieee80211_mgd_work *wk; 1753 struct ieee80211_work *wk;
2427 u16 auth_alg; 1754 u16 auth_alg;
2428 1755
2429 switch (req->auth_type) { 1756 switch (req->auth_type) {
@@ -2447,7 +1774,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2447 if (!wk) 1774 if (!wk)
2448 return -ENOMEM; 1775 return -ENOMEM;
2449 1776
2450 wk->bss = (void *)req->bss; 1777 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);;
2451 1778
2452 if (req->ie && req->ie_len) { 1779 if (req->ie && req->ie_len) {
2453 memcpy(wk->ie, req->ie, req->ie_len); 1780 memcpy(wk->ie, req->ie, req->ie_len);
@@ -2455,66 +1782,76 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2455 } 1782 }
2456 1783
2457 if (req->key && req->key_len) { 1784 if (req->key && req->key_len) {
2458 wk->key_len = req->key_len; 1785 wk->probe_auth.key_len = req->key_len;
2459 wk->key_idx = req->key_idx; 1786 wk->probe_auth.key_idx = req->key_idx;
2460 memcpy(wk->key, req->key, req->key_len); 1787 memcpy(wk->probe_auth.key, req->key, req->key_len);
2461 } 1788 }
2462 1789
2463 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); 1790 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
2464 memcpy(wk->ssid, ssid + 2, ssid[1]); 1791 memcpy(wk->probe_auth.ssid, ssid + 2, ssid[1]);
2465 wk->ssid_len = ssid[1]; 1792 wk->probe_auth.ssid_len = ssid[1];
2466 1793
2467 wk->state = IEEE80211_MGD_STATE_PROBE; 1794 wk->probe_auth.algorithm = auth_alg;
2468 wk->auth_alg = auth_alg; 1795 wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY;
2469 wk->timeout = jiffies; /* run right away */
2470 1796
2471 /* 1797 wk->type = IEEE80211_WORK_DIRECT_PROBE;
2472 * XXX: if still associated need to tell AP that we're going 1798 wk->chan = req->bss->channel;
2473 * to sleep and then change channel etc. 1799 wk->sdata = sdata;
2474 */ 1800 wk->done = ieee80211_probe_auth_done;
2475 sdata->local->oper_channel = req->bss->channel;
2476 ieee80211_hw_config(sdata->local, 0);
2477 1801
2478 mutex_lock(&ifmgd->mtx); 1802 ieee80211_add_work(wk);
2479 list_add(&wk->list, &sdata->u.mgd.work_list);
2480 mutex_unlock(&ifmgd->mtx);
2481
2482 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work);
2483 return 0; 1803 return 0;
2484} 1804}
2485 1805
2486int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, 1806static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2487 struct cfg80211_assoc_request *req) 1807 struct sk_buff *skb)
2488{ 1808{
2489 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1809 struct ieee80211_mgmt *mgmt;
2490 struct ieee80211_mgd_work *wk, *found = NULL; 1810 u16 status;
2491 int i, err;
2492 1811
2493 mutex_lock(&ifmgd->mtx); 1812 if (!skb) {
1813 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
1814 return WORK_DONE_DESTROY;
1815 }
2494 1816
2495 list_for_each_entry(wk, &ifmgd->work_list, list) { 1817 mgmt = (void *)skb->data;
2496 if (&wk->bss->cbss == req->bss && 1818 status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
2497 wk->state == IEEE80211_MGD_STATE_IDLE) { 1819
2498 found = wk; 1820 if (status == WLAN_STATUS_SUCCESS) {
2499 break; 1821 mutex_lock(&wk->sdata->u.mgd.mtx);
1822 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
1823 mutex_unlock(&wk->sdata->u.mgd.mtx);
1824 /* oops -- internal error -- send timeout for now */
1825 cfg80211_send_assoc_timeout(wk->sdata->dev,
1826 wk->filter_ta);
1827 return WORK_DONE_DESTROY;
2500 } 1828 }
1829 mutex_unlock(&wk->sdata->u.mgd.mtx);
2501 } 1830 }
2502 1831
2503 if (!found) { 1832 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
2504 err = -ENOLINK; 1833 return WORK_DONE_DESTROY;
2505 goto out; 1834}
2506 }
2507 1835
2508 list_del(&found->list); 1836int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1837 struct cfg80211_assoc_request *req)
1838{
1839 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1840 struct ieee80211_bss *bss = (void *)req->bss->priv;
1841 struct ieee80211_work *wk;
1842 const u8 *ssid;
1843 int i;
2509 1844
2510 wk = krealloc(found, sizeof(*wk) + req->ie_len, GFP_KERNEL); 1845 mutex_lock(&ifmgd->mtx);
2511 if (!wk) { 1846 if (ifmgd->associated) {
2512 list_add(&found->list, &ifmgd->work_list); 1847 mutex_unlock(&ifmgd->mtx);
2513 err = -ENOMEM; 1848 return -EALREADY;
2514 goto out;
2515 } 1849 }
1850 mutex_unlock(&ifmgd->mtx);
2516 1851
2517 list_add(&wk->list, &ifmgd->work_list); 1852 wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
1853 if (!wk)
1854 return -ENOMEM;
2518 1855
2519 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 1856 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2520 1857
@@ -2524,8 +1861,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2524 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) 1861 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
2525 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 1862 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
2526 1863
2527 sdata->local->oper_channel = req->bss->channel;
2528 ieee80211_hw_config(sdata->local, 0);
2529 1864
2530 if (req->ie && req->ie_len) { 1865 if (req->ie && req->ie_len) {
2531 memcpy(wk->ie, req->ie, req->ie_len); 1866 memcpy(wk->ie, req->ie, req->ie_len);
@@ -2533,12 +1868,46 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2533 } else 1868 } else
2534 wk->ie_len = 0; 1869 wk->ie_len = 0;
2535 1870
1871 wk->assoc.bss = req->bss;
1872
1873 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
1874
1875 /* new association always uses requested smps mode */
1876 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
1877 if (ifmgd->powersave)
1878 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
1879 else
1880 ifmgd->ap_smps = IEEE80211_SMPS_OFF;
1881 } else
1882 ifmgd->ap_smps = ifmgd->req_smps;
1883
1884 wk->assoc.smps = ifmgd->ap_smps;
1885 /*
1886 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
1887 * We still associate in non-HT mode (11a/b/g) if any one of these
1888 * ciphers is configured as pairwise.
1889 * We can set this to true for non-11n hardware, that'll be checked
1890 * separately along with the peer capabilities.
1891 */
1892 wk->assoc.use_11n = !(ifmgd->flags & IEEE80211_STA_DISABLE_11N);
1893 wk->assoc.capability = req->bss->capability;
1894 wk->assoc.wmm_used = bss->wmm_used;
1895 wk->assoc.supp_rates = bss->supp_rates;
1896 wk->assoc.supp_rates_len = bss->supp_rates_len;
1897 wk->assoc.ht_information_ie =
1898 ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION);
1899
1900 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
1901 memcpy(wk->assoc.ssid, ssid + 2, ssid[1]);
1902 wk->assoc.ssid_len = ssid[1];
1903
2536 if (req->prev_bssid) 1904 if (req->prev_bssid)
2537 memcpy(wk->prev_bssid, req->prev_bssid, ETH_ALEN); 1905 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
2538 1906
2539 wk->state = IEEE80211_MGD_STATE_ASSOC; 1907 wk->type = IEEE80211_WORK_ASSOC;
2540 wk->tries = 0; 1908 wk->chan = req->bss->channel;
2541 wk->timeout = jiffies; /* run right away */ 1909 wk->sdata = sdata;
1910 wk->done = ieee80211_assoc_done;
2542 1911
2543 if (req->use_mfp) { 1912 if (req->use_mfp) {
2544 ifmgd->mfp = IEEE80211_MFP_REQUIRED; 1913 ifmgd->mfp = IEEE80211_MFP_REQUIRED;
@@ -2553,67 +1922,57 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2553 else 1922 else
2554 ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; 1923 ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;
2555 1924
2556 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); 1925 ieee80211_add_work(wk);
2557 1926 return 0;
2558 err = 0;
2559
2560 out:
2561 mutex_unlock(&ifmgd->mtx);
2562 return err;
2563} 1927}
2564 1928
2565int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, 1929int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2566 struct cfg80211_deauth_request *req, 1930 struct cfg80211_deauth_request *req,
2567 void *cookie) 1931 void *cookie)
2568{ 1932{
1933 struct ieee80211_local *local = sdata->local;
2569 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1934 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2570 struct ieee80211_mgd_work *wk; 1935 struct ieee80211_work *wk;
2571 const u8 *bssid = NULL; 1936 const u8 *bssid = req->bss->bssid;
2572 bool not_auth_yet = false;
2573 1937
2574 mutex_lock(&ifmgd->mtx); 1938 mutex_lock(&ifmgd->mtx);
2575 1939
2576 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { 1940 if (ifmgd->associated == req->bss) {
2577 bssid = req->bss->bssid; 1941 bssid = req->bss->bssid;
2578 ieee80211_set_disassoc(sdata, true); 1942 ieee80211_set_disassoc(sdata);
2579 } else list_for_each_entry(wk, &ifmgd->work_list, list) { 1943 mutex_unlock(&ifmgd->mtx);
2580 if (&wk->bss->cbss == req->bss) { 1944 } else {
2581 bssid = req->bss->bssid; 1945 bool not_auth_yet = false;
2582 if (wk->state == IEEE80211_MGD_STATE_PROBE) 1946
2583 not_auth_yet = true; 1947 mutex_unlock(&ifmgd->mtx);
1948
1949 mutex_lock(&local->work_mtx);
1950 list_for_each_entry(wk, &local->work_list, list) {
1951 if (wk->type != IEEE80211_WORK_DIRECT_PROBE)
1952 continue;
1953 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
1954 continue;
1955 not_auth_yet = true;
2584 list_del(&wk->list); 1956 list_del(&wk->list);
2585 kfree(wk); 1957 free_work(wk);
2586 break; 1958 break;
2587 } 1959 }
2588 } 1960 mutex_unlock(&local->work_mtx);
2589 1961
2590 /* 1962 /*
2591 * If somebody requests authentication and we haven't 1963 * If somebody requests authentication and we haven't
2592 * sent out an auth frame yet there's no need to send 1964 * sent out an auth frame yet there's no need to send
2593 * out a deauth frame either. If the state was PROBE, 1965 * out a deauth frame either. If the state was PROBE,
2594 * then this is the case. If it's AUTH we have sent a 1966 * then this is the case. If it's AUTH we have sent a
2595 * frame, and if it's IDLE we have completed the auth 1967 * frame, and if it's IDLE we have completed the auth
2596 * process already. 1968 * process already.
2597 */ 1969 */
2598 if (not_auth_yet) { 1970 if (not_auth_yet) {
2599 mutex_unlock(&ifmgd->mtx); 1971 __cfg80211_auth_canceled(sdata->dev, bssid);
2600 __cfg80211_auth_canceled(sdata->dev, bssid); 1972 return 0;
2601 return 0; 1973 }
2602 }
2603
2604 /*
2605 * cfg80211 should catch this ... but it's racy since
2606 * we can receive a deauth frame, process it, hand it
2607 * to cfg80211 while that's in a locked section already
2608 * trying to tell us that the user wants to disconnect.
2609 */
2610 if (!bssid) {
2611 mutex_unlock(&ifmgd->mtx);
2612 return -ENOLINK;
2613 } 1974 }
2614 1975
2615 mutex_unlock(&ifmgd->mtx);
2616
2617 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", 1976 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
2618 sdata->name, bssid, req->reason_code); 1977 sdata->name, bssid, req->reason_code);
2619 1978
@@ -2640,7 +1999,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2640 * to cfg80211 while that's in a locked section already 1999 * to cfg80211 while that's in a locked section already
2641 * trying to tell us that the user wants to disconnect. 2000 * trying to tell us that the user wants to disconnect.
2642 */ 2001 */
2643 if (&ifmgd->associated->cbss != req->bss) { 2002 if (ifmgd->associated != req->bss) {
2644 mutex_unlock(&ifmgd->mtx); 2003 mutex_unlock(&ifmgd->mtx);
2645 return -ENOLINK; 2004 return -ENOLINK;
2646 } 2005 }
@@ -2648,7 +2007,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2648 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", 2007 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
2649 sdata->name, req->bss->bssid, req->reason_code); 2008 sdata->name, req->bss->bssid, req->reason_code);
2650 2009
2651 ieee80211_set_disassoc(sdata, false); 2010 ieee80211_set_disassoc(sdata);
2652 2011
2653 mutex_unlock(&ifmgd->mtx); 2012 mutex_unlock(&ifmgd->mtx);
2654 2013
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
new file mode 100644
index 000000000000..a7bbfc40a648
--- /dev/null
+++ b/net/mac80211/offchannel.c
@@ -0,0 +1,168 @@
1/*
2 * Off-channel operation helpers
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2004, Instant802 Networks, Inc.
6 * Copyright 2005, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15#include <net/mac80211.h>
16#include "ieee80211_i.h"
17
18/*
19 * inform AP that we will go to sleep so that it will buffer the frames
20 * while we scan
21 */
22static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
23{
24 struct ieee80211_local *local = sdata->local;
25
26 local->offchannel_ps_enabled = false;
27
28 /* FIXME: what to do when local->pspolling is true? */
29
30 del_timer_sync(&local->dynamic_ps_timer);
31 cancel_work_sync(&local->dynamic_ps_enable_work);
32
33 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
34 local->offchannel_ps_enabled = true;
35 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
36 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
37 }
38
39 if (!(local->offchannel_ps_enabled) ||
40 !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
41 /*
42 * If power save was enabled, no need to send a nullfunc
43 * frame because AP knows that we are sleeping. But if the
44 * hardware is creating the nullfunc frame for power save
45 * status (ie. IEEE80211_HW_PS_NULLFUNC_STACK is not
46 * enabled) and power save was enabled, the firmware just
47 * sent a null frame with power save disabled. So we need
48 * to send a new nullfunc frame to inform the AP that we
49 * are again sleeping.
50 */
51 ieee80211_send_nullfunc(local, sdata, 1);
52}
53
54/* inform AP that we are awake again, unless power save is enabled */
55static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
56{
57 struct ieee80211_local *local = sdata->local;
58
59 if (!local->ps_sdata)
60 ieee80211_send_nullfunc(local, sdata, 0);
61 else if (local->offchannel_ps_enabled) {
62 /*
63 * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
64 * will send a nullfunc frame with the powersave bit set
65 * even though the AP already knows that we are sleeping.
66 * This could be avoided by sending a null frame with power
67 * save bit disabled before enabling the power save, but
68 * this doesn't gain anything.
69 *
70 * When IEEE80211_HW_PS_NULLFUNC_STACK is enabled, no need
71 * to send a nullfunc frame because AP already knows that
72 * we are sleeping, let's just enable power save mode in
73 * hardware.
74 */
75 local->hw.conf.flags |= IEEE80211_CONF_PS;
76 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
77 } else if (local->hw.conf.dynamic_ps_timeout > 0) {
78 /*
79 * If IEEE80211_CONF_PS was not set and the dynamic_ps_timer
80 * had been running before leaving the operating channel,
81 * restart the timer now and send a nullfunc frame to inform
82 * the AP that we are awake.
83 */
84 ieee80211_send_nullfunc(local, sdata, 0);
85 mod_timer(&local->dynamic_ps_timer, jiffies +
86 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
87 }
88}
89
90void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local)
91{
92 struct ieee80211_sub_if_data *sdata;
93
94 mutex_lock(&local->iflist_mtx);
95 list_for_each_entry(sdata, &local->interfaces, list) {
96 if (!ieee80211_sdata_running(sdata))
97 continue;
98
99 /* disable beaconing */
100 if (sdata->vif.type == NL80211_IFTYPE_AP ||
101 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
102 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
103 ieee80211_bss_info_change_notify(
104 sdata, BSS_CHANGED_BEACON_ENABLED);
105
106 /*
107 * only handle non-STA interfaces here, STA interfaces
108 * are handled in ieee80211_offchannel_stop_station(),
109 * e.g., from the background scan state machine.
110 *
111 * In addition, do not stop monitor interface to allow it to be
112 * used from user space controlled off-channel operations.
113 */
114 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
115 sdata->vif.type != NL80211_IFTYPE_MONITOR)
116 netif_stop_queue(sdata->dev);
117 }
118 mutex_unlock(&local->iflist_mtx);
119}
120
121void ieee80211_offchannel_stop_station(struct ieee80211_local *local)
122{
123 struct ieee80211_sub_if_data *sdata;
124
125 /*
126 * notify the AP about us leaving the channel and stop all STA interfaces
127 */
128 mutex_lock(&local->iflist_mtx);
129 list_for_each_entry(sdata, &local->interfaces, list) {
130 if (!ieee80211_sdata_running(sdata))
131 continue;
132
133 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
134 netif_stop_queue(sdata->dev);
135 if (sdata->u.mgd.associated)
136 ieee80211_offchannel_ps_enable(sdata);
137 }
138 }
139 mutex_unlock(&local->iflist_mtx);
140}
141
142void ieee80211_offchannel_return(struct ieee80211_local *local,
143 bool enable_beaconing)
144{
145 struct ieee80211_sub_if_data *sdata;
146
147 mutex_lock(&local->iflist_mtx);
148 list_for_each_entry(sdata, &local->interfaces, list) {
149 if (!ieee80211_sdata_running(sdata))
150 continue;
151
152 /* Tell AP we're back */
153 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
154 if (sdata->u.mgd.associated)
155 ieee80211_offchannel_ps_disable(sdata);
156 netif_wake_queue(sdata->dev);
157 }
158
159 /* re-enable beaconing */
160 if (enable_beaconing &&
161 (sdata->vif.type == NL80211_IFTYPE_AP ||
162 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
163 sdata->vif.type == NL80211_IFTYPE_MESH_POINT))
164 ieee80211_bss_info_change_notify(
165 sdata, BSS_CHANGED_BEACON_ENABLED);
166 }
167 mutex_unlock(&local->iflist_mtx);
168}
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 05e161c3cbc5..47f818959ad7 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -10,7 +10,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
10{ 10{
11 struct ieee80211_local *local = hw_to_local(hw); 11 struct ieee80211_local *local = hw_to_local(hw);
12 struct ieee80211_sub_if_data *sdata; 12 struct ieee80211_sub_if_data *sdata;
13 struct ieee80211_if_init_conf conf;
14 struct sta_info *sta; 13 struct sta_info *sta;
15 unsigned long flags; 14 unsigned long flags;
16 15
@@ -93,17 +92,14 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
93 break; 92 break;
94 } 93 }
95 94
96 if (!netif_running(sdata->dev)) 95 if (!ieee80211_sdata_running(sdata))
97 continue; 96 continue;
98 97
99 /* disable beaconing */ 98 /* disable beaconing */
100 ieee80211_bss_info_change_notify(sdata, 99 ieee80211_bss_info_change_notify(sdata,
101 BSS_CHANGED_BEACON_ENABLED); 100 BSS_CHANGED_BEACON_ENABLED);
102 101
103 conf.vif = &sdata->vif; 102 drv_remove_interface(local, &sdata->vif);
104 conf.type = sdata->vif.type;
105 conf.mac_addr = sdata->vif.addr;
106 drv_remove_interface(local, &conf);
107 } 103 }
108 104
109 /* stop hardware - this must stop RX */ 105 /* stop hardware - this must stop RX */
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6cbf1a7b3157..bfcf09eb64b4 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -289,7 +289,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
289 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) 289 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)
290 continue; 290 continue;
291 291
292 if (!netif_running(sdata->dev)) 292 if (!ieee80211_sdata_running(sdata))
293 continue; 293 continue;
294 294
295 if (prev_dev) { 295 if (prev_dev) {
@@ -1945,6 +1945,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1945{ 1945{
1946 struct ieee80211_sub_if_data *sdata = rx->sdata; 1946 struct ieee80211_sub_if_data *sdata = rx->sdata;
1947 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; 1947 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
1948 ieee80211_rx_result rxs;
1948 1949
1949 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 1950 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1950 return RX_DROP_MONITOR; 1951 return RX_DROP_MONITOR;
@@ -1952,6 +1953,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1952 if (ieee80211_drop_unencrypted(rx, mgmt->frame_control)) 1953 if (ieee80211_drop_unencrypted(rx, mgmt->frame_control))
1953 return RX_DROP_MONITOR; 1954 return RX_DROP_MONITOR;
1954 1955
1956 rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb);
1957 if (rxs != RX_CONTINUE)
1958 return rxs;
1959
1955 if (ieee80211_vif_is_mesh(&sdata->vif)) 1960 if (ieee80211_vif_is_mesh(&sdata->vif))
1956 return ieee80211_mesh_rx_mgmt(sdata, rx->skb); 1961 return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
1957 1962
@@ -2056,7 +2061,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
2056 skb->protocol = htons(ETH_P_802_2); 2061 skb->protocol = htons(ETH_P_802_2);
2057 2062
2058 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2063 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
2059 if (!netif_running(sdata->dev)) 2064 if (!ieee80211_sdata_running(sdata))
2060 continue; 2065 continue;
2061 2066
2062 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || 2067 if (sdata->vif.type != NL80211_IFTYPE_MONITOR ||
@@ -2318,7 +2323,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2318 } 2323 }
2319 if (!found_sta) { 2324 if (!found_sta) {
2320 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2325 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
2321 if (!netif_running(sdata->dev)) 2326 if (!ieee80211_sdata_running(sdata))
2322 continue; 2327 continue;
2323 2328
2324 if (sdata->vif.type == NL80211_IFTYPE_MONITOR || 2329 if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 66da0ab1d8fa..365f40975511 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -29,16 +29,19 @@ struct ieee80211_bss *
29ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, 29ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
30 u8 *ssid, u8 ssid_len) 30 u8 *ssid, u8 ssid_len)
31{ 31{
32 return (void *)cfg80211_get_bss(local->hw.wiphy, 32 struct cfg80211_bss *cbss;
33 ieee80211_get_channel(local->hw.wiphy, 33
34 freq), 34 cbss = cfg80211_get_bss(local->hw.wiphy,
35 bssid, ssid, ssid_len, 35 ieee80211_get_channel(local->hw.wiphy, freq),
36 0, 0); 36 bssid, ssid, ssid_len, 0, 0);
37 if (!cbss)
38 return NULL;
39 return (void *)cbss->priv;
37} 40}
38 41
39static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss) 42static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
40{ 43{
41 struct ieee80211_bss *bss = (void *)cbss; 44 struct ieee80211_bss *bss = (void *)cbss->priv;
42 45
43 kfree(bss_mesh_id(bss)); 46 kfree(bss_mesh_id(bss));
44 kfree(bss_mesh_cfg(bss)); 47 kfree(bss_mesh_cfg(bss));
@@ -47,7 +50,9 @@ static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
47void ieee80211_rx_bss_put(struct ieee80211_local *local, 50void ieee80211_rx_bss_put(struct ieee80211_local *local,
48 struct ieee80211_bss *bss) 51 struct ieee80211_bss *bss)
49{ 52{
50 cfg80211_put_bss((struct cfg80211_bss *)bss); 53 if (!bss)
54 return;
55 cfg80211_put_bss(container_of((void *)bss, struct cfg80211_bss, priv));
51} 56}
52 57
53struct ieee80211_bss * 58struct ieee80211_bss *
@@ -59,6 +64,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
59 struct ieee80211_channel *channel, 64 struct ieee80211_channel *channel,
60 bool beacon) 65 bool beacon)
61{ 66{
67 struct cfg80211_bss *cbss;
62 struct ieee80211_bss *bss; 68 struct ieee80211_bss *bss;
63 int clen; 69 int clen;
64 s32 signal = 0; 70 s32 signal = 0;
@@ -68,13 +74,14 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
68 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 74 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
69 signal = (rx_status->signal * 100) / local->hw.max_signal; 75 signal = (rx_status->signal * 100) / local->hw.max_signal;
70 76
71 bss = (void *)cfg80211_inform_bss_frame(local->hw.wiphy, channel, 77 cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel,
72 mgmt, len, signal, GFP_ATOMIC); 78 mgmt, len, signal, GFP_ATOMIC);
73 79
74 if (!bss) 80 if (!cbss)
75 return NULL; 81 return NULL;
76 82
77 bss->cbss.free_priv = ieee80211_rx_bss_free; 83 cbss->free_priv = ieee80211_rx_bss_free;
84 bss = (void *)cbss->priv;
78 85
79 /* save the ERP value so that it is available at association time */ 86 /* save the ERP value so that it is available at association time */
80 if (elems->erp_info && elems->erp_info_len >= 1) { 87 if (elems->erp_info && elems->erp_info_len >= 1) {
@@ -220,82 +227,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
220 return true; 227 return true;
221} 228}
222 229
223/*
224 * inform AP that we will go to sleep so that it will buffer the frames
225 * while we scan
226 */
227static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
228{
229 struct ieee80211_local *local = sdata->local;
230
231 local->scan_ps_enabled = false;
232
233 /* FIXME: what to do when local->pspolling is true? */
234
235 del_timer_sync(&local->dynamic_ps_timer);
236 cancel_work_sync(&local->dynamic_ps_enable_work);
237
238 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
239 local->scan_ps_enabled = true;
240 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
241 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
242 }
243
244 if (!(local->scan_ps_enabled) ||
245 !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
246 /*
247 * If power save was enabled, no need to send a nullfunc
248 * frame because AP knows that we are sleeping. But if the
249 * hardware is creating the nullfunc frame for power save
250 * status (ie. IEEE80211_HW_PS_NULLFUNC_STACK is not
251 * enabled) and power save was enabled, the firmware just
252 * sent a null frame with power save disabled. So we need
253 * to send a new nullfunc frame to inform the AP that we
254 * are again sleeping.
255 */
256 ieee80211_send_nullfunc(local, sdata, 1);
257}
258
259/* inform AP that we are awake again, unless power save is enabled */
260static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
261{
262 struct ieee80211_local *local = sdata->local;
263
264 if (!local->ps_sdata)
265 ieee80211_send_nullfunc(local, sdata, 0);
266 else if (local->scan_ps_enabled) {
267 /*
268 * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
269 * will send a nullfunc frame with the powersave bit set
270 * even though the AP already knows that we are sleeping.
271 * This could be avoided by sending a null frame with power
272 * save bit disabled before enabling the power save, but
273 * this doesn't gain anything.
274 *
275 * When IEEE80211_HW_PS_NULLFUNC_STACK is enabled, no need
276 * to send a nullfunc frame because AP already knows that
277 * we are sleeping, let's just enable power save mode in
278 * hardware.
279 */
280 local->hw.conf.flags |= IEEE80211_CONF_PS;
281 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
282 } else if (local->hw.conf.dynamic_ps_timeout > 0) {
283 /*
284 * If IEEE80211_CONF_PS was not set and the dynamic_ps_timer
285 * had been running before leaving the operating channel,
286 * restart the timer now and send a nullfunc frame to inform
287 * the AP that we are awake.
288 */
289 ieee80211_send_nullfunc(local, sdata, 0);
290 mod_timer(&local->dynamic_ps_timer, jiffies +
291 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
292 }
293}
294
295void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 230void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
296{ 231{
297 struct ieee80211_local *local = hw_to_local(hw); 232 struct ieee80211_local *local = hw_to_local(hw);
298 struct ieee80211_sub_if_data *sdata;
299 bool was_hw_scan; 233 bool was_hw_scan;
300 234
301 mutex_lock(&local->scan_mtx); 235 mutex_lock(&local->scan_mtx);
@@ -344,28 +278,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
344 278
345 drv_sw_scan_complete(local); 279 drv_sw_scan_complete(local);
346 280
347 mutex_lock(&local->iflist_mtx); 281 ieee80211_offchannel_return(local, true);
348 list_for_each_entry(sdata, &local->interfaces, list) {
349 if (!netif_running(sdata->dev))
350 continue;
351
352 /* Tell AP we're back */
353 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
354 if (sdata->u.mgd.associated) {
355 ieee80211_scan_ps_disable(sdata);
356 netif_wake_queue(sdata->dev);
357 }
358 } else
359 netif_wake_queue(sdata->dev);
360
361 /* re-enable beaconing */
362 if (sdata->vif.type == NL80211_IFTYPE_AP ||
363 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
364 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
365 ieee80211_bss_info_change_notify(
366 sdata, BSS_CHANGED_BEACON_ENABLED);
367 }
368 mutex_unlock(&local->iflist_mtx);
369 282
370 done: 283 done:
371 ieee80211_recalc_idle(local); 284 ieee80211_recalc_idle(local);
@@ -377,8 +290,6 @@ EXPORT_SYMBOL(ieee80211_scan_completed);
377 290
378static int ieee80211_start_sw_scan(struct ieee80211_local *local) 291static int ieee80211_start_sw_scan(struct ieee80211_local *local)
379{ 292{
380 struct ieee80211_sub_if_data *sdata;
381
382 /* 293 /*
383 * Hardware/driver doesn't support hw_scan, so use software 294 * Hardware/driver doesn't support hw_scan, so use software
384 * scanning instead. First send a nullfunc frame with power save 295 * scanning instead. First send a nullfunc frame with power save
@@ -394,33 +305,15 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
394 */ 305 */
395 drv_sw_scan_start(local); 306 drv_sw_scan_start(local);
396 307
397 mutex_lock(&local->iflist_mtx); 308 ieee80211_offchannel_stop_beaconing(local);
398 list_for_each_entry(sdata, &local->interfaces, list) {
399 if (!netif_running(sdata->dev))
400 continue;
401
402 /* disable beaconing */
403 if (sdata->vif.type == NL80211_IFTYPE_AP ||
404 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
405 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
406 ieee80211_bss_info_change_notify(
407 sdata, BSS_CHANGED_BEACON_ENABLED);
408
409 /*
410 * only handle non-STA interfaces here, STA interfaces
411 * are handled in the scan state machine
412 */
413 if (sdata->vif.type != NL80211_IFTYPE_STATION)
414 netif_stop_queue(sdata->dev);
415 }
416 mutex_unlock(&local->iflist_mtx);
417 309
418 local->next_scan_state = SCAN_DECISION; 310 local->next_scan_state = SCAN_DECISION;
419 local->scan_channel_idx = 0; 311 local->scan_channel_idx = 0;
420 312
313 drv_flush(local, false);
314
421 ieee80211_configure_filter(local); 315 ieee80211_configure_filter(local);
422 316
423 /* TODO: start scan as soon as all nullfunc frames are ACKed */
424 ieee80211_queue_delayed_work(&local->hw, 317 ieee80211_queue_delayed_work(&local->hw,
425 &local->scan_work, 318 &local->scan_work,
426 IEEE80211_CHANNEL_TIME); 319 IEEE80211_CHANNEL_TIME);
@@ -433,7 +326,6 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
433 struct cfg80211_scan_request *req) 326 struct cfg80211_scan_request *req)
434{ 327{
435 struct ieee80211_local *local = sdata->local; 328 struct ieee80211_local *local = sdata->local;
436 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
437 int rc; 329 int rc;
438 330
439 if (local->scan_req) 331 if (local->scan_req)
@@ -463,11 +355,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
463 local->scan_req = req; 355 local->scan_req = req;
464 local->scan_sdata = sdata; 356 local->scan_sdata = sdata;
465 357
466 if (req != local->int_scan_req && 358 if (!list_empty(&local->work_list)) {
467 sdata->vif.type == NL80211_IFTYPE_STATION && 359 /* wait for the work to finish/time out */
468 !list_empty(&ifmgd->work_list)) {
469 /* actually wait for the work it's doing to finish/time out */
470 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
471 return 0; 360 return 0;
472 } 361 }
473 362
@@ -526,7 +415,7 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
526 /* check if at least one STA interface is associated */ 415 /* check if at least one STA interface is associated */
527 mutex_lock(&local->iflist_mtx); 416 mutex_lock(&local->iflist_mtx);
528 list_for_each_entry(sdata, &local->interfaces, list) { 417 list_for_each_entry(sdata, &local->interfaces, list) {
529 if (!netif_running(sdata->dev)) 418 if (!ieee80211_sdata_running(sdata))
530 continue; 419 continue;
531 420
532 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 421 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
@@ -564,56 +453,35 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
564static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, 453static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
565 unsigned long *next_delay) 454 unsigned long *next_delay)
566{ 455{
567 struct ieee80211_sub_if_data *sdata; 456 ieee80211_offchannel_stop_station(local);
457
458 __set_bit(SCAN_OFF_CHANNEL, &local->scanning);
568 459
569 /* 460 /*
570 * notify the AP about us leaving the channel and stop all STA interfaces 461 * What if the nullfunc frames didn't arrive?
571 */ 462 */
572 mutex_lock(&local->iflist_mtx); 463 drv_flush(local, false);
573 list_for_each_entry(sdata, &local->interfaces, list) { 464 if (local->ops->flush)
574 if (!netif_running(sdata->dev)) 465 *next_delay = 0;
575 continue; 466 else
576 467 *next_delay = HZ / 10;
577 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
578 netif_stop_queue(sdata->dev);
579 if (sdata->u.mgd.associated)
580 ieee80211_scan_ps_enable(sdata);
581 }
582 }
583 mutex_unlock(&local->iflist_mtx);
584
585 __set_bit(SCAN_OFF_CHANNEL, &local->scanning);
586 468
587 /* advance to the next channel to be scanned */ 469 /* advance to the next channel to be scanned */
588 *next_delay = HZ / 10;
589 local->next_scan_state = SCAN_SET_CHANNEL; 470 local->next_scan_state = SCAN_SET_CHANNEL;
590} 471}
591 472
592static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local, 473static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local,
593 unsigned long *next_delay) 474 unsigned long *next_delay)
594{ 475{
595 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
596
597 /* switch back to the operating channel */ 476 /* switch back to the operating channel */
598 local->scan_channel = NULL; 477 local->scan_channel = NULL;
599 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 478 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
600 479
601 /* 480 /*
602 * notify the AP about us being back and restart all STA interfaces 481 * Only re-enable station mode interface now; beaconing will be
482 * re-enabled once the full scan has been completed.
603 */ 483 */
604 mutex_lock(&local->iflist_mtx); 484 ieee80211_offchannel_return(local, false);
605 list_for_each_entry(sdata, &local->interfaces, list) {
606 if (!netif_running(sdata->dev))
607 continue;
608
609 /* Tell AP we're back */
610 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
611 if (sdata->u.mgd.associated)
612 ieee80211_scan_ps_disable(sdata);
613 netif_wake_queue(sdata->dev);
614 }
615 }
616 mutex_unlock(&local->iflist_mtx);
617 485
618 __clear_bit(SCAN_OFF_CHANNEL, &local->scanning); 486 __clear_bit(SCAN_OFF_CHANNEL, &local->scanning);
619 487
@@ -727,7 +595,7 @@ void ieee80211_scan_work(struct work_struct *work)
727 /* 595 /*
728 * Avoid re-scheduling when the sdata is going away. 596 * Avoid re-scheduling when the sdata is going away.
729 */ 597 */
730 if (!netif_running(sdata->dev)) { 598 if (!ieee80211_sdata_running(sdata)) {
731 ieee80211_scan_completed(&local->hw, true); 599 ieee80211_scan_completed(&local->hw, true);
732 return; 600 return;
733 } 601 }
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d1a77e79d7a9..47da552ce8a6 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -359,6 +359,7 @@ int sta_info_insert(struct sta_info *sta)
359{ 359{
360 struct ieee80211_local *local = sta->local; 360 struct ieee80211_local *local = sta->local;
361 struct ieee80211_sub_if_data *sdata = sta->sdata; 361 struct ieee80211_sub_if_data *sdata = sta->sdata;
362 struct station_info sinfo;
362 unsigned long flags; 363 unsigned long flags;
363 int err = 0; 364 int err = 0;
364 365
@@ -367,7 +368,7 @@ int sta_info_insert(struct sta_info *sta)
367 * something inserts a STA (on one CPU) without holding the RTNL 368 * something inserts a STA (on one CPU) without holding the RTNL
368 * and another CPU turns off the net device. 369 * and another CPU turns off the net device.
369 */ 370 */
370 if (unlikely(!netif_running(sdata->dev))) { 371 if (unlikely(!ieee80211_sdata_running(sdata))) {
371 err = -ENETDOWN; 372 err = -ENETDOWN;
372 goto out_free; 373 goto out_free;
373 } 374 }
@@ -408,6 +409,10 @@ int sta_info_insert(struct sta_info *sta)
408 409
409 spin_unlock_irqrestore(&local->sta_lock, flags); 410 spin_unlock_irqrestore(&local->sta_lock, flags);
410 411
412 sinfo.filled = 0;
413 sinfo.generation = local->sta_generation;
414 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_ATOMIC);
415
411#ifdef CONFIG_MAC80211_DEBUGFS 416#ifdef CONFIG_MAC80211_DEBUGFS
412 /* 417 /*
413 * Debugfs entry adding might sleep, so schedule process 418 * Debugfs entry adding might sleep, so schedule process
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 0c0850d37dda..0ebcdda24200 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -351,7 +351,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
351 rcu_read_lock(); 351 rcu_read_lock();
352 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 352 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
353 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { 353 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
354 if (!netif_running(sdata->dev)) 354 if (!ieee80211_sdata_running(sdata))
355 continue; 355 continue;
356 356
357 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) && 357 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ac48c86ae6b3..7bba49d2b6ca 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1418,6 +1418,10 @@ static bool need_dynamic_ps(struct ieee80211_local *local)
1418 if (!local->ps_sdata) 1418 if (!local->ps_sdata)
1419 return false; 1419 return false;
1420 1420
1421 /* No point if we're going to suspend */
1422 if (local->quiescing)
1423 return false;
1424
1421 return true; 1425 return true;
1422} 1426}
1423 1427
@@ -1469,7 +1473,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1469 1473
1470 list_for_each_entry_rcu(tmp_sdata, &local->interfaces, 1474 list_for_each_entry_rcu(tmp_sdata, &local->interfaces,
1471 list) { 1475 list) {
1472 if (!netif_running(tmp_sdata->dev)) 1476 if (!ieee80211_sdata_running(tmp_sdata))
1473 continue; 1477 continue;
1474 if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) 1478 if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
1475 continue; 1479 continue;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index b01972579c7c..7e38858a9280 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -468,7 +468,7 @@ void ieee80211_iterate_active_interfaces(
468 case NL80211_IFTYPE_MESH_POINT: 468 case NL80211_IFTYPE_MESH_POINT:
469 break; 469 break;
470 } 470 }
471 if (netif_running(sdata->dev)) 471 if (ieee80211_sdata_running(sdata))
472 iterator(data, sdata->vif.addr, 472 iterator(data, sdata->vif.addr,
473 &sdata->vif); 473 &sdata->vif);
474 } 474 }
@@ -502,7 +502,7 @@ void ieee80211_iterate_active_interfaces_atomic(
502 case NL80211_IFTYPE_MESH_POINT: 502 case NL80211_IFTYPE_MESH_POINT:
503 break; 503 break;
504 } 504 }
505 if (netif_running(sdata->dev)) 505 if (ieee80211_sdata_running(sdata))
506 iterator(data, sdata->vif.addr, 506 iterator(data, sdata->vif.addr,
507 &sdata->vif); 507 &sdata->vif);
508 } 508 }
@@ -881,30 +881,66 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
881 enum ieee80211_band band) 881 enum ieee80211_band band)
882{ 882{
883 struct ieee80211_supported_band *sband; 883 struct ieee80211_supported_band *sband;
884 u8 *pos, *supp_rates_len, *esupp_rates_len = NULL; 884 u8 *pos;
885 int i; 885 size_t offset = 0, noffset;
886 int supp_rates_len, i;
886 887
887 sband = local->hw.wiphy->bands[band]; 888 sband = local->hw.wiphy->bands[band];
888 889
889 pos = buffer; 890 pos = buffer;
890 891
892 supp_rates_len = min_t(int, sband->n_bitrates, 8);
893
891 *pos++ = WLAN_EID_SUPP_RATES; 894 *pos++ = WLAN_EID_SUPP_RATES;
892 supp_rates_len = pos; 895 *pos++ = supp_rates_len;
893 *pos++ = 0; 896
894 897 for (i = 0; i < supp_rates_len; i++) {
895 for (i = 0; i < sband->n_bitrates; i++) { 898 int rate = sband->bitrates[i].bitrate;
896 struct ieee80211_rate *rate = &sband->bitrates[i]; 899 *pos++ = (u8) (rate / 5);
897 900 }
898 if (esupp_rates_len) { 901
899 *esupp_rates_len += 1; 902 /* insert "request information" if in custom IEs */
900 } else if (*supp_rates_len == 8) { 903 if (ie && ie_len) {
901 *pos++ = WLAN_EID_EXT_SUPP_RATES; 904 static const u8 before_extrates[] = {
902 esupp_rates_len = pos; 905 WLAN_EID_SSID,
903 *pos++ = 1; 906 WLAN_EID_SUPP_RATES,
904 } else 907 WLAN_EID_REQUEST,
905 *supp_rates_len += 1; 908 };
909 noffset = ieee80211_ie_split(ie, ie_len,
910 before_extrates,
911 ARRAY_SIZE(before_extrates),
912 offset);
913 memcpy(pos, ie + offset, noffset - offset);
914 pos += noffset - offset;
915 offset = noffset;
916 }
906 917
907 *pos++ = rate->bitrate / 5; 918 if (sband->n_bitrates > i) {
919 *pos++ = WLAN_EID_EXT_SUPP_RATES;
920 *pos++ = sband->n_bitrates - i;
921
922 for (; i < sband->n_bitrates; i++) {
923 int rate = sband->bitrates[i].bitrate;
924 *pos++ = (u8) (rate / 5);
925 }
926 }
927
928 /* insert custom IEs that go before HT */
929 if (ie && ie_len) {
930 static const u8 before_ht[] = {
931 WLAN_EID_SSID,
932 WLAN_EID_SUPP_RATES,
933 WLAN_EID_REQUEST,
934 WLAN_EID_EXT_SUPP_RATES,
935 WLAN_EID_DS_PARAMS,
936 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
937 };
938 noffset = ieee80211_ie_split(ie, ie_len,
939 before_ht, ARRAY_SIZE(before_ht),
940 offset);
941 memcpy(pos, ie + offset, noffset - offset);
942 pos += noffset - offset;
943 offset = noffset;
908 } 944 }
909 945
910 if (sband->ht_cap.ht_supported) { 946 if (sband->ht_cap.ht_supported) {
@@ -936,9 +972,11 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
936 * that calculates local->scan_ies_len. 972 * that calculates local->scan_ies_len.
937 */ 973 */
938 974
939 if (ie) { 975 /* add any remaining custom IEs */
940 memcpy(pos, ie, ie_len); 976 if (ie && ie_len) {
941 pos += ie_len; 977 noffset = ie_len;
978 memcpy(pos, ie + offset, noffset - offset);
979 pos += noffset - offset;
942 } 980 }
943 981
944 return pos - buffer; 982 return pos - buffer;
@@ -1037,7 +1075,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1037{ 1075{
1038 struct ieee80211_hw *hw = &local->hw; 1076 struct ieee80211_hw *hw = &local->hw;
1039 struct ieee80211_sub_if_data *sdata; 1077 struct ieee80211_sub_if_data *sdata;
1040 struct ieee80211_if_init_conf conf;
1041 struct sta_info *sta; 1078 struct sta_info *sta;
1042 unsigned long flags; 1079 unsigned long flags;
1043 int res; 1080 int res;
@@ -1047,7 +1084,19 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1047 1084
1048 /* restart hardware */ 1085 /* restart hardware */
1049 if (local->open_count) { 1086 if (local->open_count) {
1087 /*
1088 * Upon resume hardware can sometimes be goofy due to
1089 * various platform / driver / bus issues, so restarting
1090 * the device may at times not work immediately. Propagate
1091 * the error.
1092 */
1050 res = drv_start(local); 1093 res = drv_start(local);
1094 if (res) {
1095 WARN(local->suspended, "Harware became unavailable "
1096 "upon resume. This is could be a software issue"
1097 "prior to suspend or a harware issue\n");
1098 return res;
1099 }
1051 1100
1052 ieee80211_led_radio(local, true); 1101 ieee80211_led_radio(local, true);
1053 } 1102 }
@@ -1056,12 +1105,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1056 list_for_each_entry(sdata, &local->interfaces, list) { 1105 list_for_each_entry(sdata, &local->interfaces, list) {
1057 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 1106 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1058 sdata->vif.type != NL80211_IFTYPE_MONITOR && 1107 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
1059 netif_running(sdata->dev)) { 1108 ieee80211_sdata_running(sdata))
1060 conf.vif = &sdata->vif; 1109 res = drv_add_interface(local, &sdata->vif);
1061 conf.type = sdata->vif.type;
1062 conf.mac_addr = sdata->vif.addr;
1063 res = drv_add_interface(local, &conf);
1064 }
1065 } 1110 }
1066 1111
1067 /* add STAs back */ 1112 /* add STAs back */
@@ -1103,7 +1148,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1103 /* Finally also reconfigure all the BSS information */ 1148 /* Finally also reconfigure all the BSS information */
1104 list_for_each_entry(sdata, &local->interfaces, list) { 1149 list_for_each_entry(sdata, &local->interfaces, list) {
1105 u32 changed = ~0; 1150 u32 changed = ~0;
1106 if (!netif_running(sdata->dev)) 1151 if (!ieee80211_sdata_running(sdata))
1107 continue; 1152 continue;
1108 switch (sdata->vif.type) { 1153 switch (sdata->vif.type) {
1109 case NL80211_IFTYPE_STATION: 1154 case NL80211_IFTYPE_STATION:
@@ -1131,7 +1176,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1131 1176
1132 /* add back keys */ 1177 /* add back keys */
1133 list_for_each_entry(sdata, &local->interfaces, list) 1178 list_for_each_entry(sdata, &local->interfaces, list)
1134 if (netif_running(sdata->dev)) 1179 if (ieee80211_sdata_running(sdata))
1135 ieee80211_enable_keys(sdata); 1180 ieee80211_enable_keys(sdata);
1136 1181
1137 ieee80211_wake_queues_by_reason(hw, 1182 ieee80211_wake_queues_by_reason(hw,
@@ -1252,3 +1297,59 @@ void ieee80211_recalc_smps(struct ieee80211_local *local,
1252 /* changed flag is auto-detected for this */ 1297 /* changed flag is auto-detected for this */
1253 ieee80211_hw_config(local, 0); 1298 ieee80211_hw_config(local, 0);
1254} 1299}
1300
1301static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)
1302{
1303 int i;
1304
1305 for (i = 0; i < n_ids; i++)
1306 if (ids[i] == id)
1307 return true;
1308 return false;
1309}
1310
1311/**
1312 * ieee80211_ie_split - split an IE buffer according to ordering
1313 *
1314 * @ies: the IE buffer
1315 * @ielen: the length of the IE buffer
1316 * @ids: an array with element IDs that are allowed before
1317 * the split
1318 * @n_ids: the size of the element ID array
1319 * @offset: offset where to start splitting in the buffer
1320 *
1321 * This function splits an IE buffer by updating the @offset
1322 * variable to point to the location where the buffer should be
1323 * split.
1324 *
1325 * It assumes that the given IE buffer is well-formed, this
1326 * has to be guaranteed by the caller!
1327 *
1328 * It also assumes that the IEs in the buffer are ordered
1329 * correctly, if not the result of using this function will not
1330 * be ordered correctly either, i.e. it does no reordering.
1331 *
1332 * The function returns the offset where the next part of the
1333 * buffer starts, which may be @ielen if the entire (remainder)
1334 * of the buffer should be used.
1335 */
1336size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
1337 const u8 *ids, int n_ids, size_t offset)
1338{
1339 size_t pos = offset;
1340
1341 while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos]))
1342 pos += 2 + ies[pos + 1];
1343
1344 return pos;
1345}
1346
1347size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
1348{
1349 size_t pos = offset;
1350
1351 while (pos < ielen && ies[pos] != WLAN_EID_VENDOR_SPECIFIC)
1352 pos += 2 + ies[pos + 1];
1353
1354 return pos;
1355}
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
new file mode 100644
index 000000000000..ea89ed70734d
--- /dev/null
+++ b/net/mac80211/work.c
@@ -0,0 +1,1086 @@
1/*
2 * mac80211 work implementation
3 *
4 * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
5 * Copyright 2004, Instant802 Networks, Inc.
6 * Copyright 2005, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/delay.h>
17#include <linux/if_ether.h>
18#include <linux/skbuff.h>
19#include <linux/if_arp.h>
20#include <linux/etherdevice.h>
21#include <linux/crc32.h>
22#include <net/mac80211.h>
23#include <asm/unaligned.h>
24
25#include "ieee80211_i.h"
26#include "rate.h"
27
28#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
29#define IEEE80211_AUTH_MAX_TRIES 3
30#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
31#define IEEE80211_ASSOC_MAX_TRIES 3
32#define IEEE80211_MAX_PROBE_TRIES 5
33
34enum work_action {
35 WORK_ACT_NONE,
36 WORK_ACT_TIMEOUT,
37 WORK_ACT_DONE,
38};
39
40
41/* utils */
42static inline void ASSERT_WORK_MTX(struct ieee80211_local *local)
43{
44 WARN_ON(!mutex_is_locked(&local->work_mtx));
45}
46
47/*
48 * We can have multiple work items (and connection probing)
49 * scheduling this timer, but we need to take care to only
50 * reschedule it when it should fire _earlier_ than it was
51 * asked for before, or if it's not pending right now. This
52 * function ensures that. Note that it then is required to
53 * run this function for all timeouts after the first one
54 * has happened -- the work that runs from this timer will
55 * do that.
56 */
57static void run_again(struct ieee80211_local *local,
58 unsigned long timeout)
59{
60 ASSERT_WORK_MTX(local);
61
62 if (!timer_pending(&local->work_timer) ||
63 time_before(timeout, local->work_timer.expires))
64 mod_timer(&local->work_timer, timeout);
65}
66
67static void work_free_rcu(struct rcu_head *head)
68{
69 struct ieee80211_work *wk =
70 container_of(head, struct ieee80211_work, rcu_head);
71
72 kfree(wk);
73}
74
75void free_work(struct ieee80211_work *wk)
76{
77 call_rcu(&wk->rcu_head, work_free_rcu);
78}
79
80static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
81 struct ieee80211_supported_band *sband,
82 u32 *rates)
83{
84 int i, j, count;
85 *rates = 0;
86 count = 0;
87 for (i = 0; i < supp_rates_len; i++) {
88 int rate = (supp_rates[i] & 0x7F) * 5;
89
90 for (j = 0; j < sband->n_bitrates; j++)
91 if (sband->bitrates[j].bitrate == rate) {
92 *rates |= BIT(j);
93 count++;
94 break;
95 }
96 }
97
98 return count;
99}
100
101/* frame sending functions */
102
103static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
104 struct ieee80211_supported_band *sband,
105 struct ieee80211_channel *channel,
106 enum ieee80211_smps_mode smps)
107{
108 struct ieee80211_ht_info *ht_info;
109 u8 *pos;
110 u32 flags = channel->flags;
111 u16 cap = sband->ht_cap.cap;
112 __le16 tmp;
113
114 if (!sband->ht_cap.ht_supported)
115 return;
116
117 if (!ht_info_ie)
118 return;
119
120 if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
121 return;
122
123 ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
124
125 /* determine capability flags */
126
127 if (ieee80211_disable_40mhz_24ghz &&
128 sband->band == IEEE80211_BAND_2GHZ) {
129 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
130 cap &= ~IEEE80211_HT_CAP_SGI_40;
131 }
132
133 switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
134 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
135 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
136 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
137 cap &= ~IEEE80211_HT_CAP_SGI_40;
138 }
139 break;
140 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
141 if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
142 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
143 cap &= ~IEEE80211_HT_CAP_SGI_40;
144 }
145 break;
146 }
147
148 /* set SM PS mode properly */
149 cap &= ~IEEE80211_HT_CAP_SM_PS;
150 switch (smps) {
151 case IEEE80211_SMPS_AUTOMATIC:
152 case IEEE80211_SMPS_NUM_MODES:
153 WARN_ON(1);
154 case IEEE80211_SMPS_OFF:
155 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
156 IEEE80211_HT_CAP_SM_PS_SHIFT;
157 break;
158 case IEEE80211_SMPS_STATIC:
159 cap |= WLAN_HT_CAP_SM_PS_STATIC <<
160 IEEE80211_HT_CAP_SM_PS_SHIFT;
161 break;
162 case IEEE80211_SMPS_DYNAMIC:
163 cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
164 IEEE80211_HT_CAP_SM_PS_SHIFT;
165 break;
166 }
167
168 /* reserve and fill IE */
169
170 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
171 *pos++ = WLAN_EID_HT_CAPABILITY;
172 *pos++ = sizeof(struct ieee80211_ht_cap);
173 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
174
175 /* capability flags */
176 tmp = cpu_to_le16(cap);
177 memcpy(pos, &tmp, sizeof(u16));
178 pos += sizeof(u16);
179
180 /* AMPDU parameters */
181 *pos++ = sband->ht_cap.ampdu_factor |
182 (sband->ht_cap.ampdu_density <<
183 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
184
185 /* MCS set */
186 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
187 pos += sizeof(sband->ht_cap.mcs);
188
189 /* extended capabilities */
190 pos += sizeof(__le16);
191
192 /* BF capabilities */
193 pos += sizeof(__le32);
194
195 /* antenna selection */
196 pos += sizeof(u8);
197}
198
199static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
200 struct ieee80211_work *wk)
201{
202 struct ieee80211_local *local = sdata->local;
203 struct sk_buff *skb;
204 struct ieee80211_mgmt *mgmt;
205 u8 *pos;
206 const u8 *ies;
207 size_t offset = 0, noffset;
208 int i, len, count, rates_len, supp_rates_len;
209 u16 capab;
210 struct ieee80211_supported_band *sband;
211 u32 rates = 0;
212
213 sband = local->hw.wiphy->bands[wk->chan->band];
214
215 /*
216 * Get all rates supported by the device and the AP as
217 * some APs don't like getting a superset of their rates
218 * in the association request (e.g. D-Link DAP 1353 in
219 * b-only mode)...
220 */
221 rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
222 wk->assoc.supp_rates_len,
223 sband, &rates);
224
225 skb = alloc_skb(local->hw.extra_tx_headroom +
226 sizeof(*mgmt) + /* bit too much but doesn't matter */
227 2 + wk->assoc.ssid_len + /* SSID */
228 4 + rates_len + /* (extended) rates */
229 4 + /* power capability */
230 2 + 2 * sband->n_channels + /* supported channels */
231 2 + sizeof(struct ieee80211_ht_cap) + /* HT */
232 wk->ie_len + /* extra IEs */
233 9, /* WMM */
234 GFP_KERNEL);
235 if (!skb) {
236 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
237 "frame\n", sdata->name);
238 return;
239 }
240 skb_reserve(skb, local->hw.extra_tx_headroom);
241
242 capab = WLAN_CAPABILITY_ESS;
243
244 if (sband->band == IEEE80211_BAND_2GHZ) {
245 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
246 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
247 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
248 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
249 }
250
251 if (wk->assoc.capability & WLAN_CAPABILITY_PRIVACY)
252 capab |= WLAN_CAPABILITY_PRIVACY;
253
254 if ((wk->assoc.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
255 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
256 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
257
258 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
259 memset(mgmt, 0, 24);
260 memcpy(mgmt->da, wk->filter_ta, ETH_ALEN);
261 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
262 memcpy(mgmt->bssid, wk->filter_ta, ETH_ALEN);
263
264 if (!is_zero_ether_addr(wk->assoc.prev_bssid)) {
265 skb_put(skb, 10);
266 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
267 IEEE80211_STYPE_REASSOC_REQ);
268 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
269 mgmt->u.reassoc_req.listen_interval =
270 cpu_to_le16(local->hw.conf.listen_interval);
271 memcpy(mgmt->u.reassoc_req.current_ap, wk->assoc.prev_bssid,
272 ETH_ALEN);
273 } else {
274 skb_put(skb, 4);
275 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
276 IEEE80211_STYPE_ASSOC_REQ);
277 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
278 mgmt->u.assoc_req.listen_interval =
279 cpu_to_le16(local->hw.conf.listen_interval);
280 }
281
282 /* SSID */
283 ies = pos = skb_put(skb, 2 + wk->assoc.ssid_len);
284 *pos++ = WLAN_EID_SSID;
285 *pos++ = wk->assoc.ssid_len;
286 memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len);
287
288 /* add all rates which were marked to be used above */
289 supp_rates_len = rates_len;
290 if (supp_rates_len > 8)
291 supp_rates_len = 8;
292
293 len = sband->n_bitrates;
294 pos = skb_put(skb, supp_rates_len + 2);
295 *pos++ = WLAN_EID_SUPP_RATES;
296 *pos++ = supp_rates_len;
297
298 count = 0;
299 for (i = 0; i < sband->n_bitrates; i++) {
300 if (BIT(i) & rates) {
301 int rate = sband->bitrates[i].bitrate;
302 *pos++ = (u8) (rate / 5);
303 if (++count == 8)
304 break;
305 }
306 }
307
308 if (rates_len > count) {
309 pos = skb_put(skb, rates_len - count + 2);
310 *pos++ = WLAN_EID_EXT_SUPP_RATES;
311 *pos++ = rates_len - count;
312
313 for (i++; i < sband->n_bitrates; i++) {
314 if (BIT(i) & rates) {
315 int rate = sband->bitrates[i].bitrate;
316 *pos++ = (u8) (rate / 5);
317 }
318 }
319 }
320
321 if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
322 /* 1. power capabilities */
323 pos = skb_put(skb, 4);
324 *pos++ = WLAN_EID_PWR_CAPABILITY;
325 *pos++ = 2;
326 *pos++ = 0; /* min tx power */
327 *pos++ = wk->chan->max_power; /* max tx power */
328
329 /* 2. supported channels */
330 /* TODO: get this in reg domain format */
331 pos = skb_put(skb, 2 * sband->n_channels + 2);
332 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
333 *pos++ = 2 * sband->n_channels;
334 for (i = 0; i < sband->n_channels; i++) {
335 *pos++ = ieee80211_frequency_to_channel(
336 sband->channels[i].center_freq);
337 *pos++ = 1; /* one channel in the subband*/
338 }
339 }
340
341 /* if present, add any custom IEs that go before HT */
342 if (wk->ie_len && wk->ie) {
343 static const u8 before_ht[] = {
344 WLAN_EID_SSID,
345 WLAN_EID_SUPP_RATES,
346 WLAN_EID_EXT_SUPP_RATES,
347 WLAN_EID_PWR_CAPABILITY,
348 WLAN_EID_SUPPORTED_CHANNELS,
349 WLAN_EID_RSN,
350 WLAN_EID_QOS_CAPA,
351 WLAN_EID_RRM_ENABLED_CAPABILITIES,
352 WLAN_EID_MOBILITY_DOMAIN,
353 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
354 };
355 noffset = ieee80211_ie_split(wk->ie, wk->ie_len,
356 before_ht, ARRAY_SIZE(before_ht),
357 offset);
358 pos = skb_put(skb, noffset - offset);
359 memcpy(pos, wk->ie + offset, noffset - offset);
360 offset = noffset;
361 }
362
363 if (wk->assoc.use_11n && wk->assoc.wmm_used &&
364 local->hw.queues >= 4)
365 ieee80211_add_ht_ie(skb, wk->assoc.ht_information_ie,
366 sband, wk->chan, wk->assoc.smps);
367
368 /* if present, add any custom non-vendor IEs that go after HT */
369 if (wk->ie_len && wk->ie) {
370 noffset = ieee80211_ie_split_vendor(wk->ie, wk->ie_len,
371 offset);
372 pos = skb_put(skb, noffset - offset);
373 memcpy(pos, wk->ie + offset, noffset - offset);
374 offset = noffset;
375 }
376
377 if (wk->assoc.wmm_used && local->hw.queues >= 4) {
378 pos = skb_put(skb, 9);
379 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
380 *pos++ = 7; /* len */
381 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
382 *pos++ = 0x50;
383 *pos++ = 0xf2;
384 *pos++ = 2; /* WME */
385 *pos++ = 0; /* WME info */
386 *pos++ = 1; /* WME ver */
387 *pos++ = 0;
388 }
389
390 /* add any remaining custom (i.e. vendor specific here) IEs */
391 if (wk->ie_len && wk->ie) {
392 noffset = wk->ie_len;
393 pos = skb_put(skb, noffset - offset);
394 memcpy(pos, wk->ie + offset, noffset - offset);
395 }
396
397 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
398 ieee80211_tx_skb(sdata, skb);
399}
400
401static void ieee80211_remove_auth_bss(struct ieee80211_local *local,
402 struct ieee80211_work *wk)
403{
404 struct cfg80211_bss *cbss;
405 u16 capa_val = WLAN_CAPABILITY_ESS;
406
407 if (wk->probe_auth.privacy)
408 capa_val |= WLAN_CAPABILITY_PRIVACY;
409
410 cbss = cfg80211_get_bss(local->hw.wiphy, wk->chan, wk->filter_ta,
411 wk->probe_auth.ssid, wk->probe_auth.ssid_len,
412 WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
413 capa_val);
414 if (!cbss)
415 return;
416
417 cfg80211_unlink_bss(local->hw.wiphy, cbss);
418 cfg80211_put_bss(cbss);
419}
420
421static enum work_action __must_check
422ieee80211_direct_probe(struct ieee80211_work *wk)
423{
424 struct ieee80211_sub_if_data *sdata = wk->sdata;
425 struct ieee80211_local *local = sdata->local;
426
427 wk->probe_auth.tries++;
428 if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
429 printk(KERN_DEBUG "%s: direct probe to %pM timed out\n",
430 sdata->name, wk->filter_ta);
431
432 /*
433 * Most likely AP is not in the range so remove the
434 * bss struct for that AP.
435 */
436 ieee80211_remove_auth_bss(local, wk);
437
438 return WORK_ACT_TIMEOUT;
439 }
440
441 printk(KERN_DEBUG "%s: direct probe to %pM (try %d)\n",
442 sdata->name, wk->filter_ta, wk->probe_auth.tries);
443
444 /*
445 * Direct probe is sent to broadcast address as some APs
446 * will not answer to direct packet in unassociated state.
447 */
448 ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
449 wk->probe_auth.ssid_len, NULL, 0);
450
451 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
452 run_again(local, wk->timeout);
453
454 return WORK_ACT_NONE;
455}
456
457
458static enum work_action __must_check
459ieee80211_authenticate(struct ieee80211_work *wk)
460{
461 struct ieee80211_sub_if_data *sdata = wk->sdata;
462 struct ieee80211_local *local = sdata->local;
463
464 wk->probe_auth.tries++;
465 if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
466 printk(KERN_DEBUG "%s: authentication with %pM"
467 " timed out\n", sdata->name, wk->filter_ta);
468
469 /*
470 * Most likely AP is not in the range so remove the
471 * bss struct for that AP.
472 */
473 ieee80211_remove_auth_bss(local, wk);
474
475 return WORK_ACT_TIMEOUT;
476 }
477
478 printk(KERN_DEBUG "%s: authenticate with %pM (try %d)\n",
479 sdata->name, wk->filter_ta, wk->probe_auth.tries);
480
481 ieee80211_send_auth(sdata, 1, wk->probe_auth.algorithm, wk->ie,
482 wk->ie_len, wk->filter_ta, NULL, 0, 0);
483 wk->probe_auth.transaction = 2;
484
485 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
486 run_again(local, wk->timeout);
487
488 return WORK_ACT_NONE;
489}
490
491static enum work_action __must_check
492ieee80211_associate(struct ieee80211_work *wk)
493{
494 struct ieee80211_sub_if_data *sdata = wk->sdata;
495 struct ieee80211_local *local = sdata->local;
496
497 wk->assoc.tries++;
498 if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) {
499 printk(KERN_DEBUG "%s: association with %pM"
500 " timed out\n",
501 sdata->name, wk->filter_ta);
502
503 /*
504 * Most likely AP is not in the range so remove the
505 * bss struct for that AP.
506 */
507 if (wk->assoc.bss)
508 cfg80211_unlink_bss(local->hw.wiphy, wk->assoc.bss);
509
510 return WORK_ACT_TIMEOUT;
511 }
512
513 printk(KERN_DEBUG "%s: associate with %pM (try %d)\n",
514 sdata->name, wk->filter_ta, wk->assoc.tries);
515 ieee80211_send_assoc(sdata, wk);
516
517 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
518 run_again(local, wk->timeout);
519
520 return WORK_ACT_NONE;
521}
522
523static enum work_action __must_check
524ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
525{
526 /*
527 * First time we run, do nothing -- the generic code will
528 * have switched to the right channel etc.
529 */
530 if (!wk->remain.started) {
531 wk->remain.started = true;
532 wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration);
533
534 cfg80211_ready_on_channel(wk->sdata->dev, (u64)wk, wk->chan,
535 wk->chan_type, wk->remain.duration,
536 GFP_KERNEL);
537
538 return WORK_ACT_NONE;
539 }
540
541 return WORK_ACT_TIMEOUT;
542}
543
544static void ieee80211_auth_challenge(struct ieee80211_work *wk,
545 struct ieee80211_mgmt *mgmt,
546 size_t len)
547{
548 struct ieee80211_sub_if_data *sdata = wk->sdata;
549 u8 *pos;
550 struct ieee802_11_elems elems;
551
552 pos = mgmt->u.auth.variable;
553 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
554 if (!elems.challenge)
555 return;
556 ieee80211_send_auth(sdata, 3, wk->probe_auth.algorithm,
557 elems.challenge - 2, elems.challenge_len + 2,
558 wk->filter_ta, wk->probe_auth.key,
559 wk->probe_auth.key_len, wk->probe_auth.key_idx);
560 wk->probe_auth.transaction = 4;
561}
562
563static enum work_action __must_check
564ieee80211_rx_mgmt_auth(struct ieee80211_work *wk,
565 struct ieee80211_mgmt *mgmt, size_t len)
566{
567 u16 auth_alg, auth_transaction, status_code;
568
569 if (wk->type != IEEE80211_WORK_AUTH)
570 return WORK_ACT_NONE;
571
572 if (len < 24 + 6)
573 return WORK_ACT_NONE;
574
575 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
576 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
577 status_code = le16_to_cpu(mgmt->u.auth.status_code);
578
579 if (auth_alg != wk->probe_auth.algorithm ||
580 auth_transaction != wk->probe_auth.transaction)
581 return WORK_ACT_NONE;
582
583 if (status_code != WLAN_STATUS_SUCCESS) {
584 printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
585 wk->sdata->name, mgmt->sa, status_code);
586 return WORK_ACT_DONE;
587 }
588
589 switch (wk->probe_auth.algorithm) {
590 case WLAN_AUTH_OPEN:
591 case WLAN_AUTH_LEAP:
592 case WLAN_AUTH_FT:
593 break;
594 case WLAN_AUTH_SHARED_KEY:
595 if (wk->probe_auth.transaction != 4) {
596 ieee80211_auth_challenge(wk, mgmt, len);
597 /* need another frame */
598 return WORK_ACT_NONE;
599 }
600 break;
601 default:
602 WARN_ON(1);
603 return WORK_ACT_NONE;
604 }
605
606 printk(KERN_DEBUG "%s: authenticated\n", wk->sdata->name);
607 return WORK_ACT_DONE;
608}
609
610static enum work_action __must_check
611ieee80211_rx_mgmt_assoc_resp(struct ieee80211_work *wk,
612 struct ieee80211_mgmt *mgmt, size_t len,
613 bool reassoc)
614{
615 struct ieee80211_sub_if_data *sdata = wk->sdata;
616 struct ieee80211_local *local = sdata->local;
617 u16 capab_info, status_code, aid;
618 struct ieee802_11_elems elems;
619 u8 *pos;
620
621 /*
622 * AssocResp and ReassocResp have identical structure, so process both
623 * of them in this function.
624 */
625
626 if (len < 24 + 6)
627 return WORK_ACT_NONE;
628
629 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
630 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
631 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
632
633 printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
634 "status=%d aid=%d)\n",
635 sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
636 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
637
638 pos = mgmt->u.assoc_resp.variable;
639 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
640
641 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
642 elems.timeout_int && elems.timeout_int_len == 5 &&
643 elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
644 u32 tu, ms;
645 tu = get_unaligned_le32(elems.timeout_int + 1);
646 ms = tu * 1024 / 1000;
647 printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
648 "comeback duration %u TU (%u ms)\n",
649 sdata->name, mgmt->sa, tu, ms);
650 wk->timeout = jiffies + msecs_to_jiffies(ms);
651 if (ms > IEEE80211_ASSOC_TIMEOUT)
652 run_again(local, wk->timeout);
653 return WORK_ACT_NONE;
654 }
655
656 if (status_code != WLAN_STATUS_SUCCESS)
657 printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
658 sdata->name, mgmt->sa, status_code);
659 else
660 printk(KERN_DEBUG "%s: associated\n", sdata->name);
661
662 return WORK_ACT_DONE;
663}
664
665static enum work_action __must_check
666ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
667 struct ieee80211_mgmt *mgmt, size_t len,
668 struct ieee80211_rx_status *rx_status)
669{
670 struct ieee80211_sub_if_data *sdata = wk->sdata;
671 struct ieee80211_local *local = sdata->local;
672 size_t baselen;
673
674 ASSERT_WORK_MTX(local);
675
676 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
677 if (baselen > len)
678 return WORK_ACT_NONE;
679
680 printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
681 return WORK_ACT_DONE;
682}
683
684static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
685 struct sk_buff *skb)
686{
687 struct ieee80211_rx_status *rx_status;
688 struct ieee80211_mgmt *mgmt;
689 struct ieee80211_work *wk;
690 enum work_action rma = WORK_ACT_NONE;
691 u16 fc;
692
693 rx_status = (struct ieee80211_rx_status *) skb->cb;
694 mgmt = (struct ieee80211_mgmt *) skb->data;
695 fc = le16_to_cpu(mgmt->frame_control);
696
697 mutex_lock(&local->work_mtx);
698
699 list_for_each_entry(wk, &local->work_list, list) {
700 const u8 *bssid = NULL;
701
702 switch (wk->type) {
703 case IEEE80211_WORK_DIRECT_PROBE:
704 case IEEE80211_WORK_AUTH:
705 case IEEE80211_WORK_ASSOC:
706 bssid = wk->filter_ta;
707 break;
708 default:
709 continue;
710 }
711
712 /*
713 * Before queuing, we already verified mgmt->sa,
714 * so this is needed just for matching.
715 */
716 if (compare_ether_addr(bssid, mgmt->bssid))
717 continue;
718
719 switch (fc & IEEE80211_FCTL_STYPE) {
720 case IEEE80211_STYPE_PROBE_RESP:
721 rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len,
722 rx_status);
723 break;
724 case IEEE80211_STYPE_AUTH:
725 rma = ieee80211_rx_mgmt_auth(wk, mgmt, skb->len);
726 break;
727 case IEEE80211_STYPE_ASSOC_RESP:
728 rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
729 skb->len, false);
730 break;
731 case IEEE80211_STYPE_REASSOC_RESP:
732 rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
733 skb->len, true);
734 break;
735 default:
736 WARN_ON(1);
737 }
738 /*
739 * We've processed this frame for that work, so it can't
740 * belong to another work struct.
741 * NB: this is also required for correctness for 'rma'!
742 */
743 break;
744 }
745
746 switch (rma) {
747 case WORK_ACT_NONE:
748 break;
749 case WORK_ACT_DONE:
750 list_del_rcu(&wk->list);
751 break;
752 default:
753 WARN(1, "unexpected: %d", rma);
754 }
755
756 mutex_unlock(&local->work_mtx);
757
758 if (rma != WORK_ACT_DONE)
759 goto out;
760
761 switch (wk->done(wk, skb)) {
762 case WORK_DONE_DESTROY:
763 free_work(wk);
764 break;
765 case WORK_DONE_REQUEUE:
766 synchronize_rcu();
767 wk->started = false; /* restart */
768 mutex_lock(&local->work_mtx);
769 list_add_tail(&wk->list, &local->work_list);
770 mutex_unlock(&local->work_mtx);
771 }
772
773 out:
774 kfree_skb(skb);
775}
776
777static void ieee80211_work_timer(unsigned long data)
778{
779 struct ieee80211_local *local = (void *) data;
780
781 if (local->quiescing)
782 return;
783
784 ieee80211_queue_work(&local->hw, &local->work_work);
785}
786
787static void ieee80211_work_work(struct work_struct *work)
788{
789 struct ieee80211_local *local =
790 container_of(work, struct ieee80211_local, work_work);
791 struct sk_buff *skb;
792 struct ieee80211_work *wk, *tmp;
793 LIST_HEAD(free_work);
794 enum work_action rma;
795 bool remain_off_channel = false;
796
797 if (local->scanning)
798 return;
799
800 /*
801 * ieee80211_queue_work() should have picked up most cases,
802 * here we'll pick the the rest.
803 */
804 if (WARN(local->suspended, "work scheduled while going to suspend\n"))
805 return;
806
807 /* first process frames to avoid timing out while a frame is pending */
808 while ((skb = skb_dequeue(&local->work_skb_queue)))
809 ieee80211_work_rx_queued_mgmt(local, skb);
810
811 ieee80211_recalc_idle(local);
812
813 mutex_lock(&local->work_mtx);
814
815 list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
816 /* mark work as started if it's on the current off-channel */
817 if (!wk->started && local->tmp_channel &&
818 wk->chan == local->tmp_channel &&
819 wk->chan_type == local->tmp_channel_type) {
820 wk->started = true;
821 }
822
823 if (!wk->started && !local->tmp_channel) {
824 /*
825 * TODO: could optimize this by leaving the
826 * station vifs in awake mode if they
827 * happen to be on the same channel as
828 * the requested channel
829 */
830 ieee80211_offchannel_stop_beaconing(local);
831 ieee80211_offchannel_stop_station(local);
832
833 local->tmp_channel = wk->chan;
834 local->tmp_channel_type = wk->chan_type;
835 ieee80211_hw_config(local, 0);
836 wk->started = true;
837 wk->timeout = jiffies;
838 }
839
840 /* don't try to work with items that aren't started */
841 if (!wk->started)
842 continue;
843
844 if (time_is_after_jiffies(wk->timeout)) {
845 /*
846 * This work item isn't supposed to be worked on
847 * right now, but take care to adjust the timer
848 * properly.
849 */
850 run_again(local, wk->timeout);
851 continue;
852 }
853
854 switch (wk->type) {
855 default:
856 WARN_ON(1);
857 /* nothing */
858 rma = WORK_ACT_NONE;
859 break;
860 case IEEE80211_WORK_ABORT:
861 rma = WORK_ACT_TIMEOUT;
862 case IEEE80211_WORK_DIRECT_PROBE:
863 rma = ieee80211_direct_probe(wk);
864 break;
865 case IEEE80211_WORK_AUTH:
866 rma = ieee80211_authenticate(wk);
867 break;
868 case IEEE80211_WORK_ASSOC:
869 rma = ieee80211_associate(wk);
870 break;
871 case IEEE80211_WORK_REMAIN_ON_CHANNEL:
872 rma = ieee80211_remain_on_channel_timeout(wk);
873 break;
874 }
875
876 switch (rma) {
877 case WORK_ACT_NONE:
878 /* might have changed the timeout */
879 run_again(local, wk->timeout);
880 break;
881 case WORK_ACT_TIMEOUT:
882 list_del_rcu(&wk->list);
883 synchronize_rcu();
884 list_add(&wk->list, &free_work);
885 break;
886 default:
887 WARN(1, "unexpected: %d", rma);
888 }
889 }
890
891 list_for_each_entry(wk, &local->work_list, list) {
892 if (!wk->started)
893 continue;
894 if (wk->chan != local->tmp_channel)
895 continue;
896 if (wk->chan_type != local->tmp_channel_type)
897 continue;
898 remain_off_channel = true;
899 }
900
901 if (!remain_off_channel && local->tmp_channel) {
902 local->tmp_channel = NULL;
903 ieee80211_hw_config(local, 0);
904 ieee80211_offchannel_return(local, true);
905 /* give connection some time to breathe */
906 run_again(local, jiffies + HZ/2);
907 }
908
909 if (list_empty(&local->work_list) && local->scan_req)
910 ieee80211_queue_delayed_work(&local->hw,
911 &local->scan_work,
912 round_jiffies_relative(0));
913
914 mutex_unlock(&local->work_mtx);
915
916 ieee80211_recalc_idle(local);
917
918 list_for_each_entry_safe(wk, tmp, &free_work, list) {
919 wk->done(wk, NULL);
920 list_del(&wk->list);
921 kfree(wk);
922 }
923}
924
925void ieee80211_add_work(struct ieee80211_work *wk)
926{
927 struct ieee80211_local *local;
928
929 if (WARN_ON(!wk->chan))
930 return;
931
932 if (WARN_ON(!wk->sdata))
933 return;
934
935 if (WARN_ON(!wk->done))
936 return;
937
938 wk->started = false;
939
940 local = wk->sdata->local;
941 mutex_lock(&local->work_mtx);
942 list_add_tail(&wk->list, &local->work_list);
943 mutex_unlock(&local->work_mtx);
944
945 ieee80211_queue_work(&local->hw, &local->work_work);
946}
947
948void ieee80211_work_init(struct ieee80211_local *local)
949{
950 mutex_init(&local->work_mtx);
951 INIT_LIST_HEAD(&local->work_list);
952 setup_timer(&local->work_timer, ieee80211_work_timer,
953 (unsigned long)local);
954 INIT_WORK(&local->work_work, ieee80211_work_work);
955 skb_queue_head_init(&local->work_skb_queue);
956}
957
958void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
959{
960 struct ieee80211_local *local = sdata->local;
961 struct ieee80211_work *wk;
962
963 mutex_lock(&local->work_mtx);
964 list_for_each_entry(wk, &local->work_list, list) {
965 if (wk->sdata != sdata)
966 continue;
967 wk->type = IEEE80211_WORK_ABORT;
968 wk->started = true;
969 wk->timeout = jiffies;
970 }
971 mutex_unlock(&local->work_mtx);
972
973 /* run cleanups etc. */
974 ieee80211_work_work(&local->work_work);
975
976 mutex_lock(&local->work_mtx);
977 list_for_each_entry(wk, &local->work_list, list) {
978 if (wk->sdata != sdata)
979 continue;
980 WARN_ON(1);
981 break;
982 }
983 mutex_unlock(&local->work_mtx);
984}
985
986ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
987 struct sk_buff *skb)
988{
989 struct ieee80211_local *local = sdata->local;
990 struct ieee80211_mgmt *mgmt;
991 struct ieee80211_work *wk;
992 u16 fc;
993
994 if (skb->len < 24)
995 return RX_DROP_MONITOR;
996
997 mgmt = (struct ieee80211_mgmt *) skb->data;
998 fc = le16_to_cpu(mgmt->frame_control);
999
1000 list_for_each_entry_rcu(wk, &local->work_list, list) {
1001 if (sdata != wk->sdata)
1002 continue;
1003 if (compare_ether_addr(wk->filter_ta, mgmt->sa))
1004 continue;
1005 if (compare_ether_addr(wk->filter_ta, mgmt->bssid))
1006 continue;
1007
1008 switch (fc & IEEE80211_FCTL_STYPE) {
1009 case IEEE80211_STYPE_AUTH:
1010 case IEEE80211_STYPE_PROBE_RESP:
1011 case IEEE80211_STYPE_ASSOC_RESP:
1012 case IEEE80211_STYPE_REASSOC_RESP:
1013 case IEEE80211_STYPE_DEAUTH:
1014 case IEEE80211_STYPE_DISASSOC:
1015 skb_queue_tail(&local->work_skb_queue, skb);
1016 ieee80211_queue_work(&local->hw, &local->work_work);
1017 return RX_QUEUED;
1018 }
1019 }
1020
1021 return RX_CONTINUE;
1022}
1023
1024static enum work_done_result ieee80211_remain_done(struct ieee80211_work *wk,
1025 struct sk_buff *skb)
1026{
1027 /*
1028 * We are done serving the remain-on-channel command.
1029 */
1030 cfg80211_remain_on_channel_expired(wk->sdata->dev, (u64)wk,
1031 wk->chan, wk->chan_type,
1032 GFP_KERNEL);
1033
1034 return WORK_DONE_DESTROY;
1035}
1036
1037int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1038 struct ieee80211_channel *chan,
1039 enum nl80211_channel_type channel_type,
1040 unsigned int duration, u64 *cookie)
1041{
1042 struct ieee80211_work *wk;
1043
1044 wk = kzalloc(sizeof(*wk), GFP_KERNEL);
1045 if (!wk)
1046 return -ENOMEM;
1047
1048 wk->type = IEEE80211_WORK_REMAIN_ON_CHANNEL;
1049 wk->chan = chan;
1050 wk->chan_type = channel_type;
1051 wk->sdata = sdata;
1052 wk->done = ieee80211_remain_done;
1053
1054 wk->remain.duration = duration;
1055
1056 *cookie = (u64)wk;
1057
1058 ieee80211_add_work(wk);
1059
1060 return 0;
1061}
1062
1063int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1064 u64 cookie)
1065{
1066 struct ieee80211_local *local = sdata->local;
1067 struct ieee80211_work *wk, *tmp;
1068 bool found = false;
1069
1070 mutex_lock(&local->work_mtx);
1071 list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
1072 if ((u64)wk == cookie) {
1073 wk->timeout = jiffies;
1074 found = true;
1075 break;
1076 }
1077 }
1078 mutex_unlock(&local->work_mtx);
1079
1080 if (!found)
1081 return -ENOENT;
1082
1083 ieee80211_queue_work(&local->hw, &local->work_work);
1084
1085 return 0;
1086}
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 8419971f07c5..d0ee29063e5d 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -94,21 +94,6 @@ config CFG80211_DEBUGFS
94 94
95 If unsure, say N. 95 If unsure, say N.
96 96
97config WIRELESS_OLD_REGULATORY
98 bool "Old wireless static regulatory definitions"
99 default n
100 depends on CFG80211
101 ---help---
102 This option enables the old static regulatory information
103 and uses it within the new framework. This option is available
104 for historical reasons and it is advised to leave it off.
105
106 For details see:
107
108 http://wireless.kernel.org/en/developers/Regulatory
109
110 Say N and if you say Y, please tell us why. The default is N.
111
112config CFG80211_INTERNAL_REGDB 97config CFG80211_INTERNAL_REGDB
113 bool "use statically compiled regulatory rules database" if EMBEDDED 98 bool "use statically compiled regulatory rules database" if EMBEDDED
114 default n 99 default n
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index a46ac6c9b365..bf1737fc9a7e 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -41,44 +41,57 @@ rdev_fixed_channel(struct cfg80211_registered_device *rdev,
41 return result; 41 return result;
42} 42}
43 43
44int rdev_set_freq(struct cfg80211_registered_device *rdev, 44struct ieee80211_channel *
45 struct wireless_dev *for_wdev, 45rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
46 int freq, enum nl80211_channel_type channel_type) 46 int freq, enum nl80211_channel_type channel_type)
47{ 47{
48 struct ieee80211_channel *chan; 48 struct ieee80211_channel *chan;
49 struct ieee80211_sta_ht_cap *ht_cap; 49 struct ieee80211_sta_ht_cap *ht_cap;
50 int result;
51
52 if (rdev_fixed_channel(rdev, for_wdev))
53 return -EBUSY;
54
55 if (!rdev->ops->set_channel)
56 return -EOPNOTSUPP;
57 50
58 chan = ieee80211_get_channel(&rdev->wiphy, freq); 51 chan = ieee80211_get_channel(&rdev->wiphy, freq);
59 52
60 /* Primary channel not allowed */ 53 /* Primary channel not allowed */
61 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) 54 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
62 return -EINVAL; 55 return NULL;
63 56
64 if (channel_type == NL80211_CHAN_HT40MINUS && 57 if (channel_type == NL80211_CHAN_HT40MINUS &&
65 chan->flags & IEEE80211_CHAN_NO_HT40MINUS) 58 chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
66 return -EINVAL; 59 return NULL;
67 else if (channel_type == NL80211_CHAN_HT40PLUS && 60 else if (channel_type == NL80211_CHAN_HT40PLUS &&
68 chan->flags & IEEE80211_CHAN_NO_HT40PLUS) 61 chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
69 return -EINVAL; 62 return NULL;
70 63
71 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap; 64 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
72 65
73 if (channel_type != NL80211_CHAN_NO_HT) { 66 if (channel_type != NL80211_CHAN_NO_HT) {
74 if (!ht_cap->ht_supported) 67 if (!ht_cap->ht_supported)
75 return -EINVAL; 68 return NULL;
76 69
77 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || 70 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
78 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT) 71 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
79 return -EINVAL; 72 return NULL;
80 } 73 }
81 74
75 return chan;
76}
77
78int rdev_set_freq(struct cfg80211_registered_device *rdev,
79 struct wireless_dev *for_wdev,
80 int freq, enum nl80211_channel_type channel_type)
81{
82 struct ieee80211_channel *chan;
83 int result;
84
85 if (rdev_fixed_channel(rdev, for_wdev))
86 return -EBUSY;
87
88 if (!rdev->ops->set_channel)
89 return -EOPNOTSUPP;
90
91 chan = rdev_freq_to_chan(rdev, freq, channel_type);
92 if (!chan)
93 return -EINVAL;
94
82 result = rdev->ops->set_channel(&rdev->wiphy, chan, channel_type); 95 result = rdev->ops->set_channel(&rdev->wiphy, chan, channel_type);
83 if (result) 96 if (result)
84 return result; 97 return result;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 35b712127143..30ec95f05b52 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -374,6 +374,9 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
374struct ieee80211_channel * 374struct ieee80211_channel *
375rdev_fixed_channel(struct cfg80211_registered_device *rdev, 375rdev_fixed_channel(struct cfg80211_registered_device *rdev,
376 struct wireless_dev *for_wdev); 376 struct wireless_dev *for_wdev);
377struct ieee80211_channel *
378rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
379 int freq, enum nl80211_channel_type channel_type);
377int rdev_set_freq(struct cfg80211_registered_device *rdev, 380int rdev_set_freq(struct cfg80211_registered_device *rdev,
378 struct wireless_dev *for_wdev, 381 struct wireless_dev *for_wdev,
379 int freq, enum nl80211_channel_type channel_type); 382 int freq, enum nl80211_channel_type channel_type);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index acaeaa784d68..94d151f6f73e 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -93,7 +93,18 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
93 } 93 }
94 } 94 }
95 95
96 WARN_ON(!bss); 96 /*
97 * We might be coming here because the driver reported
98 * a successful association at the same time as the
99 * user requested a deauth. In that case, we will have
100 * removed the BSS from the auth_bsses list due to the
101 * deauth request when the assoc response makes it. If
102 * the two code paths acquire the lock the other way
103 * around, that's just the standard situation of a
104 * deauth being requested while connected.
105 */
106 if (!bss)
107 goto out;
97 } else if (wdev->conn) { 108 } else if (wdev->conn) {
98 cfg80211_sme_failed_assoc(wdev); 109 cfg80211_sme_failed_assoc(wdev);
99 /* 110 /*
@@ -680,3 +691,40 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
680 } 691 }
681 } 692 }
682} 693}
694
695void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie,
696 struct ieee80211_channel *chan,
697 enum nl80211_channel_type channel_type,
698 unsigned int duration, gfp_t gfp)
699{
700 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
701 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
702
703 nl80211_send_remain_on_channel(rdev, dev, cookie, chan, channel_type,
704 duration, gfp);
705}
706EXPORT_SYMBOL(cfg80211_ready_on_channel);
707
708void cfg80211_remain_on_channel_expired(struct net_device *dev,
709 u64 cookie,
710 struct ieee80211_channel *chan,
711 enum nl80211_channel_type channel_type,
712 gfp_t gfp)
713{
714 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
715 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
716
717 nl80211_send_remain_on_channel_cancel(rdev, dev, cookie, chan,
718 channel_type, gfp);
719}
720EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
721
722void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
723 struct station_info *sinfo, gfp_t gfp)
724{
725 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
726 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
727
728 nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp);
729}
730EXPORT_SYMBOL(cfg80211_new_sta);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7cb0d647fc34..e3bee3cecdfa 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -141,6 +141,8 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
141 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 }, 141 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
142 [NL80211_ATTR_PMKID] = { .type = NLA_BINARY, 142 [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
143 .len = WLAN_PMKID_LEN }, 143 .len = WLAN_PMKID_LEN },
144 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
145 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
144}; 146};
145 147
146/* policy for the attributes */ 148/* policy for the attributes */
@@ -569,6 +571,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
569 CMD(set_pmksa, SET_PMKSA); 571 CMD(set_pmksa, SET_PMKSA);
570 CMD(del_pmksa, DEL_PMKSA); 572 CMD(del_pmksa, DEL_PMKSA);
571 CMD(flush_pmksa, FLUSH_PMKSA); 573 CMD(flush_pmksa, FLUSH_PMKSA);
574 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
572 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { 575 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
573 i++; 576 i++;
574 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); 577 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
@@ -1639,7 +1642,7 @@ static int parse_station_flags(struct genl_info *info,
1639 1642
1640static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, 1643static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1641 int flags, struct net_device *dev, 1644 int flags, struct net_device *dev,
1642 u8 *mac_addr, struct station_info *sinfo) 1645 const u8 *mac_addr, struct station_info *sinfo)
1643{ 1646{
1644 void *hdr; 1647 void *hdr;
1645 struct nlattr *sinfoattr, *txrate; 1648 struct nlattr *sinfoattr, *txrate;
@@ -2550,12 +2553,6 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
2550 2553
2551 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); 2554 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
2552 2555
2553#ifdef CONFIG_WIRELESS_OLD_REGULATORY
2554 /* We ignore world regdom requests with the old regdom setup */
2555 if (is_world_regdom(data))
2556 return -EINVAL;
2557#endif
2558
2559 r = regulatory_hint_user(data); 2556 r = regulatory_hint_user(data);
2560 2557
2561 return r; 2558 return r;
@@ -4289,6 +4286,143 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
4289 4286
4290} 4287}
4291 4288
4289static int nl80211_remain_on_channel(struct sk_buff *skb,
4290 struct genl_info *info)
4291{
4292 struct cfg80211_registered_device *rdev;
4293 struct net_device *dev;
4294 struct ieee80211_channel *chan;
4295 struct sk_buff *msg;
4296 void *hdr;
4297 u64 cookie;
4298 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
4299 u32 freq, duration;
4300 int err;
4301
4302 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
4303 !info->attrs[NL80211_ATTR_DURATION])
4304 return -EINVAL;
4305
4306 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
4307
4308 /*
4309 * We should be on that channel for at least one jiffie,
4310 * and more than 5 seconds seems excessive.
4311 */
4312 if (!duration || !msecs_to_jiffies(duration) || duration > 5000)
4313 return -EINVAL;
4314
4315 rtnl_lock();
4316
4317 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4318 if (err)
4319 goto unlock_rtnl;
4320
4321 if (!rdev->ops->remain_on_channel) {
4322 err = -EOPNOTSUPP;
4323 goto out;
4324 }
4325
4326 if (!netif_running(dev)) {
4327 err = -ENETDOWN;
4328 goto out;
4329 }
4330
4331 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
4332 channel_type = nla_get_u32(
4333 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
4334 if (channel_type != NL80211_CHAN_NO_HT &&
4335 channel_type != NL80211_CHAN_HT20 &&
4336 channel_type != NL80211_CHAN_HT40PLUS &&
4337 channel_type != NL80211_CHAN_HT40MINUS)
4338 err = -EINVAL;
4339 goto out;
4340 }
4341
4342 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
4343 chan = rdev_freq_to_chan(rdev, freq, channel_type);
4344 if (chan == NULL) {
4345 err = -EINVAL;
4346 goto out;
4347 }
4348
4349 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4350 if (!msg) {
4351 err = -ENOMEM;
4352 goto out;
4353 }
4354
4355 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
4356 NL80211_CMD_REMAIN_ON_CHANNEL);
4357
4358 if (IS_ERR(hdr)) {
4359 err = PTR_ERR(hdr);
4360 goto free_msg;
4361 }
4362
4363 err = rdev->ops->remain_on_channel(&rdev->wiphy, dev, chan,
4364 channel_type, duration, &cookie);
4365
4366 if (err)
4367 goto free_msg;
4368
4369 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
4370
4371 genlmsg_end(msg, hdr);
4372 err = genlmsg_reply(msg, info);
4373 goto out;
4374
4375 nla_put_failure:
4376 err = -ENOBUFS;
4377 free_msg:
4378 nlmsg_free(msg);
4379 out:
4380 cfg80211_unlock_rdev(rdev);
4381 dev_put(dev);
4382 unlock_rtnl:
4383 rtnl_unlock();
4384 return err;
4385}
4386
4387static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
4388 struct genl_info *info)
4389{
4390 struct cfg80211_registered_device *rdev;
4391 struct net_device *dev;
4392 u64 cookie;
4393 int err;
4394
4395 if (!info->attrs[NL80211_ATTR_COOKIE])
4396 return -EINVAL;
4397
4398 rtnl_lock();
4399
4400 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4401 if (err)
4402 goto unlock_rtnl;
4403
4404 if (!rdev->ops->cancel_remain_on_channel) {
4405 err = -EOPNOTSUPP;
4406 goto out;
4407 }
4408
4409 if (!netif_running(dev)) {
4410 err = -ENETDOWN;
4411 goto out;
4412 }
4413
4414 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
4415
4416 err = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie);
4417
4418 out:
4419 cfg80211_unlock_rdev(rdev);
4420 dev_put(dev);
4421 unlock_rtnl:
4422 rtnl_unlock();
4423 return err;
4424}
4425
4292static struct genl_ops nl80211_ops[] = { 4426static struct genl_ops nl80211_ops[] = {
4293 { 4427 {
4294 .cmd = NL80211_CMD_GET_WIPHY, 4428 .cmd = NL80211_CMD_GET_WIPHY,
@@ -4551,8 +4685,20 @@ static struct genl_ops nl80211_ops[] = {
4551 .policy = nl80211_policy, 4685 .policy = nl80211_policy,
4552 .flags = GENL_ADMIN_PERM, 4686 .flags = GENL_ADMIN_PERM,
4553 }, 4687 },
4554 4688 {
4689 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
4690 .doit = nl80211_remain_on_channel,
4691 .policy = nl80211_policy,
4692 .flags = GENL_ADMIN_PERM,
4693 },
4694 {
4695 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
4696 .doit = nl80211_cancel_remain_on_channel,
4697 .policy = nl80211_policy,
4698 .flags = GENL_ADMIN_PERM,
4699 },
4555}; 4700};
4701
4556static struct genl_multicast_group nl80211_mlme_mcgrp = { 4702static struct genl_multicast_group nl80211_mlme_mcgrp = {
4557 .name = "mlme", 4703 .name = "mlme",
4558}; 4704};
@@ -5140,6 +5286,89 @@ nla_put_failure:
5140 nlmsg_free(msg); 5286 nlmsg_free(msg);
5141} 5287}
5142 5288
5289static void nl80211_send_remain_on_chan_event(
5290 int cmd, struct cfg80211_registered_device *rdev,
5291 struct net_device *netdev, u64 cookie,
5292 struct ieee80211_channel *chan,
5293 enum nl80211_channel_type channel_type,
5294 unsigned int duration, gfp_t gfp)
5295{
5296 struct sk_buff *msg;
5297 void *hdr;
5298
5299 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5300 if (!msg)
5301 return;
5302
5303 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
5304 if (!hdr) {
5305 nlmsg_free(msg);
5306 return;
5307 }
5308
5309 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5310 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5311 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq);
5312 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type);
5313 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
5314
5315 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL)
5316 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
5317
5318 if (genlmsg_end(msg, hdr) < 0) {
5319 nlmsg_free(msg);
5320 return;
5321 }
5322
5323 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5324 nl80211_mlme_mcgrp.id, gfp);
5325 return;
5326
5327 nla_put_failure:
5328 genlmsg_cancel(msg, hdr);
5329 nlmsg_free(msg);
5330}
5331
5332void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
5333 struct net_device *netdev, u64 cookie,
5334 struct ieee80211_channel *chan,
5335 enum nl80211_channel_type channel_type,
5336 unsigned int duration, gfp_t gfp)
5337{
5338 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
5339 rdev, netdev, cookie, chan,
5340 channel_type, duration, gfp);
5341}
5342
5343void nl80211_send_remain_on_channel_cancel(
5344 struct cfg80211_registered_device *rdev, struct net_device *netdev,
5345 u64 cookie, struct ieee80211_channel *chan,
5346 enum nl80211_channel_type channel_type, gfp_t gfp)
5347{
5348 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
5349 rdev, netdev, cookie, chan,
5350 channel_type, 0, gfp);
5351}
5352
5353void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
5354 struct net_device *dev, const u8 *mac_addr,
5355 struct station_info *sinfo, gfp_t gfp)
5356{
5357 struct sk_buff *msg;
5358
5359 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
5360 if (!msg)
5361 return;
5362
5363 if (nl80211_send_station(msg, 0, 0, 0, dev, mac_addr, sinfo) < 0) {
5364 nlmsg_free(msg);
5365 return;
5366 }
5367
5368 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5369 nl80211_mlme_mcgrp.id, gfp);
5370}
5371
5143/* initialisation/exit functions */ 5372/* initialisation/exit functions */
5144 5373
5145int nl80211_init(void) 5374int nl80211_init(void)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 44cc2a76a1b0..14855b8fb430 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -59,4 +59,19 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
59 struct net_device *netdev, const u8 *bssid, 59 struct net_device *netdev, const u8 *bssid,
60 gfp_t gfp); 60 gfp_t gfp);
61 61
62void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
63 struct net_device *netdev,
64 u64 cookie,
65 struct ieee80211_channel *chan,
66 enum nl80211_channel_type channel_type,
67 unsigned int duration, gfp_t gfp);
68void nl80211_send_remain_on_channel_cancel(
69 struct cfg80211_registered_device *rdev, struct net_device *netdev,
70 u64 cookie, struct ieee80211_channel *chan,
71 enum nl80211_channel_type channel_type, gfp_t gfp);
72
73void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
74 struct net_device *dev, const u8 *mac_addr,
75 struct station_info *sinfo, gfp_t gfp);
76
62#endif /* __NET_WIRELESS_NL80211_H */ 77#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index dc13c3ffeca6..87ea60d84c3c 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -129,78 +129,6 @@ static char *ieee80211_regdom = "00";
129module_param(ieee80211_regdom, charp, 0444); 129module_param(ieee80211_regdom, charp, 0444);
130MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 130MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
131 131
132#ifdef CONFIG_WIRELESS_OLD_REGULATORY
133/*
134 * We assume 40 MHz bandwidth for the old regulatory work.
135 * We make emphasis we are using the exact same frequencies
136 * as before
137 */
138
139static const struct ieee80211_regdomain us_regdom = {
140 .n_reg_rules = 6,
141 .alpha2 = "US",
142 .reg_rules = {
143 /* IEEE 802.11b/g, channels 1..11 */
144 REG_RULE(2412-10, 2462+10, 40, 6, 27, 0),
145 /* IEEE 802.11a, channel 36..48 */
146 REG_RULE(5180-10, 5240+10, 40, 6, 17, 0),
147 /* IEEE 802.11a, channels 48..64 */
148 REG_RULE(5260-10, 5320+10, 40, 6, 20, NL80211_RRF_DFS),
149 /* IEEE 802.11a, channels 100..124 */
150 REG_RULE(5500-10, 5590+10, 40, 6, 20, NL80211_RRF_DFS),
151 /* IEEE 802.11a, channels 132..144 */
152 REG_RULE(5660-10, 5700+10, 40, 6, 20, NL80211_RRF_DFS),
153 /* IEEE 802.11a, channels 149..165, outdoor */
154 REG_RULE(5745-10, 5825+10, 40, 6, 30, 0),
155 }
156};
157
158static const struct ieee80211_regdomain jp_regdom = {
159 .n_reg_rules = 6,
160 .alpha2 = "JP",
161 .reg_rules = {
162 /* IEEE 802.11b/g, channels 1..11 */
163 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
164 /* IEEE 802.11b/g, channels 12..13 */
165 REG_RULE(2467-10, 2472+10, 20, 6, 20, 0),
166 /* IEEE 802.11b/g, channel 14 */
167 REG_RULE(2484-10, 2484+10, 20, 6, 20, NL80211_RRF_NO_OFDM),
168 /* IEEE 802.11a, channels 36..48 */
169 REG_RULE(5180-10, 5240+10, 40, 6, 20, 0),
170 /* IEEE 802.11a, channels 52..64 */
171 REG_RULE(5260-10, 5320+10, 40, 6, 20, NL80211_RRF_DFS),
172 /* IEEE 802.11a, channels 100..144 */
173 REG_RULE(5500-10, 5700+10, 40, 6, 23, NL80211_RRF_DFS),
174 }
175};
176
177static const struct ieee80211_regdomain *static_regdom(char *alpha2)
178{
179 if (alpha2[0] == 'U' && alpha2[1] == 'S')
180 return &us_regdom;
181 if (alpha2[0] == 'J' && alpha2[1] == 'P')
182 return &jp_regdom;
183 /* Use world roaming rules for "EU", since it was a pseudo
184 domain anyway... */
185 if (alpha2[0] == 'E' && alpha2[1] == 'U')
186 return &world_regdom;
187 /* Default, world roaming rules */
188 return &world_regdom;
189}
190
191static bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
192{
193 if (rd == &us_regdom || rd == &jp_regdom || rd == &world_regdom)
194 return true;
195 return false;
196}
197#else
198static inline bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
199{
200 return false;
201}
202#endif
203
204static void reset_regdomains(void) 132static void reset_regdomains(void)
205{ 133{
206 /* avoid freeing static information or freeing something twice */ 134 /* avoid freeing static information or freeing something twice */
@@ -210,8 +138,6 @@ static void reset_regdomains(void)
210 cfg80211_world_regdom = NULL; 138 cfg80211_world_regdom = NULL;
211 if (cfg80211_regdomain == &world_regdom) 139 if (cfg80211_regdomain == &world_regdom)
212 cfg80211_regdomain = NULL; 140 cfg80211_regdomain = NULL;
213 if (is_old_static_regdom(cfg80211_regdomain))
214 cfg80211_regdomain = NULL;
215 141
216 kfree(cfg80211_regdomain); 142 kfree(cfg80211_regdomain);
217 kfree(cfg80211_world_regdom); 143 kfree(cfg80211_world_regdom);
@@ -1490,8 +1416,6 @@ static int ignore_request(struct wiphy *wiphy,
1490 return REG_INTERSECT; 1416 return REG_INTERSECT;
1491 case NL80211_REGDOM_SET_BY_DRIVER: 1417 case NL80211_REGDOM_SET_BY_DRIVER:
1492 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) { 1418 if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) {
1493 if (is_old_static_regdom(cfg80211_regdomain))
1494 return 0;
1495 if (regdom_changes(pending_request->alpha2)) 1419 if (regdom_changes(pending_request->alpha2))
1496 return 0; 1420 return 0;
1497 return -EALREADY; 1421 return -EALREADY;
@@ -1528,8 +1452,7 @@ static int ignore_request(struct wiphy *wiphy,
1528 return -EAGAIN; 1452 return -EAGAIN;
1529 } 1453 }
1530 1454
1531 if (!is_old_static_regdom(cfg80211_regdomain) && 1455 if (!regdom_changes(pending_request->alpha2))
1532 !regdom_changes(pending_request->alpha2))
1533 return -EALREADY; 1456 return -EALREADY;
1534 1457
1535 return 0; 1458 return 0;
@@ -2111,8 +2034,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2111 * If someone else asked us to change the rd lets only bother 2034 * If someone else asked us to change the rd lets only bother
2112 * checking if the alpha2 changes if CRDA was already called 2035 * checking if the alpha2 changes if CRDA was already called
2113 */ 2036 */
2114 if (!is_old_static_regdom(cfg80211_regdomain) && 2037 if (!regdom_changes(rd->alpha2))
2115 !regdom_changes(rd->alpha2))
2116 return -EINVAL; 2038 return -EINVAL;
2117 } 2039 }
2118 2040
@@ -2311,15 +2233,8 @@ int regulatory_init(void)
2311 spin_lock_init(&reg_requests_lock); 2233 spin_lock_init(&reg_requests_lock);
2312 spin_lock_init(&reg_pending_beacons_lock); 2234 spin_lock_init(&reg_pending_beacons_lock);
2313 2235
2314#ifdef CONFIG_WIRELESS_OLD_REGULATORY
2315 cfg80211_regdomain = static_regdom(ieee80211_regdom);
2316
2317 printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
2318 print_regdomain_info(cfg80211_regdomain);
2319#else
2320 cfg80211_regdomain = cfg80211_world_regdom; 2236 cfg80211_regdomain = cfg80211_world_regdom;
2321 2237
2322#endif
2323 /* We always try to get an update for the static regdomain */ 2238 /* We always try to get an update for the static regdomain */
2324 err = regulatory_hint_core(cfg80211_regdomain->alpha2); 2239 err = regulatory_hint_core(cfg80211_regdomain->alpha2);
2325 if (err) { 2240 if (err) {
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 12dfa62aad18..0c2cbbebca95 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -601,7 +601,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
601 struct cfg80211_registered_device *rdev; 601 struct cfg80211_registered_device *rdev;
602 struct wiphy *wiphy; 602 struct wiphy *wiphy;
603 struct iw_scan_req *wreq = NULL; 603 struct iw_scan_req *wreq = NULL;
604 struct cfg80211_scan_request *creq; 604 struct cfg80211_scan_request *creq = NULL;
605 int i, err, n_channels = 0; 605 int i, err, n_channels = 0;
606 enum ieee80211_band band; 606 enum ieee80211_band band;
607 607
@@ -694,8 +694,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
694 /* translate "Scan for SSID" request */ 694 /* translate "Scan for SSID" request */
695 if (wreq) { 695 if (wreq) {
696 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 696 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
697 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) 697 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
698 return -EINVAL; 698 err = -EINVAL;
699 goto out;
700 }
699 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len); 701 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
700 creq->ssids[0].ssid_len = wreq->essid_len; 702 creq->ssids[0].ssid_len = wreq->essid_len;
701 } 703 }
@@ -707,12 +709,15 @@ int cfg80211_wext_siwscan(struct net_device *dev,
707 err = rdev->ops->scan(wiphy, dev, creq); 709 err = rdev->ops->scan(wiphy, dev, creq);
708 if (err) { 710 if (err) {
709 rdev->scan_req = NULL; 711 rdev->scan_req = NULL;
710 kfree(creq); 712 /* creq will be freed below */
711 } else { 713 } else {
712 nl80211_send_scan_start(rdev, dev); 714 nl80211_send_scan_start(rdev, dev);
715 /* creq now owned by driver */
716 creq = NULL;
713 dev_hold(dev); 717 dev_hold(dev);
714 } 718 }
715 out: 719 out:
720 kfree(creq);
716 cfg80211_unlock_rdev(rdev); 721 cfg80211_unlock_rdev(rdev);
717 return err; 722 return err;
718} 723}