diff options
Diffstat (limited to 'drivers/net/wireless/ath9k/rc.h')
-rw-r--r-- | drivers/net/wireless/ath9k/rc.h | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h new file mode 100644 index 000000000000..71aef9c75232 --- /dev/null +++ b/drivers/net/wireless/ath9k/rc.h | |||
@@ -0,0 +1,316 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004 Sam Leffler, Errno Consulting | ||
3 | * Copyright (c) 2004 Video54 Technologies, Inc. | ||
4 | * Copyright (c) 2008 Atheros Communications Inc. | ||
5 | * | ||
6 | * Permission to use, copy, modify, and/or distribute this software for any | ||
7 | * purpose with or without fee is hereby granted, provided that the above | ||
8 | * copyright notice and this permission notice appear in all copies. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #ifndef RC_H | ||
20 | #define RC_H | ||
21 | |||
22 | #include "ath9k.h" | ||
23 | /* | ||
24 | * Interface definitions for transmit rate control modules for the | ||
25 | * Atheros driver. | ||
26 | * | ||
27 | * A rate control module is responsible for choosing the transmit rate | ||
28 | * for each data frame. Management+control frames are always sent at | ||
29 | * a fixed rate. | ||
30 | * | ||
31 | * Only one module may be present at a time; the driver references | ||
32 | * rate control interfaces by symbol name. If multiple modules are | ||
33 | * to be supported we'll need to switch to a registration-based scheme | ||
34 | * as is currently done, for example, for authentication modules. | ||
35 | * | ||
36 | * An instance of the rate control module is attached to each device | ||
37 | * at attach time and detached when the device is destroyed. The module | ||
38 | * may associate data with each device and each node (station). Both | ||
39 | * sets of storage are opaque except for the size of the per-node storage | ||
40 | * which must be provided when the module is attached. | ||
41 | * | ||
42 | * The rate control module is notified for each state transition and | ||
43 | * station association/reassociation. Otherwise it is queried for a | ||
44 | * rate for each outgoing frame and provided status from each transmitted | ||
45 | * frame. Any ancillary processing is the responsibility of the module | ||
46 | * (e.g. if periodic processing is required then the module should setup | ||
47 | * it's own timer). | ||
48 | * | ||
49 | * In addition to the transmit rate for each frame the module must also | ||
50 | * indicate the number of attempts to make at the specified rate. If this | ||
51 | * number is != ATH_TXMAXTRY then an additional callback is made to setup | ||
52 | * additional transmit state. The rate control code is assumed to write | ||
53 | * this additional data directly to the transmit descriptor. | ||
54 | */ | ||
55 | |||
56 | struct ath_softc; | ||
57 | |||
58 | #define TRUE 1 | ||
59 | #define FALSE 0 | ||
60 | |||
61 | #define ATH_RATE_MAX 30 | ||
62 | #define MCS_SET_SIZE 128 | ||
63 | |||
64 | enum ieee80211_fixed_rate_mode { | ||
65 | IEEE80211_FIXED_RATE_NONE = 0, | ||
66 | IEEE80211_FIXED_RATE_MCS = 1 /* HT rates */ | ||
67 | }; | ||
68 | |||
69 | /* | ||
70 | * Use the hal os glue code to get ms time | ||
71 | */ | ||
72 | #define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8))) | ||
73 | |||
74 | #define SHORT_PRE 1 | ||
75 | #define LONG_PRE 0 | ||
76 | |||
77 | #define WLAN_PHY_HT_20_SS WLAN_RC_PHY_HT_20_SS | ||
78 | #define WLAN_PHY_HT_20_DS WLAN_RC_PHY_HT_20_DS | ||
79 | #define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI | ||
80 | #define WLAN_PHY_HT_40_SS WLAN_RC_PHY_HT_40_SS | ||
81 | #define WLAN_PHY_HT_40_SS_HGI WLAN_RC_PHY_HT_40_SS_HGI | ||
82 | #define WLAN_PHY_HT_40_DS WLAN_RC_PHY_HT_40_DS | ||
83 | #define WLAN_PHY_HT_40_DS_HGI WLAN_RC_PHY_HT_40_DS_HGI | ||
84 | |||
85 | #define WLAN_PHY_OFDM PHY_OFDM | ||
86 | #define WLAN_PHY_CCK PHY_CCK | ||
87 | |||
88 | #define TRUE_20 0x2 | ||
89 | #define TRUE_40 0x4 | ||
90 | #define TRUE_2040 (TRUE_20|TRUE_40) | ||
91 | #define TRUE_ALL (TRUE_2040|TRUE) | ||
92 | |||
93 | enum { | ||
94 | WLAN_RC_PHY_HT_20_SS = 4, | ||
95 | WLAN_RC_PHY_HT_20_DS, | ||
96 | WLAN_RC_PHY_HT_40_SS, | ||
97 | WLAN_RC_PHY_HT_40_DS, | ||
98 | WLAN_RC_PHY_HT_20_SS_HGI, | ||
99 | WLAN_RC_PHY_HT_20_DS_HGI, | ||
100 | WLAN_RC_PHY_HT_40_SS_HGI, | ||
101 | WLAN_RC_PHY_HT_40_DS_HGI, | ||
102 | WLAN_RC_PHY_MAX | ||
103 | }; | ||
104 | |||
105 | #define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \ | ||
106 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ | ||
107 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ | ||
108 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||
109 | #define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ | ||
110 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ | ||
111 | || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ | ||
112 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||
113 | #define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ | ||
114 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ | ||
115 | || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ | ||
116 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||
117 | |||
118 | #define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS) | ||
119 | |||
120 | /* Returns the capflag mode */ | ||
121 | #define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \ | ||
122 | (capflag & WLAN_RC_40_FLAG) ? TRUE_40 : TRUE_20 : TRUE)) | ||
123 | |||
124 | /* Return TRUE if flag supports HT20 && client supports HT20 or | ||
125 | * return TRUE if flag supports HT40 && client supports HT40. | ||
126 | * This is used becos some rates overlap between HT20/HT40. | ||
127 | */ | ||
128 | |||
129 | #define WLAN_RC_PHY_HT_VALID(flag, capflag) (((flag & TRUE_20) && !(capflag \ | ||
130 | & WLAN_RC_40_FLAG)) || ((flag & TRUE_40) && \ | ||
131 | (capflag & WLAN_RC_40_FLAG))) | ||
132 | |||
133 | #define WLAN_RC_DS_FLAG (0x01) | ||
134 | #define WLAN_RC_40_FLAG (0x02) | ||
135 | #define WLAN_RC_SGI_FLAG (0x04) | ||
136 | #define WLAN_RC_HT_FLAG (0x08) | ||
137 | |||
138 | /* Index into the rate table */ | ||
139 | #define INIT_RATE_MAX_20 23 | ||
140 | #define INIT_RATE_MAX_40 40 | ||
141 | |||
142 | #define RATE_TABLE_SIZE 64 | ||
143 | |||
144 | /* XXX: Convert to kdoc */ | ||
145 | struct ath_rate_table { | ||
146 | int rate_cnt; | ||
147 | struct { | ||
148 | int valid; /* Valid for use in rate control */ | ||
149 | int valid_single_stream;/* Valid for use in rate control | ||
150 | for single stream operation */ | ||
151 | u8 phy; /* CCK/OFDM/TURBO/XR */ | ||
152 | u32 ratekbps; /* Rate in Kbits per second */ | ||
153 | u32 user_ratekbps; /* User rate in KBits per second */ | ||
154 | u8 ratecode; /* rate that goes into | ||
155 | hw descriptors */ | ||
156 | u8 short_preamble; /* Mask for enabling short preamble | ||
157 | in rate code for CCK */ | ||
158 | u8 dot11rate; /* Value that goes into supported | ||
159 | rates info element of MLME */ | ||
160 | u8 ctrl_rate; /* Index of next lower basic rate, | ||
161 | used for duration computation */ | ||
162 | int8_t rssi_ack_validmin; /* Rate control related */ | ||
163 | int8_t rssi_ack_deltamin; /* Rate control related */ | ||
164 | u8 base_index; /* base rate index */ | ||
165 | u8 cw40index; /* 40cap rate index */ | ||
166 | u8 sgi_index; /* shortgi rate index */ | ||
167 | u8 ht_index; /* shortgi rate index */ | ||
168 | u32 max_4ms_framelen; /* Maximum frame length(bytes) | ||
169 | for 4ms tx duration */ | ||
170 | } info[RATE_TABLE_SIZE]; | ||
171 | u32 probe_interval; /* interval for ratectrl to | ||
172 | probe for other rates */ | ||
173 | u32 rssi_reduce_interval; /* interval for ratectrl | ||
174 | to reduce RSSI */ | ||
175 | u8 initial_ratemax; /* the initial ratemax value used | ||
176 | in ath_rc_sib_update() */ | ||
177 | }; | ||
178 | |||
179 | #define ATH_RC_PROBE_ALLOWED 0x00000001 | ||
180 | #define ATH_RC_MINRATE_LASTRATE 0x00000002 | ||
181 | #define ATH_RC_SHORT_PREAMBLE 0x00000004 | ||
182 | |||
183 | struct ath_rc_series { | ||
184 | u8 rix; | ||
185 | u8 tries; | ||
186 | u8 flags; | ||
187 | u32 max_4ms_framelen; | ||
188 | }; | ||
189 | |||
190 | /* rcs_flags definition */ | ||
191 | #define ATH_RC_DS_FLAG 0x01 | ||
192 | #define ATH_RC_CW40_FLAG 0x02 /* CW 40 */ | ||
193 | #define ATH_RC_SGI_FLAG 0x04 /* Short Guard Interval */ | ||
194 | #define ATH_RC_HT_FLAG 0x08 /* HT */ | ||
195 | #define ATH_RC_RTSCTS_FLAG 0x10 /* RTS-CTS */ | ||
196 | |||
197 | /* | ||
198 | * State structures for new rate adaptation code | ||
199 | */ | ||
200 | #define MAX_TX_RATE_TBL 64 | ||
201 | #define MAX_TX_RATE_PHY 48 | ||
202 | |||
203 | struct ath_tx_ratectrl_state { | ||
204 | int8_t rssi_thres; /* required rssi for this rate (dB) */ | ||
205 | u8 per; /* recent estimate of packet error rate (%) */ | ||
206 | }; | ||
207 | |||
208 | struct ath_tx_ratectrl { | ||
209 | struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL]; /* state */ | ||
210 | int8_t rssi_last; /* last ack rssi */ | ||
211 | int8_t rssi_last_lookup; /* last ack rssi used for lookup */ | ||
212 | int8_t rssi_last_prev; /* previous last ack rssi */ | ||
213 | int8_t rssi_last_prev2; /* 2nd previous last ack rssi */ | ||
214 | int32_t rssi_sum_cnt; /* count of rssi_sum for averaging */ | ||
215 | int32_t rssi_sum_rate; /* rate that we are averaging */ | ||
216 | int32_t rssi_sum; /* running sum of rssi for averaging */ | ||
217 | u32 valid_txrate_mask; /* mask of valid rates */ | ||
218 | u8 rate_table_size; /* rate table size */ | ||
219 | u8 rate_max; /* max rate that has recently worked */ | ||
220 | u8 probe_rate; /* rate we are probing at */ | ||
221 | u32 rssi_time; /* msec timestamp for last ack rssi */ | ||
222 | u32 rssi_down_time; /* msec timestamp for last down step */ | ||
223 | u32 probe_time; /* msec timestamp for last probe */ | ||
224 | u8 hw_maxretry_pktcnt; /* num packets since we got | ||
225 | HW max retry error */ | ||
226 | u8 max_valid_rate; /* maximum number of valid rate */ | ||
227 | u8 valid_rate_index[MAX_TX_RATE_TBL]; /* valid rate index */ | ||
228 | u32 per_down_time; /* msec timstamp for last | ||
229 | PER down step */ | ||
230 | |||
231 | /* 11n state */ | ||
232 | u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; /* valid rate count */ | ||
233 | u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL]; | ||
234 | u8 rc_phy_mode; | ||
235 | u8 rate_max_phy; /* Phy index for the max rate */ | ||
236 | u32 rate_max_lastused; /* msec timstamp of when we | ||
237 | last used rateMaxPhy */ | ||
238 | u32 probe_interval; /* interval for ratectrl to probe | ||
239 | for other rates */ | ||
240 | }; | ||
241 | |||
242 | struct ath_rateset { | ||
243 | u8 rs_nrates; | ||
244 | u8 rs_rates[ATH_RATE_MAX]; | ||
245 | }; | ||
246 | |||
247 | /* per-device state */ | ||
248 | struct ath_rate_softc { | ||
249 | /* phy tables that contain rate control data */ | ||
250 | const void *hw_rate_table[ATH9K_MODE_MAX]; | ||
251 | int fixedrix; /* -1 or index of fixed rate */ | ||
252 | }; | ||
253 | |||
254 | /* per-node state */ | ||
255 | struct ath_rate_node { | ||
256 | struct ath_tx_ratectrl tx_ratectrl; /* rate control state proper */ | ||
257 | u32 prev_data_rix; /* rate idx of last data frame */ | ||
258 | |||
259 | /* map of rate ix -> negotiated rate set ix */ | ||
260 | u8 rixmap[MAX_TX_RATE_TBL]; | ||
261 | |||
262 | /* map of ht rate ix -> negotiated rate set ix */ | ||
263 | u8 ht_rixmap[MAX_TX_RATE_TBL]; | ||
264 | |||
265 | u8 ht_cap; /* ht capabilities */ | ||
266 | u8 ant_tx; /* current transmit antenna */ | ||
267 | |||
268 | u8 single_stream; /* When TRUE, only single | ||
269 | stream Tx possible */ | ||
270 | struct ath_rateset neg_rates; /* Negotiated rates */ | ||
271 | struct ath_rateset neg_ht_rates; /* Negotiated HT rates */ | ||
272 | struct ath_rate_softc *asc; /* back pointer to atheros softc */ | ||
273 | struct ath_vap *avp; /* back pointer to vap */ | ||
274 | }; | ||
275 | |||
276 | /* Driver data of ieee80211_tx_info */ | ||
277 | struct ath_tx_info_priv { | ||
278 | struct ath_rc_series rcs[4]; | ||
279 | struct ath_tx_status tx; | ||
280 | int n_frames; | ||
281 | int n_bad_frames; | ||
282 | u8 min_rate; | ||
283 | }; | ||
284 | |||
285 | /* | ||
286 | * Attach/detach a rate control module. | ||
287 | */ | ||
288 | struct ath_rate_softc *ath_rate_attach(struct ath_hal *ah); | ||
289 | void ath_rate_detach(struct ath_rate_softc *asc); | ||
290 | |||
291 | /* | ||
292 | * Update/reset rate control state for 802.11 state transitions. | ||
293 | * Important mostly as the analog to ath_rate_newassoc when operating | ||
294 | * in station mode. | ||
295 | */ | ||
296 | void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv); | ||
297 | void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp); | ||
298 | |||
299 | /* | ||
300 | * Return the tx rate series. | ||
301 | */ | ||
302 | void ath_rate_findrate(struct ath_softc *sc, struct ath_rate_node *ath_rc_priv, | ||
303 | int num_tries, int num_rates, | ||
304 | unsigned int rcflag, struct ath_rc_series[], | ||
305 | int *is_probe, int isretry); | ||
306 | /* | ||
307 | * Return rate index for given Dot11 Rate. | ||
308 | */ | ||
309 | u8 ath_rate_findrateix(struct ath_softc *sc, | ||
310 | u8 dot11_rate); | ||
311 | |||
312 | /* Routines to register/unregister rate control algorithm */ | ||
313 | int ath_rate_control_register(void); | ||
314 | void ath_rate_control_unregister(void); | ||
315 | |||
316 | #endif /* RC_H */ | ||