1 | /* $NetBSD: athrate-sample.h,v 1.4 2012/11/08 20:43:55 dyoung Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 2005 John Bicket |
5 | * All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer, |
12 | * without modification. |
13 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
14 | * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any |
15 | * redistribution must be conditioned upon including a substantially |
16 | * similar Disclaimer requirement for further binary redistribution. |
17 | * 3. Neither the names of the above-listed copyright holders nor the names |
18 | * of any contributors may be used to endorse or promote products derived |
19 | * from this software without specific prior written permission. |
20 | * |
21 | * Alternatively, this software may be distributed under the terms of the |
22 | * GNU General Public License ("GPL") version 2 as published by the Free |
23 | * Software Foundation. |
24 | * |
25 | * NO WARRANTY |
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
27 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
28 | * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY |
29 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL |
30 | * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, |
31 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
32 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
33 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
34 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
35 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
36 | * THE POSSIBILITY OF SUCH DAMAGES. |
37 | * |
38 | * $FreeBSD: src/sys/dev/ath/ath_rate/sample/sample.h,v 1.3 2005/03/20 01:27:33 sam Exp $ |
39 | */ |
40 | |
41 | /* |
42 | * Defintions for the Atheros Wireless LAN controller driver. |
43 | */ |
44 | #ifndef _DEV_ATH_RATE_SAMPLE_H |
45 | #define _DEV_ATH_RATE_SAMPLE_H |
46 | |
47 | /* per-device state */ |
48 | struct sample_softc { |
49 | struct ath_ratectrl arc; /* base state */ |
50 | int ath_smoothing_rate; /* ewma percentage (out of 100) */ |
51 | int ath_sample_rate; /* send a different bit-rate 1/X packets */ |
52 | }; |
53 | #define ATH_SOFTC_SAMPLE(sc) ((struct sample_softc *)sc->sc_rc) |
54 | |
55 | struct rate_info { |
56 | int rate; |
57 | int rix; |
58 | int rateCode; |
59 | int shortPreambleRateCode; |
60 | }; |
61 | |
62 | |
63 | struct rate_stats { |
64 | unsigned average_tx_time; |
65 | int successive_failures; |
66 | int tries; |
67 | int total_packets; |
68 | int packets_acked; |
69 | unsigned perfect_tx_time; /* transmit time for 0 retries */ |
70 | int last_tx; |
71 | }; |
72 | |
73 | /* |
74 | * for now, we track performance for three different packet |
75 | * size buckets |
76 | */ |
77 | #define NUM_PACKET_SIZE_BINS 3 |
78 | static int packet_size_bins[NUM_PACKET_SIZE_BINS] = {250, 1600, 3000}; |
79 | |
80 | /* per-node state */ |
81 | struct sample_node { |
82 | int static_rate_ndx; |
83 | int num_rates; |
84 | |
85 | struct rate_info rates[IEEE80211_RATE_MAXSIZE]; |
86 | |
87 | struct rate_stats stats[NUM_PACKET_SIZE_BINS][IEEE80211_RATE_MAXSIZE]; |
88 | int last_sample_ndx[NUM_PACKET_SIZE_BINS]; |
89 | |
90 | int current_sample_ndx[NUM_PACKET_SIZE_BINS]; |
91 | int packets_sent[NUM_PACKET_SIZE_BINS]; |
92 | |
93 | int current_rate[NUM_PACKET_SIZE_BINS]; |
94 | int packets_since_switch[NUM_PACKET_SIZE_BINS]; |
95 | unsigned ticks_since_switch[NUM_PACKET_SIZE_BINS]; |
96 | |
97 | int packets_since_sample[NUM_PACKET_SIZE_BINS]; |
98 | unsigned sample_tt[NUM_PACKET_SIZE_BINS]; |
99 | }; |
100 | #define ATH_NODE_SAMPLE(an) ((struct sample_node *)&an[1]) |
101 | |
102 | #ifndef MIN |
103 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) |
104 | #endif |
105 | #ifndef MAX |
106 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) |
107 | #endif |
108 | |
109 | #define WIFI_CW_MIN 31 |
110 | #define WIFI_CW_MAX 1023 |
111 | |
112 | struct ar5212_desc { |
113 | /* |
114 | * tx_control_0 |
115 | */ |
116 | u_int32_t frame_len:12; |
117 | u_int32_t reserved_12_15:4; |
118 | u_int32_t xmit_power:6; |
119 | u_int32_t rts_cts_enable:1; |
120 | u_int32_t veol:1; |
121 | u_int32_t clear_dest_mask:1; |
122 | u_int32_t ant_mode_xmit:4; |
123 | u_int32_t inter_req:1; |
124 | u_int32_t encrypt_key_valid:1; |
125 | u_int32_t cts_enable:1; |
126 | |
127 | /* |
128 | * tx_control_1 |
129 | */ |
130 | u_int32_t buf_len:12; |
131 | u_int32_t more:1; |
132 | u_int32_t encrypt_key_index:7; |
133 | u_int32_t frame_type:4; |
134 | u_int32_t no_ack:1; |
135 | u_int32_t comp_proc:2; |
136 | u_int32_t comp_iv_len:2; |
137 | u_int32_t comp_icv_len:2; |
138 | u_int32_t reserved_31:1; |
139 | |
140 | /* |
141 | * tx_control_2 |
142 | */ |
143 | u_int32_t rts_duration:15; |
144 | u_int32_t duration_update_enable:1; |
145 | u_int32_t xmit_tries0:4; |
146 | u_int32_t xmit_tries1:4; |
147 | u_int32_t xmit_tries2:4; |
148 | u_int32_t xmit_tries3:4; |
149 | |
150 | /* |
151 | * tx_control_3 |
152 | */ |
153 | u_int32_t xmit_rate0:5; |
154 | u_int32_t xmit_rate1:5; |
155 | u_int32_t xmit_rate2:5; |
156 | u_int32_t xmit_rate3:5; |
157 | u_int32_t rts_cts_rate:5; |
158 | u_int32_t reserved_25_31:7; |
159 | |
160 | /* |
161 | * tx_status_0 |
162 | */ |
163 | u_int32_t frame_xmit_ok:1; |
164 | u_int32_t excessive_retries:1; |
165 | u_int32_t fifo_underrun:1; |
166 | u_int32_t filtered:1; |
167 | u_int32_t rts_fail_count:4; |
168 | u_int32_t data_fail_count:4; |
169 | u_int32_t virt_coll_count:4; |
170 | u_int32_t send_timestamp:16; |
171 | |
172 | /* |
173 | * tx_status_1 |
174 | */ |
175 | u_int32_t done:1; |
176 | u_int32_t seq_num:12; |
177 | u_int32_t ack_sig_strength:8; |
178 | u_int32_t final_ts_index:2; |
179 | u_int32_t comp_success:1; |
180 | u_int32_t xmit_antenna:1; |
181 | u_int32_t reserved_25_31_x:7; |
182 | } __packed; |
183 | |
184 | /* |
185 | * Calculate the transmit duration of a frame. |
186 | */ |
187 | static unsigned calc_usecs_unicast_packet(struct ath_softc *sc, |
188 | int length, |
189 | int rix, int short_retries, int long_retries) { |
190 | const HAL_RATE_TABLE *rt = sc->sc_currates; |
191 | int rts, cts; |
192 | |
193 | unsigned t_slot = 20; |
194 | unsigned t_difs = 50; |
195 | unsigned t_sifs = 10; |
196 | struct ieee80211com *ic = &sc->sc_ic; |
197 | int tt = 0; |
198 | int x = 0; |
199 | int cw = WIFI_CW_MIN; |
200 | int cix = rt->info[rix].controlRate; |
201 | |
202 | KASSERTMSG(rt != NULL, "no rate table, mode %u" , sc->sc_curmode); |
203 | |
204 | if (!rt->info[rix].rateKbps) { |
205 | printf("rix %d (%d) bad ratekbps %d mode %u" , |
206 | rix, rt->info[rix].dot11Rate, |
207 | rt->info[rix].rateKbps, |
208 | sc->sc_curmode); |
209 | |
210 | return 0; |
211 | } |
212 | /* |
213 | * XXX getting mac/phy level timings should be fixed for turbo |
214 | * rates, and there is probably a way to get this from the |
215 | * hal... |
216 | */ |
217 | switch (rt->info[rix].phy) { |
218 | case IEEE80211_T_OFDM: |
219 | t_slot = 9; |
220 | t_sifs = 16; |
221 | t_difs = 28; |
222 | /* fall through */ |
223 | case IEEE80211_T_TURBO: |
224 | t_slot = 9; |
225 | t_sifs = 8; |
226 | t_difs = 28; |
227 | break; |
228 | case IEEE80211_T_DS: |
229 | /* fall through to default */ |
230 | default: |
231 | /* pg 205 ieee.802.11.pdf */ |
232 | t_slot = 20; |
233 | t_difs = 50; |
234 | t_sifs = 10; |
235 | } |
236 | |
237 | rts = cts = 0; |
238 | |
239 | if ((ic->ic_flags & IEEE80211_F_USEPROT) && |
240 | rt->info[rix].phy == IEEE80211_T_OFDM) { |
241 | if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) |
242 | rts = 1; |
243 | else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) |
244 | cts = 1; |
245 | |
246 | cix = rt->info[sc->sc_protrix].controlRate; |
247 | |
248 | } |
249 | |
250 | if (0 /*length > ic->ic_rtsthreshold */) { |
251 | rts = 1; |
252 | } |
253 | |
254 | if (rts || cts) { |
255 | int ctsrate = rt->info[cix].rateCode; |
256 | int ctsduration = 0; |
257 | |
258 | if (!rt->info[cix].rateKbps) { |
259 | printf("cix %d (%d) bad ratekbps %d mode %u" , |
260 | cix, rt->info[cix].dot11Rate, |
261 | rt->info[cix].rateKbps, |
262 | sc->sc_curmode); |
263 | return 0; |
264 | } |
265 | |
266 | ctsrate |= rt->info[cix].shortPreamble; |
267 | if (rts) /* SIFS + CTS */ |
268 | ctsduration += rt->info[cix].spAckDuration; |
269 | |
270 | ctsduration += ath_hal_computetxtime(sc->sc_ah, |
271 | rt, length, rix, AH_TRUE); |
272 | |
273 | if (cts) /* SIFS + ACK */ |
274 | ctsduration += rt->info[cix].spAckDuration; |
275 | |
276 | tt += (short_retries + 1) * ctsduration; |
277 | } |
278 | tt += t_difs; |
279 | tt += (long_retries+1)*(t_sifs + rt->info[rix].spAckDuration); |
280 | tt += (long_retries+1)*ath_hal_computetxtime(sc->sc_ah, rt, length, |
281 | rix, AH_TRUE); |
282 | for (x = 0; x <= short_retries + long_retries; x++) { |
283 | cw = MIN(WIFI_CW_MAX, (cw + 1) * 2); |
284 | tt += (t_slot * cw/2); |
285 | } |
286 | return tt; |
287 | } |
288 | #endif /* _DEV_ATH_RATE_SAMPLE_H */ |
289 | |