Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
commit
c78b3841fa
37 changed files with 375 additions and 258 deletions
|
@ -437,7 +437,7 @@
|
||||||
</section>
|
</section>
|
||||||
!Finclude/net/mac80211.h ieee80211_get_buffered_bc
|
!Finclude/net/mac80211.h ieee80211_get_buffered_bc
|
||||||
!Finclude/net/mac80211.h ieee80211_beacon_get
|
!Finclude/net/mac80211.h ieee80211_beacon_get
|
||||||
!Finclude/net/mac80211.h ieee80211_sta_eosp_irqsafe
|
!Finclude/net/mac80211.h ieee80211_sta_eosp
|
||||||
!Finclude/net/mac80211.h ieee80211_frame_release_type
|
!Finclude/net/mac80211.h ieee80211_frame_release_type
|
||||||
!Finclude/net/mac80211.h ieee80211_sta_ps_transition
|
!Finclude/net/mac80211.h ieee80211_sta_ps_transition
|
||||||
!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni
|
!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni
|
||||||
|
|
|
@ -1091,7 +1091,7 @@ static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ar5523_flush(struct ieee80211_hw *hw, bool drop)
|
static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
struct ar5523 *ar = hw->priv;
|
struct ar5523 *ar = hw->priv;
|
||||||
|
|
||||||
|
|
|
@ -1745,7 +1745,7 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
|
||||||
mutex_unlock(&sc->mutex);
|
mutex_unlock(&sc->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
|
static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
struct ath_softc *sc = hw->priv;
|
struct ath_softc *sc = hw->priv;
|
||||||
struct ath_hw *ah = sc->sc_ah;
|
struct ath_hw *ah = sc->sc_ah;
|
||||||
|
|
|
@ -1703,7 +1703,7 @@ found:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop)
|
static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
struct ar9170 *ar = hw->priv;
|
struct ar9170 *ar = hw->priv;
|
||||||
unsigned int vid;
|
unsigned int vid;
|
||||||
|
|
|
@ -724,7 +724,7 @@ static bool brcms_tx_flush_completed(struct brcms_info *wl)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
|
static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
struct brcms_info *wl = hw->priv;
|
struct brcms_info *wl = hw->priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -4704,8 +4704,7 @@ out:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(il_mac_change_interface);
|
EXPORT_SYMBOL(il_mac_change_interface);
|
||||||
|
|
||||||
void
|
void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
il_mac_flush(struct ieee80211_hw *hw, bool drop)
|
|
||||||
{
|
{
|
||||||
struct il_priv *il = hw->priv;
|
struct il_priv *il = hw->priv;
|
||||||
unsigned long timeout = jiffies + msecs_to_jiffies(500);
|
unsigned long timeout = jiffies + msecs_to_jiffies(500);
|
||||||
|
|
|
@ -1720,7 +1720,7 @@ void il_mac_remove_interface(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_vif *vif);
|
struct ieee80211_vif *vif);
|
||||||
int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
enum nl80211_iftype newtype, bool newp2p);
|
enum nl80211_iftype newtype, bool newp2p);
|
||||||
void il_mac_flush(struct ieee80211_hw *hw, bool drop);
|
void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
|
||||||
int il_alloc_txq_mem(struct il_priv *il);
|
int il_alloc_txq_mem(struct il_priv *il);
|
||||||
void il_free_txq_mem(struct il_priv *il);
|
void il_free_txq_mem(struct il_priv *il);
|
||||||
|
|
||||||
|
|
|
@ -1100,7 +1100,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
|
||||||
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
|
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
|
static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
|
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
|
||||||
|
|
||||||
|
|
|
@ -964,6 +964,12 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw,
|
||||||
newtype, vif->addr);
|
newtype, vif->addr);
|
||||||
hwsim_check_magic(vif);
|
hwsim_check_magic(vif);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* interface may change from non-AP to AP in
|
||||||
|
* which case this needs to be set up again
|
||||||
|
*/
|
||||||
|
vif->cab_queue = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1389,7 +1395,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop)
|
static void mac80211_hwsim_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
/* Not implemented, queues only on kernel side */
|
/* Not implemented, queues only on kernel side */
|
||||||
}
|
}
|
||||||
|
|
|
@ -670,7 +670,7 @@ static unsigned int p54_flush_count(struct p54_common *priv)
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void p54_flush(struct ieee80211_hw *dev, bool drop)
|
static void p54_flush(struct ieee80211_hw *dev, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
struct p54_common *priv = dev->priv;
|
struct p54_common *priv = dev->priv;
|
||||||
unsigned int total, i;
|
unsigned int total, i;
|
||||||
|
|
|
@ -1366,7 +1366,7 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_vif *vif, u16 queue,
|
struct ieee80211_vif *vif, u16 queue,
|
||||||
const struct ieee80211_tx_queue_params *params);
|
const struct ieee80211_tx_queue_params *params);
|
||||||
void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
|
void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
|
||||||
void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
|
void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
|
||||||
int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
|
int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
|
||||||
int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
|
int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
|
||||||
void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
|
void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
|
||||||
|
|
|
@ -748,7 +748,7 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
|
EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
|
||||||
|
|
||||||
void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
|
void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||||
struct data_queue *queue;
|
struct data_queue *queue;
|
||||||
|
|
|
@ -1166,7 +1166,7 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
|
||||||
* before switch channle or power save, or tx buffer packet
|
* before switch channle or power save, or tx buffer packet
|
||||||
* maybe send after offchannel or rf sleep, this may cause
|
* maybe send after offchannel or rf sleep, this may cause
|
||||||
* dis-association by AP */
|
* dis-association by AP */
|
||||||
static void rtl_op_flush(struct ieee80211_hw *hw, bool drop)
|
static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
|
|
||||||
|
|
|
@ -4946,7 +4946,7 @@ out:
|
||||||
mutex_unlock(&wl->mutex);
|
mutex_unlock(&wl->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wlcore_op_flush(struct ieee80211_hw *hw, bool drop)
|
static void wlcore_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
struct wl1271 *wl = hw->priv;
|
struct wl1271 *wl = hw->priv;
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,11 @@ struct device;
|
||||||
* enum ieee80211_max_queues - maximum number of queues
|
* enum ieee80211_max_queues - maximum number of queues
|
||||||
*
|
*
|
||||||
* @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
|
* @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
|
||||||
|
* @IEEE80211_MAX_QUEUE_MAP: bitmap with maximum queues set
|
||||||
*/
|
*/
|
||||||
enum ieee80211_max_queues {
|
enum ieee80211_max_queues {
|
||||||
IEEE80211_MAX_QUEUES = 16,
|
IEEE80211_MAX_QUEUES = 16,
|
||||||
|
IEEE80211_MAX_QUEUE_MAP = BIT(IEEE80211_MAX_QUEUES) - 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IEEE80211_INVAL_HW_QUEUE 0xff
|
#define IEEE80211_INVAL_HW_QUEUE 0xff
|
||||||
|
@ -1067,6 +1069,9 @@ enum ieee80211_vif_flags {
|
||||||
* path needing to access it; even though the netdev carrier will always
|
* path needing to access it; even though the netdev carrier will always
|
||||||
* be off when it is %NULL there can still be races and packets could be
|
* be off when it is %NULL there can still be races and packets could be
|
||||||
* processed after it switches back to %NULL.
|
* processed after it switches back to %NULL.
|
||||||
|
* @debugfs_dir: debugfs dentry, can be used by drivers to create own per
|
||||||
|
* interface debug files. Note that it will be NULL for the virtual
|
||||||
|
* monitor interface (if that is requested.)
|
||||||
* @drv_priv: data area for driver use, will always be aligned to
|
* @drv_priv: data area for driver use, will always be aligned to
|
||||||
* sizeof(void *).
|
* sizeof(void *).
|
||||||
*/
|
*/
|
||||||
|
@ -1083,6 +1088,10 @@ struct ieee80211_vif {
|
||||||
|
|
||||||
u32 driver_flags;
|
u32 driver_flags;
|
||||||
|
|
||||||
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||||
|
struct dentry *debugfs_dir;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* must be last */
|
/* must be last */
|
||||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||||
};
|
};
|
||||||
|
@ -1946,14 +1955,14 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||||
* filter those response frames except in the case of frames that
|
* filter those response frames except in the case of frames that
|
||||||
* are buffered in the driver -- those must remain buffered to avoid
|
* are buffered in the driver -- those must remain buffered to avoid
|
||||||
* reordering. Because it is possible that no frames are released
|
* reordering. Because it is possible that no frames are released
|
||||||
* in this case, the driver must call ieee80211_sta_eosp_irqsafe()
|
* in this case, the driver must call ieee80211_sta_eosp()
|
||||||
* to indicate to mac80211 that the service period ended anyway.
|
* to indicate to mac80211 that the service period ended anyway.
|
||||||
*
|
*
|
||||||
* Finally, if frames from multiple TIDs are released from mac80211
|
* Finally, if frames from multiple TIDs are released from mac80211
|
||||||
* but the driver might reorder them, it must clear & set the flags
|
* but the driver might reorder them, it must clear & set the flags
|
||||||
* appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP)
|
* appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP)
|
||||||
* and also take care of the EOSP and MORE_DATA bits in the frame.
|
* and also take care of the EOSP and MORE_DATA bits in the frame.
|
||||||
* The driver may also use ieee80211_sta_eosp_irqsafe() in this case.
|
* The driver may also use ieee80211_sta_eosp() in this case.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2226,18 +2235,6 @@ enum ieee80211_roc_type {
|
||||||
* MAC address of the device going away.
|
* MAC address of the device going away.
|
||||||
* Hence, this callback must be implemented. It can sleep.
|
* Hence, this callback must be implemented. It can sleep.
|
||||||
*
|
*
|
||||||
* @add_interface_debugfs: Drivers can use this callback to add debugfs files
|
|
||||||
* when a vif is added to mac80211. This callback and
|
|
||||||
* @remove_interface_debugfs should be within a CONFIG_MAC80211_DEBUGFS
|
|
||||||
* conditional. @remove_interface_debugfs must be provided for cleanup.
|
|
||||||
* This callback can sleep.
|
|
||||||
*
|
|
||||||
* @remove_interface_debugfs: Remove the debugfs files which were added using
|
|
||||||
* @add_interface_debugfs. This callback must remove all debugfs entries
|
|
||||||
* that were added because mac80211 only removes interface debugfs when the
|
|
||||||
* interface is destroyed, not when it is removed from the driver.
|
|
||||||
* This callback can sleep.
|
|
||||||
*
|
|
||||||
* @config: Handler for configuration requests. IEEE 802.11 code calls this
|
* @config: Handler for configuration requests. IEEE 802.11 code calls this
|
||||||
* function to change hardware configuration, e.g., channel.
|
* function to change hardware configuration, e.g., channel.
|
||||||
* This function should never fail but returns a negative error code
|
* This function should never fail but returns a negative error code
|
||||||
|
@ -2259,6 +2256,9 @@ enum ieee80211_roc_type {
|
||||||
* See the section "Frame filtering" for more information.
|
* See the section "Frame filtering" for more information.
|
||||||
* This callback must be implemented and can sleep.
|
* This callback must be implemented and can sleep.
|
||||||
*
|
*
|
||||||
|
* @set_multicast_list: Configure the device's interface specific RX multicast
|
||||||
|
* filter. This callback is optional. This callback must be atomic.
|
||||||
|
*
|
||||||
* @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
|
* @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
|
||||||
* must be set or cleared for a given STA. Must be atomic.
|
* must be set or cleared for a given STA. Must be atomic.
|
||||||
*
|
*
|
||||||
|
@ -2440,8 +2440,11 @@ enum ieee80211_roc_type {
|
||||||
* @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep.
|
* @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep.
|
||||||
*
|
*
|
||||||
* @flush: Flush all pending frames from the hardware queue, making sure
|
* @flush: Flush all pending frames from the hardware queue, making sure
|
||||||
* that the hardware queues are empty. If the parameter @drop is set
|
* that the hardware queues are empty. The @queues parameter is a bitmap
|
||||||
* to %true, pending frames may be dropped. The callback can sleep.
|
* of queues to flush, which is useful if different virtual interfaces
|
||||||
|
* use different hardware queues; it may also indicate all queues.
|
||||||
|
* If the parameter @drop is set to %true, pending frames may be dropped.
|
||||||
|
* The callback can sleep.
|
||||||
*
|
*
|
||||||
* @channel_switch: Drivers that need (or want) to offload the channel
|
* @channel_switch: Drivers that need (or want) to offload the channel
|
||||||
* switch operation for CSAs received from the AP may implement this
|
* switch operation for CSAs received from the AP may implement this
|
||||||
|
@ -2506,7 +2509,7 @@ enum ieee80211_roc_type {
|
||||||
* setting the EOSP flag in the QoS header of the frames. Also, when the
|
* setting the EOSP flag in the QoS header of the frames. Also, when the
|
||||||
* service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP
|
* service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP
|
||||||
* on the last frame in the SP. Alternatively, it may call the function
|
* on the last frame in the SP. Alternatively, it may call the function
|
||||||
* ieee80211_sta_eosp_irqsafe() to inform mac80211 of the end of the SP.
|
* ieee80211_sta_eosp() to inform mac80211 of the end of the SP.
|
||||||
* This callback must be atomic.
|
* This callback must be atomic.
|
||||||
* @allow_buffered_frames: Prepare device to allow the given number of frames
|
* @allow_buffered_frames: Prepare device to allow the given number of frames
|
||||||
* to go out to the given station. The frames will be sent by mac80211
|
* to go out to the given station. The frames will be sent by mac80211
|
||||||
|
@ -2517,7 +2520,7 @@ enum ieee80211_roc_type {
|
||||||
* them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag
|
* them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag
|
||||||
* on the last frame and clear it on all others and also handle the EOSP
|
* on the last frame and clear it on all others and also handle the EOSP
|
||||||
* bit in the QoS header correctly. Alternatively, it can also call the
|
* bit in the QoS header correctly. Alternatively, it can also call the
|
||||||
* ieee80211_sta_eosp_irqsafe() function.
|
* ieee80211_sta_eosp() function.
|
||||||
* The @tids parameter is a bitmap and tells the driver which TIDs the
|
* The @tids parameter is a bitmap and tells the driver which TIDs the
|
||||||
* frames will be on; it will at most have two bits set.
|
* frames will be on; it will at most have two bits set.
|
||||||
* This callback must be atomic.
|
* This callback must be atomic.
|
||||||
|
@ -2605,6 +2608,10 @@ struct ieee80211_ops {
|
||||||
unsigned int changed_flags,
|
unsigned int changed_flags,
|
||||||
unsigned int *total_flags,
|
unsigned int *total_flags,
|
||||||
u64 multicast);
|
u64 multicast);
|
||||||
|
void (*set_multicast_list)(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif, bool allmulti,
|
||||||
|
struct netdev_hw_addr_list *mc_list);
|
||||||
|
|
||||||
int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
|
int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
|
||||||
bool set);
|
bool set);
|
||||||
int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||||
|
@ -2651,12 +2658,6 @@ struct ieee80211_ops {
|
||||||
struct ieee80211_vif *vif,
|
struct ieee80211_vif *vif,
|
||||||
struct ieee80211_sta *sta,
|
struct ieee80211_sta *sta,
|
||||||
struct dentry *dir);
|
struct dentry *dir);
|
||||||
void (*add_interface_debugfs)(struct ieee80211_hw *hw,
|
|
||||||
struct ieee80211_vif *vif,
|
|
||||||
struct dentry *dir);
|
|
||||||
void (*remove_interface_debugfs)(struct ieee80211_hw *hw,
|
|
||||||
struct ieee80211_vif *vif,
|
|
||||||
struct dentry *dir);
|
|
||||||
#endif
|
#endif
|
||||||
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
enum sta_notify_cmd, struct ieee80211_sta *sta);
|
enum sta_notify_cmd, struct ieee80211_sta *sta);
|
||||||
|
@ -2691,7 +2692,7 @@ struct ieee80211_ops {
|
||||||
struct netlink_callback *cb,
|
struct netlink_callback *cb,
|
||||||
void *data, int len);
|
void *data, int len);
|
||||||
#endif
|
#endif
|
||||||
void (*flush)(struct ieee80211_hw *hw, bool drop);
|
void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop);
|
||||||
void (*channel_switch)(struct ieee80211_hw *hw,
|
void (*channel_switch)(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_channel_switch *ch_switch);
|
struct ieee80211_channel_switch *ch_switch);
|
||||||
int (*napi_poll)(struct ieee80211_hw *hw, int budget);
|
int (*napi_poll)(struct ieee80211_hw *hw, int budget);
|
||||||
|
@ -3857,14 +3858,17 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
|
||||||
* %IEEE80211_TX_STATUS_EOSP bit and call this function instead.
|
* %IEEE80211_TX_STATUS_EOSP bit and call this function instead.
|
||||||
* This applies for PS-Poll as well as uAPSD.
|
* This applies for PS-Poll as well as uAPSD.
|
||||||
*
|
*
|
||||||
* Note that there is no non-_irqsafe version right now as
|
* Note that just like with _tx_status() and _rx() drivers must
|
||||||
* it wasn't needed, but just like _tx_status() and _rx()
|
* not mix calls to irqsafe/non-irqsafe versions, this function
|
||||||
* must not be mixed in irqsafe/non-irqsafe versions, this
|
* must not be mixed with those either. Use the all irqsafe, or
|
||||||
* function must not be mixed with those either. Use the
|
* all non-irqsafe, don't mix!
|
||||||
* all irqsafe, or all non-irqsafe, don't mix! If you need
|
*
|
||||||
* the non-irqsafe version of this, you need to add it.
|
* NB: the _irqsafe version of this function doesn't exist, no
|
||||||
|
* driver needs it right now. Don't call this function if
|
||||||
|
* you'd need the _irqsafe version, look at the git history
|
||||||
|
* and restore the _irqsafe version!
|
||||||
*/
|
*/
|
||||||
void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta);
|
void ieee80211_sta_eosp(struct ieee80211_sta *pubsta);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ieee80211_iter_keys - iterate keys programmed into the device
|
* ieee80211_iter_keys - iterate keys programmed into the device
|
||||||
|
|
|
@ -175,7 +175,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
|
||||||
* add it to the device after the station.
|
* add it to the device after the station.
|
||||||
*/
|
*/
|
||||||
if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
|
if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
|
||||||
ieee80211_key_free(sdata->local, key);
|
ieee80211_key_free_unused(key);
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
@ -214,8 +214,6 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ieee80211_key_link(key, sdata, sta);
|
err = ieee80211_key_link(key, sdata, sta);
|
||||||
if (err)
|
|
||||||
ieee80211_key_free(sdata->local, key);
|
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&sdata->local->sta_mtx);
|
mutex_unlock(&sdata->local->sta_mtx);
|
||||||
|
@ -254,7 +252,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
__ieee80211_key_free(key, true);
|
ieee80211_key_free(key, true);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
@ -445,12 +443,14 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
|
||||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||||
struct ieee80211_local *local = sdata->local;
|
struct ieee80211_local *local = sdata->local;
|
||||||
struct timespec uptime;
|
struct timespec uptime;
|
||||||
|
u64 packets = 0;
|
||||||
|
int ac;
|
||||||
|
|
||||||
sinfo->generation = sdata->local->sta_generation;
|
sinfo->generation = sdata->local->sta_generation;
|
||||||
|
|
||||||
sinfo->filled = STATION_INFO_INACTIVE_TIME |
|
sinfo->filled = STATION_INFO_INACTIVE_TIME |
|
||||||
STATION_INFO_RX_BYTES |
|
STATION_INFO_RX_BYTES64 |
|
||||||
STATION_INFO_TX_BYTES |
|
STATION_INFO_TX_BYTES64 |
|
||||||
STATION_INFO_RX_PACKETS |
|
STATION_INFO_RX_PACKETS |
|
||||||
STATION_INFO_TX_PACKETS |
|
STATION_INFO_TX_PACKETS |
|
||||||
STATION_INFO_TX_RETRIES |
|
STATION_INFO_TX_RETRIES |
|
||||||
|
@ -467,10 +467,14 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
|
||||||
sinfo->connected_time = uptime.tv_sec - sta->last_connected;
|
sinfo->connected_time = uptime.tv_sec - sta->last_connected;
|
||||||
|
|
||||||
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
|
sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
|
||||||
|
sinfo->tx_bytes = 0;
|
||||||
|
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
||||||
|
sinfo->tx_bytes += sta->tx_bytes[ac];
|
||||||
|
packets += sta->tx_packets[ac];
|
||||||
|
}
|
||||||
|
sinfo->tx_packets = packets;
|
||||||
sinfo->rx_bytes = sta->rx_bytes;
|
sinfo->rx_bytes = sta->rx_bytes;
|
||||||
sinfo->tx_bytes = sta->tx_bytes;
|
|
||||||
sinfo->rx_packets = sta->rx_packets;
|
sinfo->rx_packets = sta->rx_packets;
|
||||||
sinfo->tx_packets = sta->tx_packets;
|
|
||||||
sinfo->tx_retries = sta->tx_retry_count;
|
sinfo->tx_retries = sta->tx_retry_count;
|
||||||
sinfo->tx_failed = sta->tx_retry_failed;
|
sinfo->tx_failed = sta->tx_retry_failed;
|
||||||
sinfo->rx_dropped_misc = sta->rx_dropped;
|
sinfo->rx_dropped_misc = sta->rx_dropped;
|
||||||
|
@ -598,8 +602,8 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
|
||||||
data[i++] += sta->rx_fragments; \
|
data[i++] += sta->rx_fragments; \
|
||||||
data[i++] += sta->rx_dropped; \
|
data[i++] += sta->rx_dropped; \
|
||||||
\
|
\
|
||||||
data[i++] += sta->tx_packets; \
|
data[i++] += sinfo.tx_packets; \
|
||||||
data[i++] += sta->tx_bytes; \
|
data[i++] += sinfo.tx_bytes; \
|
||||||
data[i++] += sta->tx_fragments; \
|
data[i++] += sta->tx_fragments; \
|
||||||
data[i++] += sta->tx_filtered_count; \
|
data[i++] += sta->tx_filtered_count; \
|
||||||
data[i++] += sta->tx_retry_failed; \
|
data[i++] += sta->tx_retry_failed; \
|
||||||
|
@ -621,13 +625,14 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
|
||||||
if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
|
if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
|
||||||
goto do_survey;
|
goto do_survey;
|
||||||
|
|
||||||
|
sinfo.filled = 0;
|
||||||
|
sta_set_sinfo(sta, &sinfo);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
ADD_STA_STATS(sta);
|
ADD_STA_STATS(sta);
|
||||||
|
|
||||||
data[i++] = sta->sta_state;
|
data[i++] = sta->sta_state;
|
||||||
|
|
||||||
sinfo.filled = 0;
|
|
||||||
sta_set_sinfo(sta, &sinfo);
|
|
||||||
|
|
||||||
if (sinfo.filled & STATION_INFO_TX_BITRATE)
|
if (sinfo.filled & STATION_INFO_TX_BITRATE)
|
||||||
data[i] = 100000 *
|
data[i] = 100000 *
|
||||||
|
|
|
@ -295,7 +295,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
|
||||||
char buf[50];
|
char buf[50];
|
||||||
struct ieee80211_key *key;
|
struct ieee80211_key *key;
|
||||||
|
|
||||||
if (!sdata->debugfs.dir)
|
if (!sdata->vif.debugfs_dir)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lockdep_assert_held(&sdata->local->key_mtx);
|
lockdep_assert_held(&sdata->local->key_mtx);
|
||||||
|
@ -311,7 +311,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
|
||||||
sprintf(buf, "../keys/%d", key->debugfs.cnt);
|
sprintf(buf, "../keys/%d", key->debugfs.cnt);
|
||||||
sdata->debugfs.default_unicast_key =
|
sdata->debugfs.default_unicast_key =
|
||||||
debugfs_create_symlink("default_unicast_key",
|
debugfs_create_symlink("default_unicast_key",
|
||||||
sdata->debugfs.dir, buf);
|
sdata->vif.debugfs_dir, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdata->debugfs.default_multicast_key) {
|
if (sdata->debugfs.default_multicast_key) {
|
||||||
|
@ -325,7 +325,7 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
|
||||||
sprintf(buf, "../keys/%d", key->debugfs.cnt);
|
sprintf(buf, "../keys/%d", key->debugfs.cnt);
|
||||||
sdata->debugfs.default_multicast_key =
|
sdata->debugfs.default_multicast_key =
|
||||||
debugfs_create_symlink("default_multicast_key",
|
debugfs_create_symlink("default_multicast_key",
|
||||||
sdata->debugfs.dir, buf);
|
sdata->vif.debugfs_dir, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
|
||||||
char buf[50];
|
char buf[50];
|
||||||
struct ieee80211_key *key;
|
struct ieee80211_key *key;
|
||||||
|
|
||||||
if (!sdata->debugfs.dir)
|
if (!sdata->vif.debugfs_dir)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
key = key_mtx_dereference(sdata->local,
|
key = key_mtx_dereference(sdata->local,
|
||||||
|
@ -343,7 +343,7 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
|
||||||
sprintf(buf, "../keys/%d", key->debugfs.cnt);
|
sprintf(buf, "../keys/%d", key->debugfs.cnt);
|
||||||
sdata->debugfs.default_mgmt_key =
|
sdata->debugfs.default_mgmt_key =
|
||||||
debugfs_create_symlink("default_mgmt_key",
|
debugfs_create_symlink("default_mgmt_key",
|
||||||
sdata->debugfs.dir, buf);
|
sdata->vif.debugfs_dir, buf);
|
||||||
} else
|
} else
|
||||||
ieee80211_debugfs_key_remove_mgmt_default(sdata);
|
ieee80211_debugfs_key_remove_mgmt_default(sdata);
|
||||||
}
|
}
|
||||||
|
|
|
@ -521,7 +521,7 @@ IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEBUGFS_ADD_MODE(name, mode) \
|
#define DEBUGFS_ADD_MODE(name, mode) \
|
||||||
debugfs_create_file(#name, mode, sdata->debugfs.dir, \
|
debugfs_create_file(#name, mode, sdata->vif.debugfs_dir, \
|
||||||
sdata, &name##_ops);
|
sdata, &name##_ops);
|
||||||
|
|
||||||
#define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400)
|
#define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400)
|
||||||
|
@ -577,7 +577,7 @@ static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
|
||||||
static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
|
static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
struct dentry *dir = debugfs_create_dir("mesh_stats",
|
struct dentry *dir = debugfs_create_dir("mesh_stats",
|
||||||
sdata->debugfs.dir);
|
sdata->vif.debugfs_dir);
|
||||||
#define MESHSTATS_ADD(name)\
|
#define MESHSTATS_ADD(name)\
|
||||||
debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
|
debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
|
||||||
|
|
||||||
|
@ -594,7 +594,7 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
|
||||||
static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
|
static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
struct dentry *dir = debugfs_create_dir("mesh_config",
|
struct dentry *dir = debugfs_create_dir("mesh_config",
|
||||||
sdata->debugfs.dir);
|
sdata->vif.debugfs_dir);
|
||||||
|
|
||||||
#define MESHPARAMS_ADD(name) \
|
#define MESHPARAMS_ADD(name) \
|
||||||
debugfs_create_file(#name, 0600, dir, sdata, &name##_ops);
|
debugfs_create_file(#name, 0600, dir, sdata, &name##_ops);
|
||||||
|
@ -631,7 +631,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
|
||||||
|
|
||||||
static void add_files(struct ieee80211_sub_if_data *sdata)
|
static void add_files(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
if (!sdata->debugfs.dir)
|
if (!sdata->vif.debugfs_dir)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DEBUGFS_ADD(flags);
|
DEBUGFS_ADD(flags);
|
||||||
|
@ -673,21 +673,21 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
|
||||||
char buf[10+IFNAMSIZ];
|
char buf[10+IFNAMSIZ];
|
||||||
|
|
||||||
sprintf(buf, "netdev:%s", sdata->name);
|
sprintf(buf, "netdev:%s", sdata->name);
|
||||||
sdata->debugfs.dir = debugfs_create_dir(buf,
|
sdata->vif.debugfs_dir = debugfs_create_dir(buf,
|
||||||
sdata->local->hw.wiphy->debugfsdir);
|
sdata->local->hw.wiphy->debugfsdir);
|
||||||
if (sdata->debugfs.dir)
|
if (sdata->vif.debugfs_dir)
|
||||||
sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
|
sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
|
||||||
sdata->debugfs.dir);
|
sdata->vif.debugfs_dir);
|
||||||
add_files(sdata);
|
add_files(sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
|
void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
if (!sdata->debugfs.dir)
|
if (!sdata->vif.debugfs_dir)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
debugfs_remove_recursive(sdata->debugfs.dir);
|
debugfs_remove_recursive(sdata->vif.debugfs_dir);
|
||||||
sdata->debugfs.dir = NULL;
|
sdata->vif.debugfs_dir = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
|
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)
|
||||||
struct dentry *dir;
|
struct dentry *dir;
|
||||||
char buf[10 + IFNAMSIZ];
|
char buf[10 + IFNAMSIZ];
|
||||||
|
|
||||||
dir = sdata->debugfs.dir;
|
dir = sdata->vif.debugfs_dir;
|
||||||
|
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -241,6 +241,22 @@ static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void drv_set_multicast_list(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct netdev_hw_addr_list *mc_list)
|
||||||
|
{
|
||||||
|
bool allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI;
|
||||||
|
|
||||||
|
trace_drv_set_multicast_list(local, sdata, mc_list->count);
|
||||||
|
|
||||||
|
check_sdata_in_driver(sdata);
|
||||||
|
|
||||||
|
if (local->ops->set_multicast_list)
|
||||||
|
local->ops->set_multicast_list(&local->hw, &sdata->vif,
|
||||||
|
allmulti, mc_list);
|
||||||
|
trace_drv_return_void(local);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void drv_configure_filter(struct ieee80211_local *local,
|
static inline void drv_configure_filter(struct ieee80211_local *local,
|
||||||
unsigned int changed_flags,
|
unsigned int changed_flags,
|
||||||
unsigned int *total_flags,
|
unsigned int *total_flags,
|
||||||
|
@ -531,43 +547,6 @@ static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
|
||||||
local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
|
local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
|
||||||
sta, dir);
|
sta, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
|
||||||
void drv_add_interface_debugfs(struct ieee80211_local *local,
|
|
||||||
struct ieee80211_sub_if_data *sdata)
|
|
||||||
{
|
|
||||||
might_sleep();
|
|
||||||
|
|
||||||
check_sdata_in_driver(sdata);
|
|
||||||
|
|
||||||
if (!local->ops->add_interface_debugfs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
local->ops->add_interface_debugfs(&local->hw, &sdata->vif,
|
|
||||||
sdata->debugfs.dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
void drv_remove_interface_debugfs(struct ieee80211_local *local,
|
|
||||||
struct ieee80211_sub_if_data *sdata)
|
|
||||||
{
|
|
||||||
might_sleep();
|
|
||||||
|
|
||||||
check_sdata_in_driver(sdata);
|
|
||||||
|
|
||||||
if (!local->ops->remove_interface_debugfs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
local->ops->remove_interface_debugfs(&local->hw, &sdata->vif,
|
|
||||||
sdata->debugfs.dir);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline
|
|
||||||
void drv_add_interface_debugfs(struct ieee80211_local *local,
|
|
||||||
struct ieee80211_sub_if_data *sdata) {}
|
|
||||||
static inline
|
|
||||||
void drv_remove_interface_debugfs(struct ieee80211_local *local,
|
|
||||||
struct ieee80211_sub_if_data *sdata) {}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline __must_check
|
static inline __must_check
|
||||||
|
@ -741,13 +720,14 @@ static inline void drv_rfkill_poll(struct ieee80211_local *local)
|
||||||
local->ops->rfkill_poll(&local->hw);
|
local->ops->rfkill_poll(&local->hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void drv_flush(struct ieee80211_local *local, bool drop)
|
static inline void drv_flush(struct ieee80211_local *local,
|
||||||
|
u32 queues, bool drop)
|
||||||
{
|
{
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
trace_drv_flush(local, drop);
|
trace_drv_flush(local, queues, drop);
|
||||||
if (local->ops->flush)
|
if (local->ops->flush)
|
||||||
local->ops->flush(&local->hw, drop);
|
local->ops->flush(&local->hw, queues, drop);
|
||||||
trace_drv_return_void(local);
|
trace_drv_return_void(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -758,7 +758,6 @@ struct ieee80211_sub_if_data {
|
||||||
|
|
||||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||||
struct {
|
struct {
|
||||||
struct dentry *dir;
|
|
||||||
struct dentry *subdir_stations;
|
struct dentry *subdir_stations;
|
||||||
struct dentry *default_unicast_key;
|
struct dentry *default_unicast_key;
|
||||||
struct dentry *default_multicast_key;
|
struct dentry *default_multicast_key;
|
||||||
|
@ -800,11 +799,6 @@ enum sdata_queue_type {
|
||||||
enum {
|
enum {
|
||||||
IEEE80211_RX_MSG = 1,
|
IEEE80211_RX_MSG = 1,
|
||||||
IEEE80211_TX_STATUS_MSG = 2,
|
IEEE80211_TX_STATUS_MSG = 2,
|
||||||
IEEE80211_EOSP_MSG = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct skb_eosp_msg_data {
|
|
||||||
u8 sta[ETH_ALEN], iface[ETH_ALEN];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum queue_stop_reason {
|
enum queue_stop_reason {
|
||||||
|
@ -815,6 +809,7 @@ enum queue_stop_reason {
|
||||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND,
|
IEEE80211_QUEUE_STOP_REASON_SUSPEND,
|
||||||
IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
|
IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
|
||||||
IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
|
IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
|
||||||
|
IEEE80211_QUEUE_STOP_REASON_FLUSH,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_MAC80211_LEDS
|
#ifdef CONFIG_MAC80211_LEDS
|
||||||
|
@ -1528,8 +1523,10 @@ void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_hdr *hdr, bool ack);
|
struct ieee80211_hdr *hdr, bool ack);
|
||||||
|
|
||||||
void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
|
void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
|
||||||
|
unsigned long queues,
|
||||||
enum queue_stop_reason reason);
|
enum queue_stop_reason reason);
|
||||||
void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
|
void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
|
||||||
|
unsigned long queues,
|
||||||
enum queue_stop_reason reason);
|
enum queue_stop_reason reason);
|
||||||
void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
|
void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
|
||||||
enum queue_stop_reason reason);
|
enum queue_stop_reason reason);
|
||||||
|
@ -1546,6 +1543,8 @@ static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local,
|
||||||
{
|
{
|
||||||
ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
|
ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
void ieee80211_flush_queues(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata);
|
||||||
|
|
||||||
void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
|
||||||
u16 transaction, u16 auth_alg, u16 status,
|
u16 transaction, u16 auth_alg, u16 status,
|
||||||
|
|
|
@ -92,7 +92,7 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local)
|
||||||
if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
|
if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
drv_flush(local, false);
|
ieee80211_flush_queues(local, NULL);
|
||||||
|
|
||||||
local->hw.conf.flags |= IEEE80211_CONF_IDLE;
|
local->hw.conf.flags |= IEEE80211_CONF_IDLE;
|
||||||
return IEEE80211_CONF_CHANGE_IDLE;
|
return IEEE80211_CONF_CHANGE_IDLE;
|
||||||
|
@ -557,8 +557,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
||||||
goto err_del_interface;
|
goto err_del_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
drv_add_interface_debugfs(local, sdata);
|
|
||||||
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
||||||
local->fif_pspoll++;
|
local->fif_pspoll++;
|
||||||
local->fif_probe_req++;
|
local->fif_probe_req++;
|
||||||
|
@ -846,8 +844,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
||||||
case NL80211_IFTYPE_AP:
|
case NL80211_IFTYPE_AP:
|
||||||
skb_queue_purge(&sdata->skb_queue);
|
skb_queue_purge(&sdata->skb_queue);
|
||||||
|
|
||||||
drv_remove_interface_debugfs(local, sdata);
|
|
||||||
|
|
||||||
if (going_down)
|
if (going_down)
|
||||||
drv_remove_interface(local, sdata);
|
drv_remove_interface(local, sdata);
|
||||||
}
|
}
|
||||||
|
@ -919,6 +915,17 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
|
||||||
atomic_dec(&local->iff_promiscs);
|
atomic_dec(&local->iff_promiscs);
|
||||||
sdata->flags ^= IEEE80211_SDATA_PROMISC;
|
sdata->flags ^= IEEE80211_SDATA_PROMISC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: If somebody needs this on AP interfaces,
|
||||||
|
* it can be enabled easily but multicast
|
||||||
|
* addresses from VLANs need to be synced.
|
||||||
|
*/
|
||||||
|
if (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
|
||||||
|
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
|
||||||
|
sdata->vif.type != NL80211_IFTYPE_AP)
|
||||||
|
drv_set_multicast_list(local, sdata, &dev->mc);
|
||||||
|
|
||||||
spin_lock_bh(&local->filter_lock);
|
spin_lock_bh(&local->filter_lock);
|
||||||
__hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
|
__hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
|
||||||
spin_unlock_bh(&local->filter_lock);
|
spin_unlock_bh(&local->filter_lock);
|
||||||
|
|
|
@ -248,11 +248,11 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
||||||
struct sta_info *sta,
|
struct sta_info *sta,
|
||||||
bool pairwise,
|
bool pairwise,
|
||||||
struct ieee80211_key *old,
|
struct ieee80211_key *old,
|
||||||
struct ieee80211_key *new)
|
struct ieee80211_key *new)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
bool defunikey, defmultikey, defmgmtkey;
|
bool defunikey, defmultikey, defmgmtkey;
|
||||||
|
@ -397,25 +397,21 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __ieee80211_key_destroy(struct ieee80211_key *key,
|
static void ieee80211_key_free_common(struct ieee80211_key *key)
|
||||||
bool delay_tailroom)
|
|
||||||
{
|
{
|
||||||
if (!key)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Synchronize so the TX path can no longer be using
|
|
||||||
* this key before we free/remove it.
|
|
||||||
*/
|
|
||||||
synchronize_net();
|
|
||||||
|
|
||||||
if (key->local)
|
|
||||||
ieee80211_key_disable_hw_accel(key);
|
|
||||||
|
|
||||||
if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
|
if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
|
||||||
ieee80211_aes_key_free(key->u.ccmp.tfm);
|
ieee80211_aes_key_free(key->u.ccmp.tfm);
|
||||||
if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
|
if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
|
||||||
ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
|
ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
|
||||||
|
kfree(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __ieee80211_key_destroy(struct ieee80211_key *key,
|
||||||
|
bool delay_tailroom)
|
||||||
|
{
|
||||||
|
if (key->local)
|
||||||
|
ieee80211_key_disable_hw_accel(key);
|
||||||
|
|
||||||
if (key->local) {
|
if (key->local) {
|
||||||
struct ieee80211_sub_if_data *sdata = key->sdata;
|
struct ieee80211_sub_if_data *sdata = key->sdata;
|
||||||
|
|
||||||
|
@ -431,7 +427,28 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(key);
|
ieee80211_key_free_common(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ieee80211_key_destroy(struct ieee80211_key *key,
|
||||||
|
bool delay_tailroom)
|
||||||
|
{
|
||||||
|
if (!key)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Synchronize so the TX path can no longer be using
|
||||||
|
* this key before we free/remove it.
|
||||||
|
*/
|
||||||
|
synchronize_net();
|
||||||
|
|
||||||
|
__ieee80211_key_destroy(key, delay_tailroom);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ieee80211_key_free_unused(struct ieee80211_key *key)
|
||||||
|
{
|
||||||
|
WARN_ON(key->sdata || key->local);
|
||||||
|
ieee80211_key_free_common(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ieee80211_key_link(struct ieee80211_key *key,
|
int ieee80211_key_link(struct ieee80211_key *key,
|
||||||
|
@ -462,19 +479,22 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
||||||
|
|
||||||
increment_tailroom_need_count(sdata);
|
increment_tailroom_need_count(sdata);
|
||||||
|
|
||||||
__ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
|
ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
|
||||||
__ieee80211_key_destroy(old_key, true);
|
ieee80211_key_destroy(old_key, true);
|
||||||
|
|
||||||
ieee80211_debugfs_key_add(key);
|
ieee80211_debugfs_key_add(key);
|
||||||
|
|
||||||
ret = ieee80211_key_enable_hw_accel(key);
|
ret = ieee80211_key_enable_hw_accel(key);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
ieee80211_key_free(key, true);
|
||||||
|
|
||||||
mutex_unlock(&sdata->local->key_mtx);
|
mutex_unlock(&sdata->local->key_mtx);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
|
void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
|
||||||
{
|
{
|
||||||
if (!key)
|
if (!key)
|
||||||
return;
|
return;
|
||||||
|
@ -483,18 +503,10 @@ void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
|
||||||
* Replace key with nothingness if it was ever used.
|
* Replace key with nothingness if it was ever used.
|
||||||
*/
|
*/
|
||||||
if (key->sdata)
|
if (key->sdata)
|
||||||
__ieee80211_key_replace(key->sdata, key->sta,
|
ieee80211_key_replace(key->sdata, key->sta,
|
||||||
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
|
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
|
||||||
key, NULL);
|
key, NULL);
|
||||||
__ieee80211_key_destroy(key, delay_tailroom);
|
ieee80211_key_destroy(key, delay_tailroom);
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_key_free(struct ieee80211_local *local,
|
|
||||||
struct ieee80211_key *key)
|
|
||||||
{
|
|
||||||
mutex_lock(&local->key_mtx);
|
|
||||||
__ieee80211_key_free(key, true);
|
|
||||||
mutex_unlock(&local->key_mtx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
|
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
|
||||||
|
@ -554,6 +566,7 @@ EXPORT_SYMBOL(ieee80211_iter_keys);
|
||||||
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
|
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
struct ieee80211_key *key, *tmp;
|
struct ieee80211_key *key, *tmp;
|
||||||
|
LIST_HEAD(keys);
|
||||||
|
|
||||||
cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk);
|
cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk);
|
||||||
|
|
||||||
|
@ -565,17 +578,65 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
|
||||||
|
|
||||||
ieee80211_debugfs_key_remove_mgmt_default(sdata);
|
ieee80211_debugfs_key_remove_mgmt_default(sdata);
|
||||||
|
|
||||||
list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
|
list_for_each_entry_safe(key, tmp, &sdata->key_list, list) {
|
||||||
__ieee80211_key_free(key, false);
|
ieee80211_key_replace(key->sdata, key->sta,
|
||||||
|
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
|
||||||
|
key, NULL);
|
||||||
|
list_add_tail(&key->list, &keys);
|
||||||
|
}
|
||||||
|
|
||||||
ieee80211_debugfs_key_update_default(sdata);
|
ieee80211_debugfs_key_update_default(sdata);
|
||||||
|
|
||||||
|
if (!list_empty(&keys)) {
|
||||||
|
synchronize_net();
|
||||||
|
list_for_each_entry_safe(key, tmp, &keys, list)
|
||||||
|
__ieee80211_key_destroy(key, false);
|
||||||
|
}
|
||||||
|
|
||||||
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
|
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt ||
|
||||||
sdata->crypto_tx_tailroom_pending_dec);
|
sdata->crypto_tx_tailroom_pending_dec);
|
||||||
|
|
||||||
mutex_unlock(&sdata->local->key_mtx);
|
mutex_unlock(&sdata->local->key_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ieee80211_free_sta_keys(struct ieee80211_local *local,
|
||||||
|
struct sta_info *sta)
|
||||||
|
{
|
||||||
|
struct ieee80211_key *key, *tmp;
|
||||||
|
LIST_HEAD(keys);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mutex_lock(&local->key_mtx);
|
||||||
|
for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
|
||||||
|
key = key_mtx_dereference(local, sta->gtk[i]);
|
||||||
|
if (!key)
|
||||||
|
continue;
|
||||||
|
ieee80211_key_replace(key->sdata, key->sta,
|
||||||
|
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
|
||||||
|
key, NULL);
|
||||||
|
list_add(&key->list, &keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
key = key_mtx_dereference(local, sta->ptk);
|
||||||
|
if (key) {
|
||||||
|
ieee80211_key_replace(key->sdata, key->sta,
|
||||||
|
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
|
||||||
|
key, NULL);
|
||||||
|
list_add(&key->list, &keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NB: the station code relies on this being
|
||||||
|
* done even if there aren't any keys
|
||||||
|
*/
|
||||||
|
synchronize_net();
|
||||||
|
|
||||||
|
list_for_each_entry_safe(key, tmp, &keys, list)
|
||||||
|
__ieee80211_key_destroy(key, true);
|
||||||
|
|
||||||
|
mutex_unlock(&local->key_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
void ieee80211_delayed_tailroom_dec(struct work_struct *wk)
|
void ieee80211_delayed_tailroom_dec(struct work_struct *wk)
|
||||||
{
|
{
|
||||||
struct ieee80211_sub_if_data *sdata;
|
struct ieee80211_sub_if_data *sdata;
|
||||||
|
|
|
@ -129,19 +129,20 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
||||||
size_t seq_len, const u8 *seq);
|
size_t seq_len, const u8 *seq);
|
||||||
/*
|
/*
|
||||||
* Insert a key into data structures (sdata, sta if necessary)
|
* Insert a key into data structures (sdata, sta if necessary)
|
||||||
* to make it used, free old key.
|
* to make it used, free old key. On failure, also free the new key.
|
||||||
*/
|
*/
|
||||||
int __must_check ieee80211_key_link(struct ieee80211_key *key,
|
int ieee80211_key_link(struct ieee80211_key *key,
|
||||||
struct ieee80211_sub_if_data *sdata,
|
struct ieee80211_sub_if_data *sdata,
|
||||||
struct sta_info *sta);
|
struct sta_info *sta);
|
||||||
void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom);
|
void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom);
|
||||||
void ieee80211_key_free(struct ieee80211_local *local,
|
void ieee80211_key_free_unused(struct ieee80211_key *key);
|
||||||
struct ieee80211_key *key);
|
|
||||||
void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
|
void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
|
||||||
bool uni, bool multi);
|
bool uni, bool multi);
|
||||||
void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
|
||||||
int idx);
|
int idx);
|
||||||
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
|
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
|
||||||
|
void ieee80211_free_sta_keys(struct ieee80211_local *local,
|
||||||
|
struct sta_info *sta);
|
||||||
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
|
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
|
||||||
|
|
||||||
#define key_mtx_dereference(local, ref) \
|
#define key_mtx_dereference(local, ref) \
|
||||||
|
|
|
@ -100,7 +100,6 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
|
||||||
int power;
|
int power;
|
||||||
enum nl80211_channel_type channel_type;
|
enum nl80211_channel_type channel_type;
|
||||||
u32 offchannel_flag;
|
u32 offchannel_flag;
|
||||||
bool scanning = false;
|
|
||||||
|
|
||||||
offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
|
offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
|
||||||
if (local->scan_channel) {
|
if (local->scan_channel) {
|
||||||
|
@ -147,9 +146,6 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
|
||||||
changed |= IEEE80211_CONF_CHANGE_SMPS;
|
changed |= IEEE80211_CONF_CHANGE_SMPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
|
|
||||||
test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
|
|
||||||
test_bit(SCAN_HW_SCANNING, &local->scanning);
|
|
||||||
power = chan->max_power;
|
power = chan->max_power;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
@ -226,8 +222,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
|
||||||
static void ieee80211_tasklet_handler(unsigned long data)
|
static void ieee80211_tasklet_handler(unsigned long data)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = (struct ieee80211_local *) data;
|
struct ieee80211_local *local = (struct ieee80211_local *) data;
|
||||||
struct sta_info *sta, *tmp;
|
|
||||||
struct skb_eosp_msg_data *eosp_data;
|
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
while ((skb = skb_dequeue(&local->skb_queue)) ||
|
while ((skb = skb_dequeue(&local->skb_queue)) ||
|
||||||
|
@ -243,18 +237,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
|
||||||
skb->pkt_type = 0;
|
skb->pkt_type = 0;
|
||||||
ieee80211_tx_status(&local->hw, skb);
|
ieee80211_tx_status(&local->hw, skb);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_EOSP_MSG:
|
|
||||||
eosp_data = (void *)skb->cb;
|
|
||||||
for_each_sta_info(local, eosp_data->sta, sta, tmp) {
|
|
||||||
/* skip wrong virtual interface */
|
|
||||||
if (memcmp(eosp_data->iface,
|
|
||||||
sta->sdata->vif.addr, ETH_ALEN))
|
|
||||||
continue;
|
|
||||||
clear_sta_flag(sta, WLAN_STA_SP);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
WARN(1, "mac80211: Packet is of unknown type %d\n",
|
WARN(1, "mac80211: Packet is of unknown type %d\n",
|
||||||
skb->pkt_type);
|
skb->pkt_type);
|
||||||
|
@ -295,8 +277,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
|
||||||
"Hardware restart was requested\n");
|
"Hardware restart was requested\n");
|
||||||
|
|
||||||
/* use this reason, ieee80211_reconfig will unblock it */
|
/* use this reason, ieee80211_reconfig will unblock it */
|
||||||
ieee80211_stop_queues_by_reason(hw,
|
ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stop all Rx during the reconfig. We don't want state changes
|
* Stop all Rx during the reconfig. We don't want state changes
|
||||||
|
|
|
@ -699,10 +699,8 @@ out_free:
|
||||||
static int
|
static int
|
||||||
ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh)
|
ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh)
|
||||||
{
|
{
|
||||||
struct ieee80211_sub_if_data *sdata;
|
|
||||||
struct beacon_data *old_bcn;
|
struct beacon_data *old_bcn;
|
||||||
int ret;
|
int ret;
|
||||||
sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh);
|
|
||||||
|
|
||||||
mutex_lock(&ifmsh->mtx);
|
mutex_lock(&ifmsh->mtx);
|
||||||
|
|
||||||
|
@ -833,9 +831,8 @@ ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_mgmt *hdr;
|
struct ieee80211_mgmt *hdr;
|
||||||
struct ieee802_11_elems elems;
|
struct ieee802_11_elems elems;
|
||||||
size_t baselen;
|
size_t baselen;
|
||||||
u8 *pos, *end;
|
u8 *pos;
|
||||||
|
|
||||||
end = ((u8 *) mgmt) + len;
|
|
||||||
pos = mgmt->u.probe_req.variable;
|
pos = mgmt->u.probe_req.variable;
|
||||||
baselen = (u8 *) pos - (u8 *) mgmt;
|
baselen = (u8 *) pos - (u8 *) mgmt;
|
||||||
if (baselen > len)
|
if (baselen > len)
|
||||||
|
|
|
@ -1009,6 +1009,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
|
||||||
|
|
||||||
/* XXX: wait for a beacon first? */
|
/* XXX: wait for a beacon first? */
|
||||||
ieee80211_wake_queues_by_reason(&sdata->local->hw,
|
ieee80211_wake_queues_by_reason(&sdata->local->hw,
|
||||||
|
IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_CSA);
|
IEEE80211_QUEUE_STOP_REASON_CSA);
|
||||||
out:
|
out:
|
||||||
ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
|
ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
|
||||||
|
@ -1108,6 +1109,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
||||||
if (sw_elem->mode)
|
if (sw_elem->mode)
|
||||||
ieee80211_stop_queues_by_reason(&sdata->local->hw,
|
ieee80211_stop_queues_by_reason(&sdata->local->hw,
|
||||||
|
IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_CSA);
|
IEEE80211_QUEUE_STOP_REASON_CSA);
|
||||||
|
|
||||||
if (sdata->local->ops->channel_switch) {
|
if (sdata->local->ops->channel_switch) {
|
||||||
|
@ -1375,6 +1377,7 @@ void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee80211_wake_queues_by_reason(&local->hw,
|
ieee80211_wake_queues_by_reason(&local->hw,
|
||||||
|
IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_PS);
|
IEEE80211_QUEUE_STOP_REASON_PS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1436,7 +1439,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
|
||||||
else {
|
else {
|
||||||
ieee80211_send_nullfunc(local, sdata, 1);
|
ieee80211_send_nullfunc(local, sdata, 1);
|
||||||
/* Flush to get the tx status of nullfunc frame */
|
/* Flush to get the tx status of nullfunc frame */
|
||||||
drv_flush(local, false);
|
ieee80211_flush_queues(local, sdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1767,7 +1770,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
||||||
/* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
|
/* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
|
||||||
if (tx)
|
if (tx)
|
||||||
drv_flush(local, false);
|
ieee80211_flush_queues(local, sdata);
|
||||||
|
|
||||||
/* deauthenticate/disassociate now */
|
/* deauthenticate/disassociate now */
|
||||||
if (tx || frame_buf)
|
if (tx || frame_buf)
|
||||||
|
@ -1776,7 +1779,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
||||||
/* flush out frame */
|
/* flush out frame */
|
||||||
if (tx)
|
if (tx)
|
||||||
drv_flush(local, false);
|
ieee80211_flush_queues(local, sdata);
|
||||||
|
|
||||||
/* clear bssid only after building the needed mgmt frames */
|
/* clear bssid only after building the needed mgmt frames */
|
||||||
memset(ifmgd->bssid, 0, ETH_ALEN);
|
memset(ifmgd->bssid, 0, ETH_ALEN);
|
||||||
|
@ -1948,7 +1951,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
|
||||||
ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
|
ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
|
||||||
run_again(ifmgd, ifmgd->probe_timeout);
|
run_again(ifmgd, ifmgd->probe_timeout);
|
||||||
if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
|
if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
|
||||||
drv_flush(sdata->local, false);
|
ieee80211_flush_queues(sdata->local, sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
|
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)
|
||||||
true, frame_buf);
|
true, frame_buf);
|
||||||
ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
|
ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
|
||||||
ieee80211_wake_queues_by_reason(&sdata->local->hw,
|
ieee80211_wake_queues_by_reason(&sdata->local->hw,
|
||||||
|
IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_CSA);
|
IEEE80211_QUEUE_STOP_REASON_CSA);
|
||||||
mutex_unlock(&ifmgd->mtx);
|
mutex_unlock(&ifmgd->mtx);
|
||||||
|
|
||||||
|
|
|
@ -118,9 +118,9 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
|
||||||
* Stop queues and transmit all frames queued by the driver
|
* Stop queues and transmit all frames queued by the driver
|
||||||
* before sending nullfunc to enable powersave at the AP.
|
* before sending nullfunc to enable powersave at the AP.
|
||||||
*/
|
*/
|
||||||
ieee80211_stop_queues_by_reason(&local->hw,
|
ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
|
IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
|
||||||
drv_flush(local, false);
|
ieee80211_flush_queues(local, NULL);
|
||||||
|
|
||||||
mutex_lock(&local->iflist_mtx);
|
mutex_lock(&local->iflist_mtx);
|
||||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||||
|
@ -181,7 +181,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local)
|
||||||
}
|
}
|
||||||
mutex_unlock(&local->iflist_mtx);
|
mutex_unlock(&local->iflist_mtx);
|
||||||
|
|
||||||
ieee80211_wake_queues_by_reason(&local->hw,
|
ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
|
IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
|
||||||
ieee80211_roc_notify_destroy(roc);
|
ieee80211_roc_notify_destroy(roc);
|
||||||
|
|
||||||
if (started) {
|
if (started) {
|
||||||
drv_flush(local, false);
|
ieee80211_flush_queues(local, NULL);
|
||||||
|
|
||||||
local->tmp_channel = NULL;
|
local->tmp_channel = NULL;
|
||||||
ieee80211_hw_config(local, 0);
|
ieee80211_hw_config(local, 0);
|
||||||
|
|
|
@ -30,12 +30,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee80211_stop_queues_by_reason(hw,
|
ieee80211_stop_queues_by_reason(hw,
|
||||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
IEEE80211_MAX_QUEUE_MAP,
|
||||||
|
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
||||||
|
|
||||||
/* flush out all packets */
|
/* flush out all packets */
|
||||||
synchronize_net();
|
synchronize_net();
|
||||||
|
|
||||||
drv_flush(local, false);
|
ieee80211_flush_queues(local, NULL);
|
||||||
|
|
||||||
local->quiescing = true;
|
local->quiescing = true;
|
||||||
/* make quiescing visible to timers everywhere */
|
/* make quiescing visible to timers everywhere */
|
||||||
|
@ -68,6 +69,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||||
mutex_unlock(&local->sta_mtx);
|
mutex_unlock(&local->sta_mtx);
|
||||||
}
|
}
|
||||||
ieee80211_wake_queues_by_reason(hw,
|
ieee80211_wake_queues_by_reason(hw,
|
||||||
|
IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
||||||
return err;
|
return err;
|
||||||
} else if (err > 0) {
|
} else if (err > 0) {
|
||||||
|
|
|
@ -202,14 +202,23 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
|
||||||
struct minstrel_rate_stats *mr;
|
struct minstrel_rate_stats *mr;
|
||||||
unsigned int nsecs = 0;
|
unsigned int nsecs = 0;
|
||||||
unsigned int tp;
|
unsigned int tp;
|
||||||
|
unsigned int prob;
|
||||||
|
|
||||||
mr = &mi->groups[group].rates[rate];
|
mr = &mi->groups[group].rates[rate];
|
||||||
|
prob = mr->probability;
|
||||||
|
|
||||||
if (mr->probability < MINSTREL_FRAC(1, 10)) {
|
if (prob < MINSTREL_FRAC(1, 10)) {
|
||||||
mr->cur_tp = 0;
|
mr->cur_tp = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the throughput calculation, limit the probability value to 90% to
|
||||||
|
* account for collision related packet error rate fluctuation
|
||||||
|
*/
|
||||||
|
if (prob > MINSTREL_FRAC(9, 10))
|
||||||
|
prob = MINSTREL_FRAC(9, 10);
|
||||||
|
|
||||||
if (group != MINSTREL_CCK_GROUP)
|
if (group != MINSTREL_CCK_GROUP)
|
||||||
nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
|
nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
|
||||||
|
|
||||||
|
@ -639,15 +648,18 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||||
/*
|
/*
|
||||||
* Sampling might add some overhead (RTS, no aggregation)
|
* Sampling might add some overhead (RTS, no aggregation)
|
||||||
* to the frame. Hence, don't use sampling for the currently
|
* to the frame. Hence, don't use sampling for the currently
|
||||||
* used max TP rate.
|
* used rates.
|
||||||
*/
|
*/
|
||||||
if (sample_idx == mi->max_tp_rate)
|
if (sample_idx == mi->max_tp_rate ||
|
||||||
|
sample_idx == mi->max_tp_rate2 ||
|
||||||
|
sample_idx == mi->max_prob_rate)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When not using MRR, do not sample if the probability is already
|
* Do not sample if the probability is already higher than 95%
|
||||||
* higher than 95% to avoid wasting airtime
|
* to avoid wasting airtime.
|
||||||
*/
|
*/
|
||||||
if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100)))
|
if (mr->probability > MINSTREL_FRAC(95, 100))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -153,7 +153,6 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
|
||||||
u8 *elements;
|
u8 *elements;
|
||||||
struct ieee80211_channel *channel;
|
struct ieee80211_channel *channel;
|
||||||
size_t baselen;
|
size_t baselen;
|
||||||
bool beacon;
|
|
||||||
struct ieee802_11_elems elems;
|
struct ieee802_11_elems elems;
|
||||||
|
|
||||||
if (skb->len < 24 ||
|
if (skb->len < 24 ||
|
||||||
|
@ -175,11 +174,9 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
|
||||||
|
|
||||||
elements = mgmt->u.probe_resp.variable;
|
elements = mgmt->u.probe_resp.variable;
|
||||||
baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
|
baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
|
||||||
beacon = false;
|
|
||||||
} else {
|
} else {
|
||||||
baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
|
baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
|
||||||
elements = mgmt->u.beacon.variable;
|
elements = mgmt->u.beacon.variable;
|
||||||
beacon = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baselen > skb->len)
|
if (baselen > skb->len)
|
||||||
|
@ -335,7 +332,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
|
||||||
ieee80211_offchannel_stop_vifs(local);
|
ieee80211_offchannel_stop_vifs(local);
|
||||||
|
|
||||||
/* ensure nullfunc is transmitted before leaving operating channel */
|
/* ensure nullfunc is transmitted before leaving operating channel */
|
||||||
drv_flush(local, false);
|
ieee80211_flush_queues(local, NULL);
|
||||||
|
|
||||||
ieee80211_configure_filter(local);
|
ieee80211_configure_filter(local);
|
||||||
|
|
||||||
|
@ -671,7 +668,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local,
|
||||||
ieee80211_offchannel_stop_vifs(local);
|
ieee80211_offchannel_stop_vifs(local);
|
||||||
|
|
||||||
if (local->ops->flush) {
|
if (local->ops->flush) {
|
||||||
drv_flush(local, false);
|
ieee80211_flush_queues(local, NULL);
|
||||||
*next_delay = 0;
|
*next_delay = 0;
|
||||||
} else
|
} else
|
||||||
*next_delay = HZ / 10;
|
*next_delay = HZ / 10;
|
||||||
|
|
|
@ -556,6 +556,15 @@ static inline void __bss_tim_clear(u8 *tim, u16 id)
|
||||||
tim[id / 8] &= ~(1 << (id % 8));
|
tim[id / 8] &= ~(1 << (id % 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool __bss_tim_get(u8 *tim, u16 id)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This format has been mandated by the IEEE specifications,
|
||||||
|
* so this line may not be changed to use the test_bit() format.
|
||||||
|
*/
|
||||||
|
return tim[id / 8] & (1 << (id % 8));
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned long ieee80211_tids_for_ac(int ac)
|
static unsigned long ieee80211_tids_for_ac(int ac)
|
||||||
{
|
{
|
||||||
/* If we ever support TIDs > 7, this obviously needs to be adjusted */
|
/* 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)
|
||||||
done:
|
done:
|
||||||
spin_lock_bh(&local->tim_lock);
|
spin_lock_bh(&local->tim_lock);
|
||||||
|
|
||||||
|
if (indicate_tim == __bss_tim_get(ps->tim, id))
|
||||||
|
goto out_unlock;
|
||||||
|
|
||||||
if (indicate_tim)
|
if (indicate_tim)
|
||||||
__bss_tim_set(ps->tim, id);
|
__bss_tim_set(ps->tim, id);
|
||||||
else
|
else
|
||||||
|
@ -647,6 +659,7 @@ void sta_info_recalc_tim(struct sta_info *sta)
|
||||||
local->tim_in_locked_section = false;
|
local->tim_in_locked_section = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
spin_unlock_bh(&local->tim_lock);
|
spin_unlock_bh(&local->tim_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,7 +783,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local;
|
struct ieee80211_local *local;
|
||||||
struct ieee80211_sub_if_data *sdata;
|
struct ieee80211_sub_if_data *sdata;
|
||||||
int ret, i;
|
int ret;
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
|
@ -797,14 +810,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
|
||||||
|
|
||||||
list_del_rcu(&sta->list);
|
list_del_rcu(&sta->list);
|
||||||
|
|
||||||
mutex_lock(&local->key_mtx);
|
/* this always calls synchronize_net() */
|
||||||
for (i = 0; i < NUM_DEFAULT_KEYS; i++)
|
ieee80211_free_sta_keys(local, sta);
|
||||||
__ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]),
|
|
||||||
true);
|
|
||||||
if (sta->ptk)
|
|
||||||
__ieee80211_key_free(key_mtx_dereference(local, sta->ptk),
|
|
||||||
true);
|
|
||||||
mutex_unlock(&local->key_mtx);
|
|
||||||
|
|
||||||
sta->dead = true;
|
sta->dead = true;
|
||||||
|
|
||||||
|
@ -1390,30 +1397,16 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ieee80211_sta_block_awake);
|
EXPORT_SYMBOL(ieee80211_sta_block_awake);
|
||||||
|
|
||||||
void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta)
|
void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)
|
||||||
{
|
{
|
||||||
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
|
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
|
||||||
struct ieee80211_local *local = sta->local;
|
struct ieee80211_local *local = sta->local;
|
||||||
struct sk_buff *skb;
|
|
||||||
struct skb_eosp_msg_data *data;
|
|
||||||
|
|
||||||
trace_api_eosp(local, pubsta);
|
trace_api_eosp(local, pubsta);
|
||||||
|
|
||||||
skb = alloc_skb(0, GFP_ATOMIC);
|
clear_sta_flag(sta, WLAN_STA_SP);
|
||||||
if (!skb) {
|
|
||||||
/* too bad ... but race is better than loss */
|
|
||||||
clear_sta_flag(sta, WLAN_STA_SP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = (void *)skb->cb;
|
|
||||||
memcpy(data->sta, pubsta->addr, ETH_ALEN);
|
|
||||||
memcpy(data->iface, sta->sdata->vif.addr, ETH_ALEN);
|
|
||||||
skb->pkt_type = IEEE80211_EOSP_MSG;
|
|
||||||
skb_queue_tail(&local->skb_queue, skb);
|
|
||||||
tasklet_schedule(&local->tasklet);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ieee80211_sta_eosp_irqsafe);
|
EXPORT_SYMBOL(ieee80211_sta_eosp);
|
||||||
|
|
||||||
void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
|
void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
|
||||||
u8 tid, bool buffered)
|
u8 tid, bool buffered)
|
||||||
|
|
|
@ -333,7 +333,8 @@ struct sta_info {
|
||||||
unsigned long driver_buffered_tids;
|
unsigned long driver_buffered_tids;
|
||||||
|
|
||||||
/* Updated from RX path only, no locking requirements */
|
/* Updated from RX path only, no locking requirements */
|
||||||
unsigned long rx_packets, rx_bytes;
|
unsigned long rx_packets;
|
||||||
|
u64 rx_bytes;
|
||||||
unsigned long wep_weak_iv_count;
|
unsigned long wep_weak_iv_count;
|
||||||
unsigned long last_rx;
|
unsigned long last_rx;
|
||||||
long last_connected;
|
long last_connected;
|
||||||
|
@ -353,9 +354,9 @@ struct sta_info {
|
||||||
unsigned int fail_avg;
|
unsigned int fail_avg;
|
||||||
|
|
||||||
/* Updated from TX path only, no locking requirements */
|
/* Updated from TX path only, no locking requirements */
|
||||||
unsigned long tx_packets;
|
u32 tx_fragments;
|
||||||
unsigned long tx_bytes;
|
u64 tx_packets[IEEE80211_NUM_ACS];
|
||||||
unsigned long tx_fragments;
|
u64 tx_bytes[IEEE80211_NUM_ACS];
|
||||||
struct ieee80211_tx_rate last_tx_rate;
|
struct ieee80211_tx_rate last_tx_rate;
|
||||||
int last_rx_rate_idx;
|
int last_rx_rate_idx;
|
||||||
u32 last_rx_rate_flag;
|
u32 last_rx_rate_flag;
|
||||||
|
|
|
@ -431,6 +431,30 @@ TRACE_EVENT(drv_prepare_multicast,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(drv_set_multicast_list,
|
||||||
|
TP_PROTO(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata, int mc_count),
|
||||||
|
|
||||||
|
TP_ARGS(local, sdata, mc_count),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
LOCAL_ENTRY
|
||||||
|
__field(bool, allmulti)
|
||||||
|
__field(int, mc_count)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
LOCAL_ASSIGN;
|
||||||
|
__entry->allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI;
|
||||||
|
__entry->mc_count = mc_count;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk(
|
||||||
|
LOCAL_PR_FMT " configure mc filter, count=%d, allmulti=%d",
|
||||||
|
LOCAL_PR_ARG, __entry->mc_count, __entry->allmulti
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
TRACE_EVENT(drv_configure_filter,
|
TRACE_EVENT(drv_configure_filter,
|
||||||
TP_PROTO(struct ieee80211_local *local,
|
TP_PROTO(struct ieee80211_local *local,
|
||||||
unsigned int changed_flags,
|
unsigned int changed_flags,
|
||||||
|
@ -940,23 +964,26 @@ TRACE_EVENT(drv_get_survey,
|
||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(drv_flush,
|
TRACE_EVENT(drv_flush,
|
||||||
TP_PROTO(struct ieee80211_local *local, bool drop),
|
TP_PROTO(struct ieee80211_local *local,
|
||||||
|
u32 queues, bool drop),
|
||||||
|
|
||||||
TP_ARGS(local, drop),
|
TP_ARGS(local, queues, drop),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
LOCAL_ENTRY
|
LOCAL_ENTRY
|
||||||
__field(bool, drop)
|
__field(bool, drop)
|
||||||
|
__field(u32, queues)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
LOCAL_ASSIGN;
|
LOCAL_ASSIGN;
|
||||||
__entry->drop = drop;
|
__entry->drop = drop;
|
||||||
|
__entry->queues = queues;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk(
|
TP_printk(
|
||||||
LOCAL_PR_FMT " drop:%d",
|
LOCAL_PR_FMT " queues:0x%x drop:%d",
|
||||||
LOCAL_PR_ARG, __entry->drop
|
LOCAL_PR_ARG, __entry->queues, __entry->drop
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -233,6 +233,7 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
|
||||||
|
|
||||||
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
|
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
|
||||||
ieee80211_stop_queues_by_reason(&local->hw,
|
ieee80211_stop_queues_by_reason(&local->hw,
|
||||||
|
IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_PS);
|
IEEE80211_QUEUE_STOP_REASON_PS);
|
||||||
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
|
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
|
||||||
ieee80211_queue_work(&local->hw,
|
ieee80211_queue_work(&local->hw,
|
||||||
|
@ -991,15 +992,18 @@ static ieee80211_tx_result debug_noinline
|
||||||
ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
|
ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
int ac = -1;
|
||||||
|
|
||||||
if (!tx->sta)
|
if (!tx->sta)
|
||||||
return TX_CONTINUE;
|
return TX_CONTINUE;
|
||||||
|
|
||||||
tx->sta->tx_packets++;
|
|
||||||
skb_queue_walk(&tx->skbs, skb) {
|
skb_queue_walk(&tx->skbs, skb) {
|
||||||
|
ac = skb_get_queue_mapping(skb);
|
||||||
tx->sta->tx_fragments++;
|
tx->sta->tx_fragments++;
|
||||||
tx->sta->tx_bytes += skb->len;
|
tx->sta->tx_bytes[ac] += skb->len;
|
||||||
}
|
}
|
||||||
|
if (ac >= 0)
|
||||||
|
tx->sta->tx_packets[ac]++;
|
||||||
|
|
||||||
return TX_CONTINUE;
|
return TX_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -453,7 +453,8 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
|
void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
|
||||||
enum queue_stop_reason reason)
|
unsigned long queues,
|
||||||
|
enum queue_stop_reason reason)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = hw_to_local(hw);
|
struct ieee80211_local *local = hw_to_local(hw);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -461,7 +462,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||||
|
|
||||||
for (i = 0; i < hw->queues; i++)
|
for_each_set_bit(i, &queues, hw->queues)
|
||||||
__ieee80211_stop_queue(hw, i, reason);
|
__ieee80211_stop_queue(hw, i, reason);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||||
|
@ -469,7 +470,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
void ieee80211_stop_queues(struct ieee80211_hw *hw)
|
void ieee80211_stop_queues(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
ieee80211_stop_queues_by_reason(hw,
|
ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_DRIVER);
|
IEEE80211_QUEUE_STOP_REASON_DRIVER);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ieee80211_stop_queues);
|
EXPORT_SYMBOL(ieee80211_stop_queues);
|
||||||
|
@ -491,6 +492,7 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
|
||||||
EXPORT_SYMBOL(ieee80211_queue_stopped);
|
EXPORT_SYMBOL(ieee80211_queue_stopped);
|
||||||
|
|
||||||
void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
|
void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
|
||||||
|
unsigned long queues,
|
||||||
enum queue_stop_reason reason)
|
enum queue_stop_reason reason)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = hw_to_local(hw);
|
struct ieee80211_local *local = hw_to_local(hw);
|
||||||
|
@ -499,7 +501,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||||
|
|
||||||
for (i = 0; i < hw->queues; i++)
|
for_each_set_bit(i, &queues, hw->queues)
|
||||||
__ieee80211_wake_queue(hw, i, reason);
|
__ieee80211_wake_queue(hw, i, reason);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||||
|
@ -507,10 +509,42 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
void ieee80211_wake_queues(struct ieee80211_hw *hw)
|
void ieee80211_wake_queues(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER);
|
ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
|
||||||
|
IEEE80211_QUEUE_STOP_REASON_DRIVER);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ieee80211_wake_queues);
|
EXPORT_SYMBOL(ieee80211_wake_queues);
|
||||||
|
|
||||||
|
void ieee80211_flush_queues(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata)
|
||||||
|
{
|
||||||
|
u32 queues;
|
||||||
|
|
||||||
|
if (!local->ops->flush)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) {
|
||||||
|
int ac;
|
||||||
|
|
||||||
|
queues = 0;
|
||||||
|
|
||||||
|
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
|
||||||
|
queues |= BIT(sdata->vif.hw_queue[ac]);
|
||||||
|
if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE)
|
||||||
|
queues |= BIT(sdata->vif.cab_queue);
|
||||||
|
} else {
|
||||||
|
/* all queues */
|
||||||
|
queues = BIT(local->hw.queues) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
|
||||||
|
IEEE80211_QUEUE_STOP_REASON_FLUSH);
|
||||||
|
|
||||||
|
drv_flush(local, queues, false);
|
||||||
|
|
||||||
|
ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
|
||||||
|
IEEE80211_QUEUE_STOP_REASON_FLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
void ieee80211_iterate_active_interfaces(
|
void ieee80211_iterate_active_interfaces(
|
||||||
struct ieee80211_hw *hw, u32 iter_flags,
|
struct ieee80211_hw *hw, u32 iter_flags,
|
||||||
void (*iterator)(void *data, u8 *mac,
|
void (*iterator)(void *data, u8 *mac,
|
||||||
|
@ -1651,8 +1685,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||||
mutex_unlock(&local->sta_mtx);
|
mutex_unlock(&local->sta_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee80211_wake_queues_by_reason(hw,
|
ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
|
||||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is for hw restart things are still running.
|
* If this is for hw restart things are still running.
|
||||||
|
|
|
@ -1096,8 +1096,10 @@ static int __init cfg80211_init(void)
|
||||||
goto out_fail_reg;
|
goto out_fail_reg;
|
||||||
|
|
||||||
cfg80211_wq = create_singlethread_workqueue("cfg80211");
|
cfg80211_wq = create_singlethread_workqueue("cfg80211");
|
||||||
if (!cfg80211_wq)
|
if (!cfg80211_wq) {
|
||||||
|
err = -ENOMEM;
|
||||||
goto out_fail_wq;
|
goto out_fail_wq;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,7 @@ void cfg80211_conn_work(struct work_struct *work)
|
||||||
wdev_unlock(wdev);
|
wdev_unlock(wdev);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (wdev->sme_state != CFG80211_SME_CONNECTING) {
|
if (wdev->sme_state != CFG80211_SME_CONNECTING || !wdev->conn) {
|
||||||
wdev_unlock(wdev);
|
wdev_unlock(wdev);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue