diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-03-25 16:38:02 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-03-25 16:38:02 -0400 |
commit | c78b3841fac9a59c7494be143aa7f2e69ea47958 (patch) | |
tree | 503c1279d2bdf8b295ba7d2eb81830c5eb6bfb32 | |
parent | 0d4e67174b03e3dcfe75ce7ec488770a5d443bf4 (diff) | |
parent | f00f188f8212fec9976394976c4fd5d4a3bc4dcf (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
37 files changed, 374 insertions, 257 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 284ced7a228f..0f6a3edcd44b 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl | |||
@@ -437,7 +437,7 @@ | |||
437 | </section> | 437 | </section> |
438 | !Finclude/net/mac80211.h ieee80211_get_buffered_bc | 438 | !Finclude/net/mac80211.h ieee80211_get_buffered_bc |
439 | !Finclude/net/mac80211.h ieee80211_beacon_get | 439 | !Finclude/net/mac80211.h ieee80211_beacon_get |
440 | !Finclude/net/mac80211.h ieee80211_sta_eosp_irqsafe | 440 | !Finclude/net/mac80211.h ieee80211_sta_eosp |
441 | !Finclude/net/mac80211.h ieee80211_frame_release_type | 441 | !Finclude/net/mac80211.h ieee80211_frame_release_type |
442 | !Finclude/net/mac80211.h ieee80211_sta_ps_transition | 442 | !Finclude/net/mac80211.h ieee80211_sta_ps_transition |
443 | !Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni | 443 | !Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni |
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 7157f7d311c5..afd1e36d308f 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
@@ -1091,7 +1091,7 @@ static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | |||
1091 | return ret; | 1091 | return ret; |
1092 | } | 1092 | } |
1093 | 1093 | ||
1094 | static void ar5523_flush(struct ieee80211_hw *hw, bool drop) | 1094 | static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
1095 | { | 1095 | { |
1096 | struct ar5523 *ar = hw->priv; | 1096 | struct ar5523 *ar = hw->priv; |
1097 | 1097 | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6e66f9c6782b..24650fd41694 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1745,7 +1745,7 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | |||
1745 | mutex_unlock(&sc->mutex); | 1745 | mutex_unlock(&sc->mutex); |
1746 | } | 1746 | } |
1747 | 1747 | ||
1748 | static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | 1748 | static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
1749 | { | 1749 | { |
1750 | struct ath_softc *sc = hw->priv; | 1750 | struct ath_softc *sc = hw->priv; |
1751 | struct ath_hw *ah = sc->sc_ah; | 1751 | struct ath_hw *ah = sc->sc_ah; |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index f293b3ff4756..08b193199946 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1703,7 +1703,7 @@ found: | |||
1703 | return 0; | 1703 | return 0; |
1704 | } | 1704 | } |
1705 | 1705 | ||
1706 | static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop) | 1706 | static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
1707 | { | 1707 | { |
1708 | struct ar9170 *ar = hw->priv; | 1708 | struct ar9170 *ar = hw->priv; |
1709 | unsigned int vid; | 1709 | unsigned int vid; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index c70cf7b654cd..7cc30f8fed7d 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -724,7 +724,7 @@ static bool brcms_tx_flush_completed(struct brcms_info *wl) | |||
724 | return result; | 724 | return result; |
725 | } | 725 | } |
726 | 726 | ||
727 | static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) | 727 | static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
728 | { | 728 | { |
729 | struct brcms_info *wl = hw->priv; | 729 | struct brcms_info *wl = hw->priv; |
730 | int ret; | 730 | int ret; |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index bc465da40476..1a518feb4b26 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -4704,8 +4704,7 @@ out: | |||
4704 | } | 4704 | } |
4705 | EXPORT_SYMBOL(il_mac_change_interface); | 4705 | EXPORT_SYMBOL(il_mac_change_interface); |
4706 | 4706 | ||
4707 | void | 4707 | void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
4708 | il_mac_flush(struct ieee80211_hw *hw, bool drop) | ||
4709 | { | 4708 | { |
4710 | struct il_priv *il = hw->priv; | 4709 | struct il_priv *il = hw->priv; |
4711 | unsigned long timeout = jiffies + msecs_to_jiffies(500); | 4710 | unsigned long timeout = jiffies + msecs_to_jiffies(500); |
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 73bd3ef316c8..728aa1306ab8 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h | |||
@@ -1720,7 +1720,7 @@ void il_mac_remove_interface(struct ieee80211_hw *hw, | |||
1720 | struct ieee80211_vif *vif); | 1720 | struct ieee80211_vif *vif); |
1721 | int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 1721 | int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
1722 | enum nl80211_iftype newtype, bool newp2p); | 1722 | enum nl80211_iftype newtype, bool newp2p); |
1723 | void il_mac_flush(struct ieee80211_hw *hw, bool drop); | 1723 | void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop); |
1724 | int il_alloc_txq_mem(struct il_priv *il); | 1724 | int il_alloc_txq_mem(struct il_priv *il); |
1725 | void il_free_txq_mem(struct il_priv *il); | 1725 | void il_free_txq_mem(struct il_priv *il); |
1726 | 1726 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index c7cd2dffa5cd..a7294fa4d7e5 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -1100,7 +1100,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
1100 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | 1100 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; |
1101 | } | 1101 | } |
1102 | 1102 | ||
1103 | static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | 1103 | static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
1104 | { | 1104 | { |
1105 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1105 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1106 | 1106 | ||
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 7490c4fc7177..0064d38276bf 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -964,6 +964,12 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, | |||
964 | newtype, vif->addr); | 964 | newtype, vif->addr); |
965 | hwsim_check_magic(vif); | 965 | hwsim_check_magic(vif); |
966 | 966 | ||
967 | /* | ||
968 | * interface may change from non-AP to AP in | ||
969 | * which case this needs to be set up again | ||
970 | */ | ||
971 | vif->cab_queue = 0; | ||
972 | |||
967 | return 0; | 973 | return 0; |
968 | } | 974 | } |
969 | 975 | ||
@@ -1389,7 +1395,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw, | |||
1389 | return 0; | 1395 | return 0; |
1390 | } | 1396 | } |
1391 | 1397 | ||
1392 | static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop) | 1398 | static void mac80211_hwsim_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
1393 | { | 1399 | { |
1394 | /* Not implemented, queues only on kernel side */ | 1400 | /* Not implemented, queues only on kernel side */ |
1395 | } | 1401 | } |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index aadda99989c0..ee654a691f38 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -670,7 +670,7 @@ static unsigned int p54_flush_count(struct p54_common *priv) | |||
670 | return total; | 670 | return total; |
671 | } | 671 | } |
672 | 672 | ||
673 | static void p54_flush(struct ieee80211_hw *dev, bool drop) | 673 | static void p54_flush(struct ieee80211_hw *dev, u32 queues, bool drop) |
674 | { | 674 | { |
675 | struct p54_common *priv = dev->priv; | 675 | struct p54_common *priv = dev->priv; |
676 | unsigned int total, i; | 676 | unsigned int total, i; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 51922cc179de..cdf26ede7270 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1366,7 +1366,7 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, | |||
1366 | struct ieee80211_vif *vif, u16 queue, | 1366 | struct ieee80211_vif *vif, u16 queue, |
1367 | const struct ieee80211_tx_queue_params *params); | 1367 | const struct ieee80211_tx_queue_params *params); |
1368 | void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); | 1368 | void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); |
1369 | void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); | 1369 | void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop); |
1370 | int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); | 1370 | int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); |
1371 | int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); | 1371 | int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); |
1372 | void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, | 1372 | void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 20c6eccce5aa..9161c02d8ff9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -748,7 +748,7 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw) | |||
748 | } | 748 | } |
749 | EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); | 749 | EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); |
750 | 750 | ||
751 | void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) | 751 | void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
752 | { | 752 | { |
753 | struct rt2x00_dev *rt2x00dev = hw->priv; | 753 | struct rt2x00_dev *rt2x00dev = hw->priv; |
754 | struct data_queue *queue; | 754 | struct data_queue *queue; |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index d3ce9fbef00e..b5a7a260bf63 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
@@ -1166,7 +1166,7 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) | |||
1166 | * before switch channle or power save, or tx buffer packet | 1166 | * before switch channle or power save, or tx buffer packet |
1167 | * maybe send after offchannel or rf sleep, this may cause | 1167 | * maybe send after offchannel or rf sleep, this may cause |
1168 | * dis-association by AP */ | 1168 | * dis-association by AP */ |
1169 | static void rtl_op_flush(struct ieee80211_hw *hw, bool drop) | 1169 | static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
1170 | { | 1170 | { |
1171 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1171 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1172 | 1172 | ||
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index d7e306333f6c..a9f7041c7192 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -4946,7 +4946,7 @@ out: | |||
4946 | mutex_unlock(&wl->mutex); | 4946 | mutex_unlock(&wl->mutex); |
4947 | } | 4947 | } |
4948 | 4948 | ||
4949 | static void wlcore_op_flush(struct ieee80211_hw *hw, bool drop) | 4949 | static void wlcore_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) |
4950 | { | 4950 | { |
4951 | struct wl1271 *wl = hw->priv; | 4951 | struct wl1271 *wl = hw->priv; |
4952 | 4952 | ||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index cdd7cea1fd4c..dd73b8c6746b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -93,9 +93,11 @@ struct device; | |||
93 | * enum ieee80211_max_queues - maximum number of queues | 93 | * enum ieee80211_max_queues - maximum number of queues |
94 | * | 94 | * |
95 | * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. | 95 | * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. |
96 | * @IEEE80211_MAX_QUEUE_MAP: bitmap with maximum queues set | ||
96 | */ | 97 | */ |
97 | enum ieee80211_max_queues { | 98 | enum ieee80211_max_queues { |
98 | IEEE80211_MAX_QUEUES = 16, | 99 | IEEE80211_MAX_QUEUES = 16, |
100 | IEEE80211_MAX_QUEUE_MAP = BIT(IEEE80211_MAX_QUEUES) - 1, | ||
99 | }; | 101 | }; |
100 | 102 | ||
101 | #define IEEE80211_INVAL_HW_QUEUE 0xff | 103 | #define IEEE80211_INVAL_HW_QUEUE 0xff |
@@ -1067,6 +1069,9 @@ enum ieee80211_vif_flags { | |||
1067 | * path needing to access it; even though the netdev carrier will always | 1069 | * path needing to access it; even though the netdev carrier will always |
1068 | * be off when it is %NULL there can still be races and packets could be | 1070 | * be off when it is %NULL there can still be races and packets could be |
1069 | * processed after it switches back to %NULL. | 1071 | * processed after it switches back to %NULL. |
1072 | * @debugfs_dir: debugfs dentry, can be used by drivers to create own per | ||
1073 | * interface debug files. Note that it will be NULL for the virtual | ||
1074 | * monitor interface (if that is requested.) | ||
1070 | * @drv_priv: data area for driver use, will always be aligned to | 1075 | * @drv_priv: data area for driver use, will always be aligned to |
1071 | * sizeof(void *). | 1076 | * sizeof(void *). |
1072 | */ | 1077 | */ |
@@ -1083,6 +1088,10 @@ struct ieee80211_vif { | |||
1083 | 1088 | ||
1084 | u32 driver_flags; | 1089 | u32 driver_flags; |
1085 | 1090 | ||
1091 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
1092 | struct dentry *debugfs_dir; | ||
1093 | #endif | ||
1094 | |||
1086 | /* must be last */ | 1095 | /* must be last */ |
1087 | u8 drv_priv[0] __aligned(sizeof(void *)); | 1096 | u8 drv_priv[0] __aligned(sizeof(void *)); |
1088 | }; | 1097 | }; |
@@ -1946,14 +1955,14 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); | |||
1946 | * filter those response frames except in the case of frames that | 1955 | * filter those response frames except in the case of frames that |
1947 | * are buffered in the driver -- those must remain buffered to avoid | 1956 | * are buffered in the driver -- those must remain buffered to avoid |
1948 | * reordering. Because it is possible that no frames are released | 1957 | * reordering. Because it is possible that no frames are released |
1949 | * in this case, the driver must call ieee80211_sta_eosp_irqsafe() | 1958 | * in this case, the driver must call ieee80211_sta_eosp() |
1950 | * to indicate to mac80211 that the service period ended anyway. | 1959 | * to indicate to mac80211 that the service period ended anyway. |
1951 | * | 1960 | * |
1952 | * Finally, if frames from multiple TIDs are released from mac80211 | 1961 | * Finally, if frames from multiple TIDs are released from mac80211 |
1953 | * but the driver might reorder them, it must clear & set the flags | 1962 | * but the driver might reorder them, it must clear & set the flags |
1954 | * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP) | 1963 | * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP) |
1955 | * and also take care of the EOSP and MORE_DATA bits in the frame. | 1964 | * and also take care of the EOSP and MORE_DATA bits in the frame. |
1956 | * The driver may also use ieee80211_sta_eosp_irqsafe() in this case. | 1965 | * The driver may also use ieee80211_sta_eosp() in this case. |
1957 | */ | 1966 | */ |
1958 | 1967 | ||
1959 | /** | 1968 | /** |
@@ -2226,18 +2235,6 @@ enum ieee80211_roc_type { | |||
2226 | * MAC address of the device going away. | 2235 | * MAC address of the device going away. |
2227 | * Hence, this callback must be implemented. It can sleep. | 2236 | * Hence, this callback must be implemented. It can sleep. |
2228 | * | 2237 | * |
2229 | * @add_interface_debugfs: Drivers can use this callback to add debugfs files | ||
2230 | * when a vif is added to mac80211. This callback and | ||
2231 | * @remove_interface_debugfs should be within a CONFIG_MAC80211_DEBUGFS | ||
2232 | * conditional. @remove_interface_debugfs must be provided for cleanup. | ||
2233 | * This callback can sleep. | ||
2234 | * | ||
2235 | * @remove_interface_debugfs: Remove the debugfs files which were added using | ||
2236 | * @add_interface_debugfs. This callback must remove all debugfs entries | ||
2237 | * that were added because mac80211 only removes interface debugfs when the | ||
2238 | * interface is destroyed, not when it is removed from the driver. | ||
2239 | * This callback can sleep. | ||
2240 | * | ||
2241 | * @config: Handler for configuration requests. IEEE 802.11 code calls this | 2238 | * @config: Handler for configuration requests. IEEE 802.11 code calls this |
2242 | * function to change hardware configuration, e.g., channel. | 2239 | * function to change hardware configuration, e.g., channel. |
2243 | * This function should never fail but returns a negative error code | 2240 | * This function should never fail but returns a negative error code |
@@ -2259,6 +2256,9 @@ enum ieee80211_roc_type { | |||
2259 | * See the section "Frame filtering" for more information. | 2256 | * See the section "Frame filtering" for more information. |
2260 | * This callback must be implemented and can sleep. | 2257 | * This callback must be implemented and can sleep. |
2261 | * | 2258 | * |
2259 | * @set_multicast_list: Configure the device's interface specific RX multicast | ||
2260 | * filter. This callback is optional. This callback must be atomic. | ||
2261 | * | ||
2262 | * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit | 2262 | * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit |
2263 | * must be set or cleared for a given STA. Must be atomic. | 2263 | * must be set or cleared for a given STA. Must be atomic. |
2264 | * | 2264 | * |
@@ -2440,8 +2440,11 @@ enum ieee80211_roc_type { | |||
2440 | * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep. | 2440 | * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep. |
2441 | * | 2441 | * |
2442 | * @flush: Flush all pending frames from the hardware queue, making sure | 2442 | * @flush: Flush all pending frames from the hardware queue, making sure |
2443 | * that the hardware queues are empty. If the parameter @drop is set | 2443 | * that the hardware queues are empty. The @queues parameter is a bitmap |
2444 | * to %true, pending frames may be dropped. The callback can sleep. | 2444 | * of queues to flush, which is useful if different virtual interfaces |
2445 | * use different hardware queues; it may also indicate all queues. | ||
2446 | * If the parameter @drop is set to %true, pending frames may be dropped. | ||
2447 | * The callback can sleep. | ||
2445 | * | 2448 | * |
2446 | * @channel_switch: Drivers that need (or want) to offload the channel | 2449 | * @channel_switch: Drivers that need (or want) to offload the channel |
2447 | * switch operation for CSAs received from the AP may implement this | 2450 | * switch operation for CSAs received from the AP may implement this |
@@ -2506,7 +2509,7 @@ enum ieee80211_roc_type { | |||
2506 | * setting the EOSP flag in the QoS header of the frames. Also, when the | 2509 | * setting the EOSP flag in the QoS header of the frames. Also, when the |
2507 | * service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP | 2510 | * service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP |
2508 | * on the last frame in the SP. Alternatively, it may call the function | 2511 | * on the last frame in the SP. Alternatively, it may call the function |
2509 | * ieee80211_sta_eosp_irqsafe() to inform mac80211 of the end of the SP. | 2512 | * ieee80211_sta_eosp() to inform mac80211 of the end of the SP. |
2510 | * This callback must be atomic. | 2513 | * This callback must be atomic. |
2511 | * @allow_buffered_frames: Prepare device to allow the given number of frames | 2514 | * @allow_buffered_frames: Prepare device to allow the given number of frames |
2512 | * to go out to the given station. The frames will be sent by mac80211 | 2515 | * to go out to the given station. The frames will be sent by mac80211 |
@@ -2517,7 +2520,7 @@ enum ieee80211_roc_type { | |||
2517 | * them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag | 2520 | * them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag |
2518 | * on the last frame and clear it on all others and also handle the EOSP | 2521 | * on the last frame and clear it on all others and also handle the EOSP |
2519 | * bit in the QoS header correctly. Alternatively, it can also call the | 2522 | * bit in the QoS header correctly. Alternatively, it can also call the |
2520 | * ieee80211_sta_eosp_irqsafe() function. | 2523 | * ieee80211_sta_eosp() function. |
2521 | * The @tids parameter is a bitmap and tells the driver which TIDs the | 2524 | * The @tids parameter is a bitmap and tells the driver which TIDs the |
2522 | * frames will be on; it will at most have two bits set. | 2525 | * frames will be on; it will at most have two bits set. |
2523 | * This callback must be atomic. | 2526 | * This callback must be atomic. |
@@ -2605,6 +2608,10 @@ struct ieee80211_ops { | |||
2605 | unsigned int changed_flags, | 2608 | unsigned int changed_flags, |
2606 | unsigned int *total_flags, | 2609 | unsigned int *total_flags, |
2607 | u64 multicast); | 2610 | u64 multicast); |
2611 | void (*set_multicast_list)(struct ieee80211_hw *hw, | ||
2612 | struct ieee80211_vif *vif, bool allmulti, | ||
2613 | struct netdev_hw_addr_list *mc_list); | ||
2614 | |||
2608 | int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, | 2615 | int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, |
2609 | bool set); | 2616 | bool set); |
2610 | int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 2617 | int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
@@ -2651,12 +2658,6 @@ struct ieee80211_ops { | |||
2651 | struct ieee80211_vif *vif, | 2658 | struct ieee80211_vif *vif, |
2652 | struct ieee80211_sta *sta, | 2659 | struct ieee80211_sta *sta, |
2653 | struct dentry *dir); | 2660 | struct dentry *dir); |
2654 | void (*add_interface_debugfs)(struct ieee80211_hw *hw, | ||
2655 | struct ieee80211_vif *vif, | ||
2656 | struct dentry *dir); | ||
2657 | void (*remove_interface_debugfs)(struct ieee80211_hw *hw, | ||
2658 | struct ieee80211_vif *vif, | ||
2659 | struct dentry *dir); | ||
2660 | #endif | 2661 | #endif |
2661 | void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2662 | void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2662 | enum sta_notify_cmd, struct ieee80211_sta *sta); | 2663 | enum sta_notify_cmd, struct ieee80211_sta *sta); |
@@ -2691,7 +2692,7 @@ struct ieee80211_ops { | |||
2691 | struct netlink_callback *cb, | 2692 | struct netlink_callback *cb, |
2692 | void *data, int len); | 2693 | void *data, int len); |
2693 | #endif | 2694 | #endif |
2694 | void (*flush)(struct ieee80211_hw *hw, bool drop); | 2695 | void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop); |
2695 | void (*channel_switch)(struct ieee80211_hw *hw, | 2696 | void (*channel_switch)(struct ieee80211_hw *hw, |
2696 | struct ieee80211_channel_switch *ch_switch); | 2697 | struct ieee80211_channel_switch *ch_switch); |
2697 | int (*napi_poll)(struct ieee80211_hw *hw, int budget); | 2698 | int (*napi_poll)(struct ieee80211_hw *hw, int budget); |
@@ -3857,14 +3858,17 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | |||
3857 | * %IEEE80211_TX_STATUS_EOSP bit and call this function instead. | 3858 | * %IEEE80211_TX_STATUS_EOSP bit and call this function instead. |
3858 | * This applies for PS-Poll as well as uAPSD. | 3859 | * This applies for PS-Poll as well as uAPSD. |
3859 | * | 3860 | * |
3860 | * Note that there is no non-_irqsafe version right now as | 3861 | * Note that just like with _tx_status() and _rx() drivers must |
3861 | * it wasn't needed, but just like _tx_status() and _rx() | 3862 | * not mix calls to irqsafe/non-irqsafe versions, this function |
3862 | * must not be mixed in irqsafe/non-irqsafe versions, this | 3863 | * must not be mixed with those either. Use the all irqsafe, or |
3863 | * function must not be mixed with those either. Use the | 3864 | * all non-irqsafe, don't mix! |
3864 | * all irqsafe, or all non-irqsafe, don't mix! If you need | 3865 | * |
3865 | * the non-irqsafe version of this, you need to add it. | 3866 | * NB: the _irqsafe version of this function doesn't exist, no |
3867 | * driver needs it right now. Don't call this function if | ||
3868 | * you'd need the _irqsafe version, look at the git history | ||
3869 | * and restore the _irqsafe version! | ||
3866 | */ | 3870 | */ |
3867 | void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta); | 3871 | void ieee80211_sta_eosp(struct ieee80211_sta *pubsta); |
3868 | 3872 | ||
3869 | /** | 3873 | /** |
3870 | * ieee80211_iter_keys - iterate keys programmed into the device | 3874 | * ieee80211_iter_keys - iterate keys programmed into the device |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1d1ddabd89ca..e5c1441ac2b8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -175,7 +175,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
175 | * add it to the device after the station. | 175 | * add it to the device after the station. |
176 | */ | 176 | */ |
177 | if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) { | 177 | if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) { |
178 | ieee80211_key_free(sdata->local, key); | 178 | ieee80211_key_free_unused(key); |
179 | err = -ENOENT; | 179 | err = -ENOENT; |
180 | goto out_unlock; | 180 | goto out_unlock; |
181 | } | 181 | } |
@@ -214,8 +214,6 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
214 | } | 214 | } |
215 | 215 | ||
216 | err = ieee80211_key_link(key, sdata, sta); | 216 | err = ieee80211_key_link(key, sdata, sta); |
217 | if (err) | ||
218 | ieee80211_key_free(sdata->local, key); | ||
219 | 217 | ||
220 | out_unlock: | 218 | out_unlock: |
221 | mutex_unlock(&sdata->local->sta_mtx); | 219 | mutex_unlock(&sdata->local->sta_mtx); |
@@ -254,7 +252,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
254 | goto out_unlock; | 252 | goto out_unlock; |
255 | } | 253 | } |
256 | 254 | ||
257 | __ieee80211_key_free(key, true); | 255 | ieee80211_key_free(key, true); |
258 | 256 | ||
259 | ret = 0; | 257 | ret = 0; |
260 | out_unlock: | 258 | out_unlock: |
@@ -445,12 +443,14 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
445 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 443 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
446 | struct ieee80211_local *local = sdata->local; | 444 | struct ieee80211_local *local = sdata->local; |
447 | struct timespec uptime; | 445 | struct timespec uptime; |
446 | u64 packets = 0; | ||
447 | int ac; | ||
448 | 448 | ||
449 | sinfo->generation = sdata->local->sta_generation; | 449 | sinfo->generation = sdata->local->sta_generation; |
450 | 450 | ||
451 | sinfo->filled = STATION_INFO_INACTIVE_TIME | | 451 | sinfo->filled = STATION_INFO_INACTIVE_TIME | |
452 | STATION_INFO_RX_BYTES | | 452 | STATION_INFO_RX_BYTES64 | |
453 | STATION_INFO_TX_BYTES | | 453 | STATION_INFO_TX_BYTES64 | |
454 | STATION_INFO_RX_PACKETS | | 454 | STATION_INFO_RX_PACKETS | |
455 | STATION_INFO_TX_PACKETS | | 455 | STATION_INFO_TX_PACKETS | |
456 | STATION_INFO_TX_RETRIES | | 456 | STATION_INFO_TX_RETRIES | |
@@ -467,10 +467,14 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
467 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; | 467 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; |
468 | 468 | ||
469 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); | 469 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); |
470 | sinfo->tx_bytes = 0; | ||
471 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||
472 | sinfo->tx_bytes += sta->tx_bytes[ac]; | ||
473 | packets += sta->tx_packets[ac]; | ||
474 | } | ||
475 | sinfo->tx_packets = packets; | ||
470 | sinfo->rx_bytes = sta->rx_bytes; | 476 | sinfo->rx_bytes = sta->rx_bytes; |
471 | sinfo->tx_bytes = sta->tx_bytes; | ||
472 | sinfo->rx_packets = sta->rx_packets; | 477 | sinfo->rx_packets = sta->rx_packets; |
473 | sinfo->tx_packets = sta->tx_packets; | ||
474 | sinfo->tx_retries = sta->tx_retry_count; | 478 | sinfo->tx_retries = sta->tx_retry_count; |
475 | sinfo->tx_failed = sta->tx_retry_failed; | 479 | sinfo->tx_failed = sta->tx_retry_failed; |
476 | sinfo->rx_dropped_misc = sta->rx_dropped; | 480 | sinfo->rx_dropped_misc = sta->rx_dropped; |
@@ -598,8 +602,8 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, | |||
598 | data[i++] += sta->rx_fragments; \ | 602 | data[i++] += sta->rx_fragments; \ |
599 | data[i++] += sta->rx_dropped; \ | 603 | data[i++] += sta->rx_dropped; \ |
600 | \ | 604 | \ |
601 | data[i++] += sta->tx_packets; \ | 605 | data[i++] += sinfo.tx_packets; \ |
602 | data[i++] += sta->tx_bytes; \ | 606 | data[i++] += sinfo.tx_bytes; \ |
603 | data[i++] += sta->tx_fragments; \ | 607 | data[i++] += sta->tx_fragments; \ |
604 | data[i++] += sta->tx_filtered_count; \ | 608 | data[i++] += sta->tx_filtered_count; \ |
605 | data[i++] += sta->tx_retry_failed; \ | 609 | data[i++] += sta->tx_retry_failed; \ |
@@ -621,13 +625,14 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, | |||
621 | if (!(sta && !WARN_ON(sta->sdata->dev != dev))) | 625 | if (!(sta && !WARN_ON(sta->sdata->dev != dev))) |
622 | goto do_survey; | 626 | goto do_survey; |
623 | 627 | ||
628 | sinfo.filled = 0; | ||
629 | sta_set_sinfo(sta, &sinfo); | ||
630 | |||
624 | i = 0; | 631 | i = 0; |
625 | ADD_STA_STATS(sta); | 632 | ADD_STA_STATS(sta); |
626 | 633 | ||
627 | data[i++] = sta->sta_state; | 634 | data[i++] = sta->sta_state; |
628 | 635 | ||
629 | sinfo.filled = 0; | ||
630 | sta_set_sinfo(sta, &sinfo); | ||
631 | 636 | ||
632 | if (sinfo.filled & STATION_INFO_TX_BITRATE) | 637 | if (sinfo.filled & STATION_INFO_TX_BITRATE) |
633 | data[i] = 100000 * | 638 | data[i] = 100000 * |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index c3a3082b72e5..1521cabad3d6 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
@@ -295,7 +295,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) | |||
295 | char buf[50]; | 295 | char buf[50]; |
296 | struct ieee80211_key *key; | 296 | struct ieee80211_key *key; |
297 | 297 | ||
298 | if (!sdata->debugfs.dir) | 298 | if (!sdata->vif.debugfs_dir) |
299 | return; | 299 | return; |
300 | 300 | ||
301 | lockdep_assert_held(&sdata->local->key_mtx); | 301 | lockdep_assert_held(&sdata->local->key_mtx); |
@@ -311,7 +311,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) | |||
311 | sprintf(buf, "../keys/%d", key->debugfs.cnt); | 311 | sprintf(buf, "../keys/%d", key->debugfs.cnt); |
312 | sdata->debugfs.default_unicast_key = | 312 | sdata->debugfs.default_unicast_key = |
313 | debugfs_create_symlink("default_unicast_key", | 313 | debugfs_create_symlink("default_unicast_key", |
314 | sdata->debugfs.dir, buf); | 314 | sdata->vif.debugfs_dir, buf); |
315 | } | 315 | } |
316 | 316 | ||
317 | if (sdata->debugfs.default_multicast_key) { | 317 | if (sdata->debugfs.default_multicast_key) { |
@@ -325,7 +325,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) | |||
325 | sprintf(buf, "../keys/%d", key->debugfs.cnt); | 325 | sprintf(buf, "../keys/%d", key->debugfs.cnt); |
326 | sdata->debugfs.default_multicast_key = | 326 | sdata->debugfs.default_multicast_key = |
327 | debugfs_create_symlink("default_multicast_key", | 327 | debugfs_create_symlink("default_multicast_key", |
328 | sdata->debugfs.dir, buf); | 328 | sdata->vif.debugfs_dir, buf); |
329 | } | 329 | } |
330 | } | 330 | } |
331 | 331 | ||
@@ -334,7 +334,7 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) | |||
334 | char buf[50]; | 334 | char buf[50]; |
335 | struct ieee80211_key *key; | 335 | struct ieee80211_key *key; |
336 | 336 | ||
337 | if (!sdata->debugfs.dir) | 337 | if (!sdata->vif.debugfs_dir) |
338 | return; | 338 | return; |
339 | 339 | ||
340 | key = key_mtx_dereference(sdata->local, | 340 | key = key_mtx_dereference(sdata->local, |
@@ -343,7 +343,7 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) | |||
343 | sprintf(buf, "../keys/%d", key->debugfs.cnt); | 343 | sprintf(buf, "../keys/%d", key->debugfs.cnt); |
344 | sdata->debugfs.default_mgmt_key = | 344 | sdata->debugfs.default_mgmt_key = |
345 | debugfs_create_symlink("default_mgmt_key", | 345 | debugfs_create_symlink("default_mgmt_key", |
346 | sdata->debugfs.dir, buf); | 346 | sdata->vif.debugfs_dir, buf); |
347 | } else | 347 | } else |
348 | ieee80211_debugfs_key_remove_mgmt_default(sdata); | 348 | ieee80211_debugfs_key_remove_mgmt_default(sdata); |
349 | } | 349 | } |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 059bbb82e84f..ddb426867904 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -521,7 +521,7 @@ IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration, | |||
521 | #endif | 521 | #endif |
522 | 522 | ||
523 | #define DEBUGFS_ADD_MODE(name, mode) \ | 523 | #define DEBUGFS_ADD_MODE(name, mode) \ |
524 | debugfs_create_file(#name, mode, sdata->debugfs.dir, \ | 524 | debugfs_create_file(#name, mode, sdata->vif.debugfs_dir, \ |
525 | sdata, &name##_ops); | 525 | sdata, &name##_ops); |
526 | 526 | ||
527 | #define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400) | 527 | #define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400) |
@@ -577,7 +577,7 @@ static void add_mesh_files(struct ieee80211_sub_if_data *sdata) | |||
577 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) | 577 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) |
578 | { | 578 | { |
579 | struct dentry *dir = debugfs_create_dir("mesh_stats", | 579 | struct dentry *dir = debugfs_create_dir("mesh_stats", |
580 | sdata->debugfs.dir); | 580 | sdata->vif.debugfs_dir); |
581 | #define MESHSTATS_ADD(name)\ | 581 | #define MESHSTATS_ADD(name)\ |
582 | debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); | 582 | debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); |
583 | 583 | ||
@@ -594,7 +594,7 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) | |||
594 | static void add_mesh_config(struct ieee80211_sub_if_data *sdata) | 594 | static void add_mesh_config(struct ieee80211_sub_if_data *sdata) |
595 | { | 595 | { |
596 | struct dentry *dir = debugfs_create_dir("mesh_config", | 596 | struct dentry *dir = debugfs_create_dir("mesh_config", |
597 | sdata->debugfs.dir); | 597 | sdata->vif.debugfs_dir); |
598 | 598 | ||
599 | #define MESHPARAMS_ADD(name) \ | 599 | #define MESHPARAMS_ADD(name) \ |
600 | debugfs_create_file(#name, 0600, dir, sdata, &name##_ops); | 600 | debugfs_create_file(#name, 0600, dir, sdata, &name##_ops); |
@@ -631,7 +631,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) | |||
631 | 631 | ||
632 | static void add_files(struct ieee80211_sub_if_data *sdata) | 632 | static void add_files(struct ieee80211_sub_if_data *sdata) |
633 | { | 633 | { |
634 | if (!sdata->debugfs.dir) | 634 | if (!sdata->vif.debugfs_dir) |
635 | return; | 635 | return; |
636 | 636 | ||
637 | DEBUGFS_ADD(flags); | 637 | DEBUGFS_ADD(flags); |
@@ -673,21 +673,21 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) | |||
673 | char buf[10+IFNAMSIZ]; | 673 | char buf[10+IFNAMSIZ]; |
674 | 674 | ||
675 | sprintf(buf, "netdev:%s", sdata->name); | 675 | sprintf(buf, "netdev:%s", sdata->name); |
676 | sdata->debugfs.dir = debugfs_create_dir(buf, | 676 | sdata->vif.debugfs_dir = debugfs_create_dir(buf, |
677 | sdata->local->hw.wiphy->debugfsdir); | 677 | sdata->local->hw.wiphy->debugfsdir); |
678 | if (sdata->debugfs.dir) | 678 | if (sdata->vif.debugfs_dir) |
679 | sdata->debugfs.subdir_stations = debugfs_create_dir("stations", | 679 | sdata->debugfs.subdir_stations = debugfs_create_dir("stations", |
680 | sdata->debugfs.dir); | 680 | sdata->vif.debugfs_dir); |
681 | add_files(sdata); | 681 | add_files(sdata); |
682 | } | 682 | } |
683 | 683 | ||
684 | void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) | 684 | void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) |
685 | { | 685 | { |
686 | if (!sdata->debugfs.dir) | 686 | if (!sdata->vif.debugfs_dir) |
687 | return; | 687 | return; |
688 | 688 | ||
689 | debugfs_remove_recursive(sdata->debugfs.dir); | 689 | debugfs_remove_recursive(sdata->vif.debugfs_dir); |
690 | sdata->debugfs.dir = NULL; | 690 | sdata->vif.debugfs_dir = NULL; |
691 | } | 691 | } |
692 | 692 | ||
693 | void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) | 693 | void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) |
@@ -695,7 +695,7 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) | |||
695 | struct dentry *dir; | 695 | struct dentry *dir; |
696 | char buf[10 + IFNAMSIZ]; | 696 | char buf[10 + IFNAMSIZ]; |
697 | 697 | ||
698 | dir = sdata->debugfs.dir; | 698 | dir = sdata->vif.debugfs_dir; |
699 | 699 | ||
700 | if (!dir) | 700 | if (!dir) |
701 | return; | 701 | return; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 832acea4a5cb..169664c122e2 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -241,6 +241,22 @@ static inline u64 drv_prepare_multicast(struct ieee80211_local *local, | |||
241 | return ret; | 241 | return ret; |
242 | } | 242 | } |
243 | 243 | ||
244 | static inline void drv_set_multicast_list(struct ieee80211_local *local, | ||
245 | struct ieee80211_sub_if_data *sdata, | ||
246 | struct netdev_hw_addr_list *mc_list) | ||
247 | { | ||
248 | bool allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI; | ||
249 | |||
250 | trace_drv_set_multicast_list(local, sdata, mc_list->count); | ||
251 | |||
252 | check_sdata_in_driver(sdata); | ||
253 | |||
254 | if (local->ops->set_multicast_list) | ||
255 | local->ops->set_multicast_list(&local->hw, &sdata->vif, | ||
256 | allmulti, mc_list); | ||
257 | trace_drv_return_void(local); | ||
258 | } | ||
259 | |||
244 | static inline void drv_configure_filter(struct ieee80211_local *local, | 260 | static inline void drv_configure_filter(struct ieee80211_local *local, |
245 | unsigned int changed_flags, | 261 | unsigned int changed_flags, |
246 | unsigned int *total_flags, | 262 | unsigned int *total_flags, |
@@ -531,43 +547,6 @@ static inline void drv_sta_remove_debugfs(struct ieee80211_local *local, | |||
531 | local->ops->sta_remove_debugfs(&local->hw, &sdata->vif, | 547 | local->ops->sta_remove_debugfs(&local->hw, &sdata->vif, |
532 | sta, dir); | 548 | sta, dir); |
533 | } | 549 | } |
534 | |||
535 | static inline | ||
536 | void drv_add_interface_debugfs(struct ieee80211_local *local, | ||
537 | struct ieee80211_sub_if_data *sdata) | ||
538 | { | ||
539 | might_sleep(); | ||
540 | |||
541 | check_sdata_in_driver(sdata); | ||
542 | |||
543 | if (!local->ops->add_interface_debugfs) | ||
544 | return; | ||
545 | |||
546 | local->ops->add_interface_debugfs(&local->hw, &sdata->vif, | ||
547 | sdata->debugfs.dir); | ||
548 | } | ||
549 | |||
550 | static inline | ||
551 | void drv_remove_interface_debugfs(struct ieee80211_local *local, | ||
552 | struct ieee80211_sub_if_data *sdata) | ||
553 | { | ||
554 | might_sleep(); | ||
555 | |||
556 | check_sdata_in_driver(sdata); | ||
557 | |||
558 | if (!local->ops->remove_interface_debugfs) | ||
559 | return; | ||
560 | |||
561 | local->ops->remove_interface_debugfs(&local->hw, &sdata->vif, | ||
562 | sdata->debugfs.dir); | ||
563 | } | ||
564 | #else | ||
565 | static inline | ||
566 | void drv_add_interface_debugfs(struct ieee80211_local *local, | ||
567 | struct ieee80211_sub_if_data *sdata) {} | ||
568 | static inline | ||
569 | void drv_remove_interface_debugfs(struct ieee80211_local *local, | ||
570 | struct ieee80211_sub_if_data *sdata) {} | ||
571 | #endif | 550 | #endif |
572 | 551 | ||
573 | static inline __must_check | 552 | static inline __must_check |
@@ -741,13 +720,14 @@ static inline void drv_rfkill_poll(struct ieee80211_local *local) | |||
741 | local->ops->rfkill_poll(&local->hw); | 720 | local->ops->rfkill_poll(&local->hw); |
742 | } | 721 | } |
743 | 722 | ||
744 | static inline void drv_flush(struct ieee80211_local *local, bool drop) | 723 | static inline void drv_flush(struct ieee80211_local *local, |
724 | u32 queues, bool drop) | ||
745 | { | 725 | { |
746 | might_sleep(); | 726 | might_sleep(); |
747 | 727 | ||
748 | trace_drv_flush(local, drop); | 728 | trace_drv_flush(local, queues, drop); |
749 | if (local->ops->flush) | 729 | if (local->ops->flush) |
750 | local->ops->flush(&local->hw, drop); | 730 | local->ops->flush(&local->hw, queues, drop); |
751 | trace_drv_return_void(local); | 731 | trace_drv_return_void(local); |
752 | } | 732 | } |
753 | 733 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f4433f081e77..ae2d1754b792 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -758,7 +758,6 @@ struct ieee80211_sub_if_data { | |||
758 | 758 | ||
759 | #ifdef CONFIG_MAC80211_DEBUGFS | 759 | #ifdef CONFIG_MAC80211_DEBUGFS |
760 | struct { | 760 | struct { |
761 | struct dentry *dir; | ||
762 | struct dentry *subdir_stations; | 761 | struct dentry *subdir_stations; |
763 | struct dentry *default_unicast_key; | 762 | struct dentry *default_unicast_key; |
764 | struct dentry *default_multicast_key; | 763 | struct dentry *default_multicast_key; |
@@ -800,11 +799,6 @@ enum sdata_queue_type { | |||
800 | enum { | 799 | enum { |
801 | IEEE80211_RX_MSG = 1, | 800 | IEEE80211_RX_MSG = 1, |
802 | IEEE80211_TX_STATUS_MSG = 2, | 801 | IEEE80211_TX_STATUS_MSG = 2, |
803 | IEEE80211_EOSP_MSG = 3, | ||
804 | }; | ||
805 | |||
806 | struct skb_eosp_msg_data { | ||
807 | u8 sta[ETH_ALEN], iface[ETH_ALEN]; | ||
808 | }; | 802 | }; |
809 | 803 | ||
810 | enum queue_stop_reason { | 804 | enum queue_stop_reason { |
@@ -815,6 +809,7 @@ enum queue_stop_reason { | |||
815 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, | 809 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, |
816 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, | 810 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, |
817 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, | 811 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, |
812 | IEEE80211_QUEUE_STOP_REASON_FLUSH, | ||
818 | }; | 813 | }; |
819 | 814 | ||
820 | #ifdef CONFIG_MAC80211_LEDS | 815 | #ifdef CONFIG_MAC80211_LEDS |
@@ -1528,8 +1523,10 @@ void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, | |||
1528 | struct ieee80211_hdr *hdr, bool ack); | 1523 | struct ieee80211_hdr *hdr, bool ack); |
1529 | 1524 | ||
1530 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | 1525 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, |
1526 | unsigned long queues, | ||
1531 | enum queue_stop_reason reason); | 1527 | enum queue_stop_reason reason); |
1532 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 1528 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
1529 | unsigned long queues, | ||
1533 | enum queue_stop_reason reason); | 1530 | enum queue_stop_reason reason); |
1534 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | 1531 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, |
1535 | enum queue_stop_reason reason); | 1532 | enum queue_stop_reason reason); |
@@ -1546,6 +1543,8 @@ static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local, | |||
1546 | { | 1543 | { |
1547 | ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); | 1544 | ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); |
1548 | } | 1545 | } |
1546 | void ieee80211_flush_queues(struct ieee80211_local *local, | ||
1547 | struct ieee80211_sub_if_data *sdata); | ||
1549 | 1548 | ||
1550 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1549 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
1551 | u16 transaction, u16 auth_alg, u16 status, | 1550 | u16 transaction, u16 auth_alg, u16 status, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d85282f64405..d646e12e55a6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -92,7 +92,7 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) | |||
92 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) | 92 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) |
93 | return 0; | 93 | return 0; |
94 | 94 | ||
95 | drv_flush(local, false); | 95 | ieee80211_flush_queues(local, NULL); |
96 | 96 | ||
97 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; | 97 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; |
98 | return IEEE80211_CONF_CHANGE_IDLE; | 98 | return IEEE80211_CONF_CHANGE_IDLE; |
@@ -557,8 +557,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
557 | goto err_del_interface; | 557 | goto err_del_interface; |
558 | } | 558 | } |
559 | 559 | ||
560 | drv_add_interface_debugfs(local, sdata); | ||
561 | |||
562 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 560 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
563 | local->fif_pspoll++; | 561 | local->fif_pspoll++; |
564 | local->fif_probe_req++; | 562 | local->fif_probe_req++; |
@@ -846,8 +844,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
846 | case NL80211_IFTYPE_AP: | 844 | case NL80211_IFTYPE_AP: |
847 | skb_queue_purge(&sdata->skb_queue); | 845 | skb_queue_purge(&sdata->skb_queue); |
848 | 846 | ||
849 | drv_remove_interface_debugfs(local, sdata); | ||
850 | |||
851 | if (going_down) | 847 | if (going_down) |
852 | drv_remove_interface(local, sdata); | 848 | drv_remove_interface(local, sdata); |
853 | } | 849 | } |
@@ -919,6 +915,17 @@ static void ieee80211_set_multicast_list(struct net_device *dev) | |||
919 | atomic_dec(&local->iff_promiscs); | 915 | atomic_dec(&local->iff_promiscs); |
920 | sdata->flags ^= IEEE80211_SDATA_PROMISC; | 916 | sdata->flags ^= IEEE80211_SDATA_PROMISC; |
921 | } | 917 | } |
918 | |||
919 | /* | ||
920 | * TODO: If somebody needs this on AP interfaces, | ||
921 | * it can be enabled easily but multicast | ||
922 | * addresses from VLANs need to be synced. | ||
923 | */ | ||
924 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR && | ||
925 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | ||
926 | sdata->vif.type != NL80211_IFTYPE_AP) | ||
927 | drv_set_multicast_list(local, sdata, &dev->mc); | ||
928 | |||
922 | spin_lock_bh(&local->filter_lock); | 929 | spin_lock_bh(&local->filter_lock); |
923 | __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); | 930 | __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); |
924 | spin_unlock_bh(&local->filter_lock); | 931 | spin_unlock_bh(&local->filter_lock); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 99e9f6ae6a54..67059b88fea5 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -248,11 +248,11 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, | |||
248 | } | 248 | } |
249 | 249 | ||
250 | 250 | ||
251 | static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, | 251 | static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, |
252 | struct sta_info *sta, | 252 | struct sta_info *sta, |
253 | bool pairwise, | 253 | bool pairwise, |
254 | struct ieee80211_key *old, | 254 | struct ieee80211_key *old, |
255 | struct ieee80211_key *new) | 255 | struct ieee80211_key *new) |
256 | { | 256 | { |
257 | int idx; | 257 | int idx; |
258 | bool defunikey, defmultikey, defmgmtkey; | 258 | bool defunikey, defmultikey, defmgmtkey; |
@@ -397,25 +397,21 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | |||
397 | return key; | 397 | return key; |
398 | } | 398 | } |
399 | 399 | ||
400 | static void ieee80211_key_free_common(struct ieee80211_key *key) | ||
401 | { | ||
402 | if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP) | ||
403 | ieee80211_aes_key_free(key->u.ccmp.tfm); | ||
404 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) | ||
405 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); | ||
406 | kfree(key); | ||
407 | } | ||
408 | |||
400 | static void __ieee80211_key_destroy(struct ieee80211_key *key, | 409 | static void __ieee80211_key_destroy(struct ieee80211_key *key, |
401 | bool delay_tailroom) | 410 | bool delay_tailroom) |
402 | { | 411 | { |
403 | if (!key) | ||
404 | return; | ||
405 | |||
406 | /* | ||
407 | * Synchronize so the TX path can no longer be using | ||
408 | * this key before we free/remove it. | ||
409 | */ | ||
410 | synchronize_net(); | ||
411 | |||
412 | if (key->local) | 412 | if (key->local) |
413 | ieee80211_key_disable_hw_accel(key); | 413 | ieee80211_key_disable_hw_accel(key); |
414 | 414 | ||
415 | if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP) | ||
416 | ieee80211_aes_key_free(key->u.ccmp.tfm); | ||
417 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) | ||
418 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); | ||
419 | if (key->local) { | 415 | if (key->local) { |
420 | struct ieee80211_sub_if_data *sdata = key->sdata; | 416 | struct ieee80211_sub_if_data *sdata = key->sdata; |
421 | 417 | ||
@@ -431,7 +427,28 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key, | |||
431 | } | 427 | } |
432 | } | 428 | } |
433 | 429 | ||
434 | kfree(key); | 430 | ieee80211_key_free_common(key); |
431 | } | ||
432 | |||
433 | static void ieee80211_key_destroy(struct ieee80211_key *key, | ||
434 | bool delay_tailroom) | ||
435 | { | ||
436 | if (!key) | ||
437 | return; | ||
438 | |||
439 | /* | ||
440 | * Synchronize so the TX path can no longer be using | ||
441 | * this key before we free/remove it. | ||
442 | */ | ||
443 | synchronize_net(); | ||
444 | |||
445 | __ieee80211_key_destroy(key, delay_tailroom); | ||
446 | } | ||
447 | |||
448 | void ieee80211_key_free_unused(struct ieee80211_key *key) | ||
449 | { | ||
450 | WARN_ON(key->sdata || key->local); | ||
451 | ieee80211_key_free_common(key); | ||
435 | } | 452 | } |
436 | 453 | ||
437 | int ieee80211_key_link(struct ieee80211_key *key, | 454 | int ieee80211_key_link(struct ieee80211_key *key, |
@@ -462,19 +479,22 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
462 | 479 | ||
463 | increment_tailroom_need_count(sdata); | 480 | increment_tailroom_need_count(sdata); |
464 | 481 | ||
465 | __ieee80211_key_replace(sdata, sta, pairwise, old_key, key); | 482 | ieee80211_key_replace(sdata, sta, pairwise, old_key, key); |
466 | __ieee80211_key_destroy(old_key, true); | 483 | ieee80211_key_destroy(old_key, true); |
467 | 484 | ||
468 | ieee80211_debugfs_key_add(key); | 485 | ieee80211_debugfs_key_add(key); |
469 | 486 | ||
470 | ret = ieee80211_key_enable_hw_accel(key); | 487 | ret = ieee80211_key_enable_hw_accel(key); |
471 | 488 | ||
489 | if (ret) | ||
490 | ieee80211_key_free(key, true); | ||
491 | |||
472 | mutex_unlock(&sdata->local->key_mtx); | 492 | mutex_unlock(&sdata->local->key_mtx); |
473 | 493 | ||
474 | return ret; | 494 | return ret; |
475 | } | 495 | } |
476 | 496 | ||
477 | void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom) | 497 | void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom) |
478 | { | 498 | { |
479 | if (!key) | 499 | if (!key) |
480 | return; | 500 | return; |
@@ -483,18 +503,10 @@ void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom) | |||
483 | * Replace key with nothingness if it was ever used. | 503 | * Replace key with nothingness if it was ever used. |
484 | */ | 504 | */ |
485 | if (key->sdata) | 505 | if (key->sdata) |
486 | __ieee80211_key_replace(key->sdata, key->sta, | 506 | ieee80211_key_replace(key->sdata, key->sta, |
487 | key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, | 507 | key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, |
488 | key, NULL); | 508 | key, NULL); |
489 | __ieee80211_key_destroy(key, delay_tailroom); | 509 | ieee80211_key_destroy(key, delay_tailroom); |
490 | } | ||
491 | |||
492 | void ieee80211_key_free(struct ieee80211_local *local, | ||
493 | struct ieee80211_key *key) | ||
494 | { | ||
495 | mutex_lock(&local->key_mtx); | ||
496 | __ieee80211_key_free(key, true); | ||
497 | mutex_unlock(&local->key_mtx); | ||
498 | } | 510 | } |
499 | 511 | ||
500 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) | 512 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) |
@@ -554,6 +566,7 @@ EXPORT_SYMBOL(ieee80211_iter_keys); | |||
554 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) | 566 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) |
555 | { | 567 | { |
556 | struct ieee80211_key *key, *tmp; | 568 | struct ieee80211_key *key, *tmp; |
569 | LIST_HEAD(keys); | ||
557 | 570 | ||
558 | cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk); | 571 | cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk); |
559 | 572 | ||
@@ -565,17 +578,65 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) | |||
565 | 578 | ||
566 | ieee80211_debugfs_key_remove_mgmt_default(sdata); | 579 | ieee80211_debugfs_key_remove_mgmt_default(sdata); |
567 | 580 | ||
568 | list_for_each_entry_safe(key, tmp, &sdata->key_list, list) | 581 | list_for_each_entry_safe(key, tmp, &sdata->key_list, list) { |
569 | __ieee80211_key_free(key, false); | 582 | ieee80211_key_replace(key->sdata, key->sta, |
583 | key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, | ||
584 | key, NULL); | ||
585 | list_add_tail(&key->list, &keys); | ||
586 | } | ||
570 | 587 | ||
571 | ieee80211_debugfs_key_update_default(sdata); | 588 | ieee80211_debugfs_key_update_default(sdata); |
572 | 589 | ||
590 | if (!list_empty(&keys)) { | ||
591 | synchronize_net(); | ||
592 | list_for_each_entry_safe(key, tmp, &keys, list) | ||
593 | __ieee80211_key_destroy(key, false); | ||
594 | } | ||
595 | |||
573 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || | 596 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || |
574 | sdata->crypto_tx_tailroom_pending_dec); | 597 | sdata->crypto_tx_tailroom_pending_dec); |
575 | 598 | ||
576 | mutex_unlock(&sdata->local->key_mtx); | 599 | mutex_unlock(&sdata->local->key_mtx); |
577 | } | 600 | } |
578 | 601 | ||
602 | void ieee80211_free_sta_keys(struct ieee80211_local *local, | ||
603 | struct sta_info *sta) | ||
604 | { | ||
605 | struct ieee80211_key *key, *tmp; | ||
606 | LIST_HEAD(keys); | ||
607 | int i; | ||
608 | |||
609 | mutex_lock(&local->key_mtx); | ||
610 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { | ||
611 | key = key_mtx_dereference(local, sta->gtk[i]); | ||
612 | if (!key) | ||
613 | continue; | ||
614 | ieee80211_key_replace(key->sdata, key->sta, | ||
615 | key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, | ||
616 | key, NULL); | ||
617 | list_add(&key->list, &keys); | ||
618 | } | ||
619 | |||
620 | key = key_mtx_dereference(local, sta->ptk); | ||
621 | if (key) { | ||
622 | ieee80211_key_replace(key->sdata, key->sta, | ||
623 | key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, | ||
624 | key, NULL); | ||
625 | list_add(&key->list, &keys); | ||
626 | } | ||
627 | |||
628 | /* | ||
629 | * NB: the station code relies on this being | ||
630 | * done even if there aren't any keys | ||
631 | */ | ||
632 | synchronize_net(); | ||
633 | |||
634 | list_for_each_entry_safe(key, tmp, &keys, list) | ||
635 | __ieee80211_key_destroy(key, true); | ||
636 | |||
637 | mutex_unlock(&local->key_mtx); | ||
638 | } | ||
639 | |||
579 | void ieee80211_delayed_tailroom_dec(struct work_struct *wk) | 640 | void ieee80211_delayed_tailroom_dec(struct work_struct *wk) |
580 | { | 641 | { |
581 | struct ieee80211_sub_if_data *sdata; | 642 | struct ieee80211_sub_if_data *sdata; |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 2a682d81cee9..e8de3e6d7804 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -129,19 +129,20 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | |||
129 | size_t seq_len, const u8 *seq); | 129 | size_t seq_len, const u8 *seq); |
130 | /* | 130 | /* |
131 | * Insert a key into data structures (sdata, sta if necessary) | 131 | * Insert a key into data structures (sdata, sta if necessary) |
132 | * to make it used, free old key. | 132 | * to make it used, free old key. On failure, also free the new key. |
133 | */ | 133 | */ |
134 | int __must_check ieee80211_key_link(struct ieee80211_key *key, | 134 | int ieee80211_key_link(struct ieee80211_key *key, |
135 | struct ieee80211_sub_if_data *sdata, | 135 | struct ieee80211_sub_if_data *sdata, |
136 | struct sta_info *sta); | 136 | struct sta_info *sta); |
137 | void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom); | 137 | void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom); |
138 | void ieee80211_key_free(struct ieee80211_local *local, | 138 | void ieee80211_key_free_unused(struct ieee80211_key *key); |
139 | struct ieee80211_key *key); | ||
140 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, | 139 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, |
141 | bool uni, bool multi); | 140 | bool uni, bool multi); |
142 | void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, | 141 | void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, |
143 | int idx); | 142 | int idx); |
144 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); | 143 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); |
144 | void ieee80211_free_sta_keys(struct ieee80211_local *local, | ||
145 | struct sta_info *sta); | ||
145 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); | 146 | void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); |
146 | 147 | ||
147 | #define key_mtx_dereference(local, ref) \ | 148 | #define key_mtx_dereference(local, ref) \ |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 5a53aa5ede80..c6f81ecc36a1 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -100,7 +100,6 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) | |||
100 | int power; | 100 | int power; |
101 | enum nl80211_channel_type channel_type; | 101 | enum nl80211_channel_type channel_type; |
102 | u32 offchannel_flag; | 102 | u32 offchannel_flag; |
103 | bool scanning = false; | ||
104 | 103 | ||
105 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 104 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
106 | if (local->scan_channel) { | 105 | if (local->scan_channel) { |
@@ -147,9 +146,6 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) | |||
147 | changed |= IEEE80211_CONF_CHANGE_SMPS; | 146 | changed |= IEEE80211_CONF_CHANGE_SMPS; |
148 | } | 147 | } |
149 | 148 | ||
150 | scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || | ||
151 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || | ||
152 | test_bit(SCAN_HW_SCANNING, &local->scanning); | ||
153 | power = chan->max_power; | 149 | power = chan->max_power; |
154 | 150 | ||
155 | rcu_read_lock(); | 151 | rcu_read_lock(); |
@@ -226,8 +222,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | |||
226 | static void ieee80211_tasklet_handler(unsigned long data) | 222 | static void ieee80211_tasklet_handler(unsigned long data) |
227 | { | 223 | { |
228 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 224 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
229 | struct sta_info *sta, *tmp; | ||
230 | struct skb_eosp_msg_data *eosp_data; | ||
231 | struct sk_buff *skb; | 225 | struct sk_buff *skb; |
232 | 226 | ||
233 | while ((skb = skb_dequeue(&local->skb_queue)) || | 227 | while ((skb = skb_dequeue(&local->skb_queue)) || |
@@ -243,18 +237,6 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
243 | skb->pkt_type = 0; | 237 | skb->pkt_type = 0; |
244 | ieee80211_tx_status(&local->hw, skb); | 238 | ieee80211_tx_status(&local->hw, skb); |
245 | break; | 239 | break; |
246 | case IEEE80211_EOSP_MSG: | ||
247 | eosp_data = (void *)skb->cb; | ||
248 | for_each_sta_info(local, eosp_data->sta, sta, tmp) { | ||
249 | /* skip wrong virtual interface */ | ||
250 | if (memcmp(eosp_data->iface, | ||
251 | sta->sdata->vif.addr, ETH_ALEN)) | ||
252 | continue; | ||
253 | clear_sta_flag(sta, WLAN_STA_SP); | ||
254 | break; | ||
255 | } | ||
256 | dev_kfree_skb(skb); | ||
257 | break; | ||
258 | default: | 240 | default: |
259 | WARN(1, "mac80211: Packet is of unknown type %d\n", | 241 | WARN(1, "mac80211: Packet is of unknown type %d\n", |
260 | skb->pkt_type); | 242 | skb->pkt_type); |
@@ -295,8 +277,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) | |||
295 | "Hardware restart was requested\n"); | 277 | "Hardware restart was requested\n"); |
296 | 278 | ||
297 | /* use this reason, ieee80211_reconfig will unblock it */ | 279 | /* use this reason, ieee80211_reconfig will unblock it */ |
298 | ieee80211_stop_queues_by_reason(hw, | 280 | ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, |
299 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 281 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
300 | 282 | ||
301 | /* | 283 | /* |
302 | * Stop all Rx during the reconfig. We don't want state changes | 284 | * Stop all Rx during the reconfig. We don't want state changes |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 5ac017f3fcd2..aead5410c622 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -699,10 +699,8 @@ out_free: | |||
699 | static int | 699 | static int |
700 | ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh) | 700 | ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh) |
701 | { | 701 | { |
702 | struct ieee80211_sub_if_data *sdata; | ||
703 | struct beacon_data *old_bcn; | 702 | struct beacon_data *old_bcn; |
704 | int ret; | 703 | int ret; |
705 | sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh); | ||
706 | 704 | ||
707 | mutex_lock(&ifmsh->mtx); | 705 | mutex_lock(&ifmsh->mtx); |
708 | 706 | ||
@@ -833,9 +831,8 @@ ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata, | |||
833 | struct ieee80211_mgmt *hdr; | 831 | struct ieee80211_mgmt *hdr; |
834 | struct ieee802_11_elems elems; | 832 | struct ieee802_11_elems elems; |
835 | size_t baselen; | 833 | size_t baselen; |
836 | u8 *pos, *end; | 834 | u8 *pos; |
837 | 835 | ||
838 | end = ((u8 *) mgmt) + len; | ||
839 | pos = mgmt->u.probe_req.variable; | 836 | pos = mgmt->u.probe_req.variable; |
840 | baselen = (u8 *) pos - (u8 *) mgmt; | 837 | baselen = (u8 *) pos - (u8 *) mgmt; |
841 | if (baselen > len) | 838 | if (baselen > len) |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fdc06e381c10..4d383a93ea73 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1009,6 +1009,7 @@ static void ieee80211_chswitch_work(struct work_struct *work) | |||
1009 | 1009 | ||
1010 | /* XXX: wait for a beacon first? */ | 1010 | /* XXX: wait for a beacon first? */ |
1011 | ieee80211_wake_queues_by_reason(&sdata->local->hw, | 1011 | ieee80211_wake_queues_by_reason(&sdata->local->hw, |
1012 | IEEE80211_MAX_QUEUE_MAP, | ||
1012 | IEEE80211_QUEUE_STOP_REASON_CSA); | 1013 | IEEE80211_QUEUE_STOP_REASON_CSA); |
1013 | out: | 1014 | out: |
1014 | ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; | 1015 | ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; |
@@ -1108,6 +1109,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1108 | 1109 | ||
1109 | if (sw_elem->mode) | 1110 | if (sw_elem->mode) |
1110 | ieee80211_stop_queues_by_reason(&sdata->local->hw, | 1111 | ieee80211_stop_queues_by_reason(&sdata->local->hw, |
1112 | IEEE80211_MAX_QUEUE_MAP, | ||
1111 | IEEE80211_QUEUE_STOP_REASON_CSA); | 1113 | IEEE80211_QUEUE_STOP_REASON_CSA); |
1112 | 1114 | ||
1113 | if (sdata->local->ops->channel_switch) { | 1115 | if (sdata->local->ops->channel_switch) { |
@@ -1375,6 +1377,7 @@ void ieee80211_dynamic_ps_disable_work(struct work_struct *work) | |||
1375 | } | 1377 | } |
1376 | 1378 | ||
1377 | ieee80211_wake_queues_by_reason(&local->hw, | 1379 | ieee80211_wake_queues_by_reason(&local->hw, |
1380 | IEEE80211_MAX_QUEUE_MAP, | ||
1378 | IEEE80211_QUEUE_STOP_REASON_PS); | 1381 | IEEE80211_QUEUE_STOP_REASON_PS); |
1379 | } | 1382 | } |
1380 | 1383 | ||
@@ -1436,7 +1439,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | |||
1436 | else { | 1439 | else { |
1437 | ieee80211_send_nullfunc(local, sdata, 1); | 1440 | ieee80211_send_nullfunc(local, sdata, 1); |
1438 | /* Flush to get the tx status of nullfunc frame */ | 1441 | /* Flush to get the tx status of nullfunc frame */ |
1439 | drv_flush(local, false); | 1442 | ieee80211_flush_queues(local, sdata); |
1440 | } | 1443 | } |
1441 | } | 1444 | } |
1442 | 1445 | ||
@@ -1767,7 +1770,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1767 | 1770 | ||
1768 | /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ | 1771 | /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ |
1769 | if (tx) | 1772 | if (tx) |
1770 | drv_flush(local, false); | 1773 | ieee80211_flush_queues(local, sdata); |
1771 | 1774 | ||
1772 | /* deauthenticate/disassociate now */ | 1775 | /* deauthenticate/disassociate now */ |
1773 | if (tx || frame_buf) | 1776 | if (tx || frame_buf) |
@@ -1776,7 +1779,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1776 | 1779 | ||
1777 | /* flush out frame */ | 1780 | /* flush out frame */ |
1778 | if (tx) | 1781 | if (tx) |
1779 | drv_flush(local, false); | 1782 | ieee80211_flush_queues(local, sdata); |
1780 | 1783 | ||
1781 | /* clear bssid only after building the needed mgmt frames */ | 1784 | /* clear bssid only after building the needed mgmt frames */ |
1782 | memset(ifmgd->bssid, 0, ETH_ALEN); | 1785 | memset(ifmgd->bssid, 0, ETH_ALEN); |
@@ -1948,7 +1951,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | |||
1948 | ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); | 1951 | ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); |
1949 | run_again(ifmgd, ifmgd->probe_timeout); | 1952 | run_again(ifmgd, ifmgd->probe_timeout); |
1950 | if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | 1953 | if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) |
1951 | drv_flush(sdata->local, false); | 1954 | ieee80211_flush_queues(sdata->local, sdata); |
1952 | } | 1955 | } |
1953 | 1956 | ||
1954 | static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | 1957 | static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, |
@@ -2071,6 +2074,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) | |||
2071 | true, frame_buf); | 2074 | true, frame_buf); |
2072 | ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; | 2075 | ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; |
2073 | ieee80211_wake_queues_by_reason(&sdata->local->hw, | 2076 | ieee80211_wake_queues_by_reason(&sdata->local->hw, |
2077 | IEEE80211_MAX_QUEUE_MAP, | ||
2074 | IEEE80211_QUEUE_STOP_REASON_CSA); | 2078 | IEEE80211_QUEUE_STOP_REASON_CSA); |
2075 | mutex_unlock(&ifmgd->mtx); | 2079 | mutex_unlock(&ifmgd->mtx); |
2076 | 2080 | ||
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index db547fceaeb9..b01eb7314ec6 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -118,9 +118,9 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local) | |||
118 | * Stop queues and transmit all frames queued by the driver | 118 | * Stop queues and transmit all frames queued by the driver |
119 | * before sending nullfunc to enable powersave at the AP. | 119 | * before sending nullfunc to enable powersave at the AP. |
120 | */ | 120 | */ |
121 | ieee80211_stop_queues_by_reason(&local->hw, | 121 | ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, |
122 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); | 122 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); |
123 | drv_flush(local, false); | 123 | ieee80211_flush_queues(local, NULL); |
124 | 124 | ||
125 | mutex_lock(&local->iflist_mtx); | 125 | mutex_lock(&local->iflist_mtx); |
126 | list_for_each_entry(sdata, &local->interfaces, list) { | 126 | list_for_each_entry(sdata, &local->interfaces, list) { |
@@ -181,7 +181,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local) | |||
181 | } | 181 | } |
182 | mutex_unlock(&local->iflist_mtx); | 182 | mutex_unlock(&local->iflist_mtx); |
183 | 183 | ||
184 | ieee80211_wake_queues_by_reason(&local->hw, | 184 | ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, |
185 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); | 185 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); |
186 | } | 186 | } |
187 | 187 | ||
@@ -373,7 +373,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
373 | ieee80211_roc_notify_destroy(roc); | 373 | ieee80211_roc_notify_destroy(roc); |
374 | 374 | ||
375 | if (started) { | 375 | if (started) { |
376 | drv_flush(local, false); | 376 | ieee80211_flush_queues(local, NULL); |
377 | 377 | ||
378 | local->tmp_channel = NULL; | 378 | local->tmp_channel = NULL; |
379 | ieee80211_hw_config(local, 0); | 379 | ieee80211_hw_config(local, 0); |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index b471a67f224d..3d16f4e61743 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -30,12 +30,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
30 | } | 30 | } |
31 | 31 | ||
32 | ieee80211_stop_queues_by_reason(hw, | 32 | ieee80211_stop_queues_by_reason(hw, |
33 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 33 | IEEE80211_MAX_QUEUE_MAP, |
34 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | ||
34 | 35 | ||
35 | /* flush out all packets */ | 36 | /* flush out all packets */ |
36 | synchronize_net(); | 37 | synchronize_net(); |
37 | 38 | ||
38 | drv_flush(local, false); | 39 | ieee80211_flush_queues(local, NULL); |
39 | 40 | ||
40 | local->quiescing = true; | 41 | local->quiescing = true; |
41 | /* make quiescing visible to timers everywhere */ | 42 | /* make quiescing visible to timers everywhere */ |
@@ -68,6 +69,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
68 | mutex_unlock(&local->sta_mtx); | 69 | mutex_unlock(&local->sta_mtx); |
69 | } | 70 | } |
70 | ieee80211_wake_queues_by_reason(hw, | 71 | ieee80211_wake_queues_by_reason(hw, |
72 | IEEE80211_MAX_QUEUE_MAP, | ||
71 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 73 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
72 | return err; | 74 | return err; |
73 | } else if (err > 0) { | 75 | } else if (err > 0) { |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 749552bdcfe1..d2b264d1311d 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -202,14 +202,23 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) | |||
202 | struct minstrel_rate_stats *mr; | 202 | struct minstrel_rate_stats *mr; |
203 | unsigned int nsecs = 0; | 203 | unsigned int nsecs = 0; |
204 | unsigned int tp; | 204 | unsigned int tp; |
205 | unsigned int prob; | ||
205 | 206 | ||
206 | mr = &mi->groups[group].rates[rate]; | 207 | mr = &mi->groups[group].rates[rate]; |
208 | prob = mr->probability; | ||
207 | 209 | ||
208 | if (mr->probability < MINSTREL_FRAC(1, 10)) { | 210 | if (prob < MINSTREL_FRAC(1, 10)) { |
209 | mr->cur_tp = 0; | 211 | mr->cur_tp = 0; |
210 | return; | 212 | return; |
211 | } | 213 | } |
212 | 214 | ||
215 | /* | ||
216 | * For the throughput calculation, limit the probability value to 90% to | ||
217 | * account for collision related packet error rate fluctuation | ||
218 | */ | ||
219 | if (prob > MINSTREL_FRAC(9, 10)) | ||
220 | prob = MINSTREL_FRAC(9, 10); | ||
221 | |||
213 | if (group != MINSTREL_CCK_GROUP) | 222 | if (group != MINSTREL_CCK_GROUP) |
214 | nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); | 223 | nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); |
215 | 224 | ||
@@ -639,15 +648,18 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
639 | /* | 648 | /* |
640 | * Sampling might add some overhead (RTS, no aggregation) | 649 | * Sampling might add some overhead (RTS, no aggregation) |
641 | * to the frame. Hence, don't use sampling for the currently | 650 | * to the frame. Hence, don't use sampling for the currently |
642 | * used max TP rate. | 651 | * used rates. |
643 | */ | 652 | */ |
644 | if (sample_idx == mi->max_tp_rate) | 653 | if (sample_idx == mi->max_tp_rate || |
654 | sample_idx == mi->max_tp_rate2 || | ||
655 | sample_idx == mi->max_prob_rate) | ||
645 | return -1; | 656 | return -1; |
657 | |||
646 | /* | 658 | /* |
647 | * When not using MRR, do not sample if the probability is already | 659 | * Do not sample if the probability is already higher than 95% |
648 | * higher than 95% to avoid wasting airtime | 660 | * to avoid wasting airtime. |
649 | */ | 661 | */ |
650 | if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100))) | 662 | if (mr->probability > MINSTREL_FRAC(95, 100)) |
651 | return -1; | 663 | return -1; |
652 | 664 | ||
653 | /* | 665 | /* |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 43a45cf00e06..cb34cbbaa20c 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -153,7 +153,6 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) | |||
153 | u8 *elements; | 153 | u8 *elements; |
154 | struct ieee80211_channel *channel; | 154 | struct ieee80211_channel *channel; |
155 | size_t baselen; | 155 | size_t baselen; |
156 | bool beacon; | ||
157 | struct ieee802_11_elems elems; | 156 | struct ieee802_11_elems elems; |
158 | 157 | ||
159 | if (skb->len < 24 || | 158 | if (skb->len < 24 || |
@@ -175,11 +174,9 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) | |||
175 | 174 | ||
176 | elements = mgmt->u.probe_resp.variable; | 175 | elements = mgmt->u.probe_resp.variable; |
177 | baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); | 176 | baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); |
178 | beacon = false; | ||
179 | } else { | 177 | } else { |
180 | baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); | 178 | baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); |
181 | elements = mgmt->u.beacon.variable; | 179 | elements = mgmt->u.beacon.variable; |
182 | beacon = true; | ||
183 | } | 180 | } |
184 | 181 | ||
185 | if (baselen > skb->len) | 182 | if (baselen > skb->len) |
@@ -335,7 +332,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
335 | ieee80211_offchannel_stop_vifs(local); | 332 | ieee80211_offchannel_stop_vifs(local); |
336 | 333 | ||
337 | /* ensure nullfunc is transmitted before leaving operating channel */ | 334 | /* ensure nullfunc is transmitted before leaving operating channel */ |
338 | drv_flush(local, false); | 335 | ieee80211_flush_queues(local, NULL); |
339 | 336 | ||
340 | ieee80211_configure_filter(local); | 337 | ieee80211_configure_filter(local); |
341 | 338 | ||
@@ -671,7 +668,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local, | |||
671 | ieee80211_offchannel_stop_vifs(local); | 668 | ieee80211_offchannel_stop_vifs(local); |
672 | 669 | ||
673 | if (local->ops->flush) { | 670 | if (local->ops->flush) { |
674 | drv_flush(local, false); | 671 | ieee80211_flush_queues(local, NULL); |
675 | *next_delay = 0; | 672 | *next_delay = 0; |
676 | } else | 673 | } else |
677 | *next_delay = HZ / 10; | 674 | *next_delay = HZ / 10; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 3644ad79688a..11216bc13b27 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -556,6 +556,15 @@ static inline void __bss_tim_clear(u8 *tim, u16 id) | |||
556 | tim[id / 8] &= ~(1 << (id % 8)); | 556 | tim[id / 8] &= ~(1 << (id % 8)); |
557 | } | 557 | } |
558 | 558 | ||
559 | static inline bool __bss_tim_get(u8 *tim, u16 id) | ||
560 | { | ||
561 | /* | ||
562 | * This format has been mandated by the IEEE specifications, | ||
563 | * so this line may not be changed to use the test_bit() format. | ||
564 | */ | ||
565 | return tim[id / 8] & (1 << (id % 8)); | ||
566 | } | ||
567 | |||
559 | static unsigned long ieee80211_tids_for_ac(int ac) | 568 | static unsigned long ieee80211_tids_for_ac(int ac) |
560 | { | 569 | { |
561 | /* If we ever support TIDs > 7, this obviously needs to be adjusted */ | 570 | /* If we ever support TIDs > 7, this obviously needs to be adjusted */ |
@@ -636,6 +645,9 @@ void sta_info_recalc_tim(struct sta_info *sta) | |||
636 | done: | 645 | done: |
637 | spin_lock_bh(&local->tim_lock); | 646 | spin_lock_bh(&local->tim_lock); |
638 | 647 | ||
648 | if (indicate_tim == __bss_tim_get(ps->tim, id)) | ||
649 | goto out_unlock; | ||
650 | |||
639 | if (indicate_tim) | 651 | if (indicate_tim) |
640 | __bss_tim_set(ps->tim, id); | 652 | __bss_tim_set(ps->tim, id); |
641 | else | 653 | else |
@@ -647,6 +659,7 @@ void sta_info_recalc_tim(struct sta_info *sta) | |||
647 | local->tim_in_locked_section = false; | 659 | local->tim_in_locked_section = false; |
648 | } | 660 | } |
649 | 661 | ||
662 | out_unlock: | ||
650 | spin_unlock_bh(&local->tim_lock); | 663 | spin_unlock_bh(&local->tim_lock); |
651 | } | 664 | } |
652 | 665 | ||
@@ -770,7 +783,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta) | |||
770 | { | 783 | { |
771 | struct ieee80211_local *local; | 784 | struct ieee80211_local *local; |
772 | struct ieee80211_sub_if_data *sdata; | 785 | struct ieee80211_sub_if_data *sdata; |
773 | int ret, i; | 786 | int ret; |
774 | 787 | ||
775 | might_sleep(); | 788 | might_sleep(); |
776 | 789 | ||
@@ -797,14 +810,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta) | |||
797 | 810 | ||
798 | list_del_rcu(&sta->list); | 811 | list_del_rcu(&sta->list); |
799 | 812 | ||
800 | mutex_lock(&local->key_mtx); | 813 | /* this always calls synchronize_net() */ |
801 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) | 814 | ieee80211_free_sta_keys(local, sta); |
802 | __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]), | ||
803 | true); | ||
804 | if (sta->ptk) | ||
805 | __ieee80211_key_free(key_mtx_dereference(local, sta->ptk), | ||
806 | true); | ||
807 | mutex_unlock(&local->key_mtx); | ||
808 | 815 | ||
809 | sta->dead = true; | 816 | sta->dead = true; |
810 | 817 | ||
@@ -1390,30 +1397,16 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | |||
1390 | } | 1397 | } |
1391 | EXPORT_SYMBOL(ieee80211_sta_block_awake); | 1398 | EXPORT_SYMBOL(ieee80211_sta_block_awake); |
1392 | 1399 | ||
1393 | void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta) | 1400 | void ieee80211_sta_eosp(struct ieee80211_sta *pubsta) |
1394 | { | 1401 | { |
1395 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 1402 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
1396 | struct ieee80211_local *local = sta->local; | 1403 | struct ieee80211_local *local = sta->local; |
1397 | struct sk_buff *skb; | ||
1398 | struct skb_eosp_msg_data *data; | ||
1399 | 1404 | ||
1400 | trace_api_eosp(local, pubsta); | 1405 | trace_api_eosp(local, pubsta); |
1401 | 1406 | ||
1402 | skb = alloc_skb(0, GFP_ATOMIC); | 1407 | clear_sta_flag(sta, WLAN_STA_SP); |
1403 | if (!skb) { | ||
1404 | /* too bad ... but race is better than loss */ | ||
1405 | clear_sta_flag(sta, WLAN_STA_SP); | ||
1406 | return; | ||
1407 | } | ||
1408 | |||
1409 | data = (void *)skb->cb; | ||
1410 | memcpy(data->sta, pubsta->addr, ETH_ALEN); | ||
1411 | memcpy(data->iface, sta->sdata->vif.addr, ETH_ALEN); | ||
1412 | skb->pkt_type = IEEE80211_EOSP_MSG; | ||
1413 | skb_queue_tail(&local->skb_queue, skb); | ||
1414 | tasklet_schedule(&local->tasklet); | ||
1415 | } | 1408 | } |
1416 | EXPORT_SYMBOL(ieee80211_sta_eosp_irqsafe); | 1409 | EXPORT_SYMBOL(ieee80211_sta_eosp); |
1417 | 1410 | ||
1418 | void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, | 1411 | void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, |
1419 | u8 tid, bool buffered) | 1412 | u8 tid, bool buffered) |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index e5868c32d1a3..adc30045f99e 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -333,7 +333,8 @@ struct sta_info { | |||
333 | unsigned long driver_buffered_tids; | 333 | unsigned long driver_buffered_tids; |
334 | 334 | ||
335 | /* Updated from RX path only, no locking requirements */ | 335 | /* Updated from RX path only, no locking requirements */ |
336 | unsigned long rx_packets, rx_bytes; | 336 | unsigned long rx_packets; |
337 | u64 rx_bytes; | ||
337 | unsigned long wep_weak_iv_count; | 338 | unsigned long wep_weak_iv_count; |
338 | unsigned long last_rx; | 339 | unsigned long last_rx; |
339 | long last_connected; | 340 | long last_connected; |
@@ -353,9 +354,9 @@ struct sta_info { | |||
353 | unsigned int fail_avg; | 354 | unsigned int fail_avg; |
354 | 355 | ||
355 | /* Updated from TX path only, no locking requirements */ | 356 | /* Updated from TX path only, no locking requirements */ |
356 | unsigned long tx_packets; | 357 | u32 tx_fragments; |
357 | unsigned long tx_bytes; | 358 | u64 tx_packets[IEEE80211_NUM_ACS]; |
358 | unsigned long tx_fragments; | 359 | u64 tx_bytes[IEEE80211_NUM_ACS]; |
359 | struct ieee80211_tx_rate last_tx_rate; | 360 | struct ieee80211_tx_rate last_tx_rate; |
360 | int last_rx_rate_idx; | 361 | int last_rx_rate_idx; |
361 | u32 last_rx_rate_flag; | 362 | u32 last_rx_rate_flag; |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index e7db2b804e0c..c5899797a8d4 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -431,6 +431,30 @@ TRACE_EVENT(drv_prepare_multicast, | |||
431 | ) | 431 | ) |
432 | ); | 432 | ); |
433 | 433 | ||
434 | TRACE_EVENT(drv_set_multicast_list, | ||
435 | TP_PROTO(struct ieee80211_local *local, | ||
436 | struct ieee80211_sub_if_data *sdata, int mc_count), | ||
437 | |||
438 | TP_ARGS(local, sdata, mc_count), | ||
439 | |||
440 | TP_STRUCT__entry( | ||
441 | LOCAL_ENTRY | ||
442 | __field(bool, allmulti) | ||
443 | __field(int, mc_count) | ||
444 | ), | ||
445 | |||
446 | TP_fast_assign( | ||
447 | LOCAL_ASSIGN; | ||
448 | __entry->allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI; | ||
449 | __entry->mc_count = mc_count; | ||
450 | ), | ||
451 | |||
452 | TP_printk( | ||
453 | LOCAL_PR_FMT " configure mc filter, count=%d, allmulti=%d", | ||
454 | LOCAL_PR_ARG, __entry->mc_count, __entry->allmulti | ||
455 | ) | ||
456 | ); | ||
457 | |||
434 | TRACE_EVENT(drv_configure_filter, | 458 | TRACE_EVENT(drv_configure_filter, |
435 | TP_PROTO(struct ieee80211_local *local, | 459 | TP_PROTO(struct ieee80211_local *local, |
436 | unsigned int changed_flags, | 460 | unsigned int changed_flags, |
@@ -940,23 +964,26 @@ TRACE_EVENT(drv_get_survey, | |||
940 | ); | 964 | ); |
941 | 965 | ||
942 | TRACE_EVENT(drv_flush, | 966 | TRACE_EVENT(drv_flush, |
943 | TP_PROTO(struct ieee80211_local *local, bool drop), | 967 | TP_PROTO(struct ieee80211_local *local, |
968 | u32 queues, bool drop), | ||
944 | 969 | ||
945 | TP_ARGS(local, drop), | 970 | TP_ARGS(local, queues, drop), |
946 | 971 | ||
947 | TP_STRUCT__entry( | 972 | TP_STRUCT__entry( |
948 | LOCAL_ENTRY | 973 | LOCAL_ENTRY |
949 | __field(bool, drop) | 974 | __field(bool, drop) |
975 | __field(u32, queues) | ||
950 | ), | 976 | ), |
951 | 977 | ||
952 | TP_fast_assign( | 978 | TP_fast_assign( |
953 | LOCAL_ASSIGN; | 979 | LOCAL_ASSIGN; |
954 | __entry->drop = drop; | 980 | __entry->drop = drop; |
981 | __entry->queues = queues; | ||
955 | ), | 982 | ), |
956 | 983 | ||
957 | TP_printk( | 984 | TP_printk( |
958 | LOCAL_PR_FMT " drop:%d", | 985 | LOCAL_PR_FMT " queues:0x%x drop:%d", |
959 | LOCAL_PR_ARG, __entry->drop | 986 | LOCAL_PR_ARG, __entry->queues, __entry->drop |
960 | ) | 987 | ) |
961 | ); | 988 | ); |
962 | 989 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 8914d2d2881a..2a6ae8030bd9 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -233,6 +233,7 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) | |||
233 | 233 | ||
234 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 234 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
235 | ieee80211_stop_queues_by_reason(&local->hw, | 235 | ieee80211_stop_queues_by_reason(&local->hw, |
236 | IEEE80211_MAX_QUEUE_MAP, | ||
236 | IEEE80211_QUEUE_STOP_REASON_PS); | 237 | IEEE80211_QUEUE_STOP_REASON_PS); |
237 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; | 238 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; |
238 | ieee80211_queue_work(&local->hw, | 239 | ieee80211_queue_work(&local->hw, |
@@ -991,15 +992,18 @@ static ieee80211_tx_result debug_noinline | |||
991 | ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) | 992 | ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) |
992 | { | 993 | { |
993 | struct sk_buff *skb; | 994 | struct sk_buff *skb; |
995 | int ac = -1; | ||
994 | 996 | ||
995 | if (!tx->sta) | 997 | if (!tx->sta) |
996 | return TX_CONTINUE; | 998 | return TX_CONTINUE; |
997 | 999 | ||
998 | tx->sta->tx_packets++; | ||
999 | skb_queue_walk(&tx->skbs, skb) { | 1000 | skb_queue_walk(&tx->skbs, skb) { |
1001 | ac = skb_get_queue_mapping(skb); | ||
1000 | tx->sta->tx_fragments++; | 1002 | tx->sta->tx_fragments++; |
1001 | tx->sta->tx_bytes += skb->len; | 1003 | tx->sta->tx_bytes[ac] += skb->len; |
1002 | } | 1004 | } |
1005 | if (ac >= 0) | ||
1006 | tx->sta->tx_packets[ac]++; | ||
1003 | 1007 | ||
1004 | return TX_CONTINUE; | 1008 | return TX_CONTINUE; |
1005 | } | 1009 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index b7a856e3281b..a7368870c8ee 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -453,7 +453,8 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | |||
453 | } | 453 | } |
454 | 454 | ||
455 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 455 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
456 | enum queue_stop_reason reason) | 456 | unsigned long queues, |
457 | enum queue_stop_reason reason) | ||
457 | { | 458 | { |
458 | struct ieee80211_local *local = hw_to_local(hw); | 459 | struct ieee80211_local *local = hw_to_local(hw); |
459 | unsigned long flags; | 460 | unsigned long flags; |
@@ -461,7 +462,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | |||
461 | 462 | ||
462 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | 463 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); |
463 | 464 | ||
464 | for (i = 0; i < hw->queues; i++) | 465 | for_each_set_bit(i, &queues, hw->queues) |
465 | __ieee80211_stop_queue(hw, i, reason); | 466 | __ieee80211_stop_queue(hw, i, reason); |
466 | 467 | ||
467 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 468 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
@@ -469,7 +470,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | |||
469 | 470 | ||
470 | void ieee80211_stop_queues(struct ieee80211_hw *hw) | 471 | void ieee80211_stop_queues(struct ieee80211_hw *hw) |
471 | { | 472 | { |
472 | ieee80211_stop_queues_by_reason(hw, | 473 | ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, |
473 | IEEE80211_QUEUE_STOP_REASON_DRIVER); | 474 | IEEE80211_QUEUE_STOP_REASON_DRIVER); |
474 | } | 475 | } |
475 | EXPORT_SYMBOL(ieee80211_stop_queues); | 476 | EXPORT_SYMBOL(ieee80211_stop_queues); |
@@ -491,6 +492,7 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) | |||
491 | EXPORT_SYMBOL(ieee80211_queue_stopped); | 492 | EXPORT_SYMBOL(ieee80211_queue_stopped); |
492 | 493 | ||
493 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | 494 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, |
495 | unsigned long queues, | ||
494 | enum queue_stop_reason reason) | 496 | enum queue_stop_reason reason) |
495 | { | 497 | { |
496 | struct ieee80211_local *local = hw_to_local(hw); | 498 | struct ieee80211_local *local = hw_to_local(hw); |
@@ -499,7 +501,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | |||
499 | 501 | ||
500 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | 502 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); |
501 | 503 | ||
502 | for (i = 0; i < hw->queues; i++) | 504 | for_each_set_bit(i, &queues, hw->queues) |
503 | __ieee80211_wake_queue(hw, i, reason); | 505 | __ieee80211_wake_queue(hw, i, reason); |
504 | 506 | ||
505 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 507 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
@@ -507,10 +509,42 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | |||
507 | 509 | ||
508 | void ieee80211_wake_queues(struct ieee80211_hw *hw) | 510 | void ieee80211_wake_queues(struct ieee80211_hw *hw) |
509 | { | 511 | { |
510 | ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER); | 512 | ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, |
513 | IEEE80211_QUEUE_STOP_REASON_DRIVER); | ||
511 | } | 514 | } |
512 | EXPORT_SYMBOL(ieee80211_wake_queues); | 515 | EXPORT_SYMBOL(ieee80211_wake_queues); |
513 | 516 | ||
517 | void ieee80211_flush_queues(struct ieee80211_local *local, | ||
518 | struct ieee80211_sub_if_data *sdata) | ||
519 | { | ||
520 | u32 queues; | ||
521 | |||
522 | if (!local->ops->flush) | ||
523 | return; | ||
524 | |||
525 | if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) { | ||
526 | int ac; | ||
527 | |||
528 | queues = 0; | ||
529 | |||
530 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
531 | queues |= BIT(sdata->vif.hw_queue[ac]); | ||
532 | if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE) | ||
533 | queues |= BIT(sdata->vif.cab_queue); | ||
534 | } else { | ||
535 | /* all queues */ | ||
536 | queues = BIT(local->hw.queues) - 1; | ||
537 | } | ||
538 | |||
539 | ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, | ||
540 | IEEE80211_QUEUE_STOP_REASON_FLUSH); | ||
541 | |||
542 | drv_flush(local, queues, false); | ||
543 | |||
544 | ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, | ||
545 | IEEE80211_QUEUE_STOP_REASON_FLUSH); | ||
546 | } | ||
547 | |||
514 | void ieee80211_iterate_active_interfaces( | 548 | void ieee80211_iterate_active_interfaces( |
515 | struct ieee80211_hw *hw, u32 iter_flags, | 549 | struct ieee80211_hw *hw, u32 iter_flags, |
516 | void (*iterator)(void *data, u8 *mac, | 550 | void (*iterator)(void *data, u8 *mac, |
@@ -1651,8 +1685,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1651 | mutex_unlock(&local->sta_mtx); | 1685 | mutex_unlock(&local->sta_mtx); |
1652 | } | 1686 | } |
1653 | 1687 | ||
1654 | ieee80211_wake_queues_by_reason(hw, | 1688 | ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, |
1655 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 1689 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
1656 | 1690 | ||
1657 | /* | 1691 | /* |
1658 | * If this is for hw restart things are still running. | 1692 | * If this is for hw restart things are still running. |
diff --git a/net/wireless/core.c b/net/wireless/core.c index f382cae983ba..92e3fd44e3b0 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -1096,8 +1096,10 @@ static int __init cfg80211_init(void) | |||
1096 | goto out_fail_reg; | 1096 | goto out_fail_reg; |
1097 | 1097 | ||
1098 | cfg80211_wq = create_singlethread_workqueue("cfg80211"); | 1098 | cfg80211_wq = create_singlethread_workqueue("cfg80211"); |
1099 | if (!cfg80211_wq) | 1099 | if (!cfg80211_wq) { |
1100 | err = -ENOMEM; | ||
1100 | goto out_fail_wq; | 1101 | goto out_fail_wq; |
1102 | } | ||
1101 | 1103 | ||
1102 | return 0; | 1104 | return 0; |
1103 | 1105 | ||
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index bad4c4b5e4eb..88fc9aa54fe0 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -234,7 +234,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
234 | wdev_unlock(wdev); | 234 | wdev_unlock(wdev); |
235 | continue; | 235 | continue; |
236 | } | 236 | } |
237 | if (wdev->sme_state != CFG80211_SME_CONNECTING) { | 237 | if (wdev->sme_state != CFG80211_SME_CONNECTING || !wdev->conn) { |
238 | wdev_unlock(wdev); | 238 | wdev_unlock(wdev); |
239 | continue; | 239 | continue; |
240 | } | 240 | } |