diff options
| -rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
| -rw-r--r-- | net/mac80211/scan.c | 19 | ||||
| -rw-r--r-- | net/mac80211/util.c | 4 | ||||
| -rw-r--r-- | net/wireless/core.c | 2 | ||||
| -rw-r--r-- | net/wireless/core.h | 3 | ||||
| -rw-r--r-- | net/wireless/radiotap.c | 7 |
6 files changed, 35 insertions, 3 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b6186517ec56..611abfcfb5eb 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -893,6 +893,8 @@ struct tpt_led_trigger { | |||
| 893 | * that the scan completed. | 893 | * that the scan completed. |
| 894 | * @SCAN_ABORTED: Set for our scan work function when the driver reported | 894 | * @SCAN_ABORTED: Set for our scan work function when the driver reported |
| 895 | * a scan complete for an aborted scan. | 895 | * a scan complete for an aborted scan. |
| 896 | * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being | ||
| 897 | * cancelled. | ||
| 896 | */ | 898 | */ |
| 897 | enum { | 899 | enum { |
| 898 | SCAN_SW_SCANNING, | 900 | SCAN_SW_SCANNING, |
| @@ -900,6 +902,7 @@ enum { | |||
| 900 | SCAN_ONCHANNEL_SCANNING, | 902 | SCAN_ONCHANNEL_SCANNING, |
| 901 | SCAN_COMPLETED, | 903 | SCAN_COMPLETED, |
| 902 | SCAN_ABORTED, | 904 | SCAN_ABORTED, |
| 905 | SCAN_HW_CANCELLED, | ||
| 903 | }; | 906 | }; |
| 904 | 907 | ||
| 905 | /** | 908 | /** |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 08afe74b98f4..d2d17a449224 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -238,6 +238,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
| 238 | enum ieee80211_band band; | 238 | enum ieee80211_band band; |
| 239 | int i, ielen, n_chans; | 239 | int i, ielen, n_chans; |
| 240 | 240 | ||
| 241 | if (test_bit(SCAN_HW_CANCELLED, &local->scanning)) | ||
| 242 | return false; | ||
| 243 | |||
| 241 | do { | 244 | do { |
| 242 | if (local->hw_scan_band == IEEE80211_NUM_BANDS) | 245 | if (local->hw_scan_band == IEEE80211_NUM_BANDS) |
| 243 | return false; | 246 | return false; |
| @@ -940,7 +943,23 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) | |||
| 940 | if (!local->scan_req) | 943 | if (!local->scan_req) |
| 941 | goto out; | 944 | goto out; |
| 942 | 945 | ||
| 946 | /* | ||
| 947 | * We have a scan running and the driver already reported completion, | ||
| 948 | * but the worker hasn't run yet or is stuck on the mutex - mark it as | ||
| 949 | * cancelled. | ||
| 950 | */ | ||
| 951 | if (test_bit(SCAN_HW_SCANNING, &local->scanning) && | ||
| 952 | test_bit(SCAN_COMPLETED, &local->scanning)) { | ||
| 953 | set_bit(SCAN_HW_CANCELLED, &local->scanning); | ||
| 954 | goto out; | ||
| 955 | } | ||
| 956 | |||
| 943 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { | 957 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { |
| 958 | /* | ||
| 959 | * Make sure that __ieee80211_scan_completed doesn't trigger a | ||
| 960 | * scan on another band. | ||
| 961 | */ | ||
| 962 | set_bit(SCAN_HW_CANCELLED, &local->scanning); | ||
| 944 | if (local->ops->cancel_hw_scan) | 963 | if (local->ops->cancel_hw_scan) |
| 945 | drv_cancel_hw_scan(local, | 964 | drv_cancel_hw_scan(local, |
| 946 | rcu_dereference_protected(local->scan_sdata, | 965 | rcu_dereference_protected(local->scan_sdata, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 9c3200bcfc02..69e4ef5348a0 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -2238,6 +2238,10 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, | |||
| 2238 | } | 2238 | } |
| 2239 | 2239 | ||
| 2240 | rate = cfg80211_calculate_bitrate(&ri); | 2240 | rate = cfg80211_calculate_bitrate(&ri); |
| 2241 | if (WARN_ONCE(!rate, | ||
| 2242 | "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n", | ||
| 2243 | status->flag, status->rate_idx, status->vht_nss)) | ||
| 2244 | return 0; | ||
| 2241 | 2245 | ||
| 2242 | /* rewind from end of MPDU */ | 2246 | /* rewind from end of MPDU */ |
| 2243 | if (status->flag & RX_FLAG_MACTIME_END) | 2247 | if (status->flag & RX_FLAG_MACTIME_END) |
diff --git a/net/wireless/core.c b/net/wireless/core.c index fe8d4f2be49b..aff959e5a1b3 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -958,8 +958,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
| 958 | case NETDEV_PRE_UP: | 958 | case NETDEV_PRE_UP: |
| 959 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) | 959 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) |
| 960 | return notifier_from_errno(-EOPNOTSUPP); | 960 | return notifier_from_errno(-EOPNOTSUPP); |
| 961 | if (rfkill_blocked(rdev->rfkill)) | ||
| 962 | return notifier_from_errno(-ERFKILL); | ||
| 963 | ret = cfg80211_can_add_interface(rdev, wdev->iftype); | 961 | ret = cfg80211_can_add_interface(rdev, wdev->iftype); |
| 964 | if (ret) | 962 | if (ret) |
| 965 | return notifier_from_errno(ret); | 963 | return notifier_from_errno(ret); |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 9ad43c619c54..3159e9c284c5 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
| @@ -411,6 +411,9 @@ static inline int | |||
| 411 | cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, | 411 | cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, |
| 412 | enum nl80211_iftype iftype) | 412 | enum nl80211_iftype iftype) |
| 413 | { | 413 | { |
| 414 | if (rfkill_blocked(rdev->rfkill)) | ||
| 415 | return -ERFKILL; | ||
| 416 | |||
| 414 | return cfg80211_can_change_interface(rdev, NULL, iftype); | 417 | return cfg80211_can_change_interface(rdev, NULL, iftype); |
| 415 | } | 418 | } |
| 416 | 419 | ||
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index 7d604c06c3dc..a271c27fac77 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c | |||
| @@ -97,6 +97,10 @@ int ieee80211_radiotap_iterator_init( | |||
| 97 | struct ieee80211_radiotap_header *radiotap_header, | 97 | struct ieee80211_radiotap_header *radiotap_header, |
| 98 | int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns) | 98 | int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns) |
| 99 | { | 99 | { |
| 100 | /* check the radiotap header can actually be present */ | ||
| 101 | if (max_length < sizeof(struct ieee80211_radiotap_header)) | ||
| 102 | return -EINVAL; | ||
| 103 | |||
| 100 | /* Linux only supports version 0 radiotap format */ | 104 | /* Linux only supports version 0 radiotap format */ |
| 101 | if (radiotap_header->it_version) | 105 | if (radiotap_header->it_version) |
| 102 | return -EINVAL; | 106 | return -EINVAL; |
| @@ -131,7 +135,8 @@ int ieee80211_radiotap_iterator_init( | |||
| 131 | */ | 135 | */ |
| 132 | 136 | ||
| 133 | if ((unsigned long)iterator->_arg - | 137 | if ((unsigned long)iterator->_arg - |
| 134 | (unsigned long)iterator->_rtheader > | 138 | (unsigned long)iterator->_rtheader + |
| 139 | sizeof(uint32_t) > | ||
| 135 | (unsigned long)iterator->_max_length) | 140 | (unsigned long)iterator->_max_length) |
| 136 | return -EINVAL; | 141 | return -EINVAL; |
| 137 | } | 142 | } |
