diff options
author | David S. Miller <davem@davemloft.net> | 2015-05-09 17:27:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-05-09 17:27:25 -0400 |
commit | 0e00a0f73f9c7f5e9f02d064ed0165a3aeeb2de5 (patch) | |
tree | 5511eef8907c8b00985d74d8583c5253604ddb2e | |
parent | 82ae9c6060c6dbaf103273a5c51b8f58b951d9a2 (diff) | |
parent | bbbe8c8c596b3784a2ed08772900e827f8ba72c5 (diff) |
Merge tag 'mac80211-next-for-davem-2015-05-06' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says:
====================
Lots of updates for net-next for this cycle. As usual, we have
a lot of small fixes and cleanups, the bigger items are:
* proper mac80211 rate control locking, to fix some random crashes
(this required changing other locking as well)
* mac80211 "fast-xmit", a mechanism to reduce, in most cases, the
amount of code we execute while going from ndo_start_xmit() to
the driver
* this also clears the way for properly supporting S/G and checksum
and segmentation offloads
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
76 files changed, 1429 insertions, 843 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index f07a61899545..413528295d72 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -1353,12 +1353,7 @@ static void adm8211_configure_filter(struct ieee80211_hw *dev, | |||
1353 | 1353 | ||
1354 | new_flags = 0; | 1354 | new_flags = 0; |
1355 | 1355 | ||
1356 | if (*total_flags & FIF_PROMISC_IN_BSS) { | 1356 | if (*total_flags & FIF_ALLMULTI || multicast == ~(0ULL)) { |
1357 | new_flags |= FIF_PROMISC_IN_BSS; | ||
1358 | priv->nar |= ADM8211_NAR_PR; | ||
1359 | priv->nar &= ~ADM8211_NAR_MM; | ||
1360 | mc_filter[1] = mc_filter[0] = ~0; | ||
1361 | } else if (*total_flags & FIF_ALLMULTI || multicast == ~(0ULL)) { | ||
1362 | new_flags |= FIF_ALLMULTI; | 1357 | new_flags |= FIF_ALLMULTI; |
1363 | priv->nar &= ~ADM8211_NAR_PR; | 1358 | priv->nar &= ~ADM8211_NAR_PR; |
1364 | priv->nar |= ADM8211_NAR_MM; | 1359 | priv->nar |= ADM8211_NAR_MM; |
diff --git a/drivers/net/wireless/at76c50x-usb.h b/drivers/net/wireless/at76c50x-usb.h index 55090a38ac95..ae03271f878e 100644 --- a/drivers/net/wireless/at76c50x-usb.h +++ b/drivers/net/wireless/at76c50x-usb.h | |||
@@ -447,7 +447,7 @@ struct at76_priv { | |||
447 | int mac80211_registered; | 447 | int mac80211_registered; |
448 | }; | 448 | }; |
449 | 449 | ||
450 | #define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS | 450 | #define AT76_SUPPORTED_FILTERS 0 |
451 | 451 | ||
452 | #define SCAN_POLL_INTERVAL (HZ / 4) | 452 | #define SCAN_POLL_INTERVAL (HZ / 4) |
453 | 453 | ||
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 5147ebe4cd05..14937cbeca56 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
@@ -1319,8 +1319,7 @@ out_unlock: | |||
1319 | 1319 | ||
1320 | } | 1320 | } |
1321 | 1321 | ||
1322 | #define AR5523_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ | 1322 | #define AR5523_SUPPORTED_FILTERS (FIF_ALLMULTI | \ |
1323 | FIF_ALLMULTI | \ | ||
1324 | FIF_FCSFAIL | \ | 1323 | FIF_FCSFAIL | \ |
1325 | FIF_OTHER_BSS) | 1324 | FIF_OTHER_BSS) |
1326 | 1325 | ||
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 973485bd4121..fcd08b2f8d26 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -773,7 +773,6 @@ static int ath10k_monitor_recalc(struct ath10k *ar) | |||
773 | lockdep_assert_held(&ar->conf_mutex); | 773 | lockdep_assert_held(&ar->conf_mutex); |
774 | 774 | ||
775 | should_start = ar->monitor || | 775 | should_start = ar->monitor || |
776 | ar->filter_flags & FIF_PROMISC_IN_BSS || | ||
777 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 776 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
778 | 777 | ||
779 | ath10k_dbg(ar, ATH10K_DBG_MAC, | 778 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
@@ -3493,8 +3492,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, | |||
3493 | * FIXME: Has to be verified. | 3492 | * FIXME: Has to be verified. |
3494 | */ | 3493 | */ |
3495 | #define SUPPORTED_FILTERS \ | 3494 | #define SUPPORTED_FILTERS \ |
3496 | (FIF_PROMISC_IN_BSS | \ | 3495 | (FIF_ALLMULTI | \ |
3497 | FIF_ALLMULTI | \ | ||
3498 | FIF_CONTROL | \ | 3496 | FIF_CONTROL | \ |
3499 | FIF_PSPOLL | \ | 3497 | FIF_PSPOLL | \ |
3500 | FIF_OTHER_BSS | \ | 3498 | FIF_OTHER_BSS | \ |
@@ -5500,7 +5498,8 @@ int ath10k_mac_register(struct ath10k *ar) | |||
5500 | IEEE80211_HW_HAS_RATE_CONTROL | | 5498 | IEEE80211_HW_HAS_RATE_CONTROL | |
5501 | IEEE80211_HW_AP_LINK_PS | | 5499 | IEEE80211_HW_AP_LINK_PS | |
5502 | IEEE80211_HW_SPECTRUM_MGMT | | 5500 | IEEE80211_HW_SPECTRUM_MGMT | |
5503 | IEEE80211_HW_SW_CRYPTO_CONTROL; | 5501 | IEEE80211_HW_SW_CRYPTO_CONTROL | |
5502 | IEEE80211_HW_SUPPORT_FAST_XMIT; | ||
5504 | 5503 | ||
5505 | ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; | 5504 | ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; |
5506 | 5505 | ||
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 7ca0d6f930fd..e22b0e778927 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1280,7 +1280,6 @@ struct ath5k_hw { | |||
1280 | 1280 | ||
1281 | DECLARE_BITMAP(status, 4); | 1281 | DECLARE_BITMAP(status, 4); |
1282 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ | 1282 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ |
1283 | #define ATH_STAT_PROMISC 1 | ||
1284 | #define ATH_STAT_LEDSOFT 2 /* enable LED gpio status */ | 1283 | #define ATH_STAT_LEDSOFT 2 /* enable LED gpio status */ |
1285 | #define ATH_STAT_STARTED 3 /* opened & irqs enabled */ | 1284 | #define ATH_STAT_STARTED 3 /* opened & irqs enabled */ |
1286 | #define ATH_STAT_RESET 4 /* hw reset */ | 1285 | #define ATH_STAT_RESET 4 /* hw reset */ |
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index ca4b7ccd697f..803030fd17d3 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c | |||
@@ -124,7 +124,7 @@ ath5k_led_brightness_set(struct led_classdev *led_dev, | |||
124 | 124 | ||
125 | static int | 125 | static int |
126 | ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led, | 126 | ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led, |
127 | const char *name, char *trigger) | 127 | const char *name, const char *trigger) |
128 | { | 128 | { |
129 | int err; | 129 | int err; |
130 | 130 | ||
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 3b4a6463d87a..dc44cfef7517 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -369,7 +369,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
369 | unsigned int *new_flags, u64 multicast) | 369 | unsigned int *new_flags, u64 multicast) |
370 | { | 370 | { |
371 | #define SUPPORTED_FIF_FLAGS \ | 371 | #define SUPPORTED_FIF_FLAGS \ |
372 | (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ | 372 | (FIF_ALLMULTI | FIF_FCSFAIL | \ |
373 | FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ | 373 | FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ |
374 | FIF_BCN_PRBRESP_PROMISC) | 374 | FIF_BCN_PRBRESP_PROMISC) |
375 | 375 | ||
@@ -393,16 +393,6 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
393 | (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | | 393 | (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | |
394 | AR5K_RX_FILTER_MCAST); | 394 | AR5K_RX_FILTER_MCAST); |
395 | 395 | ||
396 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | ||
397 | if (*new_flags & FIF_PROMISC_IN_BSS) | ||
398 | __set_bit(ATH_STAT_PROMISC, ah->status); | ||
399 | else | ||
400 | __clear_bit(ATH_STAT_PROMISC, ah->status); | ||
401 | } | ||
402 | |||
403 | if (test_bit(ATH_STAT_PROMISC, ah->status)) | ||
404 | rfilt |= AR5K_RX_FILTER_PROM; | ||
405 | |||
406 | /* Note, AR5K_RX_FILTER_MCAST is already enabled */ | 396 | /* Note, AR5K_RX_FILTER_MCAST is already enabled */ |
407 | if (*new_flags & FIF_ALLMULTI) { | 397 | if (*new_flags & FIF_ALLMULTI) { |
408 | mfilt[0] = ~0; | 398 | mfilt[0] = ~0; |
@@ -418,8 +408,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
418 | if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (ah->nvifs > 1)) | 408 | if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (ah->nvifs > 1)) |
419 | rfilt |= AR5K_RX_FILTER_BEACON; | 409 | rfilt |= AR5K_RX_FILTER_BEACON; |
420 | 410 | ||
421 | /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not | 411 | /* FIF_CONTROL doc says we should only pass on control frames for this |
422 | * set we should only pass on control frames for this | ||
423 | * station. This needs testing. I believe right now this | 412 | * station. This needs testing. I believe right now this |
424 | * enables *all* control frames, which is OK.. but | 413 | * enables *all* control frames, which is OK.. but |
425 | * but we should see if we can improve on granularity */ | 414 | * but we should see if we can improve on granularity */ |
@@ -809,7 +798,6 @@ const struct ieee80211_ops ath5k_hw_ops = { | |||
809 | .sw_scan_start = ath5k_sw_scan_start, | 798 | .sw_scan_start = ath5k_sw_scan_start, |
810 | .sw_scan_complete = ath5k_sw_scan_complete, | 799 | .sw_scan_complete = ath5k_sw_scan_complete, |
811 | .get_stats = ath5k_get_stats, | 800 | .get_stats = ath5k_get_stats, |
812 | /* .get_tkip_seq = not implemented */ | ||
813 | /* .set_frag_threshold = not implemented */ | 801 | /* .set_frag_threshold = not implemented */ |
814 | /* .set_rts_threshold = not implemented */ | 802 | /* .set_rts_threshold = not implemented */ |
815 | /* .sta_add = not implemented */ | 803 | /* .sta_add = not implemented */ |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 564923c0df87..b71f3072fd9a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1238,8 +1238,7 @@ out: | |||
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | #define SUPPORTED_FILTERS \ | 1240 | #define SUPPORTED_FILTERS \ |
1241 | (FIF_PROMISC_IN_BSS | \ | 1241 | (FIF_ALLMULTI | \ |
1242 | FIF_ALLMULTI | \ | ||
1243 | FIF_CONTROL | \ | 1242 | FIF_CONTROL | \ |
1244 | FIF_PSPOLL | \ | 1243 | FIF_PSPOLL | \ |
1245 | FIF_OTHER_BSS | \ | 1244 | FIF_OTHER_BSS | \ |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index a0f58e2aa553..cc9648f844ae 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -872,14 +872,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) | |||
872 | if (priv->rxfilter & FIF_PROBE_REQ) | 872 | if (priv->rxfilter & FIF_PROBE_REQ) |
873 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; | 873 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; |
874 | 874 | ||
875 | /* | 875 | if (ah->is_monitoring) |
876 | * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station | ||
877 | * mode interface or when in monitor mode. AP mode does not need this | ||
878 | * since it receives all in-BSS frames anyway. | ||
879 | */ | ||
880 | if (((ah->opmode != NL80211_IFTYPE_AP) && | ||
881 | (priv->rxfilter & FIF_PROMISC_IN_BSS)) || | ||
882 | ah->is_monitoring) | ||
883 | rfilt |= ATH9K_RX_FILTER_PROM; | 876 | rfilt |= ATH9K_RX_FILTER_PROM; |
884 | 877 | ||
885 | if (priv->rxfilter & FIF_CONTROL) | 878 | if (priv->rxfilter & FIF_CONTROL) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index b0badef71ce7..d285e3a89853 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1442,8 +1442,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | #define SUPPORTED_FILTERS \ | 1444 | #define SUPPORTED_FILTERS \ |
1445 | (FIF_PROMISC_IN_BSS | \ | 1445 | (FIF_ALLMULTI | \ |
1446 | FIF_ALLMULTI | \ | ||
1447 | FIF_CONTROL | \ | 1446 | FIF_CONTROL | \ |
1448 | FIF_PSPOLL | \ | 1447 | FIF_PSPOLL | \ |
1449 | FIF_OTHER_BSS | \ | 1448 | FIF_OTHER_BSS | \ |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 6fb40ef86fd6..6c75fb1ab77d 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -392,11 +392,6 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
392 | if (sc->cur_chan->rxfilter & FIF_PROBE_REQ) | 392 | if (sc->cur_chan->rxfilter & FIF_PROBE_REQ) |
393 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; | 393 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; |
394 | 394 | ||
395 | /* | ||
396 | * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station | ||
397 | * mode interface or when in monitor mode. AP mode does not need this | ||
398 | * since it receives all in-BSS frames anyway. | ||
399 | */ | ||
400 | if (sc->sc_ah->is_monitoring) | 395 | if (sc->sc_ah->is_monitoring) |
401 | rfilt |= ATH9K_RX_FILTER_PROM; | 396 | rfilt |= ATH9K_RX_FILTER_PROM; |
402 | 397 | ||
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 47d5c2e910ad..020cd46471f5 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c | |||
@@ -310,8 +310,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
310 | if (SUPP(CARL9170FW_RX_FILTER)) { | 310 | if (SUPP(CARL9170FW_RX_FILTER)) { |
311 | ar->fw.rx_filter = true; | 311 | ar->fw.rx_filter = true; |
312 | ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL | | 312 | ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL | |
313 | FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS | | 313 | FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS; |
314 | FIF_PROMISC_IN_BSS; | ||
315 | } | 314 | } |
316 | 315 | ||
317 | if (SUPP(CARL9170FW_HW_COUNTERS)) | 316 | if (SUPP(CARL9170FW_HW_COUNTERS)) |
diff --git a/drivers/net/wireless/ath/carl9170/led.c b/drivers/net/wireless/ath/carl9170/led.c index 78dadc797558..2c74425f5059 100644 --- a/drivers/net/wireless/ath/carl9170/led.c +++ b/drivers/net/wireless/ath/carl9170/led.c | |||
@@ -122,7 +122,7 @@ static void carl9170_led_set_brightness(struct led_classdev *led, | |||
122 | } | 122 | } |
123 | 123 | ||
124 | static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name, | 124 | static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name, |
125 | char *trigger) | 125 | const char *trigger) |
126 | { | 126 | { |
127 | int err; | 127 | int err; |
128 | 128 | ||
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index f1455a04cb62..59db6732d4e3 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1011,9 +1011,8 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw, | |||
1011 | if (multicast != ar->cur_mc_hash) | 1011 | if (multicast != ar->cur_mc_hash) |
1012 | WARN_ON(carl9170_update_multicast(ar, multicast)); | 1012 | WARN_ON(carl9170_update_multicast(ar, multicast)); |
1013 | 1013 | ||
1014 | if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) { | 1014 | if (changed_flags & FIF_OTHER_BSS) { |
1015 | ar->sniffer_enabled = !!(*new_flags & | 1015 | ar->sniffer_enabled = !!(*new_flags & FIF_OTHER_BSS); |
1016 | (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)); | ||
1017 | 1016 | ||
1018 | WARN_ON(carl9170_set_operating_mode(ar)); | 1017 | WARN_ON(carl9170_set_operating_mode(ar)); |
1019 | } | 1018 | } |
@@ -1033,7 +1032,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw, | |||
1033 | if (!(*new_flags & FIF_PSPOLL)) | 1032 | if (!(*new_flags & FIF_PSPOLL)) |
1034 | rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL; | 1033 | rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL; |
1035 | 1034 | ||
1036 | if (!(*new_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))) { | 1035 | if (!(*new_flags & FIF_OTHER_BSS)) { |
1037 | rx_filter |= CARL9170_RX_FILTER_OTHER_RA; | 1036 | rx_filter |= CARL9170_RX_FILTER_OTHER_RA; |
1038 | rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL; | 1037 | rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL; |
1039 | } | 1038 | } |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index b2f9521fe551..f40992969b4a 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -3131,8 +3131,6 @@ static void b43_adjust_opmode(struct b43_wldev *dev) | |||
3131 | ctl |= B43_MACCTL_KEEP_BAD; | 3131 | ctl |= B43_MACCTL_KEEP_BAD; |
3132 | if (wl->filter_flags & FIF_PLCPFAIL) | 3132 | if (wl->filter_flags & FIF_PLCPFAIL) |
3133 | ctl |= B43_MACCTL_KEEP_BADPLCP; | 3133 | ctl |= B43_MACCTL_KEEP_BADPLCP; |
3134 | if (wl->filter_flags & FIF_PROMISC_IN_BSS) | ||
3135 | ctl |= B43_MACCTL_PROMISC; | ||
3136 | if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC) | 3134 | if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC) |
3137 | ctl |= B43_MACCTL_BEACPROMISC; | 3135 | ctl |= B43_MACCTL_BEACPROMISC; |
3138 | 3136 | ||
@@ -4310,16 +4308,14 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw, | |||
4310 | goto out_unlock; | 4308 | goto out_unlock; |
4311 | } | 4309 | } |
4312 | 4310 | ||
4313 | *fflags &= FIF_PROMISC_IN_BSS | | 4311 | *fflags &= FIF_ALLMULTI | |
4314 | FIF_ALLMULTI | | ||
4315 | FIF_FCSFAIL | | 4312 | FIF_FCSFAIL | |
4316 | FIF_PLCPFAIL | | 4313 | FIF_PLCPFAIL | |
4317 | FIF_CONTROL | | 4314 | FIF_CONTROL | |
4318 | FIF_OTHER_BSS | | 4315 | FIF_OTHER_BSS | |
4319 | FIF_BCN_PRBRESP_PROMISC; | 4316 | FIF_BCN_PRBRESP_PROMISC; |
4320 | 4317 | ||
4321 | changed &= FIF_PROMISC_IN_BSS | | 4318 | changed &= FIF_ALLMULTI | |
4322 | FIF_ALLMULTI | | ||
4323 | FIF_FCSFAIL | | 4319 | FIF_FCSFAIL | |
4324 | FIF_PLCPFAIL | | 4320 | FIF_PLCPFAIL | |
4325 | FIF_CONTROL | | 4321 | FIF_CONTROL | |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index c77b7f59505c..39d49d6cd07f 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -2055,8 +2055,6 @@ static void b43legacy_adjust_opmode(struct b43legacy_wldev *dev) | |||
2055 | ctl |= B43legacy_MACCTL_KEEP_BAD; | 2055 | ctl |= B43legacy_MACCTL_KEEP_BAD; |
2056 | if (wl->filter_flags & FIF_PLCPFAIL) | 2056 | if (wl->filter_flags & FIF_PLCPFAIL) |
2057 | ctl |= B43legacy_MACCTL_KEEP_BADPLCP; | 2057 | ctl |= B43legacy_MACCTL_KEEP_BADPLCP; |
2058 | if (wl->filter_flags & FIF_PROMISC_IN_BSS) | ||
2059 | ctl |= B43legacy_MACCTL_PROMISC; | ||
2060 | if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC) | 2058 | if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC) |
2061 | ctl |= B43legacy_MACCTL_BEACPROMISC; | 2059 | ctl |= B43legacy_MACCTL_BEACPROMISC; |
2062 | 2060 | ||
@@ -2922,16 +2920,14 @@ static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, | |||
2922 | } | 2920 | } |
2923 | 2921 | ||
2924 | spin_lock_irqsave(&wl->irq_lock, flags); | 2922 | spin_lock_irqsave(&wl->irq_lock, flags); |
2925 | *fflags &= FIF_PROMISC_IN_BSS | | 2923 | *fflags &= FIF_ALLMULTI | |
2926 | FIF_ALLMULTI | | ||
2927 | FIF_FCSFAIL | | 2924 | FIF_FCSFAIL | |
2928 | FIF_PLCPFAIL | | 2925 | FIF_PLCPFAIL | |
2929 | FIF_CONTROL | | 2926 | FIF_CONTROL | |
2930 | FIF_OTHER_BSS | | 2927 | FIF_OTHER_BSS | |
2931 | FIF_BCN_PRBRESP_PROMISC; | 2928 | FIF_BCN_PRBRESP_PROMISC; |
2932 | 2929 | ||
2933 | changed &= FIF_PROMISC_IN_BSS | | 2930 | changed &= FIF_ALLMULTI | |
2934 | FIF_ALLMULTI | | ||
2935 | FIF_FCSFAIL | | 2931 | FIF_FCSFAIL | |
2936 | FIF_PLCPFAIL | | 2932 | FIF_PLCPFAIL | |
2937 | FIF_CONTROL | | 2933 | FIF_CONTROL | |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 48135063347e..b46cab250615 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -41,8 +41,7 @@ | |||
41 | #define BRCMS_FLUSH_TIMEOUT 500 /* msec */ | 41 | #define BRCMS_FLUSH_TIMEOUT 500 /* msec */ |
42 | 42 | ||
43 | /* Flags we support */ | 43 | /* Flags we support */ |
44 | #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ | 44 | #define MAC_FILTERS (FIF_ALLMULTI | \ |
45 | FIF_ALLMULTI | \ | ||
46 | FIF_FCSFAIL | \ | 45 | FIF_FCSFAIL | \ |
47 | FIF_CONTROL | \ | 46 | FIF_CONTROL | \ |
48 | FIF_OTHER_BSS | \ | 47 | FIF_OTHER_BSS | \ |
@@ -743,8 +742,6 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw, | |||
743 | changed_flags &= MAC_FILTERS; | 742 | changed_flags &= MAC_FILTERS; |
744 | *total_flags &= MAC_FILTERS; | 743 | *total_flags &= MAC_FILTERS; |
745 | 744 | ||
746 | if (changed_flags & FIF_PROMISC_IN_BSS) | ||
747 | brcms_dbg_info(core, "FIF_PROMISC_IN_BSS\n"); | ||
748 | if (changed_flags & FIF_ALLMULTI) | 745 | if (changed_flags & FIF_ALLMULTI) |
749 | brcms_dbg_info(core, "FIF_ALLMULTI\n"); | 746 | brcms_dbg_info(core, "FIF_ALLMULTI\n"); |
750 | if (changed_flags & FIF_FCSFAIL) | 747 | if (changed_flags & FIF_FCSFAIL) |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 369527e27689..9728be0e704b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -3571,7 +3571,7 @@ void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags) | |||
3571 | 3571 | ||
3572 | wlc->filter_flags = filter_flags; | 3572 | wlc->filter_flags = filter_flags; |
3573 | 3573 | ||
3574 | if (filter_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) | 3574 | if (filter_flags & FIF_OTHER_BSS) |
3575 | promisc_bits |= MCTL_PROMISC; | 3575 | promisc_bits |= MCTL_PROMISC; |
3576 | 3576 | ||
3577 | if (filter_flags & FIF_BCN_PRBRESP_PROMISC) | 3577 | if (filter_flags & FIF_BCN_PRBRESP_PROMISC) |
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c index b0f65fa09428..b86500b4418f 100644 --- a/drivers/net/wireless/cw1200/sta.c +++ b/drivers/net/wireless/cw1200/sta.c | |||
@@ -578,13 +578,11 @@ void cw1200_configure_filter(struct ieee80211_hw *dev, | |||
578 | { | 578 | { |
579 | struct cw1200_common *priv = dev->priv; | 579 | struct cw1200_common *priv = dev->priv; |
580 | bool listening = !!(*total_flags & | 580 | bool listening = !!(*total_flags & |
581 | (FIF_PROMISC_IN_BSS | | 581 | (FIF_OTHER_BSS | |
582 | FIF_OTHER_BSS | | ||
583 | FIF_BCN_PRBRESP_PROMISC | | 582 | FIF_BCN_PRBRESP_PROMISC | |
584 | FIF_PROBE_REQ)); | 583 | FIF_PROBE_REQ)); |
585 | 584 | ||
586 | *total_flags &= FIF_PROMISC_IN_BSS | | 585 | *total_flags &= FIF_OTHER_BSS | |
587 | FIF_OTHER_BSS | | ||
588 | FIF_FCSFAIL | | 586 | FIF_FCSFAIL | |
589 | FIF_BCN_PRBRESP_PROMISC | | 587 | FIF_BCN_PRBRESP_PROMISC | |
590 | FIF_PROBE_REQ; | 588 | FIF_PROBE_REQ; |
@@ -592,14 +590,12 @@ void cw1200_configure_filter(struct ieee80211_hw *dev, | |||
592 | down(&priv->scan.lock); | 590 | down(&priv->scan.lock); |
593 | mutex_lock(&priv->conf_mutex); | 591 | mutex_lock(&priv->conf_mutex); |
594 | 592 | ||
595 | priv->rx_filter.promiscuous = (*total_flags & FIF_PROMISC_IN_BSS) | 593 | priv->rx_filter.promiscuous = 0; |
596 | ? 1 : 0; | ||
597 | priv->rx_filter.bssid = (*total_flags & (FIF_OTHER_BSS | | 594 | priv->rx_filter.bssid = (*total_flags & (FIF_OTHER_BSS | |
598 | FIF_PROBE_REQ)) ? 1 : 0; | 595 | FIF_PROBE_REQ)) ? 1 : 0; |
599 | priv->rx_filter.fcs = (*total_flags & FIF_FCSFAIL) ? 1 : 0; | 596 | priv->rx_filter.fcs = (*total_flags & FIF_FCSFAIL) ? 1 : 0; |
600 | priv->disable_beacon_filter = !(*total_flags & | 597 | priv->disable_beacon_filter = !(*total_flags & |
601 | (FIF_BCN_PRBRESP_PROMISC | | 598 | (FIF_BCN_PRBRESP_PROMISC | |
602 | FIF_PROMISC_IN_BSS | | ||
603 | FIF_PROBE_REQ)); | 599 | FIF_PROBE_REQ)); |
604 | if (priv->listening != listening) { | 600 | if (priv->listening != listening) { |
605 | priv->listening = listening; | 601 | priv->listening = listening; |
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index e5665804d986..189cdf58084b 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c | |||
@@ -3048,7 +3048,7 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
3048 | D_MAC80211("Enter: changed: 0x%x, total: 0x%x\n", changed_flags, | 3048 | D_MAC80211("Enter: changed: 0x%x, total: 0x%x\n", changed_flags, |
3049 | *total_flags); | 3049 | *total_flags); |
3050 | 3050 | ||
3051 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | 3051 | CHK(FIF_OTHER_BSS, RXON_FILTER_PROMISC_MSK); |
3052 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); | 3052 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); |
3053 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | 3053 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); |
3054 | 3054 | ||
@@ -3074,7 +3074,7 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
3074 | * filters into the device. | 3074 | * filters into the device. |
3075 | */ | 3075 | */ |
3076 | *total_flags &= | 3076 | *total_flags &= |
3077 | FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | 3077 | FIF_OTHER_BSS | FIF_ALLMULTI | |
3078 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | 3078 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; |
3079 | } | 3079 | } |
3080 | 3080 | ||
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 976f65fe9c38..e4b175cbeefd 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
@@ -6166,7 +6166,7 @@ il4965_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
6166 | D_MAC80211("Enter: changed: 0x%x, total: 0x%x\n", changed_flags, | 6166 | D_MAC80211("Enter: changed: 0x%x, total: 0x%x\n", changed_flags, |
6167 | *total_flags); | 6167 | *total_flags); |
6168 | 6168 | ||
6169 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | 6169 | CHK(FIF_OTHER_BSS, RXON_FILTER_PROMISC_MSK); |
6170 | /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ | 6170 | /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ |
6171 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); | 6171 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); |
6172 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | 6172 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); |
@@ -6192,7 +6192,7 @@ il4965_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
6192 | * filters into the device. | 6192 | * filters into the device. |
6193 | */ | 6193 | */ |
6194 | *total_flags &= | 6194 | *total_flags &= |
6195 | FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | 6195 | FIF_OTHER_BSS | FIF_ALLMULTI | |
6196 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | 6196 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; |
6197 | } | 6197 | } |
6198 | 6198 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 5abd62ed8cb4..ba7fc42edf97 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -1061,7 +1061,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
1061 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | 1061 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", |
1062 | changed_flags, *total_flags); | 1062 | changed_flags, *total_flags); |
1063 | 1063 | ||
1064 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | 1064 | CHK(FIF_OTHER_BSS, RXON_FILTER_PROMISC_MSK); |
1065 | /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ | 1065 | /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ |
1066 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); | 1066 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); |
1067 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | 1067 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); |
@@ -1088,7 +1088,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
1088 | * since we currently do not support programming multicast | 1088 | * since we currently do not support programming multicast |
1089 | * filters into the device. | 1089 | * filters into the device. |
1090 | */ | 1090 | */ |
1091 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | 1091 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | |
1092 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | 1092 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; |
1093 | } | 1093 | } |
1094 | 1094 | ||
@@ -1140,7 +1140,6 @@ static void iwlagn_mac_event_callback(struct ieee80211_hw *hw, | |||
1140 | return; | 1140 | return; |
1141 | 1141 | ||
1142 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1142 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1143 | mutex_lock(&priv->mutex); | ||
1144 | 1143 | ||
1145 | if (priv->lib->bt_params && | 1144 | if (priv->lib->bt_params && |
1146 | priv->lib->bt_params->advanced_bt_coexist) { | 1145 | priv->lib->bt_params->advanced_bt_coexist) { |
@@ -1149,13 +1148,12 @@ static void iwlagn_mac_event_callback(struct ieee80211_hw *hw, | |||
1149 | else if (event->u.rssi.data == RSSI_EVENT_HIGH) | 1148 | else if (event->u.rssi.data == RSSI_EVENT_HIGH) |
1150 | priv->bt_enable_pspoll = false; | 1149 | priv->bt_enable_pspoll = false; |
1151 | 1150 | ||
1152 | iwlagn_send_advance_bt_config(priv); | 1151 | queue_work(priv->workqueue, &priv->bt_runtime_config); |
1153 | } else { | 1152 | } else { |
1154 | IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled," | 1153 | IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled," |
1155 | "ignoring RSSI callback\n"); | 1154 | "ignoring RSSI callback\n"); |
1156 | } | 1155 | } |
1157 | 1156 | ||
1158 | mutex_unlock(&priv->mutex); | ||
1159 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1157 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1160 | } | 1158 | } |
1161 | 1159 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 83903a5025c2..0b5a81d52a3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -248,7 +248,7 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, | |||
248 | */ | 248 | */ |
249 | if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) && | 249 | if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) && |
250 | (flags & IEEE80211_CHAN_NO_IR)) | 250 | (flags & IEEE80211_CHAN_NO_IR)) |
251 | flags |= IEEE80211_CHAN_GO_CONCURRENT; | 251 | flags |= IEEE80211_CHAN_IR_CONCURRENT; |
252 | 252 | ||
253 | return flags; | 253 | return flags; |
254 | } | 254 | } |
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index ed02e4bf2c26..1bdf18674fb8 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c | |||
@@ -439,7 +439,7 @@ static u64 lbtf_op_prepare_multicast(struct ieee80211_hw *hw, | |||
439 | return mc_count; | 439 | return mc_count; |
440 | } | 440 | } |
441 | 441 | ||
442 | #define SUPPORTED_FIF_FLAGS (FIF_PROMISC_IN_BSS | FIF_ALLMULTI) | 442 | #define SUPPORTED_FIF_FLAGS FIF_ALLMULTI |
443 | static void lbtf_op_configure_filter(struct ieee80211_hw *hw, | 443 | static void lbtf_op_configure_filter(struct ieee80211_hw *hw, |
444 | unsigned int changed_flags, | 444 | unsigned int changed_flags, |
445 | unsigned int *new_flags, | 445 | unsigned int *new_flags, |
@@ -458,10 +458,7 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw, | |||
458 | return; | 458 | return; |
459 | } | 459 | } |
460 | 460 | ||
461 | if (*new_flags & (FIF_PROMISC_IN_BSS)) | 461 | priv->mac_control &= ~CMD_ACT_MAC_PROMISCUOUS_ENABLE; |
462 | priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE; | ||
463 | else | ||
464 | priv->mac_control &= ~CMD_ACT_MAC_PROMISCUOUS_ENABLE; | ||
465 | if (*new_flags & (FIF_ALLMULTI) || | 462 | if (*new_flags & (FIF_ALLMULTI) || |
466 | multicast > MRVDRV_MAX_MULTICAST_LIST_SIZE) { | 463 | multicast > MRVDRV_MAX_MULTICAST_LIST_SIZE) { |
467 | priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE; | 464 | priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE; |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index d5c0a1af08b9..8d2f6bbf9598 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -1554,8 +1554,6 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, | |||
1554 | wiphy_debug(hw->wiphy, "%s\n", __func__); | 1554 | wiphy_debug(hw->wiphy, "%s\n", __func__); |
1555 | 1555 | ||
1556 | data->rx_filter = 0; | 1556 | data->rx_filter = 0; |
1557 | if (*total_flags & FIF_PROMISC_IN_BSS) | ||
1558 | data->rx_filter |= FIF_PROMISC_IN_BSS; | ||
1559 | if (*total_flags & FIF_ALLMULTI) | 1557 | if (*total_flags & FIF_ALLMULTI) |
1560 | data->rx_filter |= FIF_ALLMULTI; | 1558 | data->rx_filter |= FIF_ALLMULTI; |
1561 | 1559 | ||
@@ -2399,7 +2397,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, | |||
2399 | IEEE80211_HW_WANT_MONITOR_VIF | | 2397 | IEEE80211_HW_WANT_MONITOR_VIF | |
2400 | IEEE80211_HW_QUEUE_CONTROL | | 2398 | IEEE80211_HW_QUEUE_CONTROL | |
2401 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES | | 2399 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES | |
2402 | IEEE80211_HW_CHANCTX_STA_CSA; | 2400 | IEEE80211_HW_CHANCTX_STA_CSA | |
2401 | IEEE80211_HW_SUPPORT_FAST_XMIT; | ||
2403 | if (rctbl) | 2402 | if (rctbl) |
2404 | hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE; | 2403 | hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE; |
2405 | 2404 | ||
@@ -2438,6 +2437,31 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, | |||
2438 | sband->n_channels = ARRAY_SIZE(hwsim_channels_5ghz); | 2437 | sband->n_channels = ARRAY_SIZE(hwsim_channels_5ghz); |
2439 | sband->bitrates = data->rates + 4; | 2438 | sband->bitrates = data->rates + 4; |
2440 | sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4; | 2439 | sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4; |
2440 | |||
2441 | sband->vht_cap.vht_supported = true; | ||
2442 | sband->vht_cap.cap = | ||
2443 | IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | | ||
2444 | IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | | ||
2445 | IEEE80211_VHT_CAP_RXLDPC | | ||
2446 | IEEE80211_VHT_CAP_SHORT_GI_80 | | ||
2447 | IEEE80211_VHT_CAP_SHORT_GI_160 | | ||
2448 | IEEE80211_VHT_CAP_TXSTBC | | ||
2449 | IEEE80211_VHT_CAP_RXSTBC_1 | | ||
2450 | IEEE80211_VHT_CAP_RXSTBC_2 | | ||
2451 | IEEE80211_VHT_CAP_RXSTBC_3 | | ||
2452 | IEEE80211_VHT_CAP_RXSTBC_4 | | ||
2453 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; | ||
2454 | sband->vht_cap.vht_mcs.rx_mcs_map = | ||
2455 | cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | | ||
2456 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | | ||
2457 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | | ||
2458 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | | ||
2459 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | | ||
2460 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | | ||
2461 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | | ||
2462 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 14); | ||
2463 | sband->vht_cap.vht_mcs.tx_mcs_map = | ||
2464 | sband->vht_cap.vht_mcs.rx_mcs_map; | ||
2441 | break; | 2465 | break; |
2442 | default: | 2466 | default: |
2443 | continue; | 2467 | continue; |
@@ -2458,31 +2482,6 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, | |||
2458 | sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | 2482 | sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; |
2459 | 2483 | ||
2460 | hw->wiphy->bands[band] = sband; | 2484 | hw->wiphy->bands[band] = sband; |
2461 | |||
2462 | sband->vht_cap.vht_supported = true; | ||
2463 | sband->vht_cap.cap = | ||
2464 | IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | | ||
2465 | IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | | ||
2466 | IEEE80211_VHT_CAP_RXLDPC | | ||
2467 | IEEE80211_VHT_CAP_SHORT_GI_80 | | ||
2468 | IEEE80211_VHT_CAP_SHORT_GI_160 | | ||
2469 | IEEE80211_VHT_CAP_TXSTBC | | ||
2470 | IEEE80211_VHT_CAP_RXSTBC_1 | | ||
2471 | IEEE80211_VHT_CAP_RXSTBC_2 | | ||
2472 | IEEE80211_VHT_CAP_RXSTBC_3 | | ||
2473 | IEEE80211_VHT_CAP_RXSTBC_4 | | ||
2474 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; | ||
2475 | sband->vht_cap.vht_mcs.rx_mcs_map = | ||
2476 | cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 | | ||
2477 | IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 | | ||
2478 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | | ||
2479 | IEEE80211_VHT_MCS_SUPPORT_0_8 << 6 | | ||
2480 | IEEE80211_VHT_MCS_SUPPORT_0_8 << 8 | | ||
2481 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | | ||
2482 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | | ||
2483 | IEEE80211_VHT_MCS_SUPPORT_0_8 << 14); | ||
2484 | sband->vht_cap.vht_mcs.tx_mcs_map = | ||
2485 | sband->vht_cap.vht_mcs.rx_mcs_map; | ||
2486 | } | 2485 | } |
2487 | 2486 | ||
2488 | /* By default all radios belong to the first group */ | 2487 | /* By default all radios belong to the first group */ |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 95921167b53f..b71fc74d14ab 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -5192,7 +5192,7 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw, | |||
5192 | priv->sniffer_enabled = true; | 5192 | priv->sniffer_enabled = true; |
5193 | } | 5193 | } |
5194 | 5194 | ||
5195 | *total_flags &= FIF_PROMISC_IN_BSS | FIF_ALLMULTI | | 5195 | *total_flags &= FIF_ALLMULTI | |
5196 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL | | 5196 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL | |
5197 | FIF_OTHER_BSS; | 5197 | FIF_OTHER_BSS; |
5198 | 5198 | ||
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 275408eaf95e..257a9eadd595 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c | |||
@@ -351,8 +351,7 @@ int p54_setup_mac(struct p54_common *priv) | |||
351 | * "TRANSPARENT and PROMISCUOUS are mutually exclusive" | 351 | * "TRANSPARENT and PROMISCUOUS are mutually exclusive" |
352 | * STSW45X0C LMAC API - page 12 | 352 | * STSW45X0C LMAC API - page 12 |
353 | */ | 353 | */ |
354 | if (((priv->filter_flags & FIF_PROMISC_IN_BSS) || | 354 | if (priv->filter_flags & FIF_OTHER_BSS && |
355 | (priv->filter_flags & FIF_OTHER_BSS)) && | ||
356 | (mode != P54_FILTER_TYPE_PROMISCUOUS)) | 355 | (mode != P54_FILTER_TYPE_PROMISCUOUS)) |
357 | mode |= P54_FILTER_TYPE_TRANSPARENT; | 356 | mode |= P54_FILTER_TYPE_TRANSPARENT; |
358 | } else { | 357 | } else { |
diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c index 1f6fd5ff5531..9a8fedd3c0f5 100644 --- a/drivers/net/wireless/p54/led.c +++ b/drivers/net/wireless/p54/led.c | |||
@@ -83,7 +83,7 @@ static void p54_led_brightness_set(struct led_classdev *led_dev, | |||
83 | 83 | ||
84 | static int p54_register_led(struct p54_common *priv, | 84 | static int p54_register_led(struct p54_common *priv, |
85 | unsigned int led_index, | 85 | unsigned int led_index, |
86 | char *name, char *trigger) | 86 | char *name, const char *trigger) |
87 | { | 87 | { |
88 | struct p54_led_dev *led = &priv->leds[led_index]; | 88 | struct p54_led_dev *led = &priv->leds[led_index]; |
89 | int err; | 89 | int err; |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index e79674f73dc5..2947ad21053c 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -395,13 +395,11 @@ static void p54_configure_filter(struct ieee80211_hw *dev, | |||
395 | { | 395 | { |
396 | struct p54_common *priv = dev->priv; | 396 | struct p54_common *priv = dev->priv; |
397 | 397 | ||
398 | *total_flags &= FIF_PROMISC_IN_BSS | | 398 | *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS; |
399 | FIF_ALLMULTI | | ||
400 | FIF_OTHER_BSS; | ||
401 | 399 | ||
402 | priv->filter_flags = *total_flags; | 400 | priv->filter_flags = *total_flags; |
403 | 401 | ||
404 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) | 402 | if (changed_flags & FIF_OTHER_BSS) |
405 | p54_setup_mac(priv); | 403 | p54_setup_mac(priv); |
406 | 404 | ||
407 | if (changed_flags & FIF_ALLMULTI || multicast) | 405 | if (changed_flags & FIF_ALLMULTI || multicast) |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index bdf5590ba304..7da138892026 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -273,10 +273,8 @@ static void rt2400pci_config_filter(struct rt2x00_dev *rt2x00dev, | |||
273 | !(filter_flags & FIF_PLCPFAIL)); | 273 | !(filter_flags & FIF_PLCPFAIL)); |
274 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, | 274 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, |
275 | !(filter_flags & FIF_CONTROL)); | 275 | !(filter_flags & FIF_CONTROL)); |
276 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, | 276 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, 1); |
277 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
278 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, | 277 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, |
279 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
280 | !rt2x00dev->intf_ap_count); | 278 | !rt2x00dev->intf_ap_count); |
281 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | 279 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); |
282 | rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); | 280 | rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 79f4fe65a119..4ea53aa9ede3 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -274,10 +274,8 @@ static void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev, | |||
274 | !(filter_flags & FIF_PLCPFAIL)); | 274 | !(filter_flags & FIF_PLCPFAIL)); |
275 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, | 275 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, |
276 | !(filter_flags & FIF_CONTROL)); | 276 | !(filter_flags & FIF_CONTROL)); |
277 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, | 277 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, 1); |
278 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
279 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, | 278 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, |
280 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
281 | !rt2x00dev->intf_ap_count); | 279 | !rt2x00dev->intf_ap_count); |
282 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | 280 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); |
283 | rt2x00_set_field32(®, RXCSR0_DROP_MCAST, | 281 | rt2x00_set_field32(®, RXCSR0_DROP_MCAST, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 05c64597838d..237bbb54c7a8 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -434,10 +434,8 @@ static void rt2500usb_config_filter(struct rt2x00_dev *rt2x00dev, | |||
434 | !(filter_flags & FIF_PLCPFAIL)); | 434 | !(filter_flags & FIF_PLCPFAIL)); |
435 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, | 435 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, |
436 | !(filter_flags & FIF_CONTROL)); | 436 | !(filter_flags & FIF_CONTROL)); |
437 | rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, | 437 | rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, 1); |
438 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
439 | rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, | 438 | rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, |
440 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
441 | !rt2x00dev->intf_ap_count); | 439 | !rt2x00dev->intf_ap_count); |
442 | rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1); | 440 | rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1); |
443 | rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST, | 441 | rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST, |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index be2d54f257b1..dfeca8355b22 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1513,8 +1513,7 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, | |||
1513 | !(filter_flags & FIF_FCSFAIL)); | 1513 | !(filter_flags & FIF_FCSFAIL)); |
1514 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PHY_ERROR, | 1514 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PHY_ERROR, |
1515 | !(filter_flags & FIF_PLCPFAIL)); | 1515 | !(filter_flags & FIF_PLCPFAIL)); |
1516 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_TO_ME, | 1516 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_TO_ME, 1); |
1517 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
1518 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0); | 1517 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0); |
1519 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_VER_ERROR, 1); | 1518 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_VER_ERROR, 1); |
1520 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_MULTICAST, | 1519 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_MULTICAST, |
@@ -7818,21 +7817,25 @@ EXPORT_SYMBOL_GPL(rt2800_probe_hw); | |||
7818 | /* | 7817 | /* |
7819 | * IEEE80211 stack callback functions. | 7818 | * IEEE80211 stack callback functions. |
7820 | */ | 7819 | */ |
7821 | void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32, | 7820 | void rt2800_get_key_seq(struct ieee80211_hw *hw, |
7822 | u16 *iv16) | 7821 | struct ieee80211_key_conf *key, |
7822 | struct ieee80211_key_seq *seq) | ||
7823 | { | 7823 | { |
7824 | struct rt2x00_dev *rt2x00dev = hw->priv; | 7824 | struct rt2x00_dev *rt2x00dev = hw->priv; |
7825 | struct mac_iveiv_entry iveiv_entry; | 7825 | struct mac_iveiv_entry iveiv_entry; |
7826 | u32 offset; | 7826 | u32 offset; |
7827 | 7827 | ||
7828 | offset = MAC_IVEIV_ENTRY(hw_key_idx); | 7828 | if (key->cipher != WLAN_CIPHER_SUITE_TKIP) |
7829 | return; | ||
7830 | |||
7831 | offset = MAC_IVEIV_ENTRY(key->hw_key_idx); | ||
7829 | rt2800_register_multiread(rt2x00dev, offset, | 7832 | rt2800_register_multiread(rt2x00dev, offset, |
7830 | &iveiv_entry, sizeof(iveiv_entry)); | 7833 | &iveiv_entry, sizeof(iveiv_entry)); |
7831 | 7834 | ||
7832 | memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16)); | 7835 | memcpy(&seq->tkip.iv16, &iveiv_entry.iv[0], 2); |
7833 | memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32)); | 7836 | memcpy(&seq->tkip.iv32, &iveiv_entry.iv[4], 4); |
7834 | } | 7837 | } |
7835 | EXPORT_SYMBOL_GPL(rt2800_get_tkip_seq); | 7838 | EXPORT_SYMBOL_GPL(rt2800_get_key_seq); |
7836 | 7839 | ||
7837 | int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | 7840 | int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) |
7838 | { | 7841 | { |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 3019db637a4b..1609b8a7f7eb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h | |||
@@ -209,8 +209,9 @@ int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); | |||
209 | 209 | ||
210 | int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev); | 210 | int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev); |
211 | 211 | ||
212 | void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32, | 212 | void rt2800_get_key_seq(struct ieee80211_hw *hw, |
213 | u16 *iv16); | 213 | struct ieee80211_key_conf *key, |
214 | struct ieee80211_key_seq *seq); | ||
214 | int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value); | 215 | int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value); |
215 | int rt2800_conf_tx(struct ieee80211_hw *hw, | 216 | int rt2800_conf_tx(struct ieee80211_hw *hw, |
216 | struct ieee80211_vif *vif, u16 queue_idx, | 217 | struct ieee80211_vif *vif, u16 queue_idx, |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index cc1b3cc73c5a..0af22573a2eb 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -309,7 +309,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { | |||
309 | .sw_scan_start = rt2x00mac_sw_scan_start, | 309 | .sw_scan_start = rt2x00mac_sw_scan_start, |
310 | .sw_scan_complete = rt2x00mac_sw_scan_complete, | 310 | .sw_scan_complete = rt2x00mac_sw_scan_complete, |
311 | .get_stats = rt2x00mac_get_stats, | 311 | .get_stats = rt2x00mac_get_stats, |
312 | .get_tkip_seq = rt2800_get_tkip_seq, | 312 | .get_key_seq = rt2800_get_key_seq, |
313 | .set_rts_threshold = rt2800_set_rts_threshold, | 313 | .set_rts_threshold = rt2800_set_rts_threshold, |
314 | .sta_add = rt2x00mac_sta_add, | 314 | .sta_add = rt2x00mac_sta_add, |
315 | .sta_remove = rt2x00mac_sta_remove, | 315 | .sta_remove = rt2x00mac_sta_remove, |
diff --git a/drivers/net/wireless/rt2x00/rt2800soc.c b/drivers/net/wireless/rt2x00/rt2800soc.c index aaa7aa4cad9d..a985a5a7945e 100644 --- a/drivers/net/wireless/rt2x00/rt2800soc.c +++ b/drivers/net/wireless/rt2x00/rt2800soc.c | |||
@@ -148,7 +148,7 @@ static const struct ieee80211_ops rt2800soc_mac80211_ops = { | |||
148 | .sw_scan_start = rt2x00mac_sw_scan_start, | 148 | .sw_scan_start = rt2x00mac_sw_scan_start, |
149 | .sw_scan_complete = rt2x00mac_sw_scan_complete, | 149 | .sw_scan_complete = rt2x00mac_sw_scan_complete, |
150 | .get_stats = rt2x00mac_get_stats, | 150 | .get_stats = rt2x00mac_get_stats, |
151 | .get_tkip_seq = rt2800_get_tkip_seq, | 151 | .get_key_seq = rt2800_get_key_seq, |
152 | .set_rts_threshold = rt2800_set_rts_threshold, | 152 | .set_rts_threshold = rt2800_set_rts_threshold, |
153 | .sta_add = rt2x00mac_sta_add, | 153 | .sta_add = rt2x00mac_sta_add, |
154 | .sta_remove = rt2x00mac_sta_remove, | 154 | .sta_remove = rt2x00mac_sta_remove, |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6ec2466b52b6..5932306084fd 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -835,7 +835,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { | |||
835 | .sw_scan_start = rt2x00mac_sw_scan_start, | 835 | .sw_scan_start = rt2x00mac_sw_scan_start, |
836 | .sw_scan_complete = rt2x00mac_sw_scan_complete, | 836 | .sw_scan_complete = rt2x00mac_sw_scan_complete, |
837 | .get_stats = rt2x00mac_get_stats, | 837 | .get_stats = rt2x00mac_get_stats, |
838 | .get_tkip_seq = rt2800_get_tkip_seq, | 838 | .get_key_seq = rt2800_get_key_seq, |
839 | .set_rts_threshold = rt2800_set_rts_threshold, | 839 | .set_rts_threshold = rt2800_set_rts_threshold, |
840 | .sta_add = rt2x00mac_sta_add, | 840 | .sta_add = rt2x00mac_sta_add, |
841 | .sta_remove = rt2x00mac_sta_remove, | 841 | .sta_remove = rt2x00mac_sta_remove, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 300876df056f..1b8a459a412b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -359,8 +359,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
359 | FIF_PLCPFAIL | | 359 | FIF_PLCPFAIL | |
360 | FIF_CONTROL | | 360 | FIF_CONTROL | |
361 | FIF_PSPOLL | | 361 | FIF_PSPOLL | |
362 | FIF_OTHER_BSS | | 362 | FIF_OTHER_BSS; |
363 | FIF_PROMISC_IN_BSS; | ||
364 | 363 | ||
365 | /* | 364 | /* |
366 | * Apply some rules to the filters: | 365 | * Apply some rules to the filters: |
@@ -369,9 +368,6 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
369 | * - Multicast filter seems to kill broadcast traffic so never use it. | 368 | * - Multicast filter seems to kill broadcast traffic so never use it. |
370 | */ | 369 | */ |
371 | *total_flags |= FIF_ALLMULTI; | 370 | *total_flags |= FIF_ALLMULTI; |
372 | if (*total_flags & FIF_OTHER_BSS || | ||
373 | *total_flags & FIF_PROMISC_IN_BSS) | ||
374 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
375 | 371 | ||
376 | /* | 372 | /* |
377 | * If the device has a single filter for all control frames, | 373 | * If the device has a single filter for all control frames, |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 819455009fe4..c8a967247a9a 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -530,10 +530,8 @@ static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev, | |||
530 | !(filter_flags & FIF_PLCPFAIL)); | 530 | !(filter_flags & FIF_PLCPFAIL)); |
531 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, | 531 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, |
532 | !(filter_flags & (FIF_CONTROL | FIF_PSPOLL))); | 532 | !(filter_flags & (FIF_CONTROL | FIF_PSPOLL))); |
533 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | 533 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, 1); |
534 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
535 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | 534 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, |
536 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
537 | !rt2x00dev->intf_ap_count); | 535 | !rt2x00dev->intf_ap_count); |
538 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | 536 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); |
539 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | 537 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index a5458cf01fb2..65ce3afb888a 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -480,10 +480,8 @@ static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev, | |||
480 | !(filter_flags & FIF_PLCPFAIL)); | 480 | !(filter_flags & FIF_PLCPFAIL)); |
481 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, | 481 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, |
482 | !(filter_flags & (FIF_CONTROL | FIF_PSPOLL))); | 482 | !(filter_flags & (FIF_CONTROL | FIF_PSPOLL))); |
483 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | 483 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, 1); |
484 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
485 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | 484 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, |
486 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
487 | !rt2x00dev->intf_ap_count); | 485 | !rt2x00dev->intf_ap_count); |
488 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | 486 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); |
489 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | 487 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, |
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 82733c6b8c46..782ac2fc4b28 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h | |||
@@ -27,8 +27,7 @@ | |||
27 | #define __RTL_CORE_H__ | 27 | #define __RTL_CORE_H__ |
28 | 28 | ||
29 | #define RTL_SUPPORTED_FILTERS \ | 29 | #define RTL_SUPPORTED_FILTERS \ |
30 | (FIF_PROMISC_IN_BSS | \ | 30 | (FIF_ALLMULTI | FIF_CONTROL | \ |
31 | FIF_ALLMULTI | FIF_CONTROL | \ | ||
32 | FIF_OTHER_BSS | \ | 31 | FIF_OTHER_BSS | \ |
33 | FIF_FCSFAIL | \ | 32 | FIF_FCSFAIL | \ |
34 | FIF_BCN_PRBRESP_PROMISC) | 33 | FIF_BCN_PRBRESP_PROMISC) |
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index 5d54d16a59e7..f238ee54226c 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c | |||
@@ -763,8 +763,7 @@ static u64 wl1251_op_prepare_multicast(struct ieee80211_hw *hw, | |||
763 | return (u64)(unsigned long)fp; | 763 | return (u64)(unsigned long)fp; |
764 | } | 764 | } |
765 | 765 | ||
766 | #define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ | 766 | #define WL1251_SUPPORTED_FILTERS (FIF_ALLMULTI | \ |
767 | FIF_ALLMULTI | \ | ||
768 | FIF_FCSFAIL | \ | 767 | FIF_FCSFAIL | \ |
769 | FIF_BCN_PRBRESP_PROMISC | \ | 768 | FIF_BCN_PRBRESP_PROMISC | \ |
770 | FIF_CONTROL | \ | 769 | FIF_CONTROL | \ |
@@ -795,10 +794,6 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, | |||
795 | wl->rx_config = WL1251_DEFAULT_RX_CONFIG; | 794 | wl->rx_config = WL1251_DEFAULT_RX_CONFIG; |
796 | wl->rx_filter = WL1251_DEFAULT_RX_FILTER; | 795 | wl->rx_filter = WL1251_DEFAULT_RX_FILTER; |
797 | 796 | ||
798 | if (*total & FIF_PROMISC_IN_BSS) { | ||
799 | wl->rx_config |= CFG_BSSID_FILTER_EN; | ||
800 | wl->rx_config |= CFG_RX_ALL_GOOD; | ||
801 | } | ||
802 | if (*total & FIF_ALLMULTI) | 797 | if (*total & FIF_ALLMULTI) |
803 | /* | 798 | /* |
804 | * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive | 799 | * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive |
@@ -825,7 +820,7 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, | |||
825 | if (ret < 0) | 820 | if (ret < 0) |
826 | goto out; | 821 | goto out; |
827 | 822 | ||
828 | if (*total & FIF_ALLMULTI || *total & FIF_PROMISC_IN_BSS) | 823 | if (*total & FIF_ALLMULTI) |
829 | ret = wl1251_acx_group_address_tbl(wl, false, NULL, 0); | 824 | ret = wl1251_acx_group_address_tbl(wl, false, NULL, 0); |
830 | else if (fp) | 825 | else if (fp) |
831 | ret = wl1251_acx_group_address_tbl(wl, fp->enabled, | 826 | ret = wl1251_acx_group_address_tbl(wl, fp->enabled, |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 0be807951afe..7fe50f8182f3 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -3175,8 +3175,7 @@ static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, | |||
3175 | return (u64)(unsigned long)fp; | 3175 | return (u64)(unsigned long)fp; |
3176 | } | 3176 | } |
3177 | 3177 | ||
3178 | #define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ | 3178 | #define WL1271_SUPPORTED_FILTERS (FIF_ALLMULTI | \ |
3179 | FIF_ALLMULTI | \ | ||
3180 | FIF_FCSFAIL | \ | 3179 | FIF_FCSFAIL | \ |
3181 | FIF_BCN_PRBRESP_PROMISC | \ | 3180 | FIF_BCN_PRBRESP_PROMISC | \ |
3182 | FIF_CONTROL | \ | 3181 | FIF_CONTROL | \ |
@@ -6077,7 +6076,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) | |||
6077 | IEEE80211_HW_AMPDU_AGGREGATION | | 6076 | IEEE80211_HW_AMPDU_AGGREGATION | |
6078 | IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | | 6077 | IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | |
6079 | IEEE80211_HW_QUEUE_CONTROL | | 6078 | IEEE80211_HW_QUEUE_CONTROL | |
6080 | IEEE80211_HW_CHANCTX_STA_CSA; | 6079 | IEEE80211_HW_CHANCTX_STA_CSA | |
6080 | IEEE80211_HW_SUPPORT_FAST_XMIT; | ||
6081 | 6081 | ||
6082 | wl->hw->wiphy->cipher_suites = cipher_suites; | 6082 | wl->hw->wiphy->cipher_suites = cipher_suites; |
6083 | wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); | 6083 | wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index e7af261e9198..89b6f69f09c8 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -1230,7 +1230,7 @@ static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw, | |||
1230 | } | 1230 | } |
1231 | 1231 | ||
1232 | #define SUPPORTED_FIF_FLAGS \ | 1232 | #define SUPPORTED_FIF_FLAGS \ |
1233 | (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ | 1233 | (FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ |
1234 | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC) | 1234 | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC) |
1235 | static void zd_op_configure_filter(struct ieee80211_hw *hw, | 1235 | static void zd_op_configure_filter(struct ieee80211_hw *hw, |
1236 | unsigned int changed_flags, | 1236 | unsigned int changed_flags, |
@@ -1256,7 +1256,7 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw, | |||
1256 | * we will have some issue with IPv6 which uses multicast for link | 1256 | * we will have some issue with IPv6 which uses multicast for link |
1257 | * layer address resolution. | 1257 | * layer address resolution. |
1258 | */ | 1258 | */ |
1259 | if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) | 1259 | if (*new_flags & FIF_ALLMULTI) |
1260 | zd_mc_add_all(&hash); | 1260 | zd_mc_add_all(&hash); |
1261 | 1261 | ||
1262 | spin_lock_irqsave(&mac->lock, flags); | 1262 | spin_lock_irqsave(&mac->lock, flags); |
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 4bb4f8ee4132..6b2f813afb52 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c | |||
@@ -1516,21 +1516,12 @@ static void vnt_configure(struct ieee80211_hw *hw, | |||
1516 | struct vnt_private *priv = hw->priv; | 1516 | struct vnt_private *priv = hw->priv; |
1517 | u8 rx_mode = 0; | 1517 | u8 rx_mode = 0; |
1518 | 1518 | ||
1519 | *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_PROMISC_IN_BSS | | 1519 | *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC; |
1520 | FIF_BCN_PRBRESP_PROMISC; | ||
1521 | 1520 | ||
1522 | VNSvInPortB(priv->PortOffset + MAC_REG_RCR, &rx_mode); | 1521 | VNSvInPortB(priv->PortOffset + MAC_REG_RCR, &rx_mode); |
1523 | 1522 | ||
1524 | dev_dbg(&priv->pcid->dev, "rx mode in = %x\n", rx_mode); | 1523 | dev_dbg(&priv->pcid->dev, "rx mode in = %x\n", rx_mode); |
1525 | 1524 | ||
1526 | if (changed_flags & FIF_PROMISC_IN_BSS) { | ||
1527 | /* unconditionally log net taps */ | ||
1528 | if (*total_flags & FIF_PROMISC_IN_BSS) | ||
1529 | rx_mode |= RCR_UNICAST; | ||
1530 | else | ||
1531 | rx_mode &= ~RCR_UNICAST; | ||
1532 | } | ||
1533 | |||
1534 | if (changed_flags & FIF_ALLMULTI) { | 1525 | if (changed_flags & FIF_ALLMULTI) { |
1535 | if (*total_flags & FIF_ALLMULTI) { | 1526 | if (*total_flags & FIF_ALLMULTI) { |
1536 | unsigned long flags; | 1527 | unsigned long flags; |
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index ab3ab84cb0a7..0d97b6457ead 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c | |||
@@ -785,8 +785,7 @@ static void vnt_configure(struct ieee80211_hw *hw, | |||
785 | u8 rx_mode = 0; | 785 | u8 rx_mode = 0; |
786 | int rc; | 786 | int rc; |
787 | 787 | ||
788 | *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_PROMISC_IN_BSS | | 788 | *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC; |
789 | FIF_BCN_PRBRESP_PROMISC; | ||
790 | 789 | ||
791 | rc = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR, | 790 | rc = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR, |
792 | MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode); | 791 | MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode); |
@@ -796,14 +795,6 @@ static void vnt_configure(struct ieee80211_hw *hw, | |||
796 | 795 | ||
797 | dev_dbg(&priv->usb->dev, "rx mode in = %x\n", rx_mode); | 796 | dev_dbg(&priv->usb->dev, "rx mode in = %x\n", rx_mode); |
798 | 797 | ||
799 | if (changed_flags & FIF_PROMISC_IN_BSS) { | ||
800 | /* unconditionally log net taps */ | ||
801 | if (*total_flags & FIF_PROMISC_IN_BSS) | ||
802 | rx_mode |= RCR_UNICAST; | ||
803 | else | ||
804 | rx_mode &= ~RCR_UNICAST; | ||
805 | } | ||
806 | |||
807 | if (changed_flags & FIF_ALLMULTI) { | 798 | if (changed_flags & FIF_ALLMULTI) { |
808 | if (*total_flags & FIF_ALLMULTI) { | 799 | if (*total_flags & FIF_ALLMULTI) { |
809 | if (priv->mc_list_count > 2) | 800 | if (priv->mc_list_count > 2) |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f8d6813cd5b2..d63ecec73090 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -111,7 +111,7 @@ enum ieee80211_band { | |||
111 | * This may be due to the driver or due to regulatory bandwidth | 111 | * This may be due to the driver or due to regulatory bandwidth |
112 | * restrictions. | 112 | * restrictions. |
113 | * @IEEE80211_CHAN_INDOOR_ONLY: see %NL80211_FREQUENCY_ATTR_INDOOR_ONLY | 113 | * @IEEE80211_CHAN_INDOOR_ONLY: see %NL80211_FREQUENCY_ATTR_INDOOR_ONLY |
114 | * @IEEE80211_CHAN_GO_CONCURRENT: see %NL80211_FREQUENCY_ATTR_GO_CONCURRENT | 114 | * @IEEE80211_CHAN_IR_CONCURRENT: see %NL80211_FREQUENCY_ATTR_IR_CONCURRENT |
115 | * @IEEE80211_CHAN_NO_20MHZ: 20 MHz bandwidth is not permitted | 115 | * @IEEE80211_CHAN_NO_20MHZ: 20 MHz bandwidth is not permitted |
116 | * on this channel. | 116 | * on this channel. |
117 | * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted | 117 | * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted |
@@ -129,7 +129,7 @@ enum ieee80211_channel_flags { | |||
129 | IEEE80211_CHAN_NO_80MHZ = 1<<7, | 129 | IEEE80211_CHAN_NO_80MHZ = 1<<7, |
130 | IEEE80211_CHAN_NO_160MHZ = 1<<8, | 130 | IEEE80211_CHAN_NO_160MHZ = 1<<8, |
131 | IEEE80211_CHAN_INDOOR_ONLY = 1<<9, | 131 | IEEE80211_CHAN_INDOOR_ONLY = 1<<9, |
132 | IEEE80211_CHAN_GO_CONCURRENT = 1<<10, | 132 | IEEE80211_CHAN_IR_CONCURRENT = 1<<10, |
133 | IEEE80211_CHAN_NO_20MHZ = 1<<11, | 133 | IEEE80211_CHAN_NO_20MHZ = 1<<11, |
134 | IEEE80211_CHAN_NO_10MHZ = 1<<12, | 134 | IEEE80211_CHAN_NO_10MHZ = 1<<12, |
135 | }; | 135 | }; |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index b4bef1152c05..67e0df14ba0f 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -337,10 +337,16 @@ enum ieee80211_bss_change { | |||
337 | * enum ieee80211_event_type - event to be notified to the low level driver | 337 | * enum ieee80211_event_type - event to be notified to the low level driver |
338 | * @RSSI_EVENT: AP's rssi crossed the a threshold set by the driver. | 338 | * @RSSI_EVENT: AP's rssi crossed the a threshold set by the driver. |
339 | * @MLME_EVENT: event related to MLME | 339 | * @MLME_EVENT: event related to MLME |
340 | * @BAR_RX_EVENT: a BAR was received | ||
341 | * @BA_FRAME_TIMEOUT: Frames were released from the reordering buffer because | ||
342 | * they timed out. This won't be called for each frame released, but only | ||
343 | * once each time the timeout triggers. | ||
340 | */ | 344 | */ |
341 | enum ieee80211_event_type { | 345 | enum ieee80211_event_type { |
342 | RSSI_EVENT, | 346 | RSSI_EVENT, |
343 | MLME_EVENT, | 347 | MLME_EVENT, |
348 | BAR_RX_EVENT, | ||
349 | BA_FRAME_TIMEOUT, | ||
344 | }; | 350 | }; |
345 | 351 | ||
346 | /** | 352 | /** |
@@ -354,7 +360,7 @@ enum ieee80211_rssi_event_data { | |||
354 | }; | 360 | }; |
355 | 361 | ||
356 | /** | 362 | /** |
357 | * enum ieee80211_rssi_event - data attached to an %RSSI_EVENT | 363 | * struct ieee80211_rssi_event - data attached to an %RSSI_EVENT |
358 | * @data: See &enum ieee80211_rssi_event_data | 364 | * @data: See &enum ieee80211_rssi_event_data |
359 | */ | 365 | */ |
360 | struct ieee80211_rssi_event { | 366 | struct ieee80211_rssi_event { |
@@ -388,7 +394,7 @@ enum ieee80211_mlme_event_status { | |||
388 | }; | 394 | }; |
389 | 395 | ||
390 | /** | 396 | /** |
391 | * enum ieee80211_mlme_event - data attached to an %MLME_EVENT | 397 | * struct ieee80211_mlme_event - data attached to an %MLME_EVENT |
392 | * @data: See &enum ieee80211_mlme_event_data | 398 | * @data: See &enum ieee80211_mlme_event_data |
393 | * @status: See &enum ieee80211_mlme_event_status | 399 | * @status: See &enum ieee80211_mlme_event_status |
394 | * @reason: the reason code if applicable | 400 | * @reason: the reason code if applicable |
@@ -400,16 +406,31 @@ struct ieee80211_mlme_event { | |||
400 | }; | 406 | }; |
401 | 407 | ||
402 | /** | 408 | /** |
409 | * struct ieee80211_ba_event - data attached for BlockAck related events | ||
410 | * @sta: pointer to the &ieee80211_sta to which this event relates | ||
411 | * @tid: the tid | ||
412 | * @ssn: the starting sequence number (for %BAR_RX_EVENT) | ||
413 | */ | ||
414 | struct ieee80211_ba_event { | ||
415 | struct ieee80211_sta *sta; | ||
416 | u16 tid; | ||
417 | u16 ssn; | ||
418 | }; | ||
419 | |||
420 | /** | ||
403 | * struct ieee80211_event - event to be sent to the driver | 421 | * struct ieee80211_event - event to be sent to the driver |
404 | * @type The event itself. See &enum ieee80211_event_type. | 422 | * @type: The event itself. See &enum ieee80211_event_type. |
405 | * @rssi: relevant if &type is %RSSI_EVENT | 423 | * @rssi: relevant if &type is %RSSI_EVENT |
406 | * @mlme: relevant if &type is %AUTH_EVENT | 424 | * @mlme: relevant if &type is %AUTH_EVENT |
425 | * @ba: relevant if &type is %BAR_RX_EVENT or %BA_FRAME_TIMEOUT | ||
426 | * @u:union holding the fields above | ||
407 | */ | 427 | */ |
408 | struct ieee80211_event { | 428 | struct ieee80211_event { |
409 | enum ieee80211_event_type type; | 429 | enum ieee80211_event_type type; |
410 | union { | 430 | union { |
411 | struct ieee80211_rssi_event rssi; | 431 | struct ieee80211_rssi_event rssi; |
412 | struct ieee80211_mlme_event mlme; | 432 | struct ieee80211_mlme_event mlme; |
433 | struct ieee80211_ba_event ba; | ||
413 | } u; | 434 | } u; |
414 | }; | 435 | }; |
415 | 436 | ||
@@ -1480,6 +1501,47 @@ struct ieee80211_key_conf { | |||
1480 | u8 key[0]; | 1501 | u8 key[0]; |
1481 | }; | 1502 | }; |
1482 | 1503 | ||
1504 | #define IEEE80211_MAX_PN_LEN 16 | ||
1505 | |||
1506 | /** | ||
1507 | * struct ieee80211_key_seq - key sequence counter | ||
1508 | * | ||
1509 | * @tkip: TKIP data, containing IV32 and IV16 in host byte order | ||
1510 | * @ccmp: PN data, most significant byte first (big endian, | ||
1511 | * reverse order than in packet) | ||
1512 | * @aes_cmac: PN data, most significant byte first (big endian, | ||
1513 | * reverse order than in packet) | ||
1514 | * @aes_gmac: PN data, most significant byte first (big endian, | ||
1515 | * reverse order than in packet) | ||
1516 | * @gcmp: PN data, most significant byte first (big endian, | ||
1517 | * reverse order than in packet) | ||
1518 | * @hw: data for HW-only (e.g. cipher scheme) keys | ||
1519 | */ | ||
1520 | struct ieee80211_key_seq { | ||
1521 | union { | ||
1522 | struct { | ||
1523 | u32 iv32; | ||
1524 | u16 iv16; | ||
1525 | } tkip; | ||
1526 | struct { | ||
1527 | u8 pn[6]; | ||
1528 | } ccmp; | ||
1529 | struct { | ||
1530 | u8 pn[6]; | ||
1531 | } aes_cmac; | ||
1532 | struct { | ||
1533 | u8 pn[6]; | ||
1534 | } aes_gmac; | ||
1535 | struct { | ||
1536 | u8 pn[6]; | ||
1537 | } gcmp; | ||
1538 | struct { | ||
1539 | u8 seq[IEEE80211_MAX_PN_LEN]; | ||
1540 | u8 seq_len; | ||
1541 | } hw; | ||
1542 | }; | ||
1543 | }; | ||
1544 | |||
1483 | /** | 1545 | /** |
1484 | * struct ieee80211_cipher_scheme - cipher scheme | 1546 | * struct ieee80211_cipher_scheme - cipher scheme |
1485 | * | 1547 | * |
@@ -1795,6 +1857,10 @@ struct ieee80211_txq { | |||
1795 | * the driver returns 1. This also forces the driver to advertise its | 1857 | * the driver returns 1. This also forces the driver to advertise its |
1796 | * supported cipher suites. | 1858 | * supported cipher suites. |
1797 | * | 1859 | * |
1860 | * @IEEE80211_HW_SUPPORT_FAST_XMIT: The driver/hardware supports fast-xmit, | ||
1861 | * this currently requires only the ability to calculate the duration | ||
1862 | * for frames. | ||
1863 | * | ||
1798 | * @IEEE80211_HW_QUEUE_CONTROL: The driver wants to control per-interface | 1864 | * @IEEE80211_HW_QUEUE_CONTROL: The driver wants to control per-interface |
1799 | * queue mapping in order to use different queues (not just one per AC) | 1865 | * queue mapping in order to use different queues (not just one per AC) |
1800 | * for different virtual interfaces. See the doc section on HW queue | 1866 | * for different virtual interfaces. See the doc section on HW queue |
@@ -1843,7 +1909,7 @@ enum ieee80211_hw_flags { | |||
1843 | IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, | 1909 | IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, |
1844 | IEEE80211_HW_NO_AUTO_VIF = 1<<15, | 1910 | IEEE80211_HW_NO_AUTO_VIF = 1<<15, |
1845 | IEEE80211_HW_SW_CRYPTO_CONTROL = 1<<16, | 1911 | IEEE80211_HW_SW_CRYPTO_CONTROL = 1<<16, |
1846 | /* free slots */ | 1912 | IEEE80211_HW_SUPPORT_FAST_XMIT = 1<<17, |
1847 | IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, | 1913 | IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, |
1848 | IEEE80211_HW_CONNECTION_MONITOR = 1<<19, | 1914 | IEEE80211_HW_CONNECTION_MONITOR = 1<<19, |
1849 | IEEE80211_HW_QUEUE_CONTROL = 1<<20, | 1915 | IEEE80211_HW_QUEUE_CONTROL = 1<<20, |
@@ -1937,8 +2003,8 @@ enum ieee80211_hw_flags { | |||
1937 | * Use the %IEEE80211_RADIOTAP_VHT_KNOWN_* values. | 2003 | * Use the %IEEE80211_RADIOTAP_VHT_KNOWN_* values. |
1938 | * | 2004 | * |
1939 | * @netdev_features: netdev features to be set in each netdev created | 2005 | * @netdev_features: netdev features to be set in each netdev created |
1940 | * from this HW. Note only HW checksum features are currently | 2006 | * from this HW. Note that not all features are usable with mac80211, |
1941 | * compatible with mac80211. Other feature bits will be rejected. | 2007 | * other features will be rejected during HW registration. |
1942 | * | 2008 | * |
1943 | * @uapsd_queues: This bitmap is included in (re)association frame to indicate | 2009 | * @uapsd_queues: This bitmap is included in (re)association frame to indicate |
1944 | * for each access category if it is uAPSD trigger-enabled and delivery- | 2010 | * for each access category if it is uAPSD trigger-enabled and delivery- |
@@ -2502,10 +2568,6 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); | |||
2502 | * stack. It is always safe to pass more frames than requested, | 2568 | * stack. It is always safe to pass more frames than requested, |
2503 | * but this has negative impact on power consumption. | 2569 | * but this has negative impact on power consumption. |
2504 | * | 2570 | * |
2505 | * @FIF_PROMISC_IN_BSS: promiscuous mode within your BSS, | ||
2506 | * think of the BSS as your network segment and then this corresponds | ||
2507 | * to the regular ethernet device promiscuous mode. | ||
2508 | * | ||
2509 | * @FIF_ALLMULTI: pass all multicast frames, this is used if requested | 2571 | * @FIF_ALLMULTI: pass all multicast frames, this is used if requested |
2510 | * by the user or if the hardware is not capable of filtering by | 2572 | * by the user or if the hardware is not capable of filtering by |
2511 | * multicast address. | 2573 | * multicast address. |
@@ -2522,8 +2584,8 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); | |||
2522 | * mac80211 needs to do and the amount of CPU wakeups, so you should | 2584 | * mac80211 needs to do and the amount of CPU wakeups, so you should |
2523 | * honour this flag if possible. | 2585 | * honour this flag if possible. |
2524 | * | 2586 | * |
2525 | * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS | 2587 | * @FIF_CONTROL: pass control frames (except for PS Poll) addressed to this |
2526 | * is not set then only those addressed to this station. | 2588 | * station |
2527 | * | 2589 | * |
2528 | * @FIF_OTHER_BSS: pass frames destined to other BSSes | 2590 | * @FIF_OTHER_BSS: pass frames destined to other BSSes |
2529 | * | 2591 | * |
@@ -2533,7 +2595,6 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); | |||
2533 | * @FIF_PROBE_REQ: pass probe request frames | 2595 | * @FIF_PROBE_REQ: pass probe request frames |
2534 | */ | 2596 | */ |
2535 | enum ieee80211_filter_flags { | 2597 | enum ieee80211_filter_flags { |
2536 | FIF_PROMISC_IN_BSS = 1<<0, | ||
2537 | FIF_ALLMULTI = 1<<1, | 2598 | FIF_ALLMULTI = 1<<1, |
2538 | FIF_FCSFAIL = 1<<2, | 2599 | FIF_FCSFAIL = 1<<2, |
2539 | FIF_PLCPFAIL = 1<<3, | 2600 | FIF_PLCPFAIL = 1<<3, |
@@ -2816,9 +2877,9 @@ enum ieee80211_reconfig_type { | |||
2816 | * Returns zero if statistics are available. | 2877 | * Returns zero if statistics are available. |
2817 | * The callback can sleep. | 2878 | * The callback can sleep. |
2818 | * | 2879 | * |
2819 | * @get_tkip_seq: If your device implements TKIP encryption in hardware this | 2880 | * @get_key_seq: If your device implements encryption in hardware and does |
2820 | * callback should be provided to read the TKIP transmit IVs (both IV32 | 2881 | * IV/PN assignment then this callback should be provided to read the |
2821 | * and IV16) for the given key from hardware. | 2882 | * IV/PN for the given key from hardware. |
2822 | * The callback must be atomic. | 2883 | * The callback must be atomic. |
2823 | * | 2884 | * |
2824 | * @set_frag_threshold: Configuration of fragmentation threshold. Assign this | 2885 | * @set_frag_threshold: Configuration of fragmentation threshold. Assign this |
@@ -3001,7 +3062,7 @@ enum ieee80211_reconfig_type { | |||
3001 | * The callback can sleep. | 3062 | * The callback can sleep. |
3002 | * @event_callback: Notify driver about any event in mac80211. See | 3063 | * @event_callback: Notify driver about any event in mac80211. See |
3003 | * &enum ieee80211_event_type for the different types. | 3064 | * &enum ieee80211_event_type for the different types. |
3004 | * The callback can sleep. | 3065 | * The callback must be atomic. |
3005 | * | 3066 | * |
3006 | * @release_buffered_frames: Release buffered frames according to the given | 3067 | * @release_buffered_frames: Release buffered frames according to the given |
3007 | * parameters. In the case where the driver buffers some frames for | 3068 | * parameters. In the case where the driver buffers some frames for |
@@ -3217,8 +3278,9 @@ struct ieee80211_ops { | |||
3217 | struct ieee80211_vif *vif); | 3278 | struct ieee80211_vif *vif); |
3218 | int (*get_stats)(struct ieee80211_hw *hw, | 3279 | int (*get_stats)(struct ieee80211_hw *hw, |
3219 | struct ieee80211_low_level_stats *stats); | 3280 | struct ieee80211_low_level_stats *stats); |
3220 | void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx, | 3281 | void (*get_key_seq)(struct ieee80211_hw *hw, |
3221 | u32 *iv32, u16 *iv16); | 3282 | struct ieee80211_key_conf *key, |
3283 | struct ieee80211_key_seq *seq); | ||
3222 | int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value); | 3284 | int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value); |
3223 | int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value); | 3285 | int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value); |
3224 | int (*sta_add)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 3286 | int (*sta_add)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
@@ -3466,14 +3528,15 @@ enum ieee80211_tpt_led_trigger_flags { | |||
3466 | }; | 3528 | }; |
3467 | 3529 | ||
3468 | #ifdef CONFIG_MAC80211_LEDS | 3530 | #ifdef CONFIG_MAC80211_LEDS |
3469 | char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw); | 3531 | const char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw); |
3470 | char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw); | 3532 | const char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw); |
3471 | char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw); | 3533 | const char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw); |
3472 | char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw); | 3534 | const char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw); |
3473 | char *__ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, | 3535 | const char * |
3474 | unsigned int flags, | 3536 | __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, |
3475 | const struct ieee80211_tpt_blink *blink_table, | 3537 | unsigned int flags, |
3476 | unsigned int blink_table_len); | 3538 | const struct ieee80211_tpt_blink *blink_table, |
3539 | unsigned int blink_table_len); | ||
3477 | #endif | 3540 | #endif |
3478 | /** | 3541 | /** |
3479 | * ieee80211_get_tx_led_name - get name of TX LED | 3542 | * ieee80211_get_tx_led_name - get name of TX LED |
@@ -3487,7 +3550,7 @@ char *__ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, | |||
3487 | * | 3550 | * |
3488 | * Return: The name of the LED trigger. %NULL if not configured for LEDs. | 3551 | * Return: The name of the LED trigger. %NULL if not configured for LEDs. |
3489 | */ | 3552 | */ |
3490 | static inline char *ieee80211_get_tx_led_name(struct ieee80211_hw *hw) | 3553 | static inline const char *ieee80211_get_tx_led_name(struct ieee80211_hw *hw) |
3491 | { | 3554 | { |
3492 | #ifdef CONFIG_MAC80211_LEDS | 3555 | #ifdef CONFIG_MAC80211_LEDS |
3493 | return __ieee80211_get_tx_led_name(hw); | 3556 | return __ieee80211_get_tx_led_name(hw); |
@@ -3508,7 +3571,7 @@ static inline char *ieee80211_get_tx_led_name(struct ieee80211_hw *hw) | |||
3508 | * | 3571 | * |
3509 | * Return: The name of the LED trigger. %NULL if not configured for LEDs. | 3572 | * Return: The name of the LED trigger. %NULL if not configured for LEDs. |
3510 | */ | 3573 | */ |
3511 | static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw) | 3574 | static inline const char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw) |
3512 | { | 3575 | { |
3513 | #ifdef CONFIG_MAC80211_LEDS | 3576 | #ifdef CONFIG_MAC80211_LEDS |
3514 | return __ieee80211_get_rx_led_name(hw); | 3577 | return __ieee80211_get_rx_led_name(hw); |
@@ -3529,7 +3592,7 @@ static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw) | |||
3529 | * | 3592 | * |
3530 | * Return: The name of the LED trigger. %NULL if not configured for LEDs. | 3593 | * Return: The name of the LED trigger. %NULL if not configured for LEDs. |
3531 | */ | 3594 | */ |
3532 | static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) | 3595 | static inline const char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) |
3533 | { | 3596 | { |
3534 | #ifdef CONFIG_MAC80211_LEDS | 3597 | #ifdef CONFIG_MAC80211_LEDS |
3535 | return __ieee80211_get_assoc_led_name(hw); | 3598 | return __ieee80211_get_assoc_led_name(hw); |
@@ -3550,7 +3613,7 @@ static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) | |||
3550 | * | 3613 | * |
3551 | * Return: The name of the LED trigger. %NULL if not configured for LEDs. | 3614 | * Return: The name of the LED trigger. %NULL if not configured for LEDs. |
3552 | */ | 3615 | */ |
3553 | static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw) | 3616 | static inline const char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw) |
3554 | { | 3617 | { |
3555 | #ifdef CONFIG_MAC80211_LEDS | 3618 | #ifdef CONFIG_MAC80211_LEDS |
3556 | return __ieee80211_get_radio_led_name(hw); | 3619 | return __ieee80211_get_radio_led_name(hw); |
@@ -3571,7 +3634,7 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw) | |||
3571 | * | 3634 | * |
3572 | * Note: This function must be called before ieee80211_register_hw(). | 3635 | * Note: This function must be called before ieee80211_register_hw(). |
3573 | */ | 3636 | */ |
3574 | static inline char * | 3637 | static inline const char * |
3575 | ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags, | 3638 | ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags, |
3576 | const struct ieee80211_tpt_blink *blink_table, | 3639 | const struct ieee80211_tpt_blink *blink_table, |
3577 | unsigned int blink_table_len) | 3640 | unsigned int blink_table_len) |
@@ -4252,40 +4315,6 @@ void ieee80211_aes_cmac_calculate_k1_k2(struct ieee80211_key_conf *keyconf, | |||
4252 | u8 *k1, u8 *k2); | 4315 | u8 *k1, u8 *k2); |
4253 | 4316 | ||
4254 | /** | 4317 | /** |
4255 | * struct ieee80211_key_seq - key sequence counter | ||
4256 | * | ||
4257 | * @tkip: TKIP data, containing IV32 and IV16 in host byte order | ||
4258 | * @ccmp: PN data, most significant byte first (big endian, | ||
4259 | * reverse order than in packet) | ||
4260 | * @aes_cmac: PN data, most significant byte first (big endian, | ||
4261 | * reverse order than in packet) | ||
4262 | * @aes_gmac: PN data, most significant byte first (big endian, | ||
4263 | * reverse order than in packet) | ||
4264 | * @gcmp: PN data, most significant byte first (big endian, | ||
4265 | * reverse order than in packet) | ||
4266 | */ | ||
4267 | struct ieee80211_key_seq { | ||
4268 | union { | ||
4269 | struct { | ||
4270 | u32 iv32; | ||
4271 | u16 iv16; | ||
4272 | } tkip; | ||
4273 | struct { | ||
4274 | u8 pn[6]; | ||
4275 | } ccmp; | ||
4276 | struct { | ||
4277 | u8 pn[6]; | ||
4278 | } aes_cmac; | ||
4279 | struct { | ||
4280 | u8 pn[6]; | ||
4281 | } aes_gmac; | ||
4282 | struct { | ||
4283 | u8 pn[6]; | ||
4284 | } gcmp; | ||
4285 | }; | ||
4286 | }; | ||
4287 | |||
4288 | /** | ||
4289 | * ieee80211_get_key_tx_seq - get key TX sequence counter | 4318 | * ieee80211_get_key_tx_seq - get key TX sequence counter |
4290 | * | 4319 | * |
4291 | * @keyconf: the parameter passed with the set key | 4320 | * @keyconf: the parameter passed with the set key |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 241220c43e86..c0ab6b0a3919 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -2620,16 +2620,17 @@ enum nl80211_band_attr { | |||
2620 | * an indoor surroundings, i.e., it is connected to AC power (and not | 2620 | * an indoor surroundings, i.e., it is connected to AC power (and not |
2621 | * through portable DC inverters) or is under the control of a master | 2621 | * through portable DC inverters) or is under the control of a master |
2622 | * that is acting as an AP and is connected to AC power. | 2622 | * that is acting as an AP and is connected to AC power. |
2623 | * @NL80211_FREQUENCY_ATTR_GO_CONCURRENT: GO operation is allowed on this | 2623 | * @NL80211_FREQUENCY_ATTR_IR_CONCURRENT: IR operation is allowed on this |
2624 | * channel if it's connected concurrently to a BSS on the same channel on | 2624 | * channel if it's connected concurrently to a BSS on the same channel on |
2625 | * the 2 GHz band or to a channel in the same UNII band (on the 5 GHz | 2625 | * the 2 GHz band or to a channel in the same UNII band (on the 5 GHz |
2626 | * band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO on a | 2626 | * band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO or TDLS |
2627 | * channel that has the GO_CONCURRENT attribute set can be done when there | 2627 | * off-channel on a channel that has the IR_CONCURRENT attribute set can be |
2628 | * is a clear assessment that the device is operating under the guidance of | 2628 | * done when there is a clear assessment that the device is operating under |
2629 | * an authorized master, i.e., setting up a GO while the device is also | 2629 | * the guidance of an authorized master, i.e., setting up a GO or TDLS |
2630 | * connected to an AP with DFS and radar detection on the UNII band (it is | 2630 | * off-channel while the device is also connected to an AP with DFS and |
2631 | * up to user-space, i.e., wpa_supplicant to perform the required | 2631 | * radar detection on the UNII band (it is up to user-space, i.e., |
2632 | * verifications) | 2632 | * wpa_supplicant to perform the required verifications). Using this |
2633 | * attribute for IR is disallowed for master interfaces (IBSS, AP). | ||
2633 | * @NL80211_FREQUENCY_ATTR_NO_20MHZ: 20 MHz operation is not allowed | 2634 | * @NL80211_FREQUENCY_ATTR_NO_20MHZ: 20 MHz operation is not allowed |
2634 | * on this channel in current regulatory domain. | 2635 | * on this channel in current regulatory domain. |
2635 | * @NL80211_FREQUENCY_ATTR_NO_10MHZ: 10 MHz operation is not allowed | 2636 | * @NL80211_FREQUENCY_ATTR_NO_10MHZ: 10 MHz operation is not allowed |
@@ -2641,7 +2642,7 @@ enum nl80211_band_attr { | |||
2641 | * See https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122 | 2642 | * See https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122 |
2642 | * for more information on the FCC description of the relaxations allowed | 2643 | * for more information on the FCC description of the relaxations allowed |
2643 | * by NL80211_FREQUENCY_ATTR_INDOOR_ONLY and | 2644 | * by NL80211_FREQUENCY_ATTR_INDOOR_ONLY and |
2644 | * NL80211_FREQUENCY_ATTR_GO_CONCURRENT. | 2645 | * NL80211_FREQUENCY_ATTR_IR_CONCURRENT. |
2645 | */ | 2646 | */ |
2646 | enum nl80211_frequency_attr { | 2647 | enum nl80211_frequency_attr { |
2647 | __NL80211_FREQUENCY_ATTR_INVALID, | 2648 | __NL80211_FREQUENCY_ATTR_INVALID, |
@@ -2659,7 +2660,7 @@ enum nl80211_frequency_attr { | |||
2659 | NL80211_FREQUENCY_ATTR_NO_160MHZ, | 2660 | NL80211_FREQUENCY_ATTR_NO_160MHZ, |
2660 | NL80211_FREQUENCY_ATTR_DFS_CAC_TIME, | 2661 | NL80211_FREQUENCY_ATTR_DFS_CAC_TIME, |
2661 | NL80211_FREQUENCY_ATTR_INDOOR_ONLY, | 2662 | NL80211_FREQUENCY_ATTR_INDOOR_ONLY, |
2662 | NL80211_FREQUENCY_ATTR_GO_CONCURRENT, | 2663 | NL80211_FREQUENCY_ATTR_IR_CONCURRENT, |
2663 | NL80211_FREQUENCY_ATTR_NO_20MHZ, | 2664 | NL80211_FREQUENCY_ATTR_NO_20MHZ, |
2664 | NL80211_FREQUENCY_ATTR_NO_10MHZ, | 2665 | NL80211_FREQUENCY_ATTR_NO_10MHZ, |
2665 | 2666 | ||
@@ -2672,6 +2673,8 @@ enum nl80211_frequency_attr { | |||
2672 | #define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR | 2673 | #define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR |
2673 | #define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR | 2674 | #define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR |
2674 | #define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR | 2675 | #define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR |
2676 | #define NL80211_FREQUENCY_ATTR_GO_CONCURRENT \ | ||
2677 | NL80211_FREQUENCY_ATTR_IR_CONCURRENT | ||
2675 | 2678 | ||
2676 | /** | 2679 | /** |
2677 | * enum nl80211_bitrate_attr - bitrate attributes | 2680 | * enum nl80211_bitrate_attr - bitrate attributes |
@@ -2830,7 +2833,7 @@ enum nl80211_sched_scan_match_attr { | |||
2830 | * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated | 2833 | * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated |
2831 | * base on contiguous rules and wider channels will be allowed to cross | 2834 | * base on contiguous rules and wider channels will be allowed to cross |
2832 | * multiple contiguous/overlapping frequency ranges. | 2835 | * multiple contiguous/overlapping frequency ranges. |
2833 | * @NL80211_RRF_GO_CONCURRENT: See &NL80211_FREQUENCY_ATTR_GO_CONCURRENT | 2836 | * @NL80211_RRF_IR_CONCURRENT: See &NL80211_FREQUENCY_ATTR_IR_CONCURRENT |
2834 | * @NL80211_RRF_NO_HT40MINUS: channels can't be used in HT40- operation | 2837 | * @NL80211_RRF_NO_HT40MINUS: channels can't be used in HT40- operation |
2835 | * @NL80211_RRF_NO_HT40PLUS: channels can't be used in HT40+ operation | 2838 | * @NL80211_RRF_NO_HT40PLUS: channels can't be used in HT40+ operation |
2836 | * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed | 2839 | * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed |
@@ -2847,7 +2850,7 @@ enum nl80211_reg_rule_flags { | |||
2847 | NL80211_RRF_NO_IR = 1<<7, | 2850 | NL80211_RRF_NO_IR = 1<<7, |
2848 | __NL80211_RRF_NO_IBSS = 1<<8, | 2851 | __NL80211_RRF_NO_IBSS = 1<<8, |
2849 | NL80211_RRF_AUTO_BW = 1<<11, | 2852 | NL80211_RRF_AUTO_BW = 1<<11, |
2850 | NL80211_RRF_GO_CONCURRENT = 1<<12, | 2853 | NL80211_RRF_IR_CONCURRENT = 1<<12, |
2851 | NL80211_RRF_NO_HT40MINUS = 1<<13, | 2854 | NL80211_RRF_NO_HT40MINUS = 1<<13, |
2852 | NL80211_RRF_NO_HT40PLUS = 1<<14, | 2855 | NL80211_RRF_NO_HT40PLUS = 1<<14, |
2853 | NL80211_RRF_NO_80MHZ = 1<<15, | 2856 | NL80211_RRF_NO_80MHZ = 1<<15, |
@@ -2859,6 +2862,7 @@ enum nl80211_reg_rule_flags { | |||
2859 | #define NL80211_RRF_NO_IR NL80211_RRF_NO_IR | 2862 | #define NL80211_RRF_NO_IR NL80211_RRF_NO_IR |
2860 | #define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS |\ | 2863 | #define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS |\ |
2861 | NL80211_RRF_NO_HT40PLUS) | 2864 | NL80211_RRF_NO_HT40PLUS) |
2865 | #define NL80211_RRF_GO_CONCURRENT NL80211_RRF_IR_CONCURRENT | ||
2862 | 2866 | ||
2863 | /* For backport compatibility with older userspace */ | 2867 | /* For backport compatibility with older userspace */ |
2864 | #define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS) | 2868 | #define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS) |
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 64a012a0c6e5..086de496a4c1 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -302,6 +302,20 @@ config MAC80211_DEBUG_COUNTERS | |||
302 | ---help--- | 302 | ---help--- |
303 | Selecting this option causes mac80211 to keep additional | 303 | Selecting this option causes mac80211 to keep additional |
304 | and very verbose statistics about TX and RX handler use | 304 | and very verbose statistics about TX and RX handler use |
305 | and show them in debugfs. | 305 | as well as a few selected dot11 counters. These will be |
306 | exposed in debugfs. | ||
307 | |||
308 | Note that some of the counters are not concurrency safe | ||
309 | and may thus not always be accurate. | ||
306 | 310 | ||
307 | If unsure, say N. | 311 | If unsure, say N. |
312 | |||
313 | config MAC80211_STA_HASH_MAX_SIZE | ||
314 | int "Station hash table maximum size" if MAC80211_DEBUG_MENU | ||
315 | default 0 | ||
316 | ---help--- | ||
317 | Setting this option to a low value (e.g. 4) allows testing the | ||
318 | hash table with collisions relatively deterministically (just | ||
319 | connect more stations than the number selected here.) | ||
320 | |||
321 | If unsure, leave the default of 0. | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 265e42721a66..3469bbdc891c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -137,6 +137,9 @@ static int ieee80211_set_noack_map(struct wiphy *wiphy, | |||
137 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 137 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
138 | 138 | ||
139 | sdata->noack_map = noack_map; | 139 | sdata->noack_map = noack_map; |
140 | |||
141 | ieee80211_check_fast_xmit_iface(sdata); | ||
142 | |||
140 | return 0; | 143 | return 0; |
141 | } | 144 | } |
142 | 145 | ||
@@ -309,6 +312,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
309 | u32 iv32; | 312 | u32 iv32; |
310 | u16 iv16; | 313 | u16 iv16; |
311 | int err = -ENOENT; | 314 | int err = -ENOENT; |
315 | struct ieee80211_key_seq kseq = {}; | ||
312 | 316 | ||
313 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 317 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
314 | 318 | ||
@@ -339,10 +343,12 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
339 | iv32 = key->u.tkip.tx.iv32; | 343 | iv32 = key->u.tkip.tx.iv32; |
340 | iv16 = key->u.tkip.tx.iv16; | 344 | iv16 = key->u.tkip.tx.iv16; |
341 | 345 | ||
342 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 346 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
343 | drv_get_tkip_seq(sdata->local, | 347 | !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
344 | key->conf.hw_key_idx, | 348 | drv_get_key_seq(sdata->local, key, &kseq); |
345 | &iv32, &iv16); | 349 | iv32 = kseq.tkip.iv32; |
350 | iv16 = kseq.tkip.iv16; | ||
351 | } | ||
346 | 352 | ||
347 | seq[0] = iv16 & 0xff; | 353 | seq[0] = iv16 & 0xff; |
348 | seq[1] = (iv16 >> 8) & 0xff; | 354 | seq[1] = (iv16 >> 8) & 0xff; |
@@ -355,52 +361,85 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
355 | break; | 361 | break; |
356 | case WLAN_CIPHER_SUITE_CCMP: | 362 | case WLAN_CIPHER_SUITE_CCMP: |
357 | case WLAN_CIPHER_SUITE_CCMP_256: | 363 | case WLAN_CIPHER_SUITE_CCMP_256: |
358 | pn64 = atomic64_read(&key->u.ccmp.tx_pn); | 364 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
359 | seq[0] = pn64; | 365 | !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
360 | seq[1] = pn64 >> 8; | 366 | drv_get_key_seq(sdata->local, key, &kseq); |
361 | seq[2] = pn64 >> 16; | 367 | memcpy(seq, kseq.ccmp.pn, 6); |
362 | seq[3] = pn64 >> 24; | 368 | } else { |
363 | seq[4] = pn64 >> 32; | 369 | pn64 = atomic64_read(&key->u.ccmp.tx_pn); |
364 | seq[5] = pn64 >> 40; | 370 | seq[0] = pn64; |
371 | seq[1] = pn64 >> 8; | ||
372 | seq[2] = pn64 >> 16; | ||
373 | seq[3] = pn64 >> 24; | ||
374 | seq[4] = pn64 >> 32; | ||
375 | seq[5] = pn64 >> 40; | ||
376 | } | ||
365 | params.seq = seq; | 377 | params.seq = seq; |
366 | params.seq_len = 6; | 378 | params.seq_len = 6; |
367 | break; | 379 | break; |
368 | case WLAN_CIPHER_SUITE_AES_CMAC: | 380 | case WLAN_CIPHER_SUITE_AES_CMAC: |
369 | case WLAN_CIPHER_SUITE_BIP_CMAC_256: | 381 | case WLAN_CIPHER_SUITE_BIP_CMAC_256: |
370 | pn64 = atomic64_read(&key->u.aes_cmac.tx_pn); | 382 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
371 | seq[0] = pn64; | 383 | !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
372 | seq[1] = pn64 >> 8; | 384 | drv_get_key_seq(sdata->local, key, &kseq); |
373 | seq[2] = pn64 >> 16; | 385 | memcpy(seq, kseq.aes_cmac.pn, 6); |
374 | seq[3] = pn64 >> 24; | 386 | } else { |
375 | seq[4] = pn64 >> 32; | 387 | pn64 = atomic64_read(&key->u.aes_cmac.tx_pn); |
376 | seq[5] = pn64 >> 40; | 388 | seq[0] = pn64; |
389 | seq[1] = pn64 >> 8; | ||
390 | seq[2] = pn64 >> 16; | ||
391 | seq[3] = pn64 >> 24; | ||
392 | seq[4] = pn64 >> 32; | ||
393 | seq[5] = pn64 >> 40; | ||
394 | } | ||
377 | params.seq = seq; | 395 | params.seq = seq; |
378 | params.seq_len = 6; | 396 | params.seq_len = 6; |
379 | break; | 397 | break; |
380 | case WLAN_CIPHER_SUITE_BIP_GMAC_128: | 398 | case WLAN_CIPHER_SUITE_BIP_GMAC_128: |
381 | case WLAN_CIPHER_SUITE_BIP_GMAC_256: | 399 | case WLAN_CIPHER_SUITE_BIP_GMAC_256: |
382 | pn64 = atomic64_read(&key->u.aes_gmac.tx_pn); | 400 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
383 | seq[0] = pn64; | 401 | !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
384 | seq[1] = pn64 >> 8; | 402 | drv_get_key_seq(sdata->local, key, &kseq); |
385 | seq[2] = pn64 >> 16; | 403 | memcpy(seq, kseq.aes_gmac.pn, 6); |
386 | seq[3] = pn64 >> 24; | 404 | } else { |
387 | seq[4] = pn64 >> 32; | 405 | pn64 = atomic64_read(&key->u.aes_gmac.tx_pn); |
388 | seq[5] = pn64 >> 40; | 406 | seq[0] = pn64; |
407 | seq[1] = pn64 >> 8; | ||
408 | seq[2] = pn64 >> 16; | ||
409 | seq[3] = pn64 >> 24; | ||
410 | seq[4] = pn64 >> 32; | ||
411 | seq[5] = pn64 >> 40; | ||
412 | } | ||
389 | params.seq = seq; | 413 | params.seq = seq; |
390 | params.seq_len = 6; | 414 | params.seq_len = 6; |
391 | break; | 415 | break; |
392 | case WLAN_CIPHER_SUITE_GCMP: | 416 | case WLAN_CIPHER_SUITE_GCMP: |
393 | case WLAN_CIPHER_SUITE_GCMP_256: | 417 | case WLAN_CIPHER_SUITE_GCMP_256: |
394 | pn64 = atomic64_read(&key->u.gcmp.tx_pn); | 418 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
395 | seq[0] = pn64; | 419 | !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
396 | seq[1] = pn64 >> 8; | 420 | drv_get_key_seq(sdata->local, key, &kseq); |
397 | seq[2] = pn64 >> 16; | 421 | memcpy(seq, kseq.gcmp.pn, 6); |
398 | seq[3] = pn64 >> 24; | 422 | } else { |
399 | seq[4] = pn64 >> 32; | 423 | pn64 = atomic64_read(&key->u.gcmp.tx_pn); |
400 | seq[5] = pn64 >> 40; | 424 | seq[0] = pn64; |
425 | seq[1] = pn64 >> 8; | ||
426 | seq[2] = pn64 >> 16; | ||
427 | seq[3] = pn64 >> 24; | ||
428 | seq[4] = pn64 >> 32; | ||
429 | seq[5] = pn64 >> 40; | ||
430 | } | ||
401 | params.seq = seq; | 431 | params.seq = seq; |
402 | params.seq_len = 6; | 432 | params.seq_len = 6; |
403 | break; | 433 | break; |
434 | default: | ||
435 | if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | ||
436 | break; | ||
437 | if (WARN_ON(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) | ||
438 | break; | ||
439 | drv_get_key_seq(sdata->local, key, &kseq); | ||
440 | params.seq = kseq.hw.seq; | ||
441 | params.seq_len = kseq.hw.seq_len; | ||
442 | break; | ||
404 | } | 443 | } |
405 | 444 | ||
406 | params.key = key->conf.key; | 445 | params.key = key->conf.key; |
@@ -2099,10 +2138,14 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
2099 | int err; | 2138 | int err; |
2100 | 2139 | ||
2101 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { | 2140 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { |
2141 | ieee80211_check_fast_xmit_all(local); | ||
2142 | |||
2102 | err = drv_set_frag_threshold(local, wiphy->frag_threshold); | 2143 | err = drv_set_frag_threshold(local, wiphy->frag_threshold); |
2103 | 2144 | ||
2104 | if (err) | 2145 | if (err) { |
2146 | ieee80211_check_fast_xmit_all(local); | ||
2105 | return err; | 2147 | return err; |
2148 | } | ||
2106 | } | 2149 | } |
2107 | 2150 | ||
2108 | if ((changed & WIPHY_PARAM_COVERAGE_CLASS) || | 2151 | if ((changed & WIPHY_PARAM_COVERAGE_CLASS) || |
@@ -3336,8 +3379,14 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
3336 | break; | 3379 | break; |
3337 | case NL80211_IFTYPE_STATION: | 3380 | case NL80211_IFTYPE_STATION: |
3338 | case NL80211_IFTYPE_P2P_CLIENT: | 3381 | case NL80211_IFTYPE_P2P_CLIENT: |
3339 | if (!sdata->u.mgd.associated) | 3382 | sdata_lock(sdata); |
3383 | if (!sdata->u.mgd.associated || | ||
3384 | (params->offchan && params->wait && | ||
3385 | local->ops->remain_on_channel && | ||
3386 | memcmp(sdata->u.mgd.associated->bssid, | ||
3387 | mgmt->bssid, ETH_ALEN))) | ||
3340 | need_offchan = true; | 3388 | need_offchan = true; |
3389 | sdata_unlock(sdata); | ||
3341 | break; | 3390 | break; |
3342 | case NL80211_IFTYPE_P2P_DEVICE: | 3391 | case NL80211_IFTYPE_P2P_DEVICE: |
3343 | need_offchan = true; | 3392 | need_offchan = true; |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 5bcd4e5589d3..7e9b62475400 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -664,6 +664,8 @@ out: | |||
664 | ieee80211_bss_info_change_notify(sdata, | 664 | ieee80211_bss_info_change_notify(sdata, |
665 | BSS_CHANGED_IDLE); | 665 | BSS_CHANGED_IDLE); |
666 | 666 | ||
667 | ieee80211_check_fast_xmit_iface(sdata); | ||
668 | |||
667 | return ret; | 669 | return ret; |
668 | } | 670 | } |
669 | 671 | ||
@@ -1030,6 +1032,8 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata) | |||
1030 | if (sdata->vif.type == NL80211_IFTYPE_AP) | 1032 | if (sdata->vif.type == NL80211_IFTYPE_AP) |
1031 | __ieee80211_vif_copy_chanctx_to_vlans(sdata, false); | 1033 | __ieee80211_vif_copy_chanctx_to_vlans(sdata, false); |
1032 | 1034 | ||
1035 | ieee80211_check_fast_xmit_iface(sdata); | ||
1036 | |||
1033 | if (ieee80211_chanctx_refcount(local, old_ctx) == 0) | 1037 | if (ieee80211_chanctx_refcount(local, old_ctx) == 0) |
1034 | ieee80211_free_chanctx(local, old_ctx); | 1038 | ieee80211_free_chanctx(local, old_ctx); |
1035 | 1039 | ||
@@ -1376,6 +1380,8 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) | |||
1376 | __ieee80211_vif_copy_chanctx_to_vlans(sdata, | 1380 | __ieee80211_vif_copy_chanctx_to_vlans(sdata, |
1377 | false); | 1381 | false); |
1378 | 1382 | ||
1383 | ieee80211_check_fast_xmit_iface(sdata); | ||
1384 | |||
1379 | sdata->radar_required = sdata->reserved_radar_required; | 1385 | sdata->radar_required = sdata->reserved_radar_required; |
1380 | 1386 | ||
1381 | if (sdata->vif.bss_conf.chandef.width != | 1387 | if (sdata->vif.bss_conf.chandef.width != |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 23813ebb349c..b17206db49b4 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -219,8 +219,8 @@ static const struct file_operations stats_ ##name## _ops = { \ | |||
219 | .llseek = generic_file_llseek, \ | 219 | .llseek = generic_file_llseek, \ |
220 | }; | 220 | }; |
221 | 221 | ||
222 | #define DEBUGFS_STATS_ADD(name, field) \ | 222 | #define DEBUGFS_STATS_ADD(name) \ |
223 | debugfs_create_u32(#name, 0400, statsd, (u32 *) &field); | 223 | debugfs_create_u32(#name, 0400, statsd, &local->name); |
224 | #define DEBUGFS_DEVSTATS_ADD(name) \ | 224 | #define DEBUGFS_DEVSTATS_ADD(name) \ |
225 | debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops); | 225 | debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops); |
226 | 226 | ||
@@ -255,53 +255,31 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
255 | if (!statsd) | 255 | if (!statsd) |
256 | return; | 256 | return; |
257 | 257 | ||
258 | DEBUGFS_STATS_ADD(transmitted_fragment_count, | ||
259 | local->dot11TransmittedFragmentCount); | ||
260 | DEBUGFS_STATS_ADD(multicast_transmitted_frame_count, | ||
261 | local->dot11MulticastTransmittedFrameCount); | ||
262 | DEBUGFS_STATS_ADD(failed_count, local->dot11FailedCount); | ||
263 | DEBUGFS_STATS_ADD(retry_count, local->dot11RetryCount); | ||
264 | DEBUGFS_STATS_ADD(multiple_retry_count, | ||
265 | local->dot11MultipleRetryCount); | ||
266 | DEBUGFS_STATS_ADD(frame_duplicate_count, | ||
267 | local->dot11FrameDuplicateCount); | ||
268 | DEBUGFS_STATS_ADD(received_fragment_count, | ||
269 | local->dot11ReceivedFragmentCount); | ||
270 | DEBUGFS_STATS_ADD(multicast_received_frame_count, | ||
271 | local->dot11MulticastReceivedFrameCount); | ||
272 | DEBUGFS_STATS_ADD(transmitted_frame_count, | ||
273 | local->dot11TransmittedFrameCount); | ||
274 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 258 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
275 | DEBUGFS_STATS_ADD(tx_handlers_drop, local->tx_handlers_drop); | 259 | DEBUGFS_STATS_ADD(dot11TransmittedFragmentCount); |
276 | DEBUGFS_STATS_ADD(tx_handlers_queued, local->tx_handlers_queued); | 260 | DEBUGFS_STATS_ADD(dot11MulticastTransmittedFrameCount); |
277 | DEBUGFS_STATS_ADD(tx_handlers_drop_fragment, | 261 | DEBUGFS_STATS_ADD(dot11FailedCount); |
278 | local->tx_handlers_drop_fragment); | 262 | DEBUGFS_STATS_ADD(dot11RetryCount); |
279 | DEBUGFS_STATS_ADD(tx_handlers_drop_wep, | 263 | DEBUGFS_STATS_ADD(dot11MultipleRetryCount); |
280 | local->tx_handlers_drop_wep); | 264 | DEBUGFS_STATS_ADD(dot11FrameDuplicateCount); |
281 | DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc, | 265 | DEBUGFS_STATS_ADD(dot11ReceivedFragmentCount); |
282 | local->tx_handlers_drop_not_assoc); | 266 | DEBUGFS_STATS_ADD(dot11MulticastReceivedFrameCount); |
283 | DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port, | 267 | DEBUGFS_STATS_ADD(dot11TransmittedFrameCount); |
284 | local->tx_handlers_drop_unauth_port); | 268 | DEBUGFS_STATS_ADD(tx_handlers_drop); |
285 | DEBUGFS_STATS_ADD(rx_handlers_drop, local->rx_handlers_drop); | 269 | DEBUGFS_STATS_ADD(tx_handlers_queued); |
286 | DEBUGFS_STATS_ADD(rx_handlers_queued, local->rx_handlers_queued); | 270 | DEBUGFS_STATS_ADD(tx_handlers_drop_wep); |
287 | DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc, | 271 | DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc); |
288 | local->rx_handlers_drop_nullfunc); | 272 | DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port); |
289 | DEBUGFS_STATS_ADD(rx_handlers_drop_defrag, | 273 | DEBUGFS_STATS_ADD(rx_handlers_drop); |
290 | local->rx_handlers_drop_defrag); | 274 | DEBUGFS_STATS_ADD(rx_handlers_queued); |
291 | DEBUGFS_STATS_ADD(rx_handlers_drop_short, | 275 | DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc); |
292 | local->rx_handlers_drop_short); | 276 | DEBUGFS_STATS_ADD(rx_handlers_drop_defrag); |
293 | DEBUGFS_STATS_ADD(tx_expand_skb_head, | 277 | DEBUGFS_STATS_ADD(rx_handlers_drop_short); |
294 | local->tx_expand_skb_head); | 278 | DEBUGFS_STATS_ADD(tx_expand_skb_head); |
295 | DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned, | 279 | DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned); |
296 | local->tx_expand_skb_head_cloned); | 280 | DEBUGFS_STATS_ADD(rx_expand_skb_head_defrag); |
297 | DEBUGFS_STATS_ADD(rx_expand_skb_head, | 281 | DEBUGFS_STATS_ADD(rx_handlers_fragments); |
298 | local->rx_expand_skb_head); | 282 | DEBUGFS_STATS_ADD(tx_status_drop); |
299 | DEBUGFS_STATS_ADD(rx_expand_skb_head2, | ||
300 | local->rx_expand_skb_head2); | ||
301 | DEBUGFS_STATS_ADD(rx_handlers_fragments, | ||
302 | local->rx_handlers_fragments); | ||
303 | DEBUGFS_STATS_ADD(tx_status_drop, | ||
304 | local->tx_status_drop); | ||
305 | #endif | 283 | #endif |
306 | DEBUGFS_DEVSTATS_ADD(dot11ACKFailureCount); | 284 | DEBUGFS_DEVSTATS_ADD(dot11ACKFailureCount); |
307 | DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount); | 285 | DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount); |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 252859e90e8a..06d52935036d 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -29,8 +29,6 @@ static ssize_t sta_ ##name## _read(struct file *file, \ | |||
29 | format_string, sta->field); \ | 29 | format_string, sta->field); \ |
30 | } | 30 | } |
31 | #define STA_READ_D(name, field) STA_READ(name, field, "%d\n") | 31 | #define STA_READ_D(name, field) STA_READ(name, field, "%d\n") |
32 | #define STA_READ_U(name, field) STA_READ(name, field, "%u\n") | ||
33 | #define STA_READ_S(name, field) STA_READ(name, field, "%s\n") | ||
34 | 32 | ||
35 | #define STA_OPS(name) \ | 33 | #define STA_OPS(name) \ |
36 | static const struct file_operations sta_ ##name## _ops = { \ | 34 | static const struct file_operations sta_ ##name## _ops = { \ |
@@ -52,10 +50,7 @@ static const struct file_operations sta_ ##name## _ops = { \ | |||
52 | STA_OPS(name) | 50 | STA_OPS(name) |
53 | 51 | ||
54 | STA_FILE(aid, sta.aid, D); | 52 | STA_FILE(aid, sta.aid, D); |
55 | STA_FILE(dev, sdata->name, S); | ||
56 | STA_FILE(last_signal, last_signal, D); | ||
57 | STA_FILE(last_ack_signal, last_ack_signal, D); | 53 | STA_FILE(last_ack_signal, last_ack_signal, D); |
58 | STA_FILE(beacon_loss_count, beacon_loss_count, D); | ||
59 | 54 | ||
60 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | 55 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, |
61 | size_t count, loff_t *ppos) | 56 | size_t count, loff_t *ppos) |
@@ -101,40 +96,6 @@ static ssize_t sta_num_ps_buf_frames_read(struct file *file, | |||
101 | } | 96 | } |
102 | STA_OPS(num_ps_buf_frames); | 97 | STA_OPS(num_ps_buf_frames); |
103 | 98 | ||
104 | static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, | ||
105 | size_t count, loff_t *ppos) | ||
106 | { | ||
107 | struct sta_info *sta = file->private_data; | ||
108 | return mac80211_format_buffer(userbuf, count, ppos, "%d\n", | ||
109 | jiffies_to_msecs(jiffies - sta->last_rx)); | ||
110 | } | ||
111 | STA_OPS(inactive_ms); | ||
112 | |||
113 | |||
114 | static ssize_t sta_connected_time_read(struct file *file, char __user *userbuf, | ||
115 | size_t count, loff_t *ppos) | ||
116 | { | ||
117 | struct sta_info *sta = file->private_data; | ||
118 | struct timespec uptime; | ||
119 | struct tm result; | ||
120 | long connected_time_secs; | ||
121 | char buf[100]; | ||
122 | int res; | ||
123 | ktime_get_ts(&uptime); | ||
124 | connected_time_secs = uptime.tv_sec - sta->last_connected; | ||
125 | time_to_tm(connected_time_secs, 0, &result); | ||
126 | result.tm_year -= 70; | ||
127 | result.tm_mday -= 1; | ||
128 | res = scnprintf(buf, sizeof(buf), | ||
129 | "years - %ld\nmonths - %d\ndays - %d\nclock - %d:%d:%d\n\n", | ||
130 | result.tm_year, result.tm_mon, result.tm_mday, | ||
131 | result.tm_hour, result.tm_min, result.tm_sec); | ||
132 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | ||
133 | } | ||
134 | STA_OPS(connected_time); | ||
135 | |||
136 | |||
137 | |||
138 | static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, | 99 | static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, |
139 | size_t count, loff_t *ppos) | 100 | size_t count, loff_t *ppos) |
140 | { | 101 | { |
@@ -359,37 +320,6 @@ static ssize_t sta_vht_capa_read(struct file *file, char __user *userbuf, | |||
359 | } | 320 | } |
360 | STA_OPS(vht_capa); | 321 | STA_OPS(vht_capa); |
361 | 322 | ||
362 | static ssize_t sta_current_tx_rate_read(struct file *file, char __user *userbuf, | ||
363 | size_t count, loff_t *ppos) | ||
364 | { | ||
365 | struct sta_info *sta = file->private_data; | ||
366 | struct rate_info rinfo; | ||
367 | u16 rate; | ||
368 | sta_set_rate_info_tx(sta, &sta->last_tx_rate, &rinfo); | ||
369 | rate = cfg80211_calculate_bitrate(&rinfo); | ||
370 | |||
371 | return mac80211_format_buffer(userbuf, count, ppos, | ||
372 | "%d.%d MBit/s\n", | ||
373 | rate/10, rate%10); | ||
374 | } | ||
375 | STA_OPS(current_tx_rate); | ||
376 | |||
377 | static ssize_t sta_last_rx_rate_read(struct file *file, char __user *userbuf, | ||
378 | size_t count, loff_t *ppos) | ||
379 | { | ||
380 | struct sta_info *sta = file->private_data; | ||
381 | struct rate_info rinfo; | ||
382 | u16 rate; | ||
383 | |||
384 | sta_set_rate_info_rx(sta, &rinfo); | ||
385 | |||
386 | rate = cfg80211_calculate_bitrate(&rinfo); | ||
387 | |||
388 | return mac80211_format_buffer(userbuf, count, ppos, | ||
389 | "%d.%d MBit/s\n", | ||
390 | rate/10, rate%10); | ||
391 | } | ||
392 | STA_OPS(last_rx_rate); | ||
393 | 323 | ||
394 | #define DEBUGFS_ADD(name) \ | 324 | #define DEBUGFS_ADD(name) \ |
395 | debugfs_create_file(#name, 0400, \ | 325 | debugfs_create_file(#name, 0400, \ |
@@ -432,30 +362,15 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
432 | 362 | ||
433 | DEBUGFS_ADD(flags); | 363 | DEBUGFS_ADD(flags); |
434 | DEBUGFS_ADD(num_ps_buf_frames); | 364 | DEBUGFS_ADD(num_ps_buf_frames); |
435 | DEBUGFS_ADD(inactive_ms); | ||
436 | DEBUGFS_ADD(connected_time); | ||
437 | DEBUGFS_ADD(last_seq_ctrl); | 365 | DEBUGFS_ADD(last_seq_ctrl); |
438 | DEBUGFS_ADD(agg_status); | 366 | DEBUGFS_ADD(agg_status); |
439 | DEBUGFS_ADD(dev); | ||
440 | DEBUGFS_ADD(last_signal); | ||
441 | DEBUGFS_ADD(beacon_loss_count); | ||
442 | DEBUGFS_ADD(ht_capa); | 367 | DEBUGFS_ADD(ht_capa); |
443 | DEBUGFS_ADD(vht_capa); | 368 | DEBUGFS_ADD(vht_capa); |
444 | DEBUGFS_ADD(last_ack_signal); | 369 | DEBUGFS_ADD(last_ack_signal); |
445 | DEBUGFS_ADD(current_tx_rate); | ||
446 | DEBUGFS_ADD(last_rx_rate); | ||
447 | 370 | ||
448 | DEBUGFS_ADD_COUNTER(rx_packets, rx_packets); | ||
449 | DEBUGFS_ADD_COUNTER(tx_packets, tx_packets); | ||
450 | DEBUGFS_ADD_COUNTER(rx_bytes, rx_bytes); | ||
451 | DEBUGFS_ADD_COUNTER(tx_bytes, tx_bytes); | ||
452 | DEBUGFS_ADD_COUNTER(rx_duplicates, num_duplicates); | 371 | DEBUGFS_ADD_COUNTER(rx_duplicates, num_duplicates); |
453 | DEBUGFS_ADD_COUNTER(rx_fragments, rx_fragments); | 372 | DEBUGFS_ADD_COUNTER(rx_fragments, rx_fragments); |
454 | DEBUGFS_ADD_COUNTER(rx_dropped, rx_dropped); | ||
455 | DEBUGFS_ADD_COUNTER(tx_fragments, tx_fragments); | ||
456 | DEBUGFS_ADD_COUNTER(tx_filtered, tx_filtered_count); | 373 | DEBUGFS_ADD_COUNTER(tx_filtered, tx_filtered_count); |
457 | DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed); | ||
458 | DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count); | ||
459 | 374 | ||
460 | if (sizeof(sta->driver_buffered_tids) == sizeof(u32)) | 375 | if (sizeof(sta->driver_buffered_tids) == sizeof(u32)) |
461 | debugfs_create_x32("driver_buffered_tids", 0400, | 376 | debugfs_create_x32("driver_buffered_tids", 0400, |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 26e1ca8a474a..c01e681b90fb 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -417,12 +417,13 @@ static inline int drv_get_stats(struct ieee80211_local *local, | |||
417 | return ret; | 417 | return ret; |
418 | } | 418 | } |
419 | 419 | ||
420 | static inline void drv_get_tkip_seq(struct ieee80211_local *local, | 420 | static inline void drv_get_key_seq(struct ieee80211_local *local, |
421 | u8 hw_key_idx, u32 *iv32, u16 *iv16) | 421 | struct ieee80211_key *key, |
422 | struct ieee80211_key_seq *seq) | ||
422 | { | 423 | { |
423 | if (local->ops->get_tkip_seq) | 424 | if (local->ops->get_key_seq) |
424 | local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16); | 425 | local->ops->get_key_seq(&local->hw, &key->conf, seq); |
425 | trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16); | 426 | trace_drv_get_key_seq(local, &key->conf); |
426 | } | 427 | } |
427 | 428 | ||
428 | static inline int drv_set_frag_threshold(struct ieee80211_local *local, | 429 | static inline int drv_set_frag_threshold(struct ieee80211_local *local, |
diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c index 52bcea6ad9e8..188faab11c24 100644 --- a/net/mac80211/ethtool.c +++ b/net/mac80211/ethtool.c | |||
@@ -38,7 +38,7 @@ static void ieee80211_get_ringparam(struct net_device *dev, | |||
38 | static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = { | 38 | static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = { |
39 | "rx_packets", "rx_bytes", | 39 | "rx_packets", "rx_bytes", |
40 | "rx_duplicates", "rx_fragments", "rx_dropped", | 40 | "rx_duplicates", "rx_fragments", "rx_dropped", |
41 | "tx_packets", "tx_bytes", "tx_fragments", | 41 | "tx_packets", "tx_bytes", |
42 | "tx_filtered", "tx_retry_failed", "tx_retries", | 42 | "tx_filtered", "tx_retry_failed", "tx_retries", |
43 | "beacon_loss", "sta_state", "txrate", "rxrate", "signal", | 43 | "beacon_loss", "sta_state", "txrate", "rxrate", "signal", |
44 | "channel", "noise", "ch_time", "ch_time_busy", | 44 | "channel", "noise", "ch_time", "ch_time_busy", |
@@ -87,7 +87,6 @@ static void ieee80211_get_stats(struct net_device *dev, | |||
87 | \ | 87 | \ |
88 | data[i++] += sinfo.tx_packets; \ | 88 | data[i++] += sinfo.tx_packets; \ |
89 | data[i++] += sinfo.tx_bytes; \ | 89 | data[i++] += sinfo.tx_bytes; \ |
90 | data[i++] += sta->tx_fragments; \ | ||
91 | data[i++] += sta->tx_filtered_count; \ | 90 | data[i++] += sta->tx_filtered_count; \ |
92 | data[i++] += sta->tx_retry_failed; \ | 91 | data[i++] += sta->tx_retry_failed; \ |
93 | data[i++] += sta->tx_retry_count; \ | 92 | data[i++] += sta->tx_retry_count; \ |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ab46ab4a7249..241b74f3bd81 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -181,8 +181,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
181 | 181 | ||
182 | /** | 182 | /** |
183 | * enum ieee80211_packet_rx_flags - packet RX flags | 183 | * enum ieee80211_packet_rx_flags - packet RX flags |
184 | * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed | ||
185 | * (incl. multicast frames) | ||
186 | * @IEEE80211_RX_FRAGMENTED: fragmented frame | 184 | * @IEEE80211_RX_FRAGMENTED: fragmented frame |
187 | * @IEEE80211_RX_AMSDU: a-MSDU packet | 185 | * @IEEE80211_RX_AMSDU: a-MSDU packet |
188 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed | 186 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed |
@@ -192,7 +190,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
192 | * @rx_flags field of &struct ieee80211_rx_status. | 190 | * @rx_flags field of &struct ieee80211_rx_status. |
193 | */ | 191 | */ |
194 | enum ieee80211_packet_rx_flags { | 192 | enum ieee80211_packet_rx_flags { |
195 | IEEE80211_RX_RA_MATCH = BIT(1), | ||
196 | IEEE80211_RX_FRAGMENTED = BIT(2), | 193 | IEEE80211_RX_FRAGMENTED = BIT(2), |
197 | IEEE80211_RX_AMSDU = BIT(3), | 194 | IEEE80211_RX_AMSDU = BIT(3), |
198 | IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), | 195 | IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), |
@@ -725,7 +722,6 @@ struct ieee80211_if_mesh { | |||
725 | * enum ieee80211_sub_if_data_flags - virtual interface flags | 722 | * enum ieee80211_sub_if_data_flags - virtual interface flags |
726 | * | 723 | * |
727 | * @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets | 724 | * @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets |
728 | * @IEEE80211_SDATA_PROMISC: interface is promisc | ||
729 | * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode | 725 | * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode |
730 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between | 726 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between |
731 | * associated stations and deliver multicast frames both | 727 | * associated stations and deliver multicast frames both |
@@ -735,7 +731,6 @@ struct ieee80211_if_mesh { | |||
735 | */ | 731 | */ |
736 | enum ieee80211_sub_if_data_flags { | 732 | enum ieee80211_sub_if_data_flags { |
737 | IEEE80211_SDATA_ALLMULTI = BIT(0), | 733 | IEEE80211_SDATA_ALLMULTI = BIT(0), |
738 | IEEE80211_SDATA_PROMISC = BIT(1), | ||
739 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), | 734 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), |
740 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), | 735 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), |
741 | IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4), | 736 | IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4), |
@@ -1211,8 +1206,8 @@ struct ieee80211_local { | |||
1211 | 1206 | ||
1212 | atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES]; | 1207 | atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES]; |
1213 | 1208 | ||
1214 | /* number of interfaces with corresponding IFF_ flags */ | 1209 | /* number of interfaces with allmulti RX */ |
1215 | atomic_t iff_allmultis, iff_promiscs; | 1210 | atomic_t iff_allmultis; |
1216 | 1211 | ||
1217 | struct rate_control_ref *rate_ctrl; | 1212 | struct rate_control_ref *rate_ctrl; |
1218 | 1213 | ||
@@ -1264,6 +1259,15 @@ struct ieee80211_local { | |||
1264 | struct list_head chanctx_list; | 1259 | struct list_head chanctx_list; |
1265 | struct mutex chanctx_mtx; | 1260 | struct mutex chanctx_mtx; |
1266 | 1261 | ||
1262 | #ifdef CONFIG_MAC80211_LEDS | ||
1263 | struct led_trigger tx_led, rx_led, assoc_led, radio_led; | ||
1264 | struct led_trigger tpt_led; | ||
1265 | atomic_t tx_led_active, rx_led_active, assoc_led_active; | ||
1266 | atomic_t radio_led_active, tpt_led_active; | ||
1267 | struct tpt_led_trigger *tpt_led_trigger; | ||
1268 | #endif | ||
1269 | |||
1270 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
1267 | /* SNMP counters */ | 1271 | /* SNMP counters */ |
1268 | /* dot11CountersTable */ | 1272 | /* dot11CountersTable */ |
1269 | u32 dot11TransmittedFragmentCount; | 1273 | u32 dot11TransmittedFragmentCount; |
@@ -1276,18 +1280,9 @@ struct ieee80211_local { | |||
1276 | u32 dot11MulticastReceivedFrameCount; | 1280 | u32 dot11MulticastReceivedFrameCount; |
1277 | u32 dot11TransmittedFrameCount; | 1281 | u32 dot11TransmittedFrameCount; |
1278 | 1282 | ||
1279 | #ifdef CONFIG_MAC80211_LEDS | ||
1280 | struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led; | ||
1281 | struct tpt_led_trigger *tpt_led_trigger; | ||
1282 | char tx_led_name[32], rx_led_name[32], | ||
1283 | assoc_led_name[32], radio_led_name[32]; | ||
1284 | #endif | ||
1285 | |||
1286 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
1287 | /* TX/RX handler statistics */ | 1283 | /* TX/RX handler statistics */ |
1288 | unsigned int tx_handlers_drop; | 1284 | unsigned int tx_handlers_drop; |
1289 | unsigned int tx_handlers_queued; | 1285 | unsigned int tx_handlers_queued; |
1290 | unsigned int tx_handlers_drop_fragment; | ||
1291 | unsigned int tx_handlers_drop_wep; | 1286 | unsigned int tx_handlers_drop_wep; |
1292 | unsigned int tx_handlers_drop_not_assoc; | 1287 | unsigned int tx_handlers_drop_not_assoc; |
1293 | unsigned int tx_handlers_drop_unauth_port; | 1288 | unsigned int tx_handlers_drop_unauth_port; |
@@ -1298,8 +1293,7 @@ struct ieee80211_local { | |||
1298 | unsigned int rx_handlers_drop_short; | 1293 | unsigned int rx_handlers_drop_short; |
1299 | unsigned int tx_expand_skb_head; | 1294 | unsigned int tx_expand_skb_head; |
1300 | unsigned int tx_expand_skb_head_cloned; | 1295 | unsigned int tx_expand_skb_head_cloned; |
1301 | unsigned int rx_expand_skb_head; | 1296 | unsigned int rx_expand_skb_head_defrag; |
1302 | unsigned int rx_expand_skb_head2; | ||
1303 | unsigned int rx_handlers_fragments; | 1297 | unsigned int rx_handlers_fragments; |
1304 | unsigned int tx_status_drop; | 1298 | unsigned int tx_status_drop; |
1305 | #define I802_DEBUG_INC(c) (c)++ | 1299 | #define I802_DEBUG_INC(c) (c)++ |
@@ -1651,6 +1645,11 @@ struct sk_buff * | |||
1651 | ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata, | 1645 | ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata, |
1652 | struct sk_buff *skb, u32 info_flags); | 1646 | struct sk_buff *skb, u32 info_flags); |
1653 | 1647 | ||
1648 | void ieee80211_check_fast_xmit(struct sta_info *sta); | ||
1649 | void ieee80211_check_fast_xmit_all(struct ieee80211_local *local); | ||
1650 | void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata); | ||
1651 | void ieee80211_clear_fast_xmit(struct sta_info *sta); | ||
1652 | |||
1654 | /* HT */ | 1653 | /* HT */ |
1655 | void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, | 1654 | void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, |
1656 | struct ieee80211_sta_ht_cap *ht_cap); | 1655 | struct ieee80211_sta_ht_cap *ht_cap); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index b4ac596a7cb7..dc2d7133c4f6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -697,9 +697,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
697 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) | 697 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) |
698 | atomic_inc(&local->iff_allmultis); | 698 | atomic_inc(&local->iff_allmultis); |
699 | 699 | ||
700 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | ||
701 | atomic_inc(&local->iff_promiscs); | ||
702 | |||
703 | if (coming_up) | 700 | if (coming_up) |
704 | local->open_count++; | 701 | local->open_count++; |
705 | 702 | ||
@@ -827,13 +824,10 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
827 | WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || | 824 | WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || |
828 | (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)); | 825 | (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)); |
829 | 826 | ||
830 | /* don't count this interface for promisc/allmulti while it is down */ | 827 | /* don't count this interface for allmulti while it is down */ |
831 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) | 828 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) |
832 | atomic_dec(&local->iff_allmultis); | 829 | atomic_dec(&local->iff_allmultis); |
833 | 830 | ||
834 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | ||
835 | atomic_dec(&local->iff_promiscs); | ||
836 | |||
837 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 831 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
838 | local->fif_pspoll--; | 832 | local->fif_pspoll--; |
839 | local->fif_probe_req--; | 833 | local->fif_probe_req--; |
@@ -1047,12 +1041,10 @@ static void ieee80211_set_multicast_list(struct net_device *dev) | |||
1047 | { | 1041 | { |
1048 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1042 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1049 | struct ieee80211_local *local = sdata->local; | 1043 | struct ieee80211_local *local = sdata->local; |
1050 | int allmulti, promisc, sdata_allmulti, sdata_promisc; | 1044 | int allmulti, sdata_allmulti; |
1051 | 1045 | ||
1052 | allmulti = !!(dev->flags & IFF_ALLMULTI); | 1046 | allmulti = !!(dev->flags & IFF_ALLMULTI); |
1053 | promisc = !!(dev->flags & IFF_PROMISC); | ||
1054 | sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI); | 1047 | sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI); |
1055 | sdata_promisc = !!(sdata->flags & IEEE80211_SDATA_PROMISC); | ||
1056 | 1048 | ||
1057 | if (allmulti != sdata_allmulti) { | 1049 | if (allmulti != sdata_allmulti) { |
1058 | if (dev->flags & IFF_ALLMULTI) | 1050 | if (dev->flags & IFF_ALLMULTI) |
@@ -1062,13 +1054,6 @@ static void ieee80211_set_multicast_list(struct net_device *dev) | |||
1062 | sdata->flags ^= IEEE80211_SDATA_ALLMULTI; | 1054 | sdata->flags ^= IEEE80211_SDATA_ALLMULTI; |
1063 | } | 1055 | } |
1064 | 1056 | ||
1065 | if (promisc != sdata_promisc) { | ||
1066 | if (dev->flags & IFF_PROMISC) | ||
1067 | atomic_inc(&local->iff_promiscs); | ||
1068 | else | ||
1069 | atomic_dec(&local->iff_promiscs); | ||
1070 | sdata->flags ^= IEEE80211_SDATA_PROMISC; | ||
1071 | } | ||
1072 | spin_lock_bh(&local->filter_lock); | 1057 | spin_lock_bh(&local->filter_lock); |
1073 | __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); | 1058 | __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); |
1074 | spin_unlock_bh(&local->filter_lock); | 1059 | spin_unlock_bh(&local->filter_lock); |
@@ -1109,6 +1094,35 @@ static u16 ieee80211_netdev_select_queue(struct net_device *dev, | |||
1109 | return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); | 1094 | return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); |
1110 | } | 1095 | } |
1111 | 1096 | ||
1097 | static struct rtnl_link_stats64 * | ||
1098 | ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) | ||
1099 | { | ||
1100 | int i; | ||
1101 | |||
1102 | for_each_possible_cpu(i) { | ||
1103 | const struct pcpu_sw_netstats *tstats; | ||
1104 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; | ||
1105 | unsigned int start; | ||
1106 | |||
1107 | tstats = per_cpu_ptr(dev->tstats, i); | ||
1108 | |||
1109 | do { | ||
1110 | start = u64_stats_fetch_begin_irq(&tstats->syncp); | ||
1111 | rx_packets = tstats->rx_packets; | ||
1112 | tx_packets = tstats->tx_packets; | ||
1113 | rx_bytes = tstats->rx_bytes; | ||
1114 | tx_bytes = tstats->tx_bytes; | ||
1115 | } while (u64_stats_fetch_retry_irq(&tstats->syncp, start)); | ||
1116 | |||
1117 | stats->rx_packets += rx_packets; | ||
1118 | stats->tx_packets += tx_packets; | ||
1119 | stats->rx_bytes += rx_bytes; | ||
1120 | stats->tx_bytes += tx_bytes; | ||
1121 | } | ||
1122 | |||
1123 | return stats; | ||
1124 | } | ||
1125 | |||
1112 | static const struct net_device_ops ieee80211_dataif_ops = { | 1126 | static const struct net_device_ops ieee80211_dataif_ops = { |
1113 | .ndo_open = ieee80211_open, | 1127 | .ndo_open = ieee80211_open, |
1114 | .ndo_stop = ieee80211_stop, | 1128 | .ndo_stop = ieee80211_stop, |
@@ -1118,6 +1132,7 @@ static const struct net_device_ops ieee80211_dataif_ops = { | |||
1118 | .ndo_change_mtu = ieee80211_change_mtu, | 1132 | .ndo_change_mtu = ieee80211_change_mtu, |
1119 | .ndo_set_mac_address = ieee80211_change_mac, | 1133 | .ndo_set_mac_address = ieee80211_change_mac, |
1120 | .ndo_select_queue = ieee80211_netdev_select_queue, | 1134 | .ndo_select_queue = ieee80211_netdev_select_queue, |
1135 | .ndo_get_stats64 = ieee80211_get_stats64, | ||
1121 | }; | 1136 | }; |
1122 | 1137 | ||
1123 | static u16 ieee80211_monitor_select_queue(struct net_device *dev, | 1138 | static u16 ieee80211_monitor_select_queue(struct net_device *dev, |
@@ -1151,14 +1166,21 @@ static const struct net_device_ops ieee80211_monitorif_ops = { | |||
1151 | .ndo_change_mtu = ieee80211_change_mtu, | 1166 | .ndo_change_mtu = ieee80211_change_mtu, |
1152 | .ndo_set_mac_address = ieee80211_change_mac, | 1167 | .ndo_set_mac_address = ieee80211_change_mac, |
1153 | .ndo_select_queue = ieee80211_monitor_select_queue, | 1168 | .ndo_select_queue = ieee80211_monitor_select_queue, |
1169 | .ndo_get_stats64 = ieee80211_get_stats64, | ||
1154 | }; | 1170 | }; |
1155 | 1171 | ||
1172 | static void ieee80211_if_free(struct net_device *dev) | ||
1173 | { | ||
1174 | free_percpu(dev->tstats); | ||
1175 | free_netdev(dev); | ||
1176 | } | ||
1177 | |||
1156 | static void ieee80211_if_setup(struct net_device *dev) | 1178 | static void ieee80211_if_setup(struct net_device *dev) |
1157 | { | 1179 | { |
1158 | ether_setup(dev); | 1180 | ether_setup(dev); |
1159 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | 1181 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
1160 | dev->netdev_ops = &ieee80211_dataif_ops; | 1182 | dev->netdev_ops = &ieee80211_dataif_ops; |
1161 | dev->destructor = free_netdev; | 1183 | dev->destructor = ieee80211_if_free; |
1162 | } | 1184 | } |
1163 | 1185 | ||
1164 | static void ieee80211_iface_work(struct work_struct *work) | 1186 | static void ieee80211_iface_work(struct work_struct *work) |
@@ -1699,6 +1721,12 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1699 | return -ENOMEM; | 1721 | return -ENOMEM; |
1700 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); | 1722 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); |
1701 | 1723 | ||
1724 | ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); | ||
1725 | if (!ndev->tstats) { | ||
1726 | free_netdev(ndev); | ||
1727 | return -ENOMEM; | ||
1728 | } | ||
1729 | |||
1702 | ndev->needed_headroom = local->tx_headroom + | 1730 | ndev->needed_headroom = local->tx_headroom + |
1703 | 4*6 /* four MAC addresses */ | 1731 | 4*6 /* four MAC addresses */ |
1704 | + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ | 1732 | + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 2291cd730091..2e677376c958 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -229,6 +229,7 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, | |||
229 | 229 | ||
230 | if (uni) { | 230 | if (uni) { |
231 | rcu_assign_pointer(sdata->default_unicast_key, key); | 231 | rcu_assign_pointer(sdata->default_unicast_key, key); |
232 | ieee80211_check_fast_xmit_iface(sdata); | ||
232 | drv_set_default_unicast_key(sdata->local, sdata, idx); | 233 | drv_set_default_unicast_key(sdata->local, sdata, idx); |
233 | } | 234 | } |
234 | 235 | ||
@@ -298,6 +299,7 @@ static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, | |||
298 | if (pairwise) { | 299 | if (pairwise) { |
299 | rcu_assign_pointer(sta->ptk[idx], new); | 300 | rcu_assign_pointer(sta->ptk[idx], new); |
300 | sta->ptk_idx = idx; | 301 | sta->ptk_idx = idx; |
302 | ieee80211_check_fast_xmit(sta); | ||
301 | } else { | 303 | } else { |
302 | rcu_assign_pointer(sta->gtk[idx], new); | 304 | rcu_assign_pointer(sta->gtk[idx], new); |
303 | sta->gtk_idx = idx; | 305 | sta->gtk_idx = idx; |
@@ -483,15 +485,17 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | |||
483 | break; | 485 | break; |
484 | default: | 486 | default: |
485 | if (cs) { | 487 | if (cs) { |
486 | size_t len = (seq_len > MAX_PN_LEN) ? | 488 | if (seq_len && seq_len != cs->pn_len) { |
487 | MAX_PN_LEN : seq_len; | 489 | kfree(key); |
490 | return ERR_PTR(-EINVAL); | ||
491 | } | ||
488 | 492 | ||
489 | key->conf.iv_len = cs->hdr_len; | 493 | key->conf.iv_len = cs->hdr_len; |
490 | key->conf.icv_len = cs->mic_len; | 494 | key->conf.icv_len = cs->mic_len; |
491 | for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) | 495 | for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) |
492 | for (j = 0; j < len; j++) | 496 | for (j = 0; j < seq_len; j++) |
493 | key->u.gen.rx_pn[i][j] = | 497 | key->u.gen.rx_pn[i][j] = |
494 | seq[len - j - 1]; | 498 | seq[seq_len - j - 1]; |
495 | key->flags |= KEY_FLAG_CIPHER_SCHEME; | 499 | key->flags |= KEY_FLAG_CIPHER_SCHEME; |
496 | } | 500 | } |
497 | } | 501 | } |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index c5a31835be0e..df430a618764 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | #define NUM_DEFAULT_KEYS 4 | 19 | #define NUM_DEFAULT_KEYS 4 |
20 | #define NUM_DEFAULT_MGMT_KEYS 2 | 20 | #define NUM_DEFAULT_MGMT_KEYS 2 |
21 | #define MAX_PN_LEN 16 | ||
22 | 21 | ||
23 | struct ieee80211_local; | 22 | struct ieee80211_local; |
24 | struct ieee80211_sub_if_data; | 23 | struct ieee80211_sub_if_data; |
@@ -116,7 +115,7 @@ struct ieee80211_key { | |||
116 | } gcmp; | 115 | } gcmp; |
117 | struct { | 116 | struct { |
118 | /* generic cipher scheme */ | 117 | /* generic cipher scheme */ |
119 | u8 rx_pn[IEEE80211_NUM_TIDS + 1][MAX_PN_LEN]; | 118 | u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_MAX_PN_LEN]; |
120 | } gen; | 119 | } gen; |
121 | } u; | 120 | } u; |
122 | 121 | ||
diff --git a/net/mac80211/led.c b/net/mac80211/led.c index e2b836446af3..38f05565eaac 100644 --- a/net/mac80211/led.c +++ b/net/mac80211/led.c | |||
@@ -12,96 +12,175 @@ | |||
12 | #include <linux/export.h> | 12 | #include <linux/export.h> |
13 | #include "led.h" | 13 | #include "led.h" |
14 | 14 | ||
15 | #define MAC80211_BLINK_DELAY 50 /* ms */ | ||
16 | |||
17 | void ieee80211_led_rx(struct ieee80211_local *local) | ||
18 | { | ||
19 | unsigned long led_delay = MAC80211_BLINK_DELAY; | ||
20 | if (unlikely(!local->rx_led)) | ||
21 | return; | ||
22 | led_trigger_blink_oneshot(local->rx_led, &led_delay, &led_delay, 0); | ||
23 | } | ||
24 | |||
25 | void ieee80211_led_tx(struct ieee80211_local *local) | ||
26 | { | ||
27 | unsigned long led_delay = MAC80211_BLINK_DELAY; | ||
28 | if (unlikely(!local->tx_led)) | ||
29 | return; | ||
30 | led_trigger_blink_oneshot(local->tx_led, &led_delay, &led_delay, 0); | ||
31 | } | ||
32 | |||
33 | void ieee80211_led_assoc(struct ieee80211_local *local, bool associated) | 15 | void ieee80211_led_assoc(struct ieee80211_local *local, bool associated) |
34 | { | 16 | { |
35 | if (unlikely(!local->assoc_led)) | 17 | if (!atomic_read(&local->assoc_led_active)) |
36 | return; | 18 | return; |
37 | if (associated) | 19 | if (associated) |
38 | led_trigger_event(local->assoc_led, LED_FULL); | 20 | led_trigger_event(&local->assoc_led, LED_FULL); |
39 | else | 21 | else |
40 | led_trigger_event(local->assoc_led, LED_OFF); | 22 | led_trigger_event(&local->assoc_led, LED_OFF); |
41 | } | 23 | } |
42 | 24 | ||
43 | void ieee80211_led_radio(struct ieee80211_local *local, bool enabled) | 25 | void ieee80211_led_radio(struct ieee80211_local *local, bool enabled) |
44 | { | 26 | { |
45 | if (unlikely(!local->radio_led)) | 27 | if (!atomic_read(&local->radio_led_active)) |
46 | return; | 28 | return; |
47 | if (enabled) | 29 | if (enabled) |
48 | led_trigger_event(local->radio_led, LED_FULL); | 30 | led_trigger_event(&local->radio_led, LED_FULL); |
49 | else | 31 | else |
50 | led_trigger_event(local->radio_led, LED_OFF); | 32 | led_trigger_event(&local->radio_led, LED_OFF); |
33 | } | ||
34 | |||
35 | void ieee80211_alloc_led_names(struct ieee80211_local *local) | ||
36 | { | ||
37 | local->rx_led.name = kasprintf(GFP_KERNEL, "%srx", | ||
38 | wiphy_name(local->hw.wiphy)); | ||
39 | local->tx_led.name = kasprintf(GFP_KERNEL, "%stx", | ||
40 | wiphy_name(local->hw.wiphy)); | ||
41 | local->assoc_led.name = kasprintf(GFP_KERNEL, "%sassoc", | ||
42 | wiphy_name(local->hw.wiphy)); | ||
43 | local->radio_led.name = kasprintf(GFP_KERNEL, "%sradio", | ||
44 | wiphy_name(local->hw.wiphy)); | ||
45 | } | ||
46 | |||
47 | void ieee80211_free_led_names(struct ieee80211_local *local) | ||
48 | { | ||
49 | kfree(local->rx_led.name); | ||
50 | kfree(local->tx_led.name); | ||
51 | kfree(local->assoc_led.name); | ||
52 | kfree(local->radio_led.name); | ||
53 | } | ||
54 | |||
55 | static void ieee80211_tx_led_activate(struct led_classdev *led_cdev) | ||
56 | { | ||
57 | struct ieee80211_local *local = container_of(led_cdev->trigger, | ||
58 | struct ieee80211_local, | ||
59 | tx_led); | ||
60 | |||
61 | atomic_inc(&local->tx_led_active); | ||
62 | } | ||
63 | |||
64 | static void ieee80211_tx_led_deactivate(struct led_classdev *led_cdev) | ||
65 | { | ||
66 | struct ieee80211_local *local = container_of(led_cdev->trigger, | ||
67 | struct ieee80211_local, | ||
68 | tx_led); | ||
69 | |||
70 | atomic_dec(&local->tx_led_active); | ||
71 | } | ||
72 | |||
73 | static void ieee80211_rx_led_activate(struct led_classdev *led_cdev) | ||
74 | { | ||
75 | struct ieee80211_local *local = container_of(led_cdev->trigger, | ||
76 | struct ieee80211_local, | ||
77 | rx_led); | ||
78 | |||
79 | atomic_inc(&local->rx_led_active); | ||
80 | } | ||
81 | |||
82 | static void ieee80211_rx_led_deactivate(struct led_classdev *led_cdev) | ||
83 | { | ||
84 | struct ieee80211_local *local = container_of(led_cdev->trigger, | ||
85 | struct ieee80211_local, | ||
86 | rx_led); | ||
87 | |||
88 | atomic_dec(&local->rx_led_active); | ||
89 | } | ||
90 | |||
91 | static void ieee80211_assoc_led_activate(struct led_classdev *led_cdev) | ||
92 | { | ||
93 | struct ieee80211_local *local = container_of(led_cdev->trigger, | ||
94 | struct ieee80211_local, | ||
95 | assoc_led); | ||
96 | |||
97 | atomic_inc(&local->assoc_led_active); | ||
98 | } | ||
99 | |||
100 | static void ieee80211_assoc_led_deactivate(struct led_classdev *led_cdev) | ||
101 | { | ||
102 | struct ieee80211_local *local = container_of(led_cdev->trigger, | ||
103 | struct ieee80211_local, | ||
104 | assoc_led); | ||
105 | |||
106 | atomic_dec(&local->assoc_led_active); | ||
107 | } | ||
108 | |||
109 | static void ieee80211_radio_led_activate(struct led_classdev *led_cdev) | ||
110 | { | ||
111 | struct ieee80211_local *local = container_of(led_cdev->trigger, | ||
112 | struct ieee80211_local, | ||
113 | radio_led); | ||
114 | |||
115 | atomic_inc(&local->radio_led_active); | ||
116 | } | ||
117 | |||
118 | static void ieee80211_radio_led_deactivate(struct led_classdev *led_cdev) | ||
119 | { | ||
120 | struct ieee80211_local *local = container_of(led_cdev->trigger, | ||
121 | struct ieee80211_local, | ||
122 | radio_led); | ||
123 | |||
124 | atomic_dec(&local->radio_led_active); | ||
125 | } | ||
126 | |||
127 | static void ieee80211_tpt_led_activate(struct led_classdev *led_cdev) | ||
128 | { | ||
129 | struct ieee80211_local *local = container_of(led_cdev->trigger, | ||
130 | struct ieee80211_local, | ||
131 | tpt_led); | ||
132 | |||
133 | atomic_inc(&local->tpt_led_active); | ||
51 | } | 134 | } |
52 | 135 | ||
53 | void ieee80211_led_names(struct ieee80211_local *local) | 136 | static void ieee80211_tpt_led_deactivate(struct led_classdev *led_cdev) |
54 | { | 137 | { |
55 | snprintf(local->rx_led_name, sizeof(local->rx_led_name), | 138 | struct ieee80211_local *local = container_of(led_cdev->trigger, |
56 | "%srx", wiphy_name(local->hw.wiphy)); | 139 | struct ieee80211_local, |
57 | snprintf(local->tx_led_name, sizeof(local->tx_led_name), | 140 | tpt_led); |
58 | "%stx", wiphy_name(local->hw.wiphy)); | 141 | |
59 | snprintf(local->assoc_led_name, sizeof(local->assoc_led_name), | 142 | atomic_dec(&local->tpt_led_active); |
60 | "%sassoc", wiphy_name(local->hw.wiphy)); | ||
61 | snprintf(local->radio_led_name, sizeof(local->radio_led_name), | ||
62 | "%sradio", wiphy_name(local->hw.wiphy)); | ||
63 | } | 143 | } |
64 | 144 | ||
65 | void ieee80211_led_init(struct ieee80211_local *local) | 145 | void ieee80211_led_init(struct ieee80211_local *local) |
66 | { | 146 | { |
67 | local->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); | 147 | atomic_set(&local->rx_led_active, 0); |
68 | if (local->rx_led) { | 148 | local->rx_led.activate = ieee80211_rx_led_activate; |
69 | local->rx_led->name = local->rx_led_name; | 149 | local->rx_led.deactivate = ieee80211_rx_led_deactivate; |
70 | if (led_trigger_register(local->rx_led)) { | 150 | if (local->rx_led.name && led_trigger_register(&local->rx_led)) { |
71 | kfree(local->rx_led); | 151 | kfree(local->rx_led.name); |
72 | local->rx_led = NULL; | 152 | local->rx_led.name = NULL; |
73 | } | ||
74 | } | 153 | } |
75 | 154 | ||
76 | local->tx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); | 155 | atomic_set(&local->tx_led_active, 0); |
77 | if (local->tx_led) { | 156 | local->tx_led.activate = ieee80211_tx_led_activate; |
78 | local->tx_led->name = local->tx_led_name; | 157 | local->tx_led.deactivate = ieee80211_tx_led_deactivate; |
79 | if (led_trigger_register(local->tx_led)) { | 158 | if (local->tx_led.name && led_trigger_register(&local->tx_led)) { |
80 | kfree(local->tx_led); | 159 | kfree(local->tx_led.name); |
81 | local->tx_led = NULL; | 160 | local->tx_led.name = NULL; |
82 | } | ||
83 | } | 161 | } |
84 | 162 | ||
85 | local->assoc_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); | 163 | atomic_set(&local->assoc_led_active, 0); |
86 | if (local->assoc_led) { | 164 | local->assoc_led.activate = ieee80211_assoc_led_activate; |
87 | local->assoc_led->name = local->assoc_led_name; | 165 | local->assoc_led.deactivate = ieee80211_assoc_led_deactivate; |
88 | if (led_trigger_register(local->assoc_led)) { | 166 | if (local->assoc_led.name && led_trigger_register(&local->assoc_led)) { |
89 | kfree(local->assoc_led); | 167 | kfree(local->assoc_led.name); |
90 | local->assoc_led = NULL; | 168 | local->assoc_led.name = NULL; |
91 | } | ||
92 | } | 169 | } |
93 | 170 | ||
94 | local->radio_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); | 171 | atomic_set(&local->radio_led_active, 0); |
95 | if (local->radio_led) { | 172 | local->radio_led.activate = ieee80211_radio_led_activate; |
96 | local->radio_led->name = local->radio_led_name; | 173 | local->radio_led.deactivate = ieee80211_radio_led_deactivate; |
97 | if (led_trigger_register(local->radio_led)) { | 174 | if (local->radio_led.name && led_trigger_register(&local->radio_led)) { |
98 | kfree(local->radio_led); | 175 | kfree(local->radio_led.name); |
99 | local->radio_led = NULL; | 176 | local->radio_led.name = NULL; |
100 | } | ||
101 | } | 177 | } |
102 | 178 | ||
179 | atomic_set(&local->tpt_led_active, 0); | ||
103 | if (local->tpt_led_trigger) { | 180 | if (local->tpt_led_trigger) { |
104 | if (led_trigger_register(&local->tpt_led_trigger->trig)) { | 181 | local->tpt_led.activate = ieee80211_tpt_led_activate; |
182 | local->tpt_led.deactivate = ieee80211_tpt_led_deactivate; | ||
183 | if (led_trigger_register(&local->tpt_led)) { | ||
105 | kfree(local->tpt_led_trigger); | 184 | kfree(local->tpt_led_trigger); |
106 | local->tpt_led_trigger = NULL; | 185 | local->tpt_led_trigger = NULL; |
107 | } | 186 | } |
@@ -110,58 +189,50 @@ void ieee80211_led_init(struct ieee80211_local *local) | |||
110 | 189 | ||
111 | void ieee80211_led_exit(struct ieee80211_local *local) | 190 | void ieee80211_led_exit(struct ieee80211_local *local) |
112 | { | 191 | { |
113 | if (local->radio_led) { | 192 | if (local->radio_led.name) |
114 | led_trigger_unregister(local->radio_led); | 193 | led_trigger_unregister(&local->radio_led); |
115 | kfree(local->radio_led); | 194 | if (local->assoc_led.name) |
116 | } | 195 | led_trigger_unregister(&local->assoc_led); |
117 | if (local->assoc_led) { | 196 | if (local->tx_led.name) |
118 | led_trigger_unregister(local->assoc_led); | 197 | led_trigger_unregister(&local->tx_led); |
119 | kfree(local->assoc_led); | 198 | if (local->rx_led.name) |
120 | } | 199 | led_trigger_unregister(&local->rx_led); |
121 | if (local->tx_led) { | ||
122 | led_trigger_unregister(local->tx_led); | ||
123 | kfree(local->tx_led); | ||
124 | } | ||
125 | if (local->rx_led) { | ||
126 | led_trigger_unregister(local->rx_led); | ||
127 | kfree(local->rx_led); | ||
128 | } | ||
129 | 200 | ||
130 | if (local->tpt_led_trigger) { | 201 | if (local->tpt_led_trigger) { |
131 | led_trigger_unregister(&local->tpt_led_trigger->trig); | 202 | led_trigger_unregister(&local->tpt_led); |
132 | kfree(local->tpt_led_trigger); | 203 | kfree(local->tpt_led_trigger); |
133 | } | 204 | } |
134 | } | 205 | } |
135 | 206 | ||
136 | char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw) | 207 | const char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw) |
137 | { | 208 | { |
138 | struct ieee80211_local *local = hw_to_local(hw); | 209 | struct ieee80211_local *local = hw_to_local(hw); |
139 | 210 | ||
140 | return local->radio_led_name; | 211 | return local->radio_led.name; |
141 | } | 212 | } |
142 | EXPORT_SYMBOL(__ieee80211_get_radio_led_name); | 213 | EXPORT_SYMBOL(__ieee80211_get_radio_led_name); |
143 | 214 | ||
144 | char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) | 215 | const char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) |
145 | { | 216 | { |
146 | struct ieee80211_local *local = hw_to_local(hw); | 217 | struct ieee80211_local *local = hw_to_local(hw); |
147 | 218 | ||
148 | return local->assoc_led_name; | 219 | return local->assoc_led.name; |
149 | } | 220 | } |
150 | EXPORT_SYMBOL(__ieee80211_get_assoc_led_name); | 221 | EXPORT_SYMBOL(__ieee80211_get_assoc_led_name); |
151 | 222 | ||
152 | char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw) | 223 | const char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw) |
153 | { | 224 | { |
154 | struct ieee80211_local *local = hw_to_local(hw); | 225 | struct ieee80211_local *local = hw_to_local(hw); |
155 | 226 | ||
156 | return local->tx_led_name; | 227 | return local->tx_led.name; |
157 | } | 228 | } |
158 | EXPORT_SYMBOL(__ieee80211_get_tx_led_name); | 229 | EXPORT_SYMBOL(__ieee80211_get_tx_led_name); |
159 | 230 | ||
160 | char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw) | 231 | const char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw) |
161 | { | 232 | { |
162 | struct ieee80211_local *local = hw_to_local(hw); | 233 | struct ieee80211_local *local = hw_to_local(hw); |
163 | 234 | ||
164 | return local->rx_led_name; | 235 | return local->rx_led.name; |
165 | } | 236 | } |
166 | EXPORT_SYMBOL(__ieee80211_get_rx_led_name); | 237 | EXPORT_SYMBOL(__ieee80211_get_rx_led_name); |
167 | 238 | ||
@@ -211,10 +282,11 @@ static void tpt_trig_timer(unsigned long data) | |||
211 | read_unlock(&tpt_trig->trig.leddev_list_lock); | 282 | read_unlock(&tpt_trig->trig.leddev_list_lock); |
212 | } | 283 | } |
213 | 284 | ||
214 | char *__ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, | 285 | const char * |
215 | unsigned int flags, | 286 | __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, |
216 | const struct ieee80211_tpt_blink *blink_table, | 287 | unsigned int flags, |
217 | unsigned int blink_table_len) | 288 | const struct ieee80211_tpt_blink *blink_table, |
289 | unsigned int blink_table_len) | ||
218 | { | 290 | { |
219 | struct ieee80211_local *local = hw_to_local(hw); | 291 | struct ieee80211_local *local = hw_to_local(hw); |
220 | struct tpt_led_trigger *tpt_trig; | 292 | struct tpt_led_trigger *tpt_trig; |
@@ -229,7 +301,7 @@ char *__ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, | |||
229 | snprintf(tpt_trig->name, sizeof(tpt_trig->name), | 301 | snprintf(tpt_trig->name, sizeof(tpt_trig->name), |
230 | "%stpt", wiphy_name(local->hw.wiphy)); | 302 | "%stpt", wiphy_name(local->hw.wiphy)); |
231 | 303 | ||
232 | tpt_trig->trig.name = tpt_trig->name; | 304 | local->tpt_led.name = tpt_trig->name; |
233 | 305 | ||
234 | tpt_trig->blink_table = blink_table; | 306 | tpt_trig->blink_table = blink_table; |
235 | tpt_trig->blink_table_len = blink_table_len; | 307 | tpt_trig->blink_table_len = blink_table_len; |
diff --git a/net/mac80211/led.h b/net/mac80211/led.h index 89f4344f13b9..a7893a1ac98b 100644 --- a/net/mac80211/led.h +++ b/net/mac80211/led.h | |||
@@ -11,25 +11,42 @@ | |||
11 | #include <linux/leds.h> | 11 | #include <linux/leds.h> |
12 | #include "ieee80211_i.h" | 12 | #include "ieee80211_i.h" |
13 | 13 | ||
14 | #define MAC80211_BLINK_DELAY 50 /* ms */ | ||
15 | |||
16 | static inline void ieee80211_led_rx(struct ieee80211_local *local) | ||
17 | { | ||
18 | #ifdef CONFIG_MAC80211_LEDS | ||
19 | unsigned long led_delay = MAC80211_BLINK_DELAY; | ||
20 | |||
21 | if (!atomic_read(&local->rx_led_active)) | ||
22 | return; | ||
23 | led_trigger_blink_oneshot(&local->rx_led, &led_delay, &led_delay, 0); | ||
24 | #endif | ||
25 | } | ||
26 | |||
27 | static inline void ieee80211_led_tx(struct ieee80211_local *local) | ||
28 | { | ||
29 | #ifdef CONFIG_MAC80211_LEDS | ||
30 | unsigned long led_delay = MAC80211_BLINK_DELAY; | ||
31 | |||
32 | if (!atomic_read(&local->tx_led_active)) | ||
33 | return; | ||
34 | led_trigger_blink_oneshot(&local->tx_led, &led_delay, &led_delay, 0); | ||
35 | #endif | ||
36 | } | ||
37 | |||
14 | #ifdef CONFIG_MAC80211_LEDS | 38 | #ifdef CONFIG_MAC80211_LEDS |
15 | void ieee80211_led_rx(struct ieee80211_local *local); | ||
16 | void ieee80211_led_tx(struct ieee80211_local *local); | ||
17 | void ieee80211_led_assoc(struct ieee80211_local *local, | 39 | void ieee80211_led_assoc(struct ieee80211_local *local, |
18 | bool associated); | 40 | bool associated); |
19 | void ieee80211_led_radio(struct ieee80211_local *local, | 41 | void ieee80211_led_radio(struct ieee80211_local *local, |
20 | bool enabled); | 42 | bool enabled); |
21 | void ieee80211_led_names(struct ieee80211_local *local); | 43 | void ieee80211_alloc_led_names(struct ieee80211_local *local); |
44 | void ieee80211_free_led_names(struct ieee80211_local *local); | ||
22 | void ieee80211_led_init(struct ieee80211_local *local); | 45 | void ieee80211_led_init(struct ieee80211_local *local); |
23 | void ieee80211_led_exit(struct ieee80211_local *local); | 46 | void ieee80211_led_exit(struct ieee80211_local *local); |
24 | void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local, | 47 | void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local, |
25 | unsigned int types_on, unsigned int types_off); | 48 | unsigned int types_on, unsigned int types_off); |
26 | #else | 49 | #else |
27 | static inline void ieee80211_led_rx(struct ieee80211_local *local) | ||
28 | { | ||
29 | } | ||
30 | static inline void ieee80211_led_tx(struct ieee80211_local *local) | ||
31 | { | ||
32 | } | ||
33 | static inline void ieee80211_led_assoc(struct ieee80211_local *local, | 50 | static inline void ieee80211_led_assoc(struct ieee80211_local *local, |
34 | bool associated) | 51 | bool associated) |
35 | { | 52 | { |
@@ -38,7 +55,10 @@ static inline void ieee80211_led_radio(struct ieee80211_local *local, | |||
38 | bool enabled) | 55 | bool enabled) |
39 | { | 56 | { |
40 | } | 57 | } |
41 | static inline void ieee80211_led_names(struct ieee80211_local *local) | 58 | static inline void ieee80211_alloc_led_names(struct ieee80211_local *local) |
59 | { | ||
60 | } | ||
61 | static inline void ieee80211_free_led_names(struct ieee80211_local *local) | ||
42 | { | 62 | { |
43 | } | 63 | } |
44 | static inline void ieee80211_led_init(struct ieee80211_local *local) | 64 | static inline void ieee80211_led_init(struct ieee80211_local *local) |
@@ -58,7 +78,7 @@ static inline void | |||
58 | ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, __le16 fc, int bytes) | 78 | ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, __le16 fc, int bytes) |
59 | { | 79 | { |
60 | #ifdef CONFIG_MAC80211_LEDS | 80 | #ifdef CONFIG_MAC80211_LEDS |
61 | if (local->tpt_led_trigger && ieee80211_is_data(fc)) | 81 | if (ieee80211_is_data(fc) && atomic_read(&local->tpt_led_active)) |
62 | local->tpt_led_trigger->tx_bytes += bytes; | 82 | local->tpt_led_trigger->tx_bytes += bytes; |
63 | #endif | 83 | #endif |
64 | } | 84 | } |
@@ -67,7 +87,7 @@ static inline void | |||
67 | ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, __le16 fc, int bytes) | 87 | ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, __le16 fc, int bytes) |
68 | { | 88 | { |
69 | #ifdef CONFIG_MAC80211_LEDS | 89 | #ifdef CONFIG_MAC80211_LEDS |
70 | if (local->tpt_led_trigger && ieee80211_is_data(fc)) | 90 | if (ieee80211_is_data(fc) && atomic_read(&local->tpt_led_active)) |
71 | local->tpt_led_trigger->rx_bytes += bytes; | 91 | local->tpt_led_trigger->rx_bytes += bytes; |
72 | #endif | 92 | #endif |
73 | } | 93 | } |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index df3051d96aff..3c956c5f99b2 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -41,9 +41,6 @@ void ieee80211_configure_filter(struct ieee80211_local *local) | |||
41 | unsigned int changed_flags; | 41 | unsigned int changed_flags; |
42 | unsigned int new_flags = 0; | 42 | unsigned int new_flags = 0; |
43 | 43 | ||
44 | if (atomic_read(&local->iff_promiscs)) | ||
45 | new_flags |= FIF_PROMISC_IN_BSS; | ||
46 | |||
47 | if (atomic_read(&local->iff_allmultis)) | 44 | if (atomic_read(&local->iff_allmultis)) |
48 | new_flags |= FIF_ALLMULTI; | 45 | new_flags |= FIF_ALLMULTI; |
49 | 46 | ||
@@ -646,7 +643,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, | |||
646 | skb_queue_head_init(&local->skb_queue); | 643 | skb_queue_head_init(&local->skb_queue); |
647 | skb_queue_head_init(&local->skb_queue_unreliable); | 644 | skb_queue_head_init(&local->skb_queue_unreliable); |
648 | 645 | ||
649 | ieee80211_led_names(local); | 646 | ieee80211_alloc_led_names(local); |
650 | 647 | ||
651 | ieee80211_roc_setup(local); | 648 | ieee80211_roc_setup(local); |
652 | 649 | ||
@@ -771,8 +768,11 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local) | |||
771 | suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_256; | 768 | suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_256; |
772 | } | 769 | } |
773 | 770 | ||
774 | for (r = 0; r < local->hw.n_cipher_schemes; r++) | 771 | for (r = 0; r < local->hw.n_cipher_schemes; r++) { |
775 | suites[w++] = cs[r].cipher; | 772 | suites[w++] = cs[r].cipher; |
773 | if (WARN_ON(cs[r].pn_len > IEEE80211_MAX_PN_LEN)) | ||
774 | return -EINVAL; | ||
775 | } | ||
776 | } | 776 | } |
777 | 777 | ||
778 | local->hw.wiphy->cipher_suites = suites; | 778 | local->hw.wiphy->cipher_suites = suites; |
@@ -840,7 +840,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
840 | 840 | ||
841 | /* Only HW csum features are currently compatible with mac80211 */ | 841 | /* Only HW csum features are currently compatible with mac80211 */ |
842 | feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 842 | feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
843 | NETIF_F_HW_CSUM; | 843 | NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA | |
844 | NETIF_F_GSO_SOFTWARE; | ||
844 | if (WARN_ON(hw->netdev_features & ~feature_whitelist)) | 845 | if (WARN_ON(hw->netdev_features & ~feature_whitelist)) |
845 | return -EINVAL; | 846 | return -EINVAL; |
846 | 847 | ||
@@ -1209,6 +1210,8 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
1209 | 1210 | ||
1210 | sta_info_stop(local); | 1211 | sta_info_stop(local); |
1211 | 1212 | ||
1213 | ieee80211_free_led_names(local); | ||
1214 | |||
1212 | wiphy_free(local->hw.wiphy); | 1215 | wiphy_free(local->hw.wiphy); |
1213 | } | 1216 | } |
1214 | EXPORT_SYMBOL(ieee80211_free_hw); | 1217 | EXPORT_SYMBOL(ieee80211_free_hw); |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 60d737f144e3..ac843fc88745 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -72,10 +72,11 @@ static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata, | |||
72 | * | 72 | * |
73 | * @sta: mesh peer link to restart | 73 | * @sta: mesh peer link to restart |
74 | * | 74 | * |
75 | * Locking: this function must be called holding sta->lock | 75 | * Locking: this function must be called holding sta->plink_lock |
76 | */ | 76 | */ |
77 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) | 77 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) |
78 | { | 78 | { |
79 | lockdep_assert_held(&sta->plink_lock); | ||
79 | sta->plink_state = NL80211_PLINK_LISTEN; | 80 | sta->plink_state = NL80211_PLINK_LISTEN; |
80 | sta->llid = sta->plid = sta->reason = 0; | 81 | sta->llid = sta->plid = sta->reason = 0; |
81 | sta->plink_retries = 0; | 82 | sta->plink_retries = 0; |
@@ -213,13 +214,15 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) | |||
213 | * All mesh paths with this peer as next hop will be flushed | 214 | * All mesh paths with this peer as next hop will be flushed |
214 | * Returns beacon changed flag if the beacon content changed. | 215 | * Returns beacon changed flag if the beacon content changed. |
215 | * | 216 | * |
216 | * Locking: the caller must hold sta->lock | 217 | * Locking: the caller must hold sta->plink_lock |
217 | */ | 218 | */ |
218 | static u32 __mesh_plink_deactivate(struct sta_info *sta) | 219 | static u32 __mesh_plink_deactivate(struct sta_info *sta) |
219 | { | 220 | { |
220 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 221 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
221 | u32 changed = 0; | 222 | u32 changed = 0; |
222 | 223 | ||
224 | lockdep_assert_held(&sta->plink_lock); | ||
225 | |||
223 | if (sta->plink_state == NL80211_PLINK_ESTAB) | 226 | if (sta->plink_state == NL80211_PLINK_ESTAB) |
224 | changed = mesh_plink_dec_estab_count(sdata); | 227 | changed = mesh_plink_dec_estab_count(sdata); |
225 | sta->plink_state = NL80211_PLINK_BLOCKED; | 228 | sta->plink_state = NL80211_PLINK_BLOCKED; |
@@ -244,13 +247,13 @@ u32 mesh_plink_deactivate(struct sta_info *sta) | |||
244 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 247 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
245 | u32 changed; | 248 | u32 changed; |
246 | 249 | ||
247 | spin_lock_bh(&sta->lock); | 250 | spin_lock_bh(&sta->plink_lock); |
248 | changed = __mesh_plink_deactivate(sta); | 251 | changed = __mesh_plink_deactivate(sta); |
249 | sta->reason = WLAN_REASON_MESH_PEER_CANCELED; | 252 | sta->reason = WLAN_REASON_MESH_PEER_CANCELED; |
250 | mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, | 253 | mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, |
251 | sta->sta.addr, sta->llid, sta->plid, | 254 | sta->sta.addr, sta->llid, sta->plid, |
252 | sta->reason); | 255 | sta->reason); |
253 | spin_unlock_bh(&sta->lock); | 256 | spin_unlock_bh(&sta->plink_lock); |
254 | 257 | ||
255 | return changed; | 258 | return changed; |
256 | } | 259 | } |
@@ -387,7 +390,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, | |||
387 | sband = local->hw.wiphy->bands[band]; | 390 | sband = local->hw.wiphy->bands[band]; |
388 | rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates); | 391 | rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates); |
389 | 392 | ||
390 | spin_lock_bh(&sta->lock); | 393 | spin_lock_bh(&sta->plink_lock); |
391 | sta->last_rx = jiffies; | 394 | sta->last_rx = jiffies; |
392 | 395 | ||
393 | /* rates and capabilities don't change during peering */ | 396 | /* rates and capabilities don't change during peering */ |
@@ -419,7 +422,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, | |||
419 | else | 422 | else |
420 | rate_control_rate_update(local, sband, sta, changed); | 423 | rate_control_rate_update(local, sband, sta, changed); |
421 | out: | 424 | out: |
422 | spin_unlock_bh(&sta->lock); | 425 | spin_unlock_bh(&sta->plink_lock); |
423 | } | 426 | } |
424 | 427 | ||
425 | static struct sta_info * | 428 | static struct sta_info * |
@@ -552,7 +555,7 @@ static void mesh_plink_timer(unsigned long data) | |||
552 | if (sta->sdata->local->quiescing) | 555 | if (sta->sdata->local->quiescing) |
553 | return; | 556 | return; |
554 | 557 | ||
555 | spin_lock_bh(&sta->lock); | 558 | spin_lock_bh(&sta->plink_lock); |
556 | 559 | ||
557 | /* If a timer fires just before a state transition on another CPU, | 560 | /* If a timer fires just before a state transition on another CPU, |
558 | * we may have already extended the timeout and changed state by the | 561 | * we may have already extended the timeout and changed state by the |
@@ -563,7 +566,7 @@ static void mesh_plink_timer(unsigned long data) | |||
563 | mpl_dbg(sta->sdata, | 566 | mpl_dbg(sta->sdata, |
564 | "Ignoring timer for %pM in state %s (timer adjusted)", | 567 | "Ignoring timer for %pM in state %s (timer adjusted)", |
565 | sta->sta.addr, mplstates[sta->plink_state]); | 568 | sta->sta.addr, mplstates[sta->plink_state]); |
566 | spin_unlock_bh(&sta->lock); | 569 | spin_unlock_bh(&sta->plink_lock); |
567 | return; | 570 | return; |
568 | } | 571 | } |
569 | 572 | ||
@@ -573,7 +576,7 @@ static void mesh_plink_timer(unsigned long data) | |||
573 | mpl_dbg(sta->sdata, | 576 | mpl_dbg(sta->sdata, |
574 | "Ignoring timer for %pM in state %s (timer deleted)", | 577 | "Ignoring timer for %pM in state %s (timer deleted)", |
575 | sta->sta.addr, mplstates[sta->plink_state]); | 578 | sta->sta.addr, mplstates[sta->plink_state]); |
576 | spin_unlock_bh(&sta->lock); | 579 | spin_unlock_bh(&sta->plink_lock); |
577 | return; | 580 | return; |
578 | } | 581 | } |
579 | 582 | ||
@@ -619,7 +622,7 @@ static void mesh_plink_timer(unsigned long data) | |||
619 | default: | 622 | default: |
620 | break; | 623 | break; |
621 | } | 624 | } |
622 | spin_unlock_bh(&sta->lock); | 625 | spin_unlock_bh(&sta->plink_lock); |
623 | if (action) | 626 | if (action) |
624 | mesh_plink_frame_tx(sdata, action, sta->sta.addr, | 627 | mesh_plink_frame_tx(sdata, action, sta->sta.addr, |
625 | sta->llid, sta->plid, reason); | 628 | sta->llid, sta->plid, reason); |
@@ -674,16 +677,16 @@ u32 mesh_plink_open(struct sta_info *sta) | |||
674 | if (!test_sta_flag(sta, WLAN_STA_AUTH)) | 677 | if (!test_sta_flag(sta, WLAN_STA_AUTH)) |
675 | return 0; | 678 | return 0; |
676 | 679 | ||
677 | spin_lock_bh(&sta->lock); | 680 | spin_lock_bh(&sta->plink_lock); |
678 | sta->llid = mesh_get_new_llid(sdata); | 681 | sta->llid = mesh_get_new_llid(sdata); |
679 | if (sta->plink_state != NL80211_PLINK_LISTEN && | 682 | if (sta->plink_state != NL80211_PLINK_LISTEN && |
680 | sta->plink_state != NL80211_PLINK_BLOCKED) { | 683 | sta->plink_state != NL80211_PLINK_BLOCKED) { |
681 | spin_unlock_bh(&sta->lock); | 684 | spin_unlock_bh(&sta->plink_lock); |
682 | return 0; | 685 | return 0; |
683 | } | 686 | } |
684 | sta->plink_state = NL80211_PLINK_OPN_SNT; | 687 | sta->plink_state = NL80211_PLINK_OPN_SNT; |
685 | mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout); | 688 | mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout); |
686 | spin_unlock_bh(&sta->lock); | 689 | spin_unlock_bh(&sta->plink_lock); |
687 | mpl_dbg(sdata, | 690 | mpl_dbg(sdata, |
688 | "Mesh plink: starting establishment with %pM\n", | 691 | "Mesh plink: starting establishment with %pM\n", |
689 | sta->sta.addr); | 692 | sta->sta.addr); |
@@ -700,10 +703,10 @@ u32 mesh_plink_block(struct sta_info *sta) | |||
700 | { | 703 | { |
701 | u32 changed; | 704 | u32 changed; |
702 | 705 | ||
703 | spin_lock_bh(&sta->lock); | 706 | spin_lock_bh(&sta->plink_lock); |
704 | changed = __mesh_plink_deactivate(sta); | 707 | changed = __mesh_plink_deactivate(sta); |
705 | sta->plink_state = NL80211_PLINK_BLOCKED; | 708 | sta->plink_state = NL80211_PLINK_BLOCKED; |
706 | spin_unlock_bh(&sta->lock); | 709 | spin_unlock_bh(&sta->plink_lock); |
707 | 710 | ||
708 | return changed; | 711 | return changed; |
709 | } | 712 | } |
@@ -758,7 +761,7 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata, | |||
758 | mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr, | 761 | mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr, |
759 | mplstates[sta->plink_state], mplevents[event]); | 762 | mplstates[sta->plink_state], mplevents[event]); |
760 | 763 | ||
761 | spin_lock_bh(&sta->lock); | 764 | spin_lock_bh(&sta->plink_lock); |
762 | switch (sta->plink_state) { | 765 | switch (sta->plink_state) { |
763 | case NL80211_PLINK_LISTEN: | 766 | case NL80211_PLINK_LISTEN: |
764 | switch (event) { | 767 | switch (event) { |
@@ -872,7 +875,7 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata, | |||
872 | */ | 875 | */ |
873 | break; | 876 | break; |
874 | } | 877 | } |
875 | spin_unlock_bh(&sta->lock); | 878 | spin_unlock_bh(&sta->plink_lock); |
876 | if (action) { | 879 | if (action) { |
877 | mesh_plink_frame_tx(sdata, action, sta->sta.addr, | 880 | mesh_plink_frame_tx(sdata, action, sta->sta.addr, |
878 | sta->llid, sta->plid, sta->reason); | 881 | sta->llid, sta->plid, sta->reason); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 26053bf2faa8..3294666f599c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -4307,15 +4307,15 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
4307 | } | 4307 | } |
4308 | 4308 | ||
4309 | static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | 4309 | static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, |
4310 | struct cfg80211_bss *cbss, bool assoc) | 4310 | struct cfg80211_bss *cbss, bool assoc, |
4311 | bool override) | ||
4311 | { | 4312 | { |
4312 | struct ieee80211_local *local = sdata->local; | 4313 | struct ieee80211_local *local = sdata->local; |
4313 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 4314 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
4314 | struct ieee80211_bss *bss = (void *)cbss->priv; | 4315 | struct ieee80211_bss *bss = (void *)cbss->priv; |
4315 | struct sta_info *new_sta = NULL; | 4316 | struct sta_info *new_sta = NULL; |
4316 | struct ieee80211_supported_band *sband; | 4317 | struct ieee80211_supported_band *sband; |
4317 | struct ieee80211_sta_ht_cap sta_ht_cap; | 4318 | bool have_sta = false; |
4318 | bool have_sta = false, is_override = false; | ||
4319 | int err; | 4319 | int err; |
4320 | 4320 | ||
4321 | sband = local->hw.wiphy->bands[cbss->channel->band]; | 4321 | sband = local->hw.wiphy->bands[cbss->channel->band]; |
@@ -4335,14 +4335,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
4335 | return -ENOMEM; | 4335 | return -ENOMEM; |
4336 | } | 4336 | } |
4337 | 4337 | ||
4338 | memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap)); | 4338 | if (new_sta || override) { |
4339 | ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap); | ||
4340 | |||
4341 | is_override = (sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) != | ||
4342 | (sband->ht_cap.cap & | ||
4343 | IEEE80211_HT_CAP_SUP_WIDTH_20_40); | ||
4344 | |||
4345 | if (new_sta || is_override) { | ||
4346 | err = ieee80211_prep_channel(sdata, cbss); | 4339 | err = ieee80211_prep_channel(sdata, cbss); |
4347 | if (err) { | 4340 | if (err) { |
4348 | if (new_sta) | 4341 | if (new_sta) |
@@ -4552,7 +4545,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
4552 | 4545 | ||
4553 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); | 4546 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |
4554 | 4547 | ||
4555 | err = ieee80211_prep_connection(sdata, req->bss, false); | 4548 | err = ieee80211_prep_connection(sdata, req->bss, false, false); |
4556 | if (err) | 4549 | if (err) |
4557 | goto err_clear; | 4550 | goto err_clear; |
4558 | 4551 | ||
@@ -4624,6 +4617,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4624 | struct ieee80211_supported_band *sband; | 4617 | struct ieee80211_supported_band *sband; |
4625 | const u8 *ssidie, *ht_ie, *vht_ie; | 4618 | const u8 *ssidie, *ht_ie, *vht_ie; |
4626 | int i, err; | 4619 | int i, err; |
4620 | bool override = false; | ||
4627 | 4621 | ||
4628 | assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL); | 4622 | assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL); |
4629 | if (!assoc_data) | 4623 | if (!assoc_data) |
@@ -4728,14 +4722,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4728 | } | 4722 | } |
4729 | } | 4723 | } |
4730 | 4724 | ||
4731 | if (req->flags & ASSOC_REQ_DISABLE_HT) { | ||
4732 | ifmgd->flags |= IEEE80211_STA_DISABLE_HT; | ||
4733 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; | ||
4734 | } | ||
4735 | |||
4736 | if (req->flags & ASSOC_REQ_DISABLE_VHT) | ||
4737 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; | ||
4738 | |||
4739 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ | 4725 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ |
4740 | sband = local->hw.wiphy->bands[req->bss->channel->band]; | 4726 | sband = local->hw.wiphy->bands[req->bss->channel->band]; |
4741 | if (!sband->ht_cap.ht_supported || | 4727 | if (!sband->ht_cap.ht_supported || |
@@ -4847,7 +4833,36 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4847 | ifmgd->dtim_period = 0; | 4833 | ifmgd->dtim_period = 0; |
4848 | ifmgd->have_beacon = false; | 4834 | ifmgd->have_beacon = false; |
4849 | 4835 | ||
4850 | err = ieee80211_prep_connection(sdata, req->bss, true); | 4836 | /* override HT/VHT configuration only if the AP and we support it */ |
4837 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { | ||
4838 | struct ieee80211_sta_ht_cap sta_ht_cap; | ||
4839 | |||
4840 | if (req->flags & ASSOC_REQ_DISABLE_HT) | ||
4841 | override = true; | ||
4842 | |||
4843 | memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap)); | ||
4844 | ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap); | ||
4845 | |||
4846 | /* check for 40 MHz disable override */ | ||
4847 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ) && | ||
4848 | sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && | ||
4849 | !(sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | ||
4850 | override = true; | ||
4851 | |||
4852 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && | ||
4853 | req->flags & ASSOC_REQ_DISABLE_VHT) | ||
4854 | override = true; | ||
4855 | } | ||
4856 | |||
4857 | if (req->flags & ASSOC_REQ_DISABLE_HT) { | ||
4858 | ifmgd->flags |= IEEE80211_STA_DISABLE_HT; | ||
4859 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; | ||
4860 | } | ||
4861 | |||
4862 | if (req->flags & ASSOC_REQ_DISABLE_VHT) | ||
4863 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; | ||
4864 | |||
4865 | err = ieee80211_prep_connection(sdata, req->bss, true, override); | ||
4851 | if (err) | 4866 | if (err) |
4852 | goto err_clear; | 4867 | goto err_clear; |
4853 | 4868 | ||
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index d53355b011f5..de69adf24f53 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -683,7 +683,13 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | |||
683 | if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) | 683 | if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) |
684 | return; | 684 | return; |
685 | 685 | ||
686 | ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); | 686 | if (ista) { |
687 | spin_lock_bh(&sta->rate_ctrl_lock); | ||
688 | ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); | ||
689 | spin_unlock_bh(&sta->rate_ctrl_lock); | ||
690 | } else { | ||
691 | ref->ops->get_rate(ref->priv, NULL, NULL, txrc); | ||
692 | } | ||
687 | 693 | ||
688 | if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_RC_TABLE) | 694 | if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_RC_TABLE) |
689 | return; | 695 | return; |
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index 38652f09feaf..25c9be5dd7fd 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
@@ -42,10 +42,12 @@ static inline void rate_control_tx_status(struct ieee80211_local *local, | |||
42 | if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) | 42 | if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) |
43 | return; | 43 | return; |
44 | 44 | ||
45 | spin_lock_bh(&sta->rate_ctrl_lock); | ||
45 | if (ref->ops->tx_status) | 46 | if (ref->ops->tx_status) |
46 | ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb); | 47 | ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb); |
47 | else | 48 | else |
48 | ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info); | 49 | ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info); |
50 | spin_unlock_bh(&sta->rate_ctrl_lock); | ||
49 | } | 51 | } |
50 | 52 | ||
51 | static inline void | 53 | static inline void |
@@ -64,7 +66,9 @@ rate_control_tx_status_noskb(struct ieee80211_local *local, | |||
64 | if (WARN_ON_ONCE(!ref->ops->tx_status_noskb)) | 66 | if (WARN_ON_ONCE(!ref->ops->tx_status_noskb)) |
65 | return; | 67 | return; |
66 | 68 | ||
69 | spin_lock_bh(&sta->rate_ctrl_lock); | ||
67 | ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info); | 70 | ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info); |
71 | spin_unlock_bh(&sta->rate_ctrl_lock); | ||
68 | } | 72 | } |
69 | 73 | ||
70 | static inline void rate_control_rate_init(struct sta_info *sta) | 74 | static inline void rate_control_rate_init(struct sta_info *sta) |
@@ -91,8 +95,10 @@ static inline void rate_control_rate_init(struct sta_info *sta) | |||
91 | 95 | ||
92 | sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band]; | 96 | sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band]; |
93 | 97 | ||
98 | spin_lock_bh(&sta->rate_ctrl_lock); | ||
94 | ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista, | 99 | ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista, |
95 | priv_sta); | 100 | priv_sta); |
101 | spin_unlock_bh(&sta->rate_ctrl_lock); | ||
96 | rcu_read_unlock(); | 102 | rcu_read_unlock(); |
97 | set_sta_flag(sta, WLAN_STA_RATE_CONTROL); | 103 | set_sta_flag(sta, WLAN_STA_RATE_CONTROL); |
98 | } | 104 | } |
@@ -115,18 +121,20 @@ static inline void rate_control_rate_update(struct ieee80211_local *local, | |||
115 | return; | 121 | return; |
116 | } | 122 | } |
117 | 123 | ||
124 | spin_lock_bh(&sta->rate_ctrl_lock); | ||
118 | ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def, | 125 | ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def, |
119 | ista, priv_sta, changed); | 126 | ista, priv_sta, changed); |
127 | spin_unlock_bh(&sta->rate_ctrl_lock); | ||
120 | rcu_read_unlock(); | 128 | rcu_read_unlock(); |
121 | } | 129 | } |
122 | drv_sta_rc_update(local, sta->sdata, &sta->sta, changed); | 130 | drv_sta_rc_update(local, sta->sdata, &sta->sta, changed); |
123 | } | 131 | } |
124 | 132 | ||
125 | static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, | 133 | static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, |
126 | struct ieee80211_sta *sta, | 134 | struct sta_info *sta, gfp_t gfp) |
127 | gfp_t gfp) | ||
128 | { | 135 | { |
129 | return ref->ops->alloc_sta(ref->priv, sta, gfp); | 136 | spin_lock_init(&sta->rate_ctrl_lock); |
137 | return ref->ops->alloc_sta(ref->priv, &sta->sta, gfp); | ||
130 | } | 138 | } |
131 | 139 | ||
132 | static inline void rate_control_free_sta(struct sta_info *sta) | 140 | static inline void rate_control_free_sta(struct sta_info *sta) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 260eed45b6d2..aa35977a9c4d 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -32,6 +32,16 @@ | |||
32 | #include "wme.h" | 32 | #include "wme.h" |
33 | #include "rate.h" | 33 | #include "rate.h" |
34 | 34 | ||
35 | static inline void ieee80211_rx_stats(struct net_device *dev, u32 len) | ||
36 | { | ||
37 | struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); | ||
38 | |||
39 | u64_stats_update_begin(&tstats->syncp); | ||
40 | tstats->rx_packets++; | ||
41 | tstats->rx_bytes += len; | ||
42 | u64_stats_update_end(&tstats->syncp); | ||
43 | } | ||
44 | |||
35 | /* | 45 | /* |
36 | * monitor mode reception | 46 | * monitor mode reception |
37 | * | 47 | * |
@@ -529,8 +539,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
529 | } | 539 | } |
530 | 540 | ||
531 | prev_dev = sdata->dev; | 541 | prev_dev = sdata->dev; |
532 | sdata->dev->stats.rx_packets++; | 542 | ieee80211_rx_stats(sdata->dev, skb->len); |
533 | sdata->dev->stats.rx_bytes += skb->len; | ||
534 | } | 543 | } |
535 | 544 | ||
536 | if (prev_dev) { | 545 | if (prev_dev) { |
@@ -981,7 +990,6 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, | |||
981 | struct sk_buff *skb = rx->skb; | 990 | struct sk_buff *skb = rx->skb; |
982 | struct ieee80211_local *local = rx->local; | 991 | struct ieee80211_local *local = rx->local; |
983 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 992 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
984 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
985 | struct sta_info *sta = rx->sta; | 993 | struct sta_info *sta = rx->sta; |
986 | struct tid_ampdu_rx *tid_agg_rx; | 994 | struct tid_ampdu_rx *tid_agg_rx; |
987 | u16 sc; | 995 | u16 sc; |
@@ -1016,10 +1024,6 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, | |||
1016 | ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL) | 1024 | ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL) |
1017 | goto dont_reorder; | 1025 | goto dont_reorder; |
1018 | 1026 | ||
1019 | /* not actually part of this BA session */ | ||
1020 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1021 | goto dont_reorder; | ||
1022 | |||
1023 | /* new, potentially un-ordered, ampdu frame - process it */ | 1027 | /* new, potentially un-ordered, ampdu frame - process it */ |
1024 | 1028 | ||
1025 | /* reset session timer */ | 1029 | /* reset session timer */ |
@@ -1073,10 +1077,8 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx) | |||
1073 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && | 1077 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && |
1074 | rx->sta->last_seq_ctrl[rx->seqno_idx] == | 1078 | rx->sta->last_seq_ctrl[rx->seqno_idx] == |
1075 | hdr->seq_ctrl)) { | 1079 | hdr->seq_ctrl)) { |
1076 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { | 1080 | I802_DEBUG_INC(rx->local->dot11FrameDuplicateCount); |
1077 | rx->local->dot11FrameDuplicateCount++; | 1081 | rx->sta->num_duplicates++; |
1078 | rx->sta->num_duplicates++; | ||
1079 | } | ||
1080 | return RX_DROP_UNUSABLE; | 1082 | return RX_DROP_UNUSABLE; |
1081 | } else if (!(status->flag & RX_FLAG_AMSDU_MORE)) { | 1083 | } else if (!(status->flag & RX_FLAG_AMSDU_MORE)) { |
1082 | rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl; | 1084 | rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl; |
@@ -1200,6 +1202,8 @@ static void sta_ps_start(struct sta_info *sta) | |||
1200 | ps_dbg(sdata, "STA %pM aid %d enters power save mode\n", | 1202 | ps_dbg(sdata, "STA %pM aid %d enters power save mode\n", |
1201 | sta->sta.addr, sta->sta.aid); | 1203 | sta->sta.addr, sta->sta.aid); |
1202 | 1204 | ||
1205 | ieee80211_clear_fast_xmit(sta); | ||
1206 | |||
1203 | if (!sta->sta.txq[0]) | 1207 | if (!sta->sta.txq[0]) |
1204 | return; | 1208 | return; |
1205 | 1209 | ||
@@ -1265,7 +1269,7 @@ ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx) | |||
1265 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | 1269 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); |
1266 | int tid, ac; | 1270 | int tid, ac; |
1267 | 1271 | ||
1268 | if (!rx->sta || !(status->rx_flags & IEEE80211_RX_RA_MATCH)) | 1272 | if (!rx->sta) |
1269 | return RX_CONTINUE; | 1273 | return RX_CONTINUE; |
1270 | 1274 | ||
1271 | if (sdata->vif.type != NL80211_IFTYPE_AP && | 1275 | if (sdata->vif.type != NL80211_IFTYPE_AP && |
@@ -1367,11 +1371,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1367 | } | 1371 | } |
1368 | } | 1372 | } |
1369 | } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) { | 1373 | } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) { |
1370 | u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, | 1374 | sta->last_rx = jiffies; |
1371 | NL80211_IFTYPE_OCB); | ||
1372 | /* OCB uses wild-card BSSID */ | ||
1373 | if (is_broadcast_ether_addr(bssid)) | ||
1374 | sta->last_rx = jiffies; | ||
1375 | } else if (!is_multicast_ether_addr(hdr->addr1)) { | 1375 | } else if (!is_multicast_ether_addr(hdr->addr1)) { |
1376 | /* | 1376 | /* |
1377 | * Mesh beacons will update last_rx when if they are found to | 1377 | * Mesh beacons will update last_rx when if they are found to |
@@ -1386,9 +1386,6 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1386 | } | 1386 | } |
1387 | } | 1387 | } |
1388 | 1388 | ||
1389 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1390 | return RX_CONTINUE; | ||
1391 | |||
1392 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) | 1389 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) |
1393 | ieee80211_sta_rx_notify(rx->sdata, hdr); | 1390 | ieee80211_sta_rx_notify(rx->sdata, hdr); |
1394 | 1391 | ||
@@ -1517,13 +1514,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
1517 | * possible. | 1514 | * possible. |
1518 | */ | 1515 | */ |
1519 | 1516 | ||
1520 | /* | ||
1521 | * No point in finding a key and decrypting if the frame is neither | ||
1522 | * addressed to us nor a multicast frame. | ||
1523 | */ | ||
1524 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1525 | return RX_CONTINUE; | ||
1526 | |||
1527 | /* start without a key */ | 1517 | /* start without a key */ |
1528 | rx->key = NULL; | 1518 | rx->key = NULL; |
1529 | fc = hdr->frame_control; | 1519 | fc = hdr->frame_control; |
@@ -1795,7 +1785,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1795 | frag = sc & IEEE80211_SCTL_FRAG; | 1785 | frag = sc & IEEE80211_SCTL_FRAG; |
1796 | 1786 | ||
1797 | if (is_multicast_ether_addr(hdr->addr1)) { | 1787 | if (is_multicast_ether_addr(hdr->addr1)) { |
1798 | rx->local->dot11MulticastReceivedFrameCount++; | 1788 | I802_DEBUG_INC(rx->local->dot11MulticastReceivedFrameCount); |
1799 | goto out_no_led; | 1789 | goto out_no_led; |
1800 | } | 1790 | } |
1801 | 1791 | ||
@@ -1878,7 +1868,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1878 | 1868 | ||
1879 | rx->skb = __skb_dequeue(&entry->skb_list); | 1869 | rx->skb = __skb_dequeue(&entry->skb_list); |
1880 | if (skb_tailroom(rx->skb) < entry->extra_len) { | 1870 | if (skb_tailroom(rx->skb) < entry->extra_len) { |
1881 | I802_DEBUG_INC(rx->local->rx_expand_skb_head2); | 1871 | I802_DEBUG_INC(rx->local->rx_expand_skb_head_defrag); |
1882 | if (unlikely(pskb_expand_head(rx->skb, 0, entry->extra_len, | 1872 | if (unlikely(pskb_expand_head(rx->skb, 0, entry->extra_len, |
1883 | GFP_ATOMIC))) { | 1873 | GFP_ATOMIC))) { |
1884 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); | 1874 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); |
@@ -2054,18 +2044,15 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
2054 | struct sk_buff *skb, *xmit_skb; | 2044 | struct sk_buff *skb, *xmit_skb; |
2055 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; | 2045 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; |
2056 | struct sta_info *dsta; | 2046 | struct sta_info *dsta; |
2057 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
2058 | |||
2059 | dev->stats.rx_packets++; | ||
2060 | dev->stats.rx_bytes += rx->skb->len; | ||
2061 | 2047 | ||
2062 | skb = rx->skb; | 2048 | skb = rx->skb; |
2063 | xmit_skb = NULL; | 2049 | xmit_skb = NULL; |
2064 | 2050 | ||
2051 | ieee80211_rx_stats(dev, skb->len); | ||
2052 | |||
2065 | if ((sdata->vif.type == NL80211_IFTYPE_AP || | 2053 | if ((sdata->vif.type == NL80211_IFTYPE_AP || |
2066 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && | 2054 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && |
2067 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && | 2055 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && |
2068 | (status->rx_flags & IEEE80211_RX_RA_MATCH) && | ||
2069 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { | 2056 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { |
2070 | if (is_multicast_ether_addr(ehdr->h_dest)) { | 2057 | if (is_multicast_ether_addr(ehdr->h_dest)) { |
2071 | /* | 2058 | /* |
@@ -2206,7 +2193,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
2206 | struct sk_buff *skb = rx->skb, *fwd_skb; | 2193 | struct sk_buff *skb = rx->skb, *fwd_skb; |
2207 | struct ieee80211_local *local = rx->local; | 2194 | struct ieee80211_local *local = rx->local; |
2208 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 2195 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
2209 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
2210 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 2196 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
2211 | u16 q, hdrlen; | 2197 | u16 q, hdrlen; |
2212 | 2198 | ||
@@ -2237,8 +2223,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
2237 | mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr)) | 2223 | mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr)) |
2238 | return RX_DROP_MONITOR; | 2224 | return RX_DROP_MONITOR; |
2239 | 2225 | ||
2240 | if (!ieee80211_is_data(hdr->frame_control) || | 2226 | if (!ieee80211_is_data(hdr->frame_control)) |
2241 | !(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
2242 | return RX_CONTINUE; | 2227 | return RX_CONTINUE; |
2243 | 2228 | ||
2244 | if (!mesh_hdr->ttl) | 2229 | if (!mesh_hdr->ttl) |
@@ -2329,11 +2314,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
2329 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); | 2314 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); |
2330 | ieee80211_add_pending_skb(local, fwd_skb); | 2315 | ieee80211_add_pending_skb(local, fwd_skb); |
2331 | out: | 2316 | out: |
2332 | if (is_multicast_ether_addr(hdr->addr1) || | 2317 | if (is_multicast_ether_addr(hdr->addr1)) |
2333 | sdata->dev->flags & IFF_PROMISC) | ||
2334 | return RX_CONTINUE; | 2318 | return RX_CONTINUE; |
2335 | else | 2319 | return RX_DROP_MONITOR; |
2336 | return RX_DROP_MONITOR; | ||
2337 | } | 2320 | } |
2338 | #endif | 2321 | #endif |
2339 | 2322 | ||
@@ -2444,6 +2427,9 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) | |||
2444 | struct { | 2427 | struct { |
2445 | __le16 control, start_seq_num; | 2428 | __le16 control, start_seq_num; |
2446 | } __packed bar_data; | 2429 | } __packed bar_data; |
2430 | struct ieee80211_event event = { | ||
2431 | .type = BAR_RX_EVENT, | ||
2432 | }; | ||
2447 | 2433 | ||
2448 | if (!rx->sta) | 2434 | if (!rx->sta) |
2449 | return RX_DROP_MONITOR; | 2435 | return RX_DROP_MONITOR; |
@@ -2459,6 +2445,9 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) | |||
2459 | return RX_DROP_MONITOR; | 2445 | return RX_DROP_MONITOR; |
2460 | 2446 | ||
2461 | start_seq_num = le16_to_cpu(bar_data.start_seq_num) >> 4; | 2447 | start_seq_num = le16_to_cpu(bar_data.start_seq_num) >> 4; |
2448 | event.u.ba.tid = tid; | ||
2449 | event.u.ba.ssn = start_seq_num; | ||
2450 | event.u.ba.sta = &rx->sta->sta; | ||
2462 | 2451 | ||
2463 | /* reset session timer */ | 2452 | /* reset session timer */ |
2464 | if (tid_agg_rx->timeout) | 2453 | if (tid_agg_rx->timeout) |
@@ -2471,6 +2460,8 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) | |||
2471 | start_seq_num, frames); | 2460 | start_seq_num, frames); |
2472 | spin_unlock(&tid_agg_rx->reorder_lock); | 2461 | spin_unlock(&tid_agg_rx->reorder_lock); |
2473 | 2462 | ||
2463 | drv_event_callback(rx->local, rx->sdata, &event); | ||
2464 | |||
2474 | kfree_skb(skb); | 2465 | kfree_skb(skb); |
2475 | return RX_QUEUED; | 2466 | return RX_QUEUED; |
2476 | } | 2467 | } |
@@ -2560,9 +2551,6 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | |||
2560 | rx->flags |= IEEE80211_RX_BEACON_REPORTED; | 2551 | rx->flags |= IEEE80211_RX_BEACON_REPORTED; |
2561 | } | 2552 | } |
2562 | 2553 | ||
2563 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
2564 | return RX_DROP_MONITOR; | ||
2565 | |||
2566 | if (ieee80211_drop_unencrypted_mgmt(rx)) | 2554 | if (ieee80211_drop_unencrypted_mgmt(rx)) |
2567 | return RX_DROP_UNUSABLE; | 2555 | return RX_DROP_UNUSABLE; |
2568 | 2556 | ||
@@ -2590,9 +2578,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2590 | mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT) | 2578 | mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT) |
2591 | return RX_DROP_UNUSABLE; | 2579 | return RX_DROP_UNUSABLE; |
2592 | 2580 | ||
2593 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
2594 | return RX_DROP_UNUSABLE; | ||
2595 | |||
2596 | switch (mgmt->u.action.category) { | 2581 | switch (mgmt->u.action.category) { |
2597 | case WLAN_CATEGORY_HT: | 2582 | case WLAN_CATEGORY_HT: |
2598 | /* reject HT action frames from stations not supporting HT */ | 2583 | /* reject HT action frames from stations not supporting HT */ |
@@ -3076,8 +3061,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
3076 | } | 3061 | } |
3077 | 3062 | ||
3078 | prev_dev = sdata->dev; | 3063 | prev_dev = sdata->dev; |
3079 | sdata->dev->stats.rx_packets++; | 3064 | ieee80211_rx_stats(sdata->dev, skb->len); |
3080 | sdata->dev->stats.rx_bytes += skb->len; | ||
3081 | } | 3065 | } |
3082 | 3066 | ||
3083 | if (prev_dev) { | 3067 | if (prev_dev) { |
@@ -3245,16 +3229,25 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
3245 | ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx, &frames); | 3229 | ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx, &frames); |
3246 | spin_unlock(&tid_agg_rx->reorder_lock); | 3230 | spin_unlock(&tid_agg_rx->reorder_lock); |
3247 | 3231 | ||
3232 | if (!skb_queue_empty(&frames)) { | ||
3233 | struct ieee80211_event event = { | ||
3234 | .type = BA_FRAME_TIMEOUT, | ||
3235 | .u.ba.tid = tid, | ||
3236 | .u.ba.sta = &sta->sta, | ||
3237 | }; | ||
3238 | drv_event_callback(rx.local, rx.sdata, &event); | ||
3239 | } | ||
3240 | |||
3248 | ieee80211_rx_handlers(&rx, &frames); | 3241 | ieee80211_rx_handlers(&rx, &frames); |
3249 | } | 3242 | } |
3250 | 3243 | ||
3251 | /* main receive path */ | 3244 | /* main receive path */ |
3252 | 3245 | ||
3253 | static bool prepare_for_handlers(struct ieee80211_rx_data *rx, | 3246 | static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx) |
3254 | struct ieee80211_hdr *hdr) | ||
3255 | { | 3247 | { |
3256 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 3248 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
3257 | struct sk_buff *skb = rx->skb; | 3249 | struct sk_buff *skb = rx->skb; |
3250 | struct ieee80211_hdr *hdr = (void *)skb->data; | ||
3258 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 3251 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
3259 | u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); | 3252 | u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); |
3260 | int multicast = is_multicast_ether_addr(hdr->addr1); | 3253 | int multicast = is_multicast_ether_addr(hdr->addr1); |
@@ -3263,30 +3256,23 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3263 | case NL80211_IFTYPE_STATION: | 3256 | case NL80211_IFTYPE_STATION: |
3264 | if (!bssid && !sdata->u.mgd.use_4addr) | 3257 | if (!bssid && !sdata->u.mgd.use_4addr) |
3265 | return false; | 3258 | return false; |
3266 | if (!multicast && | 3259 | if (multicast) |
3267 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { | 3260 | return true; |
3268 | if (!(sdata->dev->flags & IFF_PROMISC) || | 3261 | return ether_addr_equal(sdata->vif.addr, hdr->addr1); |
3269 | sdata->u.mgd.use_4addr) | ||
3270 | return false; | ||
3271 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | ||
3272 | } | ||
3273 | break; | ||
3274 | case NL80211_IFTYPE_ADHOC: | 3262 | case NL80211_IFTYPE_ADHOC: |
3275 | if (!bssid) | 3263 | if (!bssid) |
3276 | return false; | 3264 | return false; |
3277 | if (ether_addr_equal(sdata->vif.addr, hdr->addr2) || | 3265 | if (ether_addr_equal(sdata->vif.addr, hdr->addr2) || |
3278 | ether_addr_equal(sdata->u.ibss.bssid, hdr->addr2)) | 3266 | ether_addr_equal(sdata->u.ibss.bssid, hdr->addr2)) |
3279 | return false; | 3267 | return false; |
3280 | if (ieee80211_is_beacon(hdr->frame_control)) { | 3268 | if (ieee80211_is_beacon(hdr->frame_control)) |
3281 | return true; | 3269 | return true; |
3282 | } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 3270 | if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) |
3283 | return false; | 3271 | return false; |
3284 | } else if (!multicast && | 3272 | if (!multicast && |
3285 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { | 3273 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) |
3286 | if (!(sdata->dev->flags & IFF_PROMISC)) | 3274 | return false; |
3287 | return false; | 3275 | if (!rx->sta) { |
3288 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | ||
3289 | } else if (!rx->sta) { | ||
3290 | int rate_idx; | 3276 | int rate_idx; |
3291 | if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) | 3277 | if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) |
3292 | rate_idx = 0; /* TODO: HT/VHT rates */ | 3278 | rate_idx = 0; /* TODO: HT/VHT rates */ |
@@ -3295,25 +3281,18 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3295 | ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2, | 3281 | ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2, |
3296 | BIT(rate_idx)); | 3282 | BIT(rate_idx)); |
3297 | } | 3283 | } |
3298 | break; | 3284 | return true; |
3299 | case NL80211_IFTYPE_OCB: | 3285 | case NL80211_IFTYPE_OCB: |
3300 | if (!bssid) | 3286 | if (!bssid) |
3301 | return false; | 3287 | return false; |
3302 | if (ieee80211_is_beacon(hdr->frame_control)) { | 3288 | if (ieee80211_is_beacon(hdr->frame_control)) |
3303 | return false; | 3289 | return false; |
3304 | } else if (!is_broadcast_ether_addr(bssid)) { | 3290 | if (!is_broadcast_ether_addr(bssid)) |
3305 | ocb_dbg(sdata, "BSSID mismatch in OCB mode!\n"); | ||
3306 | return false; | 3291 | return false; |
3307 | } else if (!multicast && | 3292 | if (!multicast && |
3308 | !ether_addr_equal(sdata->dev->dev_addr, | 3293 | !ether_addr_equal(sdata->dev->dev_addr, hdr->addr1)) |
3309 | hdr->addr1)) { | 3294 | return false; |
3310 | /* if we are in promisc mode we also accept | 3295 | if (!rx->sta) { |
3311 | * packets not destined for us | ||
3312 | */ | ||
3313 | if (!(sdata->dev->flags & IFF_PROMISC)) | ||
3314 | return false; | ||
3315 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | ||
3316 | } else if (!rx->sta) { | ||
3317 | int rate_idx; | 3296 | int rate_idx; |
3318 | if (status->flag & RX_FLAG_HT) | 3297 | if (status->flag & RX_FLAG_HT) |
3319 | rate_idx = 0; /* TODO: HT rates */ | 3298 | rate_idx = 0; /* TODO: HT rates */ |
@@ -3322,22 +3301,17 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3322 | ieee80211_ocb_rx_no_sta(sdata, bssid, hdr->addr2, | 3301 | ieee80211_ocb_rx_no_sta(sdata, bssid, hdr->addr2, |
3323 | BIT(rate_idx)); | 3302 | BIT(rate_idx)); |
3324 | } | 3303 | } |
3325 | break; | 3304 | return true; |
3326 | case NL80211_IFTYPE_MESH_POINT: | 3305 | case NL80211_IFTYPE_MESH_POINT: |
3327 | if (!multicast && | 3306 | if (multicast) |
3328 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { | 3307 | return true; |
3329 | if (!(sdata->dev->flags & IFF_PROMISC)) | 3308 | return ether_addr_equal(sdata->vif.addr, hdr->addr1); |
3330 | return false; | ||
3331 | |||
3332 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | ||
3333 | } | ||
3334 | break; | ||
3335 | case NL80211_IFTYPE_AP_VLAN: | 3309 | case NL80211_IFTYPE_AP_VLAN: |
3336 | case NL80211_IFTYPE_AP: | 3310 | case NL80211_IFTYPE_AP: |
3337 | if (!bssid) { | 3311 | if (!bssid) |
3338 | if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) | 3312 | return ether_addr_equal(sdata->vif.addr, hdr->addr1); |
3339 | return false; | 3313 | |
3340 | } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { | 3314 | if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { |
3341 | /* | 3315 | /* |
3342 | * Accept public action frames even when the | 3316 | * Accept public action frames even when the |
3343 | * BSSID doesn't match, this is used for P2P | 3317 | * BSSID doesn't match, this is used for P2P |
@@ -3349,10 +3323,10 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3349 | return false; | 3323 | return false; |
3350 | if (ieee80211_is_public_action(hdr, skb->len)) | 3324 | if (ieee80211_is_public_action(hdr, skb->len)) |
3351 | return true; | 3325 | return true; |
3352 | if (!ieee80211_is_beacon(hdr->frame_control)) | 3326 | return ieee80211_is_beacon(hdr->frame_control); |
3353 | return false; | 3327 | } |
3354 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 3328 | |
3355 | } else if (!ieee80211_has_tods(hdr->frame_control)) { | 3329 | if (!ieee80211_has_tods(hdr->frame_control)) { |
3356 | /* ignore data frames to TDLS-peers */ | 3330 | /* ignore data frames to TDLS-peers */ |
3357 | if (ieee80211_is_data(hdr->frame_control)) | 3331 | if (ieee80211_is_data(hdr->frame_control)) |
3358 | return false; | 3332 | return false; |
@@ -3361,30 +3335,22 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3361 | !ether_addr_equal(bssid, hdr->addr1)) | 3335 | !ether_addr_equal(bssid, hdr->addr1)) |
3362 | return false; | 3336 | return false; |
3363 | } | 3337 | } |
3364 | break; | 3338 | return true; |
3365 | case NL80211_IFTYPE_WDS: | 3339 | case NL80211_IFTYPE_WDS: |
3366 | if (bssid || !ieee80211_is_data(hdr->frame_control)) | 3340 | if (bssid || !ieee80211_is_data(hdr->frame_control)) |
3367 | return false; | 3341 | return false; |
3368 | if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) | 3342 | return ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2); |
3369 | return false; | ||
3370 | break; | ||
3371 | case NL80211_IFTYPE_P2P_DEVICE: | 3343 | case NL80211_IFTYPE_P2P_DEVICE: |
3372 | if (!ieee80211_is_public_action(hdr, skb->len) && | 3344 | return ieee80211_is_public_action(hdr, skb->len) || |
3373 | !ieee80211_is_probe_req(hdr->frame_control) && | 3345 | ieee80211_is_probe_req(hdr->frame_control) || |
3374 | !ieee80211_is_probe_resp(hdr->frame_control) && | 3346 | ieee80211_is_probe_resp(hdr->frame_control) || |
3375 | !ieee80211_is_beacon(hdr->frame_control)) | 3347 | ieee80211_is_beacon(hdr->frame_control); |
3376 | return false; | ||
3377 | if (!ether_addr_equal(sdata->vif.addr, hdr->addr1) && | ||
3378 | !multicast) | ||
3379 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | ||
3380 | break; | ||
3381 | default: | 3348 | default: |
3382 | /* should never get here */ | ||
3383 | WARN_ON_ONCE(1); | ||
3384 | break; | 3349 | break; |
3385 | } | 3350 | } |
3386 | 3351 | ||
3387 | return true; | 3352 | WARN_ON_ONCE(1); |
3353 | return false; | ||
3388 | } | 3354 | } |
3389 | 3355 | ||
3390 | /* | 3356 | /* |
@@ -3398,13 +3364,10 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | |||
3398 | { | 3364 | { |
3399 | struct ieee80211_local *local = rx->local; | 3365 | struct ieee80211_local *local = rx->local; |
3400 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 3366 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
3401 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
3402 | struct ieee80211_hdr *hdr = (void *)skb->data; | ||
3403 | 3367 | ||
3404 | rx->skb = skb; | 3368 | rx->skb = skb; |
3405 | status->rx_flags |= IEEE80211_RX_RA_MATCH; | ||
3406 | 3369 | ||
3407 | if (!prepare_for_handlers(rx, hdr)) | 3370 | if (!ieee80211_accept_frame(rx)) |
3408 | return false; | 3371 | return false; |
3409 | 3372 | ||
3410 | if (!consume) { | 3373 | if (!consume) { |
@@ -3447,7 +3410,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
3447 | rx.local = local; | 3410 | rx.local = local; |
3448 | 3411 | ||
3449 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) | 3412 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) |
3450 | local->dot11ReceivedFragmentCount++; | 3413 | I802_DEBUG_INC(local->dot11ReceivedFragmentCount); |
3451 | 3414 | ||
3452 | if (ieee80211_is_mgmt(fc)) { | 3415 | if (ieee80211_is_mgmt(fc)) { |
3453 | /* drop frame if too short for header */ | 3416 | /* drop frame if too short for header */ |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 12971b71d0fa..aec15d746aea 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -70,6 +70,7 @@ static const struct rhashtable_params sta_rht_params = { | |||
70 | .key_offset = offsetof(struct sta_info, sta.addr), | 70 | .key_offset = offsetof(struct sta_info, sta.addr), |
71 | .key_len = ETH_ALEN, | 71 | .key_len = ETH_ALEN, |
72 | .hashfn = sta_addr_hash, | 72 | .hashfn = sta_addr_hash, |
73 | .max_size = CONFIG_MAC80211_STA_HASH_MAX_SIZE, | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | /* Caller must hold local->sta_mtx */ | 76 | /* Caller must hold local->sta_mtx */ |
@@ -269,7 +270,7 @@ static int sta_prepare_rate_control(struct ieee80211_local *local, | |||
269 | 270 | ||
270 | sta->rate_ctrl = local->rate_ctrl; | 271 | sta->rate_ctrl = local->rate_ctrl; |
271 | sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, | 272 | sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, |
272 | &sta->sta, gfp); | 273 | sta, gfp); |
273 | if (!sta->rate_ctrl_priv) | 274 | if (!sta->rate_ctrl_priv) |
274 | return -ENOMEM; | 275 | return -ENOMEM; |
275 | 276 | ||
@@ -295,6 +296,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
295 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); | 296 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); |
296 | mutex_init(&sta->ampdu_mlme.mtx); | 297 | mutex_init(&sta->ampdu_mlme.mtx); |
297 | #ifdef CONFIG_MAC80211_MESH | 298 | #ifdef CONFIG_MAC80211_MESH |
299 | spin_lock_init(&sta->plink_lock); | ||
298 | if (ieee80211_vif_is_mesh(&sdata->vif) && | 300 | if (ieee80211_vif_is_mesh(&sdata->vif) && |
299 | !sdata->u.mesh.user_mpm) | 301 | !sdata->u.mesh.user_mpm) |
300 | init_timer(&sta->plink_timer); | 302 | init_timer(&sta->plink_timer); |
@@ -1200,6 +1202,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1200 | ps_dbg(sdata, | 1202 | ps_dbg(sdata, |
1201 | "STA %pM aid %d sending %d filtered/%d PS frames since STA not sleeping anymore\n", | 1203 | "STA %pM aid %d sending %d filtered/%d PS frames since STA not sleeping anymore\n", |
1202 | sta->sta.addr, sta->sta.aid, filtered, buffered); | 1204 | sta->sta.addr, sta->sta.aid, filtered, buffered); |
1205 | |||
1206 | ieee80211_check_fast_xmit(sta); | ||
1203 | } | 1207 | } |
1204 | 1208 | ||
1205 | static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | 1209 | static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, |
@@ -1598,6 +1602,7 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | |||
1598 | 1602 | ||
1599 | if (block) { | 1603 | if (block) { |
1600 | set_sta_flag(sta, WLAN_STA_PS_DRIVER); | 1604 | set_sta_flag(sta, WLAN_STA_PS_DRIVER); |
1605 | ieee80211_clear_fast_xmit(sta); | ||
1601 | return; | 1606 | return; |
1602 | } | 1607 | } |
1603 | 1608 | ||
@@ -1615,6 +1620,7 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | |||
1615 | ieee80211_queue_work(hw, &sta->drv_deliver_wk); | 1620 | ieee80211_queue_work(hw, &sta->drv_deliver_wk); |
1616 | } else { | 1621 | } else { |
1617 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | 1622 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); |
1623 | ieee80211_check_fast_xmit(sta); | ||
1618 | } | 1624 | } |
1619 | } | 1625 | } |
1620 | EXPORT_SYMBOL(ieee80211_sta_block_awake); | 1626 | EXPORT_SYMBOL(ieee80211_sta_block_awake); |
@@ -1719,6 +1725,7 @@ int sta_info_move_state(struct sta_info *sta, | |||
1719 | !sta->sdata->u.vlan.sta)) | 1725 | !sta->sdata->u.vlan.sta)) |
1720 | atomic_dec(&sta->sdata->bss->num_mcast_sta); | 1726 | atomic_dec(&sta->sdata->bss->num_mcast_sta); |
1721 | clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags); | 1727 | clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags); |
1728 | ieee80211_clear_fast_xmit(sta); | ||
1722 | } | 1729 | } |
1723 | break; | 1730 | break; |
1724 | case IEEE80211_STA_AUTHORIZED: | 1731 | case IEEE80211_STA_AUTHORIZED: |
@@ -1728,6 +1735,7 @@ int sta_info_move_state(struct sta_info *sta, | |||
1728 | !sta->sdata->u.vlan.sta)) | 1735 | !sta->sdata->u.vlan.sta)) |
1729 | atomic_inc(&sta->sdata->bss->num_mcast_sta); | 1736 | atomic_inc(&sta->sdata->bss->num_mcast_sta); |
1730 | set_bit(WLAN_STA_AUTHORIZED, &sta->_flags); | 1737 | set_bit(WLAN_STA_AUTHORIZED, &sta->_flags); |
1738 | ieee80211_check_fast_xmit(sta); | ||
1731 | } | 1739 | } |
1732 | break; | 1740 | break; |
1733 | default: | 1741 | default: |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 5c164fb3f6c5..9bd1e97876bd 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -241,6 +241,34 @@ struct sta_ampdu_mlme { | |||
241 | /* Value to indicate no TID reservation */ | 241 | /* Value to indicate no TID reservation */ |
242 | #define IEEE80211_TID_UNRESERVED 0xff | 242 | #define IEEE80211_TID_UNRESERVED 0xff |
243 | 243 | ||
244 | #define IEEE80211_FAST_XMIT_MAX_IV 18 | ||
245 | |||
246 | /** | ||
247 | * struct ieee80211_fast_tx - TX fastpath information | ||
248 | * @key: key to use for hw crypto | ||
249 | * @hdr: the 802.11 header to put with the frame | ||
250 | * @hdr_len: actual 802.11 header length | ||
251 | * @sa_offs: offset of the SA | ||
252 | * @da_offs: offset of the DA | ||
253 | * @pn_offs: offset where to put PN for crypto (or 0 if not needed) | ||
254 | * @band: band this will be transmitted on, for tx_info | ||
255 | * @rcu_head: RCU head to free this struct | ||
256 | * | ||
257 | * This struct is small enough so that the common case (maximum crypto | ||
258 | * header length of 8 like for CCMP/GCMP) fits into a single 64-byte | ||
259 | * cache line. | ||
260 | */ | ||
261 | struct ieee80211_fast_tx { | ||
262 | struct ieee80211_key *key; | ||
263 | u8 hdr_len; | ||
264 | u8 sa_offs, da_offs, pn_offs; | ||
265 | u8 band; | ||
266 | u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV + | ||
267 | sizeof(rfc1042_header)]; | ||
268 | |||
269 | struct rcu_head rcu_head; | ||
270 | }; | ||
271 | |||
244 | /** | 272 | /** |
245 | * struct sta_info - STA information | 273 | * struct sta_info - STA information |
246 | * | 274 | * |
@@ -257,6 +285,8 @@ struct sta_ampdu_mlme { | |||
257 | * @gtk: group keys negotiated with this station, if any | 285 | * @gtk: group keys negotiated with this station, if any |
258 | * @gtk_idx: last installed group key index | 286 | * @gtk_idx: last installed group key index |
259 | * @rate_ctrl: rate control algorithm reference | 287 | * @rate_ctrl: rate control algorithm reference |
288 | * @rate_ctrl_lock: spinlock used to protect rate control data | ||
289 | * (data inside the algorithm, so serializes calls there) | ||
260 | * @rate_ctrl_priv: rate control private per-STA pointer | 290 | * @rate_ctrl_priv: rate control private per-STA pointer |
261 | * @last_tx_rate: rate used for last transmit, to report to userspace as | 291 | * @last_tx_rate: rate used for last transmit, to report to userspace as |
262 | * "the" transmit rate | 292 | * "the" transmit rate |
@@ -295,10 +325,10 @@ struct sta_ampdu_mlme { | |||
295 | * @fail_avg: moving percentage of failed MSDUs | 325 | * @fail_avg: moving percentage of failed MSDUs |
296 | * @tx_packets: number of RX/TX MSDUs | 326 | * @tx_packets: number of RX/TX MSDUs |
297 | * @tx_bytes: number of bytes transmitted to this STA | 327 | * @tx_bytes: number of bytes transmitted to this STA |
298 | * @tx_fragments: number of transmitted MPDUs | ||
299 | * @tid_seq: per-TID sequence numbers for sending to this STA | 328 | * @tid_seq: per-TID sequence numbers for sending to this STA |
300 | * @ampdu_mlme: A-MPDU state machine state | 329 | * @ampdu_mlme: A-MPDU state machine state |
301 | * @timer_to_tid: identity mapping to ID timers | 330 | * @timer_to_tid: identity mapping to ID timers |
331 | * @plink_lock: serialize access to plink fields | ||
302 | * @llid: Local link ID | 332 | * @llid: Local link ID |
303 | * @plid: Peer link ID | 333 | * @plid: Peer link ID |
304 | * @reason: Cancel reason on PLINK_HOLDING state | 334 | * @reason: Cancel reason on PLINK_HOLDING state |
@@ -338,6 +368,7 @@ struct sta_ampdu_mlme { | |||
338 | * using IEEE80211_NUM_TID entry for non-QoS frames | 368 | * using IEEE80211_NUM_TID entry for non-QoS frames |
339 | * @rx_msdu: MSDUs received from this station, using IEEE80211_NUM_TID | 369 | * @rx_msdu: MSDUs received from this station, using IEEE80211_NUM_TID |
340 | * entry for non-QoS frames | 370 | * entry for non-QoS frames |
371 | * @fast_tx: TX fastpath information | ||
341 | */ | 372 | */ |
342 | struct sta_info { | 373 | struct sta_info { |
343 | /* General information, mostly static */ | 374 | /* General information, mostly static */ |
@@ -352,8 +383,11 @@ struct sta_info { | |||
352 | u8 ptk_idx; | 383 | u8 ptk_idx; |
353 | struct rate_control_ref *rate_ctrl; | 384 | struct rate_control_ref *rate_ctrl; |
354 | void *rate_ctrl_priv; | 385 | void *rate_ctrl_priv; |
386 | spinlock_t rate_ctrl_lock; | ||
355 | spinlock_t lock; | 387 | spinlock_t lock; |
356 | 388 | ||
389 | struct ieee80211_fast_tx __rcu *fast_tx; | ||
390 | |||
357 | struct work_struct drv_deliver_wk; | 391 | struct work_struct drv_deliver_wk; |
358 | 392 | ||
359 | u16 listen_interval; | 393 | u16 listen_interval; |
@@ -400,7 +434,6 @@ struct sta_info { | |||
400 | unsigned int fail_avg; | 434 | unsigned int fail_avg; |
401 | 435 | ||
402 | /* Updated from TX path only, no locking requirements */ | 436 | /* Updated from TX path only, no locking requirements */ |
403 | u32 tx_fragments; | ||
404 | u64 tx_packets[IEEE80211_NUM_ACS]; | 437 | u64 tx_packets[IEEE80211_NUM_ACS]; |
405 | u64 tx_bytes[IEEE80211_NUM_ACS]; | 438 | u64 tx_bytes[IEEE80211_NUM_ACS]; |
406 | struct ieee80211_tx_rate last_tx_rate; | 439 | struct ieee80211_tx_rate last_tx_rate; |
@@ -422,9 +455,10 @@ struct sta_info { | |||
422 | 455 | ||
423 | #ifdef CONFIG_MAC80211_MESH | 456 | #ifdef CONFIG_MAC80211_MESH |
424 | /* | 457 | /* |
425 | * Mesh peer link attributes | 458 | * Mesh peer link attributes, protected by plink_lock. |
426 | * TODO: move to a sub-structure that is referenced with pointer? | 459 | * TODO: move to a sub-structure that is referenced with pointer? |
427 | */ | 460 | */ |
461 | spinlock_t plink_lock; | ||
428 | u16 llid; | 462 | u16 llid; |
429 | u16 plid; | 463 | u16 plid; |
430 | u16 reason; | 464 | u16 reason; |
@@ -432,6 +466,7 @@ struct sta_info { | |||
432 | enum nl80211_plink_state plink_state; | 466 | enum nl80211_plink_state plink_state; |
433 | u32 plink_timeout; | 467 | u32 plink_timeout; |
434 | struct timer_list plink_timer; | 468 | struct timer_list plink_timer; |
469 | |||
435 | s64 t_offset; | 470 | s64 t_offset; |
436 | s64 t_offset_setpoint; | 471 | s64 t_offset_setpoint; |
437 | /* mesh power save */ | 472 | /* mesh power save */ |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 005fdbe39a8b..461594966b65 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -631,15 +631,15 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, | |||
631 | } | 631 | } |
632 | 632 | ||
633 | if (acked || noack_success) { | 633 | if (acked || noack_success) { |
634 | local->dot11TransmittedFrameCount++; | 634 | I802_DEBUG_INC(local->dot11TransmittedFrameCount); |
635 | if (!pubsta) | 635 | if (!pubsta) |
636 | local->dot11MulticastTransmittedFrameCount++; | 636 | I802_DEBUG_INC(local->dot11MulticastTransmittedFrameCount); |
637 | if (retry_count > 0) | 637 | if (retry_count > 0) |
638 | local->dot11RetryCount++; | 638 | I802_DEBUG_INC(local->dot11RetryCount); |
639 | if (retry_count > 1) | 639 | if (retry_count > 1) |
640 | local->dot11MultipleRetryCount++; | 640 | I802_DEBUG_INC(local->dot11MultipleRetryCount); |
641 | } else { | 641 | } else { |
642 | local->dot11FailedCount++; | 642 | I802_DEBUG_INC(local->dot11FailedCount); |
643 | } | 643 | } |
644 | } | 644 | } |
645 | EXPORT_SYMBOL(ieee80211_tx_status_noskb); | 645 | EXPORT_SYMBOL(ieee80211_tx_status_noskb); |
@@ -802,13 +802,13 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
802 | if ((info->flags & IEEE80211_TX_STAT_ACK) || | 802 | if ((info->flags & IEEE80211_TX_STAT_ACK) || |
803 | (info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED)) { | 803 | (info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED)) { |
804 | if (ieee80211_is_first_frag(hdr->seq_ctrl)) { | 804 | if (ieee80211_is_first_frag(hdr->seq_ctrl)) { |
805 | local->dot11TransmittedFrameCount++; | 805 | I802_DEBUG_INC(local->dot11TransmittedFrameCount); |
806 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr))) | 806 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr))) |
807 | local->dot11MulticastTransmittedFrameCount++; | 807 | I802_DEBUG_INC(local->dot11MulticastTransmittedFrameCount); |
808 | if (retry_count > 0) | 808 | if (retry_count > 0) |
809 | local->dot11RetryCount++; | 809 | I802_DEBUG_INC(local->dot11RetryCount); |
810 | if (retry_count > 1) | 810 | if (retry_count > 1) |
811 | local->dot11MultipleRetryCount++; | 811 | I802_DEBUG_INC(local->dot11MultipleRetryCount); |
812 | } | 812 | } |
813 | 813 | ||
814 | /* This counter shall be incremented for an acknowledged MPDU | 814 | /* This counter shall be incremented for an acknowledged MPDU |
@@ -818,10 +818,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
818 | if (!is_multicast_ether_addr(hdr->addr1) || | 818 | if (!is_multicast_ether_addr(hdr->addr1) || |
819 | ieee80211_is_data(fc) || | 819 | ieee80211_is_data(fc) || |
820 | ieee80211_is_mgmt(fc)) | 820 | ieee80211_is_mgmt(fc)) |
821 | local->dot11TransmittedFragmentCount++; | 821 | I802_DEBUG_INC(local->dot11TransmittedFragmentCount); |
822 | } else { | 822 | } else { |
823 | if (ieee80211_is_first_frag(hdr->seq_ctrl)) | 823 | if (ieee80211_is_first_frag(hdr->seq_ctrl)) |
824 | local->dot11FailedCount++; | 824 | I802_DEBUG_INC(local->dot11FailedCount); |
825 | } | 825 | } |
826 | 826 | ||
827 | if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc) && | 827 | if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc) && |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 4c2e7690226a..6f14591d8ca9 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -69,6 +69,17 @@ | |||
69 | #define CHANCTX_PR_ARG CHANDEF_PR_ARG, MIN_CHANDEF_PR_ARG, \ | 69 | #define CHANCTX_PR_ARG CHANDEF_PR_ARG, MIN_CHANDEF_PR_ARG, \ |
70 | __entry->rx_chains_static, __entry->rx_chains_dynamic | 70 | __entry->rx_chains_static, __entry->rx_chains_dynamic |
71 | 71 | ||
72 | #define KEY_ENTRY __field(u32, cipher) \ | ||
73 | __field(u8, hw_key_idx) \ | ||
74 | __field(u8, flags) \ | ||
75 | __field(s8, keyidx) | ||
76 | #define KEY_ASSIGN(k) __entry->cipher = (k)->cipher; \ | ||
77 | __entry->flags = (k)->flags; \ | ||
78 | __entry->keyidx = (k)->keyidx; \ | ||
79 | __entry->hw_key_idx = (k)->hw_key_idx; | ||
80 | #define KEY_PR_FMT " cipher:0x%x, flags=%#x, keyidx=%d, hw_key_idx=%d" | ||
81 | #define KEY_PR_ARG __entry->cipher, __entry->flags, __entry->keyidx, __entry->hw_key_idx | ||
82 | |||
72 | 83 | ||
73 | 84 | ||
74 | /* | 85 | /* |
@@ -522,25 +533,19 @@ TRACE_EVENT(drv_set_key, | |||
522 | LOCAL_ENTRY | 533 | LOCAL_ENTRY |
523 | VIF_ENTRY | 534 | VIF_ENTRY |
524 | STA_ENTRY | 535 | STA_ENTRY |
525 | __field(u32, cipher) | 536 | KEY_ENTRY |
526 | __field(u8, hw_key_idx) | ||
527 | __field(u8, flags) | ||
528 | __field(s8, keyidx) | ||
529 | ), | 537 | ), |
530 | 538 | ||
531 | TP_fast_assign( | 539 | TP_fast_assign( |
532 | LOCAL_ASSIGN; | 540 | LOCAL_ASSIGN; |
533 | VIF_ASSIGN; | 541 | VIF_ASSIGN; |
534 | STA_ASSIGN; | 542 | STA_ASSIGN; |
535 | __entry->cipher = key->cipher; | 543 | KEY_ASSIGN(key); |
536 | __entry->flags = key->flags; | ||
537 | __entry->keyidx = key->keyidx; | ||
538 | __entry->hw_key_idx = key->hw_key_idx; | ||
539 | ), | 544 | ), |
540 | 545 | ||
541 | TP_printk( | 546 | TP_printk( |
542 | LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT, | 547 | LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT KEY_PR_FMT, |
543 | LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG | 548 | LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, KEY_PR_ARG |
544 | ) | 549 | ) |
545 | ); | 550 | ); |
546 | 551 | ||
@@ -656,28 +661,25 @@ TRACE_EVENT(drv_get_stats, | |||
656 | ) | 661 | ) |
657 | ); | 662 | ); |
658 | 663 | ||
659 | TRACE_EVENT(drv_get_tkip_seq, | 664 | TRACE_EVENT(drv_get_key_seq, |
660 | TP_PROTO(struct ieee80211_local *local, | 665 | TP_PROTO(struct ieee80211_local *local, |
661 | u8 hw_key_idx, u32 *iv32, u16 *iv16), | 666 | struct ieee80211_key_conf *key), |
662 | 667 | ||
663 | TP_ARGS(local, hw_key_idx, iv32, iv16), | 668 | TP_ARGS(local, key), |
664 | 669 | ||
665 | TP_STRUCT__entry( | 670 | TP_STRUCT__entry( |
666 | LOCAL_ENTRY | 671 | LOCAL_ENTRY |
667 | __field(u8, hw_key_idx) | 672 | KEY_ENTRY |
668 | __field(u32, iv32) | ||
669 | __field(u16, iv16) | ||
670 | ), | 673 | ), |
671 | 674 | ||
672 | TP_fast_assign( | 675 | TP_fast_assign( |
673 | LOCAL_ASSIGN; | 676 | LOCAL_ASSIGN; |
674 | __entry->hw_key_idx = hw_key_idx; | 677 | KEY_ASSIGN(key); |
675 | __entry->iv32 = *iv32; | ||
676 | __entry->iv16 = *iv16; | ||
677 | ), | 678 | ), |
678 | 679 | ||
679 | TP_printk( | 680 | TP_printk( |
680 | LOCAL_PR_FMT, LOCAL_PR_ARG | 681 | LOCAL_PR_FMT KEY_PR_FMT, |
682 | LOCAL_PR_ARG, KEY_PR_ARG | ||
681 | ) | 683 | ) |
682 | ); | 684 | ); |
683 | 685 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 667111ee6a20..8df134213adf 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -37,6 +37,16 @@ | |||
37 | 37 | ||
38 | /* misc utils */ | 38 | /* misc utils */ |
39 | 39 | ||
40 | static inline void ieee80211_tx_stats(struct net_device *dev, u32 len) | ||
41 | { | ||
42 | struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); | ||
43 | |||
44 | u64_stats_update_begin(&tstats->syncp); | ||
45 | tstats->tx_packets++; | ||
46 | tstats->tx_bytes += len; | ||
47 | u64_stats_update_end(&tstats->syncp); | ||
48 | } | ||
49 | |||
40 | static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, | 50 | static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, |
41 | struct sk_buff *skb, int group_addr, | 51 | struct sk_buff *skb, int group_addr, |
42 | int next_frag_len) | 52 | int next_frag_len) |
@@ -987,7 +997,6 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) | |||
987 | 997 | ||
988 | skb_queue_walk(&tx->skbs, skb) { | 998 | skb_queue_walk(&tx->skbs, skb) { |
989 | ac = skb_get_queue_mapping(skb); | 999 | ac = skb_get_queue_mapping(skb); |
990 | tx->sta->tx_fragments++; | ||
991 | tx->sta->tx_bytes[ac] += skb->len; | 1000 | tx->sta->tx_bytes[ac] += skb->len; |
992 | } | 1001 | } |
993 | if (ac >= 0) | 1002 | if (ac >= 0) |
@@ -1600,7 +1609,7 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, | |||
1600 | if (skb_cloned(skb) && | 1609 | if (skb_cloned(skb) && |
1601 | (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CLONED_SKBS) || | 1610 | (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CLONED_SKBS) || |
1602 | !skb_clone_writable(skb, ETH_HLEN) || | 1611 | !skb_clone_writable(skb, ETH_HLEN) || |
1603 | sdata->crypto_tx_tailroom_needed_cnt)) | 1612 | (may_encrypt && sdata->crypto_tx_tailroom_needed_cnt))) |
1604 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); | 1613 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); |
1605 | else if (head_need || tail_need) | 1614 | else if (head_need || tail_need) |
1606 | I802_DEBUG_INC(local->tx_expand_skb_head); | 1615 | I802_DEBUG_INC(local->tx_expand_skb_head); |
@@ -2387,12 +2396,460 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, | |||
2387 | return ERR_PTR(ret); | 2396 | return ERR_PTR(ret); |
2388 | } | 2397 | } |
2389 | 2398 | ||
2399 | /* | ||
2400 | * fast-xmit overview | ||
2401 | * | ||
2402 | * The core idea of this fast-xmit is to remove per-packet checks by checking | ||
2403 | * them out of band. ieee80211_check_fast_xmit() implements the out-of-band | ||
2404 | * checks that are needed to get the sta->fast_tx pointer assigned, after which | ||
2405 | * much less work can be done per packet. For example, fragmentation must be | ||
2406 | * disabled or the fast_tx pointer will not be set. All the conditions are seen | ||
2407 | * in the code here. | ||
2408 | * | ||
2409 | * Once assigned, the fast_tx data structure also caches the per-packet 802.11 | ||
2410 | * header and other data to aid packet processing in ieee80211_xmit_fast(). | ||
2411 | * | ||
2412 | * The most difficult part of this is that when any of these assumptions | ||
2413 | * change, an external trigger (i.e. a call to ieee80211_clear_fast_xmit(), | ||
2414 | * ieee80211_check_fast_xmit() or friends) is required to reset the data, | ||
2415 | * since the per-packet code no longer checks the conditions. This is reflected | ||
2416 | * by the calls to these functions throughout the rest of the code, and must be | ||
2417 | * maintained if any of the TX path checks change. | ||
2418 | */ | ||
2419 | |||
2420 | void ieee80211_check_fast_xmit(struct sta_info *sta) | ||
2421 | { | ||
2422 | struct ieee80211_fast_tx build = {}, *fast_tx = NULL, *old; | ||
2423 | struct ieee80211_local *local = sta->local; | ||
2424 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
2425 | struct ieee80211_hdr *hdr = (void *)build.hdr; | ||
2426 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
2427 | __le16 fc; | ||
2428 | |||
2429 | if (!(local->hw.flags & IEEE80211_HW_SUPPORT_FAST_XMIT)) | ||
2430 | return; | ||
2431 | |||
2432 | /* Locking here protects both the pointer itself, and against concurrent | ||
2433 | * invocations winning data access races to, e.g., the key pointer that | ||
2434 | * is used. | ||
2435 | * Without it, the invocation of this function right after the key | ||
2436 | * pointer changes wouldn't be sufficient, as another CPU could access | ||
2437 | * the pointer, then stall, and then do the cache update after the CPU | ||
2438 | * that invalidated the key. | ||
2439 | * With the locking, such scenarios cannot happen as the check for the | ||
2440 | * key and the fast-tx assignment are done atomically, so the CPU that | ||
2441 | * modifies the key will either wait or other one will see the key | ||
2442 | * cleared/changed already. | ||
2443 | */ | ||
2444 | spin_lock_bh(&sta->lock); | ||
2445 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_PS && | ||
2446 | !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) && | ||
2447 | sdata->vif.type == NL80211_IFTYPE_STATION) | ||
2448 | goto out; | ||
2449 | |||
2450 | if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | ||
2451 | goto out; | ||
2452 | |||
2453 | if (test_sta_flag(sta, WLAN_STA_PS_STA) || | ||
2454 | test_sta_flag(sta, WLAN_STA_PS_DRIVER) || | ||
2455 | test_sta_flag(sta, WLAN_STA_PS_DELIVER)) | ||
2456 | goto out; | ||
2457 | |||
2458 | if (sdata->noack_map) | ||
2459 | goto out; | ||
2460 | |||
2461 | /* fast-xmit doesn't handle fragmentation at all */ | ||
2462 | if (local->hw.wiphy->frag_threshold != (u32)-1 && | ||
2463 | !local->ops->set_frag_threshold) | ||
2464 | goto out; | ||
2465 | |||
2466 | rcu_read_lock(); | ||
2467 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
2468 | if (!chanctx_conf) { | ||
2469 | rcu_read_unlock(); | ||
2470 | goto out; | ||
2471 | } | ||
2472 | build.band = chanctx_conf->def.chan->band; | ||
2473 | rcu_read_unlock(); | ||
2474 | |||
2475 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); | ||
2476 | |||
2477 | switch (sdata->vif.type) { | ||
2478 | case NL80211_IFTYPE_ADHOC: | ||
2479 | /* DA SA BSSID */ | ||
2480 | build.da_offs = offsetof(struct ieee80211_hdr, addr1); | ||
2481 | build.sa_offs = offsetof(struct ieee80211_hdr, addr2); | ||
2482 | memcpy(hdr->addr3, sdata->u.ibss.bssid, ETH_ALEN); | ||
2483 | build.hdr_len = 24; | ||
2484 | break; | ||
2485 | case NL80211_IFTYPE_STATION: | ||
2486 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { | ||
2487 | /* DA SA BSSID */ | ||
2488 | build.da_offs = offsetof(struct ieee80211_hdr, addr1); | ||
2489 | build.sa_offs = offsetof(struct ieee80211_hdr, addr2); | ||
2490 | memcpy(hdr->addr3, sdata->u.mgd.bssid, ETH_ALEN); | ||
2491 | build.hdr_len = 24; | ||
2492 | break; | ||
2493 | } | ||
2494 | |||
2495 | if (sdata->u.mgd.use_4addr) { | ||
2496 | /* non-regular ethertype cannot use the fastpath */ | ||
2497 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | | ||
2498 | IEEE80211_FCTL_TODS); | ||
2499 | /* RA TA DA SA */ | ||
2500 | memcpy(hdr->addr1, sdata->u.mgd.bssid, ETH_ALEN); | ||
2501 | memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); | ||
2502 | build.da_offs = offsetof(struct ieee80211_hdr, addr3); | ||
2503 | build.sa_offs = offsetof(struct ieee80211_hdr, addr4); | ||
2504 | build.hdr_len = 30; | ||
2505 | break; | ||
2506 | } | ||
2507 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); | ||
2508 | /* BSSID SA DA */ | ||
2509 | memcpy(hdr->addr1, sdata->u.mgd.bssid, ETH_ALEN); | ||
2510 | build.da_offs = offsetof(struct ieee80211_hdr, addr3); | ||
2511 | build.sa_offs = offsetof(struct ieee80211_hdr, addr2); | ||
2512 | build.hdr_len = 24; | ||
2513 | break; | ||
2514 | case NL80211_IFTYPE_AP_VLAN: | ||
2515 | if (sdata->wdev.use_4addr) { | ||
2516 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | | ||
2517 | IEEE80211_FCTL_TODS); | ||
2518 | /* RA TA DA SA */ | ||
2519 | memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); | ||
2520 | memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); | ||
2521 | build.da_offs = offsetof(struct ieee80211_hdr, addr3); | ||
2522 | build.sa_offs = offsetof(struct ieee80211_hdr, addr4); | ||
2523 | build.hdr_len = 30; | ||
2524 | break; | ||
2525 | } | ||
2526 | /* fall through */ | ||
2527 | case NL80211_IFTYPE_AP: | ||
2528 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); | ||
2529 | /* DA BSSID SA */ | ||
2530 | build.da_offs = offsetof(struct ieee80211_hdr, addr1); | ||
2531 | memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); | ||
2532 | build.sa_offs = offsetof(struct ieee80211_hdr, addr3); | ||
2533 | build.hdr_len = 24; | ||
2534 | break; | ||
2535 | default: | ||
2536 | /* not handled on fast-xmit */ | ||
2537 | goto out; | ||
2538 | } | ||
2539 | |||
2540 | if (sta->sta.wme) { | ||
2541 | build.hdr_len += 2; | ||
2542 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | ||
2543 | } | ||
2544 | |||
2545 | /* We store the key here so there's no point in using rcu_dereference() | ||
2546 | * but that's fine because the code that changes the pointers will call | ||
2547 | * this function after doing so. For a single CPU that would be enough, | ||
2548 | * for multiple see the comment above. | ||
2549 | */ | ||
2550 | build.key = rcu_access_pointer(sta->ptk[sta->ptk_idx]); | ||
2551 | if (!build.key) | ||
2552 | build.key = rcu_access_pointer(sdata->default_unicast_key); | ||
2553 | if (build.key) { | ||
2554 | bool gen_iv, iv_spc, mmic; | ||
2555 | |||
2556 | gen_iv = build.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV; | ||
2557 | iv_spc = build.key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE; | ||
2558 | mmic = build.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
2559 | |||
2560 | /* don't handle software crypto */ | ||
2561 | if (!(build.key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | ||
2562 | goto out; | ||
2563 | |||
2564 | switch (build.key->conf.cipher) { | ||
2565 | case WLAN_CIPHER_SUITE_CCMP: | ||
2566 | case WLAN_CIPHER_SUITE_CCMP_256: | ||
2567 | /* add fixed key ID */ | ||
2568 | if (gen_iv) { | ||
2569 | (build.hdr + build.hdr_len)[3] = | ||
2570 | 0x20 | (build.key->conf.keyidx << 6); | ||
2571 | build.pn_offs = build.hdr_len; | ||
2572 | } | ||
2573 | if (gen_iv || iv_spc) | ||
2574 | build.hdr_len += IEEE80211_CCMP_HDR_LEN; | ||
2575 | break; | ||
2576 | case WLAN_CIPHER_SUITE_GCMP: | ||
2577 | case WLAN_CIPHER_SUITE_GCMP_256: | ||
2578 | /* add fixed key ID */ | ||
2579 | if (gen_iv) { | ||
2580 | (build.hdr + build.hdr_len)[3] = | ||
2581 | 0x20 | (build.key->conf.keyidx << 6); | ||
2582 | build.pn_offs = build.hdr_len; | ||
2583 | } | ||
2584 | if (gen_iv || iv_spc) | ||
2585 | build.hdr_len += IEEE80211_GCMP_HDR_LEN; | ||
2586 | break; | ||
2587 | case WLAN_CIPHER_SUITE_TKIP: | ||
2588 | /* cannot handle MMIC or IV generation in xmit-fast */ | ||
2589 | if (mmic || gen_iv) | ||
2590 | goto out; | ||
2591 | if (iv_spc) | ||
2592 | build.hdr_len += IEEE80211_TKIP_IV_LEN; | ||
2593 | break; | ||
2594 | case WLAN_CIPHER_SUITE_WEP40: | ||
2595 | case WLAN_CIPHER_SUITE_WEP104: | ||
2596 | /* cannot handle IV generation in fast-xmit */ | ||
2597 | if (gen_iv) | ||
2598 | goto out; | ||
2599 | if (iv_spc) | ||
2600 | build.hdr_len += IEEE80211_WEP_IV_LEN; | ||
2601 | break; | ||
2602 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
2603 | case WLAN_CIPHER_SUITE_BIP_CMAC_256: | ||
2604 | case WLAN_CIPHER_SUITE_BIP_GMAC_128: | ||
2605 | case WLAN_CIPHER_SUITE_BIP_GMAC_256: | ||
2606 | WARN(1, | ||
2607 | "management cipher suite 0x%x enabled for data\n", | ||
2608 | build.key->conf.cipher); | ||
2609 | goto out; | ||
2610 | default: | ||
2611 | /* we don't know how to generate IVs for this at all */ | ||
2612 | if (WARN_ON(gen_iv)) | ||
2613 | goto out; | ||
2614 | /* pure hardware keys are OK, of course */ | ||
2615 | if (!(build.key->flags & KEY_FLAG_CIPHER_SCHEME)) | ||
2616 | break; | ||
2617 | /* cipher scheme might require space allocation */ | ||
2618 | if (iv_spc && | ||
2619 | build.key->conf.iv_len > IEEE80211_FAST_XMIT_MAX_IV) | ||
2620 | goto out; | ||
2621 | if (iv_spc) | ||
2622 | build.hdr_len += build.key->conf.iv_len; | ||
2623 | } | ||
2624 | |||
2625 | fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); | ||
2626 | } | ||
2627 | |||
2628 | hdr->frame_control = fc; | ||
2629 | |||
2630 | memcpy(build.hdr + build.hdr_len, | ||
2631 | rfc1042_header, sizeof(rfc1042_header)); | ||
2632 | build.hdr_len += sizeof(rfc1042_header); | ||
2633 | |||
2634 | fast_tx = kmemdup(&build, sizeof(build), GFP_ATOMIC); | ||
2635 | /* if the kmemdup fails, continue w/o fast_tx */ | ||
2636 | if (!fast_tx) | ||
2637 | goto out; | ||
2638 | |||
2639 | out: | ||
2640 | /* we might have raced against another call to this function */ | ||
2641 | old = rcu_dereference_protected(sta->fast_tx, | ||
2642 | lockdep_is_held(&sta->lock)); | ||
2643 | rcu_assign_pointer(sta->fast_tx, fast_tx); | ||
2644 | if (old) | ||
2645 | kfree_rcu(old, rcu_head); | ||
2646 | spin_unlock_bh(&sta->lock); | ||
2647 | } | ||
2648 | |||
2649 | void ieee80211_check_fast_xmit_all(struct ieee80211_local *local) | ||
2650 | { | ||
2651 | struct sta_info *sta; | ||
2652 | |||
2653 | rcu_read_lock(); | ||
2654 | list_for_each_entry_rcu(sta, &local->sta_list, list) | ||
2655 | ieee80211_check_fast_xmit(sta); | ||
2656 | rcu_read_unlock(); | ||
2657 | } | ||
2658 | |||
2659 | void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata) | ||
2660 | { | ||
2661 | struct ieee80211_local *local = sdata->local; | ||
2662 | struct sta_info *sta; | ||
2663 | |||
2664 | rcu_read_lock(); | ||
2665 | |||
2666 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | ||
2667 | if (sdata != sta->sdata && | ||
2668 | (!sta->sdata->bss || sta->sdata->bss != sdata->bss)) | ||
2669 | continue; | ||
2670 | ieee80211_check_fast_xmit(sta); | ||
2671 | } | ||
2672 | |||
2673 | rcu_read_unlock(); | ||
2674 | } | ||
2675 | |||
2676 | void ieee80211_clear_fast_xmit(struct sta_info *sta) | ||
2677 | { | ||
2678 | struct ieee80211_fast_tx *fast_tx; | ||
2679 | |||
2680 | spin_lock_bh(&sta->lock); | ||
2681 | fast_tx = rcu_dereference_protected(sta->fast_tx, | ||
2682 | lockdep_is_held(&sta->lock)); | ||
2683 | RCU_INIT_POINTER(sta->fast_tx, NULL); | ||
2684 | spin_unlock_bh(&sta->lock); | ||
2685 | |||
2686 | if (fast_tx) | ||
2687 | kfree_rcu(fast_tx, rcu_head); | ||
2688 | } | ||
2689 | |||
2690 | static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, | ||
2691 | struct net_device *dev, struct sta_info *sta, | ||
2692 | struct ieee80211_fast_tx *fast_tx, | ||
2693 | struct sk_buff *skb) | ||
2694 | { | ||
2695 | struct ieee80211_local *local = sdata->local; | ||
2696 | u16 ethertype = (skb->data[12] << 8) | skb->data[13]; | ||
2697 | int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); | ||
2698 | int hw_headroom = sdata->local->hw.extra_tx_headroom; | ||
2699 | struct ethhdr eth; | ||
2700 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
2701 | struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; | ||
2702 | struct ieee80211_tx_data tx; | ||
2703 | ieee80211_tx_result r; | ||
2704 | struct tid_ampdu_tx *tid_tx = NULL; | ||
2705 | u8 tid = IEEE80211_NUM_TIDS; | ||
2706 | |||
2707 | /* control port protocol needs a lot of special handling */ | ||
2708 | if (cpu_to_be16(ethertype) == sdata->control_port_protocol) | ||
2709 | return false; | ||
2710 | |||
2711 | /* only RFC 1042 SNAP */ | ||
2712 | if (ethertype < ETH_P_802_3_MIN) | ||
2713 | return false; | ||
2714 | |||
2715 | /* don't handle TX status request here either */ | ||
2716 | if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) | ||
2717 | return false; | ||
2718 | |||
2719 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { | ||
2720 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; | ||
2721 | tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); | ||
2722 | if (tid_tx && | ||
2723 | !test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) | ||
2724 | return false; | ||
2725 | } | ||
2726 | |||
2727 | /* after this point (skb is modified) we cannot return false */ | ||
2728 | |||
2729 | if (skb_shared(skb)) { | ||
2730 | struct sk_buff *tmp_skb = skb; | ||
2731 | |||
2732 | skb = skb_clone(skb, GFP_ATOMIC); | ||
2733 | kfree_skb(tmp_skb); | ||
2734 | |||
2735 | if (!skb) | ||
2736 | return true; | ||
2737 | } | ||
2738 | |||
2739 | ieee80211_tx_stats(dev, skb->len + extra_head); | ||
2740 | |||
2741 | /* will not be crypto-handled beyond what we do here, so use false | ||
2742 | * as the may-encrypt argument for the resize to not account for | ||
2743 | * more room than we already have in 'extra_head' | ||
2744 | */ | ||
2745 | if (unlikely(ieee80211_skb_resize(sdata, skb, | ||
2746 | max_t(int, extra_head + hw_headroom - | ||
2747 | skb_headroom(skb), 0), | ||
2748 | false))) { | ||
2749 | kfree_skb(skb); | ||
2750 | return true; | ||
2751 | } | ||
2752 | |||
2753 | memcpy(ð, skb->data, ETH_HLEN - 2); | ||
2754 | hdr = (void *)skb_push(skb, extra_head); | ||
2755 | memcpy(skb->data, fast_tx->hdr, fast_tx->hdr_len); | ||
2756 | memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN); | ||
2757 | memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN); | ||
2758 | |||
2759 | memset(info, 0, sizeof(*info)); | ||
2760 | info->band = fast_tx->band; | ||
2761 | info->control.vif = &sdata->vif; | ||
2762 | info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT | | ||
2763 | IEEE80211_TX_CTL_DONTFRAG | | ||
2764 | (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0); | ||
2765 | |||
2766 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { | ||
2767 | *ieee80211_get_qos_ctl(hdr) = tid; | ||
2768 | hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); | ||
2769 | } else { | ||
2770 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | ||
2771 | hdr->seq_ctrl = cpu_to_le16(sdata->sequence_number); | ||
2772 | sdata->sequence_number += 0x10; | ||
2773 | } | ||
2774 | |||
2775 | sta->tx_msdu[tid]++; | ||
2776 | |||
2777 | info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; | ||
2778 | |||
2779 | __skb_queue_head_init(&tx.skbs); | ||
2780 | |||
2781 | tx.flags = IEEE80211_TX_UNICAST; | ||
2782 | tx.local = local; | ||
2783 | tx.sdata = sdata; | ||
2784 | tx.sta = sta; | ||
2785 | tx.key = fast_tx->key; | ||
2786 | |||
2787 | if (fast_tx->key) | ||
2788 | info->control.hw_key = &fast_tx->key->conf; | ||
2789 | |||
2790 | if (!(local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) { | ||
2791 | tx.skb = skb; | ||
2792 | r = ieee80211_tx_h_rate_ctrl(&tx); | ||
2793 | skb = tx.skb; | ||
2794 | tx.skb = NULL; | ||
2795 | |||
2796 | if (r != TX_CONTINUE) { | ||
2797 | if (r != TX_QUEUED) | ||
2798 | kfree_skb(skb); | ||
2799 | return true; | ||
2800 | } | ||
2801 | } | ||
2802 | |||
2803 | /* statistics normally done by ieee80211_tx_h_stats (but that | ||
2804 | * has to consider fragmentation, so is more complex) | ||
2805 | */ | ||
2806 | sta->tx_bytes[skb_get_queue_mapping(skb)] += skb->len; | ||
2807 | sta->tx_packets[skb_get_queue_mapping(skb)]++; | ||
2808 | |||
2809 | if (fast_tx->pn_offs) { | ||
2810 | u64 pn; | ||
2811 | u8 *crypto_hdr = skb->data + fast_tx->pn_offs; | ||
2812 | |||
2813 | switch (fast_tx->key->conf.cipher) { | ||
2814 | case WLAN_CIPHER_SUITE_CCMP: | ||
2815 | case WLAN_CIPHER_SUITE_CCMP_256: | ||
2816 | pn = atomic64_inc_return(&fast_tx->key->u.ccmp.tx_pn); | ||
2817 | crypto_hdr[0] = pn; | ||
2818 | crypto_hdr[1] = pn >> 8; | ||
2819 | crypto_hdr[4] = pn >> 16; | ||
2820 | crypto_hdr[5] = pn >> 24; | ||
2821 | crypto_hdr[6] = pn >> 32; | ||
2822 | crypto_hdr[7] = pn >> 40; | ||
2823 | break; | ||
2824 | case WLAN_CIPHER_SUITE_GCMP: | ||
2825 | case WLAN_CIPHER_SUITE_GCMP_256: | ||
2826 | pn = atomic64_inc_return(&fast_tx->key->u.gcmp.tx_pn); | ||
2827 | crypto_hdr[0] = pn; | ||
2828 | crypto_hdr[1] = pn >> 8; | ||
2829 | crypto_hdr[4] = pn >> 16; | ||
2830 | crypto_hdr[5] = pn >> 24; | ||
2831 | crypto_hdr[6] = pn >> 32; | ||
2832 | crypto_hdr[7] = pn >> 40; | ||
2833 | break; | ||
2834 | } | ||
2835 | } | ||
2836 | |||
2837 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
2838 | sdata = container_of(sdata->bss, | ||
2839 | struct ieee80211_sub_if_data, u.ap); | ||
2840 | |||
2841 | __skb_queue_tail(&tx.skbs, skb); | ||
2842 | ieee80211_tx_frags(local, &sdata->vif, &sta->sta, &tx.skbs, false); | ||
2843 | return true; | ||
2844 | } | ||
2845 | |||
2390 | void __ieee80211_subif_start_xmit(struct sk_buff *skb, | 2846 | void __ieee80211_subif_start_xmit(struct sk_buff *skb, |
2391 | struct net_device *dev, | 2847 | struct net_device *dev, |
2392 | u32 info_flags) | 2848 | u32 info_flags) |
2393 | { | 2849 | { |
2394 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2850 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2395 | struct sta_info *sta; | 2851 | struct sta_info *sta; |
2852 | struct sk_buff *next; | ||
2396 | 2853 | ||
2397 | if (unlikely(skb->len < ETH_HLEN)) { | 2854 | if (unlikely(skb->len < ETH_HLEN)) { |
2398 | kfree_skb(skb); | 2855 | kfree_skb(skb); |
@@ -2401,20 +2858,67 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2401 | 2858 | ||
2402 | rcu_read_lock(); | 2859 | rcu_read_lock(); |
2403 | 2860 | ||
2404 | if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) { | 2861 | if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) |
2405 | kfree_skb(skb); | 2862 | goto out_free; |
2406 | goto out; | 2863 | |
2864 | if (!IS_ERR_OR_NULL(sta)) { | ||
2865 | struct ieee80211_fast_tx *fast_tx; | ||
2866 | |||
2867 | fast_tx = rcu_dereference(sta->fast_tx); | ||
2868 | |||
2869 | if (fast_tx && | ||
2870 | ieee80211_xmit_fast(sdata, dev, sta, fast_tx, skb)) | ||
2871 | goto out; | ||
2407 | } | 2872 | } |
2408 | 2873 | ||
2409 | skb = ieee80211_build_hdr(sdata, skb, info_flags, sta); | 2874 | if (skb_is_gso(skb)) { |
2410 | if (IS_ERR(skb)) | 2875 | struct sk_buff *segs; |
2411 | goto out; | 2876 | |
2877 | segs = skb_gso_segment(skb, 0); | ||
2878 | if (IS_ERR(segs)) { | ||
2879 | goto out_free; | ||
2880 | } else if (segs) { | ||
2881 | consume_skb(skb); | ||
2882 | skb = segs; | ||
2883 | } | ||
2884 | } else { | ||
2885 | /* we cannot process non-linear frames on this path */ | ||
2886 | if (skb_linearize(skb)) { | ||
2887 | kfree_skb(skb); | ||
2888 | goto out; | ||
2889 | } | ||
2890 | |||
2891 | /* the frame could be fragmented, software-encrypted, and other | ||
2892 | * things so we cannot really handle checksum offload with it - | ||
2893 | * fix it up in software before we handle anything else. | ||
2894 | */ | ||
2895 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
2896 | skb_set_transport_header(skb, | ||
2897 | skb_checksum_start_offset(skb)); | ||
2898 | if (skb_checksum_help(skb)) | ||
2899 | goto out_free; | ||
2900 | } | ||
2901 | } | ||
2902 | |||
2903 | next = skb; | ||
2904 | while (next) { | ||
2905 | skb = next; | ||
2906 | next = skb->next; | ||
2412 | 2907 | ||
2413 | dev->stats.tx_packets++; | 2908 | skb->prev = NULL; |
2414 | dev->stats.tx_bytes += skb->len; | 2909 | skb->next = NULL; |
2415 | dev->trans_start = jiffies; | 2910 | |
2911 | skb = ieee80211_build_hdr(sdata, skb, info_flags, sta); | ||
2912 | if (IS_ERR(skb)) | ||
2913 | goto out; | ||
2416 | 2914 | ||
2417 | ieee80211_xmit(sdata, sta, skb); | 2915 | ieee80211_tx_stats(dev, skb->len); |
2916 | |||
2917 | ieee80211_xmit(sdata, sta, skb); | ||
2918 | } | ||
2919 | goto out; | ||
2920 | out_free: | ||
2921 | kfree_skb(skb); | ||
2418 | out: | 2922 | out: |
2419 | rcu_read_unlock(); | 2923 | rcu_read_unlock(); |
2420 | } | 2924 | } |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 7aaf7415dc4c..915b328b9ac5 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -698,19 +698,20 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, | |||
698 | EXPORT_SYMBOL(cfg80211_chandef_usable); | 698 | EXPORT_SYMBOL(cfg80211_chandef_usable); |
699 | 699 | ||
700 | /* | 700 | /* |
701 | * For GO only, check if the channel can be used under permissive conditions | 701 | * Check if the channel can be used under permissive conditions mandated by |
702 | * mandated by the some regulatory bodies, i.e., the channel is marked with | 702 | * some regulatory bodies, i.e., the channel is marked with |
703 | * IEEE80211_CHAN_GO_CONCURRENT and there is an additional station interface | 703 | * IEEE80211_CHAN_IR_CONCURRENT and there is an additional station interface |
704 | * associated to an AP on the same channel or on the same UNII band | 704 | * associated to an AP on the same channel or on the same UNII band |
705 | * (assuming that the AP is an authorized master). | 705 | * (assuming that the AP is an authorized master). |
706 | * In addition allow the GO to operate on a channel on which indoor operation is | 706 | * In addition allow operation on a channel on which indoor operation is |
707 | * allowed, iff we are currently operating in an indoor environment. | 707 | * allowed, iff we are currently operating in an indoor environment. |
708 | */ | 708 | */ |
709 | static bool cfg80211_go_permissive_chan(struct cfg80211_registered_device *rdev, | 709 | static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy, |
710 | enum nl80211_iftype iftype, | ||
710 | struct ieee80211_channel *chan) | 711 | struct ieee80211_channel *chan) |
711 | { | 712 | { |
712 | struct wireless_dev *wdev_iter; | 713 | struct wireless_dev *wdev; |
713 | struct wiphy *wiphy = wiphy_idx_to_wiphy(rdev->wiphy_idx); | 714 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
714 | 715 | ||
715 | ASSERT_RTNL(); | 716 | ASSERT_RTNL(); |
716 | 717 | ||
@@ -718,32 +719,48 @@ static bool cfg80211_go_permissive_chan(struct cfg80211_registered_device *rdev, | |||
718 | !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR)) | 719 | !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR)) |
719 | return false; | 720 | return false; |
720 | 721 | ||
722 | /* only valid for GO and TDLS off-channel (station/p2p-CL) */ | ||
723 | if (iftype != NL80211_IFTYPE_P2P_GO && | ||
724 | iftype != NL80211_IFTYPE_STATION && | ||
725 | iftype != NL80211_IFTYPE_P2P_CLIENT) | ||
726 | return false; | ||
727 | |||
721 | if (regulatory_indoor_allowed() && | 728 | if (regulatory_indoor_allowed() && |
722 | (chan->flags & IEEE80211_CHAN_INDOOR_ONLY)) | 729 | (chan->flags & IEEE80211_CHAN_INDOOR_ONLY)) |
723 | return true; | 730 | return true; |
724 | 731 | ||
725 | if (!(chan->flags & IEEE80211_CHAN_GO_CONCURRENT)) | 732 | if (!(chan->flags & IEEE80211_CHAN_IR_CONCURRENT)) |
726 | return false; | 733 | return false; |
727 | 734 | ||
728 | /* | 735 | /* |
729 | * Generally, it is possible to rely on another device/driver to allow | 736 | * Generally, it is possible to rely on another device/driver to allow |
730 | * the GO concurrent relaxation, however, since the device can further | 737 | * the IR concurrent relaxation, however, since the device can further |
731 | * enforce the relaxation (by doing a similar verifications as this), | 738 | * enforce the relaxation (by doing a similar verifications as this), |
732 | * and thus fail the GO instantiation, consider only the interfaces of | 739 | * and thus fail the GO instantiation, consider only the interfaces of |
733 | * the current registered device. | 740 | * the current registered device. |
734 | */ | 741 | */ |
735 | list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { | 742 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
736 | struct ieee80211_channel *other_chan = NULL; | 743 | struct ieee80211_channel *other_chan = NULL; |
737 | int r1, r2; | 744 | int r1, r2; |
738 | 745 | ||
739 | if (wdev_iter->iftype != NL80211_IFTYPE_STATION || | 746 | wdev_lock(wdev); |
740 | !netif_running(wdev_iter->netdev)) | 747 | if (wdev->iftype == NL80211_IFTYPE_STATION && |
741 | continue; | 748 | wdev->current_bss) |
742 | 749 | other_chan = wdev->current_bss->pub.channel; | |
743 | wdev_lock(wdev_iter); | 750 | |
744 | if (wdev_iter->current_bss) | 751 | /* |
745 | other_chan = wdev_iter->current_bss->pub.channel; | 752 | * If a GO already operates on the same GO_CONCURRENT channel, |
746 | wdev_unlock(wdev_iter); | 753 | * this one (maybe the same one) can beacon as well. We allow |
754 | * the operation even if the station we relied on with | ||
755 | * GO_CONCURRENT is disconnected now. But then we must make sure | ||
756 | * we're not outdoor on an indoor-only channel. | ||
757 | */ | ||
758 | if (iftype == NL80211_IFTYPE_P2P_GO && | ||
759 | wdev->iftype == NL80211_IFTYPE_P2P_GO && | ||
760 | wdev->beacon_interval && | ||
761 | !(chan->flags & IEEE80211_CHAN_INDOOR_ONLY)) | ||
762 | other_chan = wdev->chandef.chan; | ||
763 | wdev_unlock(wdev); | ||
747 | 764 | ||
748 | if (!other_chan) | 765 | if (!other_chan) |
749 | continue; | 766 | continue; |
@@ -784,7 +801,6 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy, | |||
784 | struct cfg80211_chan_def *chandef, | 801 | struct cfg80211_chan_def *chandef, |
785 | enum nl80211_iftype iftype) | 802 | enum nl80211_iftype iftype) |
786 | { | 803 | { |
787 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | ||
788 | bool res; | 804 | bool res; |
789 | u32 prohibited_flags = IEEE80211_CHAN_DISABLED | | 805 | u32 prohibited_flags = IEEE80211_CHAN_DISABLED | |
790 | IEEE80211_CHAN_RADAR; | 806 | IEEE80211_CHAN_RADAR; |
@@ -792,13 +808,12 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy, | |||
792 | trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype); | 808 | trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype); |
793 | 809 | ||
794 | /* | 810 | /* |
795 | * Under certain conditions suggested by the some regulatory bodies | 811 | * Under certain conditions suggested by some regulatory bodies a |
796 | * a GO can operate on channels marked with IEEE80211_NO_IR | 812 | * GO/STA can IR on channels marked with IEEE80211_NO_IR. Set this flag |
797 | * so set this flag only if such relaxations are not enabled and | 813 | * only if such relaxations are not enabled and the conditions are not |
798 | * the conditions are not met. | 814 | * met. |
799 | */ | 815 | */ |
800 | if (iftype != NL80211_IFTYPE_P2P_GO || | 816 | if (!cfg80211_ir_permissive_chan(wiphy, iftype, chandef->chan)) |
801 | !cfg80211_go_permissive_chan(rdev, chandef->chan)) | ||
802 | prohibited_flags |= IEEE80211_CHAN_NO_IR; | 817 | prohibited_flags |= IEEE80211_CHAN_NO_IR; |
803 | 818 | ||
804 | if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 && | 819 | if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 && |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index dd78445c7d50..c264effd00a6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -639,8 +639,8 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, | |||
639 | if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) && | 639 | if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) && |
640 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY)) | 640 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY)) |
641 | goto nla_put_failure; | 641 | goto nla_put_failure; |
642 | if ((chan->flags & IEEE80211_CHAN_GO_CONCURRENT) && | 642 | if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) && |
643 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_GO_CONCURRENT)) | 643 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT)) |
644 | goto nla_put_failure; | 644 | goto nla_put_failure; |
645 | if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) && | 645 | if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) && |
646 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ)) | 646 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ)) |
@@ -4061,7 +4061,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy, | |||
4061 | return -EINVAL; | 4061 | return -EINVAL; |
4062 | break; | 4062 | break; |
4063 | case CFG80211_STA_MESH_PEER_USER: | 4063 | case CFG80211_STA_MESH_PEER_USER: |
4064 | if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION) | 4064 | if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION && |
4065 | params->plink_action != NL80211_PLINK_ACTION_BLOCK) | ||
4065 | return -EINVAL; | 4066 | return -EINVAL; |
4066 | break; | 4067 | break; |
4067 | } | 4068 | } |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 0e347f888fe9..d359e0610198 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -989,8 +989,8 @@ static u32 map_regdom_flags(u32 rd_flags) | |||
989 | channel_flags |= IEEE80211_CHAN_NO_OFDM; | 989 | channel_flags |= IEEE80211_CHAN_NO_OFDM; |
990 | if (rd_flags & NL80211_RRF_NO_OUTDOOR) | 990 | if (rd_flags & NL80211_RRF_NO_OUTDOOR) |
991 | channel_flags |= IEEE80211_CHAN_INDOOR_ONLY; | 991 | channel_flags |= IEEE80211_CHAN_INDOOR_ONLY; |
992 | if (rd_flags & NL80211_RRF_GO_CONCURRENT) | 992 | if (rd_flags & NL80211_RRF_IR_CONCURRENT) |
993 | channel_flags |= IEEE80211_CHAN_GO_CONCURRENT; | 993 | channel_flags |= IEEE80211_CHAN_IR_CONCURRENT; |
994 | if (rd_flags & NL80211_RRF_NO_HT40MINUS) | 994 | if (rd_flags & NL80211_RRF_NO_HT40MINUS) |
995 | channel_flags |= IEEE80211_CHAN_NO_HT40MINUS; | 995 | channel_flags |= IEEE80211_CHAN_NO_HT40MINUS; |
996 | if (rd_flags & NL80211_RRF_NO_HT40PLUS) | 996 | if (rd_flags & NL80211_RRF_NO_HT40PLUS) |