diff options
Diffstat (limited to 'net/mac80211/sta_info.h')
-rw-r--r-- | net/mac80211/sta_info.h | 113 |
1 files changed, 65 insertions, 48 deletions
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index df9d45544ca5..54262e72376d 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -42,9 +42,6 @@ | |||
42 | * be in the queues | 42 | * be in the queues |
43 | * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping | 43 | * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping |
44 | * station in power-save mode, reply when the driver unblocks. | 44 | * station in power-save mode, reply when the driver unblocks. |
45 | * @WLAN_STA_DISASSOC: Disassociation in progress. | ||
46 | * This is used to reject TX BA session requests when disassociation | ||
47 | * is in progress. | ||
48 | */ | 45 | */ |
49 | enum ieee80211_sta_info_flags { | 46 | enum ieee80211_sta_info_flags { |
50 | WLAN_STA_AUTH = 1<<0, | 47 | WLAN_STA_AUTH = 1<<0, |
@@ -60,38 +57,44 @@ enum ieee80211_sta_info_flags { | |||
60 | WLAN_STA_BLOCK_BA = 1<<11, | 57 | WLAN_STA_BLOCK_BA = 1<<11, |
61 | WLAN_STA_PS_DRIVER = 1<<12, | 58 | WLAN_STA_PS_DRIVER = 1<<12, |
62 | WLAN_STA_PSPOLL = 1<<13, | 59 | WLAN_STA_PSPOLL = 1<<13, |
63 | WLAN_STA_DISASSOC = 1<<14, | ||
64 | }; | 60 | }; |
65 | 61 | ||
66 | #define STA_TID_NUM 16 | 62 | #define STA_TID_NUM 16 |
67 | #define ADDBA_RESP_INTERVAL HZ | 63 | #define ADDBA_RESP_INTERVAL HZ |
68 | #define HT_AGG_MAX_RETRIES (0x3) | 64 | #define HT_AGG_MAX_RETRIES 0x3 |
69 | 65 | ||
70 | #define HT_AGG_STATE_INITIATOR_SHIFT (4) | 66 | #define HT_AGG_STATE_DRV_READY 0 |
71 | 67 | #define HT_AGG_STATE_RESPONSE_RECEIVED 1 | |
72 | #define HT_ADDBA_REQUESTED_MSK BIT(0) | 68 | #define HT_AGG_STATE_OPERATIONAL 2 |
73 | #define HT_ADDBA_DRV_READY_MSK BIT(1) | 69 | #define HT_AGG_STATE_STOPPING 3 |
74 | #define HT_ADDBA_RECEIVED_MSK BIT(2) | 70 | #define HT_AGG_STATE_WANT_START 4 |
75 | #define HT_AGG_STATE_REQ_STOP_BA_MSK BIT(3) | 71 | #define HT_AGG_STATE_WANT_STOP 5 |
76 | #define HT_AGG_STATE_INITIATOR_MSK BIT(HT_AGG_STATE_INITIATOR_SHIFT) | ||
77 | #define HT_AGG_STATE_IDLE (0x0) | ||
78 | #define HT_AGG_STATE_OPERATIONAL (HT_ADDBA_REQUESTED_MSK | \ | ||
79 | HT_ADDBA_DRV_READY_MSK | \ | ||
80 | HT_ADDBA_RECEIVED_MSK) | ||
81 | 72 | ||
82 | /** | 73 | /** |
83 | * struct tid_ampdu_tx - TID aggregation information (Tx). | 74 | * struct tid_ampdu_tx - TID aggregation information (Tx). |
84 | * | 75 | * |
76 | * @rcu_head: rcu head for freeing structure | ||
85 | * @addba_resp_timer: timer for peer's response to addba request | 77 | * @addba_resp_timer: timer for peer's response to addba request |
86 | * @pending: pending frames queue -- use sta's spinlock to protect | 78 | * @pending: pending frames queue -- use sta's spinlock to protect |
87 | * @ssn: Starting Sequence Number expected to be aggregated. | ||
88 | * @dialog_token: dialog token for aggregation session | 79 | * @dialog_token: dialog token for aggregation session |
80 | * @state: session state (see above) | ||
81 | * @stop_initiator: initiator of a session stop | ||
82 | * | ||
83 | * This structure is protected by RCU and the per-station | ||
84 | * spinlock. Assignments to the array holding it must hold | ||
85 | * the spinlock, only the TX path can access it under RCU | ||
86 | * lock-free if, and only if, the state has the flag | ||
87 | * %HT_AGG_STATE_OPERATIONAL set. Otherwise, the TX path | ||
88 | * must also acquire the spinlock and re-check the state, | ||
89 | * see comments in the tx code touching it. | ||
89 | */ | 90 | */ |
90 | struct tid_ampdu_tx { | 91 | struct tid_ampdu_tx { |
92 | struct rcu_head rcu_head; | ||
91 | struct timer_list addba_resp_timer; | 93 | struct timer_list addba_resp_timer; |
92 | struct sk_buff_head pending; | 94 | struct sk_buff_head pending; |
93 | u16 ssn; | 95 | unsigned long state; |
94 | u8 dialog_token; | 96 | u8 dialog_token; |
97 | u8 stop_initiator; | ||
95 | }; | 98 | }; |
96 | 99 | ||
97 | /** | 100 | /** |
@@ -106,8 +109,18 @@ struct tid_ampdu_tx { | |||
106 | * @buf_size: buffer size for incoming A-MPDUs | 109 | * @buf_size: buffer size for incoming A-MPDUs |
107 | * @timeout: reset timer value (in TUs). | 110 | * @timeout: reset timer value (in TUs). |
108 | * @dialog_token: dialog token for aggregation session | 111 | * @dialog_token: dialog token for aggregation session |
112 | * @rcu_head: RCU head used for freeing this struct | ||
113 | * | ||
114 | * This structure is protected by RCU and the per-station | ||
115 | * spinlock. Assignments to the array holding it must hold | ||
116 | * the spinlock, only the RX path can access it under RCU | ||
117 | * lock-free. The RX path, since it is single-threaded, | ||
118 | * can even modify the structure without locking since the | ||
119 | * only other modifications to it are done when the struct | ||
120 | * can not yet or no longer be found by the RX path. | ||
109 | */ | 121 | */ |
110 | struct tid_ampdu_rx { | 122 | struct tid_ampdu_rx { |
123 | struct rcu_head rcu_head; | ||
111 | struct sk_buff **reorder_buf; | 124 | struct sk_buff **reorder_buf; |
112 | unsigned long *reorder_time; | 125 | unsigned long *reorder_time; |
113 | struct timer_list session_timer; | 126 | struct timer_list session_timer; |
@@ -120,6 +133,32 @@ struct tid_ampdu_rx { | |||
120 | }; | 133 | }; |
121 | 134 | ||
122 | /** | 135 | /** |
136 | * struct sta_ampdu_mlme - STA aggregation information. | ||
137 | * | ||
138 | * @tid_rx: aggregation info for Rx per TID -- RCU protected | ||
139 | * @tid_tx: aggregation info for Tx per TID | ||
140 | * @addba_req_num: number of times addBA request has been sent. | ||
141 | * @dialog_token_allocator: dialog token enumerator for each new session; | ||
142 | * @work: work struct for starting/stopping aggregation | ||
143 | * @tid_rx_timer_expired: bitmap indicating on which TIDs the | ||
144 | * RX timer expired until the work for it runs | ||
145 | * @mtx: mutex to protect all TX data (except non-NULL assignments | ||
146 | * to tid_tx[idx], which are protected by the sta spinlock) | ||
147 | */ | ||
148 | struct sta_ampdu_mlme { | ||
149 | struct mutex mtx; | ||
150 | /* rx */ | ||
151 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; | ||
152 | unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)]; | ||
153 | /* tx */ | ||
154 | struct work_struct work; | ||
155 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; | ||
156 | u8 addba_req_num[STA_TID_NUM]; | ||
157 | u8 dialog_token_allocator; | ||
158 | }; | ||
159 | |||
160 | |||
161 | /** | ||
123 | * enum plink_state - state of a mesh peer link finite state machine | 162 | * enum plink_state - state of a mesh peer link finite state machine |
124 | * | 163 | * |
125 | * @PLINK_LISTEN: initial state, considered the implicit state of non existant | 164 | * @PLINK_LISTEN: initial state, considered the implicit state of non existant |
@@ -143,28 +182,6 @@ enum plink_state { | |||
143 | }; | 182 | }; |
144 | 183 | ||
145 | /** | 184 | /** |
146 | * struct sta_ampdu_mlme - STA aggregation information. | ||
147 | * | ||
148 | * @tid_active_rx: TID's state in Rx session state machine. | ||
149 | * @tid_rx: aggregation info for Rx per TID | ||
150 | * @tid_state_tx: TID's state in Tx session state machine. | ||
151 | * @tid_tx: aggregation info for Tx per TID | ||
152 | * @addba_req_num: number of times addBA request has been sent. | ||
153 | * @dialog_token_allocator: dialog token enumerator for each new session; | ||
154 | */ | ||
155 | struct sta_ampdu_mlme { | ||
156 | /* rx */ | ||
157 | bool tid_active_rx[STA_TID_NUM]; | ||
158 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; | ||
159 | /* tx */ | ||
160 | u8 tid_state_tx[STA_TID_NUM]; | ||
161 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; | ||
162 | u8 addba_req_num[STA_TID_NUM]; | ||
163 | u8 dialog_token_allocator; | ||
164 | }; | ||
165 | |||
166 | |||
167 | /** | ||
168 | * struct sta_info - STA information | 185 | * struct sta_info - STA information |
169 | * | 186 | * |
170 | * This structure collects information about a station that | 187 | * This structure collects information about a station that |
@@ -410,20 +427,20 @@ void for_each_sta_info_type_check(struct ieee80211_local *local, | |||
410 | { | 427 | { |
411 | } | 428 | } |
412 | 429 | ||
413 | #define for_each_sta_info(local, _addr, sta, nxt) \ | 430 | #define for_each_sta_info(local, _addr, _sta, nxt) \ |
414 | for ( /* initialise loop */ \ | 431 | for ( /* initialise loop */ \ |
415 | sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\ | 432 | _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\ |
416 | nxt = sta ? rcu_dereference(sta->hnext) : NULL; \ | 433 | nxt = _sta ? rcu_dereference(_sta->hnext) : NULL; \ |
417 | /* typecheck */ \ | 434 | /* typecheck */ \ |
418 | for_each_sta_info_type_check(local, (_addr), sta, nxt), \ | 435 | for_each_sta_info_type_check(local, (_addr), _sta, nxt),\ |
419 | /* continue condition */ \ | 436 | /* continue condition */ \ |
420 | sta; \ | 437 | _sta; \ |
421 | /* advance loop */ \ | 438 | /* advance loop */ \ |
422 | sta = nxt, \ | 439 | _sta = nxt, \ |
423 | nxt = sta ? rcu_dereference(sta->hnext) : NULL \ | 440 | nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \ |
424 | ) \ | 441 | ) \ |
425 | /* compare address and run code only if it matches */ \ | 442 | /* compare address and run code only if it matches */ \ |
426 | if (memcmp(sta->sta.addr, (_addr), ETH_ALEN) == 0) | 443 | if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0) |
427 | 444 | ||
428 | /* | 445 | /* |
429 | * Get STA info by index, BROKEN! | 446 | * Get STA info by index, BROKEN! |