Blame view
net/mac80211/sta_info.h
29.4 KB
d2912cb15
|
1 |
/* SPDX-License-Identifier: GPL-2.0-only */ |
f0706e828
|
2 3 |
/* * Copyright 2002-2005, Devicescape Software, Inc. |
d98ad83ee
|
4 |
* Copyright 2013-2014 Intel Mobile Communications GmbH |
da6a4352e
|
5 |
* Copyright(c) 2015-2017 Intel Deutschland GmbH |
0c197f16f
|
6 |
* Copyright(c) 2020 Intel Corporation |
f0706e828
|
7 8 9 10 11 12 13 14 |
*/ #ifndef STA_INFO_H #define STA_INFO_H #include <linux/list.h> #include <linux/types.h> #include <linux/if_ether.h> |
af8185817
|
15 |
#include <linux/workqueue.h> |
541a45a14
|
16 |
#include <linux/average.h> |
dcba665b1
|
17 |
#include <linux/bitfield.h> |
888d04dfb
|
18 |
#include <linux/etherdevice.h> |
7bedd0cfa
|
19 |
#include <linux/rhashtable.h> |
0f9c5a61d
|
20 |
#include <linux/u64_stats_sync.h> |
2c8dccc77
|
21 |
#include "key.h" |
f0706e828
|
22 |
|
238814fd9
|
23 24 25 |
/** * enum ieee80211_sta_info_flags - Stations flags * |
c2c98fdeb
|
26 27 |
* These flags are used with &struct sta_info's @flags member, but * only indirectly with set_sta_flag() and friends. |
238814fd9
|
28 29 30 |
* * @WLAN_STA_AUTH: Station is authenticated. * @WLAN_STA_ASSOC: Station is associated. |
af8185817
|
31 |
* @WLAN_STA_PS_STA: Station is in power-save mode |
238814fd9
|
32 33 34 35 36 |
* @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. |
238814fd9
|
37 |
* @WLAN_STA_WDS: Station is one of our WDS peers. |
d46e144b6
|
38 |
* @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the |
e039fa4a4
|
39 |
* IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next |
d46e144b6
|
40 |
* frame to this station is transmitted. |
5394af4d8
|
41 |
* @WLAN_STA_MFP: Management frame protection is used with this STA. |
618f356b9
|
42 |
* @WLAN_STA_BLOCK_BA: Used to deny ADDBA requests (both TX and RX) |
098a60709
|
43 |
* during suspend/resume and station removal. |
af8185817
|
44 45 46 47 48 |
* @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. |
941c93cd0
|
49 50 51 |
* @WLAN_STA_TDLS_PEER: Station is a TDLS peer. * @WLAN_STA_TDLS_PEER_AUTH: This TDLS peer is authorized to send direct * packets. This means the link is enabled. |
626911cc6
|
52 53 |
* @WLAN_STA_TDLS_INITIATOR: We are the initiator of the TDLS link with this * station. |
9041c1fa5
|
54 |
* @WLAN_STA_TDLS_CHAN_SWITCH: This TDLS peer supports TDLS channel-switching |
a7a6bdd06
|
55 56 |
* @WLAN_STA_TDLS_OFF_CHANNEL: The local STA is currently off-channel with this * TDLS peer |
b98fb44ff
|
57 58 |
* @WLAN_STA_TDLS_WIDER_BW: This TDLS peer supports working on a wider bw on * the BSS base channel. |
47086fc51
|
59 60 61 62 |
* @WLAN_STA_UAPSD: Station requested unscheduled SP while driver was * keeping station in power-save mode, reply when the driver * unblocks the station. * @WLAN_STA_SP: Station is in a service period, so don't try to |
deeaee197
|
63 |
* reply to other uAPSD trigger frames or PS-Poll. |
e7f4a940b
|
64 |
* @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame. |
83d5cc012
|
65 |
* @WLAN_STA_INSERTED: This station is inserted into the hash table. |
e1936e940
|
66 |
* @WLAN_STA_RATE_CONTROL: rate control was initialized for this station. |
dbf498fba
|
67 |
* @WLAN_STA_TOFFSET_KNOWN: toffset calculated for this station is valid. |
3f52b7e32
|
68 69 |
* @WLAN_STA_MPSP_OWNER: local STA is owner of a mesh Peer Service Period. * @WLAN_STA_MPSP_RECIPIENT: local STA is recipient of a MPSP. |
5ac2e3503
|
70 71 |
* @WLAN_STA_PS_DELIVER: station woke up, but we're still blocking TX * until pending frames are delivered |
b6b5c42e3
|
72 73 |
* @WLAN_STA_USES_ENCRYPTION: This station was configured for encryption, * so drop all packets without a key later. |
c84387d2f
|
74 75 |
* * @NUM_WLAN_STA_FLAGS: number of defined flags |
238814fd9
|
76 77 |
*/ enum ieee80211_sta_info_flags { |
c2c98fdeb
|
78 79 80 81 82 |
WLAN_STA_AUTH, WLAN_STA_ASSOC, WLAN_STA_PS_STA, WLAN_STA_AUTHORIZED, WLAN_STA_SHORT_PREAMBLE, |
c2c98fdeb
|
83 84 85 86 87 88 89 90 |
WLAN_STA_WDS, WLAN_STA_CLEAR_PS_FILT, WLAN_STA_MFP, WLAN_STA_BLOCK_BA, WLAN_STA_PS_DRIVER, WLAN_STA_PSPOLL, WLAN_STA_TDLS_PEER, WLAN_STA_TDLS_PEER_AUTH, |
626911cc6
|
91 |
WLAN_STA_TDLS_INITIATOR, |
9041c1fa5
|
92 |
WLAN_STA_TDLS_CHAN_SWITCH, |
a7a6bdd06
|
93 |
WLAN_STA_TDLS_OFF_CHANNEL, |
b98fb44ff
|
94 |
WLAN_STA_TDLS_WIDER_BW, |
c2c98fdeb
|
95 96 |
WLAN_STA_UAPSD, WLAN_STA_SP, |
e7f4a940b
|
97 |
WLAN_STA_4ADDR_EVENT, |
83d5cc012
|
98 |
WLAN_STA_INSERTED, |
e1936e940
|
99 |
WLAN_STA_RATE_CONTROL, |
dbf498fba
|
100 |
WLAN_STA_TOFFSET_KNOWN, |
3f52b7e32
|
101 102 |
WLAN_STA_MPSP_OWNER, WLAN_STA_MPSP_RECIPIENT, |
5ac2e3503
|
103 |
WLAN_STA_PS_DELIVER, |
a0761a301
|
104 |
WLAN_STA_USES_ENCRYPTION, |
c84387d2f
|
105 106 |
NUM_WLAN_STA_FLAGS, |
238814fd9
|
107 |
}; |
d9a7ddb05
|
108 |
|
5aae28806
|
109 |
#define ADDBA_RESP_INTERVAL HZ |
84381b4ed
|
110 111 112 |
#define HT_AGG_MAX_RETRIES 15 #define HT_AGG_BURST_RETRIES 3 #define HT_AGG_RETRIES_PERIOD (15 * HZ) |
5aae28806
|
113 |
|
a622ab72b
|
114 115 116 117 |
#define HT_AGG_STATE_DRV_READY 0 #define HT_AGG_STATE_RESPONSE_RECEIVED 1 #define HT_AGG_STATE_OPERATIONAL 2 #define HT_AGG_STATE_STOPPING 3 |
0ab337032
|
118 119 |
#define HT_AGG_STATE_WANT_START 4 #define HT_AGG_STATE_WANT_STOP 5 |
7a7c0a643
|
120 121 |
#define HT_AGG_STATE_START_CB 6 #define HT_AGG_STATE_STOP_CB 7 |
0c197f16f
|
122 |
#define HT_AGG_STATE_SENT_ADDBA 8 |
80656c203
|
123 |
|
cc60dbbfe
|
124 |
DECLARE_EWMA(avg_signal, 10, 8) |
c82c4a80b
|
125 126 127 128 129 130 |
enum ieee80211_agg_stop_reason { AGG_STOP_DECLINED, AGG_STOP_LOCAL_REQUEST, AGG_STOP_PEER_REQUEST, AGG_STOP_DESTROY_STA, }; |
b4809e948
|
131 132 133 134 135 136 137 138 |
/* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */ #define AIRTIME_USE_TX BIT(0) #define AIRTIME_USE_RX BIT(1) struct airtime_info { u64 rx_airtime; u64 tx_airtime; s64 deficit; |
3ace10f5b
|
139 140 141 |
atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ u32 aql_limit_low; u32 aql_limit_high; |
b4809e948
|
142 |
}; |
3ace10f5b
|
143 144 145 |
void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, struct sta_info *sta, u8 ac, u16 tx_airtime, bool tx_completed); |
7cca2acdf
|
146 |
struct sta_info; |
80656c203
|
147 148 149 |
/** * struct tid_ampdu_tx - TID aggregation information (Tx). * |
a622ab72b
|
150 |
* @rcu_head: rcu head for freeing structure |
285fa6958
|
151 |
* @session_timer: check if we keep Tx-ing on the TID (by timeout value) |
80656c203
|
152 |
* @addba_resp_timer: timer for peer's response to addba request |
cd8ffc800
|
153 |
* @pending: pending frames queue -- use sta's spinlock to protect |
7cca2acdf
|
154 |
* @sta: station we are attached to |
cee24a3e5
|
155 |
* @dialog_token: dialog token for aggregation session |
bd2ce6e43
|
156 |
* @timeout: session timeout value to be filled in ADDBA requests |
7cca2acdf
|
157 |
* @tid: TID number |
a622ab72b
|
158 |
* @state: session state (see above) |
12d3952fc
|
159 |
* @last_tx: jiffies of last tx activity |
a622ab72b
|
160 |
* @stop_initiator: initiator of a session stop |
53f73c09d
|
161 |
* @tx_stop: TX DelBA frame when stopping |
0b01f030d
|
162 |
* @buf_size: reorder buffer size at receiver |
f0425beda
|
163 164 |
* @failed_bar_ssn: ssn of the last failed BAR tx attempt * @bar_pending: BAR needs to be re-sent |
e3abc8ff0
|
165 |
* @amsdu: support A-MSDU withing A-MDPU |
a622ab72b
|
166 |
* |
dd318575f
|
167 168 169 170 171 172 173 174 |
* This structure's lifetime is managed by RCU, assignments to * the array holding it must hold the aggregation mutex. * * The TX path can access it under RCU lock-free if, and * only if, the state has the flag %HT_AGG_STATE_OPERATIONAL * set. Otherwise, the TX path must also acquire the spinlock * and re-check the state, see comments in the tx code * touching it. |
80656c203
|
175 176 |
*/ struct tid_ampdu_tx { |
a622ab72b
|
177 |
struct rcu_head rcu_head; |
285fa6958
|
178 |
struct timer_list session_timer; |
80656c203
|
179 |
struct timer_list addba_resp_timer; |
cd8ffc800
|
180 |
struct sk_buff_head pending; |
7cca2acdf
|
181 |
struct sta_info *sta; |
a622ab72b
|
182 |
unsigned long state; |
12d3952fc
|
183 |
unsigned long last_tx; |
bd2ce6e43
|
184 |
u16 timeout; |
cee24a3e5
|
185 |
u8 dialog_token; |
a622ab72b
|
186 |
u8 stop_initiator; |
53f73c09d
|
187 |
bool tx_stop; |
41cbb0f5a
|
188 |
u16 buf_size; |
f0425beda
|
189 190 191 |
u16 failed_bar_ssn; bool bar_pending; |
e3abc8ff0
|
192 |
bool amsdu; |
7cca2acdf
|
193 |
u8 tid; |
80656c203
|
194 |
}; |
5aae28806
|
195 196 197 198 |
/** * struct tid_ampdu_rx - TID aggregation information (Rx). * |
83eb935ec
|
199 200 |
* @reorder_buf: buffer to reorder incoming aggregated MPDUs. An MPDU may be an * A-MSDU with individually reported subframes. |
06470f746
|
201 202 |
* @reorder_buf_filtered: bitmap indicating where there are filtered frames in * the reorder buffer that should be ignored when releasing frames |
4d050f1da
|
203 |
* @reorder_time: jiffies when skb was added |
5aae28806
|
204 |
* @session_timer: check if peer keeps Tx-ing on the TID (by timeout value) |
2bff8ebf3
|
205 |
* @reorder_timer: releases expired frames from the reorder buffer. |
7cca2acdf
|
206 |
* @sta: station we are attached to |
12d3952fc
|
207 |
* @last_rx: jiffies of last rx activity |
056cdd599
|
208 209 |
* @head_seq_num: head sequence number in reordering buffer. * @stored_mpdu_num: number of MPDUs in reordering buffer |
cee24a3e5
|
210 211 |
* @ssn: Starting Sequence Number expected to be aggregated. * @buf_size: buffer size for incoming A-MPDUs |
20ad19d0a
|
212 |
* @timeout: reset timer value (in TUs). |
7cca2acdf
|
213 |
* @tid: TID number |
a87f736d9
|
214 |
* @rcu_head: RCU head used for freeing this struct |
2bff8ebf3
|
215 |
* @reorder_lock: serializes access to reorder buffer, see below. |
4549cf2b1
|
216 217 |
* @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and * and ssn. |
788211d81
|
218 |
* @removed: this session is removed (but might have been found due to RCU) |
b7540d8f2
|
219 |
* @started: this session has started (head ssn or higher was received) |
a87f736d9
|
220 |
* |
dd318575f
|
221 222 |
* This structure's lifetime is managed by RCU, assignments to * the array holding it must hold the aggregation mutex. |
2bff8ebf3
|
223 |
* |
dd318575f
|
224 225 226 227 |
* The @reorder_lock is used to protect the members of this * struct, except for @timeout, @buf_size and @dialog_token, * which are constant across the lifetime of the struct (the * dialog token being used only for debugging). |
5aae28806
|
228 229 |
*/ struct tid_ampdu_rx { |
a87f736d9
|
230 |
struct rcu_head rcu_head; |
2bff8ebf3
|
231 |
spinlock_t reorder_lock; |
06470f746
|
232 |
u64 reorder_buf_filtered; |
83eb935ec
|
233 |
struct sk_buff_head *reorder_buf; |
4d050f1da
|
234 |
unsigned long *reorder_time; |
7cca2acdf
|
235 |
struct sta_info *sta; |
5aae28806
|
236 |
struct timer_list session_timer; |
2bff8ebf3
|
237 |
struct timer_list reorder_timer; |
12d3952fc
|
238 |
unsigned long last_rx; |
056cdd599
|
239 240 |
u16 head_seq_num; u16 stored_mpdu_num; |
cee24a3e5
|
241 242 243 |
u16 ssn; u16 buf_size; u16 timeout; |
7cca2acdf
|
244 |
u8 tid; |
b7540d8f2
|
245 246 247 |
u8 auto_seq:1, removed:1, started:1; |
5aae28806
|
248 |
}; |
b4e08ea14
|
249 |
/** |
fcea60070
|
250 251 |
* struct sta_ampdu_mlme - STA aggregation information. * |
412a6d800
|
252 253 254 |
* @mtx: mutex to protect all TX data (except non-NULL assignments * to tid_tx[idx], which are protected by the sta spinlock) * tid_start_tx is also protected by sta->lock. |
a87f736d9
|
255 |
* @tid_rx: aggregation info for Rx per TID -- RCU protected |
1c3d185a9
|
256 |
* @tid_rx_token: dialog tokens for valid aggregation sessions |
7c3b1dd8f
|
257 258 |
* @tid_rx_timer_expired: bitmap indicating on which TIDs the * RX timer expired until the work for it runs |
f41ccd71d
|
259 260 |
* @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the * driver requested to close until the work for it runs |
699cb58c8
|
261 262 |
* @tid_rx_manage_offl: bitmap indicating which BA sessions were requested * to be treated as started/stopped due to offloading |
412a6d800
|
263 |
* @agg_session_valid: bitmap indicating which TID has a rx BA session open on |
bfe40fa39
|
264 265 |
* @unexpected_agg: bitmap indicating which TID already sent a delBA due to * unexpected aggregation related frames outside a session |
412a6d800
|
266 267 268 269 270 271 |
* @work: work struct for starting/stopping aggregation * @tid_tx: aggregation info for Tx per TID * @tid_start_tx: sessions where start was requested * @last_addba_req_time: timestamp of the last addBA request. * @addba_req_num: number of times addBA request has been sent. * @dialog_token_allocator: dialog token enumerator for each new session; |
fcea60070
|
272 273 |
*/ struct sta_ampdu_mlme { |
a93e36443
|
274 |
struct mutex mtx; |
fcea60070
|
275 |
/* rx */ |
5a306f588
|
276 |
struct tid_ampdu_rx __rcu *tid_rx[IEEE80211_NUM_TIDS]; |
1c3d185a9
|
277 |
u8 tid_rx_token[IEEE80211_NUM_TIDS]; |
5a306f588
|
278 279 |
unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; |
699cb58c8
|
280 |
unsigned long tid_rx_manage_offl[BITS_TO_LONGS(2 * IEEE80211_NUM_TIDS)]; |
412a6d800
|
281 |
unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; |
bfe40fa39
|
282 |
unsigned long unexpected_agg[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; |
fcea60070
|
283 |
/* tx */ |
0ab337032
|
284 |
struct work_struct work; |
5a306f588
|
285 286 287 288 |
struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS]; struct tid_ampdu_tx *tid_start_tx[IEEE80211_NUM_TIDS]; unsigned long last_addba_req_time[IEEE80211_NUM_TIDS]; u8 addba_req_num[IEEE80211_NUM_TIDS]; |
fcea60070
|
289 290 |
u8 dialog_token_allocator; }; |
b6da911b3
|
291 292 |
/* Value to indicate no TID reservation */ #define IEEE80211_TID_UNRESERVED 0xff |
e495c2473
|
293 |
#define IEEE80211_FAST_XMIT_MAX_IV 18 |
fcea60070
|
294 |
/** |
17c18bf88
|
295 296 297 298 299 300 301 302 303 304 |
* struct ieee80211_fast_tx - TX fastpath information * @key: key to use for hw crypto * @hdr: the 802.11 header to put with the frame * @hdr_len: actual 802.11 header length * @sa_offs: offset of the SA * @da_offs: offset of the DA * @pn_offs: offset where to put PN for crypto (or 0 if not needed) * @band: band this will be transmitted on, for tx_info * @rcu_head: RCU head to free this struct * |
e495c2473
|
305 306 307 |
* This struct is small enough so that the common case (maximum crypto * header length of 8 like for CCMP/GCMP) fits into a single 64-byte * cache line. |
17c18bf88
|
308 309 310 |
*/ struct ieee80211_fast_tx { struct ieee80211_key *key; |
17c18bf88
|
311 312 313 |
u8 hdr_len; u8 sa_offs, da_offs, pn_offs; u8 band; |
e495c2473
|
314 |
u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV + |
6fe04128f
|
315 |
sizeof(rfc1042_header)] __aligned(2); |
17c18bf88
|
316 317 318 319 320 |
struct rcu_head rcu_head; }; /** |
49ddf8e6e
|
321 322 323 324 325 326 327 328 329 |
* struct ieee80211_fast_rx - RX fastpath information * @dev: netdevice for reporting the SKB * @vif_type: (P2P-less) interface type of the original sdata (sdata->vif.type) * @vif_addr: interface address * @rfc1042_hdr: copy of the RFC 1042 SNAP header (to have in cache) * @control_port_protocol: control port protocol copied from sdata * @expected_ds_bits: from/to DS bits expected * @icv_len: length of the MIC if present * @key: bool indicating encryption is expected (key is set) |
49ddf8e6e
|
330 |
* @internal_forward: forward froms internally on AP/VLAN type interfaces |
c9c5962b5
|
331 |
* @uses_rss: copy of USES_RSS hw flag |
49ddf8e6e
|
332 333 334 335 336 337 338 339 340 341 342 343 344 |
* @da_offs: offset of the DA in the header (for header conversion) * @sa_offs: offset of the SA in the header (for header conversion) * @rcu_head: RCU head for freeing this structure */ struct ieee80211_fast_rx { struct net_device *dev; enum nl80211_iftype vif_type; u8 vif_addr[ETH_ALEN] __aligned(2); u8 rfc1042_hdr[6] __aligned(2); __be16 control_port_protocol; __le16 expected_ds_bits; u8 icv_len; u8 key:1, |
c9c5962b5
|
345 346 |
internal_forward:1, uses_rss:1; |
49ddf8e6e
|
347 348 349 350 |
u8 da_offs, sa_offs; struct rcu_head rcu_head; }; |
3eb0928fc
|
351 352 |
/* we use only values in the range 0-100, so pick a large precision */ DECLARE_EWMA(mesh_fail_avg, 20, 8) |
67fc05549
|
353 |
DECLARE_EWMA(mesh_tx_rate_avg, 8, 16) |
3eb0928fc
|
354 |
|
49ddf8e6e
|
355 |
/** |
433f5bc1c
|
356 357 358 359 |
* struct mesh_sta - mesh STA information * @plink_lock: serialize access to plink fields * @llid: Local link ID * @plid: Peer link ID |
a69bd8e60
|
360 |
* @aid: local aid supplied by peer |
433f5bc1c
|
361 362 363 364 365 |
* @reason: Cancel reason on PLINK_HOLDING state * @plink_retries: Retries in establishment * @plink_state: peer link state * @plink_timeout: timeout of peer link * @plink_timer: peer link watch timer |
4c02d62fa
|
366 |
* @plink_sta: peer link watch timer's sta_info |
433f5bc1c
|
367 368 369 370 371 372 373 374 |
* @t_offset: timing offset relative to this host * @t_offset_setpoint: reference timing offset of this sta to be used when * calculating clockdrift * @local_pm: local link-specific power save mode * @peer_pm: peer-specific power save mode towards local STA * @nonpeer_pm: STA power save mode towards non-peer neighbors * @processed_beacon: set to true after peer rates and capabilities are * processed |
dbdaee7aa
|
375 |
* @connected_to_gate: true if mesh STA has a path to a mesh gate |
1303a51c2
|
376 |
* @connected_to_as: true if mesh STA has a path to a authentication server |
a76d5e0a2
|
377 |
* @fail_avg: moving percentage of failed MSDUs |
67fc05549
|
378 |
* @tx_rate_avg: moving average of tx bitrate |
433f5bc1c
|
379 380 381 |
*/ struct mesh_sta { struct timer_list plink_timer; |
4c02d62fa
|
382 |
struct sta_info *plink_sta; |
433f5bc1c
|
383 384 385 386 387 388 389 |
s64 t_offset; s64 t_offset_setpoint; spinlock_t plink_lock; u16 llid; u16 plid; |
a69bd8e60
|
390 |
u16 aid; |
433f5bc1c
|
391 392 393 394 |
u16 reason; u8 plink_retries; bool processed_beacon; |
dbdaee7aa
|
395 |
bool connected_to_gate; |
1303a51c2
|
396 |
bool connected_to_as; |
433f5bc1c
|
397 398 399 400 401 402 403 404 |
enum nl80211_plink_state plink_state; u32 plink_timeout; /* mesh power save */ enum nl80211_mesh_power_mode local_pm; enum nl80211_mesh_power_mode peer_pm; enum nl80211_mesh_power_mode nonpeer_pm; |
a76d5e0a2
|
405 406 |
/* moving percentage of failed MSDUs */ |
3eb0928fc
|
407 |
struct ewma_mesh_fail_avg fail_avg; |
67fc05549
|
408 409 |
/* moving average of tx bitrate */ struct ewma_mesh_tx_rate_avg tx_rate_avg; |
433f5bc1c
|
410 |
}; |
eb1e011a1
|
411 |
DECLARE_EWMA(signal, 10, 8) |
40d9a38ad
|
412 |
|
c9c5962b5
|
413 414 415 416 417 418 419 420 421 |
struct ieee80211_sta_rx_stats { unsigned long packets; unsigned long last_rx; unsigned long num_duplicates; unsigned long fragments; unsigned long dropped; int last_signal; u8 chains; s8 chain_signal_last[IEEE80211_MAX_CHAINS]; |
41cbb0f5a
|
422 |
u32 last_rate; |
c9c5962b5
|
423 424 425 426 |
struct u64_stats_sync syncp; u64 bytes; u64 msdu[IEEE80211_NUM_TIDS + 1]; }; |
8f797c288
|
427 |
/* |
484a54c2e
|
428 429 430 431 432 433 434 435 |
* The bandwidth threshold below which the per-station CoDel parameters will be * scaled to be more lenient (to prevent starvation of slow stations). This * value will be scaled by the number of active stations when it is being * applied. */ #define STA_SLOW_THRESHOLD 6000 /* 6 Mbps */ /** |
693b1bbcc
|
436 437 438 439 440 441 |
* struct sta_info - STA information * * This structure collects information about a station that * mac80211 is communicating with. * * @list: global linked list entry |
d778207b0
|
442 |
* @free_list: list entry for keeping track of stations to free |
7bedd0cfa
|
443 |
* @hash_node: hash node for rhashtable |
ac100ce52
|
444 445 |
* @addr: station's MAC address - duplicated from public part to * let the hash table work with just a single cacheline |
693b1bbcc
|
446 |
* @local: pointer to the global information |
e25cf4a69
|
447 |
* @sdata: virtual interface this station belongs to |
2475b1cc0
|
448 449 |
* @ptk: peer keys negotiated with this station, if any * @ptk_idx: last installed peer key index |
e31b82136
|
450 |
* @gtk: group keys negotiated with this station, if any |
e25cf4a69
|
451 |
* @rate_ctrl: rate control algorithm reference |
bbbe8c8c5
|
452 453 |
* @rate_ctrl_lock: spinlock used to protect rate control data * (data inside the algorithm, so serializes calls there) |
e25cf4a69
|
454 |
* @rate_ctrl_priv: rate control private per-STA pointer |
6ef307bc5
|
455 456 |
* @lock: used for locking all fields that require locking, see comments * in the header file. |
5ac2e3503
|
457 |
* @drv_deliver_wk: used for delivering frames after driver PS unblocking |
e25cf4a69
|
458 |
* @listen_interval: listen interval of this station, when we're acting as AP |
c2c98fdeb
|
459 |
* @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly |
1d147bfa6
|
460 |
* @ps_lock: used for powersave (when mac80211 is the AP) related locking |
948d887de
|
461 462 463 464 465 466 467 |
* @ps_tx_buf: buffers (per AC) of frames to transmit to this station * when it leaves power saving state or polls * @tx_filtered: buffers (per AC) of frames we already tried to * transmit but were filtered by hardware due to STA having * entered power saving state, these are also delivered to * the station when it leaves powersave or polls for frames * @driver_buffered_tids: bitmap of TIDs the driver has data buffered on |
ba8c3d6f1
|
468 |
* @txq_buffered_tids: bitmap of TIDs that mac80211 has txq data buffered on |
9cf023388
|
469 |
* @assoc_at: clock boottime (in ns) of last association |
ebe27c91a
|
470 |
* @last_connected: time (in seconds) when a station got connected |
798a457df
|
471 472 |
* @last_seq_ctrl: last received seq/frag number from this STA (per TID * plus one for non-QoS frames) |
e25cf4a69
|
473 |
* @tid_seq: per-TID sequence numbers for sending to this STA |
cb86880ee
|
474 475 476 |
* @airtime: per-AC struct airtime_info describing airtime statistics for this * station * @airtime_weight: station weight for airtime fairness calculation purposes |
e25cf4a69
|
477 |
* @ampdu_mlme: A-MPDU state machine state |
433f5bc1c
|
478 |
* @mesh: mesh STA information |
fc4a25c5b
|
479 |
* @debugfs_dir: debug filesystem directory dentry |
af8185817
|
480 |
* @dead: set to true when sta is unlinked |
ef044763a
|
481 |
* @removed: set to true when sta is being removed from sta_list |
34e895075
|
482 |
* @uploaded: set to true when sta is uploaded to the driver |
2a33bee27
|
483 |
* @sta: station information we share with the driver |
d9a7ddb05
|
484 |
* @sta_state: duplicates information about station state (for debug) |
077f897a8
|
485 |
* @rcu_head: RCU head used for freeing this station struct |
0af83d3df
|
486 487 |
* @cur_max_bandwidth: maximum bandwidth to use for TX to the station, * taken from HT/VHT capabilities or VHT operating mode notification |
687da1322
|
488 489 |
* @known_smps_mode: the smps_mode the client thinks we are in. Relevant for * AP only. |
2475b1cc0
|
490 |
* @cipher_scheme: optional cipher scheme for this station |
484a54c2e
|
491 |
* @cparams: CoDel parameters for this station. |
b6da911b3
|
492 |
* @reserved_tid: reserved TID (if any, otherwise IEEE80211_TID_UNRESERVED) |
17c18bf88
|
493 |
* @fast_tx: TX fastpath information |
49ddf8e6e
|
494 |
* @fast_rx: RX fastpath information |
0fabfaafe
|
495 496 |
* @tdls_chandef: a TDLS peer can have a wider chandef that is compatible to * the BSS one. |
e5a9f8d04
|
497 |
* @tx_stats: TX statistics |
7d4194633
|
498 499 500 501 |
* @tx_stats.packets: # of packets transmitted * @tx_stats.bytes: # of bytes in all packets transmitted * @tx_stats.last_rate: last TX rate * @tx_stats.msdu: # of transmitted MSDUs per TID |
e5a9f8d04
|
502 |
* @rx_stats: RX statistics |
7d4194633
|
503 504 505 |
* @rx_stats_avg: averaged RX statistics * @rx_stats_avg.signal: averaged signal * @rx_stats_avg.chain_signal: averaged per-chain signal |
c9c5962b5
|
506 507 |
* @pcpu_rx_stats: per-CPU RX statistics, assigned only if the driver needs * this (by advertising the USES_RSS hw flag) |
e5a9f8d04
|
508 |
* @status_stats: TX status statistics |
7d4194633
|
509 510 511 512 |
* @status_stats.filtered: # of filtered frames * @status_stats.retry_failed: # of frames that failed after retry * @status_stats.retry_count: # of retries attempted * @status_stats.lost_packets: # of lost packets |
47df8e059
|
513 |
* @status_stats.last_pkt_time: timestamp of last ACKed packet |
7d4194633
|
514 515 516 517 518 519 |
* @status_stats.msdu_retries: # of MSDU retries * @status_stats.msdu_failed: # of failed MSDUs * @status_stats.last_ack: last ack timestamp (jiffies) * @status_stats.last_ack_signal: last ACK signal * @status_stats.ack_signal_filled: last ACK signal validity * @status_stats.avg_ack_signal: average ACK signal |
693b1bbcc
|
520 |
*/ |
f0706e828
|
521 |
struct sta_info { |
693b1bbcc
|
522 |
/* General information, mostly static */ |
d778207b0
|
523 |
struct list_head list, free_list; |
b22cfcfca
|
524 |
struct rcu_head rcu_head; |
83e7e4ce9
|
525 |
struct rhlist_head hash_node; |
ac100ce52
|
526 |
u8 addr[ETH_ALEN]; |
f0706e828
|
527 |
struct ieee80211_local *local; |
d0709a651
|
528 |
struct ieee80211_sub_if_data *sdata; |
e5473e80d
|
529 530 531 |
struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + NUM_DEFAULT_BEACON_KEYS]; |
2475b1cc0
|
532 |
struct ieee80211_key __rcu *ptk[NUM_DEFAULT_KEYS]; |
2475b1cc0
|
533 |
u8 ptk_idx; |
f0706e828
|
534 535 |
struct rate_control_ref *rate_ctrl; void *rate_ctrl_priv; |
35c347ac5
|
536 |
spinlock_t rate_ctrl_lock; |
07346f81e
|
537 |
spinlock_t lock; |
17741cdc2
|
538 |
|
17c18bf88
|
539 |
struct ieee80211_fast_tx __rcu *fast_tx; |
49ddf8e6e
|
540 |
struct ieee80211_fast_rx __rcu *fast_rx; |
c9c5962b5
|
541 |
struct ieee80211_sta_rx_stats __percpu *pcpu_rx_stats; |
17c18bf88
|
542 |
|
433f5bc1c
|
543 544 545 |
#ifdef CONFIG_MAC80211_MESH struct mesh_sta *mesh; #endif |
5ac2e3503
|
546 |
struct work_struct drv_deliver_wk; |
af8185817
|
547 |
|
693b1bbcc
|
548 |
u16 listen_interval; |
f0706e828
|
549 |
|
af8185817
|
550 |
bool dead; |
ef044763a
|
551 |
bool removed; |
af8185817
|
552 |
|
34e895075
|
553 |
bool uploaded; |
693b1bbcc
|
554 |
|
d9a7ddb05
|
555 |
enum ieee80211_sta_state sta_state; |
c2c98fdeb
|
556 557 |
/* use the accessors defined below */ unsigned long _flags; |
693b1bbcc
|
558 |
|
1d147bfa6
|
559 560 |
/* STA powersave lock and frame queues */ spinlock_t ps_lock; |
948d887de
|
561 562 563 |
struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS]; struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS]; unsigned long driver_buffered_tids; |
ba8c3d6f1
|
564 |
unsigned long txq_buffered_tids; |
693b1bbcc
|
565 |
|
9cf023388
|
566 |
u64 assoc_at; |
ebe27c91a
|
567 |
long last_connected; |
ef0621e80
|
568 |
|
e5a9f8d04
|
569 |
/* Updated from RX path only, no locking requirements */ |
c9c5962b5
|
570 |
struct ieee80211_sta_rx_stats rx_stats; |
0be6ed133
|
571 572 573 574 |
struct { struct ewma_signal signal; struct ewma_signal chain_signal[IEEE80211_MAX_CHAINS]; } rx_stats_avg; |
ef0621e80
|
575 |
|
9e26297a5
|
576 |
/* Plus 1 for non-QoS frames */ |
5a306f588
|
577 |
__le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1]; |
693b1bbcc
|
578 579 |
/* Updated from TX status path only, no locking requirements */ |
e5a9f8d04
|
580 581 582 583 |
struct { unsigned long filtered; unsigned long retry_failed, retry_count; unsigned int lost_packets; |
47df8e059
|
584 |
unsigned long last_pkt_time; |
e5a9f8d04
|
585 586 |
u64 msdu_retries[IEEE80211_NUM_TIDS + 1]; u64 msdu_failed[IEEE80211_NUM_TIDS + 1]; |
b8da6b6a9
|
587 |
unsigned long last_ack; |
a78b26fff
|
588 589 |
s8 last_ack_signal; bool ack_signal_filled; |
cc60dbbfe
|
590 |
struct ewma_avg_signal avg_ack_signal; |
e5a9f8d04
|
591 |
} status_stats; |
693b1bbcc
|
592 593 |
/* Updated from TX path only, no locking requirements */ |
e5a9f8d04
|
594 595 596 597 |
struct { u64 packets[IEEE80211_NUM_ACS]; u64 bytes[IEEE80211_NUM_ACS]; struct ieee80211_tx_rate last_rate; |
8ed37e791
|
598 |
struct rate_info last_rate_info; |
e5a9f8d04
|
599 600 |
u64 msdu[IEEE80211_NUM_TIDS + 1]; } tx_stats; |
f591fa5db
|
601 |
u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; |
f0706e828
|
602 |
|
b4809e948
|
603 604 |
struct airtime_info airtime[IEEE80211_NUM_ACS]; u16 airtime_weight; |
d0709a651
|
605 |
/* |
07346f81e
|
606 |
* Aggregation information, locked with lock. |
d0709a651
|
607 |
*/ |
5aae28806
|
608 |
struct sta_ampdu_mlme ampdu_mlme; |
693b1bbcc
|
609 |
|
e9f207f0f
|
610 |
#ifdef CONFIG_MAC80211_DEBUGFS |
fc4a25c5b
|
611 |
struct dentry *debugfs_dir; |
e9f207f0f
|
612 |
#endif |
17741cdc2
|
613 |
|
0af83d3df
|
614 |
enum ieee80211_sta_rx_bandwidth cur_max_bandwidth; |
687da1322
|
615 |
enum ieee80211_smps_mode known_smps_mode; |
2475b1cc0
|
616 |
const struct ieee80211_cipher_scheme *cipher_scheme; |
687da1322
|
617 |
|
484a54c2e
|
618 |
struct codel_params cparams; |
b6da911b3
|
619 |
u8 reserved_tid; |
0fabfaafe
|
620 |
struct cfg80211_chan_def tdls_chandef; |
17741cdc2
|
621 622 |
/* keep last! */ struct ieee80211_sta sta; |
f0706e828
|
623 |
}; |
57cf8043a
|
624 |
static inline enum nl80211_plink_state sta_plink_state(struct sta_info *sta) |
d6d1a5a70
|
625 626 |
{ #ifdef CONFIG_MAC80211_MESH |
433f5bc1c
|
627 |
return sta->mesh->plink_state; |
d6d1a5a70
|
628 |
#endif |
57cf8043a
|
629 |
return NL80211_PLINK_LISTEN; |
d6d1a5a70
|
630 |
} |
c2c98fdeb
|
631 632 |
static inline void set_sta_flag(struct sta_info *sta, enum ieee80211_sta_info_flags flag) |
07346f81e
|
633 |
{ |
d9a7ddb05
|
634 635 636 |
WARN_ON(flag == WLAN_STA_AUTH || flag == WLAN_STA_ASSOC || flag == WLAN_STA_AUTHORIZED); |
c2c98fdeb
|
637 |
set_bit(flag, &sta->_flags); |
07346f81e
|
638 |
} |
c2c98fdeb
|
639 640 |
static inline void clear_sta_flag(struct sta_info *sta, enum ieee80211_sta_info_flags flag) |
07346f81e
|
641 |
{ |
d9a7ddb05
|
642 643 644 |
WARN_ON(flag == WLAN_STA_AUTH || flag == WLAN_STA_ASSOC || flag == WLAN_STA_AUTHORIZED); |
c2c98fdeb
|
645 |
clear_bit(flag, &sta->_flags); |
07346f81e
|
646 |
} |
c2c98fdeb
|
647 648 |
static inline int test_sta_flag(struct sta_info *sta, enum ieee80211_sta_info_flags flag) |
07346f81e
|
649 |
{ |
c2c98fdeb
|
650 |
return test_bit(flag, &sta->_flags); |
07346f81e
|
651 |
} |
c2c98fdeb
|
652 653 |
static inline int test_and_clear_sta_flag(struct sta_info *sta, enum ieee80211_sta_info_flags flag) |
07346f81e
|
654 |
{ |
d9a7ddb05
|
655 656 657 |
WARN_ON(flag == WLAN_STA_AUTH || flag == WLAN_STA_ASSOC || flag == WLAN_STA_AUTHORIZED); |
c2c98fdeb
|
658 |
return test_and_clear_bit(flag, &sta->_flags); |
07346f81e
|
659 |
} |
e7f4a940b
|
660 661 662 |
static inline int test_and_set_sta_flag(struct sta_info *sta, enum ieee80211_sta_info_flags flag) { |
d9a7ddb05
|
663 664 665 |
WARN_ON(flag == WLAN_STA_AUTH || flag == WLAN_STA_ASSOC || flag == WLAN_STA_AUTHORIZED); |
e7f4a940b
|
666 667 |
return test_and_set_bit(flag, &sta->_flags); } |
83d5cc012
|
668 669 |
int sta_info_move_state(struct sta_info *sta, enum ieee80211_sta_state new_state); |
d9a7ddb05
|
670 |
|
83d5cc012
|
671 672 |
static inline void sta_info_pre_move_state(struct sta_info *sta, enum ieee80211_sta_state new_state) |
d9a7ddb05
|
673 |
{ |
83d5cc012
|
674 675 676 677 678 |
int ret; WARN_ON_ONCE(test_sta_flag(sta, WLAN_STA_INSERTED)); ret = sta_info_move_state(sta, new_state); |
d9a7ddb05
|
679 680 |
WARN_ON_ONCE(ret); } |
ec034b208
|
681 682 |
void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, struct tid_ampdu_tx *tid_tx); |
f0706e828
|
683 |
|
40b275b69
|
684 685 686 687 688 689 690 |
static inline struct tid_ampdu_tx * rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid) { return rcu_dereference_protected(sta->ampdu_mlme.tid_tx[tid], lockdep_is_held(&sta->lock) || lockdep_is_held(&sta->ampdu_mlme.mtx)); } |
f0706e828
|
691 |
|
948d887de
|
692 693 |
/* Maximum number of frames to buffer per power saving station per AC */ #define STA_MAX_TX_BUFFER 64 |
f0706e828
|
694 695 696 697 698 699 700 701 |
/* 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) |
83e7e4ce9
|
702 703 |
struct rhlist_head *sta_info_hash_lookup(struct ieee80211_local *local, const u8 *addr); |
d0709a651
|
704 |
/* |
abe60632f
|
705 |
* Get a STA info, must be under RCU read lock. |
d0709a651
|
706 |
*/ |
abe60632f
|
707 708 |
struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, const u8 *addr); |
0e5ded5a8
|
709 710 |
struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, const u8 *addr); |
5072f73cb
|
711 712 713 |
/* user must hold sta_mtx or be in RCU critical section */ struct sta_info *sta_info_get_by_addrs(struct ieee80211_local *local, const u8 *sta_addr, const u8 *vif_addr); |
83e7e4ce9
|
714 715 716 |
#define for_each_sta_info(local, _addr, _sta, _tmp) \ rhl_for_each_entry_rcu(_sta, _tmp, \ sta_info_hash_lookup(local, _addr), hash_node) |
abe60632f
|
717 |
|
d0709a651
|
718 719 720 |
/* * Get STA info by index, BROKEN! */ |
3b53fde8a
|
721 722 |
struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata, int idx); |
d0709a651
|
723 |
/* |
73651ee63
|
724 725 |
* Create a new STA info, caller owns returned structure * until sta_info_insert(). |
d0709a651
|
726 |
*/ |
73651ee63
|
727 |
struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, |
56544160d
|
728 |
const u8 *addr, gfp_t gfp); |
d9a7ddb05
|
729 730 |
void sta_info_free(struct ieee80211_local *local, struct sta_info *sta); |
73651ee63
|
731 732 733 734 |
/* * Insert STA info into hash table/list, returns zero or a * -EEXIST if (if the same MAC address is already present). * |
34e895075
|
735 736 737 |
* Calling the non-rcu version makes the caller relinquish, * the _rcu version calls read_lock_rcu() and must be called * without it held. |
73651ee63
|
738 739 |
*/ int sta_info_insert(struct sta_info *sta); |
34e895075
|
740 |
int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU); |
34e895075
|
741 |
|
83d5cc012
|
742 |
int __must_check __sta_info_destroy(struct sta_info *sta); |
34e895075
|
743 744 745 746 |
int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, const u8 *addr); int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata, const u8 *addr); |
f0706e828
|
747 |
|
c868cb35d
|
748 |
void sta_info_recalc_tim(struct sta_info *sta); |
004c872e7
|
749 |
|
7bedd0cfa
|
750 |
int sta_info_init(struct ieee80211_local *local); |
d0709a651
|
751 |
void sta_info_stop(struct ieee80211_local *local); |
051007d9e
|
752 753 |
/** |
b1e8eb11f
|
754 |
* __sta_info_flush - flush matching STA entries from the STA table |
051007d9e
|
755 756 757 758 |
* * Returns the number of removed STA entries. * * @sdata: sdata to remove all stations from |
e716251d7
|
759 |
* @vlans: if the given interface is an AP interface, also flush VLANs |
051007d9e
|
760 |
*/ |
e716251d7
|
761 |
int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans); |
b1e8eb11f
|
762 763 764 765 766 767 768 |
/** * sta_info_flush - flush matching STA entries from the STA table * * Returns the number of removed STA entries. * * @sdata: sdata to remove all stations from */ |
e716251d7
|
769 770 771 772 |
static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata) { return __sta_info_flush(sdata, false); } |
051007d9e
|
773 |
|
6b62bf326
|
774 775 776 |
void sta_set_rate_info_tx(struct sta_info *sta, const struct ieee80211_tx_rate *rate, struct rate_info *rinfo); |
0fdf1493b
|
777 778 |
void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, bool tidstats); |
b7ffbd7ef
|
779 |
|
3b17fbf87
|
780 |
u32 sta_get_expected_throughput(struct sta_info *sta); |
24723d1bc
|
781 782 |
void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, unsigned long exp_time); |
687da1322
|
783 |
u8 sta_info_tx_streams(struct sta_info *sta); |
d0709a651
|
784 |
|
af8185817
|
785 786 |
void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta); void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); |
47086fc51
|
787 |
void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta); |
af8185817
|
788 |
|
b8da6b6a9
|
789 |
unsigned long ieee80211_sta_last_active(struct sta_info *sta); |
dcba665b1
|
790 791 792 793 794 |
enum sta_stats_type { STA_STATS_RATE_TYPE_INVALID = 0, STA_STATS_RATE_TYPE_LEGACY, STA_STATS_RATE_TYPE_HT, STA_STATS_RATE_TYPE_VHT, |
41cbb0f5a
|
795 |
STA_STATS_RATE_TYPE_HE, |
12bf8fad4
|
796 |
STA_STATS_RATE_TYPE_S1G, |
dcba665b1
|
797 798 799 800 801 802 803 |
}; #define STA_STATS_FIELD_HT_MCS GENMASK( 7, 0) #define STA_STATS_FIELD_LEGACY_IDX GENMASK( 3, 0) #define STA_STATS_FIELD_LEGACY_BAND GENMASK( 7, 4) #define STA_STATS_FIELD_VHT_MCS GENMASK( 3, 0) #define STA_STATS_FIELD_VHT_NSS GENMASK( 7, 4) |
41cbb0f5a
|
804 805 |
#define STA_STATS_FIELD_HE_MCS GENMASK( 3, 0) #define STA_STATS_FIELD_HE_NSS GENMASK( 7, 4) |
dcba665b1
|
806 807 808 |
#define STA_STATS_FIELD_BW GENMASK(11, 8) #define STA_STATS_FIELD_SGI GENMASK(12, 12) #define STA_STATS_FIELD_TYPE GENMASK(15, 13) |
41cbb0f5a
|
809 810 811 |
#define STA_STATS_FIELD_HE_RU GENMASK(18, 16) #define STA_STATS_FIELD_HE_GI GENMASK(20, 19) #define STA_STATS_FIELD_HE_DCM GENMASK(21, 21) |
dcba665b1
|
812 813 814 |
#define STA_STATS_FIELD(_n, _v) FIELD_PREP(STA_STATS_FIELD_ ## _n, _v) #define STA_STATS_GET(_n, _v) FIELD_GET(STA_STATS_FIELD_ ## _n, _v) |
4f6b1b3da
|
815 |
#define STA_STATS_RATE_INVALID 0 |
dcba665b1
|
816 817 |
static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s) |
4f6b1b3da
|
818 |
{ |
41cbb0f5a
|
819 |
u32 r; |
4f6b1b3da
|
820 |
|
dcba665b1
|
821 |
r = STA_STATS_FIELD(BW, s->bw); |
4f6b1b3da
|
822 |
|
7fdd69c5a
|
823 |
if (s->enc_flags & RX_ENC_FLAG_SHORT_GI) |
dcba665b1
|
824 |
r |= STA_STATS_FIELD(SGI, 1); |
4f6b1b3da
|
825 |
|
da6a4352e
|
826 827 |
switch (s->encoding) { case RX_ENC_VHT: |
dcba665b1
|
828 829 830 |
r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_VHT); r |= STA_STATS_FIELD(VHT_NSS, s->nss); r |= STA_STATS_FIELD(VHT_MCS, s->rate_idx); |
da6a4352e
|
831 832 |
break; case RX_ENC_HT: |
dcba665b1
|
833 834 |
r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_HT); r |= STA_STATS_FIELD(HT_MCS, s->rate_idx); |
da6a4352e
|
835 |
break; |
da6a4352e
|
836 |
case RX_ENC_LEGACY: |
dcba665b1
|
837 838 839 |
r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_LEGACY); r |= STA_STATS_FIELD(LEGACY_BAND, s->band); r |= STA_STATS_FIELD(LEGACY_IDX, s->rate_idx); |
da6a4352e
|
840 |
break; |
41cbb0f5a
|
841 842 843 844 845 846 847 848 |
case RX_ENC_HE: r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_HE); r |= STA_STATS_FIELD(HE_NSS, s->nss); r |= STA_STATS_FIELD(HE_MCS, s->rate_idx); r |= STA_STATS_FIELD(HE_GI, s->he_gi); r |= STA_STATS_FIELD(HE_RU, s->he_ru); r |= STA_STATS_FIELD(HE_DCM, s->he_dcm); break; |
dcba665b1
|
849 850 851 |
default: WARN_ON(1); return STA_STATS_RATE_INVALID; |
da6a4352e
|
852 |
} |
4f6b1b3da
|
853 854 855 |
return r; } |
f0706e828
|
856 |
#endif /* STA_INFO_H */ |