aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJeremy Erickson <jerickso@cs.unc.edu>2014-04-18 17:06:00 -0400
committerJeremy Erickson <jerickso@cs.unc.edu>2014-04-18 17:06:00 -0400
commita215aa7b9ab3759c047201199fba64d3042d7f13 (patch)
treebca37493d9b2233450e6d3ffced1261d0e4f71fe /net/mac80211
parentd31199a77ef606f1d06894385f1852181ba6136b (diff)
Update 2.6.36 to 2.6.36.4wip-dissipation2-jerickso
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/agg-rx.c11
-rw-r--r--net/mac80211/cfg.c5
-rw-r--r--net/mac80211/ibss.c1
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/key.c6
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh_plink.c17
-rw-r--r--net/mac80211/mlme.c48
-rw-r--r--net/mac80211/offchannel.c7
-rw-r--r--net/mac80211/rate.c3
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c7
-rw-r--r--net/mac80211/rx.c3
-rw-r--r--net/mac80211/status.c1
-rw-r--r--net/mac80211/tx.c27
14 files changed, 104 insertions, 37 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 965b272499fd..2f6903e48dd9 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -172,8 +172,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
172 struct ieee80211_mgmt *mgmt, 172 struct ieee80211_mgmt *mgmt,
173 size_t len) 173 size_t len)
174{ 174{
175 struct ieee80211_hw *hw = &local->hw;
176 struct ieee80211_conf *conf = &hw->conf;
177 struct tid_ampdu_rx *tid_agg_rx; 175 struct tid_ampdu_rx *tid_agg_rx;
178 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; 176 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
179 u8 dialog_token; 177 u8 dialog_token;
@@ -218,13 +216,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
218 goto end_no_lock; 216 goto end_no_lock;
219 } 217 }
220 /* determine default buffer size */ 218 /* determine default buffer size */
221 if (buf_size == 0) { 219 if (buf_size == 0)
222 struct ieee80211_supported_band *sband; 220 buf_size = IEEE80211_MAX_AMPDU_BUF;
223
224 sband = local->hw.wiphy->bands[conf->channel->band];
225 buf_size = IEEE80211_MIN_AMPDU_BUF;
226 buf_size = buf_size << sband->ht_cap.ampdu_factor;
227 }
228 221
229 222
230 /* examine state machine */ 223 /* examine state machine */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 29ac8e1a509e..2095602dcc3a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -634,6 +634,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
634 struct sta_info *sta, 634 struct sta_info *sta,
635 struct station_parameters *params) 635 struct station_parameters *params)
636{ 636{
637 unsigned long flags;
637 u32 rates; 638 u32 rates;
638 int i, j; 639 int i, j;
639 struct ieee80211_supported_band *sband; 640 struct ieee80211_supported_band *sband;
@@ -642,7 +643,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
642 643
643 sband = local->hw.wiphy->bands[local->oper_channel->band]; 644 sband = local->hw.wiphy->bands[local->oper_channel->band];
644 645
645 spin_lock_bh(&sta->lock); 646 spin_lock_irqsave(&sta->flaglock, flags);
646 mask = params->sta_flags_mask; 647 mask = params->sta_flags_mask;
647 set = params->sta_flags_set; 648 set = params->sta_flags_set;
648 649
@@ -669,7 +670,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
669 if (set & BIT(NL80211_STA_FLAG_MFP)) 670 if (set & BIT(NL80211_STA_FLAG_MFP))
670 sta->flags |= WLAN_STA_MFP; 671 sta->flags |= WLAN_STA_MFP;
671 } 672 }
672 spin_unlock_bh(&sta->lock); 673 spin_unlock_irqrestore(&sta->flaglock, flags);
673 674
674 /* 675 /*
675 * cfg80211 validates this (1-2007) and allows setting the AID 676 * cfg80211 validates this (1-2007) and allows setting the AID
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index c691780725a7..45c99f096c7b 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -435,6 +435,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
435 if (!sta) 435 if (!sta)
436 return NULL; 436 return NULL;
437 437
438 sta->last_rx = jiffies;
438 set_sta_flags(sta, WLAN_STA_AUTHORIZED); 439 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
439 440
440 /* make sure mandatory rates are always added */ 441 /* make sure mandatory rates are always added */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 65e0ed6c2975..3546054505ab 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1003,6 +1003,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
1003void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); 1003void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata);
1004void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 1004void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1005 struct sk_buff *skb); 1005 struct sk_buff *skb);
1006void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata);
1007void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
1006 1008
1007/* IBSS code */ 1009/* IBSS code */
1008void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); 1010void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 1b9d87ed143a..3f76484221a2 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -323,6 +323,12 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
323 if (!key) 323 if (!key)
324 return; 324 return;
325 325
326 /*
327 * Synchronize so the TX path can no longer be using
328 * this key before we free/remove it.
329 */
330 synchronize_rcu();
331
326 if (key->local) 332 if (key->local)
327 ieee80211_key_disable_hw_accel(key); 333 ieee80211_key_disable_hw_accel(key);
328 334
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index ded5c3843e06..e8acdb2fb2ca 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -108,7 +108,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
108 chan = scan_chan; 108 chan = scan_chan;
109 channel_type = NL80211_CHAN_NO_HT; 109 channel_type = NL80211_CHAN_NO_HT;
110 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; 110 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
111 } else if (local->tmp_channel) { 111 } else if (local->tmp_channel &&
112 local->oper_channel != local->tmp_channel) {
112 chan = scan_chan = local->tmp_channel; 113 chan = scan_chan = local->tmp_channel;
113 channel_type = local->tmp_channel_type; 114 channel_type = local->tmp_channel_type;
114 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; 115 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index ea13a80a476c..1c91f0f3c307 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
412 enum plink_event event; 412 enum plink_event event;
413 enum plink_frame_type ftype; 413 enum plink_frame_type ftype;
414 size_t baselen; 414 size_t baselen;
415 bool deactivated; 415 bool deactivated, matches_local = true;
416 u8 ie_len; 416 u8 ie_len;
417 u8 *baseaddr; 417 u8 *baseaddr;
418 __le16 plid, llid, reason; 418 __le16 plid, llid, reason;
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
487 /* Now we will figure out the appropriate event... */ 487 /* Now we will figure out the appropriate event... */
488 event = PLINK_UNDEFINED; 488 event = PLINK_UNDEFINED;
489 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { 489 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
490 matches_local = false;
490 switch (ftype) { 491 switch (ftype) {
491 case PLINK_OPEN: 492 case PLINK_OPEN:
492 event = OPN_RJCT; 493 event = OPN_RJCT;
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
498 /* avoid warning */ 499 /* avoid warning */
499 break; 500 break;
500 } 501 }
501 spin_lock_bh(&sta->lock); 502 }
503
504 if (!sta && !matches_local) {
505 rcu_read_unlock();
506 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
507 llid = 0;
508 mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid,
509 plid, reason);
510 return;
502 } else if (!sta) { 511 } else if (!sta) {
503 /* ftype == PLINK_OPEN */ 512 /* ftype == PLINK_OPEN */
504 u32 rates; 513 u32 rates;
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
522 } 531 }
523 event = OPN_ACPT; 532 event = OPN_ACPT;
524 spin_lock_bh(&sta->lock); 533 spin_lock_bh(&sta->lock);
525 } else { 534 } else if (matches_local) {
526 spin_lock_bh(&sta->lock); 535 spin_lock_bh(&sta->lock);
527 switch (ftype) { 536 switch (ftype) {
528 case PLINK_OPEN: 537 case PLINK_OPEN:
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
564 rcu_read_unlock(); 573 rcu_read_unlock();
565 return; 574 return;
566 } 575 }
576 } else {
577 spin_lock_bh(&sta->lock);
567 } 578 }
568 579
569 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", 580 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b6c163ac22da..4c5eed9446f4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -109,7 +109,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd,
109 mod_timer(&ifmgd->timer, timeout); 109 mod_timer(&ifmgd->timer, timeout);
110} 110}
111 111
112static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) 112void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
113{ 113{
114 if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) 114 if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
115 return; 115 return;
@@ -118,6 +118,19 @@ static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata)
118 round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); 118 round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
119} 119}
120 120
121void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
122{
123 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
124
125 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
126 return;
127
128 mod_timer(&sdata->u.mgd.conn_mon_timer,
129 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
130
131 ifmgd->probe_send_count = 0;
132}
133
121static int ecw2cw(int ecw) 134static int ecw2cw(int ecw)
122{ 135{
123 return (1 << ecw) - 1; 136 return (1 << ecw) - 1;
@@ -1006,21 +1019,26 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1006 if (is_multicast_ether_addr(hdr->addr1)) 1019 if (is_multicast_ether_addr(hdr->addr1))
1007 return; 1020 return;
1008 1021
1009 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) 1022 ieee80211_sta_reset_conn_monitor(sdata);
1010 return;
1011
1012 mod_timer(&sdata->u.mgd.conn_mon_timer,
1013 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
1014} 1023}
1015 1024
1016static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) 1025static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1017{ 1026{
1018 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1027 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1019 const u8 *ssid; 1028 const u8 *ssid;
1029 u8 *dst = ifmgd->associated->bssid;
1030 u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3);
1031
1032 /*
1033 * Try sending broadcast probe requests for the last three
1034 * probe requests after the first ones failed since some
1035 * buggy APs only support broadcast probe requests.
1036 */
1037 if (ifmgd->probe_send_count >= unicast_limit)
1038 dst = NULL;
1020 1039
1021 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); 1040 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
1022 ieee80211_send_probe_req(sdata, ifmgd->associated->bssid, 1041 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
1023 ssid + 2, ssid[1], NULL, 0);
1024 1042
1025 ifmgd->probe_send_count++; 1043 ifmgd->probe_send_count++;
1026 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; 1044 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
@@ -1262,7 +1280,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1262 1280
1263 rates = 0; 1281 rates = 0;
1264 basic_rates = 0; 1282 basic_rates = 0;
1265 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1283 sband = local->hw.wiphy->bands[wk->chan->band];
1266 1284
1267 for (i = 0; i < elems.supp_rates_len; i++) { 1285 for (i = 0; i < elems.supp_rates_len; i++) {
1268 int rate = (elems.supp_rates[i] & 0x7f) * 5; 1286 int rate = (elems.supp_rates[i] & 0x7f) * 5;
@@ -1298,11 +1316,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1298 } 1316 }
1299 } 1317 }
1300 1318
1301 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 1319 sta->sta.supp_rates[wk->chan->band] = rates;
1302 sdata->vif.bss_conf.basic_rates = basic_rates; 1320 sdata->vif.bss_conf.basic_rates = basic_rates;
1303 1321
1304 /* cf. IEEE 802.11 9.2.12 */ 1322 /* cf. IEEE 802.11 9.2.12 */
1305 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 1323 if (wk->chan->band == IEEE80211_BAND_2GHZ &&
1306 have_higher_than_11mbit) 1324 have_higher_than_11mbit)
1307 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 1325 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
1308 else 1326 else
@@ -1362,7 +1380,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1362 * Also start the timer that will detect beacon loss. 1380 * Also start the timer that will detect beacon loss.
1363 */ 1381 */
1364 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); 1382 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1365 mod_beacon_timer(sdata); 1383 ieee80211_sta_reset_beacon_monitor(sdata);
1366 1384
1367 return true; 1385 return true;
1368} 1386}
@@ -1465,7 +1483,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1465 * we have or will be receiving any beacons or data, so let's 1483 * we have or will be receiving any beacons or data, so let's
1466 * schedule the timers again, just in case. 1484 * schedule the timers again, just in case.
1467 */ 1485 */
1468 mod_beacon_timer(sdata); 1486 ieee80211_sta_reset_beacon_monitor(sdata);
1469 1487
1470 mod_timer(&ifmgd->conn_mon_timer, 1488 mod_timer(&ifmgd->conn_mon_timer,
1471 round_jiffies_up(jiffies + 1489 round_jiffies_up(jiffies +
@@ -1540,7 +1558,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1540 ifmgd->last_beacon_signal = rx_status->signal; 1558 ifmgd->last_beacon_signal = rx_status->signal;
1541 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { 1559 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
1542 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; 1560 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
1543 ifmgd->ave_beacon_signal = rx_status->signal; 1561 ifmgd->ave_beacon_signal = rx_status->signal * 16;
1544 ifmgd->last_cqm_event_signal = 0; 1562 ifmgd->last_cqm_event_signal = 0;
1545 } else { 1563 } else {
1546 ifmgd->ave_beacon_signal = 1564 ifmgd->ave_beacon_signal =
@@ -1588,7 +1606,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1588 * Push the beacon loss detection into the future since 1606 * Push the beacon loss detection into the future since
1589 * we are processing a beacon from the AP just now. 1607 * we are processing a beacon from the AP just now.
1590 */ 1608 */
1591 mod_beacon_timer(sdata); 1609 ieee80211_sta_reset_beacon_monitor(sdata);
1592 1610
1593 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); 1611 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
1594 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, 1612 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index c36b1911987a..cf5ee305785b 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -22,12 +22,16 @@
22static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) 22static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
23{ 23{
24 struct ieee80211_local *local = sdata->local; 24 struct ieee80211_local *local = sdata->local;
25 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
25 26
26 local->offchannel_ps_enabled = false; 27 local->offchannel_ps_enabled = false;
27 28
28 /* FIXME: what to do when local->pspolling is true? */ 29 /* FIXME: what to do when local->pspolling is true? */
29 30
30 del_timer_sync(&local->dynamic_ps_timer); 31 del_timer_sync(&local->dynamic_ps_timer);
32 del_timer_sync(&ifmgd->bcn_mon_timer);
33 del_timer_sync(&ifmgd->conn_mon_timer);
34
31 cancel_work_sync(&local->dynamic_ps_enable_work); 35 cancel_work_sync(&local->dynamic_ps_enable_work);
32 36
33 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 37 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
@@ -85,6 +89,9 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
85 mod_timer(&local->dynamic_ps_timer, jiffies + 89 mod_timer(&local->dynamic_ps_timer, jiffies +
86 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); 90 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
87 } 91 }
92
93 ieee80211_sta_reset_beacon_monitor(sdata);
94 ieee80211_sta_reset_conn_monitor(sdata);
88} 95}
89 96
90void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) 97void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local)
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index be04d46110fe..82d5750a110a 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -328,6 +328,9 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
328 * if needed. 328 * if needed.
329 */ 329 */
330 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 330 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
331 /* Skip invalid rates */
332 if (info->control.rates[i].idx < 0)
333 break;
331 /* Rate masking supports only legacy rates for now */ 334 /* Rate masking supports only legacy rates for now */
332 if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) 335 if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS)
333 continue; 336 continue;
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c5b465904e3b..2a18d6602d4a 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
397 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 397 !(info->flags & IEEE80211_TX_STAT_AMPDU))
398 return; 398 return;
399 399
400 if (!info->status.ampdu_len) { 400 if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) {
401 info->status.ampdu_ack_len = 1; 401 info->status.ampdu_ack_len =
402 (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
402 info->status.ampdu_len = 1; 403 info->status.ampdu_len = 1;
403 } 404 }
404 405
@@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
426 group = minstrel_ht_get_group_idx(&ar[i]); 427 group = minstrel_ht_get_group_idx(&ar[i]);
427 rate = &mi->groups[group].rates[ar[i].idx % 8]; 428 rate = &mi->groups[group].rates[ar[i].idx % 8];
428 429
429 if (last && (info->flags & IEEE80211_TX_STAT_ACK)) 430 if (last)
430 rate->success += info->status.ampdu_ack_len; 431 rate->success += info->status.ampdu_ack_len;
431 432
432 rate->attempts += ar[i].count * info->status.ampdu_len; 433 rate->attempts += ar[i].count * info->status.ampdu_len;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 28624282c5f3..2bec9b9dba09 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1715,6 +1715,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1715 if (!fwd_skb && net_ratelimit()) 1715 if (!fwd_skb && net_ratelimit())
1716 printk(KERN_DEBUG "%s: failed to clone mesh frame\n", 1716 printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
1717 sdata->name); 1717 sdata->name);
1718 if (!fwd_skb)
1719 goto out;
1718 1720
1719 fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; 1721 fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
1720 memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); 1722 memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
@@ -1752,6 +1754,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1752 } 1754 }
1753 } 1755 }
1754 1756
1757 out:
1755 if (is_multicast_ether_addr(hdr->addr1) || 1758 if (is_multicast_ether_addr(hdr->addr1) ||
1756 sdata->dev->flags & IFF_PROMISC) 1759 sdata->dev->flags & IFF_PROMISC)
1757 return RX_CONTINUE; 1760 return RX_CONTINUE;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 34da67995d94..6ffa26a9de39 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -58,6 +58,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
58 info->control.vif = &sta->sdata->vif; 58 info->control.vif = &sta->sdata->vif;
59 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | 59 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING |
60 IEEE80211_TX_INTFL_RETRANSMISSION; 60 IEEE80211_TX_INTFL_RETRANSMISSION;
61 info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
61 62
62 sta->tx_filtered_count++; 63 sta->tx_filtered_count++;
63 64
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c54db966926b..9d5af5dd0d98 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1694,7 +1694,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1694{ 1694{
1695 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1695 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1696 struct ieee80211_local *local = sdata->local; 1696 struct ieee80211_local *local = sdata->local;
1697 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1697 struct ieee80211_tx_info *info;
1698 int ret = NETDEV_TX_BUSY, head_need; 1698 int ret = NETDEV_TX_BUSY, head_need;
1699 u16 ethertype, hdrlen, meshhdrlen = 0; 1699 u16 ethertype, hdrlen, meshhdrlen = 0;
1700 __le16 fc; 1700 __le16 fc;
@@ -1705,15 +1705,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1705 int nh_pos, h_pos; 1705 int nh_pos, h_pos;
1706 struct sta_info *sta = NULL; 1706 struct sta_info *sta = NULL;
1707 u32 sta_flags = 0; 1707 u32 sta_flags = 0;
1708 struct sk_buff *tmp_skb;
1708 1709
1709 if (unlikely(skb->len < ETH_HLEN)) { 1710 if (unlikely(skb->len < ETH_HLEN)) {
1710 ret = NETDEV_TX_OK; 1711 ret = NETDEV_TX_OK;
1711 goto fail; 1712 goto fail;
1712 } 1713 }
1713 1714
1714 nh_pos = skb_network_header(skb) - skb->data;
1715 h_pos = skb_transport_header(skb) - skb->data;
1716
1717 /* convert Ethernet header to proper 802.11 header (based on 1715 /* convert Ethernet header to proper 802.11 header (based on
1718 * operation mode) */ 1716 * operation mode) */
1719 ethertype = (skb->data[12] << 8) | skb->data[13]; 1717 ethertype = (skb->data[12] << 8) | skb->data[13];
@@ -1885,6 +1883,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1885 goto fail; 1883 goto fail;
1886 } 1884 }
1887 1885
1886 /*
1887 * If the skb is shared we need to obtain our own copy.
1888 */
1889 if (skb_shared(skb)) {
1890 tmp_skb = skb;
1891 skb = skb_copy(skb, GFP_ATOMIC);
1892 kfree_skb(tmp_skb);
1893
1894 if (!skb) {
1895 ret = NETDEV_TX_OK;
1896 goto fail;
1897 }
1898 }
1899
1888 hdr.frame_control = fc; 1900 hdr.frame_control = fc;
1889 hdr.duration_id = 0; 1901 hdr.duration_id = 0;
1890 hdr.seq_ctrl = 0; 1902 hdr.seq_ctrl = 0;
@@ -1903,6 +1915,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1903 encaps_len = 0; 1915 encaps_len = 0;
1904 } 1916 }
1905 1917
1918 nh_pos = skb_network_header(skb) - skb->data;
1919 h_pos = skb_transport_header(skb) - skb->data;
1920
1906 skb_pull(skb, skip_header_bytes); 1921 skb_pull(skb, skip_header_bytes);
1907 nh_pos -= skip_header_bytes; 1922 nh_pos -= skip_header_bytes;
1908 h_pos -= skip_header_bytes; 1923 h_pos -= skip_header_bytes;
@@ -1969,6 +1984,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1969 skb_set_network_header(skb, nh_pos); 1984 skb_set_network_header(skb, nh_pos);
1970 skb_set_transport_header(skb, h_pos); 1985 skb_set_transport_header(skb, h_pos);
1971 1986
1987 info = IEEE80211_SKB_CB(skb);
1972 memset(info, 0, sizeof(*info)); 1988 memset(info, 0, sizeof(*info));
1973 1989
1974 dev->trans_start = jiffies; 1990 dev->trans_start = jiffies;
@@ -2160,6 +2176,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2160 2176
2161 sdata = vif_to_sdata(vif); 2177 sdata = vif_to_sdata(vif);
2162 2178
2179 if (!ieee80211_sdata_running(sdata))
2180 goto out;
2181
2163 if (tim_offset) 2182 if (tim_offset)
2164 *tim_offset = 0; 2183 *tim_offset = 0;
2165 if (tim_length) 2184 if (tim_length)