2007-05-05 22:45:53 +04:00
/*
* Copyright 2002 - 2005 , Devicescape Software , Inc .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# ifndef STA_INFO_H
# define STA_INFO_H
# include <linux/list.h>
# include <linux/types.h>
# include <linux/if_ether.h>
2008-04-08 23:14:40 +04:00
# include "key.h"
2007-05-05 22:45:53 +04:00
2008-01-28 19:19:37 +03:00
/**
* enum ieee80211_sta_info_flags - Stations flags
*
* These flags are used with & struct sta_info ' s @ flags member .
*
* @ WLAN_STA_AUTH : Station is authenticated .
* @ WLAN_STA_ASSOC : Station is associated .
* @ WLAN_STA_PS : 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_SHORT_PREAMBLE : Station is capable of receiving short - preamble
* frames .
* @ 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 .
2008-02-19 13:31:14 +03:00
* @ WLAN_STA_PSPOLL : Station has just PS - polled us .
2008-02-21 01:59:33 +03:00
* @ WLAN_STA_CLEAR_PS_FILT : Clear PS filter in hardware ( using the
2008-05-15 14:55:29 +04:00
* IEEE80211_TX_CTL_CLEAR_PS_FILT control flag ) when the next
2008-02-21 01:59:33 +03:00
* frame to this station is transmitted .
2008-01-28 19:19:37 +03:00
*/
enum ieee80211_sta_info_flags {
WLAN_STA_AUTH = 1 < < 0 ,
WLAN_STA_ASSOC = 1 < < 1 ,
WLAN_STA_PS = 1 < < 2 ,
2008-02-20 04:07:21 +03:00
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 ,
2008-02-21 01:59:33 +03:00
WLAN_STA_CLEAR_PS_FILT = 1 < < 9 ,
2008-01-28 19:19:37 +03:00
} ;
2007-05-05 22:45:53 +04:00
2007-12-25 18:00:32 +03:00
# define STA_TID_NUM 16
# define ADDBA_RESP_INTERVAL HZ
2008-01-28 15:07:16 +03:00
# define HT_AGG_MAX_RETRIES (0x3)
2007-12-25 18:00:32 +03:00
# define HT_AGG_STATE_INITIATOR_SHIFT (4)
2008-01-28 15:07:16 +03:00
# define HT_ADDBA_REQUESTED_MSK BIT(0)
# define HT_ADDBA_DRV_READY_MSK BIT(1)
# define HT_ADDBA_RECEIVED_MSK BIT(2)
2007-12-25 18:00:32 +03:00
# define HT_AGG_STATE_REQ_STOP_BA_MSK BIT(3)
2008-01-28 15:07:16 +03:00
# define HT_AGG_STATE_INITIATOR_MSK BIT(HT_AGG_STATE_INITIATOR_SHIFT)
2007-12-25 18:00:32 +03:00
# define HT_AGG_STATE_IDLE (0x0)
2008-01-28 15:07:16 +03:00
# define HT_AGG_STATE_OPERATIONAL (HT_ADDBA_REQUESTED_MSK | \
HT_ADDBA_DRV_READY_MSK | \
HT_ADDBA_RECEIVED_MSK )
2008-03-26 02:33:39 +03:00
# define HT_AGG_STATE_DEBUGFS_CTL BIT(7)
2008-01-28 15:07:16 +03:00
/**
* struct tid_ampdu_tx - TID aggregation information ( Tx ) .
*
* @ addba_resp_timer : timer for peer ' s response to addba request
2008-03-26 21:36:03 +03:00
* @ ssn : Starting Sequence Number expected to be aggregated .
* @ dialog_token : dialog token for aggregation session
2008-01-28 15:07:16 +03:00
*/
struct tid_ampdu_tx {
struct timer_list addba_resp_timer ;
2008-03-26 21:36:03 +03:00
u16 ssn ;
u8 dialog_token ;
2008-01-28 15:07:16 +03:00
} ;
2007-12-25 18:00:32 +03:00
/**
* struct tid_ampdu_rx - TID aggregation information ( Rx ) .
*
* @ reorder_buf : buffer to reorder incoming aggregated MPDUs
* @ session_timer : check if peer keeps Tx - ing on the TID ( by timeout value )
2008-03-27 01:21:47 +03:00
* @ head_seq_num : head sequence number in reordering buffer .
* @ stored_mpdu_num : number of MPDUs in reordering buffer
2008-03-26 21:36:03 +03:00
* @ ssn : Starting Sequence Number expected to be aggregated .
* @ buf_size : buffer size for incoming A - MPDUs
* @ timeout : reset timer value .
* @ dialog_token : dialog token for aggregation session
2007-12-25 18:00:32 +03:00
*/
struct tid_ampdu_rx {
struct sk_buff * * reorder_buf ;
struct timer_list session_timer ;
2008-03-27 01:21:47 +03:00
u16 head_seq_num ;
u16 stored_mpdu_num ;
2008-03-26 21:36:03 +03:00
u16 ssn ;
u16 buf_size ;
u16 timeout ;
u8 dialog_token ;
2007-12-25 18:00:32 +03:00
} ;
2008-03-01 02:46:08 +03:00
/**
* enum plink_state - state of a mesh peer link finite state machine
*
* @ PLINK_LISTEN : initial state , considered the implicit state of non existant
* mesh peer links
* @ PLINK_OPN_SNT : mesh plink open frame has been sent to this mesh peer
* @ PLINK_OPN_RCVD : mesh plink open frame has been received from this mesh peer
* @ PLINK_CNF_RCVD : mesh plink confirm frame has been received from this mesh
* peer
* @ PLINK_ESTAB : mesh peer link is established
* @ PLINK_HOLDING : mesh peer link is being closed or cancelled
* @ PLINK_BLOCKED : all frames transmitted from this mesh plink are discarded
*/
2008-02-23 17:17:11 +03:00
enum plink_state {
2008-03-01 02:46:08 +03:00
PLINK_LISTEN ,
PLINK_OPN_SNT ,
PLINK_OPN_RCVD ,
PLINK_CNF_RCVD ,
PLINK_ESTAB ,
PLINK_HOLDING ,
PLINK_BLOCKED
2008-02-23 17:17:11 +03:00
} ;
2007-12-25 18:00:32 +03:00
/**
* struct sta_ampdu_mlme - STA aggregation information .
*
2008-03-26 21:36:03 +03:00
* @ tid_state_rx : TID ' s state in Rx session state machine .
2008-01-28 15:07:16 +03:00
* @ tid_rx : aggregation info for Rx per TID
2008-03-26 21:36:03 +03:00
* @ tid_state_tx : TID ' s state in Tx session state machine .
* @ tid_tx : aggregation info for Tx per TID
* @ addba_req_num : number of times addBA request has been sent .
2008-01-28 15:07:16 +03:00
* @ dialog_token_allocator : dialog token enumerator for each new session ;
2007-12-25 18:00:32 +03:00
*/
struct sta_ampdu_mlme {
2008-03-26 21:36:03 +03:00
/* rx */
u8 tid_state_rx [ STA_TID_NUM ] ;
struct tid_ampdu_rx * tid_rx [ STA_TID_NUM ] ;
/* tx */
u8 tid_state_tx [ STA_TID_NUM ] ;
struct tid_ampdu_tx * tid_tx [ STA_TID_NUM ] ;
u8 addba_req_num [ STA_TID_NUM ] ;
2008-01-28 15:07:16 +03:00
u8 dialog_token_allocator ;
2007-12-25 18:00:32 +03:00
} ;
2007-05-05 22:45:53 +04:00
2008-02-25 18:27:46 +03:00
/* see __sta_info_unlink */
# define STA_INFO_PIN_STAT_NORMAL 0
# define STA_INFO_PIN_STAT_PINNED 1
# define STA_INFO_PIN_STAT_DESTROY 2
2008-02-25 18:27:48 +03:00
/**
* struct sta_info - STA information
*
* This structure collects information about a station that
* mac80211 is communicating with .
*
* @ list : global linked list entry
* @ hnext : hash table linked list pointer
* @ local : pointer to the global information
2008-07-04 00:52:18 +04:00
* @ sdata : TBD
* @ key : TBD
* @ rate_ctrl : TBD
* @ rate_ctrl_priv : TBD
* @ lock : used for locking all fields that require locking , see comments
* in the header file .
* @ flaglock : spinlock for flags accesses
2008-02-25 18:27:48 +03:00
* @ addr : MAC address of this STA
* @ aid : STA ' s unique AID ( 1. .2007 , 0 = not assigned yet ) ,
* only used in AP ( and IBSS ? ) mode
2008-07-04 00:52:18 +04:00
* @ listen_interval : TBD
* @ pin_status : TBD
2008-02-25 18:27:48 +03:00
* @ flags : STA flags , see & enum ieee80211_sta_info_flags
* @ ps_tx_buf : buffer of frames to transmit to this station
* when it leaves power saving state
* @ tx_filtered : buffer of frames we already tried to transmit
* but were filtered by hardware due to STA having entered
* power saving state
* @ rx_packets : Number of MSDUs received from this STA
* @ rx_bytes : Number of bytes received from this STA
2008-07-04 00:52:18 +04:00
* @ wep_weak_iv_count : TBD
* @ last_rx : TBD
* @ num_duplicates : number of duplicate frames received from this STA
* @ 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 : TBD
* @ tx_retry_failed : TBD
* @ tx_retry_count : TBD
* @ fail_avg : moving percentage of failed MSDUs
* @ tx_packets : number of RX / TX MSDUs
* @ tx_bytes : TBD
* @ tx_fragments : number of transmitted MPDUs
2008-09-12 11:53:27 +04:00
* @ last_txrate_idx : Index of the last used transmit rate
2008-09-04 20:24:53 +04:00
* @ tid_seq : TBD
2008-07-04 00:52:18 +04:00
* @ ampdu_mlme : TBD
* @ timer_to_tid : identity mapping to ID timers
* @ tid_to_tx_q : map tid to tx queue
* @ llid : Local link ID
* @ plid : Peer link ID
* @ reason : Cancel reason on PLINK_HOLDING state
* @ plink_retries : Retries in establishment
* @ ignore_plink_timer : TBD
* @ plink_state plink_state : TBD
* @ plink_timeout : TBD
* @ plink_timer : TBD
* @ debugfs : debug filesystem info
2008-09-11 02:02:02 +04:00
* @ sta : station information we share with the driver
2008-02-25 18:27:48 +03:00
*/
2007-05-05 22:45:53 +04:00
struct sta_info {
2008-02-25 18:27:48 +03:00
/* General information, mostly static */
2007-05-05 22:45:53 +04:00
struct list_head list ;
2008-02-25 18:27:48 +03:00
struct sta_info * hnext ;
2007-05-05 22:45:53 +04:00
struct ieee80211_local * local ;
2008-02-25 18:27:46 +03:00
struct ieee80211_sub_if_data * sdata ;
2007-05-05 22:45:53 +04:00
struct ieee80211_key * key ;
struct rate_control_ref * rate_ctrl ;
void * rate_ctrl_priv ;
2008-05-03 03:02:02 +04:00
spinlock_t lock ;
2008-06-18 16:58:09 +04:00
spinlock_t flaglock ;
2008-09-11 02:02:02 +04:00
2008-02-25 18:27:48 +03:00
u16 listen_interval ;
2007-05-05 22:45:53 +04:00
2008-02-25 18:27:48 +03:00
/*
* for use by the internal lifetime management ,
* see __sta_info_unlink
*/
u8 pin_status ;
2008-06-18 16:58:09 +04:00
/*
* frequently updated , locked with own spinlock ( flaglock ) ,
* use the accessors defined below
*/
2008-02-25 18:27:48 +03:00
u32 flags ;
/*
* STA powersave frame queues , no more than the internal
* locking required .
*/
struct sk_buff_head ps_tx_buf ;
struct sk_buff_head tx_filtered ;
/* Updated from RX path only, no locking requirements */
unsigned long rx_packets , rx_bytes ;
unsigned long wep_weak_iv_count ;
unsigned long last_rx ;
2008-07-04 00:52:18 +04:00
unsigned long num_duplicates ;
unsigned long rx_fragments ;
unsigned long rx_dropped ;
int last_signal ;
int last_qual ;
int last_noise ;
2008-02-25 18:27:48 +03:00
__le16 last_seq_ctrl [ NUM_RX_DATA_QUEUES ] ;
/* Updated from TX status path only, no locking requirements */
unsigned long tx_filtered_count ;
unsigned long tx_retry_failed , tx_retry_count ;
/* moving percentage of failed MSDUs */
unsigned int fail_avg ;
/* Updated from TX path only, no locking requirements */
2008-07-04 00:52:18 +04:00
unsigned long tx_packets ;
2008-02-25 18:27:48 +03:00
unsigned long tx_bytes ;
2008-07-04 00:52:18 +04:00
unsigned long tx_fragments ;
2008-09-11 05:04:36 +04:00
unsigned int last_txrate_idx ;
2008-07-10 13:21:26 +04:00
u16 tid_seq [ IEEE80211_QOS_CTL_TID_MASK + 1 ] ;
2007-05-05 22:45:53 +04:00
2008-02-25 18:27:46 +03:00
/*
2008-05-03 03:02:02 +04:00
* Aggregation information , locked with lock .
2008-02-25 18:27:46 +03:00
*/
2007-12-25 18:00:32 +03:00
struct sta_ampdu_mlme ampdu_mlme ;
2008-07-04 00:52:18 +04:00
u8 timer_to_tid [ STA_TID_NUM ] ;
u8 tid_to_tx_q [ STA_TID_NUM ] ;
2008-02-25 18:27:48 +03:00
2008-02-23 17:17:11 +03:00
# ifdef CONFIG_MAC80211_MESH
2008-02-25 18:27:48 +03:00
/*
* Mesh peer link attributes
* TODO : move to a sub - structure that is referenced with pointer ?
*/
2008-07-04 00:52:18 +04:00
__le16 llid ;
__le16 plid ;
__le16 reason ;
u8 plink_retries ;
2008-02-26 00:17:30 +03:00
bool ignore_plink_timer ;
2008-02-23 17:17:11 +03:00
enum plink_state plink_state ;
u32 plink_timeout ;
struct timer_list plink_timer ;
# endif
2007-11-26 17:14:30 +03:00
2007-05-05 22:46:38 +04:00
# 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 ;
2008-01-28 15:07:20 +03:00
struct dentry * agg_status ;
2007-05-05 22:46:38 +04:00
} debugfs ;
# endif
2008-09-11 02:02:02 +04:00
/* keep last! */
struct ieee80211_sta sta ;
2007-05-05 22:45:53 +04:00
} ;
2008-02-25 18:24:38 +03:00
static inline enum plink_state sta_plink_state ( struct sta_info * sta )
{
# ifdef CONFIG_MAC80211_MESH
return sta - > plink_state ;
# endif
2008-03-01 02:46:08 +03:00
return PLINK_LISTEN ;
2008-02-25 18:24:38 +03:00
}
2008-05-03 03:02:02 +04:00
static inline void set_sta_flags ( struct sta_info * sta , const u32 flags )
{
2008-06-18 16:58:09 +04:00
unsigned long irqfl ;
spin_lock_irqsave ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
sta - > flags | = flags ;
2008-06-18 16:58:09 +04:00
spin_unlock_irqrestore ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
}
static inline void clear_sta_flags ( struct sta_info * sta , const u32 flags )
{
2008-06-18 16:58:09 +04:00
unsigned long irqfl ;
spin_lock_irqsave ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
sta - > flags & = ~ flags ;
2008-06-18 16:58:09 +04:00
spin_unlock_irqrestore ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
}
static inline void set_and_clear_sta_flags ( struct sta_info * sta ,
const u32 set , const u32 clear )
{
2008-06-18 16:58:09 +04:00
unsigned long irqfl ;
spin_lock_irqsave ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
sta - > flags | = set ;
sta - > flags & = ~ clear ;
2008-06-18 16:58:09 +04:00
spin_unlock_irqrestore ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
}
static inline u32 test_sta_flags ( struct sta_info * sta , const u32 flags )
{
u32 ret ;
2008-06-18 16:58:09 +04:00
unsigned long irqfl ;
2008-05-03 03:02:02 +04:00
2008-06-18 16:58:09 +04:00
spin_lock_irqsave ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
ret = sta - > flags & flags ;
2008-06-18 16:58:09 +04:00
spin_unlock_irqrestore ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
return ret ;
}
static inline u32 test_and_clear_sta_flags ( struct sta_info * sta ,
const u32 flags )
{
u32 ret ;
2008-06-18 16:58:09 +04:00
unsigned long irqfl ;
2008-05-03 03:02:02 +04:00
2008-06-18 16:58:09 +04:00
spin_lock_irqsave ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
ret = sta - > flags & flags ;
sta - > flags & = ~ flags ;
2008-06-18 16:58:09 +04:00
spin_unlock_irqrestore ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
return ret ;
}
static inline u32 get_sta_flags ( struct sta_info * sta )
{
u32 ret ;
2008-06-18 16:58:09 +04:00
unsigned long irqfl ;
2008-05-03 03:02:02 +04:00
2008-06-18 16:58:09 +04:00
spin_lock_irqsave ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
ret = sta - > flags ;
2008-06-18 16:58:09 +04:00
spin_unlock_irqrestore ( & sta - > flaglock , irqfl ) ;
2008-05-03 03:02:02 +04:00
return ret ;
}
2007-05-05 22:45:53 +04:00
/* Maximum number of concurrently registered stations */
# define MAX_STA_COUNT 2007
# define STA_HASH_SIZE 256
# define STA_HASH(sta) (sta[5])
/* Maximum number of frames to buffer per power saving station */
# define STA_MAX_TX_BUFFER 128
/* Minimum buffered frame expiry time. If STA uses listen interval that is
* smaller than this value , the minimum value here is used instead . */
# define STA_TX_BUFFER_EXPIRE (10 * HZ)
/* How often station data is cleaned up (e.g., expiration of buffered frames)
*/
# define STA_INFO_CLEANUP_INTERVAL (10 * HZ)
2008-02-25 18:27:46 +03:00
/*
* Get a STA info , must have be under RCU read lock .
*/
2008-09-18 20:14:18 +04:00
struct sta_info * sta_info_get ( struct ieee80211_local * local , const u8 * addr ) ;
2008-02-25 18:27:46 +03:00
/*
* Get STA info by index , BROKEN !
*/
2008-02-23 17:17:11 +03:00
struct sta_info * sta_info_get_by_idx ( struct ieee80211_local * local , int idx ,
struct net_device * dev ) ;
2008-02-25 18:27:46 +03:00
/*
2008-02-25 18:27:47 +03:00
* Create a new STA info , caller owns returned structure
* until sta_info_insert ( ) .
2008-02-25 18:27:46 +03:00
*/
2008-02-25 18:27:47 +03:00
struct sta_info * sta_info_alloc ( struct ieee80211_sub_if_data * sdata ,
u8 * addr , gfp_t gfp ) ;
/*
* Insert STA info into hash table / list , returns zero or a
* - EEXIST if ( if the same MAC address is already present ) .
*
* Calling this without RCU protection makes the caller
* relinquish its reference to @ sta .
*/
int sta_info_insert ( struct sta_info * sta ) ;
2008-02-25 18:27:46 +03:00
/*
* Unlink a STA info from the hash table / list .
* This can NULL the STA pointer if somebody else
* has already unlinked it .
*/
void sta_info_unlink ( struct sta_info * * sta ) ;
2007-05-05 22:45:53 +04:00
2008-02-25 18:27:46 +03:00
void sta_info_destroy ( struct sta_info * sta ) ;
2008-02-20 13:21:35 +03:00
void sta_info_set_tim_bit ( struct sta_info * sta ) ;
void sta_info_clear_tim_bit ( struct sta_info * sta ) ;
2008-02-25 18:27:46 +03:00
void sta_info_init ( struct ieee80211_local * local ) ;
int sta_info_start ( struct ieee80211_local * local ) ;
void sta_info_stop ( struct ieee80211_local * local ) ;
2008-02-25 18:27:49 +03:00
int sta_info_flush ( struct ieee80211_local * local ,
2008-02-25 18:27:46 +03:00
struct ieee80211_sub_if_data * sdata ) ;
2008-03-31 21:23:03 +04:00
void sta_info_flush_delayed ( struct ieee80211_sub_if_data * sdata ) ;
2008-09-11 02:01:46 +04:00
void ieee80211_sta_expire ( struct ieee80211_sub_if_data * sdata ,
unsigned long exp_time ) ;
2008-02-25 18:27:46 +03:00
2007-05-05 22:45:53 +04:00
# endif /* STA_INFO_H */