#include <linux/list.h>
#include <linux/types.h>
#include <linux/if_ether.h>
+#include <linux/workqueue.h>
#include "key.h"
/**
*
* @WLAN_STA_AUTH: Station is authenticated.
* @WLAN_STA_ASSOC: Station is associated.
- * @WLAN_STA_PS: Station is in power-save mode
+ * @WLAN_STA_PS_STA: Station is in power-save mode
* @WLAN_STA_AUTHORIZED: Station is authorized to send/receive traffic.
* This bit is always checked so needs to be enabled for all stations
* when virtual port control is not in use.
* @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
* @WLAN_STA_WME: Station is a QoS-STA.
* @WLAN_STA_WDS: Station is one of our WDS peers.
- * @WLAN_STA_PSPOLL: Station has just PS-polled us.
* @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
* IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
* frame to this station is transmitted.
* @WLAN_STA_MFP: Management frame protection is used with this STA.
* @WLAN_STA_SUSPEND: Set/cleared during a suspend/resume cycle.
* Used to deny ADDBA requests (both TX and RX).
+ * @WLAN_STA_PS_DRIVER: driver requires keeping this station in
+ * power-save mode logically to flush frames that might still
+ * be in the queues
+ * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping
+ * station in power-save mode, reply when the driver unblocks.
*/
enum ieee80211_sta_info_flags {
WLAN_STA_AUTH = 1<<0,
WLAN_STA_ASSOC = 1<<1,
- WLAN_STA_PS = 1<<2,
+ WLAN_STA_PS_STA = 1<<2,
WLAN_STA_AUTHORIZED = 1<<3,
WLAN_STA_SHORT_PREAMBLE = 1<<4,
WLAN_STA_ASSOC_AP = 1<<5,
WLAN_STA_WME = 1<<6,
WLAN_STA_WDS = 1<<7,
- WLAN_STA_PSPOLL = 1<<8,
WLAN_STA_CLEAR_PS_FILT = 1<<9,
WLAN_STA_MFP = 1<<10,
- WLAN_STA_SUSPEND = 1<<11
+ WLAN_STA_SUSPEND = 1<<11,
+ WLAN_STA_PS_DRIVER = 1<<12,
+ WLAN_STA_PSPOLL = 1<<13,
};
#define STA_TID_NUM 16
* @lock: used for locking all fields that require locking, see comments
* in the header file.
* @flaglock: spinlock for flags accesses
+ * @drv_unblock_wk: used for driver PS unblocking
* @listen_interval: listen interval of this station, when we're acting as AP
* @pin_status: used internally for pinning a STA struct into memory
* @flags: STA flags, see &enum ieee80211_sta_info_flags
* @rx_fragments: number of received MPDUs
* @rx_dropped: number of dropped MPDUs from this STA
* @last_signal: signal of last received frame from this STA
- * @last_qual: qual of last received frame from this STA
* @last_noise: noise of last received frame from this STA
* @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
* @tx_filtered_count: number of frames the hardware filtered for this STA
* @plink_timer_was_running: used by suspend/resume to restore timers
* @debugfs: debug filesystem info
* @sta: station information we share with the driver
+ * @dead: set to true when sta is unlinked
*/
struct sta_info {
/* General information, mostly static */
spinlock_t lock;
spinlock_t flaglock;
+ struct work_struct drv_unblock_wk;
+
u16 listen_interval;
+ bool dead;
+
/*
* for use by the internal lifetime management,
* see __sta_info_unlink
unsigned long rx_fragments;
unsigned long rx_dropped;
int last_signal;
- int last_qual;
int last_noise;
__le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
#ifdef CONFIG_MAC80211_DEBUGFS
struct sta_info_debugfsdentries {
struct dentry *dir;
- struct dentry *flags;
- struct dentry *num_ps_buf_frames;
- struct dentry *inactive_ms;
- struct dentry *last_seq_ctrl;
- struct dentry *agg_status;
- struct dentry *aid;
- struct dentry *dev;
- struct dentry *rx_packets;
- struct dentry *tx_packets;
- struct dentry *rx_bytes;
- struct dentry *tx_bytes;
- struct dentry *rx_duplicates;
- struct dentry *rx_fragments;
- struct dentry *rx_dropped;
- struct dentry *tx_fragments;
- struct dentry *tx_filtered;
- struct dentry *tx_retry_failed;
- struct dentry *tx_retry_count;
- struct dentry *last_signal;
- struct dentry *last_qual;
- struct dentry *last_noise;
- struct dentry *wep_weak_iv_count;
bool add_has_run;
} debugfs;
#endif
spin_unlock_irqrestore(&sta->flaglock, irqfl);
}
-static inline void set_and_clear_sta_flags(struct sta_info *sta,
- const u32 set, const u32 clear)
-{
- unsigned long irqfl;
-
- spin_lock_irqsave(&sta->flaglock, irqfl);
- sta->flags |= set;
- sta->flags &= ~clear;
- spin_unlock_irqrestore(&sta->flaglock, irqfl);
-}
-
static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
{
u32 ret;
/*
* Get STA info by index, BROKEN!
*/
-struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx,
- struct net_device *dev);
+struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
+ int idx);
/*
* Create a new STA info, caller owns returned structure
* until sta_info_insert().
void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
unsigned long exp_time);
+void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta);
+void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta);
+
#endif /* STA_INFO_H */