diff options
author | Kalle Valo <kvalo@codeaurora.org> | 2015-01-22 07:49:44 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-01-22 07:49:44 -0500 |
commit | 6b03e32d575917d048875a182bd2dd8924036000 (patch) | |
tree | 634b311d02423f2c1138e06be53d1842902bc28b | |
parent | bc48a51c2a29e231256c2f96daf80c2b7a45f390 (diff) | |
parent | c1e140bf79d817d4a7aa9932eb98b0359c87af33 (diff) |
Merge commit 'c1e140bf79d817d4a7aa9932eb98b0359c87af33' from mac80211-next
Patch "ath9k: Fix no-ack frame status" needs these mac80211 patches:
commit 5cf16616e152dd5c274a65954c77f64892d025a8
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Date: Wed Dec 10 21:26:11 2014 +0530
mac80211: Fix accounting of multicast frames
commit 6b127c71fbdd3daacfd8b9f80b8e6ebfb70a889e
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Date: Wed Dec 10 21:26:10 2014 +0530
mac80211: Move IEEE80211_TX_CTL_PS_RESPONSE
Conflicts:
drivers/net/wireless/ath/wil6210/cfg80211.c
drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
73 files changed, 1750 insertions, 831 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index d9b9416c989f..49b8b8907f36 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl | |||
@@ -113,7 +113,6 @@ | |||
113 | !Finclude/net/cfg80211.h cfg80211_beacon_data | 113 | !Finclude/net/cfg80211.h cfg80211_beacon_data |
114 | !Finclude/net/cfg80211.h cfg80211_ap_settings | 114 | !Finclude/net/cfg80211.h cfg80211_ap_settings |
115 | !Finclude/net/cfg80211.h station_parameters | 115 | !Finclude/net/cfg80211.h station_parameters |
116 | !Finclude/net/cfg80211.h station_info_flags | ||
117 | !Finclude/net/cfg80211.h rate_info_flags | 116 | !Finclude/net/cfg80211.h rate_info_flags |
118 | !Finclude/net/cfg80211.h rate_info | 117 | !Finclude/net/cfg80211.h rate_info |
119 | !Finclude/net/cfg80211.h station_info | 118 | !Finclude/net/cfg80211.h station_info |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4df73da11adc..cdb815e833b5 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -3206,6 +3206,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
3206 | 3206 | ||
3207 | retain_initrd [RAM] Keep initrd memory after extraction | 3207 | retain_initrd [RAM] Keep initrd memory after extraction |
3208 | 3208 | ||
3209 | rfkill.default_state= | ||
3210 | 0 "airplane mode". All wifi, bluetooth, wimax, gps, fm, | ||
3211 | etc. communication is blocked by default. | ||
3212 | 1 Unblocked. | ||
3213 | |||
3214 | rfkill.master_switch_mode= | ||
3215 | 0 The "airplane mode" button does nothing. | ||
3216 | 1 The "airplane mode" button toggles between everything | ||
3217 | blocked and the previous configuration. | ||
3218 | 2 The "airplane mode" button toggles between everything | ||
3219 | blocked and everything unblocked. | ||
3220 | |||
3209 | rhash_entries= [KNL,NET] | 3221 | rhash_entries= [KNL,NET] |
3210 | Set number of hash buckets for route cache | 3222 | Set number of hash buckets for route cache |
3211 | 3223 | ||
diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt index 427e89712f4a..2ee6ef9a6554 100644 --- a/Documentation/rfkill.txt +++ b/Documentation/rfkill.txt | |||
@@ -25,6 +25,9 @@ whether they can be changed or not: | |||
25 | - soft block: writable radio block (need not be readable) that is set by | 25 | - soft block: writable radio block (need not be readable) that is set by |
26 | the system software. | 26 | the system software. |
27 | 27 | ||
28 | The rfkill subsystem has two parameters, rfkill.default_state and | ||
29 | rfkill.master_switch_mode, which are documented in kernel-parameters.txt. | ||
30 | |||
28 | 31 | ||
29 | 2. Implementation details | 32 | 2. Implementation details |
30 | 33 | ||
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 5085f558d010..08f293411bf0 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -2948,6 +2948,8 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2948 | int bit; | 2948 | int bit; |
2949 | u32 vdev_param; | 2949 | u32 vdev_param; |
2950 | 2950 | ||
2951 | vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; | ||
2952 | |||
2951 | mutex_lock(&ar->conf_mutex); | 2953 | mutex_lock(&ar->conf_mutex); |
2952 | 2954 | ||
2953 | memset(arvif, 0, sizeof(*arvif)); | 2955 | memset(arvif, 0, sizeof(*arvif)); |
@@ -5102,7 +5104,6 @@ int ath10k_mac_register(struct ath10k *ar) | |||
5102 | ar->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 5104 | ar->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
5103 | IEEE80211_HW_SUPPORTS_PS | | 5105 | IEEE80211_HW_SUPPORTS_PS | |
5104 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | | 5106 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | |
5105 | IEEE80211_HW_SUPPORTS_UAPSD | | ||
5106 | IEEE80211_HW_MFP_CAPABLE | | 5107 | IEEE80211_HW_MFP_CAPABLE | |
5107 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 5108 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
5108 | IEEE80211_HW_HAS_RATE_CONTROL | | 5109 | IEEE80211_HW_HAS_RATE_CONTROL | |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index ac742905331b..23eca8bc85d1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -1650,11 +1650,11 @@ void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb) | |||
1650 | rx_clear_count -= ar->survey_last_rx_clear_count; | 1650 | rx_clear_count -= ar->survey_last_rx_clear_count; |
1651 | 1651 | ||
1652 | survey = &ar->survey[idx]; | 1652 | survey = &ar->survey[idx]; |
1653 | survey->channel_time = WMI_CHAN_INFO_MSEC(cycle_count); | 1653 | survey->time = WMI_CHAN_INFO_MSEC(cycle_count); |
1654 | survey->channel_time_rx = WMI_CHAN_INFO_MSEC(rx_clear_count); | 1654 | survey->time_rx = WMI_CHAN_INFO_MSEC(rx_clear_count); |
1655 | survey->noise = noise_floor; | 1655 | survey->noise = noise_floor; |
1656 | survey->filled = SURVEY_INFO_CHANNEL_TIME | | 1656 | survey->filled = SURVEY_INFO_TIME | |
1657 | SURVEY_INFO_CHANNEL_TIME_RX | | 1657 | SURVEY_INFO_TIME_RX | |
1658 | SURVEY_INFO_NOISE_DBM; | 1658 | SURVEY_INFO_NOISE_DBM; |
1659 | } | 1659 | } |
1660 | 1660 | ||
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 19eab2a69ad5..3b4a6463d87a 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -672,10 +672,10 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) | |||
672 | spin_lock_bh(&common->cc_lock); | 672 | spin_lock_bh(&common->cc_lock); |
673 | ath_hw_cycle_counters_update(common); | 673 | ath_hw_cycle_counters_update(common); |
674 | if (cc->cycles > 0) { | 674 | if (cc->cycles > 0) { |
675 | ah->survey.channel_time += cc->cycles / div; | 675 | ah->survey.time += cc->cycles / div; |
676 | ah->survey.channel_time_busy += cc->rx_busy / div; | 676 | ah->survey.time_busy += cc->rx_busy / div; |
677 | ah->survey.channel_time_rx += cc->rx_frame / div; | 677 | ah->survey.time_rx += cc->rx_frame / div; |
678 | ah->survey.channel_time_tx += cc->tx_frame / div; | 678 | ah->survey.time_tx += cc->tx_frame / div; |
679 | } | 679 | } |
680 | memset(cc, 0, sizeof(*cc)); | 680 | memset(cc, 0, sizeof(*cc)); |
681 | spin_unlock_bh(&common->cc_lock); | 681 | spin_unlock_bh(&common->cc_lock); |
@@ -686,10 +686,10 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) | |||
686 | survey->noise = ah->ah_noise_floor; | 686 | survey->noise = ah->ah_noise_floor; |
687 | survey->filled = SURVEY_INFO_NOISE_DBM | | 687 | survey->filled = SURVEY_INFO_NOISE_DBM | |
688 | SURVEY_INFO_IN_USE | | 688 | SURVEY_INFO_IN_USE | |
689 | SURVEY_INFO_CHANNEL_TIME | | 689 | SURVEY_INFO_TIME | |
690 | SURVEY_INFO_CHANNEL_TIME_BUSY | | 690 | SURVEY_INFO_TIME_BUSY | |
691 | SURVEY_INFO_CHANNEL_TIME_RX | | 691 | SURVEY_INFO_TIME_RX | |
692 | SURVEY_INFO_CHANNEL_TIME_TX; | 692 | SURVEY_INFO_TIME_TX; |
693 | 693 | ||
694 | return 0; | 694 | return 0; |
695 | } | 695 | } |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 7a5337877a0c..85da63a67faf 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -1799,20 +1799,20 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1799 | 1799 | ||
1800 | if (vif->target_stats.rx_byte) { | 1800 | if (vif->target_stats.rx_byte) { |
1801 | sinfo->rx_bytes = vif->target_stats.rx_byte; | 1801 | sinfo->rx_bytes = vif->target_stats.rx_byte; |
1802 | sinfo->filled |= STATION_INFO_RX_BYTES64; | 1802 | sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES64); |
1803 | sinfo->rx_packets = vif->target_stats.rx_pkt; | 1803 | sinfo->rx_packets = vif->target_stats.rx_pkt; |
1804 | sinfo->filled |= STATION_INFO_RX_PACKETS; | 1804 | sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); |
1805 | } | 1805 | } |
1806 | 1806 | ||
1807 | if (vif->target_stats.tx_byte) { | 1807 | if (vif->target_stats.tx_byte) { |
1808 | sinfo->tx_bytes = vif->target_stats.tx_byte; | 1808 | sinfo->tx_bytes = vif->target_stats.tx_byte; |
1809 | sinfo->filled |= STATION_INFO_TX_BYTES64; | 1809 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES64); |
1810 | sinfo->tx_packets = vif->target_stats.tx_pkt; | 1810 | sinfo->tx_packets = vif->target_stats.tx_pkt; |
1811 | sinfo->filled |= STATION_INFO_TX_PACKETS; | 1811 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); |
1812 | } | 1812 | } |
1813 | 1813 | ||
1814 | sinfo->signal = vif->target_stats.cs_rssi; | 1814 | sinfo->signal = vif->target_stats.cs_rssi; |
1815 | sinfo->filled |= STATION_INFO_SIGNAL; | 1815 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); |
1816 | 1816 | ||
1817 | rate = vif->target_stats.tx_ucast_rate; | 1817 | rate = vif->target_stats.tx_ucast_rate; |
1818 | 1818 | ||
@@ -1827,6 +1827,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1827 | } | 1827 | } |
1828 | 1828 | ||
1829 | sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; | 1829 | sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; |
1830 | sinfo->txrate.bw = RATE_INFO_BW_20; | ||
1830 | } else if (is_rate_ht40(rate, &mcs, &sgi)) { | 1831 | } else if (is_rate_ht40(rate, &mcs, &sgi)) { |
1831 | if (sgi) { | 1832 | if (sgi) { |
1832 | sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; | 1833 | sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; |
@@ -1835,7 +1836,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1835 | sinfo->txrate.mcs = mcs; | 1836 | sinfo->txrate.mcs = mcs; |
1836 | } | 1837 | } |
1837 | 1838 | ||
1838 | sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | 1839 | sinfo->txrate.bw = RATE_INFO_BW_40; |
1839 | sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; | 1840 | sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; |
1840 | } else { | 1841 | } else { |
1841 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, | 1842 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, |
@@ -1844,12 +1845,12 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1844 | return 0; | 1845 | return 0; |
1845 | } | 1846 | } |
1846 | 1847 | ||
1847 | sinfo->filled |= STATION_INFO_TX_BITRATE; | 1848 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); |
1848 | 1849 | ||
1849 | if (test_bit(CONNECTED, &vif->flags) && | 1850 | if (test_bit(CONNECTED, &vif->flags) && |
1850 | test_bit(DTIM_PERIOD_AVAIL, &vif->flags) && | 1851 | test_bit(DTIM_PERIOD_AVAIL, &vif->flags) && |
1851 | vif->nw_type == INFRA_NETWORK) { | 1852 | vif->nw_type == INFRA_NETWORK) { |
1852 | sinfo->filled |= STATION_INFO_BSS_PARAM; | 1853 | sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); |
1853 | sinfo->bss_param.flags = 0; | 1854 | sinfo->bss_param.flags = 0; |
1854 | sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period; | 1855 | sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period; |
1855 | sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int; | 1856 | sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int; |
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 933aef025698..b42ba46b5030 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -488,7 +488,6 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, | |||
488 | 488 | ||
489 | sinfo.assoc_req_ies = ies; | 489 | sinfo.assoc_req_ies = ies; |
490 | sinfo.assoc_req_ies_len = ies_len; | 490 | sinfo.assoc_req_ies_len = ies_len; |
491 | sinfo.filled |= STATION_INFO_ASSOC_REQ_IES; | ||
492 | 491 | ||
493 | cfg80211_new_sta(vif->ndev, mac_addr, &sinfo, GFP_KERNEL); | 492 | cfg80211_new_sta(vif->ndev, mac_addr, &sinfo, GFP_KERNEL); |
494 | 493 | ||
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index b829263e3d0a..90631d768a60 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -516,14 +516,14 @@ int ath_update_survey_stats(struct ath_softc *sc) | |||
516 | ath_hw_cycle_counters_update(common); | 516 | ath_hw_cycle_counters_update(common); |
517 | 517 | ||
518 | if (cc->cycles > 0) { | 518 | if (cc->cycles > 0) { |
519 | survey->filled |= SURVEY_INFO_CHANNEL_TIME | | 519 | survey->filled |= SURVEY_INFO_TIME | |
520 | SURVEY_INFO_CHANNEL_TIME_BUSY | | 520 | SURVEY_INFO_TIME_BUSY | |
521 | SURVEY_INFO_CHANNEL_TIME_RX | | 521 | SURVEY_INFO_TIME_RX | |
522 | SURVEY_INFO_CHANNEL_TIME_TX; | 522 | SURVEY_INFO_TIME_TX; |
523 | survey->channel_time += cc->cycles / div; | 523 | survey->time += cc->cycles / div; |
524 | survey->channel_time_busy += cc->rx_busy / div; | 524 | survey->time_busy += cc->rx_busy / div; |
525 | survey->channel_time_rx += cc->rx_frame / div; | 525 | survey->time_rx += cc->rx_frame / div; |
526 | survey->channel_time_tx += cc->tx_frame / div; | 526 | survey->time_tx += cc->tx_frame / div; |
527 | } | 527 | } |
528 | 528 | ||
529 | if (cc->cycles < div) | 529 | if (cc->cycles < div) |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 9c332f9c3fc5..1176d919569e 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2303,7 +2303,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2303 | struct ath_txq *txq = txctl->txq; | 2303 | struct ath_txq *txq = txctl->txq; |
2304 | struct ath_atx_tid *tid = NULL; | 2304 | struct ath_atx_tid *tid = NULL; |
2305 | struct ath_buf *bf; | 2305 | struct ath_buf *bf; |
2306 | bool queue, skip_uapsd = false; | 2306 | bool queue, skip_uapsd = false, ps_resp; |
2307 | int q, ret; | 2307 | int q, ret; |
2308 | 2308 | ||
2309 | if (vif) | 2309 | if (vif) |
@@ -2312,6 +2312,8 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2312 | if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) | 2312 | if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) |
2313 | txctl->force_channel = true; | 2313 | txctl->force_channel = true; |
2314 | 2314 | ||
2315 | ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE); | ||
2316 | |||
2315 | ret = ath_tx_prepare(hw, skb, txctl); | 2317 | ret = ath_tx_prepare(hw, skb, txctl); |
2316 | if (ret) | 2318 | if (ret) |
2317 | return ret; | 2319 | return ret; |
@@ -2354,7 +2356,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2354 | if (txctl->an && queue) | 2356 | if (txctl->an && queue) |
2355 | tid = ath_get_skb_tid(sc, txctl->an, skb); | 2357 | tid = ath_get_skb_tid(sc, txctl->an, skb); |
2356 | 2358 | ||
2357 | if (!skip_uapsd && (info->flags & IEEE80211_TX_CTL_PS_RESPONSE)) { | 2359 | if (!skip_uapsd && ps_resp) { |
2358 | ath_txq_unlock(sc, txq); | 2360 | ath_txq_unlock(sc, txq); |
2359 | txq = sc->tx.uapsdq; | 2361 | txq = sc->tx.uapsdq; |
2360 | ath_txq_lock(sc, txq); | 2362 | ath_txq_lock(sc, txq); |
diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c index 39a63874b275..f2b4f537e4c1 100644 --- a/drivers/net/wireless/ath/carl9170/cmd.c +++ b/drivers/net/wireless/ath/carl9170/cmd.c | |||
@@ -188,12 +188,12 @@ int carl9170_collect_tally(struct ar9170 *ar) | |||
188 | 188 | ||
189 | if (ar->channel) { | 189 | if (ar->channel) { |
190 | info = &ar->survey[ar->channel->hw_value]; | 190 | info = &ar->survey[ar->channel->hw_value]; |
191 | info->channel_time = ar->tally.active; | 191 | info->time = ar->tally.active; |
192 | info->channel_time_busy = ar->tally.cca; | 192 | info->time_busy = ar->tally.cca; |
193 | info->channel_time_tx = ar->tally.tx_time; | 193 | info->time_tx = ar->tally.tx_time; |
194 | do_div(info->channel_time, 1000); | 194 | do_div(info->time, 1000); |
195 | do_div(info->channel_time_busy, 1000); | 195 | do_div(info->time_busy, 1000); |
196 | do_div(info->channel_time_tx, 1000); | 196 | do_div(info->time_tx, 1000); |
197 | } | 197 | } |
198 | } | 198 | } |
199 | return 0; | 199 | return 0; |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index ef5b6dc7b7f1..f1455a04cb62 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1690,9 +1690,9 @@ found: | |||
1690 | survey->filled |= SURVEY_INFO_IN_USE; | 1690 | survey->filled |= SURVEY_INFO_IN_USE; |
1691 | 1691 | ||
1692 | if (ar->fw.hw_counters) { | 1692 | if (ar->fw.hw_counters) { |
1693 | survey->filled |= SURVEY_INFO_CHANNEL_TIME | | 1693 | survey->filled |= SURVEY_INFO_TIME | |
1694 | SURVEY_INFO_CHANNEL_TIME_BUSY | | 1694 | SURVEY_INFO_TIME_BUSY | |
1695 | SURVEY_INFO_CHANNEL_TIME_TX; | 1695 | SURVEY_INFO_TIME_TX; |
1696 | } | 1696 | } |
1697 | 1697 | ||
1698 | return 0; | 1698 | return 0; |
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 5c79f1d62103..bd013fdb86dc 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c | |||
@@ -142,14 +142,14 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, | |||
142 | 142 | ||
143 | sinfo->generation = wil->sinfo_gen; | 143 | sinfo->generation = wil->sinfo_gen; |
144 | 144 | ||
145 | sinfo->filled = STATION_INFO_RX_BYTES | | 145 | sinfo->filled = BIT(NL80211_STA_INFO_RX_BYTES) | |
146 | STATION_INFO_TX_BYTES | | 146 | BIT(NL80211_STA_INFO_TX_BYTES) | |
147 | STATION_INFO_RX_PACKETS | | 147 | BIT(NL80211_STA_INFO_RX_PACKETS) | |
148 | STATION_INFO_TX_PACKETS | | 148 | BIT(NL80211_STA_INFO_TX_PACKETS) | |
149 | STATION_INFO_RX_BITRATE | | 149 | BIT(NL80211_STA_INFO_RX_BITRATE) | |
150 | STATION_INFO_TX_BITRATE | | 150 | BIT(NL80211_STA_INFO_TX_BITRATE) | |
151 | STATION_INFO_RX_DROP_MISC | | 151 | BIT(NL80211_STA_INFO_RX_DROP_MISC) | |
152 | STATION_INFO_TX_FAILED; | 152 | BIT(NL80211_STA_INFO_TX_FAILED); |
153 | 153 | ||
154 | sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G; | 154 | sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G; |
155 | sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs); | 155 | sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs); |
@@ -163,7 +163,7 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, | |||
163 | sinfo->tx_failed = stats->tx_errors; | 163 | sinfo->tx_failed = stats->tx_errors; |
164 | 164 | ||
165 | if (test_bit(wil_status_fwconnected, wil->status)) { | 165 | if (test_bit(wil_status_fwconnected, wil->status)) { |
166 | sinfo->filled |= STATION_INFO_SIGNAL; | 166 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); |
167 | sinfo->signal = reply.evt.sqi; | 167 | sinfo->signal = reply.evt.sqi; |
168 | } | 168 | } |
169 | 169 | ||
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index f3524a15b1ad..b2b0fe1faa96 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c | |||
@@ -462,7 +462,6 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) | |||
462 | if (assoc_req_ie) { | 462 | if (assoc_req_ie) { |
463 | sinfo.assoc_req_ies = assoc_req_ie; | 463 | sinfo.assoc_req_ies = assoc_req_ie; |
464 | sinfo.assoc_req_ies_len = assoc_req_ielen; | 464 | sinfo.assoc_req_ies_len = assoc_req_ielen; |
465 | sinfo.filled |= STATION_INFO_ASSOC_REQ_IES; | ||
466 | } | 465 | } |
467 | 466 | ||
468 | cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL); | 467 | cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c index 1783c0350e1f..ebe654312b74 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | |||
@@ -2375,10 +2375,10 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, | |||
2375 | brcmf_err("GET STA INFO failed, %d\n", err); | 2375 | brcmf_err("GET STA INFO failed, %d\n", err); |
2376 | goto done; | 2376 | goto done; |
2377 | } | 2377 | } |
2378 | sinfo->filled = STATION_INFO_INACTIVE_TIME; | 2378 | sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); |
2379 | sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; | 2379 | sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; |
2380 | if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { | 2380 | if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { |
2381 | sinfo->filled |= STATION_INFO_CONNECTED_TIME; | 2381 | sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); |
2382 | sinfo->connected_time = le32_to_cpu(sta_info_le.in); | 2382 | sinfo->connected_time = le32_to_cpu(sta_info_le.in); |
2383 | } | 2383 | } |
2384 | brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n", | 2384 | brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n", |
@@ -2396,7 +2396,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, | |||
2396 | brcmf_err("Could not get rate (%d)\n", err); | 2396 | brcmf_err("Could not get rate (%d)\n", err); |
2397 | goto done; | 2397 | goto done; |
2398 | } else { | 2398 | } else { |
2399 | sinfo->filled |= STATION_INFO_TX_BITRATE; | 2399 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); |
2400 | sinfo->txrate.legacy = rate * 5; | 2400 | sinfo->txrate.legacy = rate * 5; |
2401 | brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2); | 2401 | brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2); |
2402 | } | 2402 | } |
@@ -2411,7 +2411,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, | |||
2411 | goto done; | 2411 | goto done; |
2412 | } else { | 2412 | } else { |
2413 | rssi = le32_to_cpu(scb_val.val); | 2413 | rssi = le32_to_cpu(scb_val.val); |
2414 | sinfo->filled |= STATION_INFO_SIGNAL; | 2414 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); |
2415 | sinfo->signal = rssi; | 2415 | sinfo->signal = rssi; |
2416 | brcmf_dbg(CONN, "RSSI %d dBm\n", rssi); | 2416 | brcmf_dbg(CONN, "RSSI %d dBm\n", rssi); |
2417 | } | 2417 | } |
@@ -2438,7 +2438,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, | |||
2438 | brcmf_dbg(CONN, "DTIM peroid %d\n", | 2438 | brcmf_dbg(CONN, "DTIM peroid %d\n", |
2439 | dtim_period); | 2439 | dtim_period); |
2440 | } | 2440 | } |
2441 | sinfo->filled |= STATION_INFO_BSS_PARAM; | 2441 | sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); |
2442 | } | 2442 | } |
2443 | } else | 2443 | } else |
2444 | err = -EPERM; | 2444 | err = -EPERM; |
@@ -4878,7 +4878,6 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, | |||
4878 | if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) && | 4878 | if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) && |
4879 | (reason == BRCMF_E_STATUS_SUCCESS)) { | 4879 | (reason == BRCMF_E_STATUS_SUCCESS)) { |
4880 | memset(&sinfo, 0, sizeof(sinfo)); | 4880 | memset(&sinfo, 0, sizeof(sinfo)); |
4881 | sinfo.filled = STATION_INFO_ASSOC_REQ_IES; | ||
4882 | if (!data) { | 4881 | if (!data) { |
4883 | brcmf_err("No IEs present in ASSOC/REASSOC_IND"); | 4882 | brcmf_err("No IEs present in ASSOC/REASSOC_IND"); |
4884 | return -EINVAL; | 4883 | return -EINVAL; |
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c index fa965ee9f56b..3689dbbd10bd 100644 --- a/drivers/net/wireless/cw1200/main.c +++ b/drivers/net/wireless/cw1200/main.c | |||
@@ -282,7 +282,6 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr, | |||
282 | IEEE80211_HW_SUPPORTS_PS | | 282 | IEEE80211_HW_SUPPORTS_PS | |
283 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | | 283 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | |
284 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 284 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
285 | IEEE80211_HW_SUPPORTS_UAPSD | | ||
286 | IEEE80211_HW_CONNECTION_MONITOR | | 285 | IEEE80211_HW_CONNECTION_MONITOR | |
287 | IEEE80211_HW_AMPDU_AGGREGATION | | 286 | IEEE80211_HW_AMPDU_AGGREGATION | |
288 | IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | | 287 | IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | |
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c index 5b84664db13b..4a47c7f8a246 100644 --- a/drivers/net/wireless/cw1200/sta.c +++ b/drivers/net/wireless/cw1200/sta.c | |||
@@ -213,6 +213,7 @@ int cw1200_add_interface(struct ieee80211_hw *dev, | |||
213 | /* __le32 auto_calibration_mode = __cpu_to_le32(1); */ | 213 | /* __le32 auto_calibration_mode = __cpu_to_le32(1); */ |
214 | 214 | ||
215 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | | 215 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | |
216 | IEEE80211_VIF_SUPPORTS_UAPSD | | ||
216 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; | 217 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; |
217 | 218 | ||
218 | mutex_lock(&priv->conf_mutex); | 219 | mutex_lock(&priv->conf_mutex); |
@@ -708,7 +709,8 @@ int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, | |||
708 | if (sta) | 709 | if (sta) |
709 | peer_addr = sta->addr; | 710 | peer_addr = sta->addr; |
710 | 711 | ||
711 | key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; | 712 | key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE | |
713 | IEEE80211_KEY_FLAG_RESERVE_TAILROOM; | ||
712 | 714 | ||
713 | switch (key->cipher) { | 715 | switch (key->cipher) { |
714 | case WLAN_CIPHER_SUITE_WEP40: | 716 | case WLAN_CIPHER_SUITE_WEP40: |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 3756c03e752f..aa1ee04b1514 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -327,6 +327,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
327 | hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC | | 327 | hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC | |
328 | IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED; | 328 | IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED; |
329 | hw->rate_control_algorithm = "iwl-mvm-rs"; | 329 | hw->rate_control_algorithm = "iwl-mvm-rs"; |
330 | hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES; | ||
331 | hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; | ||
330 | 332 | ||
331 | /* | 333 | /* |
332 | * Enable 11w if advertised by firmware and software crypto | 334 | * Enable 11w if advertised by firmware and software crypto |
@@ -337,13 +339,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
337 | !iwlwifi_mod_params.sw_crypto) | 339 | !iwlwifi_mod_params.sw_crypto) |
338 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | 340 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; |
339 | 341 | ||
340 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT && | ||
341 | !iwlwifi_mod_params.uapsd_disable) { | ||
342 | hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD; | ||
343 | hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES; | ||
344 | hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; | ||
345 | } | ||
346 | |||
347 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || | 342 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || |
348 | mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { | 343 | mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { |
349 | hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; | 344 | hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; |
@@ -1218,6 +1213,10 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
1218 | mvm->bf_allowed_vif = mvmvif; | 1213 | mvm->bf_allowed_vif = mvmvif; |
1219 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | | 1214 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | |
1220 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; | 1215 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; |
1216 | if (mvm->fw->ucode_capa.flags & | ||
1217 | IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT && | ||
1218 | !iwlwifi_mod_params.uapsd_disable) | ||
1219 | vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; | ||
1221 | } | 1220 | } |
1222 | 1221 | ||
1223 | /* | 1222 | /* |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 34f09ef90bb3..a92985a6ea21 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -1616,10 +1616,10 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1616 | 1616 | ||
1617 | lbs_deb_enter(LBS_DEB_CFG80211); | 1617 | lbs_deb_enter(LBS_DEB_CFG80211); |
1618 | 1618 | ||
1619 | sinfo->filled |= STATION_INFO_TX_BYTES | | 1619 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES) | |
1620 | STATION_INFO_TX_PACKETS | | 1620 | BIT(NL80211_STA_INFO_TX_PACKETS) | |
1621 | STATION_INFO_RX_BYTES | | 1621 | BIT(NL80211_STA_INFO_RX_BYTES) | |
1622 | STATION_INFO_RX_PACKETS; | 1622 | BIT(NL80211_STA_INFO_RX_PACKETS); |
1623 | sinfo->tx_bytes = priv->dev->stats.tx_bytes; | 1623 | sinfo->tx_bytes = priv->dev->stats.tx_bytes; |
1624 | sinfo->tx_packets = priv->dev->stats.tx_packets; | 1624 | sinfo->tx_packets = priv->dev->stats.tx_packets; |
1625 | sinfo->rx_bytes = priv->dev->stats.rx_bytes; | 1625 | sinfo->rx_bytes = priv->dev->stats.rx_bytes; |
@@ -1629,14 +1629,14 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1629 | ret = lbs_get_rssi(priv, &signal, &noise); | 1629 | ret = lbs_get_rssi(priv, &signal, &noise); |
1630 | if (ret == 0) { | 1630 | if (ret == 0) { |
1631 | sinfo->signal = signal; | 1631 | sinfo->signal = signal; |
1632 | sinfo->filled |= STATION_INFO_SIGNAL; | 1632 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); |
1633 | } | 1633 | } |
1634 | 1634 | ||
1635 | /* Convert priv->cur_rate from hw_value to NL80211 value */ | 1635 | /* Convert priv->cur_rate from hw_value to NL80211 value */ |
1636 | for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) { | 1636 | for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) { |
1637 | if (priv->cur_rate == lbs_rates[i].hw_value) { | 1637 | if (priv->cur_rate == lbs_rates[i].hw_value) { |
1638 | sinfo->txrate.legacy = lbs_rates[i].bitrate; | 1638 | sinfo->txrate.legacy = lbs_rates[i].bitrate; |
1639 | sinfo->filled |= STATION_INFO_TX_BITRATE; | 1639 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); |
1640 | break; | 1640 | break; |
1641 | } | 1641 | } |
1642 | } | 1642 | } |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index ef58a8862d91..494e7335aa64 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -625,22 +625,22 @@ static int hwsim_fops_ps_write(void *dat, u64 val) | |||
625 | old_ps = data->ps; | 625 | old_ps = data->ps; |
626 | data->ps = val; | 626 | data->ps = val; |
627 | 627 | ||
628 | local_bh_disable(); | ||
628 | if (val == PS_MANUAL_POLL) { | 629 | if (val == PS_MANUAL_POLL) { |
629 | ieee80211_iterate_active_interfaces(data->hw, | 630 | ieee80211_iterate_active_interfaces_atomic( |
630 | IEEE80211_IFACE_ITER_NORMAL, | 631 | data->hw, IEEE80211_IFACE_ITER_NORMAL, |
631 | hwsim_send_ps_poll, data); | 632 | hwsim_send_ps_poll, data); |
632 | data->ps_poll_pending = true; | 633 | data->ps_poll_pending = true; |
633 | } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { | 634 | } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { |
634 | ieee80211_iterate_active_interfaces(data->hw, | 635 | ieee80211_iterate_active_interfaces_atomic( |
635 | IEEE80211_IFACE_ITER_NORMAL, | 636 | data->hw, IEEE80211_IFACE_ITER_NORMAL, |
636 | hwsim_send_nullfunc_ps, | 637 | hwsim_send_nullfunc_ps, data); |
637 | data); | ||
638 | } else if (old_ps != PS_DISABLED && val == PS_DISABLED) { | 638 | } else if (old_ps != PS_DISABLED && val == PS_DISABLED) { |
639 | ieee80211_iterate_active_interfaces(data->hw, | 639 | ieee80211_iterate_active_interfaces_atomic( |
640 | IEEE80211_IFACE_ITER_NORMAL, | 640 | data->hw, IEEE80211_IFACE_ITER_NORMAL, |
641 | hwsim_send_nullfunc_no_ps, | 641 | hwsim_send_nullfunc_no_ps, data); |
642 | data); | ||
643 | } | 642 | } |
643 | local_bh_enable(); | ||
644 | 644 | ||
645 | return 0; | 645 | return 0; |
646 | } | 646 | } |
@@ -2149,14 +2149,14 @@ static int append_radio_msg(struct sk_buff *skb, int id, | |||
2149 | if (param->regd) { | 2149 | if (param->regd) { |
2150 | int i; | 2150 | int i; |
2151 | 2151 | ||
2152 | for (i = 0; hwsim_world_regdom_custom[i] != param->regd && | 2152 | for (i = 0; i < ARRAY_SIZE(hwsim_world_regdom_custom); i++) { |
2153 | i < ARRAY_SIZE(hwsim_world_regdom_custom); i++) | 2153 | if (hwsim_world_regdom_custom[i] != param->regd) |
2154 | ; | 2154 | continue; |
2155 | 2155 | ||
2156 | if (i < ARRAY_SIZE(hwsim_world_regdom_custom)) { | ||
2157 | ret = nla_put_u32(skb, HWSIM_ATTR_REG_CUSTOM_REG, i); | 2156 | ret = nla_put_u32(skb, HWSIM_ATTR_REG_CUSTOM_REG, i); |
2158 | if (ret < 0) | 2157 | if (ret < 0) |
2159 | return ret; | 2158 | return ret; |
2159 | break; | ||
2160 | } | 2160 | } |
2161 | } | 2161 | } |
2162 | 2162 | ||
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 93ab36fc9f93..b3bf2cd150b7 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -856,16 +856,16 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo, | |||
856 | /* HT or VHT */ | 856 | /* HT or VHT */ |
857 | switch (tx_htinfo & (BIT(3) | BIT(2))) { | 857 | switch (tx_htinfo & (BIT(3) | BIT(2))) { |
858 | case 0: | 858 | case 0: |
859 | /* This will be 20MHz */ | 859 | rate->bw = RATE_INFO_BW_20; |
860 | break; | 860 | break; |
861 | case (BIT(2)): | 861 | case (BIT(2)): |
862 | rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | 862 | rate->bw = RATE_INFO_BW_40; |
863 | break; | 863 | break; |
864 | case (BIT(3)): | 864 | case (BIT(3)): |
865 | rate->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; | 865 | rate->bw = RATE_INFO_BW_80; |
866 | break; | 866 | break; |
867 | case (BIT(3) | BIT(2)): | 867 | case (BIT(3) | BIT(2)): |
868 | rate->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; | 868 | rate->bw = RATE_INFO_BW_160; |
869 | break; | 869 | break; |
870 | } | 870 | } |
871 | 871 | ||
@@ -885,8 +885,9 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo, | |||
885 | if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) { | 885 | if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) { |
886 | rate->mcs = priv->tx_rate; | 886 | rate->mcs = priv->tx_rate; |
887 | rate->flags |= RATE_INFO_FLAGS_MCS; | 887 | rate->flags |= RATE_INFO_FLAGS_MCS; |
888 | rate->bw = RATE_INFO_BW_20; | ||
888 | if (tx_htinfo & BIT(1)) | 889 | if (tx_htinfo & BIT(1)) |
889 | rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | 890 | rate->bw = RATE_INFO_BW_40; |
890 | if (tx_htinfo & BIT(2)) | 891 | if (tx_htinfo & BIT(2)) |
891 | rate->flags |= RATE_INFO_FLAGS_SHORT_GI; | 892 | rate->flags |= RATE_INFO_FLAGS_SHORT_GI; |
892 | } | 893 | } |
@@ -910,10 +911,10 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, | |||
910 | { | 911 | { |
911 | u32 rate; | 912 | u32 rate; |
912 | 913 | ||
913 | sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES | | 914 | sinfo->filled = BIT(NL80211_STA_INFO_RX_BYTES) | BIT(NL80211_STA_INFO_TX_BYTES) | |
914 | STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS | | 915 | BIT(NL80211_STA_INFO_RX_PACKETS) | BIT(NL80211_STA_INFO_TX_PACKETS) | |
915 | STATION_INFO_TX_BITRATE | | 916 | BIT(NL80211_STA_INFO_TX_BITRATE) | |
916 | STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; | 917 | BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_SIGNAL_AVG); |
917 | 918 | ||
918 | /* Get signal information from the firmware */ | 919 | /* Get signal information from the firmware */ |
919 | if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, | 920 | if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, |
@@ -944,7 +945,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, | |||
944 | sinfo->txrate.legacy = rate * 5; | 945 | sinfo->txrate.legacy = rate * 5; |
945 | 946 | ||
946 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 947 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { |
947 | sinfo->filled |= STATION_INFO_BSS_PARAM; | 948 | sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); |
948 | sinfo->bss_param.flags = 0; | 949 | sinfo->bss_param.flags = 0; |
949 | if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & | 950 | if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & |
950 | WLAN_CAPABILITY_SHORT_PREAMBLE) | 951 | WLAN_CAPABILITY_SHORT_PREAMBLE) |
@@ -1037,10 +1038,11 @@ mwifiex_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *dev, | |||
1037 | survey->channel = ieee80211_get_channel(wiphy, | 1038 | survey->channel = ieee80211_get_channel(wiphy, |
1038 | ieee80211_channel_to_frequency(pchan_stats[idx].chan_num, band)); | 1039 | ieee80211_channel_to_frequency(pchan_stats[idx].chan_num, band)); |
1039 | survey->filled = SURVEY_INFO_NOISE_DBM | | 1040 | survey->filled = SURVEY_INFO_NOISE_DBM | |
1040 | SURVEY_INFO_CHANNEL_TIME | SURVEY_INFO_CHANNEL_TIME_BUSY; | 1041 | SURVEY_INFO_TIME | |
1042 | SURVEY_INFO_TIME_BUSY; | ||
1041 | survey->noise = pchan_stats[idx].noise; | 1043 | survey->noise = pchan_stats[idx].noise; |
1042 | survey->channel_time = pchan_stats[idx].cca_scan_dur; | 1044 | survey->time = pchan_stats[idx].cca_scan_dur; |
1043 | survey->channel_time_busy = pchan_stats[idx].cca_busy_dur; | 1045 | survey->time_busy = pchan_stats[idx].cca_busy_dur; |
1044 | 1046 | ||
1045 | return 0; | 1047 | return 0; |
1046 | } | 1048 | } |
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c index f31086cdf937..96ff39722f8f 100644 --- a/drivers/net/wireless/mwifiex/uap_event.c +++ b/drivers/net/wireless/mwifiex/uap_event.c | |||
@@ -68,7 +68,6 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) | |||
68 | len = ETH_ALEN; | 68 | len = ETH_ALEN; |
69 | 69 | ||
70 | if (len != -1) { | 70 | if (len != -1) { |
71 | sinfo.filled = STATION_INFO_ASSOC_REQ_IES; | ||
72 | sinfo.assoc_req_ies = &event->data[len]; | 71 | sinfo.assoc_req_ies = &event->data[len]; |
73 | len = (u8 *)sinfo.assoc_req_ies - | 72 | len = (u8 *)sinfo.assoc_req_ies - |
74 | (u8 *)&event->frame_control; | 73 | (u8 *)&event->frame_control; |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index b8d1e04aa9b9..f9b1218c761a 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -3098,14 +3098,14 @@ static void mwl8k_update_survey(struct mwl8k_priv *priv, | |||
3098 | 3098 | ||
3099 | cca_cnt = ioread32(priv->regs + NOK_CCA_CNT_REG); | 3099 | cca_cnt = ioread32(priv->regs + NOK_CCA_CNT_REG); |
3100 | cca_cnt /= 1000; /* uSecs to mSecs */ | 3100 | cca_cnt /= 1000; /* uSecs to mSecs */ |
3101 | survey->channel_time_busy = (u64) cca_cnt; | 3101 | survey->time_busy = (u64) cca_cnt; |
3102 | 3102 | ||
3103 | rx_rdy = ioread32(priv->regs + BBU_RXRDY_CNT_REG); | 3103 | rx_rdy = ioread32(priv->regs + BBU_RXRDY_CNT_REG); |
3104 | rx_rdy /= 1000; /* uSecs to mSecs */ | 3104 | rx_rdy /= 1000; /* uSecs to mSecs */ |
3105 | survey->channel_time_rx = (u64) rx_rdy; | 3105 | survey->time_rx = (u64) rx_rdy; |
3106 | 3106 | ||
3107 | priv->channel_time = jiffies - priv->channel_time; | 3107 | priv->channel_time = jiffies - priv->channel_time; |
3108 | survey->channel_time = jiffies_to_msecs(priv->channel_time); | 3108 | survey->time = jiffies_to_msecs(priv->channel_time); |
3109 | 3109 | ||
3110 | survey->channel = channel; | 3110 | survey->channel = channel; |
3111 | 3111 | ||
@@ -3115,9 +3115,9 @@ static void mwl8k_update_survey(struct mwl8k_priv *priv, | |||
3115 | survey->noise = nf * -1; | 3115 | survey->noise = nf * -1; |
3116 | 3116 | ||
3117 | survey->filled = SURVEY_INFO_NOISE_DBM | | 3117 | survey->filled = SURVEY_INFO_NOISE_DBM | |
3118 | SURVEY_INFO_CHANNEL_TIME | | 3118 | SURVEY_INFO_TIME | |
3119 | SURVEY_INFO_CHANNEL_TIME_BUSY | | 3119 | SURVEY_INFO_TIME_BUSY | |
3120 | SURVEY_INFO_CHANNEL_TIME_RX; | 3120 | SURVEY_INFO_TIME_RX; |
3121 | } | 3121 | } |
3122 | 3122 | ||
3123 | /* | 3123 | /* |
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 0fe67d2da208..2fe713eda7ad 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c | |||
@@ -196,9 +196,9 @@ static int p54_generate_band(struct ieee80211_hw *dev, | |||
196 | dest->max_power = chan->max_power; | 196 | dest->max_power = chan->max_power; |
197 | priv->survey[*chan_num].channel = &tmp->channels[j]; | 197 | priv->survey[*chan_num].channel = &tmp->channels[j]; |
198 | priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM | | 198 | priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM | |
199 | SURVEY_INFO_CHANNEL_TIME | | 199 | SURVEY_INFO_TIME | |
200 | SURVEY_INFO_CHANNEL_TIME_BUSY | | 200 | SURVEY_INFO_TIME_BUSY | |
201 | SURVEY_INFO_CHANNEL_TIME_TX; | 201 | SURVEY_INFO_TIME_TX; |
202 | dest->hw_value = (*chan_num); | 202 | dest->hw_value = (*chan_num); |
203 | j++; | 203 | j++; |
204 | (*chan_num)++; | 204 | (*chan_num)++; |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 97aeff0edb84..b9250d75d253 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -305,9 +305,9 @@ static void p54_reset_stats(struct p54_common *priv) | |||
305 | struct survey_info *info = &priv->survey[chan->hw_value]; | 305 | struct survey_info *info = &priv->survey[chan->hw_value]; |
306 | 306 | ||
307 | /* only reset channel statistics, don't touch .filled, etc. */ | 307 | /* only reset channel statistics, don't touch .filled, etc. */ |
308 | info->channel_time = 0; | 308 | info->time = 0; |
309 | info->channel_time_busy = 0; | 309 | info->time_busy = 0; |
310 | info->channel_time_tx = 0; | 310 | info->time_tx = 0; |
311 | } | 311 | } |
312 | 312 | ||
313 | priv->update_stats = true; | 313 | priv->update_stats = true; |
@@ -575,6 +575,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, | |||
575 | key->hw_key_idx = 0xff; | 575 | key->hw_key_idx = 0xff; |
576 | goto out_unlock; | 576 | goto out_unlock; |
577 | } | 577 | } |
578 | |||
579 | key->flags |= IEEE80211_KEY_FLAG_RESERVE_TAILROOM; | ||
578 | } else { | 580 | } else { |
579 | slot = key->hw_key_idx; | 581 | slot = key->hw_key_idx; |
580 | 582 | ||
@@ -634,7 +636,7 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx, | |||
634 | 636 | ||
635 | if (in_use) { | 637 | if (in_use) { |
636 | /* test if the reported statistics are valid. */ | 638 | /* test if the reported statistics are valid. */ |
637 | if (survey->channel_time != 0) { | 639 | if (survey->time != 0) { |
638 | survey->filled |= SURVEY_INFO_IN_USE; | 640 | survey->filled |= SURVEY_INFO_IN_USE; |
639 | } else { | 641 | } else { |
640 | /* | 642 | /* |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 153c61539ec8..24e5ff9a9272 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -587,13 +587,13 @@ static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb) | |||
587 | if (chan) { | 587 | if (chan) { |
588 | struct survey_info *survey = &priv->survey[chan->hw_value]; | 588 | struct survey_info *survey = &priv->survey[chan->hw_value]; |
589 | survey->noise = clamp(priv->noise, -128, 127); | 589 | survey->noise = clamp(priv->noise, -128, 127); |
590 | survey->channel_time = priv->survey_raw.active; | 590 | survey->time = priv->survey_raw.active; |
591 | survey->channel_time_tx = priv->survey_raw.tx; | 591 | survey->time_tx = priv->survey_raw.tx; |
592 | survey->channel_time_busy = priv->survey_raw.tx + | 592 | survey->time_busy = priv->survey_raw.tx + |
593 | priv->survey_raw.cca; | 593 | priv->survey_raw.cca; |
594 | do_div(survey->channel_time, 1024); | 594 | do_div(survey->time, 1024); |
595 | do_div(survey->channel_time_tx, 1024); | 595 | do_div(survey->time_tx, 1024); |
596 | do_div(survey->channel_time_busy, 1024); | 596 | do_div(survey->time_busy, 1024); |
597 | } | 597 | } |
598 | 598 | ||
599 | tmp = p54_find_and_unlink_skb(priv, hdr->req_id); | 599 | tmp = p54_find_and_unlink_skb(priv, hdr->req_id); |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 1a4facd1fbf3..60d44ce9c017 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -2478,7 +2478,7 @@ static void rndis_fill_station_info(struct usbnet *usbdev, | |||
2478 | ret = rndis_query_oid(usbdev, RNDIS_OID_GEN_LINK_SPEED, &linkspeed, &len); | 2478 | ret = rndis_query_oid(usbdev, RNDIS_OID_GEN_LINK_SPEED, &linkspeed, &len); |
2479 | if (ret == 0) { | 2479 | if (ret == 0) { |
2480 | sinfo->txrate.legacy = le32_to_cpu(linkspeed) / 1000; | 2480 | sinfo->txrate.legacy = le32_to_cpu(linkspeed) / 1000; |
2481 | sinfo->filled |= STATION_INFO_TX_BITRATE; | 2481 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); |
2482 | } | 2482 | } |
2483 | 2483 | ||
2484 | len = sizeof(rssi); | 2484 | len = sizeof(rssi); |
@@ -2486,7 +2486,7 @@ static void rndis_fill_station_info(struct usbnet *usbdev, | |||
2486 | &rssi, &len); | 2486 | &rssi, &len); |
2487 | if (ret == 0) { | 2487 | if (ret == 0) { |
2488 | sinfo->signal = level_to_qual(le32_to_cpu(rssi)); | 2488 | sinfo->signal = level_to_qual(le32_to_cpu(rssi)); |
2489 | sinfo->filled |= STATION_INFO_SIGNAL; | 2489 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); |
2490 | } | 2490 | } |
2491 | } | 2491 | } |
2492 | 2492 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 81ee481487cf..be2d54f257b1 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -8020,13 +8020,13 @@ int rt2800_get_survey(struct ieee80211_hw *hw, int idx, | |||
8020 | rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext); | 8020 | rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext); |
8021 | 8021 | ||
8022 | if (idle || busy) { | 8022 | if (idle || busy) { |
8023 | survey->filled = SURVEY_INFO_CHANNEL_TIME | | 8023 | survey->filled = SURVEY_INFO_TIME | |
8024 | SURVEY_INFO_CHANNEL_TIME_BUSY | | 8024 | SURVEY_INFO_TIME_BUSY | |
8025 | SURVEY_INFO_CHANNEL_TIME_EXT_BUSY; | 8025 | SURVEY_INFO_TIME_EXT_BUSY; |
8026 | 8026 | ||
8027 | survey->channel_time = (idle + busy) / 1000; | 8027 | survey->time = (idle + busy) / 1000; |
8028 | survey->channel_time_busy = busy / 1000; | 8028 | survey->time_busy = busy / 1000; |
8029 | survey->channel_time_ext_busy = busy_ext / 1000; | 8029 | survey->time_ext_busy = busy_ext / 1000; |
8030 | } | 8030 | } |
8031 | 8031 | ||
8032 | if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) | 8032 | if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) |
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index 0b30a7b4d663..d4ba009ac9aa 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c | |||
@@ -500,6 +500,7 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw, | |||
500 | int ret = 0; | 500 | int ret = 0; |
501 | 501 | ||
502 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | | 502 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | |
503 | IEEE80211_VIF_SUPPORTS_UAPSD | | ||
503 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; | 504 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; |
504 | 505 | ||
505 | wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", | 506 | wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", |
@@ -1480,9 +1481,7 @@ int wl1251_init_ieee80211(struct wl1251 *wl) | |||
1480 | /* unit us */ | 1481 | /* unit us */ |
1481 | /* FIXME: find a proper value */ | 1482 | /* FIXME: find a proper value */ |
1482 | 1483 | ||
1483 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 1484 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS; |
1484 | IEEE80211_HW_SUPPORTS_PS | | ||
1485 | IEEE80211_HW_SUPPORTS_UAPSD; | ||
1486 | 1485 | ||
1487 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 1486 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
1488 | BIT(NL80211_IFTYPE_ADHOC); | 1487 | BIT(NL80211_IFTYPE_ADHOC); |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index e90fb781a6a1..0a9d9a1b2d85 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -2552,6 +2552,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, | |||
2552 | } | 2552 | } |
2553 | 2553 | ||
2554 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | | 2554 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | |
2555 | IEEE80211_VIF_SUPPORTS_UAPSD | | ||
2555 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; | 2556 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; |
2556 | 2557 | ||
2557 | wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", | 2558 | wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", |
@@ -5661,14 +5662,15 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw, | |||
5661 | ieee80211_queue_work(hw, &wlvif->rc_update_work); | 5662 | ieee80211_queue_work(hw, &wlvif->rc_update_work); |
5662 | } | 5663 | } |
5663 | 5664 | ||
5664 | static int wlcore_op_get_rssi(struct ieee80211_hw *hw, | 5665 | static void wlcore_op_sta_statistics(struct ieee80211_hw *hw, |
5665 | struct ieee80211_vif *vif, | 5666 | struct ieee80211_vif *vif, |
5666 | struct ieee80211_sta *sta, | 5667 | struct ieee80211_sta *sta, |
5667 | s8 *rssi_dbm) | 5668 | struct station_info *sinfo) |
5668 | { | 5669 | { |
5669 | struct wl1271 *wl = hw->priv; | 5670 | struct wl1271 *wl = hw->priv; |
5670 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | 5671 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); |
5671 | int ret = 0; | 5672 | s8 rssi_dbm; |
5673 | int ret; | ||
5672 | 5674 | ||
5673 | wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi"); | 5675 | wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi"); |
5674 | 5676 | ||
@@ -5681,17 +5683,18 @@ static int wlcore_op_get_rssi(struct ieee80211_hw *hw, | |||
5681 | if (ret < 0) | 5683 | if (ret < 0) |
5682 | goto out_sleep; | 5684 | goto out_sleep; |
5683 | 5685 | ||
5684 | ret = wlcore_acx_average_rssi(wl, wlvif, rssi_dbm); | 5686 | ret = wlcore_acx_average_rssi(wl, wlvif, &rssi_dbm); |
5685 | if (ret < 0) | 5687 | if (ret < 0) |
5686 | goto out_sleep; | 5688 | goto out_sleep; |
5687 | 5689 | ||
5690 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); | ||
5691 | sinfo->signal = rssi_dbm; | ||
5692 | |||
5688 | out_sleep: | 5693 | out_sleep: |
5689 | wl1271_ps_elp_sleep(wl); | 5694 | wl1271_ps_elp_sleep(wl); |
5690 | 5695 | ||
5691 | out: | 5696 | out: |
5692 | mutex_unlock(&wl->mutex); | 5697 | mutex_unlock(&wl->mutex); |
5693 | |||
5694 | return ret; | ||
5695 | } | 5698 | } |
5696 | 5699 | ||
5697 | static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) | 5700 | static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) |
@@ -5893,7 +5896,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
5893 | .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx, | 5896 | .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx, |
5894 | .switch_vif_chanctx = wlcore_op_switch_vif_chanctx, | 5897 | .switch_vif_chanctx = wlcore_op_switch_vif_chanctx, |
5895 | .sta_rc_update = wlcore_op_sta_rc_update, | 5898 | .sta_rc_update = wlcore_op_sta_rc_update, |
5896 | .get_rssi = wlcore_op_get_rssi, | 5899 | .sta_statistics = wlcore_op_sta_statistics, |
5897 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) | 5900 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) |
5898 | }; | 5901 | }; |
5899 | 5902 | ||
@@ -6064,7 +6067,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) | |||
6064 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 6067 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
6065 | IEEE80211_HW_SUPPORTS_PS | | 6068 | IEEE80211_HW_SUPPORTS_PS | |
6066 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | | 6069 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | |
6067 | IEEE80211_HW_SUPPORTS_UAPSD | | ||
6068 | IEEE80211_HW_HAS_RATE_CONTROL | | 6070 | IEEE80211_HW_HAS_RATE_CONTROL | |
6069 | IEEE80211_HW_CONNECTION_MONITOR | | 6071 | IEEE80211_HW_CONNECTION_MONITOR | |
6070 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 6072 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index 82a8c06ab347..c5800ae71fcf 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c | |||
@@ -1091,17 +1091,17 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy, | |||
1091 | goto exit; | 1091 | goto exit; |
1092 | } | 1092 | } |
1093 | 1093 | ||
1094 | sinfo->filled |= STATION_INFO_SIGNAL; | 1094 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); |
1095 | sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv. | 1095 | sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv. |
1096 | signal_strength); | 1096 | signal_strength); |
1097 | 1097 | ||
1098 | sinfo->filled |= STATION_INFO_TX_BITRATE; | 1098 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); |
1099 | sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter); | 1099 | sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter); |
1100 | 1100 | ||
1101 | sinfo->filled |= STATION_INFO_RX_PACKETS; | 1101 | sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); |
1102 | sinfo->rx_packets = sta_rx_data_pkts(psta); | 1102 | sinfo->rx_packets = sta_rx_data_pkts(psta); |
1103 | 1103 | ||
1104 | sinfo->filled |= STATION_INFO_TX_PACKETS; | 1104 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); |
1105 | sinfo->tx_packets = psta->sta_stats.tx_pkts; | 1105 | sinfo->tx_packets = psta->sta_stats.tx_pkts; |
1106 | } | 1106 | } |
1107 | 1107 | ||
@@ -2363,7 +2363,7 @@ void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter, | |||
2363 | ie_offset = offsetof(struct ieee80211_mgmt, | 2363 | ie_offset = offsetof(struct ieee80211_mgmt, |
2364 | u.reassoc_req.variable); | 2364 | u.reassoc_req.variable); |
2365 | 2365 | ||
2366 | sinfo.filled = STATION_INFO_ASSOC_REQ_IES; | 2366 | sinfo.filled = 0; |
2367 | sinfo.assoc_req_ies = pmgmt_frame + ie_offset; | 2367 | sinfo.assoc_req_ies = pmgmt_frame + ie_offset; |
2368 | sinfo.assoc_req_ies_len = frame_len - ie_offset; | 2368 | sinfo.assoc_req_ies_len = frame_len - ie_offset; |
2369 | cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC); | 2369 | cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC); |
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 8942dcb44180..7c87aecf4744 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c | |||
@@ -325,9 +325,9 @@ static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
325 | 325 | ||
326 | if (result == 0) { | 326 | if (result == 0) { |
327 | sinfo->txrate.legacy = quality.txrate.data; | 327 | sinfo->txrate.legacy = quality.txrate.data; |
328 | sinfo->filled |= STATION_INFO_TX_BITRATE; | 328 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); |
329 | sinfo->signal = quality.level.data; | 329 | sinfo->signal = quality.level.data; |
330 | sinfo->filled |= STATION_INFO_SIGNAL; | 330 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); |
331 | } | 331 | } |
332 | 332 | ||
333 | return result; | 333 | return result; |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4ebb816241fa..7b44ba0a7632 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -520,37 +520,41 @@ ieee80211_chandef_max_power(struct cfg80211_chan_def *chandef) | |||
520 | * | 520 | * |
521 | * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in | 521 | * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in |
522 | * @SURVEY_INFO_IN_USE: channel is currently being used | 522 | * @SURVEY_INFO_IN_USE: channel is currently being used |
523 | * @SURVEY_INFO_CHANNEL_TIME: channel active time (in ms) was filled in | 523 | * @SURVEY_INFO_TIME: active time (in ms) was filled in |
524 | * @SURVEY_INFO_CHANNEL_TIME_BUSY: channel busy time was filled in | 524 | * @SURVEY_INFO_TIME_BUSY: busy time was filled in |
525 | * @SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: extension channel busy time was filled in | 525 | * @SURVEY_INFO_TIME_EXT_BUSY: extension channel busy time was filled in |
526 | * @SURVEY_INFO_CHANNEL_TIME_RX: channel receive time was filled in | 526 | * @SURVEY_INFO_TIME_RX: receive time was filled in |
527 | * @SURVEY_INFO_CHANNEL_TIME_TX: channel transmit time was filled in | 527 | * @SURVEY_INFO_TIME_TX: transmit time was filled in |
528 | * @SURVEY_INFO_TIME_SCAN: scan time was filled in | ||
528 | * | 529 | * |
529 | * Used by the driver to indicate which info in &struct survey_info | 530 | * Used by the driver to indicate which info in &struct survey_info |
530 | * it has filled in during the get_survey(). | 531 | * it has filled in during the get_survey(). |
531 | */ | 532 | */ |
532 | enum survey_info_flags { | 533 | enum survey_info_flags { |
533 | SURVEY_INFO_NOISE_DBM = 1<<0, | 534 | SURVEY_INFO_NOISE_DBM = BIT(0), |
534 | SURVEY_INFO_IN_USE = 1<<1, | 535 | SURVEY_INFO_IN_USE = BIT(1), |
535 | SURVEY_INFO_CHANNEL_TIME = 1<<2, | 536 | SURVEY_INFO_TIME = BIT(2), |
536 | SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3, | 537 | SURVEY_INFO_TIME_BUSY = BIT(3), |
537 | SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4, | 538 | SURVEY_INFO_TIME_EXT_BUSY = BIT(4), |
538 | SURVEY_INFO_CHANNEL_TIME_RX = 1<<5, | 539 | SURVEY_INFO_TIME_RX = BIT(5), |
539 | SURVEY_INFO_CHANNEL_TIME_TX = 1<<6, | 540 | SURVEY_INFO_TIME_TX = BIT(6), |
541 | SURVEY_INFO_TIME_SCAN = BIT(7), | ||
540 | }; | 542 | }; |
541 | 543 | ||
542 | /** | 544 | /** |
543 | * struct survey_info - channel survey response | 545 | * struct survey_info - channel survey response |
544 | * | 546 | * |
545 | * @channel: the channel this survey record reports, mandatory | 547 | * @channel: the channel this survey record reports, may be %NULL for a single |
548 | * record to report global statistics | ||
546 | * @filled: bitflag of flags from &enum survey_info_flags | 549 | * @filled: bitflag of flags from &enum survey_info_flags |
547 | * @noise: channel noise in dBm. This and all following fields are | 550 | * @noise: channel noise in dBm. This and all following fields are |
548 | * optional | 551 | * optional |
549 | * @channel_time: amount of time in ms the radio spent on the channel | 552 | * @time: amount of time in ms the radio was turn on (on the channel) |
550 | * @channel_time_busy: amount of time the primary channel was sensed busy | 553 | * @time_busy: amount of time the primary channel was sensed busy |
551 | * @channel_time_ext_busy: amount of time the extension channel was sensed busy | 554 | * @time_ext_busy: amount of time the extension channel was sensed busy |
552 | * @channel_time_rx: amount of time the radio spent receiving data | 555 | * @time_rx: amount of time the radio spent receiving data |
553 | * @channel_time_tx: amount of time the radio spent transmitting data | 556 | * @time_tx: amount of time the radio spent transmitting data |
557 | * @time_scan: amount of time the radio spent for scanning | ||
554 | * | 558 | * |
555 | * Used by dump_survey() to report back per-channel survey information. | 559 | * Used by dump_survey() to report back per-channel survey information. |
556 | * | 560 | * |
@@ -559,11 +563,12 @@ enum survey_info_flags { | |||
559 | */ | 563 | */ |
560 | struct survey_info { | 564 | struct survey_info { |
561 | struct ieee80211_channel *channel; | 565 | struct ieee80211_channel *channel; |
562 | u64 channel_time; | 566 | u64 time; |
563 | u64 channel_time_busy; | 567 | u64 time_busy; |
564 | u64 channel_time_ext_busy; | 568 | u64 time_ext_busy; |
565 | u64 channel_time_rx; | 569 | u64 time_rx; |
566 | u64 channel_time_tx; | 570 | u64 time_tx; |
571 | u64 time_scan; | ||
567 | u32 filled; | 572 | u32 filled; |
568 | s8 noise; | 573 | s8 noise; |
569 | }; | 574 | }; |
@@ -861,75 +866,6 @@ int cfg80211_check_station_change(struct wiphy *wiphy, | |||
861 | enum cfg80211_station_type statype); | 866 | enum cfg80211_station_type statype); |
862 | 867 | ||
863 | /** | 868 | /** |
864 | * enum station_info_flags - station information flags | ||
865 | * | ||
866 | * Used by the driver to indicate which info in &struct station_info | ||
867 | * it has filled in during get_station() or dump_station(). | ||
868 | * | ||
869 | * @STATION_INFO_INACTIVE_TIME: @inactive_time filled | ||
870 | * @STATION_INFO_RX_BYTES: @rx_bytes filled | ||
871 | * @STATION_INFO_TX_BYTES: @tx_bytes filled | ||
872 | * @STATION_INFO_RX_BYTES64: @rx_bytes filled with 64-bit value | ||
873 | * @STATION_INFO_TX_BYTES64: @tx_bytes filled with 64-bit value | ||
874 | * @STATION_INFO_LLID: @llid filled | ||
875 | * @STATION_INFO_PLID: @plid filled | ||
876 | * @STATION_INFO_PLINK_STATE: @plink_state filled | ||
877 | * @STATION_INFO_SIGNAL: @signal filled | ||
878 | * @STATION_INFO_TX_BITRATE: @txrate fields are filled | ||
879 | * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) | ||
880 | * @STATION_INFO_RX_PACKETS: @rx_packets filled with 32-bit value | ||
881 | * @STATION_INFO_TX_PACKETS: @tx_packets filled with 32-bit value | ||
882 | * @STATION_INFO_TX_RETRIES: @tx_retries filled | ||
883 | * @STATION_INFO_TX_FAILED: @tx_failed filled | ||
884 | * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled | ||
885 | * @STATION_INFO_SIGNAL_AVG: @signal_avg filled | ||
886 | * @STATION_INFO_RX_BITRATE: @rxrate fields are filled | ||
887 | * @STATION_INFO_BSS_PARAM: @bss_param filled | ||
888 | * @STATION_INFO_CONNECTED_TIME: @connected_time filled | ||
889 | * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled | ||
890 | * @STATION_INFO_STA_FLAGS: @sta_flags filled | ||
891 | * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled | ||
892 | * @STATION_INFO_T_OFFSET: @t_offset filled | ||
893 | * @STATION_INFO_LOCAL_PM: @local_pm filled | ||
894 | * @STATION_INFO_PEER_PM: @peer_pm filled | ||
895 | * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled | ||
896 | * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled | ||
897 | * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled | ||
898 | * @STATION_INFO_EXPECTED_THROUGHPUT: @expected_throughput filled | ||
899 | */ | ||
900 | enum station_info_flags { | ||
901 | STATION_INFO_INACTIVE_TIME = BIT(0), | ||
902 | STATION_INFO_RX_BYTES = BIT(1), | ||
903 | STATION_INFO_TX_BYTES = BIT(2), | ||
904 | STATION_INFO_LLID = BIT(3), | ||
905 | STATION_INFO_PLID = BIT(4), | ||
906 | STATION_INFO_PLINK_STATE = BIT(5), | ||
907 | STATION_INFO_SIGNAL = BIT(6), | ||
908 | STATION_INFO_TX_BITRATE = BIT(7), | ||
909 | STATION_INFO_RX_PACKETS = BIT(8), | ||
910 | STATION_INFO_TX_PACKETS = BIT(9), | ||
911 | STATION_INFO_TX_RETRIES = BIT(10), | ||
912 | STATION_INFO_TX_FAILED = BIT(11), | ||
913 | STATION_INFO_RX_DROP_MISC = BIT(12), | ||
914 | STATION_INFO_SIGNAL_AVG = BIT(13), | ||
915 | STATION_INFO_RX_BITRATE = BIT(14), | ||
916 | STATION_INFO_BSS_PARAM = BIT(15), | ||
917 | STATION_INFO_CONNECTED_TIME = BIT(16), | ||
918 | STATION_INFO_ASSOC_REQ_IES = BIT(17), | ||
919 | STATION_INFO_STA_FLAGS = BIT(18), | ||
920 | STATION_INFO_BEACON_LOSS_COUNT = BIT(19), | ||
921 | STATION_INFO_T_OFFSET = BIT(20), | ||
922 | STATION_INFO_LOCAL_PM = BIT(21), | ||
923 | STATION_INFO_PEER_PM = BIT(22), | ||
924 | STATION_INFO_NONPEER_PM = BIT(23), | ||
925 | STATION_INFO_RX_BYTES64 = BIT(24), | ||
926 | STATION_INFO_TX_BYTES64 = BIT(25), | ||
927 | STATION_INFO_CHAIN_SIGNAL = BIT(26), | ||
928 | STATION_INFO_CHAIN_SIGNAL_AVG = BIT(27), | ||
929 | STATION_INFO_EXPECTED_THROUGHPUT = BIT(28), | ||
930 | }; | ||
931 | |||
932 | /** | ||
933 | * enum station_info_rate_flags - bitrate info flags | 869 | * enum station_info_rate_flags - bitrate info flags |
934 | * | 870 | * |
935 | * Used by the driver to indicate the specific rate transmission | 871 | * Used by the driver to indicate the specific rate transmission |
@@ -937,22 +873,35 @@ enum station_info_flags { | |||
937 | * | 873 | * |
938 | * @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS | 874 | * @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS |
939 | * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS | 875 | * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS |
940 | * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 MHz width transmission | ||
941 | * @RATE_INFO_FLAGS_80_MHZ_WIDTH: 80 MHz width transmission | ||
942 | * @RATE_INFO_FLAGS_80P80_MHZ_WIDTH: 80+80 MHz width transmission | ||
943 | * @RATE_INFO_FLAGS_160_MHZ_WIDTH: 160 MHz width transmission | ||
944 | * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval | 876 | * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval |
945 | * @RATE_INFO_FLAGS_60G: 60GHz MCS | 877 | * @RATE_INFO_FLAGS_60G: 60GHz MCS |
946 | */ | 878 | */ |
947 | enum rate_info_flags { | 879 | enum rate_info_flags { |
948 | RATE_INFO_FLAGS_MCS = BIT(0), | 880 | RATE_INFO_FLAGS_MCS = BIT(0), |
949 | RATE_INFO_FLAGS_VHT_MCS = BIT(1), | 881 | RATE_INFO_FLAGS_VHT_MCS = BIT(1), |
950 | RATE_INFO_FLAGS_40_MHZ_WIDTH = BIT(2), | 882 | RATE_INFO_FLAGS_SHORT_GI = BIT(2), |
951 | RATE_INFO_FLAGS_80_MHZ_WIDTH = BIT(3), | 883 | RATE_INFO_FLAGS_60G = BIT(3), |
952 | RATE_INFO_FLAGS_80P80_MHZ_WIDTH = BIT(4), | 884 | }; |
953 | RATE_INFO_FLAGS_160_MHZ_WIDTH = BIT(5), | 885 | |
954 | RATE_INFO_FLAGS_SHORT_GI = BIT(6), | 886 | /** |
955 | RATE_INFO_FLAGS_60G = BIT(7), | 887 | * enum rate_info_bw - rate bandwidth information |
888 | * | ||
889 | * Used by the driver to indicate the rate bandwidth. | ||
890 | * | ||
891 | * @RATE_INFO_BW_5: 5 MHz bandwidth | ||
892 | * @RATE_INFO_BW_10: 10 MHz bandwidth | ||
893 | * @RATE_INFO_BW_20: 20 MHz bandwidth | ||
894 | * @RATE_INFO_BW_40: 40 MHz bandwidth | ||
895 | * @RATE_INFO_BW_80: 80 MHz bandwidth | ||
896 | * @RATE_INFO_BW_160: 160 MHz bandwidth | ||
897 | */ | ||
898 | enum rate_info_bw { | ||
899 | RATE_INFO_BW_5, | ||
900 | RATE_INFO_BW_10, | ||
901 | RATE_INFO_BW_20, | ||
902 | RATE_INFO_BW_40, | ||
903 | RATE_INFO_BW_80, | ||
904 | RATE_INFO_BW_160, | ||
956 | }; | 905 | }; |
957 | 906 | ||
958 | /** | 907 | /** |
@@ -964,12 +913,14 @@ enum rate_info_flags { | |||
964 | * @mcs: mcs index if struct describes a 802.11n bitrate | 913 | * @mcs: mcs index if struct describes a 802.11n bitrate |
965 | * @legacy: bitrate in 100kbit/s for 802.11abg | 914 | * @legacy: bitrate in 100kbit/s for 802.11abg |
966 | * @nss: number of streams (VHT only) | 915 | * @nss: number of streams (VHT only) |
916 | * @bw: bandwidth (from &enum rate_info_bw) | ||
967 | */ | 917 | */ |
968 | struct rate_info { | 918 | struct rate_info { |
969 | u8 flags; | 919 | u8 flags; |
970 | u8 mcs; | 920 | u8 mcs; |
971 | u16 legacy; | 921 | u16 legacy; |
972 | u8 nss; | 922 | u8 nss; |
923 | u8 bw; | ||
973 | }; | 924 | }; |
974 | 925 | ||
975 | /** | 926 | /** |
@@ -1003,6 +954,24 @@ struct sta_bss_parameters { | |||
1003 | u16 beacon_interval; | 954 | u16 beacon_interval; |
1004 | }; | 955 | }; |
1005 | 956 | ||
957 | /** | ||
958 | * struct cfg80211_tid_stats - per-TID statistics | ||
959 | * @filled: bitmap of flags using the bits of &enum nl80211_tid_stats to | ||
960 | * indicate the relevant values in this struct are filled | ||
961 | * @rx_msdu: number of received MSDUs | ||
962 | * @tx_msdu: number of (attempted) transmitted MSDUs | ||
963 | * @tx_msdu_retries: number of retries (not counting the first) for | ||
964 | * transmitted MSDUs | ||
965 | * @tx_msdu_failed: number of failed transmitted MSDUs | ||
966 | */ | ||
967 | struct cfg80211_tid_stats { | ||
968 | u32 filled; | ||
969 | u64 rx_msdu; | ||
970 | u64 tx_msdu; | ||
971 | u64 tx_msdu_retries; | ||
972 | u64 tx_msdu_failed; | ||
973 | }; | ||
974 | |||
1006 | #define IEEE80211_MAX_CHAINS 4 | 975 | #define IEEE80211_MAX_CHAINS 4 |
1007 | 976 | ||
1008 | /** | 977 | /** |
@@ -1010,11 +979,12 @@ struct sta_bss_parameters { | |||
1010 | * | 979 | * |
1011 | * Station information filled by driver for get_station() and dump_station. | 980 | * Station information filled by driver for get_station() and dump_station. |
1012 | * | 981 | * |
1013 | * @filled: bitflag of flags from &enum station_info_flags | 982 | * @filled: bitflag of flags using the bits of &enum nl80211_sta_info to |
983 | * indicate the relevant values in this struct for them | ||
1014 | * @connected_time: time(in secs) since a station is last connected | 984 | * @connected_time: time(in secs) since a station is last connected |
1015 | * @inactive_time: time since last station activity (tx/rx) in milliseconds | 985 | * @inactive_time: time since last station activity (tx/rx) in milliseconds |
1016 | * @rx_bytes: bytes received from this station | 986 | * @rx_bytes: bytes (size of MPDUs) received from this station |
1017 | * @tx_bytes: bytes transmitted to this station | 987 | * @tx_bytes: bytes (size of MPDUs) transmitted to this station |
1018 | * @llid: mesh local link id | 988 | * @llid: mesh local link id |
1019 | * @plid: mesh peer link id | 989 | * @plid: mesh peer link id |
1020 | * @plink_state: mesh peer link state | 990 | * @plink_state: mesh peer link state |
@@ -1027,10 +997,10 @@ struct sta_bss_parameters { | |||
1027 | * @chain_signal_avg: per-chain signal strength average in dBm | 997 | * @chain_signal_avg: per-chain signal strength average in dBm |
1028 | * @txrate: current unicast bitrate from this station | 998 | * @txrate: current unicast bitrate from this station |
1029 | * @rxrate: current unicast bitrate to this station | 999 | * @rxrate: current unicast bitrate to this station |
1030 | * @rx_packets: packets received from this station | 1000 | * @rx_packets: packets (MSDUs & MMPDUs) received from this station |
1031 | * @tx_packets: packets transmitted to this station | 1001 | * @tx_packets: packets (MSDUs & MMPDUs) transmitted to this station |
1032 | * @tx_retries: cumulative retry counts | 1002 | * @tx_retries: cumulative retry counts (MPDUs) |
1033 | * @tx_failed: number of failed transmissions (retries exceeded, no ACK) | 1003 | * @tx_failed: number of failed transmissions (MPDUs) (retries exceeded, no ACK) |
1034 | * @rx_dropped_misc: Dropped for un-specified reason. | 1004 | * @rx_dropped_misc: Dropped for un-specified reason. |
1035 | * @bss_param: current BSS parameters | 1005 | * @bss_param: current BSS parameters |
1036 | * @generation: generation number for nl80211 dumps. | 1006 | * @generation: generation number for nl80211 dumps. |
@@ -1050,6 +1020,11 @@ struct sta_bss_parameters { | |||
1050 | * @nonpeer_pm: non-peer mesh STA power save mode | 1020 | * @nonpeer_pm: non-peer mesh STA power save mode |
1051 | * @expected_throughput: expected throughput in kbps (including 802.11 headers) | 1021 | * @expected_throughput: expected throughput in kbps (including 802.11 headers) |
1052 | * towards this station. | 1022 | * towards this station. |
1023 | * @rx_beacon: number of beacons received from this peer | ||
1024 | * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received | ||
1025 | * from this peer | ||
1026 | * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last | ||
1027 | * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs. | ||
1053 | */ | 1028 | */ |
1054 | struct station_info { | 1029 | struct station_info { |
1055 | u32 filled; | 1030 | u32 filled; |
@@ -1090,10 +1065,9 @@ struct station_info { | |||
1090 | 1065 | ||
1091 | u32 expected_throughput; | 1066 | u32 expected_throughput; |
1092 | 1067 | ||
1093 | /* | 1068 | u64 rx_beacon; |
1094 | * Note: Add a new enum station_info_flags value for each new field and | 1069 | u8 rx_beacon_signal_avg; |
1095 | * use it to check which fields are initialized. | 1070 | struct cfg80211_tid_stats pertid[IEEE80211_NUM_TIDS + 1]; |
1096 | */ | ||
1097 | }; | 1071 | }; |
1098 | 1072 | ||
1099 | /** | 1073 | /** |
@@ -1516,6 +1490,9 @@ struct cfg80211_match_set { | |||
1516 | * @mac_addr_mask: MAC address mask used with randomisation, bits that | 1490 | * @mac_addr_mask: MAC address mask used with randomisation, bits that |
1517 | * are 0 in the mask should be randomised, bits that are 1 should | 1491 | * are 0 in the mask should be randomised, bits that are 1 should |
1518 | * be taken from the @mac_addr | 1492 | * be taken from the @mac_addr |
1493 | * @rcu_head: RCU callback used to free the struct | ||
1494 | * @owner_nlportid: netlink portid of owner (if this should is a request | ||
1495 | * owned by a particular socket) | ||
1519 | */ | 1496 | */ |
1520 | struct cfg80211_sched_scan_request { | 1497 | struct cfg80211_sched_scan_request { |
1521 | struct cfg80211_ssid *ssids; | 1498 | struct cfg80211_ssid *ssids; |
@@ -1537,6 +1514,8 @@ struct cfg80211_sched_scan_request { | |||
1537 | struct wiphy *wiphy; | 1514 | struct wiphy *wiphy; |
1538 | struct net_device *dev; | 1515 | struct net_device *dev; |
1539 | unsigned long scan_start; | 1516 | unsigned long scan_start; |
1517 | struct rcu_head rcu_head; | ||
1518 | u32 owner_nlportid; | ||
1540 | 1519 | ||
1541 | /* keep last */ | 1520 | /* keep last */ |
1542 | struct ieee80211_channel *channels[0]; | 1521 | struct ieee80211_channel *channels[0]; |
@@ -3011,6 +2990,8 @@ struct wiphy_vendor_command { | |||
3011 | * @regulatory_flags: wiphy regulatory flags, see | 2990 | * @regulatory_flags: wiphy regulatory flags, see |
3012 | * &enum ieee80211_regulatory_flags | 2991 | * &enum ieee80211_regulatory_flags |
3013 | * @features: features advertised to nl80211, see &enum nl80211_feature_flags. | 2992 | * @features: features advertised to nl80211, see &enum nl80211_feature_flags. |
2993 | * @ext_features: extended features advertised to nl80211, see | ||
2994 | * &enum nl80211_ext_feature_index. | ||
3014 | * @bss_priv_size: each BSS struct has private data allocated with it, | 2995 | * @bss_priv_size: each BSS struct has private data allocated with it, |
3015 | * this variable determines its size | 2996 | * this variable determines its size |
3016 | * @max_scan_ssids: maximum number of SSIDs the device can scan for in | 2997 | * @max_scan_ssids: maximum number of SSIDs the device can scan for in |
@@ -3120,6 +3101,7 @@ struct wiphy { | |||
3120 | u16 max_acl_mac_addrs; | 3101 | u16 max_acl_mac_addrs; |
3121 | 3102 | ||
3122 | u32 flags, regulatory_flags, features; | 3103 | u32 flags, regulatory_flags, features; |
3104 | u8 ext_features[DIV_ROUND_UP(NUM_NL80211_EXT_FEATURES, 8)]; | ||
3123 | 3105 | ||
3124 | u32 ap_sme_capa; | 3106 | u32 ap_sme_capa; |
3125 | 3107 | ||
@@ -3808,6 +3790,34 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, | |||
3808 | int regulatory_hint(struct wiphy *wiphy, const char *alpha2); | 3790 | int regulatory_hint(struct wiphy *wiphy, const char *alpha2); |
3809 | 3791 | ||
3810 | /** | 3792 | /** |
3793 | * regulatory_set_wiphy_regd - set regdom info for self managed drivers | ||
3794 | * @wiphy: the wireless device we want to process the regulatory domain on | ||
3795 | * @rd: the regulatory domain informatoin to use for this wiphy | ||
3796 | * | ||
3797 | * Set the regulatory domain information for self-managed wiphys, only they | ||
3798 | * may use this function. See %REGULATORY_WIPHY_SELF_MANAGED for more | ||
3799 | * information. | ||
3800 | * | ||
3801 | * Return: 0 on success. -EINVAL, -EPERM | ||
3802 | */ | ||
3803 | int regulatory_set_wiphy_regd(struct wiphy *wiphy, | ||
3804 | struct ieee80211_regdomain *rd); | ||
3805 | |||
3806 | /** | ||
3807 | * regulatory_set_wiphy_regd_sync_rtnl - set regdom for self-managed drivers | ||
3808 | * @wiphy: the wireless device we want to process the regulatory domain on | ||
3809 | * @rd: the regulatory domain information to use for this wiphy | ||
3810 | * | ||
3811 | * This functions requires the RTNL to be held and applies the new regdomain | ||
3812 | * synchronously to this wiphy. For more details see | ||
3813 | * regulatory_set_wiphy_regd(). | ||
3814 | * | ||
3815 | * Return: 0 on success. -EINVAL, -EPERM | ||
3816 | */ | ||
3817 | int regulatory_set_wiphy_regd_sync_rtnl(struct wiphy *wiphy, | ||
3818 | struct ieee80211_regdomain *rd); | ||
3819 | |||
3820 | /** | ||
3811 | * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain | 3821 | * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain |
3812 | * @wiphy: the wireless device we want to process the regulatory domain on | 3822 | * @wiphy: the wireless device we want to process the regulatory domain on |
3813 | * @regd: the custom regulatory domain to use for this wiphy | 3823 | * @regd: the custom regulatory domain to use for this wiphy |
@@ -4565,13 +4575,27 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, | |||
4565 | struct station_info *sinfo, gfp_t gfp); | 4575 | struct station_info *sinfo, gfp_t gfp); |
4566 | 4576 | ||
4567 | /** | 4577 | /** |
4578 | * cfg80211_del_sta_sinfo - notify userspace about deletion of a station | ||
4579 | * @dev: the netdev | ||
4580 | * @mac_addr: the station's address | ||
4581 | * @sinfo: the station information/statistics | ||
4582 | * @gfp: allocation flags | ||
4583 | */ | ||
4584 | void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr, | ||
4585 | struct station_info *sinfo, gfp_t gfp); | ||
4586 | |||
4587 | /** | ||
4568 | * cfg80211_del_sta - notify userspace about deletion of a station | 4588 | * cfg80211_del_sta - notify userspace about deletion of a station |
4569 | * | 4589 | * |
4570 | * @dev: the netdev | 4590 | * @dev: the netdev |
4571 | * @mac_addr: the station's address | 4591 | * @mac_addr: the station's address |
4572 | * @gfp: allocation flags | 4592 | * @gfp: allocation flags |
4573 | */ | 4593 | */ |
4574 | void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); | 4594 | static inline void cfg80211_del_sta(struct net_device *dev, |
4595 | const u8 *mac_addr, gfp_t gfp) | ||
4596 | { | ||
4597 | cfg80211_del_sta_sinfo(dev, mac_addr, NULL, gfp); | ||
4598 | } | ||
4575 | 4599 | ||
4576 | /** | 4600 | /** |
4577 | * cfg80211_conn_failed - connection request failed notification | 4601 | * cfg80211_conn_failed - connection request failed notification |
@@ -5033,6 +5057,42 @@ void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
5033 | */ | 5057 | */ |
5034 | void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy); | 5058 | void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy); |
5035 | 5059 | ||
5060 | /** | ||
5061 | * wiphy_ext_feature_set - set the extended feature flag | ||
5062 | * | ||
5063 | * @wiphy: the wiphy to modify. | ||
5064 | * @ftidx: extended feature bit index. | ||
5065 | * | ||
5066 | * The extended features are flagged in multiple bytes (see | ||
5067 | * &struct wiphy.@ext_features) | ||
5068 | */ | ||
5069 | static inline void wiphy_ext_feature_set(struct wiphy *wiphy, | ||
5070 | enum nl80211_ext_feature_index ftidx) | ||
5071 | { | ||
5072 | u8 *ft_byte; | ||
5073 | |||
5074 | ft_byte = &wiphy->ext_features[ftidx / 8]; | ||
5075 | *ft_byte |= BIT(ftidx % 8); | ||
5076 | } | ||
5077 | |||
5078 | /** | ||
5079 | * wiphy_ext_feature_isset - check the extended feature flag | ||
5080 | * | ||
5081 | * @wiphy: the wiphy to modify. | ||
5082 | * @ftidx: extended feature bit index. | ||
5083 | * | ||
5084 | * The extended features are flagged in multiple bytes (see | ||
5085 | * &struct wiphy.@ext_features) | ||
5086 | */ | ||
5087 | static inline bool | ||
5088 | wiphy_ext_feature_isset(struct wiphy *wiphy, | ||
5089 | enum nl80211_ext_feature_index ftidx) | ||
5090 | { | ||
5091 | u8 ft_byte; | ||
5092 | |||
5093 | ft_byte = wiphy->ext_features[ftidx / 8]; | ||
5094 | return (ft_byte & BIT(ftidx % 8)) != 0; | ||
5095 | } | ||
5036 | 5096 | ||
5037 | /* ethtool helper */ | 5097 | /* ethtool helper */ |
5038 | void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); | 5098 | void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 58d719ddaa60..275ee56152ad 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -505,8 +505,11 @@ struct ieee80211_bss_conf { | |||
505 | * @IEEE80211_TX_CTL_DONTFRAG: Don't fragment this packet even if it | 505 | * @IEEE80211_TX_CTL_DONTFRAG: Don't fragment this packet even if it |
506 | * would be fragmented by size (this is optional, only used for | 506 | * would be fragmented by size (this is optional, only used for |
507 | * monitor injection). | 507 | * monitor injection). |
508 | * @IEEE80211_TX_CTL_PS_RESPONSE: This frame is a response to a poll | 508 | * @IEEE80211_TX_STAT_NOACK_TRANSMITTED: A frame that was marked with |
509 | * frame (PS-Poll or uAPSD). | 509 | * IEEE80211_TX_CTL_NO_ACK has been successfully transmitted without |
510 | * any errors (like issues specific to the driver/HW). | ||
511 | * This flag must not be set for frames that don't request no-ack | ||
512 | * behaviour with IEEE80211_TX_CTL_NO_ACK. | ||
510 | * | 513 | * |
511 | * Note: If you have to add new flags to the enumeration, then don't | 514 | * Note: If you have to add new flags to the enumeration, then don't |
512 | * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. | 515 | * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. |
@@ -542,7 +545,7 @@ enum mac80211_tx_info_flags { | |||
542 | IEEE80211_TX_STATUS_EOSP = BIT(28), | 545 | IEEE80211_TX_STATUS_EOSP = BIT(28), |
543 | IEEE80211_TX_CTL_USE_MINRATE = BIT(29), | 546 | IEEE80211_TX_CTL_USE_MINRATE = BIT(29), |
544 | IEEE80211_TX_CTL_DONTFRAG = BIT(30), | 547 | IEEE80211_TX_CTL_DONTFRAG = BIT(30), |
545 | IEEE80211_TX_CTL_PS_RESPONSE = BIT(31), | 548 | IEEE80211_TX_STAT_NOACK_TRANSMITTED = BIT(31), |
546 | }; | 549 | }; |
547 | 550 | ||
548 | #define IEEE80211_TX_CTL_STBC_SHIFT 23 | 551 | #define IEEE80211_TX_CTL_STBC_SHIFT 23 |
@@ -552,11 +555,14 @@ enum mac80211_tx_info_flags { | |||
552 | * | 555 | * |
553 | * @IEEE80211_TX_CTRL_PORT_CTRL_PROTO: this frame is a port control | 556 | * @IEEE80211_TX_CTRL_PORT_CTRL_PROTO: this frame is a port control |
554 | * protocol frame (e.g. EAP) | 557 | * protocol frame (e.g. EAP) |
558 | * @IEEE80211_TX_CTRL_PS_RESPONSE: This frame is a response to a poll | ||
559 | * frame (PS-Poll or uAPSD). | ||
555 | * | 560 | * |
556 | * These flags are used in tx_info->control.flags. | 561 | * These flags are used in tx_info->control.flags. |
557 | */ | 562 | */ |
558 | enum mac80211_tx_control_flags { | 563 | enum mac80211_tx_control_flags { |
559 | IEEE80211_TX_CTRL_PORT_CTRL_PROTO = BIT(0), | 564 | IEEE80211_TX_CTRL_PORT_CTRL_PROTO = BIT(0), |
565 | IEEE80211_TX_CTRL_PS_RESPONSE = BIT(1), | ||
560 | }; | 566 | }; |
561 | 567 | ||
562 | /* | 568 | /* |
@@ -925,15 +931,13 @@ enum mac80211_rx_flags { | |||
925 | * These flags are used with the @vht_flag member of | 931 | * These flags are used with the @vht_flag member of |
926 | * &struct ieee80211_rx_status. | 932 | * &struct ieee80211_rx_status. |
927 | * @RX_VHT_FLAG_80MHZ: 80 MHz was used | 933 | * @RX_VHT_FLAG_80MHZ: 80 MHz was used |
928 | * @RX_VHT_FLAG_80P80MHZ: 80+80 MHz was used | ||
929 | * @RX_VHT_FLAG_160MHZ: 160 MHz was used | 934 | * @RX_VHT_FLAG_160MHZ: 160 MHz was used |
930 | * @RX_VHT_FLAG_BF: packet was beamformed | 935 | * @RX_VHT_FLAG_BF: packet was beamformed |
931 | */ | 936 | */ |
932 | enum mac80211_rx_vht_flags { | 937 | enum mac80211_rx_vht_flags { |
933 | RX_VHT_FLAG_80MHZ = BIT(0), | 938 | RX_VHT_FLAG_80MHZ = BIT(0), |
934 | RX_VHT_FLAG_80P80MHZ = BIT(1), | 939 | RX_VHT_FLAG_160MHZ = BIT(1), |
935 | RX_VHT_FLAG_160MHZ = BIT(2), | 940 | RX_VHT_FLAG_BF = BIT(2), |
936 | RX_VHT_FLAG_BF = BIT(3), | ||
937 | }; | 941 | }; |
938 | 942 | ||
939 | /** | 943 | /** |
@@ -1181,10 +1185,15 @@ struct ieee80211_channel_switch { | |||
1181 | * monitoring on this virtual interface -- i.e. it can monitor | 1185 | * monitoring on this virtual interface -- i.e. it can monitor |
1182 | * connection quality related parameters, such as the RSSI level and | 1186 | * connection quality related parameters, such as the RSSI level and |
1183 | * provide notifications if configured trigger levels are reached. | 1187 | * provide notifications if configured trigger levels are reached. |
1188 | * @IEEE80211_VIF_SUPPORTS_UAPSD: The device can do U-APSD for this | ||
1189 | * interface. This flag should be set during interface addition, | ||
1190 | * but may be set/cleared as late as authentication to an AP. It is | ||
1191 | * only valid for managed/station mode interfaces. | ||
1184 | */ | 1192 | */ |
1185 | enum ieee80211_vif_flags { | 1193 | enum ieee80211_vif_flags { |
1186 | IEEE80211_VIF_BEACON_FILTER = BIT(0), | 1194 | IEEE80211_VIF_BEACON_FILTER = BIT(0), |
1187 | IEEE80211_VIF_SUPPORTS_CQM_RSSI = BIT(1), | 1195 | IEEE80211_VIF_SUPPORTS_CQM_RSSI = BIT(1), |
1196 | IEEE80211_VIF_SUPPORTS_UAPSD = BIT(2), | ||
1188 | }; | 1197 | }; |
1189 | 1198 | ||
1190 | /** | 1199 | /** |
@@ -1296,6 +1305,9 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); | |||
1296 | * @IEEE80211_KEY_FLAG_GENERATE_IV_MGMT: This flag should be set by the | 1305 | * @IEEE80211_KEY_FLAG_GENERATE_IV_MGMT: This flag should be set by the |
1297 | * driver for a CCMP key to indicate that is requires IV generation | 1306 | * driver for a CCMP key to indicate that is requires IV generation |
1298 | * only for managment frames (MFP). | 1307 | * only for managment frames (MFP). |
1308 | * @IEEE80211_KEY_FLAG_RESERVE_TAILROOM: This flag should be set by the | ||
1309 | * driver for a key to indicate that sufficient tailroom must always | ||
1310 | * be reserved for ICV or MIC, even when HW encryption is enabled. | ||
1299 | */ | 1311 | */ |
1300 | enum ieee80211_key_flags { | 1312 | enum ieee80211_key_flags { |
1301 | IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0), | 1313 | IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0), |
@@ -1305,6 +1317,7 @@ enum ieee80211_key_flags { | |||
1305 | IEEE80211_KEY_FLAG_SW_MGMT_TX = BIT(4), | 1317 | IEEE80211_KEY_FLAG_SW_MGMT_TX = BIT(4), |
1306 | IEEE80211_KEY_FLAG_PUT_IV_SPACE = BIT(5), | 1318 | IEEE80211_KEY_FLAG_PUT_IV_SPACE = BIT(5), |
1307 | IEEE80211_KEY_FLAG_RX_MGMT = BIT(6), | 1319 | IEEE80211_KEY_FLAG_RX_MGMT = BIT(6), |
1320 | IEEE80211_KEY_FLAG_RESERVE_TAILROOM = BIT(7), | ||
1308 | }; | 1321 | }; |
1309 | 1322 | ||
1310 | /** | 1323 | /** |
@@ -1583,11 +1596,6 @@ struct ieee80211_tx_control { | |||
1583 | * @IEEE80211_HW_MFP_CAPABLE: | 1596 | * @IEEE80211_HW_MFP_CAPABLE: |
1584 | * Hardware supports management frame protection (MFP, IEEE 802.11w). | 1597 | * Hardware supports management frame protection (MFP, IEEE 802.11w). |
1585 | * | 1598 | * |
1586 | * @IEEE80211_HW_SUPPORTS_UAPSD: | ||
1587 | * Hardware supports Unscheduled Automatic Power Save Delivery | ||
1588 | * (U-APSD) in managed mode. The mode is configured with | ||
1589 | * conf_tx() operation. | ||
1590 | * | ||
1591 | * @IEEE80211_HW_REPORTS_TX_ACK_STATUS: | 1599 | * @IEEE80211_HW_REPORTS_TX_ACK_STATUS: |
1592 | * Hardware can provide ack status reports of Tx frames to | 1600 | * Hardware can provide ack status reports of Tx frames to |
1593 | * the stack. | 1601 | * the stack. |
@@ -1673,8 +1681,7 @@ enum ieee80211_hw_flags { | |||
1673 | IEEE80211_HW_MFP_CAPABLE = 1<<13, | 1681 | IEEE80211_HW_MFP_CAPABLE = 1<<13, |
1674 | IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, | 1682 | IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, |
1675 | IEEE80211_HW_NO_AUTO_VIF = 1<<15, | 1683 | IEEE80211_HW_NO_AUTO_VIF = 1<<15, |
1676 | /* free slot */ | 1684 | /* free slots */ |
1677 | IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, | ||
1678 | IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, | 1685 | IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, |
1679 | IEEE80211_HW_CONNECTION_MONITOR = 1<<19, | 1686 | IEEE80211_HW_CONNECTION_MONITOR = 1<<19, |
1680 | IEEE80211_HW_QUEUE_CONTROL = 1<<20, | 1687 | IEEE80211_HW_QUEUE_CONTROL = 1<<20, |
@@ -2026,7 +2033,7 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); | |||
2026 | * enabled whenever user has enabled powersave. | 2033 | * enabled whenever user has enabled powersave. |
2027 | * | 2034 | * |
2028 | * Driver informs U-APSD client support by enabling | 2035 | * Driver informs U-APSD client support by enabling |
2029 | * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the | 2036 | * %IEEE80211_VIF_SUPPORTS_UAPSD flag. The mode is configured through the |
2030 | * uapsd parameter in conf_tx() operation. Hardware needs to send the QoS | 2037 | * uapsd parameter in conf_tx() operation. Hardware needs to send the QoS |
2031 | * Nullfunc frames and stay awake until the service period has ended. To | 2038 | * Nullfunc frames and stay awake until the service period has ended. To |
2032 | * utilize U-APSD, dynamic powersave is disabled for voip AC and all frames | 2039 | * utilize U-APSD, dynamic powersave is disabled for voip AC and all frames |
@@ -2699,6 +2706,14 @@ enum ieee80211_reconfig_type { | |||
2699 | * is only used if the configured rate control algorithm actually uses | 2706 | * is only used if the configured rate control algorithm actually uses |
2700 | * the new rate table API, and is therefore optional. Must be atomic. | 2707 | * the new rate table API, and is therefore optional. Must be atomic. |
2701 | * | 2708 | * |
2709 | * @sta_statistics: Get statistics for this station. For example with beacon | ||
2710 | * filtering, the statistics kept by mac80211 might not be accurate, so | ||
2711 | * let the driver pre-fill the statistics. The driver can fill most of | ||
2712 | * the values (indicating which by setting the filled bitmap), but not | ||
2713 | * all of them make sense - see the source for which ones are possible. | ||
2714 | * Statistics that the driver doesn't fill will be filled by mac80211. | ||
2715 | * The callback can sleep. | ||
2716 | * | ||
2702 | * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), | 2717 | * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), |
2703 | * bursting) for a hardware TX queue. | 2718 | * bursting) for a hardware TX queue. |
2704 | * Returns a negative error code on failure. | 2719 | * Returns a negative error code on failure. |
@@ -2859,9 +2874,6 @@ enum ieee80211_reconfig_type { | |||
2859 | * @get_et_strings: Ethtool API to get a set of strings to describe stats | 2874 | * @get_et_strings: Ethtool API to get a set of strings to describe stats |
2860 | * and perhaps other supported types of ethtool data-sets. | 2875 | * and perhaps other supported types of ethtool data-sets. |
2861 | * | 2876 | * |
2862 | * @get_rssi: Get current signal strength in dBm, the function is optional | ||
2863 | * and can sleep. | ||
2864 | * | ||
2865 | * @mgd_prepare_tx: Prepare for transmitting a management frame for association | 2877 | * @mgd_prepare_tx: Prepare for transmitting a management frame for association |
2866 | * before associated. In multi-channel scenarios, a virtual interface is | 2878 | * before associated. In multi-channel scenarios, a virtual interface is |
2867 | * bound to a channel before it is associated, but as it isn't associated | 2879 | * bound to a channel before it is associated, but as it isn't associated |
@@ -3062,6 +3074,10 @@ struct ieee80211_ops { | |||
3062 | void (*sta_rate_tbl_update)(struct ieee80211_hw *hw, | 3074 | void (*sta_rate_tbl_update)(struct ieee80211_hw *hw, |
3063 | struct ieee80211_vif *vif, | 3075 | struct ieee80211_vif *vif, |
3064 | struct ieee80211_sta *sta); | 3076 | struct ieee80211_sta *sta); |
3077 | void (*sta_statistics)(struct ieee80211_hw *hw, | ||
3078 | struct ieee80211_vif *vif, | ||
3079 | struct ieee80211_sta *sta, | ||
3080 | struct station_info *sinfo); | ||
3065 | int (*conf_tx)(struct ieee80211_hw *hw, | 3081 | int (*conf_tx)(struct ieee80211_hw *hw, |
3066 | struct ieee80211_vif *vif, u16 ac, | 3082 | struct ieee80211_vif *vif, u16 ac, |
3067 | const struct ieee80211_tx_queue_params *params); | 3083 | const struct ieee80211_tx_queue_params *params); |
@@ -3129,8 +3145,6 @@ struct ieee80211_ops { | |||
3129 | void (*get_et_strings)(struct ieee80211_hw *hw, | 3145 | void (*get_et_strings)(struct ieee80211_hw *hw, |
3130 | struct ieee80211_vif *vif, | 3146 | struct ieee80211_vif *vif, |
3131 | u32 sset, u8 *data); | 3147 | u32 sset, u8 *data); |
3132 | int (*get_rssi)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
3133 | struct ieee80211_sta *sta, s8 *rssi_dbm); | ||
3134 | 3148 | ||
3135 | void (*mgd_prepare_tx)(struct ieee80211_hw *hw, | 3149 | void (*mgd_prepare_tx)(struct ieee80211_hw *hw, |
3136 | struct ieee80211_vif *vif); | 3150 | struct ieee80211_vif *vif); |
diff --git a/include/net/regulatory.h b/include/net/regulatory.h index b776d72d84be..ebc5a2ed8631 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h | |||
@@ -147,6 +147,24 @@ struct regulatory_request { | |||
147 | * NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO, | 147 | * NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO, |
148 | * NL80211_IFTYPE_P2P_DEVICE. The flag will be set by default if a device | 148 | * NL80211_IFTYPE_P2P_DEVICE. The flag will be set by default if a device |
149 | * includes any modes unsupported for enforcement checking. | 149 | * includes any modes unsupported for enforcement checking. |
150 | * @REGULATORY_WIPHY_SELF_MANAGED: for devices that employ wiphy-specific | ||
151 | * regdom management. These devices will ignore all regdom changes not | ||
152 | * originating from their own wiphy. | ||
153 | * A self-managed wiphys only employs regulatory information obtained from | ||
154 | * the FW and driver and does not use other cfg80211 sources like | ||
155 | * beacon-hints, country-code IEs and hints from other devices on the same | ||
156 | * system. Conversely, a self-managed wiphy does not share its regulatory | ||
157 | * hints with other devices in the system. If a system contains several | ||
158 | * devices, one or more of which are self-managed, there might be | ||
159 | * contradictory regulatory settings between them. Usage of flag is | ||
160 | * generally discouraged. Only use it if the FW/driver is incompatible | ||
161 | * with non-locally originated hints. | ||
162 | * This flag is incompatible with the flags: %REGULATORY_CUSTOM_REG, | ||
163 | * %REGULATORY_STRICT_REG, %REGULATORY_COUNTRY_IE_FOLLOW_POWER, | ||
164 | * %REGULATORY_COUNTRY_IE_IGNORE and %REGULATORY_DISABLE_BEACON_HINTS. | ||
165 | * Mixing any of the above flags with this flag will result in a failure | ||
166 | * to register the wiphy. This flag implies | ||
167 | * %REGULATORY_DISABLE_BEACON_HINTS and %REGULATORY_COUNTRY_IE_IGNORE. | ||
150 | */ | 168 | */ |
151 | enum ieee80211_regulatory_flags { | 169 | enum ieee80211_regulatory_flags { |
152 | REGULATORY_CUSTOM_REG = BIT(0), | 170 | REGULATORY_CUSTOM_REG = BIT(0), |
@@ -156,6 +174,7 @@ enum ieee80211_regulatory_flags { | |||
156 | REGULATORY_COUNTRY_IE_IGNORE = BIT(4), | 174 | REGULATORY_COUNTRY_IE_IGNORE = BIT(4), |
157 | REGULATORY_ENABLE_RELAX_NO_IR = BIT(5), | 175 | REGULATORY_ENABLE_RELAX_NO_IR = BIT(5), |
158 | REGULATORY_IGNORE_STALE_KICKOFF = BIT(6), | 176 | REGULATORY_IGNORE_STALE_KICKOFF = BIT(6), |
177 | REGULATORY_WIPHY_SELF_MANAGED = BIT(7), | ||
159 | }; | 178 | }; |
160 | 179 | ||
161 | struct ieee80211_freq_range { | 180 | struct ieee80211_freq_range { |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index b37bd5a1cb82..f52797a90816 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -29,6 +29,13 @@ | |||
29 | 29 | ||
30 | #define NL80211_GENL_NAME "nl80211" | 30 | #define NL80211_GENL_NAME "nl80211" |
31 | 31 | ||
32 | #define NL80211_MULTICAST_GROUP_CONFIG "config" | ||
33 | #define NL80211_MULTICAST_GROUP_SCAN "scan" | ||
34 | #define NL80211_MULTICAST_GROUP_REG "regulatory" | ||
35 | #define NL80211_MULTICAST_GROUP_MLME "mlme" | ||
36 | #define NL80211_MULTICAST_GROUP_VENDOR "vendor" | ||
37 | #define NL80211_MULTICAST_GROUP_TESTMODE "testmode" | ||
38 | |||
32 | /** | 39 | /** |
33 | * DOC: Station handling | 40 | * DOC: Station handling |
34 | * | 41 | * |
@@ -252,7 +259,18 @@ | |||
252 | * %NL80211_ATTR_IFINDEX. | 259 | * %NL80211_ATTR_IFINDEX. |
253 | * | 260 | * |
254 | * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set | 261 | * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set |
255 | * regulatory domain. | 262 | * regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device |
263 | * has a private regulatory domain, it will be returned. Otherwise, the | ||
264 | * global regdomain will be returned. | ||
265 | * A device will have a private regulatory domain if it uses the | ||
266 | * regulatory_hint() API. Even when a private regdomain is used the channel | ||
267 | * information will still be mended according to further hints from | ||
268 | * the regulatory core to help with compliance. A dump version of this API | ||
269 | * is now available which will returns the global regdomain as well as | ||
270 | * all private regdomains of present wiphys (for those that have it). | ||
271 | * If a wiphy is self-managed (%NL80211_ATTR_WIPHY_SELF_MANAGED_REG), then | ||
272 | * its private regdomain is the only valid one for it. The regulatory | ||
273 | * core is not used to help with compliance in this case. | ||
256 | * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command | 274 | * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command |
257 | * after being queried by the kernel. CRDA replies by sending a regulatory | 275 | * after being queried by the kernel. CRDA replies by sending a regulatory |
258 | * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our | 276 | * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our |
@@ -774,6 +792,10 @@ | |||
774 | * peer given by %NL80211_ATTR_MAC. Both peers must be on the base channel | 792 | * peer given by %NL80211_ATTR_MAC. Both peers must be on the base channel |
775 | * when this command completes. | 793 | * when this command completes. |
776 | * | 794 | * |
795 | * @NL80211_CMD_WIPHY_REG_CHANGE: Similar to %NL80211_CMD_REG_CHANGE, but used | ||
796 | * as an event to indicate changes for devices with wiphy-specific regdom | ||
797 | * management. | ||
798 | * | ||
777 | * @NL80211_CMD_MAX: highest used command number | 799 | * @NL80211_CMD_MAX: highest used command number |
778 | * @__NL80211_CMD_AFTER_LAST: internal use | 800 | * @__NL80211_CMD_AFTER_LAST: internal use |
779 | */ | 801 | */ |
@@ -958,6 +980,8 @@ enum nl80211_commands { | |||
958 | NL80211_CMD_TDLS_CHANNEL_SWITCH, | 980 | NL80211_CMD_TDLS_CHANNEL_SWITCH, |
959 | NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH, | 981 | NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH, |
960 | 982 | ||
983 | NL80211_CMD_WIPHY_REG_CHANGE, | ||
984 | |||
961 | /* add new commands above here */ | 985 | /* add new commands above here */ |
962 | 986 | ||
963 | /* used to define NL80211_CMD_MAX below */ | 987 | /* used to define NL80211_CMD_MAX below */ |
@@ -1655,6 +1679,9 @@ enum nl80211_commands { | |||
1655 | * @NL80211_ATTR_SOCKET_OWNER: Flag attribute, if set during interface | 1679 | * @NL80211_ATTR_SOCKET_OWNER: Flag attribute, if set during interface |
1656 | * creation then the new interface will be owned by the netlink socket | 1680 | * creation then the new interface will be owned by the netlink socket |
1657 | * that created it and will be destroyed when the socket is closed. | 1681 | * that created it and will be destroyed when the socket is closed. |
1682 | * If set during scheduled scan start then the new scan req will be | ||
1683 | * owned by the netlink socket that created it and the scheduled scan will | ||
1684 | * be stopped when the socket is closed. | ||
1658 | * | 1685 | * |
1659 | * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is | 1686 | * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is |
1660 | * the TDLS link initiator. | 1687 | * the TDLS link initiator. |
@@ -1688,6 +1715,26 @@ enum nl80211_commands { | |||
1688 | * | 1715 | * |
1689 | * @NL80211_ATTR_MAC_MASK: MAC address mask | 1716 | * @NL80211_ATTR_MAC_MASK: MAC address mask |
1690 | * | 1717 | * |
1718 | * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating this device | ||
1719 | * is self-managing its regulatory information and any regulatory domain | ||
1720 | * obtained from it is coming from the device's wiphy and not the global | ||
1721 | * cfg80211 regdomain. | ||
1722 | * | ||
1723 | * @NL80211_ATTR_EXT_FEATURES: extended feature flags contained in a byte | ||
1724 | * array. The feature flags are identified by their bit index (see &enum | ||
1725 | * nl80211_ext_feature_index). The bit index is ordered starting at the | ||
1726 | * least-significant bit of the first byte in the array, ie. bit index 0 | ||
1727 | * is located at bit 0 of byte 0. bit index 25 would be located at bit 1 | ||
1728 | * of byte 3 (u8 array). | ||
1729 | * | ||
1730 | * @NL80211_ATTR_SURVEY_RADIO_STATS: Request overall radio statistics to be | ||
1731 | * returned along with other survey data. If set, @NL80211_CMD_GET_SURVEY | ||
1732 | * may return a survey entry without a channel indicating global radio | ||
1733 | * statistics (only some values are valid and make sense.) | ||
1734 | * For devices that don't return such an entry even then, the information | ||
1735 | * should be contained in the result as the sum of the respective counters | ||
1736 | * over all channels. | ||
1737 | * | ||
1691 | * @NUM_NL80211_ATTR: total number of nl80211_attrs available | 1738 | * @NUM_NL80211_ATTR: total number of nl80211_attrs available |
1692 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1739 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1693 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1740 | * @__NL80211_ATTR_AFTER_LAST: internal use |
@@ -2045,6 +2092,12 @@ enum nl80211_attrs { | |||
2045 | 2092 | ||
2046 | NL80211_ATTR_MAC_MASK, | 2093 | NL80211_ATTR_MAC_MASK, |
2047 | 2094 | ||
2095 | NL80211_ATTR_WIPHY_SELF_MANAGED_REG, | ||
2096 | |||
2097 | NL80211_ATTR_EXT_FEATURES, | ||
2098 | |||
2099 | NL80211_ATTR_SURVEY_RADIO_STATS, | ||
2100 | |||
2048 | /* add attributes here, update the policy in nl80211.c */ | 2101 | /* add attributes here, update the policy in nl80211.c */ |
2049 | 2102 | ||
2050 | __NL80211_ATTR_AFTER_LAST, | 2103 | __NL80211_ATTR_AFTER_LAST, |
@@ -2085,7 +2138,7 @@ enum nl80211_attrs { | |||
2085 | 2138 | ||
2086 | #define NL80211_MAX_SUPP_RATES 32 | 2139 | #define NL80211_MAX_SUPP_RATES 32 |
2087 | #define NL80211_MAX_SUPP_HT_RATES 77 | 2140 | #define NL80211_MAX_SUPP_HT_RATES 77 |
2088 | #define NL80211_MAX_SUPP_REG_RULES 32 | 2141 | #define NL80211_MAX_SUPP_REG_RULES 64 |
2089 | #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 | 2142 | #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 |
2090 | #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 | 2143 | #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 |
2091 | #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 | 2144 | #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 |
@@ -2225,8 +2278,15 @@ struct nl80211_sta_flag_update { | |||
2225 | * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8) | 2278 | * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8) |
2226 | * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8) | 2279 | * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8) |
2227 | * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate | 2280 | * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate |
2228 | * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: 80+80 MHz VHT rate | 2281 | * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: unused - 80+80 is treated the |
2282 | * same as 160 for purposes of the bitrates | ||
2229 | * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate | 2283 | * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate |
2284 | * @NL80211_RATE_INFO_10_MHZ_WIDTH: 10 MHz width - note that this is | ||
2285 | * a legacy rate and will be reported as the actual bitrate, i.e. | ||
2286 | * half the base (20 MHz) rate | ||
2287 | * @NL80211_RATE_INFO_5_MHZ_WIDTH: 5 MHz width - note that this is | ||
2288 | * a legacy rate and will be reported as the actual bitrate, i.e. | ||
2289 | * a quarter of the base (20 MHz) rate | ||
2230 | * @__NL80211_RATE_INFO_AFTER_LAST: internal use | 2290 | * @__NL80211_RATE_INFO_AFTER_LAST: internal use |
2231 | */ | 2291 | */ |
2232 | enum nl80211_rate_info { | 2292 | enum nl80211_rate_info { |
@@ -2241,6 +2301,8 @@ enum nl80211_rate_info { | |||
2241 | NL80211_RATE_INFO_80_MHZ_WIDTH, | 2301 | NL80211_RATE_INFO_80_MHZ_WIDTH, |
2242 | NL80211_RATE_INFO_80P80_MHZ_WIDTH, | 2302 | NL80211_RATE_INFO_80P80_MHZ_WIDTH, |
2243 | NL80211_RATE_INFO_160_MHZ_WIDTH, | 2303 | NL80211_RATE_INFO_160_MHZ_WIDTH, |
2304 | NL80211_RATE_INFO_10_MHZ_WIDTH, | ||
2305 | NL80211_RATE_INFO_5_MHZ_WIDTH, | ||
2244 | 2306 | ||
2245 | /* keep last */ | 2307 | /* keep last */ |
2246 | __NL80211_RATE_INFO_AFTER_LAST, | 2308 | __NL80211_RATE_INFO_AFTER_LAST, |
@@ -2285,18 +2347,24 @@ enum nl80211_sta_bss_param { | |||
2285 | * | 2347 | * |
2286 | * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved | 2348 | * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved |
2287 | * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs) | 2349 | * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs) |
2288 | * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station) | 2350 | * @NL80211_STA_INFO_RX_BYTES: total received bytes (MPDU length) |
2289 | * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) | 2351 | * (u32, from this station) |
2290 | * @NL80211_STA_INFO_RX_BYTES64: total received bytes (u64, from this station) | 2352 | * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (MPDU length) |
2291 | * @NL80211_STA_INFO_TX_BYTES64: total transmitted bytes (u64, to this station) | 2353 | * (u32, to this station) |
2354 | * @NL80211_STA_INFO_RX_BYTES64: total received bytes (MPDU length) | ||
2355 | * (u64, from this station) | ||
2356 | * @NL80211_STA_INFO_TX_BYTES64: total transmitted bytes (MPDU length) | ||
2357 | * (u64, to this station) | ||
2292 | * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) | 2358 | * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) |
2293 | * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute | 2359 | * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute |
2294 | * containing info as possible, see &enum nl80211_rate_info | 2360 | * containing info as possible, see &enum nl80211_rate_info |
2295 | * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) | 2361 | * @NL80211_STA_INFO_RX_PACKETS: total received packet (MSDUs and MMPDUs) |
2296 | * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this | 2362 | * (u32, from this station) |
2297 | * station) | 2363 | * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (MSDUs and MMPDUs) |
2298 | * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) | 2364 | * (u32, to this station) |
2299 | * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) | 2365 | * @NL80211_STA_INFO_TX_RETRIES: total retries (MPDUs) (u32, to this station) |
2366 | * @NL80211_STA_INFO_TX_FAILED: total failed packets (MPDUs) | ||
2367 | * (u32, to this station) | ||
2300 | * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) | 2368 | * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) |
2301 | * @NL80211_STA_INFO_LLID: the station's mesh LLID | 2369 | * @NL80211_STA_INFO_LLID: the station's mesh LLID |
2302 | * @NL80211_STA_INFO_PLID: the station's mesh PLID | 2370 | * @NL80211_STA_INFO_PLID: the station's mesh PLID |
@@ -2320,6 +2388,16 @@ enum nl80211_sta_bss_param { | |||
2320 | * Same format as NL80211_STA_INFO_CHAIN_SIGNAL. | 2388 | * Same format as NL80211_STA_INFO_CHAIN_SIGNAL. |
2321 | * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the | 2389 | * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the |
2322 | * 802.11 header (u32, kbps) | 2390 | * 802.11 header (u32, kbps) |
2391 | * @NL80211_STA_INFO_RX_DROP_MISC: RX packets dropped for unspecified reasons | ||
2392 | * (u64) | ||
2393 | * @NL80211_STA_INFO_BEACON_RX: number of beacons received from this peer (u64) | ||
2394 | * @NL80211_STA_INFO_BEACON_SIGNAL_AVG: signal strength average | ||
2395 | * for beacons only (u8, dBm) | ||
2396 | * @NL80211_STA_INFO_TID_STATS: per-TID statistics (see &enum nl80211_tid_stats) | ||
2397 | * This is a nested attribute where each the inner attribute number is the | ||
2398 | * TID+1 and the special TID 16 (i.e. value 17) is used for non-QoS frames; | ||
2399 | * each one of those is again nested with &enum nl80211_tid_stats | ||
2400 | * attributes carrying the actual values. | ||
2323 | * @__NL80211_STA_INFO_AFTER_LAST: internal | 2401 | * @__NL80211_STA_INFO_AFTER_LAST: internal |
2324 | * @NL80211_STA_INFO_MAX: highest possible station info attribute | 2402 | * @NL80211_STA_INFO_MAX: highest possible station info attribute |
2325 | */ | 2403 | */ |
@@ -2352,6 +2430,10 @@ enum nl80211_sta_info { | |||
2352 | NL80211_STA_INFO_CHAIN_SIGNAL, | 2430 | NL80211_STA_INFO_CHAIN_SIGNAL, |
2353 | NL80211_STA_INFO_CHAIN_SIGNAL_AVG, | 2431 | NL80211_STA_INFO_CHAIN_SIGNAL_AVG, |
2354 | NL80211_STA_INFO_EXPECTED_THROUGHPUT, | 2432 | NL80211_STA_INFO_EXPECTED_THROUGHPUT, |
2433 | NL80211_STA_INFO_RX_DROP_MISC, | ||
2434 | NL80211_STA_INFO_BEACON_RX, | ||
2435 | NL80211_STA_INFO_BEACON_SIGNAL_AVG, | ||
2436 | NL80211_STA_INFO_TID_STATS, | ||
2355 | 2437 | ||
2356 | /* keep last */ | 2438 | /* keep last */ |
2357 | __NL80211_STA_INFO_AFTER_LAST, | 2439 | __NL80211_STA_INFO_AFTER_LAST, |
@@ -2359,6 +2441,31 @@ enum nl80211_sta_info { | |||
2359 | }; | 2441 | }; |
2360 | 2442 | ||
2361 | /** | 2443 | /** |
2444 | * enum nl80211_tid_stats - per TID statistics attributes | ||
2445 | * @__NL80211_TID_STATS_INVALID: attribute number 0 is reserved | ||
2446 | * @NL80211_TID_STATS_RX_MSDU: number of MSDUs received (u64) | ||
2447 | * @NL80211_TID_STATS_TX_MSDU: number of MSDUs transmitted (or | ||
2448 | * attempted to transmit; u64) | ||
2449 | * @NL80211_TID_STATS_TX_MSDU_RETRIES: number of retries for | ||
2450 | * transmitted MSDUs (not counting the first attempt; u64) | ||
2451 | * @NL80211_TID_STATS_TX_MSDU_FAILED: number of failed transmitted | ||
2452 | * MSDUs (u64) | ||
2453 | * @NUM_NL80211_TID_STATS: number of attributes here | ||
2454 | * @NL80211_TID_STATS_MAX: highest numbered attribute here | ||
2455 | */ | ||
2456 | enum nl80211_tid_stats { | ||
2457 | __NL80211_TID_STATS_INVALID, | ||
2458 | NL80211_TID_STATS_RX_MSDU, | ||
2459 | NL80211_TID_STATS_TX_MSDU, | ||
2460 | NL80211_TID_STATS_TX_MSDU_RETRIES, | ||
2461 | NL80211_TID_STATS_TX_MSDU_FAILED, | ||
2462 | |||
2463 | /* keep last */ | ||
2464 | NUM_NL80211_TID_STATS, | ||
2465 | NL80211_TID_STATS_MAX = NUM_NL80211_TID_STATS - 1 | ||
2466 | }; | ||
2467 | |||
2468 | /** | ||
2362 | * enum nl80211_mpath_flags - nl80211 mesh path flags | 2469 | * enum nl80211_mpath_flags - nl80211 mesh path flags |
2363 | * | 2470 | * |
2364 | * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active | 2471 | * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active |
@@ -2772,16 +2879,18 @@ enum nl80211_user_reg_hint_type { | |||
2772 | * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel | 2879 | * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel |
2773 | * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) | 2880 | * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) |
2774 | * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used | 2881 | * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used |
2775 | * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio | 2882 | * @NL80211_SURVEY_INFO_TIME: amount of time (in ms) that the radio |
2776 | * spent on this channel | 2883 | * was turned on (on channel or globally) |
2777 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary | 2884 | * @NL80211_SURVEY_INFO_TIME_BUSY: amount of the time the primary |
2778 | * channel was sensed busy (either due to activity or energy detect) | 2885 | * channel was sensed busy (either due to activity or energy detect) |
2779 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension | 2886 | * @NL80211_SURVEY_INFO_TIME_EXT_BUSY: amount of time the extension |
2780 | * channel was sensed busy | 2887 | * channel was sensed busy |
2781 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent | 2888 | * @NL80211_SURVEY_INFO_TIME_RX: amount of time the radio spent |
2782 | * receiving data | 2889 | * receiving data (on channel or globally) |
2783 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent | 2890 | * @NL80211_SURVEY_INFO_TIME_TX: amount of time the radio spent |
2784 | * transmitting data | 2891 | * transmitting data (on channel or globally) |
2892 | * @NL80211_SURVEY_INFO_TIME_SCAN: time the radio spent for scan | ||
2893 | * (on this channel or globally) | ||
2785 | * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number | 2894 | * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number |
2786 | * currently defined | 2895 | * currently defined |
2787 | * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use | 2896 | * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use |
@@ -2791,17 +2900,25 @@ enum nl80211_survey_info { | |||
2791 | NL80211_SURVEY_INFO_FREQUENCY, | 2900 | NL80211_SURVEY_INFO_FREQUENCY, |
2792 | NL80211_SURVEY_INFO_NOISE, | 2901 | NL80211_SURVEY_INFO_NOISE, |
2793 | NL80211_SURVEY_INFO_IN_USE, | 2902 | NL80211_SURVEY_INFO_IN_USE, |
2794 | NL80211_SURVEY_INFO_CHANNEL_TIME, | 2903 | NL80211_SURVEY_INFO_TIME, |
2795 | NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, | 2904 | NL80211_SURVEY_INFO_TIME_BUSY, |
2796 | NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, | 2905 | NL80211_SURVEY_INFO_TIME_EXT_BUSY, |
2797 | NL80211_SURVEY_INFO_CHANNEL_TIME_RX, | 2906 | NL80211_SURVEY_INFO_TIME_RX, |
2798 | NL80211_SURVEY_INFO_CHANNEL_TIME_TX, | 2907 | NL80211_SURVEY_INFO_TIME_TX, |
2908 | NL80211_SURVEY_INFO_TIME_SCAN, | ||
2799 | 2909 | ||
2800 | /* keep last */ | 2910 | /* keep last */ |
2801 | __NL80211_SURVEY_INFO_AFTER_LAST, | 2911 | __NL80211_SURVEY_INFO_AFTER_LAST, |
2802 | NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 | 2912 | NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 |
2803 | }; | 2913 | }; |
2804 | 2914 | ||
2915 | /* keep old names for compatibility */ | ||
2916 | #define NL80211_SURVEY_INFO_CHANNEL_TIME NL80211_SURVEY_INFO_TIME | ||
2917 | #define NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY NL80211_SURVEY_INFO_TIME_BUSY | ||
2918 | #define NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY NL80211_SURVEY_INFO_TIME_EXT_BUSY | ||
2919 | #define NL80211_SURVEY_INFO_CHANNEL_TIME_RX NL80211_SURVEY_INFO_TIME_RX | ||
2920 | #define NL80211_SURVEY_INFO_CHANNEL_TIME_TX NL80211_SURVEY_INFO_TIME_TX | ||
2921 | |||
2805 | /** | 2922 | /** |
2806 | * enum nl80211_mntr_flags - monitor configuration flags | 2923 | * enum nl80211_mntr_flags - monitor configuration flags |
2807 | * | 2924 | * |
@@ -3238,6 +3355,9 @@ enum nl80211_bss { | |||
3238 | /** | 3355 | /** |
3239 | * enum nl80211_bss_status - BSS "status" | 3356 | * enum nl80211_bss_status - BSS "status" |
3240 | * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS. | 3357 | * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS. |
3358 | * Note that this is no longer used since cfg80211 no longer | ||
3359 | * keeps track of whether or not authentication was done with | ||
3360 | * a given BSS. | ||
3241 | * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS. | 3361 | * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS. |
3242 | * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS. | 3362 | * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS. |
3243 | * | 3363 | * |
@@ -3623,7 +3743,9 @@ struct nl80211_pattern_support { | |||
3623 | * same attributes used with @NL80211_CMD_START_SCHED_SCAN. It | 3743 | * same attributes used with @NL80211_CMD_START_SCHED_SCAN. It |
3624 | * specifies how the scan is performed (e.g. the interval and the | 3744 | * specifies how the scan is performed (e.g. the interval and the |
3625 | * channels to scan) as well as the scan results that will | 3745 | * channels to scan) as well as the scan results that will |
3626 | * trigger a wake (i.e. the matchsets). | 3746 | * trigger a wake (i.e. the matchsets). This attribute is also |
3747 | * sent in a response to @NL80211_CMD_GET_WIPHY, indicating the | ||
3748 | * number of match sets supported by the driver (u32). | ||
3627 | * @NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS: nested attribute | 3749 | * @NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS: nested attribute |
3628 | * containing an array with information about what triggered the | 3750 | * containing an array with information about what triggered the |
3629 | * wake up. If no elements are present in the array, it means | 3751 | * wake up. If no elements are present in the array, it means |
@@ -4194,6 +4316,19 @@ enum nl80211_feature_flags { | |||
4194 | }; | 4316 | }; |
4195 | 4317 | ||
4196 | /** | 4318 | /** |
4319 | * enum nl80211_ext_feature_index - bit index of extended features. | ||
4320 | * | ||
4321 | * @NUM_NL80211_EXT_FEATURES: number of extended features. | ||
4322 | * @MAX_NL80211_EXT_FEATURES: highest extended feature index. | ||
4323 | */ | ||
4324 | enum nl80211_ext_feature_index { | ||
4325 | |||
4326 | /* add new features before the definition below */ | ||
4327 | NUM_NL80211_EXT_FEATURES, | ||
4328 | MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1 | ||
4329 | }; | ||
4330 | |||
4331 | /** | ||
4197 | * enum nl80211_probe_resp_offload_support_attr - optional supported | 4332 | * enum nl80211_probe_resp_offload_support_attr - optional supported |
4198 | * protocols for probe-response offloading by the driver/FW. | 4333 | * protocols for probe-response offloading by the driver/FW. |
4199 | * To be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD attribute. | 4334 | * To be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD attribute. |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index e75d5c53e97b..ff090ef1ea2c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -428,11 +428,13 @@ void sta_set_rate_info_tx(struct sta_info *sta, | |||
428 | rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); | 428 | rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); |
429 | } | 429 | } |
430 | if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | 430 | if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) |
431 | rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | 431 | rinfo->bw = RATE_INFO_BW_40; |
432 | if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) | 432 | else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) |
433 | rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; | 433 | rinfo->bw = RATE_INFO_BW_80; |
434 | if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) | 434 | else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) |
435 | rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; | 435 | rinfo->bw = RATE_INFO_BW_160; |
436 | else | ||
437 | rinfo->bw = RATE_INFO_BW_20; | ||
436 | if (rate->flags & IEEE80211_TX_RC_SHORT_GI) | 438 | if (rate->flags & IEEE80211_TX_RC_SHORT_GI) |
437 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; | 439 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; |
438 | } | 440 | } |
@@ -459,16 +461,21 @@ void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo) | |||
459 | rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); | 461 | rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); |
460 | } | 462 | } |
461 | 463 | ||
462 | if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) | ||
463 | rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | ||
464 | if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI) | 464 | if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI) |
465 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; | 465 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; |
466 | if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_80MHZ) | 466 | |
467 | rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; | 467 | if (sta->last_rx_rate_flag & RX_FLAG_5MHZ) |
468 | if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_80P80MHZ) | 468 | rinfo->bw = RATE_INFO_BW_5; |
469 | rinfo->flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH; | 469 | else if (sta->last_rx_rate_flag & RX_FLAG_10MHZ) |
470 | if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_160MHZ) | 470 | rinfo->bw = RATE_INFO_BW_10; |
471 | rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; | 471 | else if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) |
472 | rinfo->bw = RATE_INFO_BW_40; | ||
473 | else if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_80MHZ) | ||
474 | rinfo->bw = RATE_INFO_BW_80; | ||
475 | else if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_160MHZ) | ||
476 | rinfo->bw = RATE_INFO_BW_160; | ||
477 | else | ||
478 | rinfo->bw = RATE_INFO_BW_20; | ||
472 | } | 479 | } |
473 | 480 | ||
474 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, | 481 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, |
@@ -678,7 +685,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
678 | BSS_CHANGED_BEACON_ENABLED | | 685 | BSS_CHANGED_BEACON_ENABLED | |
679 | BSS_CHANGED_BEACON | | 686 | BSS_CHANGED_BEACON | |
680 | BSS_CHANGED_SSID | | 687 | BSS_CHANGED_SSID | |
681 | BSS_CHANGED_P2P_PS; | 688 | BSS_CHANGED_P2P_PS | |
689 | BSS_CHANGED_TXPOWER; | ||
682 | int err; | 690 | int err; |
683 | 691 | ||
684 | old = sdata_dereference(sdata->u.ap.beacon, sdata); | 692 | old = sdata_dereference(sdata->u.ap.beacon, sdata); |
@@ -2556,7 +2564,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
2556 | 2564 | ||
2557 | /* if there's one pending or we're scanning, queue this one */ | 2565 | /* if there's one pending or we're scanning, queue this one */ |
2558 | if (!list_empty(&local->roc_list) || | 2566 | if (!list_empty(&local->roc_list) || |
2559 | local->scanning || local->radar_detect_enabled) | 2567 | local->scanning || ieee80211_is_radar_required(local)) |
2560 | goto out_check_combine; | 2568 | goto out_check_combine; |
2561 | 2569 | ||
2562 | /* if not HW assist, just queue & schedule work */ | 2570 | /* if not HW assist, just queue & schedule work */ |
@@ -3664,7 +3672,7 @@ static int ieee80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev, | |||
3664 | * queues. | 3672 | * queues. |
3665 | */ | 3673 | */ |
3666 | synchronize_net(); | 3674 | synchronize_net(); |
3667 | ieee80211_flush_queues(local, sdata); | 3675 | ieee80211_flush_queues(local, sdata, false); |
3668 | 3676 | ||
3669 | /* restore the normal QoS parameters | 3677 | /* restore the normal QoS parameters |
3670 | * (unconditionally to avoid races) | 3678 | * (unconditionally to avoid races) |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index da1c12c34487..35b11e11e0c4 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -388,7 +388,7 @@ ieee80211_find_chanctx(struct ieee80211_local *local, | |||
388 | return NULL; | 388 | return NULL; |
389 | } | 389 | } |
390 | 390 | ||
391 | static bool ieee80211_is_radar_required(struct ieee80211_local *local) | 391 | bool ieee80211_is_radar_required(struct ieee80211_local *local) |
392 | { | 392 | { |
393 | struct ieee80211_sub_if_data *sdata; | 393 | struct ieee80211_sub_if_data *sdata; |
394 | 394 | ||
@@ -406,6 +406,34 @@ static bool ieee80211_is_radar_required(struct ieee80211_local *local) | |||
406 | return false; | 406 | return false; |
407 | } | 407 | } |
408 | 408 | ||
409 | static bool | ||
410 | ieee80211_chanctx_radar_required(struct ieee80211_local *local, | ||
411 | struct ieee80211_chanctx *ctx) | ||
412 | { | ||
413 | struct ieee80211_chanctx_conf *conf = &ctx->conf; | ||
414 | struct ieee80211_sub_if_data *sdata; | ||
415 | bool required = false; | ||
416 | |||
417 | lockdep_assert_held(&local->chanctx_mtx); | ||
418 | lockdep_assert_held(&local->mtx); | ||
419 | |||
420 | rcu_read_lock(); | ||
421 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
422 | if (!ieee80211_sdata_running(sdata)) | ||
423 | continue; | ||
424 | if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) | ||
425 | continue; | ||
426 | if (!sdata->radar_required) | ||
427 | continue; | ||
428 | |||
429 | required = true; | ||
430 | break; | ||
431 | } | ||
432 | rcu_read_unlock(); | ||
433 | |||
434 | return required; | ||
435 | } | ||
436 | |||
409 | static struct ieee80211_chanctx * | 437 | static struct ieee80211_chanctx * |
410 | ieee80211_alloc_chanctx(struct ieee80211_local *local, | 438 | ieee80211_alloc_chanctx(struct ieee80211_local *local, |
411 | const struct cfg80211_chan_def *chandef, | 439 | const struct cfg80211_chan_def *chandef, |
@@ -425,7 +453,7 @@ ieee80211_alloc_chanctx(struct ieee80211_local *local, | |||
425 | ctx->conf.rx_chains_static = 1; | 453 | ctx->conf.rx_chains_static = 1; |
426 | ctx->conf.rx_chains_dynamic = 1; | 454 | ctx->conf.rx_chains_dynamic = 1; |
427 | ctx->mode = mode; | 455 | ctx->mode = mode; |
428 | ctx->conf.radar_enabled = ieee80211_is_radar_required(local); | 456 | ctx->conf.radar_enabled = false; |
429 | ieee80211_recalc_chanctx_min_def(local, ctx); | 457 | ieee80211_recalc_chanctx_min_def(local, ctx); |
430 | 458 | ||
431 | return ctx; | 459 | return ctx; |
@@ -567,16 +595,15 @@ static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, | |||
567 | bool radar_enabled; | 595 | bool radar_enabled; |
568 | 596 | ||
569 | lockdep_assert_held(&local->chanctx_mtx); | 597 | lockdep_assert_held(&local->chanctx_mtx); |
570 | /* for setting local->radar_detect_enabled */ | 598 | /* for ieee80211_is_radar_required */ |
571 | lockdep_assert_held(&local->mtx); | 599 | lockdep_assert_held(&local->mtx); |
572 | 600 | ||
573 | radar_enabled = ieee80211_is_radar_required(local); | 601 | radar_enabled = ieee80211_chanctx_radar_required(local, chanctx); |
574 | 602 | ||
575 | if (radar_enabled == chanctx->conf.radar_enabled) | 603 | if (radar_enabled == chanctx->conf.radar_enabled) |
576 | return; | 604 | return; |
577 | 605 | ||
578 | chanctx->conf.radar_enabled = radar_enabled; | 606 | chanctx->conf.radar_enabled = radar_enabled; |
579 | local->radar_detect_enabled = chanctx->conf.radar_enabled; | ||
580 | 607 | ||
581 | if (!local->use_chanctx) { | 608 | if (!local->use_chanctx) { |
582 | local->hw.conf.radar_enabled = chanctx->conf.radar_enabled; | 609 | local->hw.conf.radar_enabled = chanctx->conf.radar_enabled; |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 54a189f0393e..eeb0bbd69d98 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -303,8 +303,6 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf, | |||
303 | sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n"); | 303 | sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n"); |
304 | if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE) | 304 | if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE) |
305 | sf += scnprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n"); | 305 | sf += scnprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n"); |
306 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) | ||
307 | sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_UAPSD\n"); | ||
308 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | 306 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) |
309 | sf += scnprintf(buf + sf, mxln - sf, | 307 | sf += scnprintf(buf + sf, mxln - sf, |
310 | "REPORTS_TX_ACK_STATUS\n"); | 308 | "REPORTS_TX_ACK_STATUS\n"); |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 2ebc9ead9695..fdeda17b8dd2 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -639,6 +639,21 @@ static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local, | |||
639 | trace_drv_return_void(local); | 639 | trace_drv_return_void(local); |
640 | } | 640 | } |
641 | 641 | ||
642 | static inline void drv_sta_statistics(struct ieee80211_local *local, | ||
643 | struct ieee80211_sub_if_data *sdata, | ||
644 | struct ieee80211_sta *sta, | ||
645 | struct station_info *sinfo) | ||
646 | { | ||
647 | sdata = get_bss_sdata(sdata); | ||
648 | if (!check_sdata_in_driver(sdata)) | ||
649 | return; | ||
650 | |||
651 | trace_drv_sta_statistics(local, sdata, sta); | ||
652 | if (local->ops->sta_statistics) | ||
653 | local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo); | ||
654 | trace_drv_return_void(local); | ||
655 | } | ||
656 | |||
642 | static inline int drv_conf_tx(struct ieee80211_local *local, | 657 | static inline int drv_conf_tx(struct ieee80211_local *local, |
643 | struct ieee80211_sub_if_data *sdata, u16 ac, | 658 | struct ieee80211_sub_if_data *sdata, u16 ac, |
644 | const struct ieee80211_tx_queue_params *params) | 659 | const struct ieee80211_tx_queue_params *params) |
@@ -966,21 +981,6 @@ drv_allow_buffered_frames(struct ieee80211_local *local, | |||
966 | trace_drv_return_void(local); | 981 | trace_drv_return_void(local); |
967 | } | 982 | } |
968 | 983 | ||
969 | static inline int drv_get_rssi(struct ieee80211_local *local, | ||
970 | struct ieee80211_sub_if_data *sdata, | ||
971 | struct ieee80211_sta *sta, | ||
972 | s8 *rssi_dbm) | ||
973 | { | ||
974 | int ret; | ||
975 | |||
976 | might_sleep(); | ||
977 | |||
978 | ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm); | ||
979 | trace_drv_get_rssi(local, sta, *rssi_dbm, ret); | ||
980 | |||
981 | return ret; | ||
982 | } | ||
983 | |||
984 | static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, | 984 | static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, |
985 | struct ieee80211_sub_if_data *sdata) | 985 | struct ieee80211_sub_if_data *sdata) |
986 | { | 986 | { |
diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c index ebfc8091557b..52bcea6ad9e8 100644 --- a/net/mac80211/ethtool.c +++ b/net/mac80211/ethtool.c | |||
@@ -117,16 +117,16 @@ static void ieee80211_get_stats(struct net_device *dev, | |||
117 | data[i++] = sta->sta_state; | 117 | data[i++] = sta->sta_state; |
118 | 118 | ||
119 | 119 | ||
120 | if (sinfo.filled & STATION_INFO_TX_BITRATE) | 120 | if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) |
121 | data[i] = 100000 * | 121 | data[i] = 100000 * |
122 | cfg80211_calculate_bitrate(&sinfo.txrate); | 122 | cfg80211_calculate_bitrate(&sinfo.txrate); |
123 | i++; | 123 | i++; |
124 | if (sinfo.filled & STATION_INFO_RX_BITRATE) | 124 | if (sinfo.filled & BIT(NL80211_STA_INFO_RX_BITRATE)) |
125 | data[i] = 100000 * | 125 | data[i] = 100000 * |
126 | cfg80211_calculate_bitrate(&sinfo.rxrate); | 126 | cfg80211_calculate_bitrate(&sinfo.rxrate); |
127 | i++; | 127 | i++; |
128 | 128 | ||
129 | if (sinfo.filled & STATION_INFO_SIGNAL_AVG) | 129 | if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL_AVG)) |
130 | data[i] = (u8)sinfo.signal_avg; | 130 | data[i] = (u8)sinfo.signal_avg; |
131 | i++; | 131 | i++; |
132 | } else { | 132 | } else { |
@@ -175,24 +175,24 @@ do_survey: | |||
175 | data[i++] = (u8)survey.noise; | 175 | data[i++] = (u8)survey.noise; |
176 | else | 176 | else |
177 | data[i++] = -1LL; | 177 | data[i++] = -1LL; |
178 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME) | 178 | if (survey.filled & SURVEY_INFO_TIME) |
179 | data[i++] = survey.channel_time; | 179 | data[i++] = survey.time; |
180 | else | 180 | else |
181 | data[i++] = -1LL; | 181 | data[i++] = -1LL; |
182 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY) | 182 | if (survey.filled & SURVEY_INFO_TIME_BUSY) |
183 | data[i++] = survey.channel_time_busy; | 183 | data[i++] = survey.time_busy; |
184 | else | 184 | else |
185 | data[i++] = -1LL; | 185 | data[i++] = -1LL; |
186 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) | 186 | if (survey.filled & SURVEY_INFO_TIME_EXT_BUSY) |
187 | data[i++] = survey.channel_time_ext_busy; | 187 | data[i++] = survey.time_ext_busy; |
188 | else | 188 | else |
189 | data[i++] = -1LL; | 189 | data[i++] = -1LL; |
190 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX) | 190 | if (survey.filled & SURVEY_INFO_TIME_RX) |
191 | data[i++] = survey.channel_time_rx; | 191 | data[i++] = survey.time_rx; |
192 | else | 192 | else |
193 | data[i++] = -1LL; | 193 | data[i++] = -1LL; |
194 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX) | 194 | if (survey.filled & SURVEY_INFO_TIME_TX) |
195 | data[i++] = survey.channel_time_tx; | 195 | data[i++] = survey.time_tx; |
196 | else | 196 | else |
197 | data[i++] = -1LL; | 197 | data[i++] = -1LL; |
198 | 198 | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 509bc157ce55..b606b53a49a7 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -1069,9 +1069,16 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | if (sta && rates_updated) { | 1071 | if (sta && rates_updated) { |
1072 | drv_sta_rc_update(local, sdata, &sta->sta, | 1072 | u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED; |
1073 | IEEE80211_RC_SUPP_RATES_CHANGED); | 1073 | u8 rx_nss = sta->sta.rx_nss; |
1074 | |||
1075 | /* Force rx_nss recalculation */ | ||
1076 | sta->sta.rx_nss = 0; | ||
1074 | rate_control_rate_init(sta); | 1077 | rate_control_rate_init(sta); |
1078 | if (sta->sta.rx_nss != rx_nss) | ||
1079 | changed |= IEEE80211_RC_NSS_CHANGED; | ||
1080 | |||
1081 | drv_sta_rc_update(local, sdata, &sta->sta, changed); | ||
1075 | } | 1082 | } |
1076 | 1083 | ||
1077 | rcu_read_unlock(); | 1084 | rcu_read_unlock(); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index cc6e964d9837..156ea79e0157 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1168,8 +1168,6 @@ struct ieee80211_local { | |||
1168 | /* wowlan is enabled -- don't reconfig on resume */ | 1168 | /* wowlan is enabled -- don't reconfig on resume */ |
1169 | bool wowlan; | 1169 | bool wowlan; |
1170 | 1170 | ||
1171 | /* DFS/radar detection is enabled */ | ||
1172 | bool radar_detect_enabled; | ||
1173 | struct work_struct radar_detected_work; | 1171 | struct work_struct radar_detected_work; |
1174 | 1172 | ||
1175 | /* number of RX chains the hardware has */ | 1173 | /* number of RX chains the hardware has */ |
@@ -1704,6 +1702,7 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | |||
1704 | struct ieee80211_supported_band *sband, | 1702 | struct ieee80211_supported_band *sband, |
1705 | const struct ieee80211_vht_cap *vht_cap_ie, | 1703 | const struct ieee80211_vht_cap *vht_cap_ie, |
1706 | struct sta_info *sta); | 1704 | struct sta_info *sta); |
1705 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta); | ||
1707 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta); | 1706 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta); |
1708 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); | 1707 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); |
1709 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | 1708 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, |
@@ -1881,10 +1880,10 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
1881 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, | 1880 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, |
1882 | struct sk_buff_head *skbs); | 1881 | struct sk_buff_head *skbs); |
1883 | void ieee80211_flush_queues(struct ieee80211_local *local, | 1882 | void ieee80211_flush_queues(struct ieee80211_local *local, |
1884 | struct ieee80211_sub_if_data *sdata); | 1883 | struct ieee80211_sub_if_data *sdata, bool drop); |
1885 | void __ieee80211_flush_queues(struct ieee80211_local *local, | 1884 | void __ieee80211_flush_queues(struct ieee80211_local *local, |
1886 | struct ieee80211_sub_if_data *sdata, | 1885 | struct ieee80211_sub_if_data *sdata, |
1887 | unsigned int queues); | 1886 | unsigned int queues, bool drop); |
1888 | 1887 | ||
1889 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1888 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
1890 | u16 transaction, u16 auth_alg, u16 status, | 1889 | u16 transaction, u16 auth_alg, u16 status, |
@@ -1981,6 +1980,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, | |||
1981 | struct ieee80211_chanctx *chanctx); | 1980 | struct ieee80211_chanctx *chanctx); |
1982 | void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, | 1981 | void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, |
1983 | struct ieee80211_chanctx *ctx); | 1982 | struct ieee80211_chanctx *ctx); |
1983 | bool ieee80211_is_radar_required(struct ieee80211_local *local); | ||
1984 | 1984 | ||
1985 | void ieee80211_dfs_cac_timer(unsigned long data); | 1985 | void ieee80211_dfs_cac_timer(unsigned long data); |
1986 | void ieee80211_dfs_cac_timer_work(struct work_struct *work); | 1986 | void ieee80211_dfs_cac_timer_work(struct work_struct *work); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 417355390873..677422e11e07 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -93,7 +93,7 @@ static u32 __ieee80211_idle_on(struct ieee80211_local *local) | |||
93 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) | 93 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) |
94 | return 0; | 94 | return 0; |
95 | 95 | ||
96 | ieee80211_flush_queues(local, NULL); | 96 | ieee80211_flush_queues(local, NULL, false); |
97 | 97 | ||
98 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; | 98 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; |
99 | return IEEE80211_CONF_CHANGE_IDLE; | 99 | return IEEE80211_CONF_CHANGE_IDLE; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 0bb7038121ac..f8d9f0ee59bf 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -140,7 +140,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
140 | if (!ret) { | 140 | if (!ret) { |
141 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; | 141 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
142 | 142 | ||
143 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | 143 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
144 | (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) | ||
144 | sdata->crypto_tx_tailroom_needed_cnt--; | 145 | sdata->crypto_tx_tailroom_needed_cnt--; |
145 | 146 | ||
146 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && | 147 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && |
@@ -188,7 +189,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
188 | sta = key->sta; | 189 | sta = key->sta; |
189 | sdata = key->sdata; | 190 | sdata = key->sdata; |
190 | 191 | ||
191 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | 192 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
193 | (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) | ||
192 | increment_tailroom_need_count(sdata); | 194 | increment_tailroom_need_count(sdata); |
193 | 195 | ||
194 | ret = drv_set_key(key->local, DISABLE_KEY, sdata, | 196 | ret = drv_set_key(key->local, DISABLE_KEY, sdata, |
@@ -884,7 +886,8 @@ void ieee80211_remove_key(struct ieee80211_key_conf *keyconf) | |||
884 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 886 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
885 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 887 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
886 | 888 | ||
887 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | 889 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
890 | (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) | ||
888 | increment_tailroom_need_count(key->sdata); | 891 | increment_tailroom_need_count(key->sdata); |
889 | } | 892 | } |
890 | 893 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 6ab99da38db9..d9ce33663c73 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -916,10 +916,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
916 | } | 916 | } |
917 | } | 917 | } |
918 | 918 | ||
919 | WARN((local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) | ||
920 | && (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK), | ||
921 | "U-APSD not supported with HW_PS_NULLFUNC_STACK\n"); | ||
922 | |||
923 | /* | 919 | /* |
924 | * Calculate scan IE length -- we need this to alloc | 920 | * Calculate scan IE length -- we need this to alloc |
925 | * memory and to subtract from the driver limit. It | 921 | * memory and to subtract from the driver limit. It |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index b488e1859b18..fa94ca15ba95 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -523,6 +523,13 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, | |||
523 | sdata->u.mesh.mshcfg.auto_open_plinks && | 523 | sdata->u.mesh.mshcfg.auto_open_plinks && |
524 | rssi_threshold_check(sdata, sta)) | 524 | rssi_threshold_check(sdata, sta)) |
525 | changed = mesh_plink_open(sta); | 525 | changed = mesh_plink_open(sta); |
526 | else if (sta->plink_state == NL80211_PLINK_LISTEN && | ||
527 | (sdata->u.mesh.user_mpm || | ||
528 | sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)) | ||
529 | cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, | ||
530 | elems->ie_start, | ||
531 | elems->total_len, | ||
532 | GFP_ATOMIC); | ||
526 | 533 | ||
527 | ieee80211_mps_frame_release(sta, elems); | 534 | ieee80211_mps_frame_release(sta, elems); |
528 | out: | 535 | out: |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2c36c4765f47..1875181ebd94 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -157,14 +157,18 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | |||
157 | { | 157 | { |
158 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 158 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
159 | struct cfg80211_chan_def vht_chandef; | 159 | struct cfg80211_chan_def vht_chandef; |
160 | struct ieee80211_sta_ht_cap sta_ht_cap; | ||
160 | u32 ht_cfreq, ret; | 161 | u32 ht_cfreq, ret; |
161 | 162 | ||
163 | memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap)); | ||
164 | ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap); | ||
165 | |||
162 | chandef->chan = channel; | 166 | chandef->chan = channel; |
163 | chandef->width = NL80211_CHAN_WIDTH_20_NOHT; | 167 | chandef->width = NL80211_CHAN_WIDTH_20_NOHT; |
164 | chandef->center_freq1 = channel->center_freq; | 168 | chandef->center_freq1 = channel->center_freq; |
165 | chandef->center_freq2 = 0; | 169 | chandef->center_freq2 = 0; |
166 | 170 | ||
167 | if (!ht_cap || !ht_oper || !sband->ht_cap.ht_supported) { | 171 | if (!ht_cap || !ht_oper || !sta_ht_cap.ht_supported) { |
168 | ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; | 172 | ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; |
169 | goto out; | 173 | goto out; |
170 | } | 174 | } |
@@ -198,7 +202,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | |||
198 | } | 202 | } |
199 | 203 | ||
200 | /* check 40 MHz support, if we have it */ | 204 | /* check 40 MHz support, if we have it */ |
201 | if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { | 205 | if (sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { |
202 | switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 206 | switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
203 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 207 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
204 | chandef->width = NL80211_CHAN_WIDTH_40; | 208 | chandef->width = NL80211_CHAN_WIDTH_40; |
@@ -1054,8 +1058,6 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata) | |||
1054 | sdata->csa_block_tx = false; | 1058 | sdata->csa_block_tx = false; |
1055 | } | 1059 | } |
1056 | 1060 | ||
1057 | cfg80211_ch_switch_notify(sdata->dev, &sdata->reserved_chandef); | ||
1058 | |||
1059 | sdata->vif.csa_active = false; | 1061 | sdata->vif.csa_active = false; |
1060 | ifmgd->csa_waiting_bcn = false; | 1062 | ifmgd->csa_waiting_bcn = false; |
1061 | 1063 | ||
@@ -1067,6 +1069,8 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata) | |||
1067 | &ifmgd->csa_connection_drop_work); | 1069 | &ifmgd->csa_connection_drop_work); |
1068 | return; | 1070 | return; |
1069 | } | 1071 | } |
1072 | |||
1073 | cfg80211_ch_switch_notify(sdata->dev, &sdata->reserved_chandef); | ||
1070 | } | 1074 | } |
1071 | 1075 | ||
1072 | void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) | 1076 | void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) |
@@ -1284,8 +1288,11 @@ ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata, | |||
1284 | country_ie_len -= 3; | 1288 | country_ie_len -= 3; |
1285 | } | 1289 | } |
1286 | 1290 | ||
1287 | if (have_chan_pwr) | 1291 | if (have_chan_pwr && pwr_constr_elem) |
1288 | *pwr_reduction = *pwr_constr_elem; | 1292 | *pwr_reduction = *pwr_constr_elem; |
1293 | else | ||
1294 | *pwr_reduction = 0; | ||
1295 | |||
1289 | return have_chan_pwr; | 1296 | return have_chan_pwr; |
1290 | } | 1297 | } |
1291 | 1298 | ||
@@ -1314,10 +1321,11 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, | |||
1314 | int chan_pwr = 0, pwr_reduction_80211h = 0; | 1321 | int chan_pwr = 0, pwr_reduction_80211h = 0; |
1315 | int pwr_level_cisco, pwr_level_80211h; | 1322 | int pwr_level_cisco, pwr_level_80211h; |
1316 | int new_ap_level; | 1323 | int new_ap_level; |
1324 | __le16 capab = mgmt->u.probe_resp.capab_info; | ||
1317 | 1325 | ||
1318 | if (country_ie && pwr_constr_ie && | 1326 | if (country_ie && |
1319 | mgmt->u.probe_resp.capab_info & | 1327 | (capab & cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT) || |
1320 | cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) { | 1328 | capab & cpu_to_le16(WLAN_CAPABILITY_RADIO_MEASURE))) { |
1321 | has_80211h_pwr = ieee80211_find_80211h_pwr_constr( | 1329 | has_80211h_pwr = ieee80211_find_80211h_pwr_constr( |
1322 | sdata, channel, country_ie, country_ie_len, | 1330 | sdata, channel, country_ie, country_ie_len, |
1323 | pwr_constr_ie, &chan_pwr, &pwr_reduction_80211h); | 1331 | pwr_constr_ie, &chan_pwr, &pwr_reduction_80211h); |
@@ -1596,7 +1604,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | |||
1596 | } else { | 1604 | } else { |
1597 | ieee80211_send_nullfunc(local, sdata, 1); | 1605 | ieee80211_send_nullfunc(local, sdata, 1); |
1598 | /* Flush to get the tx status of nullfunc frame */ | 1606 | /* Flush to get the tx status of nullfunc frame */ |
1599 | ieee80211_flush_queues(local, sdata); | 1607 | ieee80211_flush_queues(local, sdata, false); |
1600 | } | 1608 | } |
1601 | } | 1609 | } |
1602 | 1610 | ||
@@ -2003,18 +2011,23 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2003 | /* disable per-vif ps */ | 2011 | /* disable per-vif ps */ |
2004 | ieee80211_recalc_ps_vif(sdata); | 2012 | ieee80211_recalc_ps_vif(sdata); |
2005 | 2013 | ||
2006 | /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ | 2014 | /* |
2015 | * drop any frame before deauth/disassoc, this can be data or | ||
2016 | * management frame. Since we are disconnecting, we should not | ||
2017 | * insist sending these frames which can take time and delay | ||
2018 | * the disconnection and possible the roaming. | ||
2019 | */ | ||
2007 | if (tx) | 2020 | if (tx) |
2008 | ieee80211_flush_queues(local, sdata); | 2021 | ieee80211_flush_queues(local, sdata, true); |
2009 | 2022 | ||
2010 | /* deauthenticate/disassociate now */ | 2023 | /* deauthenticate/disassociate now */ |
2011 | if (tx || frame_buf) | 2024 | if (tx || frame_buf) |
2012 | ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, | 2025 | ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, |
2013 | reason, tx, frame_buf); | 2026 | reason, tx, frame_buf); |
2014 | 2027 | ||
2015 | /* flush out frame */ | 2028 | /* flush out frame - make sure the deauth was actually sent */ |
2016 | if (tx) | 2029 | if (tx) |
2017 | ieee80211_flush_queues(local, sdata); | 2030 | ieee80211_flush_queues(local, sdata, false); |
2018 | 2031 | ||
2019 | /* clear bssid only after building the needed mgmt frames */ | 2032 | /* clear bssid only after building the needed mgmt frames */ |
2020 | memset(ifmgd->bssid, 0, ETH_ALEN); | 2033 | memset(ifmgd->bssid, 0, ETH_ALEN); |
@@ -2440,6 +2453,12 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, | |||
2440 | sdata_assert_lock(sdata); | 2453 | sdata_assert_lock(sdata); |
2441 | 2454 | ||
2442 | if (!assoc) { | 2455 | if (!assoc) { |
2456 | /* | ||
2457 | * we are not authenticated yet, the only timer that could be | ||
2458 | * running is the timeout for the authentication response which | ||
2459 | * which is not relevant anymore. | ||
2460 | */ | ||
2461 | del_timer_sync(&sdata->u.mgd.timer); | ||
2443 | sta_info_destroy_addr(sdata, auth_data->bss->bssid); | 2462 | sta_info_destroy_addr(sdata, auth_data->bss->bssid); |
2444 | 2463 | ||
2445 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | 2464 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); |
@@ -2747,6 +2766,12 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, | |||
2747 | sdata_assert_lock(sdata); | 2766 | sdata_assert_lock(sdata); |
2748 | 2767 | ||
2749 | if (!assoc) { | 2768 | if (!assoc) { |
2769 | /* | ||
2770 | * we are not associated yet, the only timer that could be | ||
2771 | * running is the timeout for the association response which | ||
2772 | * which is not relevant anymore. | ||
2773 | */ | ||
2774 | del_timer_sync(&sdata->u.mgd.timer); | ||
2750 | sta_info_destroy_addr(sdata, assoc_data->bss->bssid); | 2775 | sta_info_destroy_addr(sdata, assoc_data->bss->bssid); |
2751 | 2776 | ||
2752 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | 2777 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); |
@@ -4197,9 +4222,13 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
4197 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 4222 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
4198 | struct ieee80211_bss *bss = (void *)cbss->priv; | 4223 | struct ieee80211_bss *bss = (void *)cbss->priv; |
4199 | struct sta_info *new_sta = NULL; | 4224 | struct sta_info *new_sta = NULL; |
4200 | bool have_sta = false; | 4225 | struct ieee80211_supported_band *sband; |
4226 | struct ieee80211_sta_ht_cap sta_ht_cap; | ||
4227 | bool have_sta = false, is_override = false; | ||
4201 | int err; | 4228 | int err; |
4202 | 4229 | ||
4230 | sband = local->hw.wiphy->bands[cbss->channel->band]; | ||
4231 | |||
4203 | if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) | 4232 | if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) |
4204 | return -EINVAL; | 4233 | return -EINVAL; |
4205 | 4234 | ||
@@ -4214,25 +4243,32 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
4214 | if (!new_sta) | 4243 | if (!new_sta) |
4215 | return -ENOMEM; | 4244 | return -ENOMEM; |
4216 | } | 4245 | } |
4246 | |||
4247 | memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap)); | ||
4248 | ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap); | ||
4249 | |||
4250 | is_override = (sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) != | ||
4251 | (sband->ht_cap.cap & | ||
4252 | IEEE80211_HT_CAP_SUP_WIDTH_20_40); | ||
4253 | |||
4254 | if (new_sta || is_override) { | ||
4255 | err = ieee80211_prep_channel(sdata, cbss); | ||
4256 | if (err) { | ||
4257 | if (new_sta) | ||
4258 | sta_info_free(local, new_sta); | ||
4259 | return -EINVAL; | ||
4260 | } | ||
4261 | } | ||
4262 | |||
4217 | if (new_sta) { | 4263 | if (new_sta) { |
4218 | u32 rates = 0, basic_rates = 0; | 4264 | u32 rates = 0, basic_rates = 0; |
4219 | bool have_higher_than_11mbit; | 4265 | bool have_higher_than_11mbit; |
4220 | int min_rate = INT_MAX, min_rate_index = -1; | 4266 | int min_rate = INT_MAX, min_rate_index = -1; |
4221 | struct ieee80211_chanctx_conf *chanctx_conf; | 4267 | struct ieee80211_chanctx_conf *chanctx_conf; |
4222 | struct ieee80211_supported_band *sband; | ||
4223 | const struct cfg80211_bss_ies *ies; | 4268 | const struct cfg80211_bss_ies *ies; |
4224 | int shift; | 4269 | int shift = ieee80211_vif_get_shift(&sdata->vif); |
4225 | u32 rate_flags; | 4270 | u32 rate_flags; |
4226 | 4271 | ||
4227 | sband = local->hw.wiphy->bands[cbss->channel->band]; | ||
4228 | |||
4229 | err = ieee80211_prep_channel(sdata, cbss); | ||
4230 | if (err) { | ||
4231 | sta_info_free(local, new_sta); | ||
4232 | return -EINVAL; | ||
4233 | } | ||
4234 | shift = ieee80211_vif_get_shift(&sdata->vif); | ||
4235 | |||
4236 | rcu_read_lock(); | 4272 | rcu_read_lock(); |
4237 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 4273 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
4238 | if (WARN_ON(!chanctx_conf)) { | 4274 | if (WARN_ON(!chanctx_conf)) { |
@@ -4668,8 +4704,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4668 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; | 4704 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; |
4669 | rcu_read_unlock(); | 4705 | rcu_read_unlock(); |
4670 | 4706 | ||
4707 | if (WARN((sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_UAPSD) && | ||
4708 | (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK), | ||
4709 | "U-APSD not supported with HW_PS_NULLFUNC_STACK\n")) | ||
4710 | sdata->vif.driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD; | ||
4711 | |||
4671 | if (bss->wmm_used && bss->uapsd_supported && | 4712 | if (bss->wmm_used && bss->uapsd_supported && |
4672 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { | 4713 | (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_UAPSD)) { |
4673 | assoc_data->uapsd = true; | 4714 | assoc_data->uapsd = true; |
4674 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; | 4715 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; |
4675 | } else { | 4716 | } else { |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index ff20b2ebdb30..683f0e3cb124 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -121,7 +121,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local) | |||
121 | ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, | 121 | ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, |
122 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, | 122 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, |
123 | false); | 123 | false); |
124 | ieee80211_flush_queues(local, NULL); | 124 | ieee80211_flush_queues(local, NULL, false); |
125 | 125 | ||
126 | mutex_lock(&local->iflist_mtx); | 126 | mutex_lock(&local->iflist_mtx); |
127 | list_for_each_entry(sdata, &local->interfaces, list) { | 127 | list_for_each_entry(sdata, &local->interfaces, list) { |
@@ -398,7 +398,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
398 | ieee80211_roc_notify_destroy(roc, !roc->abort); | 398 | ieee80211_roc_notify_destroy(roc, !roc->abort); |
399 | 399 | ||
400 | if (started && !on_channel) { | 400 | if (started && !on_channel) { |
401 | ieee80211_flush_queues(local, NULL); | 401 | ieee80211_flush_queues(local, NULL, false); |
402 | 402 | ||
403 | local->tmp_channel = NULL; | 403 | local->tmp_channel = NULL; |
404 | ieee80211_hw_config(local, 0); | 404 | ieee80211_hw_config(local, 0); |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 4c5192e0d66c..8c8c67819072 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -41,7 +41,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
41 | /* flush out all packets */ | 41 | /* flush out all packets */ |
42 | synchronize_net(); | 42 | synchronize_net(); |
43 | 43 | ||
44 | ieee80211_flush_queues(local, NULL); | 44 | ieee80211_flush_queues(local, NULL, true); |
45 | 45 | ||
46 | local->quiescing = true; | 46 | local->quiescing = true; |
47 | /* make quiescing visible to timers everywhere */ | 47 | /* make quiescing visible to timers everywhere */ |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index d51f6b1c549b..7c86a002df95 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -263,12 +263,12 @@ static inline unsigned int | |||
263 | minstrel_get_retry_count(struct minstrel_rate *mr, | 263 | minstrel_get_retry_count(struct minstrel_rate *mr, |
264 | struct ieee80211_tx_info *info) | 264 | struct ieee80211_tx_info *info) |
265 | { | 265 | { |
266 | unsigned int retry = mr->adjusted_retry_count; | 266 | u8 retry = mr->adjusted_retry_count; |
267 | 267 | ||
268 | if (info->control.use_rts) | 268 | if (info->control.use_rts) |
269 | retry = max(2U, min(mr->stats.retry_count_rtscts, retry)); | 269 | retry = max_t(u8, 2, min(mr->stats.retry_count_rtscts, retry)); |
270 | else if (info->control.use_cts_prot) | 270 | else if (info->control.use_cts_prot) |
271 | retry = max(2U, min(mr->retry_count_cts, retry)); | 271 | retry = max_t(u8, 2, min(mr->retry_count_cts, retry)); |
272 | return retry; | 272 | return retry; |
273 | } | 273 | } |
274 | 274 | ||
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 97eca86a4af0..410efe620c57 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h | |||
@@ -33,8 +33,8 @@ minstrel_ewma(int old, int new, int weight) | |||
33 | 33 | ||
34 | struct minstrel_rate_stats { | 34 | struct minstrel_rate_stats { |
35 | /* current / last sampling period attempts/success counters */ | 35 | /* current / last sampling period attempts/success counters */ |
36 | unsigned int attempts, last_attempts; | 36 | u16 attempts, last_attempts; |
37 | unsigned int success, last_success; | 37 | u16 success, last_success; |
38 | 38 | ||
39 | /* total attempts/success counters */ | 39 | /* total attempts/success counters */ |
40 | u64 att_hist, succ_hist; | 40 | u64 att_hist, succ_hist; |
@@ -46,8 +46,8 @@ struct minstrel_rate_stats { | |||
46 | unsigned int cur_prob, probability; | 46 | unsigned int cur_prob, probability; |
47 | 47 | ||
48 | /* maximum retry counts */ | 48 | /* maximum retry counts */ |
49 | unsigned int retry_count; | 49 | u8 retry_count; |
50 | unsigned int retry_count_rtscts; | 50 | u8 retry_count_rtscts; |
51 | 51 | ||
52 | u8 sample_skipped; | 52 | u8 sample_skipped; |
53 | bool retry_updated; | 53 | bool retry_updated; |
@@ -55,14 +55,15 @@ struct minstrel_rate_stats { | |||
55 | 55 | ||
56 | struct minstrel_rate { | 56 | struct minstrel_rate { |
57 | int bitrate; | 57 | int bitrate; |
58 | int rix; | 58 | |
59 | s8 rix; | ||
60 | u8 retry_count_cts; | ||
61 | u8 adjusted_retry_count; | ||
59 | 62 | ||
60 | unsigned int perfect_tx_time; | 63 | unsigned int perfect_tx_time; |
61 | unsigned int ack_time; | 64 | unsigned int ack_time; |
62 | 65 | ||
63 | int sample_limit; | 66 | int sample_limit; |
64 | unsigned int retry_count_cts; | ||
65 | unsigned int adjusted_retry_count; | ||
66 | 67 | ||
67 | struct minstrel_rate_stats stats; | 68 | struct minstrel_rate_stats stats; |
68 | }; | 69 | }; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 683b10f46505..3d79d498e7f6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -361,9 +361,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
361 | u16 known = local->hw.radiotap_vht_details; | 361 | u16 known = local->hw.radiotap_vht_details; |
362 | 362 | ||
363 | rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); | 363 | rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); |
364 | /* known field - how to handle 80+80? */ | ||
365 | if (status->vht_flag & RX_VHT_FLAG_80P80MHZ) | ||
366 | known &= ~IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; | ||
367 | put_unaligned_le16(known, pos); | 364 | put_unaligned_le16(known, pos); |
368 | pos += 2; | 365 | pos += 2; |
369 | /* flags */ | 366 | /* flags */ |
@@ -378,8 +375,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
378 | /* bandwidth */ | 375 | /* bandwidth */ |
379 | if (status->vht_flag & RX_VHT_FLAG_80MHZ) | 376 | if (status->vht_flag & RX_VHT_FLAG_80MHZ) |
380 | *pos++ = 4; | 377 | *pos++ = 4; |
381 | else if (status->vht_flag & RX_VHT_FLAG_80P80MHZ) | ||
382 | *pos++ = 0; /* marked not known above */ | ||
383 | else if (status->vht_flag & RX_VHT_FLAG_160MHZ) | 378 | else if (status->vht_flag & RX_VHT_FLAG_160MHZ) |
384 | *pos++ = 11; | 379 | *pos++ = 11; |
385 | else if (status->flag & RX_FLAG_40MHZ) | 380 | else if (status->flag & RX_FLAG_40MHZ) |
@@ -2314,6 +2309,15 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
2314 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) | 2309 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) |
2315 | return RX_DROP_MONITOR; | 2310 | return RX_DROP_MONITOR; |
2316 | 2311 | ||
2312 | if (rx->sta) { | ||
2313 | /* The security index has the same property as needed | ||
2314 | * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS | ||
2315 | * for non-QoS-data frames. Here we know it's a data | ||
2316 | * frame, so count MSDUs. | ||
2317 | */ | ||
2318 | rx->sta->rx_msdu[rx->security_idx]++; | ||
2319 | } | ||
2320 | |||
2317 | /* | 2321 | /* |
2318 | * Send unexpected-4addr-frame event to hostapd. For older versions, | 2322 | * Send unexpected-4addr-frame event to hostapd. For older versions, |
2319 | * also drop the frame to cooked monitor interfaces. | 2323 | * also drop the frame to cooked monitor interfaces. |
@@ -2598,7 +2602,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2598 | case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { | 2602 | case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { |
2599 | struct ieee80211_supported_band *sband; | 2603 | struct ieee80211_supported_band *sband; |
2600 | u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; | 2604 | u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; |
2601 | enum ieee80211_sta_rx_bandwidth new_bw; | 2605 | enum ieee80211_sta_rx_bandwidth max_bw, new_bw; |
2602 | 2606 | ||
2603 | /* If it doesn't support 40 MHz it can't change ... */ | 2607 | /* If it doesn't support 40 MHz it can't change ... */ |
2604 | if (!(rx->sta->sta.ht_cap.cap & | 2608 | if (!(rx->sta->sta.ht_cap.cap & |
@@ -2606,13 +2610,18 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2606 | goto handled; | 2610 | goto handled; |
2607 | 2611 | ||
2608 | if (chanwidth == IEEE80211_HT_CHANWIDTH_20MHZ) | 2612 | if (chanwidth == IEEE80211_HT_CHANWIDTH_20MHZ) |
2609 | new_bw = IEEE80211_STA_RX_BW_20; | 2613 | max_bw = IEEE80211_STA_RX_BW_20; |
2610 | else | 2614 | else |
2611 | new_bw = ieee80211_sta_cur_vht_bw(rx->sta); | 2615 | max_bw = ieee80211_sta_cap_rx_bw(rx->sta); |
2616 | |||
2617 | /* set cur_max_bandwidth and recalc sta bw */ | ||
2618 | rx->sta->cur_max_bandwidth = max_bw; | ||
2619 | new_bw = ieee80211_sta_cur_vht_bw(rx->sta); | ||
2612 | 2620 | ||
2613 | if (rx->sta->sta.bandwidth == new_bw) | 2621 | if (rx->sta->sta.bandwidth == new_bw) |
2614 | goto handled; | 2622 | goto handled; |
2615 | 2623 | ||
2624 | rx->sta->sta.bandwidth = new_bw; | ||
2616 | sband = rx->local->hw.wiphy->bands[status->band]; | 2625 | sband = rx->local->hw.wiphy->bands[status->band]; |
2617 | 2626 | ||
2618 | rate_control_rate_update(local, sband, rx->sta, | 2627 | rate_control_rate_update(local, sband, rx->sta, |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index ae842678b629..7807fa42ed3f 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -416,7 +416,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local, | |||
416 | ieee80211_offchannel_stop_vifs(local); | 416 | ieee80211_offchannel_stop_vifs(local); |
417 | 417 | ||
418 | /* ensure nullfunc is transmitted before leaving operating channel */ | 418 | /* ensure nullfunc is transmitted before leaving operating channel */ |
419 | ieee80211_flush_queues(local, NULL); | 419 | ieee80211_flush_queues(local, NULL, false); |
420 | 420 | ||
421 | ieee80211_configure_filter(local); | 421 | ieee80211_configure_filter(local); |
422 | 422 | ||
@@ -432,7 +432,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local, | |||
432 | static bool ieee80211_can_scan(struct ieee80211_local *local, | 432 | static bool ieee80211_can_scan(struct ieee80211_local *local, |
433 | struct ieee80211_sub_if_data *sdata) | 433 | struct ieee80211_sub_if_data *sdata) |
434 | { | 434 | { |
435 | if (local->radar_detect_enabled) | 435 | if (ieee80211_is_radar_required(local)) |
436 | return false; | 436 | return false; |
437 | 437 | ||
438 | if (!list_empty(&local->roc_list)) | 438 | if (!list_empty(&local->roc_list)) |
@@ -505,7 +505,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
505 | 505 | ||
506 | lockdep_assert_held(&local->mtx); | 506 | lockdep_assert_held(&local->mtx); |
507 | 507 | ||
508 | if (local->scan_req) | 508 | if (local->scan_req || ieee80211_is_radar_required(local)) |
509 | return -EBUSY; | 509 | return -EBUSY; |
510 | 510 | ||
511 | if (!ieee80211_can_scan(local, sdata)) { | 511 | if (!ieee80211_can_scan(local, sdata)) { |
@@ -805,7 +805,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local, | |||
805 | ieee80211_offchannel_stop_vifs(local); | 805 | ieee80211_offchannel_stop_vifs(local); |
806 | 806 | ||
807 | if (local->ops->flush) { | 807 | if (local->ops->flush) { |
808 | ieee80211_flush_queues(local, NULL); | 808 | ieee80211_flush_queues(local, NULL, false); |
809 | *next_delay = 0; | 809 | *next_delay = 0; |
810 | } else | 810 | } else |
811 | *next_delay = HZ / 10; | 811 | *next_delay = HZ / 10; |
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index efeba56c913b..06e6ac8cc693 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c | |||
@@ -34,19 +34,15 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
34 | struct cfg80211_chan_def new_vht_chandef = {}; | 34 | struct cfg80211_chan_def new_vht_chandef = {}; |
35 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; | 35 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; |
36 | const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie; | 36 | const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie; |
37 | const struct ieee80211_ht_operation *ht_oper; | ||
38 | int secondary_channel_offset = -1; | 37 | int secondary_channel_offset = -1; |
39 | 38 | ||
40 | sec_chan_offs = elems->sec_chan_offs; | 39 | sec_chan_offs = elems->sec_chan_offs; |
41 | wide_bw_chansw_ie = elems->wide_bw_chansw_ie; | 40 | wide_bw_chansw_ie = elems->wide_bw_chansw_ie; |
42 | ht_oper = elems->ht_operation; | ||
43 | 41 | ||
44 | if (sta_flags & (IEEE80211_STA_DISABLE_HT | | 42 | if (sta_flags & (IEEE80211_STA_DISABLE_HT | |
45 | IEEE80211_STA_DISABLE_40MHZ)) { | 43 | IEEE80211_STA_DISABLE_40MHZ)) { |
46 | sec_chan_offs = NULL; | 44 | sec_chan_offs = NULL; |
47 | wide_bw_chansw_ie = NULL; | 45 | wide_bw_chansw_ie = NULL; |
48 | /* only used for bandwidth here */ | ||
49 | ht_oper = NULL; | ||
50 | } | 46 | } |
51 | 47 | ||
52 | if (sta_flags & IEEE80211_STA_DISABLE_VHT) | 48 | if (sta_flags & IEEE80211_STA_DISABLE_VHT) |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a42f5b2b024d..79383ef0c264 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -116,7 +116,6 @@ static void __cleanup_single_sta(struct sta_info *sta) | |||
116 | clear_sta_flag(sta, WLAN_STA_PS_DELIVER); | 116 | clear_sta_flag(sta, WLAN_STA_PS_DELIVER); |
117 | 117 | ||
118 | atomic_dec(&ps->num_sta_ps); | 118 | atomic_dec(&ps->num_sta_ps); |
119 | sta_info_recalc_tim(sta); | ||
120 | } | 119 | } |
121 | 120 | ||
122 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 121 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
@@ -625,7 +624,7 @@ static unsigned long ieee80211_tids_for_ac(int ac) | |||
625 | } | 624 | } |
626 | } | 625 | } |
627 | 626 | ||
628 | void sta_info_recalc_tim(struct sta_info *sta) | 627 | static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending) |
629 | { | 628 | { |
630 | struct ieee80211_local *local = sta->local; | 629 | struct ieee80211_local *local = sta->local; |
631 | struct ps_data *ps; | 630 | struct ps_data *ps; |
@@ -667,6 +666,9 @@ void sta_info_recalc_tim(struct sta_info *sta) | |||
667 | if (ignore_for_tim == BIT(IEEE80211_NUM_ACS) - 1) | 666 | if (ignore_for_tim == BIT(IEEE80211_NUM_ACS) - 1) |
668 | ignore_for_tim = 0; | 667 | ignore_for_tim = 0; |
669 | 668 | ||
669 | if (ignore_pending) | ||
670 | ignore_for_tim = BIT(IEEE80211_NUM_ACS) - 1; | ||
671 | |||
670 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 672 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
671 | unsigned long tids; | 673 | unsigned long tids; |
672 | 674 | ||
@@ -695,7 +697,7 @@ void sta_info_recalc_tim(struct sta_info *sta) | |||
695 | else | 697 | else |
696 | __bss_tim_clear(ps->tim, id); | 698 | __bss_tim_clear(ps->tim, id); |
697 | 699 | ||
698 | if (local->ops->set_tim) { | 700 | if (local->ops->set_tim && !WARN_ON(sta->dead)) { |
699 | local->tim_in_locked_section = true; | 701 | local->tim_in_locked_section = true; |
700 | drv_set_tim(local, &sta->sta, indicate_tim); | 702 | drv_set_tim(local, &sta->sta, indicate_tim); |
701 | local->tim_in_locked_section = false; | 703 | local->tim_in_locked_section = false; |
@@ -705,6 +707,11 @@ out_unlock: | |||
705 | spin_unlock_bh(&local->tim_lock); | 707 | spin_unlock_bh(&local->tim_lock); |
706 | } | 708 | } |
707 | 709 | ||
710 | void sta_info_recalc_tim(struct sta_info *sta) | ||
711 | { | ||
712 | __sta_info_recalc_tim(sta, false); | ||
713 | } | ||
714 | |||
708 | static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb) | 715 | static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb) |
709 | { | 716 | { |
710 | struct ieee80211_tx_info *info; | 717 | struct ieee80211_tx_info *info; |
@@ -874,6 +881,7 @@ static void __sta_info_destroy_part2(struct sta_info *sta) | |||
874 | { | 881 | { |
875 | struct ieee80211_local *local = sta->local; | 882 | struct ieee80211_local *local = sta->local; |
876 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 883 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
884 | struct station_info sinfo = {}; | ||
877 | int ret; | 885 | int ret; |
878 | 886 | ||
879 | /* | 887 | /* |
@@ -887,6 +895,9 @@ static void __sta_info_destroy_part2(struct sta_info *sta) | |||
887 | /* now keys can no longer be reached */ | 895 | /* now keys can no longer be reached */ |
888 | ieee80211_free_sta_keys(local, sta); | 896 | ieee80211_free_sta_keys(local, sta); |
889 | 897 | ||
898 | /* disable TIM bit - last chance to tell driver */ | ||
899 | __sta_info_recalc_tim(sta, true); | ||
900 | |||
890 | sta->dead = true; | 901 | sta->dead = true; |
891 | 902 | ||
892 | local->num_sta--; | 903 | local->num_sta--; |
@@ -908,7 +919,8 @@ static void __sta_info_destroy_part2(struct sta_info *sta) | |||
908 | 919 | ||
909 | sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr); | 920 | sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr); |
910 | 921 | ||
911 | cfg80211_del_sta(sdata->dev, sta->sta.addr, GFP_KERNEL); | 922 | sta_set_sinfo(sta, &sinfo); |
923 | cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL); | ||
912 | 924 | ||
913 | rate_control_remove_sta_debugfs(sta); | 925 | rate_control_remove_sta_debugfs(sta); |
914 | ieee80211_sta_debugfs_remove(sta); | 926 | ieee80211_sta_debugfs_remove(sta); |
@@ -1243,10 +1255,11 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1243 | * ends the poll/service period. | 1255 | * ends the poll/service period. |
1244 | */ | 1256 | */ |
1245 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | | 1257 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | |
1246 | IEEE80211_TX_CTL_PS_RESPONSE | | ||
1247 | IEEE80211_TX_STATUS_EOSP | | 1258 | IEEE80211_TX_STATUS_EOSP | |
1248 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 1259 | IEEE80211_TX_CTL_REQ_TX_STATUS; |
1249 | 1260 | ||
1261 | info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE; | ||
1262 | |||
1250 | if (call_driver) | 1263 | if (call_driver) |
1251 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, | 1264 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, |
1252 | reason, false); | 1265 | reason, false); |
@@ -1395,8 +1408,8 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1395 | * STA may still remain is PS mode after this frame | 1408 | * STA may still remain is PS mode after this frame |
1396 | * exchange. | 1409 | * exchange. |
1397 | */ | 1410 | */ |
1398 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | | 1411 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; |
1399 | IEEE80211_TX_CTL_PS_RESPONSE; | 1412 | info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE; |
1400 | 1413 | ||
1401 | /* | 1414 | /* |
1402 | * Use MoreData flag to indicate whether there are | 1415 | * Use MoreData flag to indicate whether there are |
@@ -1743,7 +1756,6 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
1743 | struct ieee80211_local *local = sdata->local; | 1756 | struct ieee80211_local *local = sdata->local; |
1744 | struct rate_control_ref *ref = NULL; | 1757 | struct rate_control_ref *ref = NULL; |
1745 | struct timespec uptime; | 1758 | struct timespec uptime; |
1746 | u64 packets = 0; | ||
1747 | u32 thr = 0; | 1759 | u32 thr = 0; |
1748 | int i, ac; | 1760 | int i, ac; |
1749 | 1761 | ||
@@ -1752,49 +1764,76 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
1752 | 1764 | ||
1753 | sinfo->generation = sdata->local->sta_generation; | 1765 | sinfo->generation = sdata->local->sta_generation; |
1754 | 1766 | ||
1755 | sinfo->filled = STATION_INFO_INACTIVE_TIME | | 1767 | drv_sta_statistics(local, sdata, &sta->sta, sinfo); |
1756 | STATION_INFO_RX_BYTES64 | | 1768 | |
1757 | STATION_INFO_TX_BYTES64 | | 1769 | sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME) | |
1758 | STATION_INFO_RX_PACKETS | | 1770 | BIT(NL80211_STA_INFO_STA_FLAGS) | |
1759 | STATION_INFO_TX_PACKETS | | 1771 | BIT(NL80211_STA_INFO_BSS_PARAM) | |
1760 | STATION_INFO_TX_RETRIES | | 1772 | BIT(NL80211_STA_INFO_CONNECTED_TIME) | |
1761 | STATION_INFO_TX_FAILED | | 1773 | BIT(NL80211_STA_INFO_RX_DROP_MISC) | |
1762 | STATION_INFO_TX_BITRATE | | 1774 | BIT(NL80211_STA_INFO_BEACON_LOSS); |
1763 | STATION_INFO_RX_BITRATE | | ||
1764 | STATION_INFO_RX_DROP_MISC | | ||
1765 | STATION_INFO_BSS_PARAM | | ||
1766 | STATION_INFO_CONNECTED_TIME | | ||
1767 | STATION_INFO_STA_FLAGS | | ||
1768 | STATION_INFO_BEACON_LOSS_COUNT; | ||
1769 | 1775 | ||
1770 | ktime_get_ts(&uptime); | 1776 | ktime_get_ts(&uptime); |
1771 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; | 1777 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; |
1772 | |||
1773 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); | 1778 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); |
1774 | sinfo->tx_bytes = 0; | 1779 | |
1775 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 1780 | if (!(sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES64) | |
1776 | sinfo->tx_bytes += sta->tx_bytes[ac]; | 1781 | BIT(NL80211_STA_INFO_TX_BYTES)))) { |
1777 | packets += sta->tx_packets[ac]; | 1782 | sinfo->tx_bytes = 0; |
1783 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
1784 | sinfo->tx_bytes += sta->tx_bytes[ac]; | ||
1785 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES64); | ||
1786 | } | ||
1787 | |||
1788 | if (!(sinfo->filled & BIT(NL80211_STA_INFO_TX_PACKETS))) { | ||
1789 | sinfo->tx_packets = 0; | ||
1790 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
1791 | sinfo->tx_packets += sta->tx_packets[ac]; | ||
1792 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); | ||
1793 | } | ||
1794 | |||
1795 | if (!(sinfo->filled & (BIT(NL80211_STA_INFO_RX_BYTES64) | | ||
1796 | BIT(NL80211_STA_INFO_RX_BYTES)))) { | ||
1797 | sinfo->rx_bytes = sta->rx_bytes; | ||
1798 | sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES64); | ||
1799 | } | ||
1800 | |||
1801 | if (!(sinfo->filled & BIT(NL80211_STA_INFO_RX_PACKETS))) { | ||
1802 | sinfo->rx_packets = sta->rx_packets; | ||
1803 | sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); | ||
1804 | } | ||
1805 | |||
1806 | if (!(sinfo->filled & BIT(NL80211_STA_INFO_TX_RETRIES))) { | ||
1807 | sinfo->tx_retries = sta->tx_retry_count; | ||
1808 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_RETRIES); | ||
1778 | } | 1809 | } |
1779 | sinfo->tx_packets = packets; | 1810 | |
1780 | sinfo->rx_bytes = sta->rx_bytes; | 1811 | if (!(sinfo->filled & BIT(NL80211_STA_INFO_TX_FAILED))) { |
1781 | sinfo->rx_packets = sta->rx_packets; | 1812 | sinfo->tx_failed = sta->tx_retry_failed; |
1782 | sinfo->tx_retries = sta->tx_retry_count; | 1813 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); |
1783 | sinfo->tx_failed = sta->tx_retry_failed; | 1814 | } |
1815 | |||
1784 | sinfo->rx_dropped_misc = sta->rx_dropped; | 1816 | sinfo->rx_dropped_misc = sta->rx_dropped; |
1785 | sinfo->beacon_loss_count = sta->beacon_loss_count; | 1817 | sinfo->beacon_loss_count = sta->beacon_loss_count; |
1786 | 1818 | ||
1787 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || | 1819 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || |
1788 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { | 1820 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { |
1789 | sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; | 1821 | if (!(sinfo->filled & BIT(NL80211_STA_INFO_SIGNAL))) { |
1790 | if (!local->ops->get_rssi || | ||
1791 | drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal)) | ||
1792 | sinfo->signal = (s8)sta->last_signal; | 1822 | sinfo->signal = (s8)sta->last_signal; |
1793 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); | 1823 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); |
1824 | } | ||
1825 | |||
1826 | if (!(sinfo->filled & BIT(NL80211_STA_INFO_SIGNAL_AVG))) { | ||
1827 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); | ||
1828 | sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL_AVG); | ||
1829 | } | ||
1794 | } | 1830 | } |
1795 | if (sta->chains) { | 1831 | |
1796 | sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | | 1832 | if (sta->chains && |
1797 | STATION_INFO_CHAIN_SIGNAL_AVG; | 1833 | !(sinfo->filled & (BIT(NL80211_STA_INFO_CHAIN_SIGNAL) | |
1834 | BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)))) { | ||
1835 | sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL) | | ||
1836 | BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); | ||
1798 | 1837 | ||
1799 | sinfo->chains = sta->chains; | 1838 | sinfo->chains = sta->chains; |
1800 | for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { | 1839 | for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { |
@@ -1804,23 +1843,61 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
1804 | } | 1843 | } |
1805 | } | 1844 | } |
1806 | 1845 | ||
1807 | sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); | 1846 | if (!(sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE))) { |
1808 | sta_set_rate_info_rx(sta, &sinfo->rxrate); | 1847 | sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); |
1848 | sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); | ||
1849 | } | ||
1850 | |||
1851 | if (!(sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE))) { | ||
1852 | sta_set_rate_info_rx(sta, &sinfo->rxrate); | ||
1853 | sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); | ||
1854 | } | ||
1855 | |||
1856 | sinfo->filled |= BIT(NL80211_STA_INFO_TID_STATS); | ||
1857 | for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) { | ||
1858 | struct cfg80211_tid_stats *tidstats = &sinfo->pertid[i]; | ||
1859 | |||
1860 | if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) { | ||
1861 | tidstats->filled |= BIT(NL80211_TID_STATS_RX_MSDU); | ||
1862 | tidstats->rx_msdu = sta->rx_msdu[i]; | ||
1863 | } | ||
1864 | |||
1865 | if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU))) { | ||
1866 | tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU); | ||
1867 | tidstats->tx_msdu = sta->tx_msdu[i]; | ||
1868 | } | ||
1869 | |||
1870 | if (!(tidstats->filled & | ||
1871 | BIT(NL80211_TID_STATS_TX_MSDU_RETRIES)) && | ||
1872 | local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { | ||
1873 | tidstats->filled |= | ||
1874 | BIT(NL80211_TID_STATS_TX_MSDU_RETRIES); | ||
1875 | tidstats->tx_msdu_retries = sta->tx_msdu_retries[i]; | ||
1876 | } | ||
1877 | |||
1878 | if (!(tidstats->filled & | ||
1879 | BIT(NL80211_TID_STATS_TX_MSDU_FAILED)) && | ||
1880 | local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { | ||
1881 | tidstats->filled |= | ||
1882 | BIT(NL80211_TID_STATS_TX_MSDU_FAILED); | ||
1883 | tidstats->tx_msdu_failed = sta->tx_msdu_failed[i]; | ||
1884 | } | ||
1885 | } | ||
1809 | 1886 | ||
1810 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 1887 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
1811 | #ifdef CONFIG_MAC80211_MESH | 1888 | #ifdef CONFIG_MAC80211_MESH |
1812 | sinfo->filled |= STATION_INFO_LLID | | 1889 | sinfo->filled |= BIT(NL80211_STA_INFO_LLID) | |
1813 | STATION_INFO_PLID | | 1890 | BIT(NL80211_STA_INFO_PLID) | |
1814 | STATION_INFO_PLINK_STATE | | 1891 | BIT(NL80211_STA_INFO_PLINK_STATE) | |
1815 | STATION_INFO_LOCAL_PM | | 1892 | BIT(NL80211_STA_INFO_LOCAL_PM) | |
1816 | STATION_INFO_PEER_PM | | 1893 | BIT(NL80211_STA_INFO_PEER_PM) | |
1817 | STATION_INFO_NONPEER_PM; | 1894 | BIT(NL80211_STA_INFO_NONPEER_PM); |
1818 | 1895 | ||
1819 | sinfo->llid = sta->llid; | 1896 | sinfo->llid = sta->llid; |
1820 | sinfo->plid = sta->plid; | 1897 | sinfo->plid = sta->plid; |
1821 | sinfo->plink_state = sta->plink_state; | 1898 | sinfo->plink_state = sta->plink_state; |
1822 | if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { | 1899 | if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { |
1823 | sinfo->filled |= STATION_INFO_T_OFFSET; | 1900 | sinfo->filled |= BIT(NL80211_STA_INFO_T_OFFSET); |
1824 | sinfo->t_offset = sta->t_offset; | 1901 | sinfo->t_offset = sta->t_offset; |
1825 | } | 1902 | } |
1826 | sinfo->local_pm = sta->local_pm; | 1903 | sinfo->local_pm = sta->local_pm; |
@@ -1869,7 +1946,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
1869 | thr = drv_get_expected_throughput(local, &sta->sta); | 1946 | thr = drv_get_expected_throughput(local, &sta->sta); |
1870 | 1947 | ||
1871 | if (thr != 0) { | 1948 | if (thr != 0) { |
1872 | sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT; | 1949 | sinfo->filled |= BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT); |
1873 | sinfo->expected_throughput = thr; | 1950 | sinfo->expected_throughput = thr; |
1874 | } | 1951 | } |
1875 | } | 1952 | } |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 4f052bb2a5ad..925e68fe64c7 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -346,6 +346,14 @@ struct ieee80211_tx_latency_stat { | |||
346 | * @cipher_scheme: optional cipher scheme for this station | 346 | * @cipher_scheme: optional cipher scheme for this station |
347 | * @last_tdls_pkt_time: holds the time in jiffies of last TDLS pkt ACKed | 347 | * @last_tdls_pkt_time: holds the time in jiffies of last TDLS pkt ACKed |
348 | * @reserved_tid: reserved TID (if any, otherwise IEEE80211_TID_UNRESERVED) | 348 | * @reserved_tid: reserved TID (if any, otherwise IEEE80211_TID_UNRESERVED) |
349 | * @tx_msdu: MSDUs transmitted to this station, using IEEE80211_NUM_TID | ||
350 | * entry for non-QoS frames | ||
351 | * @tx_msdu_retries: MSDU retries for transmissions to to this station, | ||
352 | * using IEEE80211_NUM_TID entry for non-QoS frames | ||
353 | * @tx_msdu_failed: MSDU failures for transmissions to to this station, | ||
354 | * using IEEE80211_NUM_TID entry for non-QoS frames | ||
355 | * @rx_msdu: MSDUs received from this station, using IEEE80211_NUM_TID | ||
356 | * entry for non-QoS frames | ||
349 | */ | 357 | */ |
350 | struct sta_info { | 358 | struct sta_info { |
351 | /* General information, mostly static */ | 359 | /* General information, mostly static */ |
@@ -416,6 +424,10 @@ struct sta_info { | |||
416 | u32 last_rx_rate_vht_flag; | 424 | u32 last_rx_rate_vht_flag; |
417 | u8 last_rx_rate_vht_nss; | 425 | u8 last_rx_rate_vht_nss; |
418 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; | 426 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; |
427 | u64 tx_msdu[IEEE80211_NUM_TIDS + 1]; | ||
428 | u64 tx_msdu_retries[IEEE80211_NUM_TIDS + 1]; | ||
429 | u64 tx_msdu_failed[IEEE80211_NUM_TIDS + 1]; | ||
430 | u64 rx_msdu[IEEE80211_NUM_TIDS + 1]; | ||
419 | 431 | ||
420 | /* | 432 | /* |
421 | * Aggregation information, locked with lock. | 433 | * Aggregation information, locked with lock. |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index bb146f377ee4..e679b7c9b160 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -664,13 +664,15 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, | |||
664 | struct ieee80211_supported_band *sband; | 664 | struct ieee80211_supported_band *sband; |
665 | int retry_count; | 665 | int retry_count; |
666 | int rates_idx; | 666 | int rates_idx; |
667 | bool acked; | 667 | bool acked, noack_success; |
668 | 668 | ||
669 | rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count); | 669 | rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count); |
670 | 670 | ||
671 | sband = hw->wiphy->bands[info->band]; | 671 | sband = hw->wiphy->bands[info->band]; |
672 | 672 | ||
673 | acked = !!(info->flags & IEEE80211_TX_STAT_ACK); | 673 | acked = !!(info->flags & IEEE80211_TX_STAT_ACK); |
674 | noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED); | ||
675 | |||
674 | if (pubsta) { | 676 | if (pubsta) { |
675 | struct sta_info *sta; | 677 | struct sta_info *sta; |
676 | 678 | ||
@@ -696,7 +698,7 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, | |||
696 | rate_control_tx_status_noskb(local, sband, sta, info); | 698 | rate_control_tx_status_noskb(local, sband, sta, info); |
697 | } | 699 | } |
698 | 700 | ||
699 | if (acked) { | 701 | if (acked || noack_success) { |
700 | local->dot11TransmittedFrameCount++; | 702 | local->dot11TransmittedFrameCount++; |
701 | if (!pubsta) | 703 | if (!pubsta) |
702 | local->dot11MulticastTransmittedFrameCount++; | 704 | local->dot11MulticastTransmittedFrameCount++; |
@@ -728,6 +730,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
728 | struct ieee80211_bar *bar; | 730 | struct ieee80211_bar *bar; |
729 | int rtap_len; | 731 | int rtap_len; |
730 | int shift = 0; | 732 | int shift = 0; |
733 | int tid = IEEE80211_NUM_TIDS; | ||
731 | 734 | ||
732 | rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count); | 735 | rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count); |
733 | 736 | ||
@@ -771,7 +774,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
771 | 774 | ||
772 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | 775 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && |
773 | (ieee80211_is_data_qos(fc))) { | 776 | (ieee80211_is_data_qos(fc))) { |
774 | u16 tid, ssn; | 777 | u16 ssn; |
775 | u8 *qc; | 778 | u8 *qc; |
776 | 779 | ||
777 | qc = ieee80211_get_qos_ctl(hdr); | 780 | qc = ieee80211_get_qos_ctl(hdr); |
@@ -780,10 +783,14 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
780 | & IEEE80211_SCTL_SEQ); | 783 | & IEEE80211_SCTL_SEQ); |
781 | ieee80211_send_bar(&sta->sdata->vif, hdr->addr1, | 784 | ieee80211_send_bar(&sta->sdata->vif, hdr->addr1, |
782 | tid, ssn); | 785 | tid, ssn); |
786 | } else if (ieee80211_is_data_qos(fc)) { | ||
787 | u8 *qc = ieee80211_get_qos_ctl(hdr); | ||
788 | |||
789 | tid = qc[0] & 0xf; | ||
783 | } | 790 | } |
784 | 791 | ||
785 | if (!acked && ieee80211_is_back_req(fc)) { | 792 | if (!acked && ieee80211_is_back_req(fc)) { |
786 | u16 tid, control; | 793 | u16 control; |
787 | 794 | ||
788 | /* | 795 | /* |
789 | * BAR failed, store the last SSN and retry sending | 796 | * BAR failed, store the last SSN and retry sending |
@@ -811,6 +818,12 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
811 | if (!acked) | 818 | if (!acked) |
812 | sta->tx_retry_failed++; | 819 | sta->tx_retry_failed++; |
813 | sta->tx_retry_count += retry_count; | 820 | sta->tx_retry_count += retry_count; |
821 | |||
822 | if (ieee80211_is_data_present(fc)) { | ||
823 | if (!acked) | ||
824 | sta->tx_msdu_failed[tid]++; | ||
825 | sta->tx_msdu_retries[tid] += retry_count; | ||
826 | } | ||
814 | } | 827 | } |
815 | 828 | ||
816 | rate_control_tx_status(local, sband, sta, skb); | 829 | rate_control_tx_status(local, sband, sta, skb); |
@@ -856,10 +869,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
856 | * Fragments are passed to low-level drivers as separate skbs, so these | 869 | * Fragments are passed to low-level drivers as separate skbs, so these |
857 | * are actually fragments, not frames. Update frame counters only for | 870 | * are actually fragments, not frames. Update frame counters only for |
858 | * the first fragment of the frame. */ | 871 | * the first fragment of the frame. */ |
859 | if (info->flags & IEEE80211_TX_STAT_ACK) { | 872 | if ((info->flags & IEEE80211_TX_STAT_ACK) || |
873 | (info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED)) { | ||
860 | if (ieee80211_is_first_frag(hdr->seq_ctrl)) { | 874 | if (ieee80211_is_first_frag(hdr->seq_ctrl)) { |
861 | local->dot11TransmittedFrameCount++; | 875 | local->dot11TransmittedFrameCount++; |
862 | if (is_multicast_ether_addr(hdr->addr1)) | 876 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr))) |
863 | local->dot11MulticastTransmittedFrameCount++; | 877 | local->dot11MulticastTransmittedFrameCount++; |
864 | if (retry_count > 0) | 878 | if (retry_count > 0) |
865 | local->dot11RetryCount++; | 879 | local->dot11RetryCount++; |
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 55ddd77b865d..917088dfd696 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -68,17 +68,24 @@ ieee80211_tdls_add_subband(struct ieee80211_sub_if_data *sdata, | |||
68 | ch = ieee80211_get_channel(sdata->local->hw.wiphy, i); | 68 | ch = ieee80211_get_channel(sdata->local->hw.wiphy, i); |
69 | if (ch) { | 69 | if (ch) { |
70 | /* we will be active on the channel */ | 70 | /* we will be active on the channel */ |
71 | u32 flags = IEEE80211_CHAN_DISABLED | | ||
72 | IEEE80211_CHAN_NO_IR; | ||
73 | cfg80211_chandef_create(&chandef, ch, | 71 | cfg80211_chandef_create(&chandef, ch, |
74 | NL80211_CHAN_HT20); | 72 | NL80211_CHAN_NO_HT); |
75 | if (cfg80211_chandef_usable(sdata->local->hw.wiphy, | 73 | if (cfg80211_reg_can_beacon(sdata->local->hw.wiphy, |
76 | &chandef, flags)) { | 74 | &chandef, |
75 | sdata->wdev.iftype)) { | ||
77 | ch_cnt++; | 76 | ch_cnt++; |
77 | /* | ||
78 | * check if the next channel is also part of | ||
79 | * this allowed range | ||
80 | */ | ||
78 | continue; | 81 | continue; |
79 | } | 82 | } |
80 | } | 83 | } |
81 | 84 | ||
85 | /* | ||
86 | * we've reached the end of a range, with allowed channels | ||
87 | * found | ||
88 | */ | ||
82 | if (ch_cnt) { | 89 | if (ch_cnt) { |
83 | u8 *pos = skb_put(skb, 2); | 90 | u8 *pos = skb_put(skb, 2); |
84 | *pos++ = ieee80211_frequency_to_channel(subband_start); | 91 | *pos++ = ieee80211_frequency_to_channel(subband_start); |
@@ -89,6 +96,15 @@ ieee80211_tdls_add_subband(struct ieee80211_sub_if_data *sdata, | |||
89 | } | 96 | } |
90 | } | 97 | } |
91 | 98 | ||
99 | /* all channels in the requested range are allowed - add them here */ | ||
100 | if (ch_cnt) { | ||
101 | u8 *pos = skb_put(skb, 2); | ||
102 | *pos++ = ieee80211_frequency_to_channel(subband_start); | ||
103 | *pos++ = ch_cnt; | ||
104 | |||
105 | subband_cnt++; | ||
106 | } | ||
107 | |||
92 | return subband_cnt; | 108 | return subband_cnt; |
93 | } | 109 | } |
94 | 110 | ||
@@ -912,7 +928,7 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev, | |||
912 | rcu_read_unlock(); | 928 | rcu_read_unlock(); |
913 | } | 929 | } |
914 | 930 | ||
915 | ieee80211_flush_queues(local, sdata); | 931 | ieee80211_flush_queues(local, sdata, false); |
916 | 932 | ||
917 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, | 933 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, |
918 | dialog_token, status_code, | 934 | dialog_token, status_code, |
@@ -952,7 +968,7 @@ ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev, | |||
952 | */ | 968 | */ |
953 | ieee80211_stop_vif_queues(local, sdata, | 969 | ieee80211_stop_vif_queues(local, sdata, |
954 | IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN); | 970 | IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN); |
955 | ieee80211_flush_queues(local, sdata); | 971 | ieee80211_flush_queues(local, sdata, false); |
956 | 972 | ||
957 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, | 973 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, |
958 | dialog_token, status_code, | 974 | dialog_token, status_code, |
@@ -1098,7 +1114,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
1098 | */ | 1114 | */ |
1099 | tasklet_kill(&local->tx_pending_tasklet); | 1115 | tasklet_kill(&local->tx_pending_tasklet); |
1100 | /* flush a potentially queued teardown packet */ | 1116 | /* flush a potentially queued teardown packet */ |
1101 | ieee80211_flush_queues(local, sdata); | 1117 | ieee80211_flush_queues(local, sdata, false); |
1102 | 1118 | ||
1103 | ret = sta_info_destroy_addr(sdata, peer); | 1119 | ret = sta_info_destroy_addr(sdata, peer); |
1104 | break; | 1120 | break; |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 8e461a02c6a8..263a9561eb26 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -825,6 +825,13 @@ DECLARE_EVENT_CLASS(sta_event, | |||
825 | ) | 825 | ) |
826 | ); | 826 | ); |
827 | 827 | ||
828 | DEFINE_EVENT(sta_event, drv_sta_statistics, | ||
829 | TP_PROTO(struct ieee80211_local *local, | ||
830 | struct ieee80211_sub_if_data *sdata, | ||
831 | struct ieee80211_sta *sta), | ||
832 | TP_ARGS(local, sdata, sta) | ||
833 | ); | ||
834 | |||
828 | DEFINE_EVENT(sta_event, drv_sta_add, | 835 | DEFINE_EVENT(sta_event, drv_sta_add, |
829 | TP_PROTO(struct ieee80211_local *local, | 836 | TP_PROTO(struct ieee80211_local *local, |
830 | struct ieee80211_sub_if_data *sdata, | 837 | struct ieee80211_sub_if_data *sdata, |
@@ -1329,32 +1336,6 @@ DEFINE_EVENT(release_evt, drv_allow_buffered_frames, | |||
1329 | TP_ARGS(local, sta, tids, num_frames, reason, more_data) | 1336 | TP_ARGS(local, sta, tids, num_frames, reason, more_data) |
1330 | ); | 1337 | ); |
1331 | 1338 | ||
1332 | TRACE_EVENT(drv_get_rssi, | ||
1333 | TP_PROTO(struct ieee80211_local *local, struct ieee80211_sta *sta, | ||
1334 | s8 rssi, int ret), | ||
1335 | |||
1336 | TP_ARGS(local, sta, rssi, ret), | ||
1337 | |||
1338 | TP_STRUCT__entry( | ||
1339 | LOCAL_ENTRY | ||
1340 | STA_ENTRY | ||
1341 | __field(s8, rssi) | ||
1342 | __field(int, ret) | ||
1343 | ), | ||
1344 | |||
1345 | TP_fast_assign( | ||
1346 | LOCAL_ASSIGN; | ||
1347 | STA_ASSIGN; | ||
1348 | __entry->rssi = rssi; | ||
1349 | __entry->ret = ret; | ||
1350 | ), | ||
1351 | |||
1352 | TP_printk( | ||
1353 | LOCAL_PR_FMT STA_PR_FMT " rssi:%d ret:%d", | ||
1354 | LOCAL_PR_ARG, STA_PR_ARG, __entry->rssi, __entry->ret | ||
1355 | ) | ||
1356 | ); | ||
1357 | |||
1358 | DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, | 1339 | DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, |
1359 | TP_PROTO(struct ieee80211_local *local, | 1340 | TP_PROTO(struct ieee80211_local *local, |
1360 | struct ieee80211_sub_if_data *sdata), | 1341 | struct ieee80211_sub_if_data *sdata), |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 058686a721a1..02ed6f60629a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -815,6 +815,8 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
815 | /* for pure STA mode without beacons, we can do it */ | 815 | /* for pure STA mode without beacons, we can do it */ |
816 | hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number); | 816 | hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number); |
817 | tx->sdata->sequence_number += 0x10; | 817 | tx->sdata->sequence_number += 0x10; |
818 | if (tx->sta) | ||
819 | tx->sta->tx_msdu[IEEE80211_NUM_TIDS]++; | ||
818 | return TX_CONTINUE; | 820 | return TX_CONTINUE; |
819 | } | 821 | } |
820 | 822 | ||
@@ -831,6 +833,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
831 | qc = ieee80211_get_qos_ctl(hdr); | 833 | qc = ieee80211_get_qos_ctl(hdr); |
832 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | 834 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; |
833 | seq = &tx->sta->tid_seq[tid]; | 835 | seq = &tx->sta->tid_seq[tid]; |
836 | tx->sta->tx_msdu[tid]++; | ||
834 | 837 | ||
835 | hdr->seq_ctrl = cpu_to_le16(*seq); | 838 | hdr->seq_ctrl = cpu_to_le16(*seq); |
836 | 839 | ||
@@ -3152,7 +3155,7 @@ int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid) | |||
3152 | } | 3155 | } |
3153 | 3156 | ||
3154 | queues = BIT(sdata->vif.hw_queue[ieee802_1d_to_ac[tid]]); | 3157 | queues = BIT(sdata->vif.hw_queue[ieee802_1d_to_ac[tid]]); |
3155 | __ieee80211_flush_queues(local, sdata, queues); | 3158 | __ieee80211_flush_queues(local, sdata, queues, false); |
3156 | 3159 | ||
3157 | sta->reserved_tid = tid; | 3160 | sta->reserved_tid = tid; |
3158 | 3161 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 974ebe70f5b0..fbd37d43dfce 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -578,7 +578,7 @@ ieee80211_get_vif_queues(struct ieee80211_local *local, | |||
578 | 578 | ||
579 | void __ieee80211_flush_queues(struct ieee80211_local *local, | 579 | void __ieee80211_flush_queues(struct ieee80211_local *local, |
580 | struct ieee80211_sub_if_data *sdata, | 580 | struct ieee80211_sub_if_data *sdata, |
581 | unsigned int queues) | 581 | unsigned int queues, bool drop) |
582 | { | 582 | { |
583 | if (!local->ops->flush) | 583 | if (!local->ops->flush) |
584 | return; | 584 | return; |
@@ -594,7 +594,7 @@ void __ieee80211_flush_queues(struct ieee80211_local *local, | |||
594 | IEEE80211_QUEUE_STOP_REASON_FLUSH, | 594 | IEEE80211_QUEUE_STOP_REASON_FLUSH, |
595 | false); | 595 | false); |
596 | 596 | ||
597 | drv_flush(local, sdata, queues, false); | 597 | drv_flush(local, sdata, queues, drop); |
598 | 598 | ||
599 | ieee80211_wake_queues_by_reason(&local->hw, queues, | 599 | ieee80211_wake_queues_by_reason(&local->hw, queues, |
600 | IEEE80211_QUEUE_STOP_REASON_FLUSH, | 600 | IEEE80211_QUEUE_STOP_REASON_FLUSH, |
@@ -602,9 +602,9 @@ void __ieee80211_flush_queues(struct ieee80211_local *local, | |||
602 | } | 602 | } |
603 | 603 | ||
604 | void ieee80211_flush_queues(struct ieee80211_local *local, | 604 | void ieee80211_flush_queues(struct ieee80211_local *local, |
605 | struct ieee80211_sub_if_data *sdata) | 605 | struct ieee80211_sub_if_data *sdata, bool drop) |
606 | { | 606 | { |
607 | __ieee80211_flush_queues(local, sdata, 0); | 607 | __ieee80211_flush_queues(local, sdata, 0, drop); |
608 | } | 608 | } |
609 | 609 | ||
610 | void ieee80211_stop_vif_queues(struct ieee80211_local *local, | 610 | void ieee80211_stop_vif_queues(struct ieee80211_local *local, |
@@ -1470,10 +1470,12 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, | |||
1470 | 1470 | ||
1471 | /* Check if any channel in this sband supports at least 80 MHz */ | 1471 | /* Check if any channel in this sband supports at least 80 MHz */ |
1472 | for (i = 0; i < sband->n_channels; i++) { | 1472 | for (i = 0; i < sband->n_channels; i++) { |
1473 | if (!(sband->channels[i].flags & IEEE80211_CHAN_NO_80MHZ)) { | 1473 | if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED | |
1474 | have_80mhz = true; | 1474 | IEEE80211_CHAN_NO_80MHZ)) |
1475 | break; | 1475 | continue; |
1476 | } | 1476 | |
1477 | have_80mhz = true; | ||
1478 | break; | ||
1477 | } | 1479 | } |
1478 | 1480 | ||
1479 | if (sband->vht_cap.vht_supported && have_80mhz) { | 1481 | if (sband->vht_cap.vht_supported && have_80mhz) { |
@@ -1735,6 +1737,10 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1735 | struct cfg80211_sched_scan_request *sched_scan_req; | 1737 | struct cfg80211_sched_scan_request *sched_scan_req; |
1736 | bool sched_scan_stopped = false; | 1738 | bool sched_scan_stopped = false; |
1737 | 1739 | ||
1740 | /* nothing to do if HW shouldn't run */ | ||
1741 | if (!local->open_count) | ||
1742 | goto wake_up; | ||
1743 | |||
1738 | #ifdef CONFIG_PM | 1744 | #ifdef CONFIG_PM |
1739 | if (local->suspended) | 1745 | if (local->suspended) |
1740 | local->resuming = true; | 1746 | local->resuming = true; |
@@ -1756,9 +1762,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1756 | reconfig_due_to_wowlan = true; | 1762 | reconfig_due_to_wowlan = true; |
1757 | } | 1763 | } |
1758 | #endif | 1764 | #endif |
1759 | /* everything else happens only if HW was up & running */ | ||
1760 | if (!local->open_count) | ||
1761 | goto wake_up; | ||
1762 | 1765 | ||
1763 | /* | 1766 | /* |
1764 | * Upon resume hardware can sometimes be goofy due to | 1767 | * Upon resume hardware can sometimes be goofy due to |
@@ -2042,7 +2045,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
2042 | * If this is for hw restart things are still running. | 2045 | * If this is for hw restart things are still running. |
2043 | * We may want to change that later, however. | 2046 | * We may want to change that later, however. |
2044 | */ | 2047 | */ |
2045 | if (!local->suspended || reconfig_due_to_wowlan) | 2048 | if (local->open_count && (!local->suspended || reconfig_due_to_wowlan)) |
2046 | drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART); | 2049 | drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART); |
2047 | 2050 | ||
2048 | if (!local->suspended) | 2051 | if (!local->suspended) |
@@ -2054,7 +2057,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
2054 | mb(); | 2057 | mb(); |
2055 | local->resuming = false; | 2058 | local->resuming = false; |
2056 | 2059 | ||
2057 | if (!reconfig_due_to_wowlan) | 2060 | if (local->open_count && !reconfig_due_to_wowlan) |
2058 | drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); | 2061 | drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); |
2059 | 2062 | ||
2060 | list_for_each_entry(sdata, &local->interfaces, list) { | 2063 | list_for_each_entry(sdata, &local->interfaces, list) { |
@@ -2538,7 +2541,9 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, | |||
2538 | ri.mcs = status->rate_idx; | 2541 | ri.mcs = status->rate_idx; |
2539 | ri.flags |= RATE_INFO_FLAGS_MCS; | 2542 | ri.flags |= RATE_INFO_FLAGS_MCS; |
2540 | if (status->flag & RX_FLAG_40MHZ) | 2543 | if (status->flag & RX_FLAG_40MHZ) |
2541 | ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | 2544 | ri.bw = RATE_INFO_BW_40; |
2545 | else | ||
2546 | ri.bw = RATE_INFO_BW_20; | ||
2542 | if (status->flag & RX_FLAG_SHORT_GI) | 2547 | if (status->flag & RX_FLAG_SHORT_GI) |
2543 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; | 2548 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; |
2544 | } else if (status->flag & RX_FLAG_VHT) { | 2549 | } else if (status->flag & RX_FLAG_VHT) { |
@@ -2546,13 +2551,13 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, | |||
2546 | ri.mcs = status->rate_idx; | 2551 | ri.mcs = status->rate_idx; |
2547 | ri.nss = status->vht_nss; | 2552 | ri.nss = status->vht_nss; |
2548 | if (status->flag & RX_FLAG_40MHZ) | 2553 | if (status->flag & RX_FLAG_40MHZ) |
2549 | ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | 2554 | ri.bw = RATE_INFO_BW_40; |
2550 | if (status->vht_flag & RX_VHT_FLAG_80MHZ) | 2555 | else if (status->vht_flag & RX_VHT_FLAG_80MHZ) |
2551 | ri.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; | 2556 | ri.bw = RATE_INFO_BW_80; |
2552 | if (status->vht_flag & RX_VHT_FLAG_80P80MHZ) | 2557 | else if (status->vht_flag & RX_VHT_FLAG_160MHZ) |
2553 | ri.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH; | 2558 | ri.bw = RATE_INFO_BW_160; |
2554 | if (status->vht_flag & RX_VHT_FLAG_160MHZ) | 2559 | else |
2555 | ri.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; | 2560 | ri.bw = RATE_INFO_BW_20; |
2556 | if (status->flag & RX_FLAG_SHORT_GI) | 2561 | if (status->flag & RX_FLAG_SHORT_GI) |
2557 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; | 2562 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; |
2558 | } else { | 2563 | } else { |
@@ -2560,10 +2565,15 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, | |||
2560 | int shift = 0; | 2565 | int shift = 0; |
2561 | int bitrate; | 2566 | int bitrate; |
2562 | 2567 | ||
2563 | if (status->flag & RX_FLAG_10MHZ) | 2568 | if (status->flag & RX_FLAG_10MHZ) { |
2564 | shift = 1; | 2569 | shift = 1; |
2565 | if (status->flag & RX_FLAG_5MHZ) | 2570 | ri.bw = RATE_INFO_BW_10; |
2571 | } else if (status->flag & RX_FLAG_5MHZ) { | ||
2566 | shift = 2; | 2572 | shift = 2; |
2573 | ri.bw = RATE_INFO_BW_5; | ||
2574 | } else { | ||
2575 | ri.bw = RATE_INFO_BW_20; | ||
2576 | } | ||
2567 | 2577 | ||
2568 | sband = local->hw.wiphy->bands[status->band]; | 2578 | sband = local->hw.wiphy->bands[status->band]; |
2569 | bitrate = sband->bitrates[status->rate_idx].bitrate; | 2579 | bitrate = sband->bitrates[status->rate_idx].bitrate; |
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index bc9e8fc48785..85f9596da07b 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c | |||
@@ -269,51 +269,54 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | |||
269 | sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta); | 269 | sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta); |
270 | } | 270 | } |
271 | 271 | ||
272 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) | 272 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta) |
273 | { | 273 | { |
274 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 274 | struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap; |
275 | u32 cap = sta->sta.vht_cap.cap; | 275 | u32 cap_width; |
276 | enum ieee80211_sta_rx_bandwidth bw; | ||
277 | 276 | ||
278 | if (!sta->sta.vht_cap.vht_supported) { | 277 | if (!vht_cap->vht_supported) |
279 | bw = sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? | 278 | return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? |
280 | IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; | 279 | IEEE80211_STA_RX_BW_40 : |
281 | goto check_max; | 280 | IEEE80211_STA_RX_BW_20; |
282 | } | ||
283 | 281 | ||
284 | switch (sdata->vif.bss_conf.chandef.width) { | 282 | cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; |
285 | default: | 283 | |
286 | WARN_ON_ONCE(1); | 284 | if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ || |
287 | /* fall through */ | 285 | cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) |
286 | return IEEE80211_STA_RX_BW_160; | ||
287 | |||
288 | return IEEE80211_STA_RX_BW_80; | ||
289 | } | ||
290 | |||
291 | static enum ieee80211_sta_rx_bandwidth | ||
292 | ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width) | ||
293 | { | ||
294 | switch (width) { | ||
288 | case NL80211_CHAN_WIDTH_20_NOHT: | 295 | case NL80211_CHAN_WIDTH_20_NOHT: |
289 | case NL80211_CHAN_WIDTH_20: | 296 | case NL80211_CHAN_WIDTH_20: |
290 | bw = IEEE80211_STA_RX_BW_20; | 297 | return IEEE80211_STA_RX_BW_20; |
291 | break; | ||
292 | case NL80211_CHAN_WIDTH_40: | 298 | case NL80211_CHAN_WIDTH_40: |
293 | bw = sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? | 299 | return IEEE80211_STA_RX_BW_40; |
294 | IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; | 300 | case NL80211_CHAN_WIDTH_80: |
295 | break; | 301 | return IEEE80211_STA_RX_BW_80; |
296 | case NL80211_CHAN_WIDTH_160: | 302 | case NL80211_CHAN_WIDTH_160: |
297 | if ((cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == | ||
298 | IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ) { | ||
299 | bw = IEEE80211_STA_RX_BW_160; | ||
300 | break; | ||
301 | } | ||
302 | /* fall through */ | ||
303 | case NL80211_CHAN_WIDTH_80P80: | 303 | case NL80211_CHAN_WIDTH_80P80: |
304 | if ((cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == | 304 | return IEEE80211_STA_RX_BW_160; |
305 | IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) { | 305 | default: |
306 | bw = IEEE80211_STA_RX_BW_160; | 306 | WARN_ON_ONCE(1); |
307 | break; | 307 | return IEEE80211_STA_RX_BW_20; |
308 | } | ||
309 | /* fall through */ | ||
310 | case NL80211_CHAN_WIDTH_80: | ||
311 | bw = IEEE80211_STA_RX_BW_80; | ||
312 | } | 308 | } |
309 | } | ||
310 | |||
311 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) | ||
312 | { | ||
313 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
314 | enum ieee80211_sta_rx_bandwidth bw; | ||
315 | |||
316 | bw = ieee80211_chan_width_to_rx_bw(sdata->vif.bss_conf.chandef.width); | ||
317 | bw = min(bw, ieee80211_sta_cap_rx_bw(sta)); | ||
318 | bw = min(bw, sta->cur_max_bandwidth); | ||
313 | 319 | ||
314 | check_max: | ||
315 | if (bw > sta->cur_max_bandwidth) | ||
316 | bw = sta->cur_max_bandwidth; | ||
317 | return bw; | 320 | return bw; |
318 | } | 321 | } |
319 | 322 | ||
diff --git a/net/wireless/core.c b/net/wireless/core.c index 53dda7728f86..3af0ecf1cc16 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -320,6 +320,20 @@ static void cfg80211_destroy_iface_wk(struct work_struct *work) | |||
320 | rtnl_unlock(); | 320 | rtnl_unlock(); |
321 | } | 321 | } |
322 | 322 | ||
323 | static void cfg80211_sched_scan_stop_wk(struct work_struct *work) | ||
324 | { | ||
325 | struct cfg80211_registered_device *rdev; | ||
326 | |||
327 | rdev = container_of(work, struct cfg80211_registered_device, | ||
328 | sched_scan_stop_wk); | ||
329 | |||
330 | rtnl_lock(); | ||
331 | |||
332 | __cfg80211_stop_sched_scan(rdev, false); | ||
333 | |||
334 | rtnl_unlock(); | ||
335 | } | ||
336 | |||
323 | /* exported functions */ | 337 | /* exported functions */ |
324 | 338 | ||
325 | struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, | 339 | struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, |
@@ -406,6 +420,7 @@ use_default_name: | |||
406 | INIT_LIST_HEAD(&rdev->destroy_list); | 420 | INIT_LIST_HEAD(&rdev->destroy_list); |
407 | spin_lock_init(&rdev->destroy_list_lock); | 421 | spin_lock_init(&rdev->destroy_list_lock); |
408 | INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk); | 422 | INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk); |
423 | INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk); | ||
409 | 424 | ||
410 | #ifdef CONFIG_CFG80211_DEFAULT_PS | 425 | #ifdef CONFIG_CFG80211_DEFAULT_PS |
411 | rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; | 426 | rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; |
@@ -560,6 +575,14 @@ int wiphy_register(struct wiphy *wiphy) | |||
560 | BIT(NL80211_IFTYPE_MONITOR))) | 575 | BIT(NL80211_IFTYPE_MONITOR))) |
561 | wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; | 576 | wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF; |
562 | 577 | ||
578 | if (WARN_ON((wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) && | ||
579 | (wiphy->regulatory_flags & | ||
580 | (REGULATORY_CUSTOM_REG | | ||
581 | REGULATORY_STRICT_REG | | ||
582 | REGULATORY_COUNTRY_IE_FOLLOW_POWER | | ||
583 | REGULATORY_COUNTRY_IE_IGNORE)))) | ||
584 | return -EINVAL; | ||
585 | |||
563 | if (WARN_ON(wiphy->coalesce && | 586 | if (WARN_ON(wiphy->coalesce && |
564 | (!wiphy->coalesce->n_rules || | 587 | (!wiphy->coalesce->n_rules || |
565 | !wiphy->coalesce->n_patterns) && | 588 | !wiphy->coalesce->n_patterns) && |
@@ -778,6 +801,7 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
778 | flush_work(&rdev->event_work); | 801 | flush_work(&rdev->event_work); |
779 | cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); | 802 | cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); |
780 | flush_work(&rdev->destroy_work); | 803 | flush_work(&rdev->destroy_work); |
804 | flush_work(&rdev->sched_scan_stop_wk); | ||
781 | 805 | ||
782 | #ifdef CONFIG_PM | 806 | #ifdef CONFIG_PM |
783 | if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) | 807 | if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) |
@@ -858,6 +882,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, | |||
858 | struct wireless_dev *wdev) | 882 | struct wireless_dev *wdev) |
859 | { | 883 | { |
860 | struct net_device *dev = wdev->netdev; | 884 | struct net_device *dev = wdev->netdev; |
885 | struct cfg80211_sched_scan_request *sched_scan_req; | ||
861 | 886 | ||
862 | ASSERT_RTNL(); | 887 | ASSERT_RTNL(); |
863 | ASSERT_WDEV_LOCK(wdev); | 888 | ASSERT_WDEV_LOCK(wdev); |
@@ -868,7 +893,8 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, | |||
868 | break; | 893 | break; |
869 | case NL80211_IFTYPE_P2P_CLIENT: | 894 | case NL80211_IFTYPE_P2P_CLIENT: |
870 | case NL80211_IFTYPE_STATION: | 895 | case NL80211_IFTYPE_STATION: |
871 | if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev) | 896 | sched_scan_req = rtnl_dereference(rdev->sched_scan_req); |
897 | if (sched_scan_req && dev == sched_scan_req->dev) | ||
872 | __cfg80211_stop_sched_scan(rdev, false); | 898 | __cfg80211_stop_sched_scan(rdev, false); |
873 | 899 | ||
874 | #ifdef CONFIG_CFG80211_WEXT | 900 | #ifdef CONFIG_CFG80211_WEXT |
@@ -943,6 +969,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
943 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | 969 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
944 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 970 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
945 | struct cfg80211_registered_device *rdev; | 971 | struct cfg80211_registered_device *rdev; |
972 | struct cfg80211_sched_scan_request *sched_scan_req; | ||
946 | 973 | ||
947 | if (!wdev) | 974 | if (!wdev) |
948 | return NOTIFY_DONE; | 975 | return NOTIFY_DONE; |
@@ -1007,8 +1034,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
1007 | ___cfg80211_scan_done(rdev, false); | 1034 | ___cfg80211_scan_done(rdev, false); |
1008 | } | 1035 | } |
1009 | 1036 | ||
1010 | if (WARN_ON(rdev->sched_scan_req && | 1037 | sched_scan_req = rtnl_dereference(rdev->sched_scan_req); |
1011 | rdev->sched_scan_req->dev == wdev->netdev)) { | 1038 | if (WARN_ON(sched_scan_req && |
1039 | sched_scan_req->dev == wdev->netdev)) { | ||
1012 | __cfg80211_stop_sched_scan(rdev, false); | 1040 | __cfg80211_stop_sched_scan(rdev, false); |
1013 | } | 1041 | } |
1014 | 1042 | ||
diff --git a/net/wireless/core.h b/net/wireless/core.h index faa5b1609aae..801cd49c5a0c 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -36,6 +36,13 @@ struct cfg80211_registered_device { | |||
36 | * the country on the country IE changed. */ | 36 | * the country on the country IE changed. */ |
37 | char country_ie_alpha2[2]; | 37 | char country_ie_alpha2[2]; |
38 | 38 | ||
39 | /* | ||
40 | * the driver requests the regulatory core to set this regulatory | ||
41 | * domain as the wiphy's. Only used for %REGULATORY_WIPHY_SELF_MANAGED | ||
42 | * devices using the regulatory_set_wiphy_regd() API | ||
43 | */ | ||
44 | const struct ieee80211_regdomain *requested_regd; | ||
45 | |||
39 | /* If a Country IE has been received this tells us the environment | 46 | /* If a Country IE has been received this tells us the environment |
40 | * which its telling us its in. This defaults to ENVIRON_ANY */ | 47 | * which its telling us its in. This defaults to ENVIRON_ANY */ |
41 | enum environment_cap env; | 48 | enum environment_cap env; |
@@ -63,7 +70,7 @@ struct cfg80211_registered_device { | |||
63 | u32 bss_generation; | 70 | u32 bss_generation; |
64 | struct cfg80211_scan_request *scan_req; /* protected by RTNL */ | 71 | struct cfg80211_scan_request *scan_req; /* protected by RTNL */ |
65 | struct sk_buff *scan_msg; | 72 | struct sk_buff *scan_msg; |
66 | struct cfg80211_sched_scan_request *sched_scan_req; | 73 | struct cfg80211_sched_scan_request __rcu *sched_scan_req; |
67 | unsigned long suspend_at; | 74 | unsigned long suspend_at; |
68 | struct work_struct scan_done_wk; | 75 | struct work_struct scan_done_wk; |
69 | struct work_struct sched_scan_results_wk; | 76 | struct work_struct sched_scan_results_wk; |
@@ -84,6 +91,8 @@ struct cfg80211_registered_device { | |||
84 | struct list_head destroy_list; | 91 | struct list_head destroy_list; |
85 | struct work_struct destroy_work; | 92 | struct work_struct destroy_work; |
86 | 93 | ||
94 | struct work_struct sched_scan_stop_wk; | ||
95 | |||
87 | /* must be last because of the way we do wiphy_priv(), | 96 | /* must be last because of the way we do wiphy_priv(), |
88 | * and it should at least be aligned to NETDEV_ALIGN */ | 97 | * and it should at least be aligned to NETDEV_ALIGN */ |
89 | struct wiphy wiphy __aligned(NETDEV_ALIGN); | 98 | struct wiphy wiphy __aligned(NETDEV_ALIGN); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7ca4b5133123..c5661c5ad8f3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -59,13 +59,13 @@ enum nl80211_multicast_groups { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | static const struct genl_multicast_group nl80211_mcgrps[] = { | 61 | static const struct genl_multicast_group nl80211_mcgrps[] = { |
62 | [NL80211_MCGRP_CONFIG] = { .name = "config", }, | 62 | [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG }, |
63 | [NL80211_MCGRP_SCAN] = { .name = "scan", }, | 63 | [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN }, |
64 | [NL80211_MCGRP_REGULATORY] = { .name = "regulatory", }, | 64 | [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG }, |
65 | [NL80211_MCGRP_MLME] = { .name = "mlme", }, | 65 | [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME }, |
66 | [NL80211_MCGRP_VENDOR] = { .name = "vendor", }, | 66 | [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR }, |
67 | #ifdef CONFIG_NL80211_TESTMODE | 67 | #ifdef CONFIG_NL80211_TESTMODE |
68 | [NL80211_MCGRP_TESTMODE] = { .name = "testmode", } | 68 | [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE } |
69 | #endif | 69 | #endif |
70 | }; | 70 | }; |
71 | 71 | ||
@@ -396,6 +396,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { | |||
396 | [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, | 396 | [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, |
397 | [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, | 397 | [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, |
398 | [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN }, | 398 | [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN }, |
399 | [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG }, | ||
399 | }; | 400 | }; |
400 | 401 | ||
401 | /* policy for the key attributes */ | 402 | /* policy for the key attributes */ |
@@ -1087,6 +1088,11 @@ static int nl80211_send_wowlan(struct sk_buff *msg, | |||
1087 | return -ENOBUFS; | 1088 | return -ENOBUFS; |
1088 | } | 1089 | } |
1089 | 1090 | ||
1091 | if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) && | ||
1092 | nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT, | ||
1093 | rdev->wiphy.wowlan->max_nd_match_sets)) | ||
1094 | return -ENOBUFS; | ||
1095 | |||
1090 | if (large && nl80211_send_wowlan_tcp_caps(rdev, msg)) | 1096 | if (large && nl80211_send_wowlan_tcp_caps(rdev, msg)) |
1091 | return -ENOBUFS; | 1097 | return -ENOBUFS; |
1092 | 1098 | ||
@@ -1701,6 +1707,15 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1701 | rdev->wiphy.max_num_csa_counters)) | 1707 | rdev->wiphy.max_num_csa_counters)) |
1702 | goto nla_put_failure; | 1708 | goto nla_put_failure; |
1703 | 1709 | ||
1710 | if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED && | ||
1711 | nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG)) | ||
1712 | goto nla_put_failure; | ||
1713 | |||
1714 | if (nla_put(msg, NL80211_ATTR_EXT_FEATURES, | ||
1715 | sizeof(rdev->wiphy.ext_features), | ||
1716 | rdev->wiphy.ext_features)) | ||
1717 | goto nla_put_failure; | ||
1718 | |||
1704 | /* done */ | 1719 | /* done */ |
1705 | state->split_start = 0; | 1720 | state->split_start = 0; |
1706 | break; | 1721 | break; |
@@ -3563,6 +3578,7 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, | |||
3563 | struct nlattr *rate; | 3578 | struct nlattr *rate; |
3564 | u32 bitrate; | 3579 | u32 bitrate; |
3565 | u16 bitrate_compat; | 3580 | u16 bitrate_compat; |
3581 | enum nl80211_attrs rate_flg; | ||
3566 | 3582 | ||
3567 | rate = nla_nest_start(msg, attr); | 3583 | rate = nla_nest_start(msg, attr); |
3568 | if (!rate) | 3584 | if (!rate) |
@@ -3579,12 +3595,36 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, | |||
3579 | nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) | 3595 | nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) |
3580 | return false; | 3596 | return false; |
3581 | 3597 | ||
3598 | switch (info->bw) { | ||
3599 | case RATE_INFO_BW_5: | ||
3600 | rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH; | ||
3601 | break; | ||
3602 | case RATE_INFO_BW_10: | ||
3603 | rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH; | ||
3604 | break; | ||
3605 | default: | ||
3606 | WARN_ON(1); | ||
3607 | /* fall through */ | ||
3608 | case RATE_INFO_BW_20: | ||
3609 | rate_flg = 0; | ||
3610 | break; | ||
3611 | case RATE_INFO_BW_40: | ||
3612 | rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH; | ||
3613 | break; | ||
3614 | case RATE_INFO_BW_80: | ||
3615 | rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH; | ||
3616 | break; | ||
3617 | case RATE_INFO_BW_160: | ||
3618 | rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH; | ||
3619 | break; | ||
3620 | } | ||
3621 | |||
3622 | if (rate_flg && nla_put_flag(msg, rate_flg)) | ||
3623 | return false; | ||
3624 | |||
3582 | if (info->flags & RATE_INFO_FLAGS_MCS) { | 3625 | if (info->flags & RATE_INFO_FLAGS_MCS) { |
3583 | if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) | 3626 | if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) |
3584 | return false; | 3627 | return false; |
3585 | if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH && | ||
3586 | nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) | ||
3587 | return false; | ||
3588 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && | 3628 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && |
3589 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) | 3629 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) |
3590 | return false; | 3630 | return false; |
@@ -3593,18 +3633,6 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, | |||
3593 | return false; | 3633 | return false; |
3594 | if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss)) | 3634 | if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss)) |
3595 | return false; | 3635 | return false; |
3596 | if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH && | ||
3597 | nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) | ||
3598 | return false; | ||
3599 | if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH && | ||
3600 | nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH)) | ||
3601 | return false; | ||
3602 | if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH && | ||
3603 | nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH)) | ||
3604 | return false; | ||
3605 | if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH && | ||
3606 | nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH)) | ||
3607 | return false; | ||
3608 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && | 3636 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && |
3609 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) | 3637 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) |
3610 | return false; | 3638 | return false; |
@@ -3640,8 +3668,8 @@ static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal, | |||
3640 | return true; | 3668 | return true; |
3641 | } | 3669 | } |
3642 | 3670 | ||
3643 | static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | 3671 | static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, |
3644 | int flags, | 3672 | u32 seq, int flags, |
3645 | struct cfg80211_registered_device *rdev, | 3673 | struct cfg80211_registered_device *rdev, |
3646 | struct net_device *dev, | 3674 | struct net_device *dev, |
3647 | const u8 *mac_addr, struct station_info *sinfo) | 3675 | const u8 *mac_addr, struct station_info *sinfo) |
@@ -3649,7 +3677,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | |||
3649 | void *hdr; | 3677 | void *hdr; |
3650 | struct nlattr *sinfoattr, *bss_param; | 3678 | struct nlattr *sinfoattr, *bss_param; |
3651 | 3679 | ||
3652 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); | 3680 | hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); |
3653 | if (!hdr) | 3681 | if (!hdr) |
3654 | return -1; | 3682 | return -1; |
3655 | 3683 | ||
@@ -3661,115 +3689,77 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | |||
3661 | sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); | 3689 | sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); |
3662 | if (!sinfoattr) | 3690 | if (!sinfoattr) |
3663 | goto nla_put_failure; | 3691 | goto nla_put_failure; |
3664 | if ((sinfo->filled & STATION_INFO_CONNECTED_TIME) && | 3692 | |
3665 | nla_put_u32(msg, NL80211_STA_INFO_CONNECTED_TIME, | 3693 | #define PUT_SINFO(attr, memb, type) do { \ |
3666 | sinfo->connected_time)) | 3694 | if (sinfo->filled & BIT(NL80211_STA_INFO_ ## attr) && \ |
3667 | goto nla_put_failure; | 3695 | nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \ |
3668 | if ((sinfo->filled & STATION_INFO_INACTIVE_TIME) && | 3696 | sinfo->memb)) \ |
3669 | nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME, | 3697 | goto nla_put_failure; \ |
3670 | sinfo->inactive_time)) | 3698 | } while (0) |
3671 | goto nla_put_failure; | 3699 | |
3672 | if ((sinfo->filled & (STATION_INFO_RX_BYTES | | 3700 | PUT_SINFO(CONNECTED_TIME, connected_time, u32); |
3673 | STATION_INFO_RX_BYTES64)) && | 3701 | PUT_SINFO(INACTIVE_TIME, inactive_time, u32); |
3702 | |||
3703 | if (sinfo->filled & (BIT(NL80211_STA_INFO_RX_BYTES) | | ||
3704 | BIT(NL80211_STA_INFO_RX_BYTES64)) && | ||
3674 | nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES, | 3705 | nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES, |
3675 | (u32)sinfo->rx_bytes)) | 3706 | (u32)sinfo->rx_bytes)) |
3676 | goto nla_put_failure; | 3707 | goto nla_put_failure; |
3677 | if ((sinfo->filled & (STATION_INFO_TX_BYTES | | 3708 | |
3678 | STATION_INFO_TX_BYTES64)) && | 3709 | if (sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES) | |
3710 | BIT(NL80211_STA_INFO_TX_BYTES64)) && | ||
3679 | nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, | 3711 | nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, |
3680 | (u32)sinfo->tx_bytes)) | 3712 | (u32)sinfo->tx_bytes)) |
3681 | goto nla_put_failure; | 3713 | goto nla_put_failure; |
3682 | if ((sinfo->filled & STATION_INFO_RX_BYTES64) && | 3714 | |
3683 | nla_put_u64(msg, NL80211_STA_INFO_RX_BYTES64, | 3715 | PUT_SINFO(RX_BYTES64, rx_bytes, u64); |
3684 | sinfo->rx_bytes)) | 3716 | PUT_SINFO(TX_BYTES64, tx_bytes, u64); |
3685 | goto nla_put_failure; | 3717 | PUT_SINFO(LLID, llid, u16); |
3686 | if ((sinfo->filled & STATION_INFO_TX_BYTES64) && | 3718 | PUT_SINFO(PLID, plid, u16); |
3687 | nla_put_u64(msg, NL80211_STA_INFO_TX_BYTES64, | 3719 | PUT_SINFO(PLINK_STATE, plink_state, u8); |
3688 | sinfo->tx_bytes)) | 3720 | |
3689 | goto nla_put_failure; | ||
3690 | if ((sinfo->filled & STATION_INFO_LLID) && | ||
3691 | nla_put_u16(msg, NL80211_STA_INFO_LLID, sinfo->llid)) | ||
3692 | goto nla_put_failure; | ||
3693 | if ((sinfo->filled & STATION_INFO_PLID) && | ||
3694 | nla_put_u16(msg, NL80211_STA_INFO_PLID, sinfo->plid)) | ||
3695 | goto nla_put_failure; | ||
3696 | if ((sinfo->filled & STATION_INFO_PLINK_STATE) && | ||
3697 | nla_put_u8(msg, NL80211_STA_INFO_PLINK_STATE, | ||
3698 | sinfo->plink_state)) | ||
3699 | goto nla_put_failure; | ||
3700 | switch (rdev->wiphy.signal_type) { | 3721 | switch (rdev->wiphy.signal_type) { |
3701 | case CFG80211_SIGNAL_TYPE_MBM: | 3722 | case CFG80211_SIGNAL_TYPE_MBM: |
3702 | if ((sinfo->filled & STATION_INFO_SIGNAL) && | 3723 | PUT_SINFO(SIGNAL, signal, u8); |
3703 | nla_put_u8(msg, NL80211_STA_INFO_SIGNAL, | 3724 | PUT_SINFO(SIGNAL_AVG, signal_avg, u8); |
3704 | sinfo->signal)) | ||
3705 | goto nla_put_failure; | ||
3706 | if ((sinfo->filled & STATION_INFO_SIGNAL_AVG) && | ||
3707 | nla_put_u8(msg, NL80211_STA_INFO_SIGNAL_AVG, | ||
3708 | sinfo->signal_avg)) | ||
3709 | goto nla_put_failure; | ||
3710 | break; | 3725 | break; |
3711 | default: | 3726 | default: |
3712 | break; | 3727 | break; |
3713 | } | 3728 | } |
3714 | if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) { | 3729 | if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL)) { |
3715 | if (!nl80211_put_signal(msg, sinfo->chains, | 3730 | if (!nl80211_put_signal(msg, sinfo->chains, |
3716 | sinfo->chain_signal, | 3731 | sinfo->chain_signal, |
3717 | NL80211_STA_INFO_CHAIN_SIGNAL)) | 3732 | NL80211_STA_INFO_CHAIN_SIGNAL)) |
3718 | goto nla_put_failure; | 3733 | goto nla_put_failure; |
3719 | } | 3734 | } |
3720 | if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) { | 3735 | if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) { |
3721 | if (!nl80211_put_signal(msg, sinfo->chains, | 3736 | if (!nl80211_put_signal(msg, sinfo->chains, |
3722 | sinfo->chain_signal_avg, | 3737 | sinfo->chain_signal_avg, |
3723 | NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) | 3738 | NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) |
3724 | goto nla_put_failure; | 3739 | goto nla_put_failure; |
3725 | } | 3740 | } |
3726 | if (sinfo->filled & STATION_INFO_TX_BITRATE) { | 3741 | if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE)) { |
3727 | if (!nl80211_put_sta_rate(msg, &sinfo->txrate, | 3742 | if (!nl80211_put_sta_rate(msg, &sinfo->txrate, |
3728 | NL80211_STA_INFO_TX_BITRATE)) | 3743 | NL80211_STA_INFO_TX_BITRATE)) |
3729 | goto nla_put_failure; | 3744 | goto nla_put_failure; |
3730 | } | 3745 | } |
3731 | if (sinfo->filled & STATION_INFO_RX_BITRATE) { | 3746 | if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE)) { |
3732 | if (!nl80211_put_sta_rate(msg, &sinfo->rxrate, | 3747 | if (!nl80211_put_sta_rate(msg, &sinfo->rxrate, |
3733 | NL80211_STA_INFO_RX_BITRATE)) | 3748 | NL80211_STA_INFO_RX_BITRATE)) |
3734 | goto nla_put_failure; | 3749 | goto nla_put_failure; |
3735 | } | 3750 | } |
3736 | if ((sinfo->filled & STATION_INFO_RX_PACKETS) && | 3751 | |
3737 | nla_put_u32(msg, NL80211_STA_INFO_RX_PACKETS, | 3752 | PUT_SINFO(RX_PACKETS, rx_packets, u32); |
3738 | sinfo->rx_packets)) | 3753 | PUT_SINFO(TX_PACKETS, tx_packets, u32); |
3739 | goto nla_put_failure; | 3754 | PUT_SINFO(TX_RETRIES, tx_retries, u32); |
3740 | if ((sinfo->filled & STATION_INFO_TX_PACKETS) && | 3755 | PUT_SINFO(TX_FAILED, tx_failed, u32); |
3741 | nla_put_u32(msg, NL80211_STA_INFO_TX_PACKETS, | 3756 | PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32); |
3742 | sinfo->tx_packets)) | 3757 | PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32); |
3743 | goto nla_put_failure; | 3758 | PUT_SINFO(LOCAL_PM, local_pm, u32); |
3744 | if ((sinfo->filled & STATION_INFO_TX_RETRIES) && | 3759 | PUT_SINFO(PEER_PM, peer_pm, u32); |
3745 | nla_put_u32(msg, NL80211_STA_INFO_TX_RETRIES, | 3760 | PUT_SINFO(NONPEER_PM, nonpeer_pm, u32); |
3746 | sinfo->tx_retries)) | 3761 | |
3747 | goto nla_put_failure; | 3762 | if (sinfo->filled & BIT(NL80211_STA_INFO_BSS_PARAM)) { |
3748 | if ((sinfo->filled & STATION_INFO_TX_FAILED) && | ||
3749 | nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED, | ||
3750 | sinfo->tx_failed)) | ||
3751 | goto nla_put_failure; | ||
3752 | if ((sinfo->filled & STATION_INFO_EXPECTED_THROUGHPUT) && | ||
3753 | nla_put_u32(msg, NL80211_STA_INFO_EXPECTED_THROUGHPUT, | ||
3754 | sinfo->expected_throughput)) | ||
3755 | goto nla_put_failure; | ||
3756 | if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) && | ||
3757 | nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS, | ||
3758 | sinfo->beacon_loss_count)) | ||
3759 | goto nla_put_failure; | ||
3760 | if ((sinfo->filled & STATION_INFO_LOCAL_PM) && | ||
3761 | nla_put_u32(msg, NL80211_STA_INFO_LOCAL_PM, | ||
3762 | sinfo->local_pm)) | ||
3763 | goto nla_put_failure; | ||
3764 | if ((sinfo->filled & STATION_INFO_PEER_PM) && | ||
3765 | nla_put_u32(msg, NL80211_STA_INFO_PEER_PM, | ||
3766 | sinfo->peer_pm)) | ||
3767 | goto nla_put_failure; | ||
3768 | if ((sinfo->filled & STATION_INFO_NONPEER_PM) && | ||
3769 | nla_put_u32(msg, NL80211_STA_INFO_NONPEER_PM, | ||
3770 | sinfo->nonpeer_pm)) | ||
3771 | goto nla_put_failure; | ||
3772 | if (sinfo->filled & STATION_INFO_BSS_PARAM) { | ||
3773 | bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); | 3763 | bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); |
3774 | if (!bss_param) | 3764 | if (!bss_param) |
3775 | goto nla_put_failure; | 3765 | goto nla_put_failure; |
@@ -3788,18 +3778,62 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | |||
3788 | 3778 | ||
3789 | nla_nest_end(msg, bss_param); | 3779 | nla_nest_end(msg, bss_param); |
3790 | } | 3780 | } |
3791 | if ((sinfo->filled & STATION_INFO_STA_FLAGS) && | 3781 | if ((sinfo->filled & BIT(NL80211_STA_INFO_STA_FLAGS)) && |
3792 | nla_put(msg, NL80211_STA_INFO_STA_FLAGS, | 3782 | nla_put(msg, NL80211_STA_INFO_STA_FLAGS, |
3793 | sizeof(struct nl80211_sta_flag_update), | 3783 | sizeof(struct nl80211_sta_flag_update), |
3794 | &sinfo->sta_flags)) | 3784 | &sinfo->sta_flags)) |
3795 | goto nla_put_failure; | 3785 | goto nla_put_failure; |
3796 | if ((sinfo->filled & STATION_INFO_T_OFFSET) && | 3786 | |
3797 | nla_put_u64(msg, NL80211_STA_INFO_T_OFFSET, | 3787 | PUT_SINFO(T_OFFSET, t_offset, u64); |
3798 | sinfo->t_offset)) | 3788 | PUT_SINFO(RX_DROP_MISC, rx_dropped_misc, u64); |
3799 | goto nla_put_failure; | 3789 | PUT_SINFO(BEACON_RX, rx_beacon, u64); |
3790 | PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8); | ||
3791 | |||
3792 | #undef PUT_SINFO | ||
3793 | |||
3794 | if (sinfo->filled & BIT(NL80211_STA_INFO_TID_STATS)) { | ||
3795 | struct nlattr *tidsattr; | ||
3796 | int tid; | ||
3797 | |||
3798 | tidsattr = nla_nest_start(msg, NL80211_STA_INFO_TID_STATS); | ||
3799 | if (!tidsattr) | ||
3800 | goto nla_put_failure; | ||
3801 | |||
3802 | for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) { | ||
3803 | struct cfg80211_tid_stats *tidstats; | ||
3804 | struct nlattr *tidattr; | ||
3805 | |||
3806 | tidstats = &sinfo->pertid[tid]; | ||
3807 | |||
3808 | if (!tidstats->filled) | ||
3809 | continue; | ||
3810 | |||
3811 | tidattr = nla_nest_start(msg, tid + 1); | ||
3812 | if (!tidattr) | ||
3813 | goto nla_put_failure; | ||
3814 | |||
3815 | #define PUT_TIDVAL(attr, memb, type) do { \ | ||
3816 | if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \ | ||
3817 | nla_put_ ## type(msg, NL80211_TID_STATS_ ## attr, \ | ||
3818 | tidstats->memb)) \ | ||
3819 | goto nla_put_failure; \ | ||
3820 | } while (0) | ||
3821 | |||
3822 | PUT_TIDVAL(RX_MSDU, rx_msdu, u64); | ||
3823 | PUT_TIDVAL(TX_MSDU, tx_msdu, u64); | ||
3824 | PUT_TIDVAL(TX_MSDU_RETRIES, tx_msdu_retries, u64); | ||
3825 | PUT_TIDVAL(TX_MSDU_FAILED, tx_msdu_failed, u64); | ||
3826 | |||
3827 | #undef PUT_TIDVAL | ||
3828 | nla_nest_end(msg, tidattr); | ||
3829 | } | ||
3830 | |||
3831 | nla_nest_end(msg, tidsattr); | ||
3832 | } | ||
3833 | |||
3800 | nla_nest_end(msg, sinfoattr); | 3834 | nla_nest_end(msg, sinfoattr); |
3801 | 3835 | ||
3802 | if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) && | 3836 | if (sinfo->assoc_req_ies_len && |
3803 | nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, | 3837 | nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, |
3804 | sinfo->assoc_req_ies)) | 3838 | sinfo->assoc_req_ies)) |
3805 | goto nla_put_failure; | 3839 | goto nla_put_failure; |
@@ -3844,7 +3878,7 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
3844 | if (err) | 3878 | if (err) |
3845 | goto out_err; | 3879 | goto out_err; |
3846 | 3880 | ||
3847 | if (nl80211_send_station(skb, | 3881 | if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION, |
3848 | NETLINK_CB(cb->skb).portid, | 3882 | NETLINK_CB(cb->skb).portid, |
3849 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 3883 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
3850 | rdev, wdev->netdev, mac_addr, | 3884 | rdev, wdev->netdev, mac_addr, |
@@ -3891,7 +3925,8 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) | |||
3891 | if (!msg) | 3925 | if (!msg) |
3892 | return -ENOMEM; | 3926 | return -ENOMEM; |
3893 | 3927 | ||
3894 | if (nl80211_send_station(msg, info->snd_portid, info->snd_seq, 0, | 3928 | if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, |
3929 | info->snd_portid, info->snd_seq, 0, | ||
3895 | rdev, dev, mac_addr, &sinfo) < 0) { | 3930 | rdev, dev, mac_addr, &sinfo) < 0) { |
3896 | nlmsg_free(msg); | 3931 | nlmsg_free(msg); |
3897 | return -ENOBUFS; | 3932 | return -ENOBUFS; |
@@ -5327,42 +5362,20 @@ static int nl80211_update_mesh_config(struct sk_buff *skb, | |||
5327 | return err; | 5362 | return err; |
5328 | } | 5363 | } |
5329 | 5364 | ||
5330 | static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) | 5365 | static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom, |
5366 | struct sk_buff *msg) | ||
5331 | { | 5367 | { |
5332 | const struct ieee80211_regdomain *regdom; | ||
5333 | struct sk_buff *msg; | ||
5334 | void *hdr = NULL; | ||
5335 | struct nlattr *nl_reg_rules; | 5368 | struct nlattr *nl_reg_rules; |
5336 | unsigned int i; | 5369 | unsigned int i; |
5337 | 5370 | ||
5338 | if (!cfg80211_regdomain) | ||
5339 | return -EINVAL; | ||
5340 | |||
5341 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
5342 | if (!msg) | ||
5343 | return -ENOBUFS; | ||
5344 | |||
5345 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | ||
5346 | NL80211_CMD_GET_REG); | ||
5347 | if (!hdr) | ||
5348 | goto put_failure; | ||
5349 | |||
5350 | if (reg_last_request_cell_base() && | ||
5351 | nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE, | ||
5352 | NL80211_USER_REG_HINT_CELL_BASE)) | ||
5353 | goto nla_put_failure; | ||
5354 | |||
5355 | rcu_read_lock(); | ||
5356 | regdom = rcu_dereference(cfg80211_regdomain); | ||
5357 | |||
5358 | if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) || | 5371 | if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) || |
5359 | (regdom->dfs_region && | 5372 | (regdom->dfs_region && |
5360 | nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region))) | 5373 | nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region))) |
5361 | goto nla_put_failure_rcu; | 5374 | goto nla_put_failure; |
5362 | 5375 | ||
5363 | nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); | 5376 | nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); |
5364 | if (!nl_reg_rules) | 5377 | if (!nl_reg_rules) |
5365 | goto nla_put_failure_rcu; | 5378 | goto nla_put_failure; |
5366 | 5379 | ||
5367 | for (i = 0; i < regdom->n_reg_rules; i++) { | 5380 | for (i = 0; i < regdom->n_reg_rules; i++) { |
5368 | struct nlattr *nl_reg_rule; | 5381 | struct nlattr *nl_reg_rule; |
@@ -5377,7 +5390,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) | |||
5377 | 5390 | ||
5378 | nl_reg_rule = nla_nest_start(msg, i); | 5391 | nl_reg_rule = nla_nest_start(msg, i); |
5379 | if (!nl_reg_rule) | 5392 | if (!nl_reg_rule) |
5380 | goto nla_put_failure_rcu; | 5393 | goto nla_put_failure; |
5381 | 5394 | ||
5382 | max_bandwidth_khz = freq_range->max_bandwidth_khz; | 5395 | max_bandwidth_khz = freq_range->max_bandwidth_khz; |
5383 | if (!max_bandwidth_khz) | 5396 | if (!max_bandwidth_khz) |
@@ -5398,13 +5411,74 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) | |||
5398 | power_rule->max_eirp) || | 5411 | power_rule->max_eirp) || |
5399 | nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME, | 5412 | nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME, |
5400 | reg_rule->dfs_cac_ms)) | 5413 | reg_rule->dfs_cac_ms)) |
5401 | goto nla_put_failure_rcu; | 5414 | goto nla_put_failure; |
5402 | 5415 | ||
5403 | nla_nest_end(msg, nl_reg_rule); | 5416 | nla_nest_end(msg, nl_reg_rule); |
5404 | } | 5417 | } |
5405 | rcu_read_unlock(); | ||
5406 | 5418 | ||
5407 | nla_nest_end(msg, nl_reg_rules); | 5419 | nla_nest_end(msg, nl_reg_rules); |
5420 | return 0; | ||
5421 | |||
5422 | nla_put_failure: | ||
5423 | return -EMSGSIZE; | ||
5424 | } | ||
5425 | |||
5426 | static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info) | ||
5427 | { | ||
5428 | const struct ieee80211_regdomain *regdom = NULL; | ||
5429 | struct cfg80211_registered_device *rdev; | ||
5430 | struct wiphy *wiphy = NULL; | ||
5431 | struct sk_buff *msg; | ||
5432 | void *hdr; | ||
5433 | |||
5434 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
5435 | if (!msg) | ||
5436 | return -ENOBUFS; | ||
5437 | |||
5438 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | ||
5439 | NL80211_CMD_GET_REG); | ||
5440 | if (!hdr) | ||
5441 | goto put_failure; | ||
5442 | |||
5443 | if (info->attrs[NL80211_ATTR_WIPHY]) { | ||
5444 | bool self_managed; | ||
5445 | |||
5446 | rdev = cfg80211_get_dev_from_info(genl_info_net(info), info); | ||
5447 | if (IS_ERR(rdev)) { | ||
5448 | nlmsg_free(msg); | ||
5449 | return PTR_ERR(rdev); | ||
5450 | } | ||
5451 | |||
5452 | wiphy = &rdev->wiphy; | ||
5453 | self_managed = wiphy->regulatory_flags & | ||
5454 | REGULATORY_WIPHY_SELF_MANAGED; | ||
5455 | regdom = get_wiphy_regdom(wiphy); | ||
5456 | |||
5457 | /* a self-managed-reg device must have a private regdom */ | ||
5458 | if (WARN_ON(!regdom && self_managed)) { | ||
5459 | nlmsg_free(msg); | ||
5460 | return -EINVAL; | ||
5461 | } | ||
5462 | |||
5463 | if (regdom && | ||
5464 | nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy))) | ||
5465 | goto nla_put_failure; | ||
5466 | } | ||
5467 | |||
5468 | if (!wiphy && reg_last_request_cell_base() && | ||
5469 | nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE, | ||
5470 | NL80211_USER_REG_HINT_CELL_BASE)) | ||
5471 | goto nla_put_failure; | ||
5472 | |||
5473 | rcu_read_lock(); | ||
5474 | |||
5475 | if (!regdom) | ||
5476 | regdom = rcu_dereference(cfg80211_regdomain); | ||
5477 | |||
5478 | if (nl80211_put_regdom(regdom, msg)) | ||
5479 | goto nla_put_failure_rcu; | ||
5480 | |||
5481 | rcu_read_unlock(); | ||
5408 | 5482 | ||
5409 | genlmsg_end(msg, hdr); | 5483 | genlmsg_end(msg, hdr); |
5410 | return genlmsg_reply(msg, info); | 5484 | return genlmsg_reply(msg, info); |
@@ -5418,6 +5492,83 @@ put_failure: | |||
5418 | return -EMSGSIZE; | 5492 | return -EMSGSIZE; |
5419 | } | 5493 | } |
5420 | 5494 | ||
5495 | static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb, | ||
5496 | u32 seq, int flags, struct wiphy *wiphy, | ||
5497 | const struct ieee80211_regdomain *regdom) | ||
5498 | { | ||
5499 | void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags, | ||
5500 | NL80211_CMD_GET_REG); | ||
5501 | |||
5502 | if (!hdr) | ||
5503 | return -1; | ||
5504 | |||
5505 | genl_dump_check_consistent(cb, hdr, &nl80211_fam); | ||
5506 | |||
5507 | if (nl80211_put_regdom(regdom, msg)) | ||
5508 | goto nla_put_failure; | ||
5509 | |||
5510 | if (!wiphy && reg_last_request_cell_base() && | ||
5511 | nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE, | ||
5512 | NL80211_USER_REG_HINT_CELL_BASE)) | ||
5513 | goto nla_put_failure; | ||
5514 | |||
5515 | if (wiphy && | ||
5516 | nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy))) | ||
5517 | goto nla_put_failure; | ||
5518 | |||
5519 | if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED && | ||
5520 | nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG)) | ||
5521 | goto nla_put_failure; | ||
5522 | |||
5523 | return genlmsg_end(msg, hdr); | ||
5524 | |||
5525 | nla_put_failure: | ||
5526 | genlmsg_cancel(msg, hdr); | ||
5527 | return -EMSGSIZE; | ||
5528 | } | ||
5529 | |||
5530 | static int nl80211_get_reg_dump(struct sk_buff *skb, | ||
5531 | struct netlink_callback *cb) | ||
5532 | { | ||
5533 | const struct ieee80211_regdomain *regdom = NULL; | ||
5534 | struct cfg80211_registered_device *rdev; | ||
5535 | int err, reg_idx, start = cb->args[2]; | ||
5536 | |||
5537 | rtnl_lock(); | ||
5538 | |||
5539 | if (cfg80211_regdomain && start == 0) { | ||
5540 | err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq, | ||
5541 | NLM_F_MULTI, NULL, | ||
5542 | rtnl_dereference(cfg80211_regdomain)); | ||
5543 | if (err < 0) | ||
5544 | goto out_err; | ||
5545 | } | ||
5546 | |||
5547 | /* the global regdom is idx 0 */ | ||
5548 | reg_idx = 1; | ||
5549 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | ||
5550 | regdom = get_wiphy_regdom(&rdev->wiphy); | ||
5551 | if (!regdom) | ||
5552 | continue; | ||
5553 | |||
5554 | if (++reg_idx <= start) | ||
5555 | continue; | ||
5556 | |||
5557 | err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq, | ||
5558 | NLM_F_MULTI, &rdev->wiphy, regdom); | ||
5559 | if (err < 0) { | ||
5560 | reg_idx--; | ||
5561 | break; | ||
5562 | } | ||
5563 | } | ||
5564 | |||
5565 | cb->args[2] = reg_idx; | ||
5566 | err = skb->len; | ||
5567 | out_err: | ||
5568 | rtnl_unlock(); | ||
5569 | return err; | ||
5570 | } | ||
5571 | |||
5421 | static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) | 5572 | static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) |
5422 | { | 5573 | { |
5423 | struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1]; | 5574 | struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1]; |
@@ -6069,6 +6220,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
6069 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6220 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6070 | struct net_device *dev = info->user_ptr[1]; | 6221 | struct net_device *dev = info->user_ptr[1]; |
6071 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 6222 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
6223 | struct cfg80211_sched_scan_request *sched_scan_req; | ||
6072 | int err; | 6224 | int err; |
6073 | 6225 | ||
6074 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || | 6226 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || |
@@ -6078,27 +6230,32 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
6078 | if (rdev->sched_scan_req) | 6230 | if (rdev->sched_scan_req) |
6079 | return -EINPROGRESS; | 6231 | return -EINPROGRESS; |
6080 | 6232 | ||
6081 | rdev->sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev, | 6233 | sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev, |
6082 | info->attrs); | 6234 | info->attrs); |
6083 | err = PTR_ERR_OR_ZERO(rdev->sched_scan_req); | 6235 | |
6236 | err = PTR_ERR_OR_ZERO(sched_scan_req); | ||
6084 | if (err) | 6237 | if (err) |
6085 | goto out_err; | 6238 | goto out_err; |
6086 | 6239 | ||
6087 | err = rdev_sched_scan_start(rdev, dev, rdev->sched_scan_req); | 6240 | err = rdev_sched_scan_start(rdev, dev, sched_scan_req); |
6088 | if (err) | 6241 | if (err) |
6089 | goto out_free; | 6242 | goto out_free; |
6090 | 6243 | ||
6091 | rdev->sched_scan_req->dev = dev; | 6244 | sched_scan_req->dev = dev; |
6092 | rdev->sched_scan_req->wiphy = &rdev->wiphy; | 6245 | sched_scan_req->wiphy = &rdev->wiphy; |
6246 | |||
6247 | if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) | ||
6248 | sched_scan_req->owner_nlportid = info->snd_portid; | ||
6249 | |||
6250 | rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req); | ||
6093 | 6251 | ||
6094 | nl80211_send_sched_scan(rdev, dev, | 6252 | nl80211_send_sched_scan(rdev, dev, |
6095 | NL80211_CMD_START_SCHED_SCAN); | 6253 | NL80211_CMD_START_SCHED_SCAN); |
6096 | return 0; | 6254 | return 0; |
6097 | 6255 | ||
6098 | out_free: | 6256 | out_free: |
6099 | kfree(rdev->sched_scan_req); | 6257 | kfree(sched_scan_req); |
6100 | out_err: | 6258 | out_err: |
6101 | rdev->sched_scan_req = NULL; | ||
6102 | return err; | 6259 | return err; |
6103 | } | 6260 | } |
6104 | 6261 | ||
@@ -6481,12 +6638,17 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb) | |||
6481 | } | 6638 | } |
6482 | 6639 | ||
6483 | static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, | 6640 | static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, |
6484 | int flags, struct net_device *dev, | 6641 | int flags, struct net_device *dev, |
6485 | struct survey_info *survey) | 6642 | bool allow_radio_stats, |
6643 | struct survey_info *survey) | ||
6486 | { | 6644 | { |
6487 | void *hdr; | 6645 | void *hdr; |
6488 | struct nlattr *infoattr; | 6646 | struct nlattr *infoattr; |
6489 | 6647 | ||
6648 | /* skip radio stats if userspace didn't request them */ | ||
6649 | if (!survey->channel && !allow_radio_stats) | ||
6650 | return 0; | ||
6651 | |||
6490 | hdr = nl80211hdr_put(msg, portid, seq, flags, | 6652 | hdr = nl80211hdr_put(msg, portid, seq, flags, |
6491 | NL80211_CMD_NEW_SURVEY_RESULTS); | 6653 | NL80211_CMD_NEW_SURVEY_RESULTS); |
6492 | if (!hdr) | 6654 | if (!hdr) |
@@ -6499,7 +6661,8 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, | |||
6499 | if (!infoattr) | 6661 | if (!infoattr) |
6500 | goto nla_put_failure; | 6662 | goto nla_put_failure; |
6501 | 6663 | ||
6502 | if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY, | 6664 | if (survey->channel && |
6665 | nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY, | ||
6503 | survey->channel->center_freq)) | 6666 | survey->channel->center_freq)) |
6504 | goto nla_put_failure; | 6667 | goto nla_put_failure; |
6505 | 6668 | ||
@@ -6509,25 +6672,29 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, | |||
6509 | if ((survey->filled & SURVEY_INFO_IN_USE) && | 6672 | if ((survey->filled & SURVEY_INFO_IN_USE) && |
6510 | nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE)) | 6673 | nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE)) |
6511 | goto nla_put_failure; | 6674 | goto nla_put_failure; |
6512 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME) && | 6675 | if ((survey->filled & SURVEY_INFO_TIME) && |
6513 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME, | 6676 | nla_put_u64(msg, NL80211_SURVEY_INFO_TIME, |
6514 | survey->channel_time)) | 6677 | survey->time)) |
6678 | goto nla_put_failure; | ||
6679 | if ((survey->filled & SURVEY_INFO_TIME_BUSY) && | ||
6680 | nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_BUSY, | ||
6681 | survey->time_busy)) | ||
6515 | goto nla_put_failure; | 6682 | goto nla_put_failure; |
6516 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) && | 6683 | if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) && |
6517 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, | 6684 | nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY, |
6518 | survey->channel_time_busy)) | 6685 | survey->time_ext_busy)) |
6519 | goto nla_put_failure; | 6686 | goto nla_put_failure; |
6520 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) && | 6687 | if ((survey->filled & SURVEY_INFO_TIME_RX) && |
6521 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, | 6688 | nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_RX, |
6522 | survey->channel_time_ext_busy)) | 6689 | survey->time_rx)) |
6523 | goto nla_put_failure; | 6690 | goto nla_put_failure; |
6524 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) && | 6691 | if ((survey->filled & SURVEY_INFO_TIME_TX) && |
6525 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX, | 6692 | nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_TX, |
6526 | survey->channel_time_rx)) | 6693 | survey->time_tx)) |
6527 | goto nla_put_failure; | 6694 | goto nla_put_failure; |
6528 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) && | 6695 | if ((survey->filled & SURVEY_INFO_TIME_SCAN) && |
6529 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX, | 6696 | nla_put_u64(msg, NL80211_SURVEY_INFO_TIME_SCAN, |
6530 | survey->channel_time_tx)) | 6697 | survey->time_scan)) |
6531 | goto nla_put_failure; | 6698 | goto nla_put_failure; |
6532 | 6699 | ||
6533 | nla_nest_end(msg, infoattr); | 6700 | nla_nest_end(msg, infoattr); |
@@ -6539,19 +6706,22 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, | |||
6539 | return -EMSGSIZE; | 6706 | return -EMSGSIZE; |
6540 | } | 6707 | } |
6541 | 6708 | ||
6542 | static int nl80211_dump_survey(struct sk_buff *skb, | 6709 | static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb) |
6543 | struct netlink_callback *cb) | ||
6544 | { | 6710 | { |
6545 | struct survey_info survey; | 6711 | struct survey_info survey; |
6546 | struct cfg80211_registered_device *rdev; | 6712 | struct cfg80211_registered_device *rdev; |
6547 | struct wireless_dev *wdev; | 6713 | struct wireless_dev *wdev; |
6548 | int survey_idx = cb->args[2]; | 6714 | int survey_idx = cb->args[2]; |
6549 | int res; | 6715 | int res; |
6716 | bool radio_stats; | ||
6550 | 6717 | ||
6551 | res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); | 6718 | res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); |
6552 | if (res) | 6719 | if (res) |
6553 | return res; | 6720 | return res; |
6554 | 6721 | ||
6722 | /* prepare_wdev_dump parsed the attributes */ | ||
6723 | radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS]; | ||
6724 | |||
6555 | if (!wdev->netdev) { | 6725 | if (!wdev->netdev) { |
6556 | res = -EINVAL; | 6726 | res = -EINVAL; |
6557 | goto out_err; | 6727 | goto out_err; |
@@ -6569,13 +6739,9 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
6569 | if (res) | 6739 | if (res) |
6570 | goto out_err; | 6740 | goto out_err; |
6571 | 6741 | ||
6572 | /* Survey without a channel doesn't make sense */ | 6742 | /* don't send disabled channels, but do send non-channel data */ |
6573 | if (!survey.channel) { | 6743 | if (survey.channel && |
6574 | res = -EINVAL; | 6744 | survey.channel->flags & IEEE80211_CHAN_DISABLED) { |
6575 | goto out; | ||
6576 | } | ||
6577 | |||
6578 | if (survey.channel->flags & IEEE80211_CHAN_DISABLED) { | ||
6579 | survey_idx++; | 6745 | survey_idx++; |
6580 | continue; | 6746 | continue; |
6581 | } | 6747 | } |
@@ -6583,7 +6749,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
6583 | if (nl80211_send_survey(skb, | 6749 | if (nl80211_send_survey(skb, |
6584 | NETLINK_CB(cb->skb).portid, | 6750 | NETLINK_CB(cb->skb).portid, |
6585 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 6751 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
6586 | wdev->netdev, &survey) < 0) | 6752 | wdev->netdev, radio_stats, &survey) < 0) |
6587 | goto out; | 6753 | goto out; |
6588 | survey_idx++; | 6754 | survey_idx++; |
6589 | } | 6755 | } |
@@ -8599,6 +8765,48 @@ static int nl80211_send_wowlan_tcp(struct sk_buff *msg, | |||
8599 | return 0; | 8765 | return 0; |
8600 | } | 8766 | } |
8601 | 8767 | ||
8768 | static int nl80211_send_wowlan_nd(struct sk_buff *msg, | ||
8769 | struct cfg80211_sched_scan_request *req) | ||
8770 | { | ||
8771 | struct nlattr *nd, *freqs, *matches, *match; | ||
8772 | int i; | ||
8773 | |||
8774 | if (!req) | ||
8775 | return 0; | ||
8776 | |||
8777 | nd = nla_nest_start(msg, NL80211_WOWLAN_TRIG_NET_DETECT); | ||
8778 | if (!nd) | ||
8779 | return -ENOBUFS; | ||
8780 | |||
8781 | if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, req->interval)) | ||
8782 | return -ENOBUFS; | ||
8783 | |||
8784 | freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES); | ||
8785 | if (!freqs) | ||
8786 | return -ENOBUFS; | ||
8787 | |||
8788 | for (i = 0; i < req->n_channels; i++) | ||
8789 | nla_put_u32(msg, i, req->channels[i]->center_freq); | ||
8790 | |||
8791 | nla_nest_end(msg, freqs); | ||
8792 | |||
8793 | if (req->n_match_sets) { | ||
8794 | matches = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH); | ||
8795 | for (i = 0; i < req->n_match_sets; i++) { | ||
8796 | match = nla_nest_start(msg, i); | ||
8797 | nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID, | ||
8798 | req->match_sets[i].ssid.ssid_len, | ||
8799 | req->match_sets[i].ssid.ssid); | ||
8800 | nla_nest_end(msg, match); | ||
8801 | } | ||
8802 | nla_nest_end(msg, matches); | ||
8803 | } | ||
8804 | |||
8805 | nla_nest_end(msg, nd); | ||
8806 | |||
8807 | return 0; | ||
8808 | } | ||
8809 | |||
8602 | static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) | 8810 | static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) |
8603 | { | 8811 | { |
8604 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 8812 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
@@ -8656,6 +8864,11 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
8656 | rdev->wiphy.wowlan_config->tcp)) | 8864 | rdev->wiphy.wowlan_config->tcp)) |
8657 | goto nla_put_failure; | 8865 | goto nla_put_failure; |
8658 | 8866 | ||
8867 | if (nl80211_send_wowlan_nd( | ||
8868 | msg, | ||
8869 | rdev->wiphy.wowlan_config->nd_config)) | ||
8870 | goto nla_put_failure; | ||
8871 | |||
8659 | nla_nest_end(msg, nl_wowlan); | 8872 | nla_nest_end(msg, nl_wowlan); |
8660 | } | 8873 | } |
8661 | 8874 | ||
@@ -10225,7 +10438,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
10225 | }, | 10438 | }, |
10226 | { | 10439 | { |
10227 | .cmd = NL80211_CMD_GET_REG, | 10440 | .cmd = NL80211_CMD_GET_REG, |
10228 | .doit = nl80211_get_reg, | 10441 | .doit = nl80211_get_reg_do, |
10442 | .dumpit = nl80211_get_reg_dump, | ||
10229 | .policy = nl80211_policy, | 10443 | .policy = nl80211_policy, |
10230 | .internal_flags = NL80211_FLAG_NEED_RTNL, | 10444 | .internal_flags = NL80211_FLAG_NEED_RTNL, |
10231 | /* can be retrieved by unprivileged users */ | 10445 | /* can be retrieved by unprivileged users */ |
@@ -10939,25 +11153,9 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, | |||
10939 | NL80211_MCGRP_SCAN, GFP_KERNEL); | 11153 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
10940 | } | 11154 | } |
10941 | 11155 | ||
10942 | /* | 11156 | static bool nl80211_reg_change_event_fill(struct sk_buff *msg, |
10943 | * This can happen on global regulatory changes or device specific settings | 11157 | struct regulatory_request *request) |
10944 | * based on custom world regulatory domains. | ||
10945 | */ | ||
10946 | void nl80211_send_reg_change_event(struct regulatory_request *request) | ||
10947 | { | 11158 | { |
10948 | struct sk_buff *msg; | ||
10949 | void *hdr; | ||
10950 | |||
10951 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
10952 | if (!msg) | ||
10953 | return; | ||
10954 | |||
10955 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE); | ||
10956 | if (!hdr) { | ||
10957 | nlmsg_free(msg); | ||
10958 | return; | ||
10959 | } | ||
10960 | |||
10961 | /* Userspace can always count this one always being set */ | 11159 | /* Userspace can always count this one always being set */ |
10962 | if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator)) | 11160 | if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator)) |
10963 | goto nla_put_failure; | 11161 | goto nla_put_failure; |
@@ -10983,8 +11181,46 @@ void nl80211_send_reg_change_event(struct regulatory_request *request) | |||
10983 | goto nla_put_failure; | 11181 | goto nla_put_failure; |
10984 | } | 11182 | } |
10985 | 11183 | ||
10986 | if (request->wiphy_idx != WIPHY_IDX_INVALID && | 11184 | if (request->wiphy_idx != WIPHY_IDX_INVALID) { |
10987 | nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx)) | 11185 | struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx); |
11186 | |||
11187 | if (wiphy && | ||
11188 | nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx)) | ||
11189 | goto nla_put_failure; | ||
11190 | |||
11191 | if (wiphy && | ||
11192 | wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED && | ||
11193 | nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG)) | ||
11194 | goto nla_put_failure; | ||
11195 | } | ||
11196 | |||
11197 | return true; | ||
11198 | |||
11199 | nla_put_failure: | ||
11200 | return false; | ||
11201 | } | ||
11202 | |||
11203 | /* | ||
11204 | * This can happen on global regulatory changes or device specific settings | ||
11205 | * based on custom regulatory domains. | ||
11206 | */ | ||
11207 | void nl80211_common_reg_change_event(enum nl80211_commands cmd_id, | ||
11208 | struct regulatory_request *request) | ||
11209 | { | ||
11210 | struct sk_buff *msg; | ||
11211 | void *hdr; | ||
11212 | |||
11213 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
11214 | if (!msg) | ||
11215 | return; | ||
11216 | |||
11217 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id); | ||
11218 | if (!hdr) { | ||
11219 | nlmsg_free(msg); | ||
11220 | return; | ||
11221 | } | ||
11222 | |||
11223 | if (nl80211_reg_change_event_fill(msg, request) == false) | ||
10988 | goto nla_put_failure; | 11224 | goto nla_put_failure; |
10989 | 11225 | ||
10990 | genlmsg_end(msg, hdr); | 11226 | genlmsg_end(msg, hdr); |
@@ -11523,7 +11759,7 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, | |||
11523 | if (!msg) | 11759 | if (!msg) |
11524 | return; | 11760 | return; |
11525 | 11761 | ||
11526 | if (nl80211_send_station(msg, 0, 0, 0, | 11762 | if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0, |
11527 | rdev, dev, mac_addr, sinfo) < 0) { | 11763 | rdev, dev, mac_addr, sinfo) < 0) { |
11528 | nlmsg_free(msg); | 11764 | nlmsg_free(msg); |
11529 | return; | 11765 | return; |
@@ -11534,12 +11770,16 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, | |||
11534 | } | 11770 | } |
11535 | EXPORT_SYMBOL(cfg80211_new_sta); | 11771 | EXPORT_SYMBOL(cfg80211_new_sta); |
11536 | 11772 | ||
11537 | void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) | 11773 | void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr, |
11774 | struct station_info *sinfo, gfp_t gfp) | ||
11538 | { | 11775 | { |
11539 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 11776 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; |
11540 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | 11777 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
11541 | struct sk_buff *msg; | 11778 | struct sk_buff *msg; |
11542 | void *hdr; | 11779 | struct station_info empty_sinfo = {}; |
11780 | |||
11781 | if (!sinfo) | ||
11782 | sinfo = &empty_sinfo; | ||
11543 | 11783 | ||
11544 | trace_cfg80211_del_sta(dev, mac_addr); | 11784 | trace_cfg80211_del_sta(dev, mac_addr); |
11545 | 11785 | ||
@@ -11547,27 +11787,16 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) | |||
11547 | if (!msg) | 11787 | if (!msg) |
11548 | return; | 11788 | return; |
11549 | 11789 | ||
11550 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION); | 11790 | if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0, |
11551 | if (!hdr) { | 11791 | rdev, dev, mac_addr, sinfo) < 0) { |
11552 | nlmsg_free(msg); | 11792 | nlmsg_free(msg); |
11553 | return; | 11793 | return; |
11554 | } | 11794 | } |
11555 | 11795 | ||
11556 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | ||
11557 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) | ||
11558 | goto nla_put_failure; | ||
11559 | |||
11560 | genlmsg_end(msg, hdr); | ||
11561 | |||
11562 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 11796 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
11563 | NL80211_MCGRP_MLME, gfp); | 11797 | NL80211_MCGRP_MLME, gfp); |
11564 | return; | ||
11565 | |||
11566 | nla_put_failure: | ||
11567 | genlmsg_cancel(msg, hdr); | ||
11568 | nlmsg_free(msg); | ||
11569 | } | 11798 | } |
11570 | EXPORT_SYMBOL(cfg80211_del_sta); | 11799 | EXPORT_SYMBOL(cfg80211_del_sta_sinfo); |
11571 | 11800 | ||
11572 | void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, | 11801 | void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, |
11573 | enum nl80211_connect_failed_reason reason, | 11802 | enum nl80211_connect_failed_reason reason, |
@@ -12471,6 +12700,13 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
12471 | 12700 | ||
12472 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { | 12701 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { |
12473 | bool schedule_destroy_work = false; | 12702 | bool schedule_destroy_work = false; |
12703 | bool schedule_scan_stop = false; | ||
12704 | struct cfg80211_sched_scan_request *sched_scan_req = | ||
12705 | rcu_dereference(rdev->sched_scan_req); | ||
12706 | |||
12707 | if (sched_scan_req && notify->portid && | ||
12708 | sched_scan_req->owner_nlportid == notify->portid) | ||
12709 | schedule_scan_stop = true; | ||
12474 | 12710 | ||
12475 | list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) { | 12711 | list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) { |
12476 | cfg80211_mlme_unregister_socket(wdev, notify->portid); | 12712 | cfg80211_mlme_unregister_socket(wdev, notify->portid); |
@@ -12501,6 +12737,12 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
12501 | spin_unlock(&rdev->destroy_list_lock); | 12737 | spin_unlock(&rdev->destroy_list_lock); |
12502 | schedule_work(&rdev->destroy_work); | 12738 | schedule_work(&rdev->destroy_work); |
12503 | } | 12739 | } |
12740 | } else if (schedule_scan_stop) { | ||
12741 | sched_scan_req->owner_nlportid = 0; | ||
12742 | |||
12743 | if (rdev->ops->sched_scan_stop && | ||
12744 | rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) | ||
12745 | schedule_work(&rdev->sched_scan_stop_wk); | ||
12504 | } | 12746 | } |
12505 | } | 12747 | } |
12506 | 12748 | ||
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 7ad70d6f0cc6..84d4edf1d545 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -17,7 +17,21 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, | |||
17 | struct net_device *netdev, u32 cmd); | 17 | struct net_device *netdev, u32 cmd); |
18 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, | 18 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, |
19 | struct net_device *netdev); | 19 | struct net_device *netdev); |
20 | void nl80211_send_reg_change_event(struct regulatory_request *request); | 20 | void nl80211_common_reg_change_event(enum nl80211_commands cmd_id, |
21 | struct regulatory_request *request); | ||
22 | |||
23 | static inline void | ||
24 | nl80211_send_reg_change_event(struct regulatory_request *request) | ||
25 | { | ||
26 | nl80211_common_reg_change_event(NL80211_CMD_REG_CHANGE, request); | ||
27 | } | ||
28 | |||
29 | static inline void | ||
30 | nl80211_send_wiphy_reg_change_event(struct regulatory_request *request) | ||
31 | { | ||
32 | nl80211_common_reg_change_event(NL80211_CMD_WIPHY_REG_CHANGE, request); | ||
33 | } | ||
34 | |||
21 | void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, | 35 | void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, |
22 | struct net_device *netdev, | 36 | struct net_device *netdev, |
23 | const u8 *buf, size_t len, gfp_t gfp); | 37 | const u8 *buf, size_t len, gfp_t gfp); |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 7b8309840d4e..886cc7cb5566 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -109,7 +109,7 @@ static struct regulatory_request core_request_world = { | |||
109 | * protected by RTNL (and can be accessed with RCU protection) | 109 | * protected by RTNL (and can be accessed with RCU protection) |
110 | */ | 110 | */ |
111 | static struct regulatory_request __rcu *last_request = | 111 | static struct regulatory_request __rcu *last_request = |
112 | (void __rcu *)&core_request_world; | 112 | (void __force __rcu *)&core_request_world; |
113 | 113 | ||
114 | /* To trigger userspace events */ | 114 | /* To trigger userspace events */ |
115 | static struct platform_device *reg_pdev; | 115 | static struct platform_device *reg_pdev; |
@@ -142,7 +142,7 @@ static const struct ieee80211_regdomain *get_cfg80211_regdom(void) | |||
142 | return rtnl_dereference(cfg80211_regdomain); | 142 | return rtnl_dereference(cfg80211_regdomain); |
143 | } | 143 | } |
144 | 144 | ||
145 | static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy) | 145 | const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy) |
146 | { | 146 | { |
147 | return rtnl_dereference(wiphy->regd); | 147 | return rtnl_dereference(wiphy->regd); |
148 | } | 148 | } |
@@ -1307,6 +1307,9 @@ static bool ignore_reg_update(struct wiphy *wiphy, | |||
1307 | { | 1307 | { |
1308 | struct regulatory_request *lr = get_last_request(); | 1308 | struct regulatory_request *lr = get_last_request(); |
1309 | 1309 | ||
1310 | if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) | ||
1311 | return true; | ||
1312 | |||
1310 | if (!lr) { | 1313 | if (!lr) { |
1311 | REG_DBG_PRINT("Ignoring regulatory request set by %s " | 1314 | REG_DBG_PRINT("Ignoring regulatory request set by %s " |
1312 | "since last_request is not set\n", | 1315 | "since last_request is not set\n", |
@@ -1683,8 +1686,12 @@ static void handle_channel_custom(struct wiphy *wiphy, | |||
1683 | if (IS_ERR(reg_rule)) { | 1686 | if (IS_ERR(reg_rule)) { |
1684 | REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n", | 1687 | REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n", |
1685 | chan->center_freq); | 1688 | chan->center_freq); |
1686 | chan->orig_flags |= IEEE80211_CHAN_DISABLED; | 1689 | if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) { |
1687 | chan->flags = chan->orig_flags; | 1690 | chan->flags |= IEEE80211_CHAN_DISABLED; |
1691 | } else { | ||
1692 | chan->orig_flags |= IEEE80211_CHAN_DISABLED; | ||
1693 | chan->flags = chan->orig_flags; | ||
1694 | } | ||
1688 | return; | 1695 | return; |
1689 | } | 1696 | } |
1690 | 1697 | ||
@@ -1709,7 +1716,13 @@ static void handle_channel_custom(struct wiphy *wiphy, | |||
1709 | chan->dfs_state = NL80211_DFS_USABLE; | 1716 | chan->dfs_state = NL80211_DFS_USABLE; |
1710 | 1717 | ||
1711 | chan->beacon_found = false; | 1718 | chan->beacon_found = false; |
1712 | chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; | 1719 | |
1720 | if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) | ||
1721 | chan->flags = chan->orig_flags | bw_flags | | ||
1722 | map_regdom_flags(reg_rule->flags); | ||
1723 | else | ||
1724 | chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; | ||
1725 | |||
1713 | chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); | 1726 | chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); |
1714 | chan->max_reg_power = chan->max_power = | 1727 | chan->max_reg_power = chan->max_power = |
1715 | (int) MBM_TO_DBM(power_rule->max_eirp); | 1728 | (int) MBM_TO_DBM(power_rule->max_eirp); |
@@ -2095,6 +2108,26 @@ out_free: | |||
2095 | reg_free_request(reg_request); | 2108 | reg_free_request(reg_request); |
2096 | } | 2109 | } |
2097 | 2110 | ||
2111 | static bool reg_only_self_managed_wiphys(void) | ||
2112 | { | ||
2113 | struct cfg80211_registered_device *rdev; | ||
2114 | struct wiphy *wiphy; | ||
2115 | bool self_managed_found = false; | ||
2116 | |||
2117 | ASSERT_RTNL(); | ||
2118 | |||
2119 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | ||
2120 | wiphy = &rdev->wiphy; | ||
2121 | if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) | ||
2122 | self_managed_found = true; | ||
2123 | else | ||
2124 | return false; | ||
2125 | } | ||
2126 | |||
2127 | /* make sure at least one self-managed wiphy exists */ | ||
2128 | return self_managed_found; | ||
2129 | } | ||
2130 | |||
2098 | /* | 2131 | /* |
2099 | * Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* | 2132 | * Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* |
2100 | * Regulatory hints come on a first come first serve basis and we | 2133 | * Regulatory hints come on a first come first serve basis and we |
@@ -2126,6 +2159,11 @@ static void reg_process_pending_hints(void) | |||
2126 | 2159 | ||
2127 | spin_unlock(®_requests_lock); | 2160 | spin_unlock(®_requests_lock); |
2128 | 2161 | ||
2162 | if (reg_only_self_managed_wiphys()) { | ||
2163 | reg_free_request(reg_request); | ||
2164 | return; | ||
2165 | } | ||
2166 | |||
2129 | reg_process_hint(reg_request); | 2167 | reg_process_hint(reg_request); |
2130 | } | 2168 | } |
2131 | 2169 | ||
@@ -2153,11 +2191,52 @@ static void reg_process_pending_beacon_hints(void) | |||
2153 | spin_unlock_bh(®_pending_beacons_lock); | 2191 | spin_unlock_bh(®_pending_beacons_lock); |
2154 | } | 2192 | } |
2155 | 2193 | ||
2194 | static void reg_process_self_managed_hints(void) | ||
2195 | { | ||
2196 | struct cfg80211_registered_device *rdev; | ||
2197 | struct wiphy *wiphy; | ||
2198 | const struct ieee80211_regdomain *tmp; | ||
2199 | const struct ieee80211_regdomain *regd; | ||
2200 | enum ieee80211_band band; | ||
2201 | struct regulatory_request request = {}; | ||
2202 | |||
2203 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | ||
2204 | wiphy = &rdev->wiphy; | ||
2205 | |||
2206 | spin_lock(®_requests_lock); | ||
2207 | regd = rdev->requested_regd; | ||
2208 | rdev->requested_regd = NULL; | ||
2209 | spin_unlock(®_requests_lock); | ||
2210 | |||
2211 | if (regd == NULL) | ||
2212 | continue; | ||
2213 | |||
2214 | tmp = get_wiphy_regdom(wiphy); | ||
2215 | rcu_assign_pointer(wiphy->regd, regd); | ||
2216 | rcu_free_regdom(tmp); | ||
2217 | |||
2218 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | ||
2219 | handle_band_custom(wiphy, wiphy->bands[band], regd); | ||
2220 | |||
2221 | reg_process_ht_flags(wiphy); | ||
2222 | |||
2223 | request.wiphy_idx = get_wiphy_idx(wiphy); | ||
2224 | request.alpha2[0] = regd->alpha2[0]; | ||
2225 | request.alpha2[1] = regd->alpha2[1]; | ||
2226 | request.initiator = NL80211_REGDOM_SET_BY_DRIVER; | ||
2227 | |||
2228 | nl80211_send_wiphy_reg_change_event(&request); | ||
2229 | } | ||
2230 | |||
2231 | reg_check_channels(); | ||
2232 | } | ||
2233 | |||
2156 | static void reg_todo(struct work_struct *work) | 2234 | static void reg_todo(struct work_struct *work) |
2157 | { | 2235 | { |
2158 | rtnl_lock(); | 2236 | rtnl_lock(); |
2159 | reg_process_pending_hints(); | 2237 | reg_process_pending_hints(); |
2160 | reg_process_pending_beacon_hints(); | 2238 | reg_process_pending_beacon_hints(); |
2239 | reg_process_self_managed_hints(); | ||
2161 | rtnl_unlock(); | 2240 | rtnl_unlock(); |
2162 | } | 2241 | } |
2163 | 2242 | ||
@@ -2438,6 +2517,8 @@ static void restore_regulatory_settings(bool reset_user) | |||
2438 | world_alpha2[1] = cfg80211_world_regdom->alpha2[1]; | 2517 | world_alpha2[1] = cfg80211_world_regdom->alpha2[1]; |
2439 | 2518 | ||
2440 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | 2519 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { |
2520 | if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) | ||
2521 | continue; | ||
2441 | if (rdev->wiphy.regulatory_flags & REGULATORY_CUSTOM_REG) | 2522 | if (rdev->wiphy.regulatory_flags & REGULATORY_CUSTOM_REG) |
2442 | restore_custom_reg_settings(&rdev->wiphy); | 2523 | restore_custom_reg_settings(&rdev->wiphy); |
2443 | } | 2524 | } |
@@ -2841,10 +2922,79 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
2841 | return 0; | 2922 | return 0; |
2842 | } | 2923 | } |
2843 | 2924 | ||
2925 | static int __regulatory_set_wiphy_regd(struct wiphy *wiphy, | ||
2926 | struct ieee80211_regdomain *rd) | ||
2927 | { | ||
2928 | const struct ieee80211_regdomain *regd; | ||
2929 | const struct ieee80211_regdomain *prev_regd; | ||
2930 | struct cfg80211_registered_device *rdev; | ||
2931 | |||
2932 | if (WARN_ON(!wiphy || !rd)) | ||
2933 | return -EINVAL; | ||
2934 | |||
2935 | if (WARN(!(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED), | ||
2936 | "wiphy should have REGULATORY_WIPHY_SELF_MANAGED\n")) | ||
2937 | return -EPERM; | ||
2938 | |||
2939 | if (WARN(!is_valid_rd(rd), "Invalid regulatory domain detected\n")) { | ||
2940 | print_regdomain_info(rd); | ||
2941 | return -EINVAL; | ||
2942 | } | ||
2943 | |||
2944 | regd = reg_copy_regd(rd); | ||
2945 | if (IS_ERR(regd)) | ||
2946 | return PTR_ERR(regd); | ||
2947 | |||
2948 | rdev = wiphy_to_rdev(wiphy); | ||
2949 | |||
2950 | spin_lock(®_requests_lock); | ||
2951 | prev_regd = rdev->requested_regd; | ||
2952 | rdev->requested_regd = regd; | ||
2953 | spin_unlock(®_requests_lock); | ||
2954 | |||
2955 | kfree(prev_regd); | ||
2956 | return 0; | ||
2957 | } | ||
2958 | |||
2959 | int regulatory_set_wiphy_regd(struct wiphy *wiphy, | ||
2960 | struct ieee80211_regdomain *rd) | ||
2961 | { | ||
2962 | int ret = __regulatory_set_wiphy_regd(wiphy, rd); | ||
2963 | |||
2964 | if (ret) | ||
2965 | return ret; | ||
2966 | |||
2967 | schedule_work(®_work); | ||
2968 | return 0; | ||
2969 | } | ||
2970 | EXPORT_SYMBOL(regulatory_set_wiphy_regd); | ||
2971 | |||
2972 | int regulatory_set_wiphy_regd_sync_rtnl(struct wiphy *wiphy, | ||
2973 | struct ieee80211_regdomain *rd) | ||
2974 | { | ||
2975 | int ret; | ||
2976 | |||
2977 | ASSERT_RTNL(); | ||
2978 | |||
2979 | ret = __regulatory_set_wiphy_regd(wiphy, rd); | ||
2980 | if (ret) | ||
2981 | return ret; | ||
2982 | |||
2983 | /* process the request immediately */ | ||
2984 | reg_process_self_managed_hints(); | ||
2985 | return 0; | ||
2986 | } | ||
2987 | EXPORT_SYMBOL(regulatory_set_wiphy_regd_sync_rtnl); | ||
2988 | |||
2844 | void wiphy_regulatory_register(struct wiphy *wiphy) | 2989 | void wiphy_regulatory_register(struct wiphy *wiphy) |
2845 | { | 2990 | { |
2846 | struct regulatory_request *lr; | 2991 | struct regulatory_request *lr; |
2847 | 2992 | ||
2993 | /* self-managed devices ignore external hints */ | ||
2994 | if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) | ||
2995 | wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS | | ||
2996 | REGULATORY_COUNTRY_IE_IGNORE; | ||
2997 | |||
2848 | if (!reg_dev_ignore_cell_hint(wiphy)) | 2998 | if (!reg_dev_ignore_cell_hint(wiphy)) |
2849 | reg_num_devs_support_basehint++; | 2999 | reg_num_devs_support_basehint++; |
2850 | 3000 | ||
diff --git a/net/wireless/reg.h b/net/wireless/reg.h index 5e48031ccb9a..4b45d6e61d24 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h | |||
@@ -38,6 +38,7 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, | |||
38 | const struct ieee80211_reg_rule *rule); | 38 | const struct ieee80211_reg_rule *rule); |
39 | 39 | ||
40 | bool reg_last_request_cell_base(void); | 40 | bool reg_last_request_cell_base(void); |
41 | const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy); | ||
41 | 42 | ||
42 | /** | 43 | /** |
43 | * regulatory_hint_found_beacon - hints a beacon was found on a channel | 44 | * regulatory_hint_found_beacon - hints a beacon was found on a channel |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index bda39f149810..c705c3e2b751 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -257,7 +257,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk) | |||
257 | 257 | ||
258 | rtnl_lock(); | 258 | rtnl_lock(); |
259 | 259 | ||
260 | request = rdev->sched_scan_req; | 260 | request = rtnl_dereference(rdev->sched_scan_req); |
261 | 261 | ||
262 | /* we don't have sched_scan_req anymore if the scan is stopping */ | 262 | /* we don't have sched_scan_req anymore if the scan is stopping */ |
263 | if (request) { | 263 | if (request) { |
@@ -279,7 +279,8 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy) | |||
279 | { | 279 | { |
280 | trace_cfg80211_sched_scan_results(wiphy); | 280 | trace_cfg80211_sched_scan_results(wiphy); |
281 | /* ignore if we're not scanning */ | 281 | /* ignore if we're not scanning */ |
282 | if (wiphy_to_rdev(wiphy)->sched_scan_req) | 282 | |
283 | if (rcu_access_pointer(wiphy_to_rdev(wiphy)->sched_scan_req)) | ||
283 | queue_work(cfg80211_wq, | 284 | queue_work(cfg80211_wq, |
284 | &wiphy_to_rdev(wiphy)->sched_scan_results_wk); | 285 | &wiphy_to_rdev(wiphy)->sched_scan_results_wk); |
285 | } | 286 | } |
@@ -308,6 +309,7 @@ EXPORT_SYMBOL(cfg80211_sched_scan_stopped); | |||
308 | int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | 309 | int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, |
309 | bool driver_initiated) | 310 | bool driver_initiated) |
310 | { | 311 | { |
312 | struct cfg80211_sched_scan_request *sched_scan_req; | ||
311 | struct net_device *dev; | 313 | struct net_device *dev; |
312 | 314 | ||
313 | ASSERT_RTNL(); | 315 | ASSERT_RTNL(); |
@@ -315,7 +317,8 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | |||
315 | if (!rdev->sched_scan_req) | 317 | if (!rdev->sched_scan_req) |
316 | return -ENOENT; | 318 | return -ENOENT; |
317 | 319 | ||
318 | dev = rdev->sched_scan_req->dev; | 320 | sched_scan_req = rtnl_dereference(rdev->sched_scan_req); |
321 | dev = sched_scan_req->dev; | ||
319 | 322 | ||
320 | if (!driver_initiated) { | 323 | if (!driver_initiated) { |
321 | int err = rdev_sched_scan_stop(rdev, dev); | 324 | int err = rdev_sched_scan_stop(rdev, dev); |
@@ -325,8 +328,8 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | |||
325 | 328 | ||
326 | nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED); | 329 | nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED); |
327 | 330 | ||
328 | kfree(rdev->sched_scan_req); | 331 | RCU_INIT_POINTER(rdev->sched_scan_req, NULL); |
329 | rdev->sched_scan_req = NULL; | 332 | kfree_rcu(sched_scan_req, rcu_head); |
330 | 333 | ||
331 | return 0; | 334 | return 0; |
332 | } | 335 | } |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index ad38910f7036..b17b3692f8c2 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1604,11 +1604,12 @@ TRACE_EVENT(rdev_return_int_survey_info, | |||
1604 | WIPHY_ENTRY | 1604 | WIPHY_ENTRY |
1605 | CHAN_ENTRY | 1605 | CHAN_ENTRY |
1606 | __field(int, ret) | 1606 | __field(int, ret) |
1607 | __field(u64, channel_time) | 1607 | __field(u64, time) |
1608 | __field(u64, channel_time_busy) | 1608 | __field(u64, time_busy) |
1609 | __field(u64, channel_time_ext_busy) | 1609 | __field(u64, time_ext_busy) |
1610 | __field(u64, channel_time_rx) | 1610 | __field(u64, time_rx) |
1611 | __field(u64, channel_time_tx) | 1611 | __field(u64, time_tx) |
1612 | __field(u64, time_scan) | ||
1612 | __field(u32, filled) | 1613 | __field(u32, filled) |
1613 | __field(s8, noise) | 1614 | __field(s8, noise) |
1614 | ), | 1615 | ), |
@@ -1616,22 +1617,24 @@ TRACE_EVENT(rdev_return_int_survey_info, | |||
1616 | WIPHY_ASSIGN; | 1617 | WIPHY_ASSIGN; |
1617 | CHAN_ASSIGN(info->channel); | 1618 | CHAN_ASSIGN(info->channel); |
1618 | __entry->ret = ret; | 1619 | __entry->ret = ret; |
1619 | __entry->channel_time = info->channel_time; | 1620 | __entry->time = info->time; |
1620 | __entry->channel_time_busy = info->channel_time_busy; | 1621 | __entry->time_busy = info->time_busy; |
1621 | __entry->channel_time_ext_busy = info->channel_time_ext_busy; | 1622 | __entry->time_ext_busy = info->time_ext_busy; |
1622 | __entry->channel_time_rx = info->channel_time_rx; | 1623 | __entry->time_rx = info->time_rx; |
1623 | __entry->channel_time_tx = info->channel_time_tx; | 1624 | __entry->time_tx = info->time_tx; |
1625 | __entry->time_scan = info->time_scan; | ||
1624 | __entry->filled = info->filled; | 1626 | __entry->filled = info->filled; |
1625 | __entry->noise = info->noise; | 1627 | __entry->noise = info->noise; |
1626 | ), | 1628 | ), |
1627 | TP_printk(WIPHY_PR_FMT ", returned: %d, " CHAN_PR_FMT | 1629 | TP_printk(WIPHY_PR_FMT ", returned: %d, " CHAN_PR_FMT |
1628 | ", channel time: %llu, channel time busy: %llu, " | 1630 | ", channel time: %llu, channel time busy: %llu, " |
1629 | "channel time extension busy: %llu, channel time rx: %llu, " | 1631 | "channel time extension busy: %llu, channel time rx: %llu, " |
1630 | "channel time tx: %llu, filled: %u, noise: %d", | 1632 | "channel time tx: %llu, scan time: %llu, filled: %u, noise: %d", |
1631 | WIPHY_PR_ARG, __entry->ret, CHAN_PR_ARG, | 1633 | WIPHY_PR_ARG, __entry->ret, CHAN_PR_ARG, |
1632 | __entry->channel_time, __entry->channel_time_busy, | 1634 | __entry->time, __entry->time_busy, |
1633 | __entry->channel_time_ext_busy, __entry->channel_time_rx, | 1635 | __entry->time_ext_busy, __entry->time_rx, |
1634 | __entry->channel_time_tx, __entry->filled, __entry->noise) | 1636 | __entry->time_tx, __entry->time_scan, |
1637 | __entry->filled, __entry->noise) | ||
1635 | ); | 1638 | ); |
1636 | 1639 | ||
1637 | TRACE_EVENT(rdev_tdls_oper, | 1640 | TRACE_EVENT(rdev_tdls_oper, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index d0ac795445b7..3535e8ade48f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -1073,10 +1073,24 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate) | |||
1073 | if (WARN_ON_ONCE(rate->mcs > 9)) | 1073 | if (WARN_ON_ONCE(rate->mcs > 9)) |
1074 | return 0; | 1074 | return 0; |
1075 | 1075 | ||
1076 | idx = rate->flags & (RATE_INFO_FLAGS_160_MHZ_WIDTH | | 1076 | switch (rate->bw) { |
1077 | RATE_INFO_FLAGS_80P80_MHZ_WIDTH) ? 3 : | 1077 | case RATE_INFO_BW_160: |
1078 | rate->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH ? 2 : | 1078 | idx = 3; |
1079 | rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH ? 1 : 0; | 1079 | break; |
1080 | case RATE_INFO_BW_80: | ||
1081 | idx = 2; | ||
1082 | break; | ||
1083 | case RATE_INFO_BW_40: | ||
1084 | idx = 1; | ||
1085 | break; | ||
1086 | case RATE_INFO_BW_5: | ||
1087 | case RATE_INFO_BW_10: | ||
1088 | default: | ||
1089 | WARN_ON(1); | ||
1090 | /* fall through */ | ||
1091 | case RATE_INFO_BW_20: | ||
1092 | idx = 0; | ||
1093 | } | ||
1080 | 1094 | ||
1081 | bitrate = base[idx][rate->mcs]; | 1095 | bitrate = base[idx][rate->mcs]; |
1082 | bitrate *= rate->nss; | 1096 | bitrate *= rate->nss; |
@@ -1107,8 +1121,7 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate) | |||
1107 | modulation = rate->mcs & 7; | 1121 | modulation = rate->mcs & 7; |
1108 | streams = (rate->mcs >> 3) + 1; | 1122 | streams = (rate->mcs >> 3) + 1; |
1109 | 1123 | ||
1110 | bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ? | 1124 | bitrate = (rate->bw == RATE_INFO_BW_40) ? 13500000 : 6500000; |
1111 | 13500000 : 6500000; | ||
1112 | 1125 | ||
1113 | if (modulation < 4) | 1126 | if (modulation < 4) |
1114 | bitrate *= (modulation + 1); | 1127 | bitrate *= (modulation + 1); |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 0f47948c572f..5b24d39d7903 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -1300,7 +1300,7 @@ static int cfg80211_wext_giwrate(struct net_device *dev, | |||
1300 | if (err) | 1300 | if (err) |
1301 | return err; | 1301 | return err; |
1302 | 1302 | ||
1303 | if (!(sinfo.filled & STATION_INFO_TX_BITRATE)) | 1303 | if (!(sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE))) |
1304 | return -EOPNOTSUPP; | 1304 | return -EOPNOTSUPP; |
1305 | 1305 | ||
1306 | rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate); | 1306 | rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate); |
@@ -1340,7 +1340,7 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) | |||
1340 | 1340 | ||
1341 | switch (rdev->wiphy.signal_type) { | 1341 | switch (rdev->wiphy.signal_type) { |
1342 | case CFG80211_SIGNAL_TYPE_MBM: | 1342 | case CFG80211_SIGNAL_TYPE_MBM: |
1343 | if (sinfo.filled & STATION_INFO_SIGNAL) { | 1343 | if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL)) { |
1344 | int sig = sinfo.signal; | 1344 | int sig = sinfo.signal; |
1345 | wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; | 1345 | wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; |
1346 | wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; | 1346 | wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; |
@@ -1354,7 +1354,7 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) | |||
1354 | break; | 1354 | break; |
1355 | } | 1355 | } |
1356 | case CFG80211_SIGNAL_TYPE_UNSPEC: | 1356 | case CFG80211_SIGNAL_TYPE_UNSPEC: |
1357 | if (sinfo.filled & STATION_INFO_SIGNAL) { | 1357 | if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL)) { |
1358 | wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; | 1358 | wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; |
1359 | wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; | 1359 | wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; |
1360 | wstats.qual.level = sinfo.signal; | 1360 | wstats.qual.level = sinfo.signal; |
@@ -1367,9 +1367,9 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) | |||
1367 | } | 1367 | } |
1368 | 1368 | ||
1369 | wstats.qual.updated |= IW_QUAL_NOISE_INVALID; | 1369 | wstats.qual.updated |= IW_QUAL_NOISE_INVALID; |
1370 | if (sinfo.filled & STATION_INFO_RX_DROP_MISC) | 1370 | if (sinfo.filled & BIT(NL80211_STA_INFO_RX_DROP_MISC)) |
1371 | wstats.discard.misc = sinfo.rx_dropped_misc; | 1371 | wstats.discard.misc = sinfo.rx_dropped_misc; |
1372 | if (sinfo.filled & STATION_INFO_TX_FAILED) | 1372 | if (sinfo.filled & BIT(NL80211_STA_INFO_TX_FAILED)) |
1373 | wstats.discard.retries = sinfo.tx_failed; | 1373 | wstats.discard.retries = sinfo.tx_failed; |
1374 | 1374 | ||
1375 | return &wstats; | 1375 | return &wstats; |