aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-02-08 16:52:31 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-08 16:52:31 -0500
commitc0c84ef5c130f8871adbdaac2ba824b9195cb6d9 (patch)
treed7221b5323d5a4d3d84676d32bdca21d21d85a18 /net/mac80211
parent2360d2e8f01043632d6b651672bec66c49892f94 (diff)
parent3ad97fbcc233a295f2ccc2c6bdeb32323e360a5e (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c26
-rw-r--r--net/mac80211/debugfs_netdev.c108
-rw-r--r--net/mac80211/ieee80211_i.h14
-rw-r--r--net/mac80211/iface.c9
-rw-r--r--net/mac80211/main.c53
-rw-r--r--net/mac80211/mlme.c60
-rw-r--r--net/mac80211/offchannel.c68
-rw-r--r--net/mac80211/rx.c59
-rw-r--r--net/mac80211/scan.c88
-rw-r--r--net/mac80211/sta_info.c3
-rw-r--r--net/mac80211/status.c4
-rw-r--r--net/mac80211/tx.c12
-rw-r--r--net/mac80211/work.c66
-rw-r--r--net/mac80211/wpa.c39
14 files changed, 458 insertions, 151 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 4bc8a9250cf..845c76d58d2 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1215,6 +1215,9 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1215{ 1215{
1216 struct ieee80211_local *local = wiphy_priv(wiphy); 1216 struct ieee80211_local *local = wiphy_priv(wiphy);
1217 struct ieee80211_sub_if_data *sdata = NULL; 1217 struct ieee80211_sub_if_data *sdata = NULL;
1218 struct ieee80211_channel *old_oper;
1219 enum nl80211_channel_type old_oper_type;
1220 enum nl80211_channel_type old_vif_oper_type= NL80211_CHAN_NO_HT;
1218 1221
1219 if (netdev) 1222 if (netdev)
1220 sdata = IEEE80211_DEV_TO_SUB_IF(netdev); 1223 sdata = IEEE80211_DEV_TO_SUB_IF(netdev);
@@ -1232,13 +1235,23 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1232 break; 1235 break;
1233 } 1236 }
1234 1237
1235 local->oper_channel = chan; 1238 if (sdata)
1239 old_vif_oper_type = sdata->vif.bss_conf.channel_type;
1240 old_oper_type = local->_oper_channel_type;
1236 1241
1237 if (!ieee80211_set_channel_type(local, sdata, channel_type)) 1242 if (!ieee80211_set_channel_type(local, sdata, channel_type))
1238 return -EBUSY; 1243 return -EBUSY;
1239 1244
1240 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1245 old_oper = local->oper_channel;
1241 if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR) 1246 local->oper_channel = chan;
1247
1248 /* Update driver if changes were actually made. */
1249 if ((old_oper != local->oper_channel) ||
1250 (old_oper_type != local->_oper_channel_type))
1251 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1252
1253 if ((sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR) &&
1254 old_vif_oper_type != sdata->vif.bss_conf.channel_type)
1242 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); 1255 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
1243 1256
1244 return 0; 1257 return 0;
@@ -1274,8 +1287,11 @@ static int ieee80211_scan(struct wiphy *wiphy,
1274 case NL80211_IFTYPE_P2P_GO: 1287 case NL80211_IFTYPE_P2P_GO:
1275 if (sdata->local->ops->hw_scan) 1288 if (sdata->local->ops->hw_scan)
1276 break; 1289 break;
1277 /* FIXME: implement NoA while scanning in software */ 1290 /*
1278 return -EOPNOTSUPP; 1291 * FIXME: implement NoA while scanning in software,
1292 * for now fall through to allow scanning only when
1293 * beaconing hasn't been configured yet
1294 */
1279 case NL80211_IFTYPE_AP: 1295 case NL80211_IFTYPE_AP:
1280 if (sdata->u.ap.beacon) 1296 if (sdata->u.ap.beacon)
1281 return -EOPNOTSUPP; 1297 return -EOPNOTSUPP;
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 872adb86200..dacace6b139 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -36,7 +36,7 @@ static ssize_t ieee80211_if_read(
36 ret = (*format)(sdata, buf, sizeof(buf)); 36 ret = (*format)(sdata, buf, sizeof(buf));
37 read_unlock(&dev_base_lock); 37 read_unlock(&dev_base_lock);
38 38
39 if (ret != -EINVAL) 39 if (ret >= 0)
40 ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret); 40 ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
41 41
42 return ret; 42 return ret;
@@ -149,6 +149,7 @@ IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
149 HEX); 149 HEX);
150IEEE80211_IF_FILE(flags, flags, HEX); 150IEEE80211_IF_FILE(flags, flags, HEX);
151IEEE80211_IF_FILE(state, state, LHEX); 151IEEE80211_IF_FILE(state, state, LHEX);
152IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC);
152 153
153/* STA attributes */ 154/* STA attributes */
154IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 155IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
@@ -220,6 +221,104 @@ static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata,
220 221
221__IEEE80211_IF_FILE_W(smps); 222__IEEE80211_IF_FILE_W(smps);
222 223
224static ssize_t ieee80211_if_fmt_tkip_mic_test(
225 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
226{
227 return -EOPNOTSUPP;
228}
229
230static int hwaddr_aton(const char *txt, u8 *addr)
231{
232 int i;
233
234 for (i = 0; i < ETH_ALEN; i++) {
235 int a, b;
236
237 a = hex_to_bin(*txt++);
238 if (a < 0)
239 return -1;
240 b = hex_to_bin(*txt++);
241 if (b < 0)
242 return -1;
243 *addr++ = (a << 4) | b;
244 if (i < 5 && *txt++ != ':')
245 return -1;
246 }
247
248 return 0;
249}
250
251static ssize_t ieee80211_if_parse_tkip_mic_test(
252 struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
253{
254 struct ieee80211_local *local = sdata->local;
255 u8 addr[ETH_ALEN];
256 struct sk_buff *skb;
257 struct ieee80211_hdr *hdr;
258 __le16 fc;
259
260 /*
261 * Assume colon-delimited MAC address with possible white space
262 * following.
263 */
264 if (buflen < 3 * ETH_ALEN - 1)
265 return -EINVAL;
266 if (hwaddr_aton(buf, addr) < 0)
267 return -EINVAL;
268
269 if (!ieee80211_sdata_running(sdata))
270 return -ENOTCONN;
271
272 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 100);
273 if (!skb)
274 return -ENOMEM;
275 skb_reserve(skb, local->hw.extra_tx_headroom);
276
277 hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
278 memset(hdr, 0, 24);
279 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
280
281 switch (sdata->vif.type) {
282 case NL80211_IFTYPE_AP:
283 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
284 /* DA BSSID SA */
285 memcpy(hdr->addr1, addr, ETH_ALEN);
286 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
287 memcpy(hdr->addr3, sdata->vif.addr, ETH_ALEN);
288 break;
289 case NL80211_IFTYPE_STATION:
290 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
291 /* BSSID SA DA */
292 if (sdata->vif.bss_conf.bssid == NULL) {
293 dev_kfree_skb(skb);
294 return -ENOTCONN;
295 }
296 memcpy(hdr->addr1, sdata->vif.bss_conf.bssid, ETH_ALEN);
297 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
298 memcpy(hdr->addr3, addr, ETH_ALEN);
299 break;
300 default:
301 dev_kfree_skb(skb);
302 return -EOPNOTSUPP;
303 }
304 hdr->frame_control = fc;
305
306 /*
307 * Add some length to the test frame to make it look bit more valid.
308 * The exact contents does not matter since the recipient is required
309 * to drop this because of the Michael MIC failure.
310 */
311 memset(skb_put(skb, 50), 0, 50);
312
313 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_TKIP_MIC_FAILURE;
314
315 ieee80211_tx_skb(sdata, skb);
316
317 return buflen;
318}
319
320__IEEE80211_IF_FILE_W(tkip_mic_test);
321
223/* AP attributes */ 322/* AP attributes */
224IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); 323IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
225IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); 324IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC);
@@ -289,6 +388,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
289 DEBUGFS_ADD(drop_unencrypted); 388 DEBUGFS_ADD(drop_unencrypted);
290 DEBUGFS_ADD(flags); 389 DEBUGFS_ADD(flags);
291 DEBUGFS_ADD(state); 390 DEBUGFS_ADD(state);
391 DEBUGFS_ADD(channel_type);
292 DEBUGFS_ADD(rc_rateidx_mask_2ghz); 392 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
293 DEBUGFS_ADD(rc_rateidx_mask_5ghz); 393 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
294 394
@@ -297,6 +397,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
297 DEBUGFS_ADD(last_beacon); 397 DEBUGFS_ADD(last_beacon);
298 DEBUGFS_ADD(ave_beacon); 398 DEBUGFS_ADD(ave_beacon);
299 DEBUGFS_ADD_MODE(smps, 0600); 399 DEBUGFS_ADD_MODE(smps, 0600);
400 DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
300} 401}
301 402
302static void add_ap_files(struct ieee80211_sub_if_data *sdata) 403static void add_ap_files(struct ieee80211_sub_if_data *sdata)
@@ -304,12 +405,14 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
304 DEBUGFS_ADD(drop_unencrypted); 405 DEBUGFS_ADD(drop_unencrypted);
305 DEBUGFS_ADD(flags); 406 DEBUGFS_ADD(flags);
306 DEBUGFS_ADD(state); 407 DEBUGFS_ADD(state);
408 DEBUGFS_ADD(channel_type);
307 DEBUGFS_ADD(rc_rateidx_mask_2ghz); 409 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
308 DEBUGFS_ADD(rc_rateidx_mask_5ghz); 410 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
309 411
310 DEBUGFS_ADD(num_sta_ps); 412 DEBUGFS_ADD(num_sta_ps);
311 DEBUGFS_ADD(dtim_count); 413 DEBUGFS_ADD(dtim_count);
312 DEBUGFS_ADD(num_buffered_multicast); 414 DEBUGFS_ADD(num_buffered_multicast);
415 DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
313} 416}
314 417
315static void add_wds_files(struct ieee80211_sub_if_data *sdata) 418static void add_wds_files(struct ieee80211_sub_if_data *sdata)
@@ -317,6 +420,7 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
317 DEBUGFS_ADD(drop_unencrypted); 420 DEBUGFS_ADD(drop_unencrypted);
318 DEBUGFS_ADD(flags); 421 DEBUGFS_ADD(flags);
319 DEBUGFS_ADD(state); 422 DEBUGFS_ADD(state);
423 DEBUGFS_ADD(channel_type);
320 DEBUGFS_ADD(rc_rateidx_mask_2ghz); 424 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
321 DEBUGFS_ADD(rc_rateidx_mask_5ghz); 425 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
322 426
@@ -328,6 +432,7 @@ static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
328 DEBUGFS_ADD(drop_unencrypted); 432 DEBUGFS_ADD(drop_unencrypted);
329 DEBUGFS_ADD(flags); 433 DEBUGFS_ADD(flags);
330 DEBUGFS_ADD(state); 434 DEBUGFS_ADD(state);
435 DEBUGFS_ADD(channel_type);
331 DEBUGFS_ADD(rc_rateidx_mask_2ghz); 436 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
332 DEBUGFS_ADD(rc_rateidx_mask_5ghz); 437 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
333} 438}
@@ -336,6 +441,7 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
336{ 441{
337 DEBUGFS_ADD(flags); 442 DEBUGFS_ADD(flags);
338 DEBUGFS_ADD(state); 443 DEBUGFS_ADD(state);
444 DEBUGFS_ADD(channel_type);
339} 445}
340 446
341#ifdef CONFIG_MAC80211_MESH 447#ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c47d7c0e48a..44eea1af155 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -225,6 +225,7 @@ struct ieee80211_if_ap {
225 struct sk_buff_head ps_bc_buf; 225 struct sk_buff_head ps_bc_buf;
226 atomic_t num_sta_ps; /* number of stations in PS mode */ 226 atomic_t num_sta_ps; /* number of stations in PS mode */
227 int dtim_count; 227 int dtim_count;
228 bool dtim_bc_mc;
228}; 229};
229 230
230struct ieee80211_if_wds { 231struct ieee80211_if_wds {
@@ -654,8 +655,6 @@ struct tpt_led_trigger {
654 * well be on the operating channel 655 * well be on the operating channel
655 * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to 656 * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to
656 * determine if we are on the operating channel or not 657 * determine if we are on the operating channel or not
657 * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning,
658 * gets only set in conjunction with SCAN_SW_SCANNING
659 * @SCAN_COMPLETED: Set for our scan work function when the driver reported 658 * @SCAN_COMPLETED: Set for our scan work function when the driver reported
660 * that the scan completed. 659 * that the scan completed.
661 * @SCAN_ABORTED: Set for our scan work function when the driver reported 660 * @SCAN_ABORTED: Set for our scan work function when the driver reported
@@ -664,7 +663,6 @@ struct tpt_led_trigger {
664enum { 663enum {
665 SCAN_SW_SCANNING, 664 SCAN_SW_SCANNING,
666 SCAN_HW_SCANNING, 665 SCAN_HW_SCANNING,
667 SCAN_OFF_CHANNEL,
668 SCAN_COMPLETED, 666 SCAN_COMPLETED,
669 SCAN_ABORTED, 667 SCAN_ABORTED,
670}; 668};
@@ -1147,10 +1145,14 @@ void ieee80211_rx_bss_put(struct ieee80211_local *local,
1147 struct ieee80211_bss *bss); 1145 struct ieee80211_bss *bss);
1148 1146
1149/* off-channel helpers */ 1147/* off-channel helpers */
1150void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local); 1148bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local);
1151void ieee80211_offchannel_stop_station(struct ieee80211_local *local); 1149void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,
1150 bool tell_ap);
1151void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
1152 bool offchannel_ps_enable);
1152void ieee80211_offchannel_return(struct ieee80211_local *local, 1153void ieee80211_offchannel_return(struct ieee80211_local *local,
1153 bool enable_beaconing); 1154 bool enable_beaconing,
1155 bool offchannel_ps_disable);
1154void ieee80211_hw_roc_setup(struct ieee80211_local *local); 1156void ieee80211_hw_roc_setup(struct ieee80211_local *local);
1155 1157
1156/* interface handling */ 1158/* interface handling */
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8acba456744..5a4e19b8803 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -382,6 +382,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
382 struct sk_buff *skb, *tmp; 382 struct sk_buff *skb, *tmp;
383 u32 hw_reconf_flags = 0; 383 u32 hw_reconf_flags = 0;
384 int i; 384 int i;
385 enum nl80211_channel_type orig_ct;
385 386
386 if (local->scan_sdata == sdata) 387 if (local->scan_sdata == sdata)
387 ieee80211_scan_cancel(local); 388 ieee80211_scan_cancel(local);
@@ -542,8 +543,14 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
542 hw_reconf_flags = 0; 543 hw_reconf_flags = 0;
543 } 544 }
544 545
546 /* Re-calculate channel-type, in case there are multiple vifs
547 * on different channel types.
548 */
549 orig_ct = local->_oper_channel_type;
550 ieee80211_set_channel_type(local, NULL, NL80211_CHAN_NO_HT);
551
545 /* do after stop to avoid reconfiguring when we stop anyway */ 552 /* do after stop to avoid reconfiguring when we stop anyway */
546 if (hw_reconf_flags) 553 if (hw_reconf_flags || (orig_ct != local->_oper_channel_type))
547 ieee80211_hw_config(local, hw_reconf_flags); 554 ieee80211_hw_config(local, hw_reconf_flags);
548 555
549 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 556 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 09a27449f3f..c155c0b6942 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -98,6 +98,41 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
98 ieee80211_configure_filter(local); 98 ieee80211_configure_filter(local);
99} 99}
100 100
101/*
102 * Returns true if we are logically configured to be on
103 * the operating channel AND the hardware-conf is currently
104 * configured on the operating channel. Compares channel-type
105 * as well.
106 */
107bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local)
108{
109 struct ieee80211_channel *chan, *scan_chan;
110 enum nl80211_channel_type channel_type;
111
112 /* This logic needs to match logic in ieee80211_hw_config */
113 if (local->scan_channel) {
114 chan = local->scan_channel;
115 channel_type = NL80211_CHAN_NO_HT;
116 } else if (local->tmp_channel) {
117 chan = scan_chan = local->tmp_channel;
118 channel_type = local->tmp_channel_type;
119 } else {
120 chan = local->oper_channel;
121 channel_type = local->_oper_channel_type;
122 }
123
124 if (chan != local->oper_channel ||
125 channel_type != local->_oper_channel_type)
126 return false;
127
128 /* Check current hardware-config against oper_channel. */
129 if ((local->oper_channel != local->hw.conf.channel) ||
130 (local->_oper_channel_type != local->hw.conf.channel_type))
131 return false;
132
133 return true;
134}
135
101int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 136int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
102{ 137{
103 struct ieee80211_channel *chan, *scan_chan; 138 struct ieee80211_channel *chan, *scan_chan;
@@ -110,21 +145,27 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
110 145
111 scan_chan = local->scan_channel; 146 scan_chan = local->scan_channel;
112 147
148 /* If this off-channel logic ever changes, ieee80211_on_oper_channel
149 * may need to change as well.
150 */
113 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 151 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
114 if (scan_chan) { 152 if (scan_chan) {
115 chan = scan_chan; 153 chan = scan_chan;
116 channel_type = NL80211_CHAN_NO_HT; 154 channel_type = NL80211_CHAN_NO_HT;
117 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; 155 } else if (local->tmp_channel) {
118 } else if (local->tmp_channel &&
119 local->oper_channel != local->tmp_channel) {
120 chan = scan_chan = local->tmp_channel; 156 chan = scan_chan = local->tmp_channel;
121 channel_type = local->tmp_channel_type; 157 channel_type = local->tmp_channel_type;
122 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
123 } else { 158 } else {
124 chan = local->oper_channel; 159 chan = local->oper_channel;
125 channel_type = local->_oper_channel_type; 160 channel_type = local->_oper_channel_type;
126 local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
127 } 161 }
162
163 if (chan != local->oper_channel ||
164 channel_type != local->_oper_channel_type)
165 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
166 else
167 local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
168
128 offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 169 offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
129 170
130 if (offchannel_flag || chan != local->hw.conf.channel || 171 if (offchannel_flag || chan != local->hw.conf.channel ||
@@ -231,7 +272,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
231 272
232 if (changed & BSS_CHANGED_BEACON_ENABLED) { 273 if (changed & BSS_CHANGED_BEACON_ENABLED) {
233 if (local->quiescing || !ieee80211_sdata_running(sdata) || 274 if (local->quiescing || !ieee80211_sdata_running(sdata) ||
234 test_bit(SCAN_SW_SCANNING, &local->scanning)) { 275 test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) {
235 sdata->vif.bss_conf.enable_beacon = false; 276 sdata->vif.bss_conf.enable_beacon = false;
236 } else { 277 } else {
237 /* 278 /*
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index dfa752e5520..f77adf1a520 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -28,8 +28,15 @@
28#include "rate.h" 28#include "rate.h"
29#include "led.h" 29#include "led.h"
30 30
31#define IEEE80211_MAX_NULLFUNC_TRIES 2 31static int max_nullfunc_tries = 2;
32#define IEEE80211_MAX_PROBE_TRIES 5 32module_param(max_nullfunc_tries, int, 0644);
33MODULE_PARM_DESC(max_nullfunc_tries,
34 "Maximum nullfunc tx tries before disconnecting (reason 4).");
35
36static int max_probe_tries = 5;
37module_param(max_probe_tries, int, 0644);
38MODULE_PARM_DESC(max_probe_tries,
39 "Maximum probe tries before disconnecting (reason 4).");
33 40
34/* 41/*
35 * Beacon loss timeout is calculated as N frames times the 42 * Beacon loss timeout is calculated as N frames times the
@@ -51,7 +58,11 @@
51 * a probe request because of beacon loss or for 58 * a probe request because of beacon loss or for
52 * checking the connection still works. 59 * checking the connection still works.
53 */ 60 */
54#define IEEE80211_PROBE_WAIT (HZ / 2) 61static int probe_wait_ms = 500;
62module_param(probe_wait_ms, int, 0644);
63MODULE_PARM_DESC(probe_wait_ms,
64 "Maximum time(ms) to wait for probe response"
65 " before disconnecting (reason 4).");
55 66
56/* 67/*
57 * Weight given to the latest Beacon frame when calculating average signal 68 * Weight given to the latest Beacon frame when calculating average signal
@@ -161,6 +172,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
161 struct ieee80211_supported_band *sband; 172 struct ieee80211_supported_band *sband;
162 struct sta_info *sta; 173 struct sta_info *sta;
163 u32 changed = 0; 174 u32 changed = 0;
175 int hti_cfreq;
164 u16 ht_opmode; 176 u16 ht_opmode;
165 bool enable_ht = true; 177 bool enable_ht = true;
166 enum nl80211_channel_type prev_chantype; 178 enum nl80211_channel_type prev_chantype;
@@ -174,10 +186,27 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
174 if (!sband->ht_cap.ht_supported) 186 if (!sband->ht_cap.ht_supported)
175 enable_ht = false; 187 enable_ht = false;
176 188
177 /* check that channel matches the right operating channel */ 189 if (enable_ht) {
178 if (local->hw.conf.channel->center_freq != 190 hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan,
179 ieee80211_channel_to_frequency(hti->control_chan, sband->band)) 191 sband->band);
180 enable_ht = false; 192 /* check that channel matches the right operating channel */
193 if (local->hw.conf.channel->center_freq != hti_cfreq) {
194 /* Some APs mess this up, evidently.
195 * Netgear WNDR3700 sometimes reports 4 higher than
196 * the actual channel, for instance.
197 */
198 printk(KERN_DEBUG
199 "%s: Wrong control channel in association"
200 " response: configured center-freq: %d"
201 " hti-cfreq: %d hti->control_chan: %d"
202 " band: %d. Disabling HT.\n",
203 sdata->name,
204 local->hw.conf.channel->center_freq,
205 hti_cfreq, hti->control_chan,
206 sband->band);
207 enable_ht = false;
208 }
209 }
181 210
182 if (enable_ht) { 211 if (enable_ht) {
183 channel_type = NL80211_CHAN_HT20; 212 channel_type = NL80211_CHAN_HT20;
@@ -1098,7 +1127,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1098 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1127 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1099 const u8 *ssid; 1128 const u8 *ssid;
1100 u8 *dst = ifmgd->associated->bssid; 1129 u8 *dst = ifmgd->associated->bssid;
1101 u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3); 1130 u8 unicast_limit = max(1, max_probe_tries - 3);
1102 1131
1103 /* 1132 /*
1104 * Try sending broadcast probe requests for the last three 1133 * Try sending broadcast probe requests for the last three
@@ -1124,7 +1153,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1124 } 1153 }
1125 1154
1126 ifmgd->probe_send_count++; 1155 ifmgd->probe_send_count++;
1127 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; 1156 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
1128 run_again(ifmgd, ifmgd->probe_timeout); 1157 run_again(ifmgd, ifmgd->probe_timeout);
1129} 1158}
1130 1159
@@ -1225,7 +1254,8 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
1225 1254
1226 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); 1255 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1227 1256
1228 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); 1257 printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n",
1258 sdata->name, bssid);
1229 1259
1230 ieee80211_set_disassoc(sdata, true, true); 1260 ieee80211_set_disassoc(sdata, true, true);
1231 mutex_unlock(&ifmgd->mtx); 1261 mutex_unlock(&ifmgd->mtx);
@@ -1970,9 +2000,9 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1970 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); 2000 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1971 2001
1972 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 2002 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
1973 max_tries = IEEE80211_MAX_NULLFUNC_TRIES; 2003 max_tries = max_nullfunc_tries;
1974 else 2004 else
1975 max_tries = IEEE80211_MAX_PROBE_TRIES; 2005 max_tries = max_probe_tries;
1976 2006
1977 /* ACK received for nullfunc probing frame */ 2007 /* ACK received for nullfunc probing frame */
1978 if (!ifmgd->probe_send_count) 2008 if (!ifmgd->probe_send_count)
@@ -2004,7 +2034,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2004 "%s: Failed to send nullfunc to AP %pM" 2034 "%s: Failed to send nullfunc to AP %pM"
2005 " after %dms, disconnecting.\n", 2035 " after %dms, disconnecting.\n",
2006 sdata->name, 2036 sdata->name,
2007 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2037 bssid, probe_wait_ms);
2008#endif 2038#endif
2009 ieee80211_sta_connection_lost(sdata, bssid); 2039 ieee80211_sta_connection_lost(sdata, bssid);
2010 } else if (ifmgd->probe_send_count < max_tries) { 2040 } else if (ifmgd->probe_send_count < max_tries) {
@@ -2013,7 +2043,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2013 "%s: No probe response from AP %pM" 2043 "%s: No probe response from AP %pM"
2014 " after %dms, try %d/%i\n", 2044 " after %dms, try %d/%i\n",
2015 sdata->name, 2045 sdata->name,
2016 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ, 2046 bssid, probe_wait_ms,
2017 ifmgd->probe_send_count, max_tries); 2047 ifmgd->probe_send_count, max_tries);
2018#endif 2048#endif
2019 ieee80211_mgd_probe_ap_send(sdata); 2049 ieee80211_mgd_probe_ap_send(sdata);
@@ -2026,7 +2056,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2026 "%s: No probe response from AP %pM" 2056 "%s: No probe response from AP %pM"
2027 " after %dms, disconnecting.\n", 2057 " after %dms, disconnecting.\n",
2028 sdata->name, 2058 sdata->name,
2029 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2059 bssid, probe_wait_ms);
2030 2060
2031 ieee80211_sta_connection_lost(sdata, bssid); 2061 ieee80211_sta_connection_lost(sdata, bssid);
2032 } 2062 }
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index b4e52676f3f..13427b194ce 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -17,10 +17,14 @@
17#include "driver-trace.h" 17#include "driver-trace.h"
18 18
19/* 19/*
20 * inform AP that we will go to sleep so that it will buffer the frames 20 * Tell our hardware to disable PS.
21 * while we scan 21 * Optionally inform AP that we will go to sleep so that it will buffer
22 * the frames while we are doing off-channel work. This is optional
23 * because we *may* be doing work on-operating channel, and want our
24 * hardware unconditionally awake, but still let the AP send us normal frames.
22 */ 25 */
23static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) 26static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata,
27 bool tell_ap)
24{ 28{
25 struct ieee80211_local *local = sdata->local; 29 struct ieee80211_local *local = sdata->local;
26 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 30 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -41,8 +45,8 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
41 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 45 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
42 } 46 }
43 47
44 if (!(local->offchannel_ps_enabled) || 48 if (tell_ap && (!local->offchannel_ps_enabled ||
45 !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) 49 !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)))
46 /* 50 /*
47 * If power save was enabled, no need to send a nullfunc 51 * If power save was enabled, no need to send a nullfunc
48 * frame because AP knows that we are sleeping. But if the 52 * frame because AP knows that we are sleeping. But if the
@@ -77,6 +81,9 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
77 * we are sleeping, let's just enable power save mode in 81 * we are sleeping, let's just enable power save mode in
78 * hardware. 82 * hardware.
79 */ 83 */
84 /* TODO: Only set hardware if CONF_PS changed?
85 * TODO: Should we set offchannel_ps_enabled to false?
86 */
80 local->hw.conf.flags |= IEEE80211_CONF_PS; 87 local->hw.conf.flags |= IEEE80211_CONF_PS;
81 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 88 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
82 } else if (local->hw.conf.dynamic_ps_timeout > 0) { 89 } else if (local->hw.conf.dynamic_ps_timeout > 0) {
@@ -95,63 +102,61 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
95 ieee80211_sta_reset_conn_monitor(sdata); 102 ieee80211_sta_reset_conn_monitor(sdata);
96} 103}
97 104
98void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) 105void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
106 bool offchannel_ps_enable)
99{ 107{
100 struct ieee80211_sub_if_data *sdata; 108 struct ieee80211_sub_if_data *sdata;
101 109
110 /*
111 * notify the AP about us leaving the channel and stop all
112 * STA interfaces.
113 */
102 mutex_lock(&local->iflist_mtx); 114 mutex_lock(&local->iflist_mtx);
103 list_for_each_entry(sdata, &local->interfaces, list) { 115 list_for_each_entry(sdata, &local->interfaces, list) {
104 if (!ieee80211_sdata_running(sdata)) 116 if (!ieee80211_sdata_running(sdata))
105 continue; 117 continue;
106 118
107 /* disable beaconing */ 119 if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
120 set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
121
122 /* Check to see if we should disable beaconing. */
108 if (sdata->vif.type == NL80211_IFTYPE_AP || 123 if (sdata->vif.type == NL80211_IFTYPE_AP ||
109 sdata->vif.type == NL80211_IFTYPE_ADHOC || 124 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
110 sdata->vif.type == NL80211_IFTYPE_MESH_POINT) 125 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
111 ieee80211_bss_info_change_notify( 126 ieee80211_bss_info_change_notify(
112 sdata, BSS_CHANGED_BEACON_ENABLED); 127 sdata, BSS_CHANGED_BEACON_ENABLED);
113 128
114 /* 129 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
115 * only handle non-STA interfaces here, STA interfaces
116 * are handled in ieee80211_offchannel_stop_station(),
117 * e.g., from the background scan state machine.
118 *
119 * In addition, do not stop monitor interface to allow it to be
120 * used from user space controlled off-channel operations.
121 */
122 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
123 sdata->vif.type != NL80211_IFTYPE_MONITOR) {
124 set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
125 netif_tx_stop_all_queues(sdata->dev); 130 netif_tx_stop_all_queues(sdata->dev);
131 if (offchannel_ps_enable &&
132 (sdata->vif.type == NL80211_IFTYPE_STATION) &&
133 sdata->u.mgd.associated)
134 ieee80211_offchannel_ps_enable(sdata, true);
126 } 135 }
127 } 136 }
128 mutex_unlock(&local->iflist_mtx); 137 mutex_unlock(&local->iflist_mtx);
129} 138}
130 139
131void ieee80211_offchannel_stop_station(struct ieee80211_local *local) 140void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,
141 bool tell_ap)
132{ 142{
133 struct ieee80211_sub_if_data *sdata; 143 struct ieee80211_sub_if_data *sdata;
134 144
135 /*
136 * notify the AP about us leaving the channel and stop all STA interfaces
137 */
138 mutex_lock(&local->iflist_mtx); 145 mutex_lock(&local->iflist_mtx);
139 list_for_each_entry(sdata, &local->interfaces, list) { 146 list_for_each_entry(sdata, &local->interfaces, list) {
140 if (!ieee80211_sdata_running(sdata)) 147 if (!ieee80211_sdata_running(sdata))
141 continue; 148 continue;
142 149
143 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 150 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
144 set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); 151 sdata->u.mgd.associated)
145 netif_tx_stop_all_queues(sdata->dev); 152 ieee80211_offchannel_ps_enable(sdata, tell_ap);
146 if (sdata->u.mgd.associated)
147 ieee80211_offchannel_ps_enable(sdata);
148 }
149 } 153 }
150 mutex_unlock(&local->iflist_mtx); 154 mutex_unlock(&local->iflist_mtx);
151} 155}
152 156
153void ieee80211_offchannel_return(struct ieee80211_local *local, 157void ieee80211_offchannel_return(struct ieee80211_local *local,
154 bool enable_beaconing) 158 bool enable_beaconing,
159 bool offchannel_ps_disable)
155{ 160{
156 struct ieee80211_sub_if_data *sdata; 161 struct ieee80211_sub_if_data *sdata;
157 162
@@ -161,7 +166,8 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
161 continue; 166 continue;
162 167
163 /* Tell AP we're back */ 168 /* Tell AP we're back */
164 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 169 if (offchannel_ps_disable &&
170 sdata->vif.type == NL80211_IFTYPE_STATION) {
165 if (sdata->u.mgd.associated) 171 if (sdata->u.mgd.associated)
166 ieee80211_offchannel_ps_disable(sdata); 172 ieee80211_offchannel_ps_disable(sdata);
167 } 173 }
@@ -181,7 +187,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
181 netif_tx_wake_all_queues(sdata->dev); 187 netif_tx_wake_all_queues(sdata->dev);
182 } 188 }
183 189
184 /* re-enable beaconing */ 190 /* Check to see if we should re-enable beaconing */
185 if (enable_beaconing && 191 if (enable_beaconing &&
186 (sdata->vif.type == NL80211_IFTYPE_AP || 192 (sdata->vif.type == NL80211_IFTYPE_AP ||
187 sdata->vif.type == NL80211_IFTYPE_ADHOC || 193 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 7185c9316be..045b2fe4a41 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -142,11 +142,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
142 /* IEEE80211_RADIOTAP_RATE */ 142 /* IEEE80211_RADIOTAP_RATE */
143 if (status->flag & RX_FLAG_HT) { 143 if (status->flag & RX_FLAG_HT) {
144 /* 144 /*
145 * TODO: add following information into radiotap header once 145 * MCS information is a separate field in radiotap,
146 * suitable fields are defined for it: 146 * added below.
147 * - MCS index (status->rate_idx)
148 * - HT40 (status->flag & RX_FLAG_40MHZ)
149 * - short-GI (status->flag & RX_FLAG_SHORT_GI)
150 */ 147 */
151 *pos = 0; 148 *pos = 0;
152 } else { 149 } else {
@@ -409,16 +406,10 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
409 if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN))) 406 if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN)))
410 return RX_CONTINUE; 407 return RX_CONTINUE;
411 408
412 if (test_bit(SCAN_HW_SCANNING, &local->scanning)) 409 if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
410 test_bit(SCAN_SW_SCANNING, &local->scanning))
413 return ieee80211_scan_rx(rx->sdata, skb); 411 return ieee80211_scan_rx(rx->sdata, skb);
414 412
415 if (test_bit(SCAN_SW_SCANNING, &local->scanning)) {
416 /* drop all the other packets during a software scan anyway */
417 if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED)
418 dev_kfree_skb(skb);
419 return RX_QUEUED;
420 }
421
422 /* scanning finished during invoking of handlers */ 413 /* scanning finished during invoking of handlers */
423 I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); 414 I802_DEBUG_INC(local->rx_handlers_drop_passive_scan);
424 return RX_DROP_UNUSABLE; 415 return RX_DROP_UNUSABLE;
@@ -815,7 +806,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
815 rx->local->dot11FrameDuplicateCount++; 806 rx->local->dot11FrameDuplicateCount++;
816 rx->sta->num_duplicates++; 807 rx->sta->num_duplicates++;
817 } 808 }
818 return RX_DROP_MONITOR; 809 return RX_DROP_UNUSABLE;
819 } else 810 } else
820 rx->sta->last_seq_ctrl[rx->queue] = hdr->seq_ctrl; 811 rx->sta->last_seq_ctrl[rx->queue] = hdr->seq_ctrl;
821 } 812 }
@@ -1105,7 +1096,8 @@ static void ap_sta_ps_start(struct sta_info *sta)
1105 1096
1106 atomic_inc(&sdata->bss->num_sta_ps); 1097 atomic_inc(&sdata->bss->num_sta_ps);
1107 set_sta_flags(sta, WLAN_STA_PS_STA); 1098 set_sta_flags(sta, WLAN_STA_PS_STA);
1108 drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); 1099 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
1100 drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta);
1109#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1101#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1110 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", 1102 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
1111 sdata->name, sta->sta.addr, sta->sta.aid); 1103 sdata->name, sta->sta.addr, sta->sta.aid);
@@ -1134,6 +1126,27 @@ static void ap_sta_ps_end(struct sta_info *sta)
1134 ieee80211_sta_ps_deliver_wakeup(sta); 1126 ieee80211_sta_ps_deliver_wakeup(sta);
1135} 1127}
1136 1128
1129int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start)
1130{
1131 struct sta_info *sta_inf = container_of(sta, struct sta_info, sta);
1132 bool in_ps;
1133
1134 WARN_ON(!(sta_inf->local->hw.flags & IEEE80211_HW_AP_LINK_PS));
1135
1136 /* Don't let the same PS state be set twice */
1137 in_ps = test_sta_flags(sta_inf, WLAN_STA_PS_STA);
1138 if ((start && in_ps) || (!start && !in_ps))
1139 return -EINVAL;
1140
1141 if (start)
1142 ap_sta_ps_start(sta_inf);
1143 else
1144 ap_sta_ps_end(sta_inf);
1145
1146 return 0;
1147}
1148EXPORT_SYMBOL(ieee80211_sta_ps_transition);
1149
1137static ieee80211_rx_result debug_noinline 1150static ieee80211_rx_result debug_noinline
1138ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) 1151ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1139{ 1152{
@@ -1178,7 +1191,8 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1178 * Change STA power saving mode only at the end of a frame 1191 * Change STA power saving mode only at the end of a frame
1179 * exchange sequence. 1192 * exchange sequence.
1180 */ 1193 */
1181 if (!ieee80211_has_morefrags(hdr->frame_control) && 1194 if (!(sta->local->hw.flags & IEEE80211_HW_AP_LINK_PS) &&
1195 !ieee80211_has_morefrags(hdr->frame_control) &&
1182 !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && 1196 !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
1183 (rx->sdata->vif.type == NL80211_IFTYPE_AP || 1197 (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
1184 rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { 1198 rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
@@ -1929,7 +1943,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1929 dev->stats.rx_bytes += rx->skb->len; 1943 dev->stats.rx_bytes += rx->skb->len;
1930 1944
1931 if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 && 1945 if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 &&
1932 !is_multicast_ether_addr(((struct ethhdr *)rx->skb->data)->h_dest)) { 1946 !is_multicast_ether_addr(
1947 ((struct ethhdr *)rx->skb->data)->h_dest) &&
1948 (!local->scanning &&
1949 !test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))) {
1933 mod_timer(&local->dynamic_ps_timer, jiffies + 1950 mod_timer(&local->dynamic_ps_timer, jiffies +
1934 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); 1951 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
1935 } 1952 }
@@ -2626,7 +2643,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2626 return 0; 2643 return 0;
2627 if (!multicast && 2644 if (!multicast &&
2628 compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { 2645 compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) {
2629 if (!(sdata->dev->flags & IFF_PROMISC)) 2646 if (!(sdata->dev->flags & IFF_PROMISC) ||
2647 sdata->u.mgd.use_4addr)
2630 return 0; 2648 return 0;
2631 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2649 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2632 } 2650 }
@@ -2675,7 +2693,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2675 return 0; 2693 return 0;
2676 } else if (!ieee80211_bssid_match(bssid, 2694 } else if (!ieee80211_bssid_match(bssid,
2677 sdata->vif.addr)) { 2695 sdata->vif.addr)) {
2678 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) 2696 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
2697 !ieee80211_is_beacon(hdr->frame_control))
2679 return 0; 2698 return 0;
2680 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2699 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2681 } 2700 }
@@ -2766,7 +2785,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2766 local->dot11ReceivedFragmentCount++; 2785 local->dot11ReceivedFragmentCount++;
2767 2786
2768 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || 2787 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2769 test_bit(SCAN_OFF_CHANNEL, &local->scanning))) 2788 test_bit(SCAN_SW_SCANNING, &local->scanning)))
2770 status->rx_flags |= IEEE80211_RX_IN_SCAN; 2789 status->rx_flags |= IEEE80211_RX_IN_SCAN;
2771 2790
2772 if (ieee80211_is_mgmt(fc)) 2791 if (ieee80211_is_mgmt(fc))
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 1ef73be76b2..0ea6adae3e0 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -212,6 +212,14 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
212 if (bss) 212 if (bss)
213 ieee80211_rx_bss_put(sdata->local, bss); 213 ieee80211_rx_bss_put(sdata->local, bss);
214 214
215 /* If we are on-operating-channel, and this packet is for the
216 * current channel, pass the pkt on up the stack so that
217 * the rest of the stack can make use of it.
218 */
219 if (ieee80211_cfg_on_oper_channel(sdata->local)
220 && (channel == sdata->local->oper_channel))
221 return RX_CONTINUE;
222
215 dev_kfree_skb(skb); 223 dev_kfree_skb(skb);
216 return RX_QUEUED; 224 return RX_QUEUED;
217} 225}
@@ -293,15 +301,31 @@ static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw,
293 bool was_hw_scan) 301 bool was_hw_scan)
294{ 302{
295 struct ieee80211_local *local = hw_to_local(hw); 303 struct ieee80211_local *local = hw_to_local(hw);
304 bool on_oper_chan;
305 bool enable_beacons = false;
306
307 mutex_lock(&local->mtx);
308 on_oper_chan = ieee80211_cfg_on_oper_channel(local);
309
310 if (was_hw_scan || !on_oper_chan) {
311 if (WARN_ON(local->scan_channel))
312 local->scan_channel = NULL;
313 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
314 }
296 315
297 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
298 if (!was_hw_scan) { 316 if (!was_hw_scan) {
317 bool on_oper_chan2;
299 ieee80211_configure_filter(local); 318 ieee80211_configure_filter(local);
300 drv_sw_scan_complete(local); 319 drv_sw_scan_complete(local);
301 ieee80211_offchannel_return(local, true); 320 on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);
321 /* We should always be on-channel at this point. */
322 WARN_ON(!on_oper_chan2);
323 if (on_oper_chan2 && (on_oper_chan != on_oper_chan2))
324 enable_beacons = true;
325
326 ieee80211_offchannel_return(local, enable_beacons, true);
302 } 327 }
303 328
304 mutex_lock(&local->mtx);
305 ieee80211_recalc_idle(local); 329 ieee80211_recalc_idle(local);
306 mutex_unlock(&local->mtx); 330 mutex_unlock(&local->mtx);
307 331
@@ -341,13 +365,15 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
341 */ 365 */
342 drv_sw_scan_start(local); 366 drv_sw_scan_start(local);
343 367
344 ieee80211_offchannel_stop_beaconing(local);
345
346 local->leave_oper_channel_time = 0; 368 local->leave_oper_channel_time = 0;
347 local->next_scan_state = SCAN_DECISION; 369 local->next_scan_state = SCAN_DECISION;
348 local->scan_channel_idx = 0; 370 local->scan_channel_idx = 0;
349 371
350 drv_flush(local, false); 372 /* We always want to use off-channel PS, even if we
373 * are not really leaving oper-channel. Don't
374 * tell the AP though, as long as we are on-channel.
375 */
376 ieee80211_offchannel_enable_all_ps(local, false);
351 377
352 ieee80211_configure_filter(local); 378 ieee80211_configure_filter(local);
353 379
@@ -487,7 +513,21 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
487 } 513 }
488 mutex_unlock(&local->iflist_mtx); 514 mutex_unlock(&local->iflist_mtx);
489 515
490 if (local->scan_channel) { 516 next_chan = local->scan_req->channels[local->scan_channel_idx];
517
518 if (ieee80211_cfg_on_oper_channel(local)) {
519 /* We're currently on operating channel. */
520 if ((next_chan == local->oper_channel) &&
521 (local->_oper_channel_type == NL80211_CHAN_NO_HT))
522 /* We don't need to move off of operating channel. */
523 local->next_scan_state = SCAN_SET_CHANNEL;
524 else
525 /*
526 * We do need to leave operating channel, as next
527 * scan is somewhere else.
528 */
529 local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
530 } else {
491 /* 531 /*
492 * we're currently scanning a different channel, let's 532 * we're currently scanning a different channel, let's
493 * see if we can scan another channel without interfering 533 * see if we can scan another channel without interfering
@@ -503,7 +543,6 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
503 * 543 *
504 * Otherwise switch back to the operating channel. 544 * Otherwise switch back to the operating channel.
505 */ 545 */
506 next_chan = local->scan_req->channels[local->scan_channel_idx];
507 546
508 bad_latency = time_after(jiffies + 547 bad_latency = time_after(jiffies +
509 ieee80211_scan_get_channel_time(next_chan), 548 ieee80211_scan_get_channel_time(next_chan),
@@ -521,12 +560,6 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
521 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL; 560 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
522 else 561 else
523 local->next_scan_state = SCAN_SET_CHANNEL; 562 local->next_scan_state = SCAN_SET_CHANNEL;
524 } else {
525 /*
526 * we're on the operating channel currently, let's
527 * leave that channel now to scan another one
528 */
529 local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
530 } 563 }
531 564
532 *next_delay = 0; 565 *next_delay = 0;
@@ -535,9 +568,10 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
535static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, 568static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
536 unsigned long *next_delay) 569 unsigned long *next_delay)
537{ 570{
538 ieee80211_offchannel_stop_station(local); 571 /* PS will already be in off-channel mode,
539 572 * we do that once at the beginning of scanning.
540 __set_bit(SCAN_OFF_CHANNEL, &local->scanning); 573 */
574 ieee80211_offchannel_stop_vifs(local, false);
541 575
542 /* 576 /*
543 * What if the nullfunc frames didn't arrive? 577 * What if the nullfunc frames didn't arrive?
@@ -560,15 +594,15 @@ static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *loca
560{ 594{
561 /* switch back to the operating channel */ 595 /* switch back to the operating channel */
562 local->scan_channel = NULL; 596 local->scan_channel = NULL;
563 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 597 if (!ieee80211_cfg_on_oper_channel(local))
598 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
564 599
565 /* 600 /*
566 * Only re-enable station mode interface now; beaconing will be 601 * Re-enable vifs and beaconing. Leave PS
567 * re-enabled once the full scan has been completed. 602 * in off-channel state..will put that back
603 * on-channel at the end of scanning.
568 */ 604 */
569 ieee80211_offchannel_return(local, false); 605 ieee80211_offchannel_return(local, true, false);
570
571 __clear_bit(SCAN_OFF_CHANNEL, &local->scanning);
572 606
573 *next_delay = HZ / 5; 607 *next_delay = HZ / 5;
574 local->next_scan_state = SCAN_DECISION; 608 local->next_scan_state = SCAN_DECISION;
@@ -584,8 +618,12 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
584 chan = local->scan_req->channels[local->scan_channel_idx]; 618 chan = local->scan_req->channels[local->scan_channel_idx];
585 619
586 local->scan_channel = chan; 620 local->scan_channel = chan;
587 if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) 621
588 skip = 1; 622 /* Only call hw-config if we really need to change channels. */
623 if ((chan != local->hw.conf.channel) ||
624 (local->hw.conf.channel_type != NL80211_CHAN_NO_HT))
625 if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
626 skip = 1;
589 627
590 /* advance state machine to next channel/band */ 628 /* advance state machine to next channel/band */
591 local->scan_channel_idx++; 629 local->scan_channel_idx++;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index c426504ed1c..5a11078827a 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -899,7 +899,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
899 struct ieee80211_local *local = sdata->local; 899 struct ieee80211_local *local = sdata->local;
900 int sent, buffered; 900 int sent, buffered;
901 901
902 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); 902 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
903 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
903 904
904 if (!skb_queue_empty(&sta->ps_tx_buf)) 905 if (!skb_queue_empty(&sta->ps_tx_buf))
905 sta_info_clear_tim_bit(sta); 906 sta_info_clear_tim_bit(sta);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 38a797217a9..ffb0de9bc2f 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -98,6 +98,10 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
98 * (b) always process RX events before TX status events if ordering 98 * (b) always process RX events before TX status events if ordering
99 * can be unknown, for example with different interrupt status 99 * can be unknown, for example with different interrupt status
100 * bits. 100 * bits.
101 * (c) if PS mode transitions are manual (i.e. the flag
102 * %IEEE80211_HW_AP_LINK_PS is set), always process PS state
103 * changes before calling TX status events if ordering can be
104 * unknown.
101 */ 105 */
102 if (test_sta_flags(sta, WLAN_STA_PS_STA) && 106 if (test_sta_flags(sta, WLAN_STA_PS_STA) &&
103 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { 107 skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ffc67491c38..38e59393972 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -257,7 +257,8 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
257 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) 257 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
258 return TX_CONTINUE; 258 return TX_CONTINUE;
259 259
260 if (unlikely(test_bit(SCAN_OFF_CHANNEL, &tx->local->scanning)) && 260 if (unlikely(test_bit(SCAN_SW_SCANNING, &tx->local->scanning)) &&
261 test_bit(SDATA_STATE_OFFCHANNEL, &tx->sdata->state) &&
261 !ieee80211_is_probe_req(hdr->frame_control) && 262 !ieee80211_is_probe_req(hdr->frame_control) &&
262 !ieee80211_is_nullfunc(hdr->frame_control)) 263 !ieee80211_is_nullfunc(hdr->frame_control))
263 /* 264 /*
@@ -1394,7 +1395,8 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1394 /* handlers after fragment must be aware of tx info fragmentation! */ 1395 /* handlers after fragment must be aware of tx info fragmentation! */
1395 CALL_TXH(ieee80211_tx_h_stats); 1396 CALL_TXH(ieee80211_tx_h_stats);
1396 CALL_TXH(ieee80211_tx_h_encrypt); 1397 CALL_TXH(ieee80211_tx_h_encrypt);
1397 CALL_TXH(ieee80211_tx_h_calculate_duration); 1398 if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
1399 CALL_TXH(ieee80211_tx_h_calculate_duration);
1398#undef CALL_TXH 1400#undef CALL_TXH
1399 1401
1400 txh_done: 1402 txh_done:
@@ -2178,6 +2180,8 @@ static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss,
2178 if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf)) 2180 if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf))
2179 aid0 = 1; 2181 aid0 = 1;
2180 2182
2183 bss->dtim_bc_mc = aid0 == 1;
2184
2181 if (have_bits) { 2185 if (have_bits) {
2182 /* Find largest even number N1 so that bits numbered 1 through 2186 /* Find largest even number N1 so that bits numbered 1 through
2183 * (N1 x 8) - 1 in the bitmap are 0 and number N2 so that bits 2187 * (N1 x 8) - 1 in the bitmap are 0 and number N2 so that bits
@@ -2241,7 +2245,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2241 if (sdata->vif.type == NL80211_IFTYPE_AP) { 2245 if (sdata->vif.type == NL80211_IFTYPE_AP) {
2242 ap = &sdata->u.ap; 2246 ap = &sdata->u.ap;
2243 beacon = rcu_dereference(ap->beacon); 2247 beacon = rcu_dereference(ap->beacon);
2244 if (ap && beacon) { 2248 if (beacon) {
2245 /* 2249 /*
2246 * headroom, head length, 2250 * headroom, head length,
2247 * tail length and maximum TIM length 2251 * tail length and maximum TIM length
@@ -2548,7 +2552,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2548 if (sdata->vif.type != NL80211_IFTYPE_AP || !beacon || !beacon->head) 2552 if (sdata->vif.type != NL80211_IFTYPE_AP || !beacon || !beacon->head)
2549 goto out; 2553 goto out;
2550 2554
2551 if (bss->dtim_count != 0) 2555 if (bss->dtim_count != 0 || !bss->dtim_bc_mc)
2552 goto out; /* send buffered bc/mc only after DTIM beacon */ 2556 goto out; /* send buffered bc/mc only after DTIM beacon */
2553 2557
2554 while (1) { 2558 while (1) {
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 36305e0d06e..6bf787a5b38 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -924,18 +924,44 @@ static void ieee80211_work_work(struct work_struct *work)
924 } 924 }
925 925
926 if (!started && !local->tmp_channel) { 926 if (!started && !local->tmp_channel) {
927 /* 927 bool on_oper_chan;
928 * TODO: could optimize this by leaving the 928 bool tmp_chan_changed = false;
929 * station vifs in awake mode if they 929 bool on_oper_chan2;
930 * happen to be on the same channel as 930 on_oper_chan = ieee80211_cfg_on_oper_channel(local);
931 * the requested channel 931 if (local->tmp_channel)
932 */ 932 if ((local->tmp_channel != wk->chan) ||
933 ieee80211_offchannel_stop_beaconing(local); 933 (local->tmp_channel_type != wk->chan_type))
934 ieee80211_offchannel_stop_station(local); 934 tmp_chan_changed = true;
935 935
936 local->tmp_channel = wk->chan; 936 local->tmp_channel = wk->chan;
937 local->tmp_channel_type = wk->chan_type; 937 local->tmp_channel_type = wk->chan_type;
938 ieee80211_hw_config(local, 0); 938 /*
939 * Leave the station vifs in awake mode if they
940 * happen to be on the same channel as
941 * the requested channel.
942 */
943 on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);
944 if (on_oper_chan != on_oper_chan2) {
945 if (on_oper_chan2) {
946 /* going off oper channel, PS too */
947 ieee80211_offchannel_stop_vifs(local,
948 true);
949 ieee80211_hw_config(local, 0);
950 } else {
951 /* going on channel, but leave PS
952 * off-channel. */
953 ieee80211_hw_config(local, 0);
954 ieee80211_offchannel_return(local,
955 true,
956 false);
957 }
958 } else if (tmp_chan_changed)
959 /* Still off-channel, but on some other
960 * channel, so update hardware.
961 * PS should already be off-channel.
962 */
963 ieee80211_hw_config(local, 0);
964
939 started = true; 965 started = true;
940 wk->timeout = jiffies; 966 wk->timeout = jiffies;
941 } 967 }
@@ -1011,9 +1037,27 @@ static void ieee80211_work_work(struct work_struct *work)
1011 } 1037 }
1012 1038
1013 if (!remain_off_channel && local->tmp_channel) { 1039 if (!remain_off_channel && local->tmp_channel) {
1040 bool on_oper_chan = ieee80211_cfg_on_oper_channel(local);
1014 local->tmp_channel = NULL; 1041 local->tmp_channel = NULL;
1015 ieee80211_hw_config(local, 0); 1042 /* If tmp_channel wasn't operating channel, then
1016 ieee80211_offchannel_return(local, true); 1043 * we need to go back on-channel.
1044 * NOTE: If we can ever be here while scannning,
1045 * or if the hw_config() channel config logic changes,
1046 * then we may need to do a more thorough check to see if
1047 * we still need to do a hardware config. Currently,
1048 * we cannot be here while scanning, however.
1049 */
1050 if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan)
1051 ieee80211_hw_config(local, 0);
1052
1053 /* At the least, we need to disable offchannel_ps,
1054 * so just go ahead and run the entire offchannel
1055 * return logic here. We *could* skip enabling
1056 * beaconing if we were already on-oper-channel
1057 * as a future optimization.
1058 */
1059 ieee80211_offchannel_return(local, true, true);
1060
1017 /* give connection some time to breathe */ 1061 /* give connection some time to breathe */
1018 run_again(local, jiffies + HZ/2); 1062 run_again(local, jiffies + HZ/2);
1019 } 1063 }
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index bee230d8fd1..f1765de2f4b 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -26,13 +26,12 @@
26ieee80211_tx_result 26ieee80211_tx_result
27ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) 27ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
28{ 28{
29 u8 *data, *key, *mic, key_offset; 29 u8 *data, *key, *mic;
30 size_t data_len; 30 size_t data_len;
31 unsigned int hdrlen; 31 unsigned int hdrlen;
32 struct ieee80211_hdr *hdr; 32 struct ieee80211_hdr *hdr;
33 struct sk_buff *skb = tx->skb; 33 struct sk_buff *skb = tx->skb;
34 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 34 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
35 int authenticator;
36 int tail; 35 int tail;
37 36
38 hdr = (struct ieee80211_hdr *)skb->data; 37 hdr = (struct ieee80211_hdr *)skb->data;
@@ -47,6 +46,11 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
47 data = skb->data + hdrlen; 46 data = skb->data + hdrlen;
48 data_len = skb->len - hdrlen; 47 data_len = skb->len - hdrlen;
49 48
49 if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE)) {
50 /* Need to use software crypto for the test */
51 info->control.hw_key = NULL;
52 }
53
50 if (info->control.hw_key && 54 if (info->control.hw_key &&
51 !(tx->flags & IEEE80211_TX_FRAGMENTED) && 55 !(tx->flags & IEEE80211_TX_FRAGMENTED) &&
52 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) { 56 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
@@ -62,17 +66,11 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
62 skb_headroom(skb) < TKIP_IV_LEN)) 66 skb_headroom(skb) < TKIP_IV_LEN))
63 return TX_DROP; 67 return TX_DROP;
64 68
65#if 0 69 key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY];
66 authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */
67#else
68 authenticator = 1;
69#endif
70 key_offset = authenticator ?
71 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY :
72 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
73 key = &tx->key->conf.key[key_offset];
74 mic = skb_put(skb, MICHAEL_MIC_LEN); 70 mic = skb_put(skb, MICHAEL_MIC_LEN);
75 michael_mic(key, hdr, data, data_len, mic); 71 michael_mic(key, hdr, data, data_len, mic);
72 if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE))
73 mic[0]++;
76 74
77 return TX_CONTINUE; 75 return TX_CONTINUE;
78} 76}
@@ -81,14 +79,13 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
81ieee80211_rx_result 79ieee80211_rx_result
82ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) 80ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
83{ 81{
84 u8 *data, *key = NULL, key_offset; 82 u8 *data, *key = NULL;
85 size_t data_len; 83 size_t data_len;
86 unsigned int hdrlen; 84 unsigned int hdrlen;
87 u8 mic[MICHAEL_MIC_LEN]; 85 u8 mic[MICHAEL_MIC_LEN];
88 struct sk_buff *skb = rx->skb; 86 struct sk_buff *skb = rx->skb;
89 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 87 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
90 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 88 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
91 int authenticator = 1, wpa_test = 0;
92 89
93 /* No way to verify the MIC if the hardware stripped it */ 90 /* No way to verify the MIC if the hardware stripped it */
94 if (status->flag & RX_FLAG_MMIC_STRIPPED) 91 if (status->flag & RX_FLAG_MMIC_STRIPPED)
@@ -106,17 +103,9 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
106 data = skb->data + hdrlen; 103 data = skb->data + hdrlen;
107 data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; 104 data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
108 105
109#if 0 106 key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
110 authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */
111#else
112 authenticator = 1;
113#endif
114 key_offset = authenticator ?
115 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY :
116 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
117 key = &rx->key->conf.key[key_offset];
118 michael_mic(key, hdr, data, data_len, mic); 107 michael_mic(key, hdr, data, data_len, mic);
119 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { 108 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) {
120 if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) 109 if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
121 return RX_DROP_UNUSABLE; 110 return RX_DROP_UNUSABLE;
122 111
@@ -208,7 +197,7 @@ ieee80211_rx_result
208ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) 197ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
209{ 198{
210 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 199 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
211 int hdrlen, res, hwaccel = 0, wpa_test = 0; 200 int hdrlen, res, hwaccel = 0;
212 struct ieee80211_key *key = rx->key; 201 struct ieee80211_key *key = rx->key;
213 struct sk_buff *skb = rx->skb; 202 struct sk_buff *skb = rx->skb;
214 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 203 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
@@ -235,7 +224,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
235 hdr->addr1, hwaccel, rx->queue, 224 hdr->addr1, hwaccel, rx->queue,
236 &rx->tkip_iv32, 225 &rx->tkip_iv32,
237 &rx->tkip_iv16); 226 &rx->tkip_iv16);
238 if (res != TKIP_DECRYPT_OK || wpa_test) 227 if (res != TKIP_DECRYPT_OK)
239 return RX_DROP_UNUSABLE; 228 return RX_DROP_UNUSABLE;
240 229
241 /* Trim ICV */ 230 /* Trim ICV */