aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-12-04 11:29:10 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-12-04 11:29:10 -0500
commitde51f1649ab77f9ad17bdad581a326cbf6e71b49 (patch)
tree82aa375e132b3c639afe239c4e49363636199827 /net/mac80211
parent04bb7ecf8854186f47fb1ea321fc77e7bc931993 (diff)
parentf027c2aca0cf43e0f15fc8de8841f7b566163d94 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg <johannes@sipsolutions.net> says: "This time I have Felix's no-status rate control work, which will allow drivers to work better with rate control even if they don't have perfect status reporting. In addition to this, a small hwsim fix from Patrik, one of the regulatory patches from Arik, and a number of cleanups and fixes I did myself. Of note is a patch where I disable CFG80211_WEXT so that compatibility is no longer selectable - this is intended as a wake-up call for anyone who's still using it, and is still easily worked around (it's a one-line patch) before we fully remove the code as well in the future." Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/chan.c23
-rw-r--r--net/mac80211/iface.c1
-rw-r--r--net/mac80211/mlme.c24
-rw-r--r--net/mac80211/rate.c3
-rw-r--r--net/mac80211/rate.h24
-rw-r--r--net/mac80211/rc80211_minstrel.c5
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c15
-rw-r--r--net/mac80211/status.c113
-rw-r--r--net/mac80211/trace.h6
-rw-r--r--net/mac80211/tx.c2
-rw-r--r--net/mac80211/util.c11
11 files changed, 180 insertions, 47 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index c7c514220298..5d6dae9e4aac 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -932,6 +932,21 @@ ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
932 } 932 }
933} 933}
934 934
935static void
936ieee80211_vif_update_chandef(struct ieee80211_sub_if_data *sdata,
937 const struct cfg80211_chan_def *chandef)
938{
939 struct ieee80211_sub_if_data *vlan;
940
941 sdata->vif.bss_conf.chandef = *chandef;
942
943 if (sdata->vif.type != NL80211_IFTYPE_AP)
944 return;
945
946 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
947 vlan->vif.bss_conf.chandef = *chandef;
948}
949
935static int 950static int
936ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata) 951ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
937{ 952{
@@ -994,7 +1009,7 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
994 if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width) 1009 if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
995 changed = BSS_CHANGED_BANDWIDTH; 1010 changed = BSS_CHANGED_BANDWIDTH;
996 1011
997 sdata->vif.bss_conf.chandef = sdata->reserved_chandef; 1012 ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
998 1013
999 if (changed) 1014 if (changed)
1000 ieee80211_bss_info_change_notify(sdata, changed); 1015 ieee80211_bss_info_change_notify(sdata, changed);
@@ -1336,7 +1351,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
1336 sdata->reserved_chandef.width) 1351 sdata->reserved_chandef.width)
1337 changed = BSS_CHANGED_BANDWIDTH; 1352 changed = BSS_CHANGED_BANDWIDTH;
1338 1353
1339 sdata->vif.bss_conf.chandef = sdata->reserved_chandef; 1354 ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
1340 if (changed) 1355 if (changed)
1341 ieee80211_bss_info_change_notify(sdata, 1356 ieee80211_bss_info_change_notify(sdata,
1342 changed); 1357 changed);
@@ -1507,7 +1522,7 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1507 goto out; 1522 goto out;
1508 } 1523 }
1509 1524
1510 sdata->vif.bss_conf.chandef = *chandef; 1525 ieee80211_vif_update_chandef(sdata, chandef);
1511 1526
1512 ret = ieee80211_assign_vif_chanctx(sdata, ctx); 1527 ret = ieee80211_assign_vif_chanctx(sdata, ctx);
1513 if (ret) { 1528 if (ret) {
@@ -1649,7 +1664,7 @@ int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1649 break; 1664 break;
1650 } 1665 }
1651 1666
1652 sdata->vif.bss_conf.chandef = *chandef; 1667 ieee80211_vif_update_chandef(sdata, chandef);
1653 1668
1654 ieee80211_recalc_chanctx_chantype(local, ctx); 1669 ieee80211_recalc_chanctx_chantype(local, ctx);
1655 1670
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 538fe4ef5c85..417355390873 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -520,6 +520,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
520 sdata->vif.cab_queue = master->vif.cab_queue; 520 sdata->vif.cab_queue = master->vif.cab_queue;
521 memcpy(sdata->vif.hw_queue, master->vif.hw_queue, 521 memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
522 sizeof(sdata->vif.hw_queue)); 522 sizeof(sdata->vif.hw_queue));
523 sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef;
523 break; 524 break;
524 } 525 }
525 case NL80211_IFTYPE_AP: 526 case NL80211_IFTYPE_AP:
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ba06cd003375..75a9bf50207e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -552,13 +552,17 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
552 cap = vht_cap.cap; 552 cap = vht_cap.cap;
553 553
554 if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_80P80MHZ) { 554 if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_80P80MHZ) {
555 cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 555 u32 bw = cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
556 cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; 556
557 cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
558 if (bw == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ||
559 bw == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
560 cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
557 } 561 }
558 562
559 if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_160MHZ) { 563 if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_160MHZ) {
560 cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160; 564 cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
561 cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; 565 cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
562 } 566 }
563 567
564 /* 568 /*
@@ -2263,9 +2267,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
2263 "detected beacon loss from AP (missed %d beacons) - probing\n", 2267 "detected beacon loss from AP (missed %d beacons) - probing\n",
2264 beacon_loss_count); 2268 beacon_loss_count);
2265 2269
2266 ieee80211_cqm_rssi_notify(&sdata->vif, 2270 ieee80211_cqm_beacon_loss_notify(&sdata->vif, GFP_KERNEL);
2267 NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
2268 GFP_KERNEL);
2269 } 2271 }
2270 2272
2271 /* 2273 /*
@@ -4898,3 +4900,13 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
4898 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); 4900 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp);
4899} 4901}
4900EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); 4902EXPORT_SYMBOL(ieee80211_cqm_rssi_notify);
4903
4904void ieee80211_cqm_beacon_loss_notify(struct ieee80211_vif *vif, gfp_t gfp)
4905{
4906 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
4907
4908 trace_api_cqm_beacon_loss_notify(sdata->local, sdata);
4909
4910 cfg80211_cqm_beacon_loss_notify(sdata->dev, gfp);
4911}
4912EXPORT_SYMBOL(ieee80211_cqm_beacon_loss_notify);
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 08ab7d6d1517..d53355b011f5 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -446,7 +446,8 @@ static void rate_fixup_ratelist(struct ieee80211_vif *vif,
446 * 446 *
447 * XXX: Should this check all retry rates? 447 * XXX: Should this check all retry rates?
448 */ 448 */
449 if (!(rates[0].flags & IEEE80211_TX_RC_MCS)) { 449 if (!(rates[0].flags &
450 (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))) {
450 u32 basic_rates = vif->bss_conf.basic_rates; 451 u32 basic_rates = vif->bss_conf.basic_rates;
451 s8 baserate = basic_rates ? ffs(basic_rates) - 1 : 0; 452 s8 baserate = basic_rates ? ffs(basic_rates) - 1 : 0;
452 453
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 18babe302832..38652f09feaf 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -37,13 +37,35 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
37 struct rate_control_ref *ref = local->rate_ctrl; 37 struct rate_control_ref *ref = local->rate_ctrl;
38 struct ieee80211_sta *ista = &sta->sta; 38 struct ieee80211_sta *ista = &sta->sta;
39 void *priv_sta = sta->rate_ctrl_priv; 39 void *priv_sta = sta->rate_ctrl_priv;
40 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
40 41
41 if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) 42 if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
42 return; 43 return;
43 44
44 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb); 45 if (ref->ops->tx_status)
46 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
47 else
48 ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
45} 49}
46 50
51static inline void
52rate_control_tx_status_noskb(struct ieee80211_local *local,
53 struct ieee80211_supported_band *sband,
54 struct sta_info *sta,
55 struct ieee80211_tx_info *info)
56{
57 struct rate_control_ref *ref = local->rate_ctrl;
58 struct ieee80211_sta *ista = &sta->sta;
59 void *priv_sta = sta->rate_ctrl_priv;
60
61 if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
62 return;
63
64 if (WARN_ON_ONCE(!ref->ops->tx_status_noskb))
65 return;
66
67 ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
68}
47 69
48static inline void rate_control_rate_init(struct sta_info *sta) 70static inline void rate_control_rate_init(struct sta_info *sta)
49{ 71{
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index c2b91bf47f6d..d51f6b1c549b 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -223,11 +223,10 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
223static void 223static void
224minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, 224minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
225 struct ieee80211_sta *sta, void *priv_sta, 225 struct ieee80211_sta *sta, void *priv_sta,
226 struct sk_buff *skb) 226 struct ieee80211_tx_info *info)
227{ 227{
228 struct minstrel_priv *mp = priv; 228 struct minstrel_priv *mp = priv;
229 struct minstrel_sta_info *mi = priv_sta; 229 struct minstrel_sta_info *mi = priv_sta;
230 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
231 struct ieee80211_tx_rate *ar = info->status.rates; 230 struct ieee80211_tx_rate *ar = info->status.rates;
232 int i, ndx; 231 int i, ndx;
233 int success; 232 int success;
@@ -674,7 +673,7 @@ static u32 minstrel_get_expected_throughput(void *priv_sta)
674 673
675const struct rate_control_ops mac80211_minstrel = { 674const struct rate_control_ops mac80211_minstrel = {
676 .name = "minstrel", 675 .name = "minstrel",
677 .tx_status = minstrel_tx_status, 676 .tx_status_noskb = minstrel_tx_status,
678 .get_rate = minstrel_get_rate, 677 .get_rate = minstrel_get_rate,
679 .rate_init = minstrel_rate_init, 678 .rate_init = minstrel_rate_init,
680 .alloc = minstrel_alloc, 679 .alloc = minstrel_alloc,
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 62ff7cfb2723..b52996aca4f1 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -709,11 +709,10 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb)
709static void 709static void
710minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, 710minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
711 struct ieee80211_sta *sta, void *priv_sta, 711 struct ieee80211_sta *sta, void *priv_sta,
712 struct sk_buff *skb) 712 struct ieee80211_tx_info *info)
713{ 713{
714 struct minstrel_ht_sta_priv *msp = priv_sta; 714 struct minstrel_ht_sta_priv *msp = priv_sta;
715 struct minstrel_ht_sta *mi = &msp->ht; 715 struct minstrel_ht_sta *mi = &msp->ht;
716 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
717 struct ieee80211_tx_rate *ar = info->status.rates; 716 struct ieee80211_tx_rate *ar = info->status.rates;
718 struct minstrel_rate_stats *rate, *rate2; 717 struct minstrel_rate_stats *rate, *rate2;
719 struct minstrel_priv *mp = priv; 718 struct minstrel_priv *mp = priv;
@@ -721,7 +720,8 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
721 int i; 720 int i;
722 721
723 if (!msp->is_ht) 722 if (!msp->is_ht)
724 return mac80211_minstrel.tx_status(priv, sband, sta, &msp->legacy, skb); 723 return mac80211_minstrel.tx_status_noskb(priv, sband, sta,
724 &msp->legacy, info);
725 725
726 /* This packet was aggregated but doesn't carry status info */ 726 /* This packet was aggregated but doesn't carry status info */
727 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && 727 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
@@ -782,9 +782,6 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
782 if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { 782 if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) {
783 update = true; 783 update = true;
784 minstrel_ht_update_stats(mp, mi); 784 minstrel_ht_update_stats(mp, mi);
785 if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
786 mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP)
787 minstrel_aggr_check(sta, skb);
788 } 785 }
789 786
790 if (update) 787 if (update)
@@ -1026,6 +1023,10 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
1026 if (!msp->is_ht) 1023 if (!msp->is_ht)
1027 return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc); 1024 return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
1028 1025
1026 if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
1027 mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP)
1028 minstrel_aggr_check(sta, txrc->skb);
1029
1029 info->flags |= mi->tx_flags; 1030 info->flags |= mi->tx_flags;
1030 minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble); 1031 minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble);
1031 1032
@@ -1342,7 +1343,7 @@ static u32 minstrel_ht_get_expected_throughput(void *priv_sta)
1342 1343
1343static const struct rate_control_ops mac80211_minstrel_ht = { 1344static const struct rate_control_ops mac80211_minstrel_ht = {
1344 .name = "minstrel_ht", 1345 .name = "minstrel_ht",
1345 .tx_status = minstrel_ht_tx_status, 1346 .tx_status_noskb = minstrel_ht_tx_status,
1346 .get_rate = minstrel_ht_get_rate, 1347 .get_rate = minstrel_ht_get_rate,
1347 .rate_init = minstrel_ht_rate_init, 1348 .rate_init = minstrel_ht_rate_init,
1348 .rate_update = minstrel_ht_rate_update, 1349 .rate_update = minstrel_ht_rate_update,
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 71de2d3866cc..bb146f377ee4 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -592,10 +592,9 @@ static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local,
592#define STA_LOST_TDLS_PKT_THRESHOLD 10 592#define STA_LOST_TDLS_PKT_THRESHOLD 10
593#define STA_LOST_TDLS_PKT_TIME (10*HZ) /* 10secs since last ACK */ 593#define STA_LOST_TDLS_PKT_TIME (10*HZ) /* 10secs since last ACK */
594 594
595static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb) 595static void ieee80211_lost_packet(struct sta_info *sta,
596 struct ieee80211_tx_info *info)
596{ 597{
597 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
598
599 /* This packet was aggregated but doesn't carry status info */ 598 /* This packet was aggregated but doesn't carry status info */
600 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && 599 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
601 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 600 !(info->flags & IEEE80211_TX_STAT_AMPDU))
@@ -622,24 +621,13 @@ static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
622 sta->lost_packets = 0; 621 sta->lost_packets = 0;
623} 622}
624 623
625void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) 624static int ieee80211_tx_get_rates(struct ieee80211_hw *hw,
625 struct ieee80211_tx_info *info,
626 int *retry_count)
626{ 627{
627 struct sk_buff *skb2;
628 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
629 struct ieee80211_local *local = hw_to_local(hw);
630 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
631 __le16 fc;
632 struct ieee80211_supported_band *sband;
633 struct ieee80211_sub_if_data *sdata;
634 struct net_device *prev_dev = NULL;
635 struct sta_info *sta, *tmp;
636 int retry_count = -1, i;
637 int rates_idx = -1; 628 int rates_idx = -1;
638 bool send_to_cooked; 629 int count = -1;
639 bool acked; 630 int i;
640 struct ieee80211_bar *bar;
641 int rtap_len;
642 int shift = 0;
643 631
644 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 632 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
645 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && 633 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
@@ -657,12 +645,91 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
657 break; 645 break;
658 } 646 }
659 647
660 retry_count += info->status.rates[i].count; 648 count += info->status.rates[i].count;
661 } 649 }
662 rates_idx = i - 1; 650 rates_idx = i - 1;
663 651
664 if (retry_count < 0) 652 if (count < 0)
665 retry_count = 0; 653 count = 0;
654
655 *retry_count = count;
656 return rates_idx;
657}
658
659void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
660 struct ieee80211_sta *pubsta,
661 struct ieee80211_tx_info *info)
662{
663 struct ieee80211_local *local = hw_to_local(hw);
664 struct ieee80211_supported_band *sband;
665 int retry_count;
666 int rates_idx;
667 bool acked;
668
669 rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
670
671 sband = hw->wiphy->bands[info->band];
672
673 acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
674 if (pubsta) {
675 struct sta_info *sta;
676
677 sta = container_of(pubsta, struct sta_info, sta);
678
679 if (!acked)
680 sta->tx_retry_failed++;
681 sta->tx_retry_count += retry_count;
682
683 if (acked) {
684 sta->last_rx = jiffies;
685
686 if (sta->lost_packets)
687 sta->lost_packets = 0;
688
689 /* Track when last TDLS packet was ACKed */
690 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
691 sta->last_tdls_pkt_time = jiffies;
692 } else {
693 ieee80211_lost_packet(sta, info);
694 }
695
696 rate_control_tx_status_noskb(local, sband, sta, info);
697 }
698
699 if (acked) {
700 local->dot11TransmittedFrameCount++;
701 if (!pubsta)
702 local->dot11MulticastTransmittedFrameCount++;
703 if (retry_count > 0)
704 local->dot11RetryCount++;
705 if (retry_count > 1)
706 local->dot11MultipleRetryCount++;
707 } else {
708 local->dot11FailedCount++;
709 }
710}
711EXPORT_SYMBOL(ieee80211_tx_status_noskb);
712
713void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
714{
715 struct sk_buff *skb2;
716 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
717 struct ieee80211_local *local = hw_to_local(hw);
718 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
719 __le16 fc;
720 struct ieee80211_supported_band *sband;
721 struct ieee80211_sub_if_data *sdata;
722 struct net_device *prev_dev = NULL;
723 struct sta_info *sta, *tmp;
724 int retry_count;
725 int rates_idx;
726 bool send_to_cooked;
727 bool acked;
728 struct ieee80211_bar *bar;
729 int rtap_len;
730 int shift = 0;
731
732 rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
666 733
667 rcu_read_lock(); 734 rcu_read_lock();
668 735
@@ -767,7 +834,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
767 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) 834 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
768 sta->last_tdls_pkt_time = jiffies; 835 sta->last_tdls_pkt_time = jiffies;
769 } else { 836 } else {
770 ieee80211_lost_packet(sta, skb); 837 ieee80211_lost_packet(sta, info);
771 } 838 }
772 } 839 }
773 840
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 85ccfbe863db..8e461a02c6a8 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1829,6 +1829,12 @@ TRACE_EVENT(api_cqm_rssi_notify,
1829 ) 1829 )
1830); 1830);
1831 1831
1832DEFINE_EVENT(local_sdata_evt, api_cqm_beacon_loss_notify,
1833 TP_PROTO(struct ieee80211_local *local,
1834 struct ieee80211_sub_if_data *sdata),
1835 TP_ARGS(local, sdata)
1836);
1837
1832TRACE_EVENT(api_scan_completed, 1838TRACE_EVENT(api_scan_completed,
1833 TP_PROTO(struct ieee80211_local *local, bool aborted), 1839 TP_PROTO(struct ieee80211_local *local, bool aborted),
1834 1840
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 66ddbbeccd20..058686a721a1 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -60,7 +60,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
60 rcu_read_unlock(); 60 rcu_read_unlock();
61 61
62 /* assume HW handles this */ 62 /* assume HW handles this */
63 if (tx->rate.flags & IEEE80211_TX_RC_MCS) 63 if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))
64 return 0; 64 return 0;
65 65
66 /* uh huh? */ 66 /* uh huh? */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index bb9664cb8831..974ebe70f5b0 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1339,6 +1339,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
1339 int ext_rates_len; 1339 int ext_rates_len;
1340 int shift; 1340 int shift;
1341 u32 rate_flags; 1341 u32 rate_flags;
1342 bool have_80mhz = false;
1342 1343
1343 *offset = 0; 1344 *offset = 0;
1344 1345
@@ -1467,7 +1468,15 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
1467 *offset = noffset; 1468 *offset = noffset;
1468 } 1469 }
1469 1470
1470 if (sband->vht_cap.vht_supported) { 1471 /* Check if any channel in this sband supports at least 80 MHz */
1472 for (i = 0; i < sband->n_channels; i++) {
1473 if (!(sband->channels[i].flags & IEEE80211_CHAN_NO_80MHZ)) {
1474 have_80mhz = true;
1475 break;
1476 }
1477 }
1478
1479 if (sband->vht_cap.vht_supported && have_80mhz) {
1471 if (end - pos < 2 + sizeof(struct ieee80211_vht_cap)) 1480 if (end - pos < 2 + sizeof(struct ieee80211_vht_cap))
1472 goto out_err; 1481 goto out_err;
1473 pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap, 1482 pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap,