xref: /titanic_50/usr/src/uts/common/io/arn/arn_rc.c (revision 174bc6499d233e329ecd3d98a880a7b07df16bfa)
1 /*
2  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2004 Video54 Technologies, Inc.
8  * Copyright (c) 2004-2008 Atheros Communications, Inc.
9  *
10  * Permission to use, copy, modify, and/or distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 #include <sys/time.h>
23 #include <sys/types.h>
24 #include <sys/ddi.h>
25 #include <sys/net80211_ht.h>
26 
27 #include "arn_core.h"
28 #include "arn_hw.h"
29 #include "arn_reg.h"
30 
31 static struct ath_rate_table ar5416_11na_ratetable = {
32 	42,
33 	{0},
34 	{
35 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
36 			5400, 0x0b, 0x00, 12,
37 			0, 2, 1, 0, 0, 0, 0, 0 },
38 		{ VALID,	VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
39 			7800,  0x0f, 0x00, 18,
40 			0, 3, 1, 1, 1, 1, 1, 0 },
41 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
42 			10000, 0x0a, 0x00, 24,
43 			2, 4, 2, 2, 2, 2, 2, 0 },
44 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
45 			13900, 0x0e, 0x00, 36,
46 			2, 6,  2, 3, 3, 3, 3, 0 },
47 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
48 			17300, 0x09, 0x00, 48,
49 			4, 10, 3, 4, 4, 4, 4, 0 },
50 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
51 			23000, 0x0d, 0x00, 72,
52 			4, 14, 3, 5, 5, 5, 5, 0 },
53 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
54 			27400, 0x08, 0x00, 96,
55 			4, 20, 3, 6, 6, 6, 6, 0 },
56 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
57 			29300, 0x0c, 0x00, 108,
58 			4, 23, 3, 7, 7, 7, 7, 0 },
59 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
60 			6400, 0x80, 0x00, 0,
61 			0, 2, 3, 8, 24, 8, 24, 3216 },
62 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
63 			12700, 0x81, 0x00, 1,
64 			2, 4, 3, 9, 25, 9, 25, 6434 },
65 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
66 			18800, 0x82, 0x00, 2,
67 			2, 6, 3, 10, 26, 10, 26, 9650 },
68 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
69 			25000, 0x83, 0x00, 3,
70 			4, 10, 3, 11, 27, 11, 27, 12868 },
71 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
72 			36700, 0x84, 0x00, 4,
73 			4, 14, 3, 12, 28, 12, 28, 19304 },
74 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
75 			48100, 0x85, 0x00, 5,
76 			4, 20, 3, 13, 29, 13, 29, 25740 },
77 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
78 			53500, 0x86, 0x00, 6,
79 			4, 23, 3, 14, 30, 14, 30,  28956 },
80 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
81 			59000, 0x87, 0x00, 7,
82 			4, 25, 3, 15, 31, 15, 32, 32180 },
83 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
84 			12700, 0x88, 0x00,
85 			8, 0, 2, 3, 16, 33, 16, 33, 6430 },
86 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
87 			24800, 0x89, 0x00, 9,
88 			2, 4, 3, 17, 34, 17, 34, 12860 },
89 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
90 			36600, 0x8a, 0x00, 10,
91 			2, 6, 3, 18, 35, 18, 35, 19300 },
92 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
93 			48100, 0x8b, 0x00, 11,
94 			4, 10, 3, 19, 36, 19, 36, 25736 },
95 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
96 			69500, 0x8c, 0x00, 12,
97 			4, 14, 3, 20, 37, 20, 37, 38600 },
98 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
99 			89500, 0x8d, 0x00, 13,
100 			4, 20, 3, 21, 38, 21, 38, 51472 },
101 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
102 			98900, 0x8e, 0x00, 14,
103 			4, 23, 3, 22, 39, 22, 39, 57890 },
104 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
105 			108300, 0x8f, 0x00, 15,
106 			4, 25, 3, 23, 40, 23, 41, 64320 },
107 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
108 			13200, 0x80, 0x00, 0,
109 			0, 2, 3, 8, 24, 24, 24, 6684 },
110 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
111 			25900, 0x81, 0x00, 1,
112 			2, 4, 3, 9, 25, 25, 25, 13368 },
113 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
114 			38600, 0x82, 0x00, 2,
115 			2, 6, 3, 10, 26, 26, 26, 20052 },
116 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
117 			49800, 0x83, 0x00, 3,
118 			4, 10, 3, 11, 27, 27, 27, 26738 },
119 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
120 			72200, 0x84, 0x00, 4,
121 			4, 14, 3, 12, 28, 28, 28, 40104 },
122 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
123 			92900, 0x85, 0x00, 5,
124 			4, 20, 3, 13, 29, 29, 29, 53476 },
125 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5Mb */
126 			102700, 0x86, 0x00, 6,
127 			4, 23, 3, 14, 30, 30, 30, 60156 },
128 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
129 			112000, 0x87, 0x00, 7,
130 			4, 25, 3, 15, 31, 32, 32, 66840 },
131 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI,
132 			150000, /* 150Mb */
133 			122000, 0x87, 0x00, 7,
134 			4, 25, 3, 15, 31, 32, 32, 74200 },
135 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
136 			25800, 0x88, 0x00, 8,
137 			0, 2, 3, 16, 33, 33, 33, 13360 },
138 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
139 			49800, 0x89, 0x00, 9,
140 			2, 4, 3, 17, 34, 34, 34, 26720 },
141 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
142 			71900, 0x8a, 0x00, 10,
143 			2, 6, 3, 18, 35, 35, 35, 40080 },
144 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
145 			92500, 0x8b, 0x00, 11,
146 			4, 10, 3, 19, 36, 36, 36, 53440 },
147 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
148 			130300, 0x8c, 0x00, 12,
149 			4, 14, 3, 20, 37, 37, 37, 80160 },
150 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
151 			162800, 0x8d, 0x00, 13,
152 			4, 20, 3, 21, 38, 38, 38, 106880 },
153 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
154 			178200, 0x8e, 0x00, 14,
155 			4, 23, 3, 22, 39, 39, 39, 120240 },
156 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
157 			192100, 0x8f, 0x00, 15,
158 			4, 25, 3, 23, 40, 41, 41, 133600 },
159 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI,
160 			300000, /* 300 Mb */
161 			207000, 0x8f, 0x00, 15,
162 			4, 25, 3, 23, 40, 41, 41, 148400 },
163 	},
164 	50,  /* probe interval */
165 	50,  /* rssi reduce interval */
166 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
167 };
168 
169 /*
170  * 4ms frame limit not used for NG mode.  The values filled
171  * for HT are the 64K max aggregate limit
172  */
173 
174 static struct ath_rate_table ar5416_11ng_ratetable = {
175 	46,
176 	{0},
177 	{
178 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
179 			900, 0x1b, 0x00, 2,
180 			0, 0, 1, 0, 0, 0, 0, 0 },
181 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
182 			1900, 0x1a, 0x04, 4,
183 			1, 1, 1, 1, 1, 1, 1, 0 },
184 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
185 			4900, 0x19, 0x04, 11,
186 			2, 2, 2, 2, 2, 2, 2, 0 },
187 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
188 			8100, 0x18, 0x04, 22,
189 			3, 3, 2, 3, 3, 3, 3, 0 },
190 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
191 			5400, 0x0b, 0x00, 12,
192 			4, 2, 1, 4, 4, 4, 4, 0 },
193 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
194 			7800, 0x0f, 0x00, 18,
195 			4, 3, 1, 5, 5, 5, 5, 0 },
196 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
197 			10100, 0x0a, 0x00, 24,
198 			6, 4, 1, 6, 6, 6, 6, 0 },
199 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
200 			14100,  0x0e, 0x00, 36,
201 			6, 6, 2, 7, 7, 7, 7, 0 },
202 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
203 			17700, 0x09, 0x00, 48,
204 			8, 10, 3, 8, 8, 8, 8, 0 },
205 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
206 			23700, 0x0d, 0x00, 72,
207 			8, 14, 3, 9, 9, 9, 9, 0 },
208 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
209 			27400, 0x08, 0x00, 96,
210 			8, 20, 3, 10, 10, 10, 10, 0 },
211 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
212 			30900, 0x0c, 0x00, 108,
213 			8, 23, 3, 11, 11, 11, 11, 0 },
214 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
215 			6400, 0x80, 0x00, 0,
216 			4, 2, 3, 12, 28, 12, 28, 3216 },
217 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
218 			12700, 0x81, 0x00, 1,
219 			6, 4, 3, 13, 29, 13, 29, 6434 },
220 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
221 			18800, 0x82, 0x00, 2,
222 			6, 6, 3, 14, 30, 14, 30, 9650 },
223 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
224 			25000, 0x83, 0x00, 3,
225 			8, 10, 3, 15, 31, 15, 31, 12868 },
226 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
227 			36700, 0x84, 0x00, 4,
228 			8, 14, 3, 16, 32, 16, 32, 19304 },
229 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
230 			48100, 0x85, 0x00, 5,
231 			8, 20, 3, 17, 33, 17, 33, 25740 },
232 		{ INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
233 			53500, 0x86, 0x00, 6,
234 			8, 23, 3, 18, 34, 18, 34, 28956 },
235 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
236 			59000, 0x87, 0x00, 7,
237 			8, 25, 3, 19, 35, 19, 36, 32180 },
238 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
239 			12700, 0x88, 0x00, 8,
240 			4, 2, 3, 20, 37, 20, 37, 6430 },
241 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
242 			24800, 0x89, 0x00, 9,
243 			6, 4, 3, 21, 38, 21, 38, 12860 },
244 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
245 			36600, 0x8a, 0x00, 10,
246 			6, 6, 3, 22, 39, 22, 39, 19300 },
247 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
248 			48100, 0x8b, 0x00, 11,
249 			8, 10, 3, 23, 40, 23, 40, 25736 },
250 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
251 			69500, 0x8c, 0x00, 12,
252 			8, 14, 3, 24, 41, 24, 41, 38600 },
253 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
254 			89500, 0x8d, 0x00, 13,
255 			8, 20, 3, 25, 42, 25, 42, 51472 },
256 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
257 			98900, 0x8e, 0x00, 14,
258 			8, 23, 3, 26, 43, 26, 44, 57890 },
259 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
260 			108300, 0x8f, 0x00, 15,
261 			8, 25, 3, 27, 44, 27, 45, 64320 },
262 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
263 			13200, 0x80, 0x00, 0,
264 			8, 2, 3, 12, 28, 28, 28, 6684 },
265 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
266 			25900, 0x81, 0x00, 1,
267 			8, 4, 3, 13, 29, 29, 29, 13368 },
268 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
269 			38600, 0x82, 0x00, 2,
270 			8, 6, 3, 14, 30, 30, 30, 20052 },
271 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
272 			49800, 0x83, 0x00, 3,
273 			8, 10, 3, 15, 31, 31, 31, 26738 },
274 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
275 			72200, 0x84, 0x00, 4,
276 			8, 14, 3, 16, 32, 32, 32, 40104 },
277 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
278 			92900, 0x85, 0x00, 5,
279 			8, 20, 3, 17, 33, 33, 33, 53476 },
280 		{ INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS,
281 			121500, /* 121.5 Mb */
282 			102700, 0x86, 0x00, 6,
283 			8, 23, 3, 18, 34, 34, 34, 60156 },
284 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
285 			112000, 0x87, 0x00, 7,
286 			8, 23, 3, 19, 35, 36, 36, 66840 },
287 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI,
288 			150000, /* 150 Mb */
289 			122000, 0x87, 0x00, 7,
290 			8, 25, 3, 19, 35, 36, 36, 74200 },
291 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
292 			25800, 0x88, 0x00, 8,
293 			8, 2, 3, 20, 37, 37, 37, 13360 },
294 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
295 			49800, 0x89, 0x00, 9,
296 			8, 4, 3, 21, 38, 38, 38, 26720 },
297 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
298 			71900, 0x8a, 0x00, 10,
299 			8, 6, 3, 22, 39, 39, 39, 40080 },
300 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
301 			92500, 0x8b, 0x00, 11,
302 			8, 10, 3, 23, 40, 40, 40, 53440 },
303 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
304 			130300, 0x8c, 0x00, 12,
305 			8, 14, 3, 24, 41, 41, 41, 80160 },
306 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
307 			162800, 0x8d, 0x00, 13,
308 			8, 20, 3, 25, 42, 42, 42, 106880 },
309 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
310 			178200, 0x8e, 0x00, 14,
311 			8, 23, 3, 26, 43, 43, 43, 120240 },
312 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
313 			192100, 0x8f, 0x00, 15,
314 			8, 23, 3, 27, 44, 45, 45, 133600 },
315 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI,
316 			300000, /* 300 Mb */
317 			207000, 0x8f, 0x00, 15,
318 			8, 25, 3, 27, 44, 45, 45, 148400 },
319 		},
320 	50,  /* probe interval */
321 	50,  /* rssi reduce interval */
322 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
323 };
324 
325 static struct ath_rate_table ar5416_11a_ratetable = {
326 	8,
327 	{0},
328 	{
329 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
330 			5400, 0x0b, 0x00, (0x80|12),
331 			0, 2, 1, 0, 0 },
332 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
333 			7800, 0x0f, 0x00, 18,
334 			0, 3, 1, 1, 0 },
335 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
336 			10000, 0x0a, 0x00, (0x80|24),
337 			2, 4, 2, 2, 0 },
338 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
339 			13900, 0x0e, 0x00, 36,
340 			2, 6, 2, 3, 0 },
341 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
342 			17300, 0x09, 0x00, (0x80|48),
343 			4, 10, 3, 4, 0 },
344 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
345 			23000, 0x0d, 0x00, 72,
346 			4, 14, 3, 5, 0 },
347 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
348 			27400, 0x08, 0x00, 96,
349 			4, 19, 3, 6, 0 },
350 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
351 			29300, 0x0c, 0x00, 108,
352 			4, 23, 3, 7, 0 },
353 	},
354 	50,  /* probe interval */
355 	50,  /* rssi reduce interval */
356 	0,   /* Phy rates allowed initially */
357 };
358 
359 static struct ath_rate_table ar5416_11g_ratetable = {
360 	12,
361 	{0},
362 	{
363 		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
364 			900, 0x1b, 0x00, 2,
365 			0, 0, 1, 0, 0 },
366 		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
367 			1900, 0x1a, 0x04, 4,
368 			1, 1, 1, 1, 0 },
369 		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
370 			4900, 0x19, 0x04, 11,
371 			2, 2, 2, 2, 0 },
372 		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
373 			8100, 0x18, 0x04, 22,
374 			3, 3, 2, 3, 0 },
375 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
376 			5400, 0x0b, 0x00, 12,
377 			4, 2, 1, 4, 0 },
378 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
379 			7800, 0x0f, 0x00, 18,
380 			4, 3, 1, 5, 0 },
381 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
382 			10000, 0x0a, 0x00, 24,
383 			6, 4, 1, 6, 0 },
384 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
385 			13900, 0x0e, 0x00, 36,
386 			6, 6, 2, 7, 0 },
387 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
388 			17300, 0x09, 0x00, 48,
389 			8, 10, 3, 8, 0 },
390 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
391 			23000, 0x0d, 0x00, 72,
392 			8, 14, 3, 9, 0 },
393 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
394 			27400, 0x08, 0x00, 96,
395 			8, 19, 3, 10, 0 },
396 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
397 			29300, 0x0c, 0x00, 108,
398 			8, 23, 3, 11, 0 },
399 	},
400 	50,  /* probe interval */
401 	50,  /* rssi reduce interval */
402 	0,   /* Phy rates allowed initially */
403 };
404 
405 static struct ath_rate_table ar5416_11b_ratetable = {
406 	4,
407 	{0},
408 	{
409 		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
410 			900, 0x1b,  0x00, (0x80|2),
411 			0, 0, 1, 0, 0 },
412 		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
413 			1800, 0x1a, 0x04, (0x80|4),
414 			1, 1, 1, 1, 0 },
415 		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
416 			4300, 0x19, 0x04, (0x80|11),
417 			1, 2, 2, 2, 0 },
418 		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
419 			7100, 0x18, 0x04, (0x80|22),
420 			1, 4, 100, 3, 0 },
421 	},
422 	100, /* probe interval */
423 	100, /* rssi reduce interval */
424 	0,   /* Phy rates allowed initially */
425 };
426 
427 static inline int8_t
428 median(int8_t a, int8_t b, int8_t c)
429 {
430 	if (a >= b) {
431 		if (b >= c)
432 			return (b);
433 		else if (a > c)
434 			return (c);
435 		else
436 			return (a);
437 	} else {
438 		if (a >= c)
439 			return (a);
440 		else if (b >= c)
441 			return (c);
442 		else
443 			return (b);
444 	}
445 }
446 
447 static void
448 arn_rc_sort_validrates(struct ath_rate_table *rate_table,
449     struct ath_rate_priv *ath_rc_priv)
450 {
451 	uint8_t i, j, idx, idx_next;
452 
453 	for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
454 		for (j = 0; j <= i-1; j++) {
455 			idx = ath_rc_priv->valid_rate_index[j];
456 			idx_next = ath_rc_priv->valid_rate_index[j+1];
457 
458 			if (rate_table->info[idx].ratekbps >
459 			    rate_table->info[idx_next].ratekbps) {
460 				ath_rc_priv->valid_rate_index[j] = idx_next;
461 				ath_rc_priv->valid_rate_index[j+1] = idx;
462 			}
463 		}
464 	}
465 }
466 
467 static void
468 arn_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
469 {
470 	uint8_t i;
471 
472 	for (i = 0; i < ath_rc_priv->rate_table_size; i++)
473 		ath_rc_priv->valid_rate_index[i] = 0;
474 }
475 
476 static inline void
477 arn_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
478     uint8_t index, int valid_tx_rate)
479 {
480 	ASSERT(index <= ath_rc_priv->rate_table_size);
481 	ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
482 }
483 
484 static inline int
485 /* LINTED E_STATIC_UNUSED */
486 arn_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv, uint8_t index)
487 {
488 	ASSERT(index <= ath_rc_priv->rate_table_size);
489 	return (ath_rc_priv->valid_rate_index[index]);
490 }
491 
492 /* ARGSUSED */
493 static inline int
494 arn_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
495     struct ath_rate_priv *ath_rc_priv,
496     uint8_t cur_valid_txrate,
497     uint8_t *next_idx)
498 {
499 	uint8_t i;
500 
501 	for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) {
502 		if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
503 			*next_idx = ath_rc_priv->valid_rate_index[i+1];
504 			return (1);
505 		}
506 	}
507 
508 	/* No more valid rates */
509 	*next_idx = 0;
510 
511 	return (0);
512 }
513 
514 /* Return true only for single stream */
515 static int
516 arn_rc_valid_phyrate(uint32_t phy, uint32_t capflag, int ignore_cw)
517 {
518 	if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
519 		return (0);
520 	if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
521 		return (0);
522 	if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
523 		return (0);
524 	if (!ignore_cw && WLAN_RC_PHY_HT(phy))
525 		if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
526 			return (0);
527 		if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
528 			return (0);
529 
530 	return (1);
531 }
532 
533 /* ARGSUSED */
534 static inline int
535 arn_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
536     struct ath_rate_priv *ath_rc_priv,
537     uint8_t cur_valid_txrate, uint8_t *next_idx)
538 {
539 	int8_t i;
540 
541 	for (i = 1; i < ath_rc_priv->max_valid_rate; i++) {
542 		if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
543 			*next_idx = ath_rc_priv->valid_rate_index[i-1];
544 			return (1);
545 		}
546 	}
547 
548 	return (0);
549 }
550 
551 static uint8_t
552 arn_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
553     struct ath_rate_table *rate_table, uint32_t capflag)
554 {
555 	uint8_t i, hi = 0;
556 	uint32_t valid;
557 
558 	for (i = 0; i < rate_table->rate_cnt; i++) {
559 		valid = (ath_rc_priv->single_stream ?
560 		    rate_table->info[i].valid_single_stream :
561 		    rate_table->info[i].valid);
562 		if (valid == 1) {
563 			uint32_t phy = rate_table->info[i].phy;
564 			uint8_t valid_rate_count = 0;
565 
566 			if (!arn_rc_valid_phyrate(phy, capflag, 0))
567 				continue;
568 
569 			valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
570 
571 			ath_rc_priv->
572 			    valid_phy_rateidx[phy][valid_rate_count] = i;
573 			ath_rc_priv->valid_phy_ratecnt[phy] += 1;
574 			arn_rc_set_valid_txmask(ath_rc_priv, i, 1);
575 			hi = A_MAX(hi, i);
576 		}
577 	}
578 
579 	return (hi);
580 }
581 
582 static uint8_t
583 arn_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
584     struct ath_rate_table *rate_table,
585     struct ath_rateset *rateset,
586     uint32_t capflag)
587 {
588 	uint8_t i, j, hi = 0;
589 
590 	/* Use intersection of working rates and valid rates */
591 	for (i = 0; i < rateset->rs_nrates; i++) {
592 		for (j = 0; j < rate_table->rate_cnt; j++) {
593 			uint32_t phy = rate_table->info[j].phy;
594 			uint32_t valid = (ath_rc_priv->single_stream ?
595 			    rate_table->info[j].valid_single_stream :
596 			    rate_table->info[j].valid);
597 			uint8_t rate = rateset->rs_rates[i];
598 			uint8_t dot11rate = rate_table->info[j].dot11rate;
599 
600 			/*
601 			 * We allow a rate only if its valid and the
602 			 * capflag matches one of the validity
603 			 * (VALID/VALID_20/VALID_40) flags
604 			 */
605 			if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
606 			    ((valid & WLAN_RC_CAP_MODE(capflag)) ==
607 			    WLAN_RC_CAP_MODE(capflag)) &&
608 			    !WLAN_RC_PHY_HT(phy)) {
609 				uint8_t valid_rate_count = 0;
610 
611 				if (!arn_rc_valid_phyrate(phy, capflag, 0))
612 					continue;
613 
614 				valid_rate_count =
615 				    ath_rc_priv->valid_phy_ratecnt[phy];
616 
617 				ath_rc_priv->valid_phy_rateidx[phy]
618 				    [valid_rate_count] = j;
619 				ath_rc_priv->valid_phy_ratecnt[phy] += 1;
620 				arn_rc_set_valid_txmask(ath_rc_priv, j, 1);
621 				hi = A_MAX(hi, j);
622 			}
623 		}
624 	}
625 
626 	return (hi);
627 }
628 
629 static uint8_t
630 arn_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
631     struct ath_rate_table *rate_table,
632     uint8_t *mcs_set, uint32_t capflag)
633 {
634 	struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
635 
636 	uint8_t i, j, hi = 0;
637 
638 	/* Use intersection of working rates and valid rates */
639 	for (i = 0; i < rateset->rs_nrates; i++) {
640 		for (j = 0; j < rate_table->rate_cnt; j++) {
641 			uint32_t phy = rate_table->info[j].phy;
642 			uint32_t valid = (ath_rc_priv->single_stream ?
643 			    rate_table->info[j].valid_single_stream :
644 			    rate_table->info[j].valid);
645 			uint8_t rate = rateset->rs_rates[i];
646 			uint8_t dot11rate = rate_table->info[j].dot11rate;
647 
648 			if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
649 			    !WLAN_RC_PHY_HT(phy) ||
650 			    !WLAN_RC_PHY_HT_VALID(valid, capflag))
651 				continue;
652 
653 			if (!arn_rc_valid_phyrate(phy, capflag, 0))
654 				continue;
655 
656 			ath_rc_priv->valid_phy_rateidx[phy]
657 			    [ath_rc_priv->valid_phy_ratecnt[phy]] = j;
658 			ath_rc_priv->valid_phy_ratecnt[phy] += 1;
659 			arn_rc_set_valid_txmask(ath_rc_priv, j, 1);
660 			hi = A_MAX(hi, j);
661 		}
662 	}
663 
664 	return (hi);
665 }
666 
667 /* ARGSUSED */
668 static uint8_t
669 arn_rc_ratefind_ht(struct arn_softc *sc,
670     struct ath_rate_priv *ath_rc_priv,
671     struct ath_rate_table *rate_table,
672     int probe_allowed, int *is_probing,
673     int is_retry)
674 {
675 	uint32_t dt, best_thruput, this_thruput, now_msec;
676 	uint8_t rate, next_rate, best_rate, maxindex, minindex;
677 	int8_t  rssi_last, rssi_reduce = 0, index = 0;
678 
679 	*is_probing = 0;
680 
681 	rssi_last = median(ath_rc_priv->rssi_last,
682 	    ath_rc_priv->rssi_last_prev,
683 	    ath_rc_priv->rssi_last_prev2);
684 
685 	/*
686 	 * Age (reduce) last ack rssi based on how old it is.
687 	 * The bizarre numbers are so the delta is 160msec,
688 	 * meaning we divide by 16.
689 	 * 0msec   <= dt <= 25msec: don't derate
690 	 * 25msec  <= dt <= 185msec: derate linearly from 0 to 10dB
691 	 * 185msec <= dt: derate by 10dB
692 	 */
693 
694 	/* now_msec = jiffies_to_msecs(jiffies); */
695 	now_msec = drv_hztousec(ddi_get_lbolt())/1000; /* mescs ? */
696 	dt = now_msec - ath_rc_priv->rssi_time;
697 
698 	if (dt >= 185)
699 		rssi_reduce = 10;
700 	else if (dt >= 25)
701 		rssi_reduce = (uint8_t)((dt - 25) >> 4);
702 
703 	/* Now reduce rssi_last by rssi_reduce */
704 	if (rssi_last < rssi_reduce)
705 		rssi_last = 0;
706 	else
707 		rssi_last -= rssi_reduce;
708 
709 	/*
710 	 * Now look up the rate in the rssi table and return it.
711 	 * If no rates match then we return 0 (lowest rate)
712 	 */
713 
714 	best_thruput = 0;
715 	maxindex = ath_rc_priv->max_valid_rate-1;
716 
717 	minindex = 0;
718 	best_rate = minindex;
719 
720 	/*
721 	 * Try the higher rate first. It will reduce memory moving time
722 	 * if we have very good channel characteristics.
723 	 */
724 	for (index = maxindex; index >= minindex; index--) {
725 		uint8_t per_thres;
726 
727 		rate = ath_rc_priv->valid_rate_index[index];
728 		if (rate > ath_rc_priv->rate_max_phy)
729 			continue;
730 
731 		/*
732 		 * For TCP the average collision rate is around 11%,
733 		 * so we ignore PERs less than this.  This is to
734 		 * prevent the rate we are currently using (whose
735 		 * PER might be in the 10-15 range because of TCP
736 		 * collisions) looking worse than the next lower
737 		 * rate whose PER has decayed close to 0.  If we
738 		 * used to next lower rate, its PER would grow to
739 		 * 10-15 and we would be worse off then staying
740 		 * at the current rate.
741 		 */
742 		per_thres = ath_rc_priv->state[rate].per;
743 		if (per_thres < 12)
744 			per_thres = 12;
745 
746 		this_thruput = rate_table->info[rate].user_ratekbps *
747 		    (100 - per_thres);
748 
749 		if (best_thruput <= this_thruput) {
750 			best_thruput = this_thruput;
751 			best_rate    = rate;
752 		}
753 	}
754 
755 	rate = best_rate;
756 
757 	/*
758 	 * if we are retrying for more than half the number
759 	 * of max retries, use the min rate for the next retry
760 	 */
761 	if (is_retry)
762 		rate = ath_rc_priv->valid_rate_index[minindex];
763 
764 	ath_rc_priv->rssi_last_lookup = rssi_last;
765 
766 	/*
767 	 * Must check the actual rate (ratekbps) to account for
768 	 * non-monoticity of 11g's rate table
769 	 */
770 
771 	if (rate >= ath_rc_priv->rate_max_phy && probe_allowed) {
772 		rate = ath_rc_priv->rate_max_phy;
773 
774 		/* Probe the next allowed phy state */
775 		/* FIXME:XXXX Check to make sure ratMax is checked properly */
776 		if (arn_rc_get_nextvalid_txrate(rate_table,
777 		    ath_rc_priv, rate, &next_rate) &&
778 		    (now_msec - ath_rc_priv->probe_time >
779 		    rate_table->probe_interval) &&
780 		    (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
781 			rate = next_rate;
782 			ath_rc_priv->probe_rate = rate;
783 			ath_rc_priv->probe_time = now_msec;
784 			ath_rc_priv->hw_maxretry_pktcnt = 0;
785 			*is_probing = 1;
786 		}
787 	}
788 
789 	if (rate > (ath_rc_priv->rate_table_size - 1))
790 		rate = ath_rc_priv->rate_table_size - 1;
791 
792 	ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) ||
793 	    (rate_table->info[rate].valid_single_stream &&
794 	    ath_rc_priv->single_stream));
795 
796 	return (rate);
797 }
798 
799 static void
800 arn_rc_rate_set_series(struct ath_rate_table *rate_table,
801     struct ath9k_tx_rate *rate,
802     uint8_t tries,
803     uint8_t rix,
804     int rtsctsenable)
805 {
806 #if 0
807 	struct ieee80211_node *in;
808 	ieee80211com_t *ic = (ieee80211com_t *)sc;
809 #endif
810 	rate->count = tries;
811 	rate->idx = rix;
812 
813 	if (rtsctsenable)
814 		rate->flags |= ATH9K_TX_RC_USE_RTS_CTS;
815 #if 0
816 	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
817 	    (in->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
818 		rate->flags |= ATH9K_TX_RC_USE_SHORT_PREAMBLE;
819 	}
820 #endif
821 	if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
822 		rate->flags |= ATH9K_TX_RC_40_MHZ_WIDTH;
823 	if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
824 		rate->flags |= ATH9K_TX_RC_SHORT_GI;
825 	if (WLAN_RC_PHY_HT(rate_table->info[rix].phy))
826 		rate->flags |= ATH9K_TX_RC_MCS;
827 }
828 
829 /* ARGSUSED */
830 static uint8_t
831 arn_rc_rate_getidx(struct arn_softc *sc,
832     struct ath_rate_priv *ath_rc_priv,
833     struct ath_rate_table *rate_table,
834     uint8_t rix, uint16_t stepdown,
835     uint16_t min_rate)
836 {
837 	uint32_t j;
838 	uint8_t nextindex;
839 
840 	if (min_rate) {
841 		for (j = RATE_TABLE_SIZE; j > 0; j--) {
842 			if (arn_rc_get_nextlowervalid_txrate(rate_table,
843 			    ath_rc_priv, rix, &nextindex))
844 				rix = nextindex;
845 			else
846 				break;
847 		}
848 	} else {
849 		for (j = stepdown; j > 0; j--) {
850 			if (arn_rc_get_nextlowervalid_txrate(rate_table,
851 			    ath_rc_priv, rix, &nextindex))
852 				rix = nextindex;
853 			else
854 				break;
855 		}
856 	}
857 	return (rix);
858 }
859 
860 static void
861 arn_rc_ratefind(struct arn_softc *sc, struct ath_rate_priv *ath_rc_priv,
862     struct ath_buf *bf, int num_tries, int num_rates, int *is_probe,
863     boolean_t is_retry)
864 {
865 	uint8_t try_per_rate = 0, i = 0, rix, nrix;
866 	struct ath_rate_table *rate_table;
867 	struct ath9k_tx_rate *rates = bf->rates;
868 	ieee80211com_t *ic = (ieee80211com_t *)sc;
869 
870 	rate_table = sc->sc_currates;
871 	rix = arn_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1,
872 	    is_probe, is_retry);
873 	nrix = rix;
874 
875 	if (*is_probe) {
876 		/*
877 		 * set one try for probe rates. For the
878 		 * probes don't enable rts
879 		 */
880 		arn_rc_rate_set_series(rate_table,
881 		    &rates[i++], 1, nrix, 0);
882 
883 		try_per_rate = (num_tries/num_rates);
884 		/*
885 		 * Get the next tried/allowed rate. No RTS for the next series
886 		 * after the probe rate
887 		 */
888 		nrix = arn_rc_rate_getidx(sc,
889 		    ath_rc_priv, rate_table, nrix, 1, 0);
890 		arn_rc_rate_set_series(rate_table,
891 		    &rates[i++], try_per_rate, nrix, 0);
892 	} else {
893 		try_per_rate = (num_tries/num_rates);
894 		/* Set the choosen rate. No RTS for first series entry. */
895 		arn_rc_rate_set_series(rate_table,
896 		    &rates[i++], try_per_rate, nrix, 0);
897 	}
898 
899 	/* Fill in the other rates for multirate retry */
900 	for (; i < num_rates; i++) {
901 		uint8_t try_num;
902 		uint8_t min_rate;
903 
904 		try_num = ((i + 1) == num_rates) ?
905 		    num_tries - (try_per_rate * i) : try_per_rate;
906 		/* LINTED E_FALSE_LOGICAL_EXPR */
907 		min_rate = (((i + 1) == num_rates) && 0);
908 
909 		nrix = arn_rc_rate_getidx(sc, ath_rc_priv,
910 		    rate_table, nrix, 1, min_rate);
911 		/* All other rates in the series have RTS enabled */
912 		arn_rc_rate_set_series(rate_table, &rates[i], try_num, nrix, 1);
913 	}
914 
915 	/*
916 	 * NB:Change rate series to enable aggregation when operating
917 	 * at lower MCS rates. When first rate in series is MCS2
918 	 * in HT40 @ 2.4GHz, series should look like:
919 	 *
920 	 * {MCS2, MCS1, MCS0, MCS0}.
921 	 *
922 	 * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should
923 	 * look like:
924 	 *
925 	 * {MCS3, MCS2, MCS1, MCS1}
926 	 *
927 	 * So, set fourth rate in series to be same as third one for
928 	 * above conditions.
929 	 */
930 
931 	if (IEEE80211_IS_CHAN_HTG(ic->ic_curchan)) {
932 		uint8_t dot11rate = rate_table->info[rix].dot11rate;
933 		uint8_t phy = rate_table->info[rix].phy;
934 		if (i == 4 &&
935 		    ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
936 		    (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
937 			rates[3].idx = rates[2].idx;
938 			rates[3].flags = rates[2].flags;
939 		}
940 	}
941 }
942 
943 /* ARGSUSED */
944 static boolean_t
945 arn_rc_update_per(struct arn_softc *sc,
946     struct ath_rate_table *rate_table,
947     struct ath_rate_priv *ath_rc_priv,
948     struct ath_tx_info_priv *tx_info_priv,
949     int tx_rate, int xretries, int retries,
950 	uint32_t now_msec)
951 {
952 	boolean_t state_change = B_FALSE;
953 	int count;
954 	uint8_t last_per;
955 	static uint32_t nretry_to_per_lookup[10] = {
956 		100 * 0 / 1,
957 		100 * 1 / 4,
958 		100 * 1 / 2,
959 		100 * 3 / 4,
960 		100 * 4 / 5,
961 		100 * 5 / 6,
962 		100 * 6 / 7,
963 		100 * 7 / 8,
964 		100 * 8 / 9,
965 		100 * 9 / 10
966 	};
967 
968 	last_per = ath_rc_priv->state[tx_rate].per;
969 
970 	if (xretries) {
971 		if (xretries == 1) {
972 			ath_rc_priv->state[tx_rate].per += 30;
973 			if (ath_rc_priv->state[tx_rate].per > 100)
974 				ath_rc_priv->state[tx_rate].per = 100;
975 		} else {
976 			/* xretries == 2 */
977 			count = ARRAY_SIZE(nretry_to_per_lookup);
978 			if (retries >= count)
979 				retries = count - 1;
980 
981 			/* new_PER = 7/8*old_PER + 1/8*(currentPER) */
982 			ath_rc_priv->state[tx_rate].per =
983 			    (uint8_t)(last_per - (last_per >> 3) + (100 >> 3));
984 		}
985 
986 		/* xretries == 1 or 2 */
987 
988 		if (ath_rc_priv->probe_rate == tx_rate)
989 			ath_rc_priv->probe_rate = 0;
990 
991 	} else { /* xretries == 0 */
992 		count = ARRAY_SIZE(nretry_to_per_lookup);
993 		if (retries >= count)
994 			retries = count - 1;
995 
996 		if (tx_info_priv->n_bad_frames) {
997 			/*
998 			 * new_PER = 7/8*old_PER + 1/8*(currentPER)
999 			 * Assuming that n_frames is not 0.  The current PER
1000 			 * from the retries is 100 * retries / (retries+1),
1001 			 * since the first retries attempts failed, and the
1002 			 * next one worked.  For the one that worked,
1003 			 * n_bad_frames subframes out of n_frames wored,
1004 			 * so the PER for that part is
1005 			 * 100 * n_bad_frames / n_frames, and it contributes
1006 			 * 100 * n_bad_frames / (n_frames * (retries+1)) to
1007 			 * the above PER.  The expression below is a
1008 			 * simplified version of the sum of these two terms.
1009 			 */
1010 			if (tx_info_priv->n_frames > 0) {
1011 				int n_frames, n_bad_frames;
1012 				uint8_t cur_per, new_per;
1013 
1014 				n_bad_frames = retries *
1015 				    tx_info_priv->n_frames +
1016 				    tx_info_priv->n_bad_frames;
1017 				n_frames =
1018 				    tx_info_priv->n_frames * (retries + 1);
1019 				cur_per =
1020 				    (100 * n_bad_frames / n_frames) >> 3;
1021 				new_per = (uint8_t)
1022 				    (last_per - (last_per >> 3) + cur_per);
1023 				ath_rc_priv->state[tx_rate].per = new_per;
1024 			}
1025 		} else {
1026 			ath_rc_priv->state[tx_rate].per =
1027 			    (uint8_t)(last_per - (last_per >> 3) +
1028 			    (nretry_to_per_lookup[retries] >> 3));
1029 		}
1030 
1031 		ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
1032 		ath_rc_priv->rssi_last_prev  = ath_rc_priv->rssi_last;
1033 		ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi;
1034 		ath_rc_priv->rssi_time = now_msec;
1035 
1036 		/*
1037 		 * If we got at most one retry then increase the max rate if
1038 		 * this was a probe.  Otherwise, ignore the probe.
1039 		 */
1040 		if (ath_rc_priv->probe_rate &&
1041 		    ath_rc_priv->probe_rate == tx_rate) {
1042 			if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
1043 			    tx_info_priv->n_frames) {
1044 				/*
1045 				 * Since we probed with just a single attempt,
1046 				 * any retries means the probe failed.  Also,
1047 				 * if the attempt worked, but more than half
1048 				 * the subframes were bad then also consider
1049 				 * the probe a failure.
1050 				 */
1051 				ath_rc_priv->probe_rate = 0;
1052 			} else {
1053 				uint8_t probe_rate = 0;
1054 
1055 				ath_rc_priv->rate_max_phy =
1056 				    ath_rc_priv->probe_rate;
1057 				probe_rate = ath_rc_priv->probe_rate;
1058 
1059 				if (ath_rc_priv->state[probe_rate].per > 30)
1060 					ath_rc_priv->state[probe_rate].per = 20;
1061 
1062 				ath_rc_priv->probe_rate = 0;
1063 
1064 				/*
1065 				 * Since this probe succeeded, we allow the next
1066 				 * probe twice as soon.  This allows the maxRate
1067 				 * to move up faster if the probes are
1068 				 * succesful.
1069 				 */
1070 				ath_rc_priv->probe_time =
1071 				    now_msec - rate_table->probe_interval / 2;
1072 			}
1073 		}
1074 
1075 		if (retries > 0) {
1076 			/*
1077 			 * Don't update anything.  We don't know if
1078 			 * this was because of collisions or poor signal.
1079 			 *
1080 			 * Later: if rssi_ack is close to
1081 			 * ath_rc_priv->state[txRate].rssi_thres and we see lots
1082 			 * of retries, then we could increase
1083 			 * ath_rc_priv->state[txRate].rssi_thres.
1084 			 */
1085 			ath_rc_priv->hw_maxretry_pktcnt = 0;
1086 		} else {
1087 			int32_t rssi_ackAvg;
1088 			int8_t rssi_thres;
1089 			int8_t rssi_ack_vmin;
1090 
1091 			/*
1092 			 * It worked with no retries. First ignore bogus (small)
1093 			 * rssi_ack values.
1094 			 */
1095 			if (tx_rate == ath_rc_priv->rate_max_phy &&
1096 			    ath_rc_priv->hw_maxretry_pktcnt < 255) {
1097 				ath_rc_priv->hw_maxretry_pktcnt++;
1098 			}
1099 
1100 			if (tx_info_priv->tx.ts_rssi <
1101 			    rate_table->info[tx_rate].rssi_ack_validmin)
1102 				goto exit;
1103 
1104 			/* Average the rssi */
1105 			if (tx_rate != ath_rc_priv->rssi_sum_rate) {
1106 				ath_rc_priv->rssi_sum_rate = tx_rate;
1107 				ath_rc_priv->rssi_sum =
1108 				    ath_rc_priv->rssi_sum_cnt = 0;
1109 			}
1110 
1111 			ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
1112 			ath_rc_priv->rssi_sum_cnt++;
1113 
1114 			if (ath_rc_priv->rssi_sum_cnt < 4)
1115 				goto exit;
1116 
1117 			rssi_ackAvg =
1118 			    (ath_rc_priv->rssi_sum + 2) / 4;
1119 			rssi_thres =
1120 			    ath_rc_priv->state[tx_rate].rssi_thres;
1121 			rssi_ack_vmin =
1122 			    rate_table->info[tx_rate].rssi_ack_validmin;
1123 
1124 			ath_rc_priv->rssi_sum =
1125 			    ath_rc_priv->rssi_sum_cnt = 0;
1126 
1127 			/* Now reduce the current rssi threshold */
1128 			if ((rssi_ackAvg < rssi_thres + 2) &&
1129 			    (rssi_thres > rssi_ack_vmin)) {
1130 				ath_rc_priv->state[tx_rate].rssi_thres--;
1131 			}
1132 
1133 			state_change = B_TRUE;
1134 		}
1135 	}
1136 exit:
1137 	return (state_change);
1138 }
1139 
1140 /*
1141  * Update PER, RSSI and whatever else that the code thinks
1142  * it is doing. If you can make sense of all this, you really
1143  * need to go out more.
1144  */
1145 static void
1146 arn_rc_update_ht(struct arn_softc *sc,
1147     struct ath_rate_priv *ath_rc_priv,
1148     struct ath_tx_info_priv *tx_info_priv,
1149     int tx_rate, int xretries, int retries)
1150 {
1151 #define	CHK_RSSI(rate)					\
1152 	((ath_rc_priv->state[(rate)].rssi_thres +	\
1153 	    rate_table->info[(rate)].rssi_ack_deltamin) > \
1154 	    ath_rc_priv->state[(rate)+1].rssi_thres)
1155 
1156 	/* u32 now_msec = jiffies_to_msecs(jiffies); */
1157 	uint32_t now_msec = drv_hztousec(ddi_get_lbolt())/1000; /* mescs ? */
1158 	int rate;
1159 	uint8_t last_per;
1160 	boolean_t state_change = B_FALSE;
1161 	struct ath_rate_table *rate_table = sc->sc_currates;
1162 	int size = ath_rc_priv->rate_table_size;
1163 
1164 	if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
1165 		return;
1166 
1167 	/* To compensate for some imbalance between ctrl and ext. channel */
1168 
1169 	if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
1170 		tx_info_priv->tx.ts_rssi =
1171 		    tx_info_priv->tx.ts_rssi < 3 ? 0 :
1172 		    tx_info_priv->tx.ts_rssi - 3;
1173 
1174 	last_per = ath_rc_priv->state[tx_rate].per;
1175 
1176 	/* Update PER first */
1177 	state_change = arn_rc_update_per(sc, rate_table, ath_rc_priv,
1178 	    tx_info_priv, tx_rate, xretries,
1179 	    retries, now_msec);
1180 
1181 	/*
1182 	 * If this rate looks bad (high PER) then stop using it for
1183 	 * a while (except if we are probing).
1184 	 */
1185 	if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
1186 	    rate_table->info[tx_rate].ratekbps <=
1187 	    rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
1188 		(void) arn_rc_get_nextlowervalid_txrate(rate_table,
1189 		    ath_rc_priv,
1190 		    (uint8_t)tx_rate,
1191 		    &ath_rc_priv->rate_max_phy);
1192 
1193 		/* Don't probe for a little while. */
1194 		ath_rc_priv->probe_time = now_msec;
1195 	}
1196 
1197 	if (state_change) {
1198 		/*
1199 		 * Make sure the rates above this have higher rssi thresholds.
1200 		 * (Note:  Monotonicity is kept within the OFDM rates and
1201 		 * within the CCK rates. However, no adjustment is
1202 		 * made to keep the rssi thresholds monotonically
1203 		 * increasing between the CCK and OFDM rates.)
1204 		 */
1205 		for (rate = tx_rate; rate < size - 1; rate++) {
1206 			if (rate_table->info[rate+1].phy !=
1207 			    rate_table->info[tx_rate].phy)
1208 				break;
1209 
1210 			if (CHK_RSSI(rate)) {
1211 				ath_rc_priv->state[rate+1].rssi_thres =
1212 				    ath_rc_priv->state[rate].rssi_thres +
1213 				    rate_table->info[rate].rssi_ack_deltamin;
1214 			}
1215 		}
1216 
1217 		/* Make sure the rates below this have lower rssi thresholds. */
1218 		for (rate = tx_rate - 1; rate >= 0; rate--) {
1219 			if (rate_table->info[rate].phy !=
1220 			    rate_table->info[tx_rate].phy)
1221 				break;
1222 
1223 			if (CHK_RSSI(rate)) {
1224 				if (ath_rc_priv->state[rate+1].rssi_thres <
1225 				    rate_table->info[rate].rssi_ack_deltamin)
1226 					ath_rc_priv->state[rate].rssi_thres = 0;
1227 				else {
1228 					ath_rc_priv->state[rate].rssi_thres =
1229 					    ath_rc_priv->state[rate+1].
1230 					    rssi_thres -
1231 					    rate_table->info[rate].
1232 					    rssi_ack_deltamin;
1233 				}
1234 
1235 				if (ath_rc_priv->state[rate].rssi_thres <
1236 				    rate_table->info[rate].rssi_ack_validmin) {
1237 					ath_rc_priv->state[rate].rssi_thres =
1238 					    rate_table->info[rate].
1239 					    rssi_ack_validmin;
1240 				}
1241 			}
1242 		}
1243 	}
1244 
1245 	/* Make sure the rates below this have lower PER */
1246 	/* Monotonicity is kept only for rates below the current rate. */
1247 	if (ath_rc_priv->state[tx_rate].per < last_per) {
1248 		for (rate = tx_rate - 1; rate >= 0; rate--) {
1249 			if (rate_table->info[rate].phy !=
1250 			    rate_table->info[tx_rate].phy)
1251 				break;
1252 
1253 			if (ath_rc_priv->state[rate].per >
1254 			    ath_rc_priv->state[rate+1].per) {
1255 				ath_rc_priv->state[rate].per =
1256 				    ath_rc_priv->state[rate+1].per;
1257 			}
1258 		}
1259 	}
1260 
1261 	/* Maintain monotonicity for rates above the current rate */
1262 	for (rate = tx_rate; rate < size - 1; rate++) {
1263 		if (ath_rc_priv->state[rate+1].per <
1264 		    ath_rc_priv->state[rate].per)
1265 			ath_rc_priv->state[rate+1].per =
1266 			    ath_rc_priv->state[rate].per;
1267 	}
1268 
1269 	/*
1270 	 * Every so often, we reduce the thresholds and
1271 	 * PER (different for CCK and OFDM).
1272 	 */
1273 	if (now_msec - ath_rc_priv->rssi_down_time >=
1274 	    rate_table->rssi_reduce_interval) {
1275 
1276 		for (rate = 0; rate < size; rate++) {
1277 			if (ath_rc_priv->state[rate].rssi_thres >
1278 			    rate_table->info[rate].rssi_ack_validmin)
1279 				ath_rc_priv->state[rate].rssi_thres -= 1;
1280 		}
1281 		ath_rc_priv->rssi_down_time = now_msec;
1282 	}
1283 
1284 	/*
1285 	 * Every so often, we reduce the thresholds
1286 	 * and PER (different for CCK and OFDM).
1287 	 */
1288 	if (now_msec - ath_rc_priv->per_down_time >=
1289 	    rate_table->rssi_reduce_interval) {
1290 		for (rate = 0; rate < size; rate++) {
1291 			ath_rc_priv->state[rate].per =
1292 			    7 * ath_rc_priv->state[rate].per / 8;
1293 		}
1294 
1295 		ath_rc_priv->per_down_time = now_msec;
1296 	}
1297 
1298 #undef CHK_RSSI
1299 }
1300 
1301 static int
1302 ath_rc_get_rateindex(struct ath_rate_table *rate_table,
1303     struct ath9k_tx_rate *rate)
1304 {
1305 	int rix;
1306 
1307 	if ((rate->flags & ATH9K_TX_RC_40_MHZ_WIDTH) &&
1308 	    (rate->flags & ATH9K_TX_RC_SHORT_GI))
1309 		rix = rate_table->info[rate->idx].ht_index;
1310 	else if (rate->flags & ATH9K_TX_RC_SHORT_GI)
1311 		rix = rate_table->info[rate->idx].sgi_index;
1312 	else if (rate->flags & ATH9K_TX_RC_40_MHZ_WIDTH)
1313 		rix = rate_table->info[rate->idx].cw40index;
1314 	else
1315 		rix = rate_table->info[rate->idx].base_index;
1316 
1317 	return (rix);
1318 }
1319 
1320 static void
1321 ath_rc_tx_status(struct arn_softc *sc, struct ath_rate_priv *ath_rc_priv,
1322     struct ath_buf *bf, int final_ts_idx, int xretries, int long_retry)
1323 {
1324 	struct ath_tx_info_priv *tx_info_priv =
1325 	    (struct ath_tx_info_priv *)&bf->tx_info_priv;
1326 	struct ath9k_tx_rate *rates = bf->rates;
1327 	struct ath_rate_table *rate_table;
1328 	uint32_t i = 0, rix;
1329 	uint8_t flags;
1330 
1331 	rate_table = sc->sc_currates;
1332 
1333 	/*
1334 	 * If the first rate is not the final index, there
1335 	 * are intermediate rate failures to be processed.
1336 	 */
1337 	if (final_ts_idx != 0) {
1338 		/* Process intermediate rates that failed. */
1339 		for (i = 0; i < final_ts_idx; i++) {
1340 			if (rates[i].count != 0 && (rates[i].idx >= 0)) {
1341 				flags = rates[i].flags;
1342 
1343 				/*
1344 				 * If HT40 and we have switched mode from
1345 				 * 40 to 20 => don't update
1346 				 */
1347 
1348 				if ((flags & ATH9K_TX_RC_40_MHZ_WIDTH) &&
1349 				    (ath_rc_priv->rc_phy_mode !=
1350 				    WLAN_RC_40_FLAG))
1351 					return;
1352 
1353 				rix =
1354 				    ath_rc_get_rateindex(rate_table, &rates[i]);
1355 				arn_rc_update_ht(sc, ath_rc_priv,
1356 				    tx_info_priv, rix,
1357 				    xretries ? 1 : 2,
1358 				    rates[i].count);
1359 			}
1360 		}
1361 	} else {
1362 		/*
1363 		 * Handle the special case of MIMO PS burst, where the second
1364 		 * aggregate is sent out with only one rate and one try.
1365 		 * Treating it as an excessive retry penalizes the rate
1366 		 * inordinately.
1367 		 */
1368 		if (rates[0].count == 1 && xretries == 1)
1369 			xretries = 2;
1370 	}
1371 
1372 	flags = rates[i].flags;
1373 
1374 	/* If HT40 and we have switched mode from 40 to 20 => don't update */
1375 	if ((flags & ATH9K_TX_RC_40_MHZ_WIDTH) &&
1376 	    (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) {
1377 		return;
1378 	}
1379 
1380 	rix = ath_rc_get_rateindex(rate_table, &rates[i]);
1381 	arn_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
1382 	    xretries, long_retry);
1383 }
1384 
1385 static struct ath_rate_table *
1386 arn_choose_rate_table(struct arn_softc *sc, uint32_t cur_mode,
1387     boolean_t is_ht, boolean_t is_cw_40)
1388 {
1389 	int ath9k_mode;
1390 	switch (cur_mode) {
1391 	case IEEE80211_MODE_11A:
1392 	case IEEE80211_MODE_11NA:
1393 		ath9k_mode = ATH9K_MODE_11A;
1394 		if (is_ht)
1395 			ath9k_mode = ATH9K_MODE_11NA_HT20;
1396 		if (is_cw_40)
1397 			ath9k_mode = ATH9K_MODE_11NA_HT40PLUS;
1398 		break;
1399 	case IEEE80211_MODE_11B:
1400 		ath9k_mode = ATH9K_MODE_11B;
1401 		break;
1402 	case IEEE80211_MODE_11G:
1403 	case IEEE80211_MODE_11NG:
1404 		ath9k_mode = ATH9K_MODE_11G;
1405 		if (is_ht)
1406 			ath9k_mode = ATH9K_MODE_11NG_HT20;
1407 		if (is_cw_40)
1408 			ath9k_mode = ATH9K_MODE_11NG_HT40PLUS;
1409 		break;
1410 	default:
1411 		ARN_DBG((ARN_DBG_RATE, "Invalid band\n"));
1412 		return (NULL);
1413 	}
1414 
1415 	switch (ath9k_mode) {
1416 	case ATH9K_MODE_11A:
1417 		ARN_DBG((ARN_DBG_RATE, "choose rate table:ATH9K_MODE_11A\n"));
1418 		break;
1419 	case ATH9K_MODE_11B:
1420 		ARN_DBG((ARN_DBG_RATE, "choose rate table:ATH9K_MODE_11B\n"));
1421 		break;
1422 	case ATH9K_MODE_11G:
1423 		ARN_DBG((ARN_DBG_RATE, "choose rate table:ATH9K_MODE_11G\n"));
1424 		break;
1425 	case ATH9K_MODE_11NA_HT20:
1426 		ARN_DBG((ARN_DBG_RATE,
1427 		    "choose rate table:ATH9K_MODE_11NA_HT20\n"));
1428 		break;
1429 	case ATH9K_MODE_11NA_HT40PLUS:
1430 		ARN_DBG((ARN_DBG_RATE,
1431 		    "choose rate table:ATH9K_MODE_11NA_HT40PLUS\n"));
1432 		break;
1433 	case ATH9K_MODE_11NG_HT20:
1434 		ARN_DBG((ARN_DBG_RATE,
1435 		    "choose rate table:ATH9K_MODE_11NG_HT20\n"));
1436 		break;
1437 	case ATH9K_MODE_11NG_HT40PLUS:
1438 		ARN_DBG((ARN_DBG_RATE,
1439 		    "choose rate table:ATH9K_MODE_11NG_HT40PLUS\n"));
1440 		break;
1441 	default:
1442 		arn_problem("Invalid band\n");
1443 		break;
1444 	}
1445 
1446 	ARN_DBG((ARN_DBG_RATE, "Choosing rate table for mode: %d\n",
1447 	    ath9k_mode));
1448 	return (sc->hw_rate_table[ath9k_mode]);
1449 }
1450 
1451 /* Private rate contral initialization */
1452 static void
1453 arn_rc_init(struct arn_softc *sc,
1454     struct ath_rate_priv *ath_rc_priv,
1455     struct ieee80211_node *in)
1456 {
1457 	struct ath_rate_table *rate_table = NULL;
1458 	struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
1459 	ieee80211com_t *ic = (ieee80211com_t *)sc;
1460 	uint32_t cur_mode = ic->ic_curmode;
1461 	uint8_t *ht_mcs = (uint8_t *)&ath_rc_priv->neg_ht_rates;
1462 	uint8_t i, j, k, hi = 0, hthi = 0;
1463 	boolean_t is_rc_ds;
1464 
1465 	/* FIXME: Adhoc */
1466 	if ((sc->sc_ah->ah_opmode == ATH9K_M_STA) ||
1467 	    (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)) {
1468 		boolean_t is_ht = in->in_flags & IEEE80211_NODE_HT;
1469 		/* 20/40 support */
1470 		boolean_t is_cw_40 =
1471 		    in->in_htcap & IEEE80211_HTCAP_CHWIDTH40;
1472 		rate_table =
1473 		    arn_choose_rate_table(sc, cur_mode, is_ht, is_cw_40);
1474 	} else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
1475 		/* cur_rate_table would be set on init */
1476 		rate_table = sc->sc_currates;
1477 	}
1478 
1479 	if (!rate_table) {
1480 		ARN_DBG((ARN_DBG_FATAL, "Rate table not initialized\n"));
1481 		return;
1482 	}
1483 
1484 	if (in->in_flags & IEEE80211_NODE_HT) {
1485 		/* 2.6.30 */
1486 		ath_rc_priv->ht_cap = WLAN_RC_HT_FLAG;
1487 		is_rc_ds = (AR_SREV_9280_20_OR_LATER(sc->sc_ah) &&
1488 		    (ath9k_hw_get_eeprom(sc->sc_ah, EEP_RC_CHAIN_MASK) == 1)) ?
1489 		    B_FALSE: B_TRUE;
1490 		if (sc->sc_ah->ah_caps.tx_chainmask != 1 && is_rc_ds) {
1491 			if (sc->sc_ht_conf.rx_mcs_mask[1]) {
1492 				ath_rc_priv->ht_cap |= WLAN_RC_DS_FLAG;
1493 			}
1494 		}
1495 
1496 		if (in->in_htcap & IEEE80211_HTCAP_CHWIDTH40)
1497 			ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG;
1498 		if (in->in_htcap & IEEE80211_HTCAP_SHORTGI40)
1499 			ath_rc_priv->ht_cap |= WLAN_RC_SGI_FLAG;
1500 	}
1501 
1502 	/*
1503 	 * Initial rate table size. Will change depending
1504 	 * on the working rate set
1505 	 */
1506 	ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
1507 
1508 	/* Initialize thresholds according to the global rate table */
1509 	for (i = 0; i < ath_rc_priv->rate_table_size; i++) {
1510 		ath_rc_priv->state[i].rssi_thres =
1511 		    rate_table->info[i].rssi_ack_validmin;
1512 		ath_rc_priv->state[i].per = 0;
1513 	}
1514 
1515 	/* Determine the valid rates */
1516 	arn_rc_init_valid_txmask(ath_rc_priv);
1517 
1518 	for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
1519 		for (j = 0; j < MAX_TX_RATE_PHY; j++)
1520 			ath_rc_priv->valid_phy_rateidx[i][j] = 0;
1521 		ath_rc_priv->valid_phy_ratecnt[i] = 0;
1522 	}
1523 	ath_rc_priv->rc_phy_mode = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG);
1524 
1525 	/* Set stream capability */
1526 	ath_rc_priv->single_stream =
1527 	    (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1;
1528 
1529 	if (!rateset->rs_nrates) {
1530 		/* No working rate, just initialize valid rates */
1531 		hi = arn_rc_init_validrates(ath_rc_priv, rate_table,
1532 		    ath_rc_priv->ht_cap);
1533 	} else {
1534 		/* Use intersection of working rates and valid rates */
1535 		hi = arn_rc_setvalid_rates(ath_rc_priv, rate_table,
1536 		    rateset, ath_rc_priv->ht_cap);
1537 		if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
1538 			hthi = arn_rc_setvalid_htrates(ath_rc_priv,
1539 			    rate_table,
1540 			    ht_mcs,
1541 			    ath_rc_priv->ht_cap);
1542 		}
1543 		hi = A_MAX(hi, hthi);
1544 	}
1545 
1546 	ath_rc_priv->rate_table_size = hi + 1;
1547 	ath_rc_priv->rate_max_phy = 0;
1548 	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
1549 
1550 	for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1551 		for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
1552 			ath_rc_priv->valid_rate_index[k++] =
1553 			    ath_rc_priv->valid_phy_rateidx[i][j];
1554 		}
1555 
1556 		if (!arn_rc_valid_phyrate(i, rate_table->initial_ratemax, 1) ||
1557 		    !ath_rc_priv->valid_phy_ratecnt[i])
1558 			continue;
1559 
1560 		ath_rc_priv->rate_max_phy =
1561 		    ath_rc_priv->valid_phy_rateidx[i][j-1];
1562 	}
1563 	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
1564 	ASSERT(k <= RATE_TABLE_SIZE);
1565 
1566 	ath_rc_priv->max_valid_rate = k;
1567 	arn_rc_sort_validrates(rate_table, ath_rc_priv);
1568 	ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
1569 	sc->sc_currates = rate_table;
1570 }
1571 
1572 void
1573 arn_tx_status(struct arn_softc *sc, struct ath_buf *bf, boolean_t is_data)
1574 {
1575 	struct ieee80211_node *in = (struct ieee80211_node *)(bf->bf_in);
1576 	struct ath_node *an = ATH_NODE(in);
1577 	struct ath_rate_priv *ath_rc_priv =
1578 	    (struct ath_rate_priv *)&an->rate_priv;
1579 	struct ath_tx_info_priv *tx_info_priv =
1580 	    (struct ath_tx_info_priv *)&bf->tx_info_priv;
1581 	int final_ts_idx, tx_status = 0, is_underrun = 0;
1582 
1583 	final_ts_idx = tx_info_priv->tx.ts_rateindex;
1584 
1585 	if (!is_data || !tx_info_priv->update_rc)
1586 		return;
1587 
1588 	if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
1589 		return;
1590 
1591 	/*
1592 	 * If underrun error is seen assume it as an excessive retry only
1593 	 * if prefetch trigger level have reached the max (0x3f for 5416)
1594 	 * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
1595 	 * times. This affects how ratectrl updates PER for the failed rate.
1596 	 */
1597 	if (tx_info_priv->tx.ts_flags &
1598 	    (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
1599 	    ((sc->sc_ah->ah_txTrigLevel) >= ath_rc_priv->tx_triglevel_max)) {
1600 		tx_status = 1;
1601 		is_underrun = 1;
1602 	}
1603 
1604 	if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) ||
1605 	    (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
1606 		tx_status = 1;
1607 
1608 	ath_rc_tx_status(sc,
1609 	    ath_rc_priv,
1610 	    bf,
1611 	    final_ts_idx,
1612 	    tx_status,
1613 	    (is_underrun) ? ATH_11N_TXMAXTRY : tx_info_priv->tx.ts_longretry);
1614 }
1615 
1616 void
1617 arn_get_rate(struct arn_softc *sc, struct ath_buf *bf,
1618     struct ieee80211_frame *wh)
1619 {
1620 	struct ieee80211_node *in = (struct ieee80211_node *)(bf->bf_in);
1621 	struct ath_node *an = ATH_NODE(in);
1622 	struct ath_rate_priv *ath_rc_priv =
1623 	    (struct ath_rate_priv *)&an->rate_priv;
1624 	struct ath_rate_table *rt = sc->sc_currates;
1625 	ieee80211com_t *ic = (ieee80211com_t *)sc;
1626 	int is_probe = 0;
1627 	uint8_t i;
1628 
1629 	/* lowest rate for management and multicast/broadcast frames */
1630 	if (!IEEE80211_IS_DATA(wh) || IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1631 		bf->rates[0].idx = 0; /* xxx Fix me */
1632 		bf->rates[0].count =
1633 		    IEEE80211_IS_MULTICAST(wh->i_addr1) ?
1634 		    1 : ATH_MGT_TXMAXTRY;
1635 		return;
1636 	}
1637 
1638 	/* Find tx rate for unicast frames */
1639 	arn_rc_ratefind(sc, ath_rc_priv, bf, ATH_11N_TXMAXTRY, 4,
1640 	    &is_probe, B_FALSE);
1641 
1642 	/* Temporary workaround for 'dladm show-wifi' */
1643 	for (i = 0; i < in->in_rates.ir_nrates; i++) {
1644 		ARN_DBG((ARN_DBG_RATE, "arn: arn_get_rate(): "
1645 		    "in->in_rates.ir_rates[%d] = %d,"
1646 		    "bf->rates[0].idx = %d,"
1647 		    "rt->info[bf->rates[0].idx].dot11rate = %d\n",
1648 		    i,
1649 		    in->in_rates.ir_rates[i],
1650 		    bf->rates[0].idx,
1651 		    rt->info[bf->rates[0].idx].dot11rate));
1652 		if (rt->info[bf->rates[0].idx].dot11rate ==
1653 		    in->in_rates.ir_rates[i])
1654 			break;
1655 	}
1656 	in->in_txrate = i;
1657 	if (ic->ic_curmode == IEEE80211_MODE_11NA ||
1658 	    ic->ic_curmode == IEEE80211_MODE_11NG)
1659 		in->in_txrate = in->in_rates.ir_nrates - 1;
1660 
1661 	/* Check if aggregation has to be enabled for this tid */
1662 #ifdef ARN_TX_AGGREGATION
1663 	/* should check if enabled, not supported */
1664 	if (sc->sc_ht_conf.ht_supported) {
1665 		if (ieee80211_is_data_qos(wh)) {
1666 			uint8_t *qc, tid;
1667 			struct ath_node *an;
1668 			struct ieee80211_qosframe *qwh = NULL;
1669 
1670 			qwh = (struct ieee80211_qosframe *)wh;
1671 			tid = qc[0] & 0xf;
1672 			an = (struct ath_node *)sta->drv_priv;
1673 
1674 			if (arn_tx_aggr_check(sc, an, tid))
1675 				/* to do */
1676 		}
1677 	}
1678 #endif /* ARN_TX_AGGREGATION */
1679 }
1680 
1681 void
1682 arn_rate_init(struct arn_softc *sc, struct ieee80211_node *in)
1683 {
1684 	int i;
1685 	struct ath_node *an = ATH_NODE(in);
1686 	struct ath_rate_priv *ath_rc_priv =
1687 	    (struct ath_rate_priv *)&an->rate_priv;
1688 
1689 	/* should be moved to arn_node_init later */
1690 	ath_rc_priv->rssi_down_time =
1691 	    drv_hztousec(ddi_get_lbolt())/1000; /* mesc */
1692 	ath_rc_priv->tx_triglevel_max =
1693 	    sc->sc_ah->ah_caps.tx_triglevel_max;
1694 
1695 	for (i = 0; i < in->in_rates.ir_nrates; i++) {
1696 		ath_rc_priv->neg_rates.rs_rates[i] = in->in_rates.ir_rates[i];
1697 		ARN_DBG((ARN_DBG_RATE, "arn:arn_rate_init()"
1698 		    "ath_rc_priv->neg_rates.rs_rates[%d] = %d\n",
1699 		    i, ath_rc_priv->neg_rates.rs_rates[i]));
1700 	}
1701 	ath_rc_priv->neg_rates.rs_nrates = in->in_rates.ir_nrates;
1702 
1703 	/* negotiated ht rate set ??? */
1704 	if (in->in_flags & IEEE80211_NODE_HT) {
1705 		for (i = 0; i < in->in_htrates.rs_nrates; i++) {
1706 			ath_rc_priv->neg_ht_rates.rs_rates[i] =
1707 			    in->in_htrates.rs_rates[i];
1708 			ARN_DBG((ARN_DBG_RATE, "arn:arn_rate_init()"
1709 			    "ath_rc_priv->neg_ht_rates.rs_rates[%d] = %d\n",
1710 			    i, ath_rc_priv->neg_ht_rates.rs_rates[i]));
1711 		}
1712 		ath_rc_priv->neg_ht_rates.rs_nrates = in->in_htrates.rs_nrates;
1713 
1714 		/* arn_update_chainmask(sc); */
1715 	}
1716 
1717 #ifdef ARN_TX_AGGREGATION
1718 	/* Temply put the following ht info init here */
1719 	uint8_t ampdu_factor, ampdu_density;
1720 	if (sc->sc_ht_conf.ht_support &&
1721 	    (in->in_htcap_ie != NULL) &&
1722 	    (in->in_htcap != 0) &&
1723 	    (in->in_htparam != 0)) {
1724 		ampdu_factor = in->in_htparam & HT_RX_AMPDU_FACTOR_MSK;
1725 		ampdu_density = (in->in_htparam & HT_MPDU_DENSITY_MSK) >>
1726 		    HT_MPDU_DENSITY_POS;
1727 		an->maxampdu =
1728 		    1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + ampdu_factor);
1729 		an->mpdudensity = parse_mpdudensity(ampdu_density);
1730 	}
1731 	/* end */
1732 #endif /* ARN_TX_AGGREGATION */
1733 
1734 	arn_rc_init(sc, ath_rc_priv, in);
1735 }
1736 
1737 static void
1738 arn_setup_rate_table(struct arn_softc *sc,
1739     struct ath_rate_table *rate_table)
1740 {
1741 	int i;
1742 
1743 	for (i = 0; i < 256; i++)
1744 		rate_table->rateCodeToIndex[i] = (uint8_t)-1;
1745 
1746 	for (i = 0; i < rate_table->rate_cnt; i++) {
1747 		uint8_t code = rate_table->info[i].ratecode;
1748 		uint8_t cix = rate_table->info[i].ctrl_rate;
1749 		uint8_t sh = rate_table->info[i].short_preamble;
1750 
1751 		rate_table->rateCodeToIndex[code] = (int)i;
1752 		rate_table->rateCodeToIndex[code | sh] = (int)i;
1753 
1754 		rate_table->info[i].lpAckDuration =
1755 		    ath9k_hw_computetxtime(sc->sc_ah, rate_table,
1756 		    WLAN_CTRL_FRAME_SIZE,
1757 		    cix,
1758 		    B_FALSE);
1759 		rate_table->info[i].spAckDuration =
1760 		    ath9k_hw_computetxtime(sc->sc_ah, rate_table,
1761 		    WLAN_CTRL_FRAME_SIZE,
1762 		    cix,
1763 		    B_TRUE);
1764 	}
1765 }
1766 
1767 void
1768 arn_rate_attach(struct arn_softc *sc)
1769 {
1770 	sc->hw_rate_table[ATH9K_MODE_11B] =
1771 	    &ar5416_11b_ratetable;
1772 	sc->hw_rate_table[ATH9K_MODE_11A] =
1773 	    &ar5416_11a_ratetable;
1774 	sc->hw_rate_table[ATH9K_MODE_11G] =
1775 	    &ar5416_11g_ratetable;
1776 	sc->hw_rate_table[ATH9K_MODE_11NA_HT20] =
1777 	    &ar5416_11na_ratetable;
1778 	sc->hw_rate_table[ATH9K_MODE_11NG_HT20] =
1779 	    &ar5416_11ng_ratetable;
1780 	sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
1781 	    &ar5416_11na_ratetable;
1782 	sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
1783 	    &ar5416_11na_ratetable;
1784 	sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
1785 	    &ar5416_11ng_ratetable;
1786 	sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
1787 	    &ar5416_11ng_ratetable;
1788 
1789 	arn_setup_rate_table(sc, &ar5416_11b_ratetable);
1790 	arn_setup_rate_table(sc, &ar5416_11a_ratetable);
1791 	arn_setup_rate_table(sc, &ar5416_11g_ratetable);
1792 	arn_setup_rate_table(sc, &ar5416_11na_ratetable);
1793 	arn_setup_rate_table(sc, &ar5416_11ng_ratetable);
1794 }
1795 
1796 #ifdef ARN_LEGACY_RC
1797 void
1798 arn_rate_update(struct arn_softc *sc, struct ieee80211_node *in, int32_t rate)
1799 {
1800 	struct ath_node *an = ATH_NODE(in);
1801 	const struct ath_rate_table *rt = sc->sc_currates;
1802 	uint8_t rix;
1803 
1804 	ASSERT(rt != NULL);
1805 
1806 	in->in_txrate = rate;
1807 
1808 	/* management/control frames always go at the lowest speed */
1809 	an->an_tx_mgtrate = rt->info[0].ratecode;
1810 	an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].short_preamble;
1811 
1812 	ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_update(): "
1813 	    "mgtrate=%d mgtratesp=%d\n",
1814 	    an->an_tx_mgtrate, an->an_tx_mgtratesp));
1815 
1816 	/*
1817 	 * Before associating a node has no rate set setup
1818 	 * so we can't calculate any transmit codes to use.
1819 	 * This is ok since we should never be sending anything
1820 	 * but management frames and those always go at the
1821 	 * lowest hardware rate.
1822 	 */
1823 	if (in->in_rates.ir_nrates == 0)
1824 		goto done;
1825 	an->an_tx_rix0 = sc->asc_rixmap[
1826 	    in->in_rates.ir_rates[rate] & IEEE80211_RATE_VAL];
1827 	an->an_tx_rate0 = rt->info[an->an_tx_rix0].ratecode;
1828 	an->an_tx_rate0sp = an->an_tx_rate0 |
1829 	    rt->info[an->an_tx_rix0].short_preamble;
1830 	if (sc->sc_mrretry) {
1831 		/*
1832 		 * Hardware supports multi-rate retry; setup two
1833 		 * step-down retry rates and make the lowest rate
1834 		 * be the ``last chance''.  We use 4, 2, 2, 2 tries
1835 		 * respectively (4 is set here, the rest are fixed
1836 		 * in the xmit routine).
1837 		 */
1838 		an->an_tx_try0 = 1 + 3;		/* 4 tries at rate 0 */
1839 		if (--rate >= 0) {
1840 			rix = sc->asc_rixmap[
1841 			    in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL];
1842 			an->an_tx_rate1 = rt->info[rix].ratecode;
1843 			an->an_tx_rate1sp = an->an_tx_rate1 |
1844 			    rt->info[rix].short_preamble;
1845 		} else {
1846 			an->an_tx_rate1 = an->an_tx_rate1sp = 0;
1847 		}
1848 		if (--rate >= 0) {
1849 			rix = sc->asc_rixmap[
1850 			    in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL];
1851 			an->an_tx_rate2 = rt->info[rix].ratecode;
1852 			an->an_tx_rate2sp = an->an_tx_rate2 |
1853 			    rt->info[rix].short_preamble;
1854 		} else {
1855 			an->an_tx_rate2 = an->an_tx_rate2sp = 0;
1856 		}
1857 		if (rate > 0) {
1858 			an->an_tx_rate3 = rt->info[0].ratecode;
1859 			an->an_tx_rate3sp =
1860 			    an->an_tx_mgtrate | rt->info[0].short_preamble;
1861 		} else {
1862 			an->an_tx_rate3 = an->an_tx_rate3sp = 0;
1863 		}
1864 	} else {
1865 		an->an_tx_try0 = ATH_TXMAXTRY;  /* max tries at rate 0 */
1866 		an->an_tx_rate1 = an->an_tx_rate1sp = 0;
1867 		an->an_tx_rate2 = an->an_tx_rate2sp = 0;
1868 		an->an_tx_rate3 = an->an_tx_rate3sp = 0;
1869 	}
1870 done:
1871 	an->an_tx_ok = an->an_tx_err = an->an_tx_retr = an->an_tx_upper = 0;
1872 }
1873 
1874 /*
1875  * Set the starting transmit rate for a node.
1876  */
1877 void
1878 arn_rate_ctl_start(struct arn_softc *sc, struct ieee80211_node *in)
1879 {
1880 	ieee80211com_t *ic = (ieee80211com_t *)sc;
1881 	int32_t srate;
1882 
1883 	if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
1884 		/*
1885 		 * No fixed rate is requested. For 11b start with
1886 		 * the highest negotiated rate; otherwise, for 11g
1887 		 * and 11a, we start "in the middle" at 24Mb or 36Mb.
1888 		 */
1889 		srate = in->in_rates.ir_nrates - 1;
1890 		if (sc->sc_curmode != IEEE80211_MODE_11B) {
1891 			/*
1892 			 * Scan the negotiated rate set to find the
1893 			 * closest rate.
1894 			 */
1895 			/* NB: the rate set is assumed sorted */
1896 			for (; srate >= 0 && IEEE80211_RATE(srate) > 72;
1897 			    srate--) {}
1898 		}
1899 	} else {
1900 		/*
1901 		 * A fixed rate is to be used; We know the rate is
1902 		 * there because the rate set is checked when the
1903 		 * station associates.
1904 		 */
1905 		/* NB: the rate set is assumed sorted */
1906 		srate = in->in_rates.ir_nrates - 1;
1907 		for (; srate >= 0 && IEEE80211_RATE(srate) != ic->ic_fixed_rate;
1908 		    srate--) {}
1909 	}
1910 
1911 	ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl_start(): "
1912 	    "srate=%d rate=%d\n", srate, IEEE80211_RATE(srate)));
1913 
1914 	arn_rate_update(sc, in, srate);
1915 }
1916 
1917 void
1918 arn_rate_cb(void *arg, struct ieee80211_node *in)
1919 {
1920 	arn_rate_update((struct arn_softc *)arg, in, 0);
1921 }
1922 #endif /* ARN_LEGACY_RC */
1923 /*
1924  * Reset the rate control state for each 802.11 state transition.
1925  */
1926 void
1927 arn_rate_ctl_reset(struct arn_softc *sc, enum ieee80211_state state)
1928 {
1929 	ieee80211com_t *ic = (ieee80211com_t *)sc;
1930 	struct ieee80211_node *in;
1931 
1932 	if (ic->ic_opmode == IEEE80211_M_STA) {
1933 		/*
1934 		 * Reset local xmit state; this is really only
1935 		 * meaningful when operating in station mode.
1936 		 */
1937 		in = (struct ieee80211_node *)ic->ic_bss;
1938 
1939 #ifdef ARN_LEGACY_RC
1940 		if (state == IEEE80211_S_RUN) {
1941 			arn_rate_ctl_start(sc, in);
1942 		} else {
1943 			arn_rate_update(sc, in, 0);
1944 		}
1945 #else
1946 		if (state == IEEE80211_S_RUN)
1947 			arn_rate_init(sc, in);
1948 #endif
1949 	/* LINTED E_NOP_ELSE_STMT */
1950 	} else {
1951 		/*
1952 		 * When operating as a station the node table holds
1953 		 * the AP's that were discovered during scanning.
1954 		 * For any other operating mode we want to reset the
1955 		 * tx rate state of each node.
1956 		 */
1957 #ifdef ARN_LEGACY_RC
1958 		ieee80211_iterate_nodes(&ic->ic_sta, arn_rate_cb, sc);
1959 #endif
1960 	}
1961 }
1962 
1963 #ifdef ARN_LEGACY_RC
1964 /*
1965  * Examine and potentially adjust the transmit rate.
1966  */
1967 void
1968 arn_rate_ctl(void *arg, struct ieee80211_node *in)
1969 {
1970 	struct arn_softc *sc = arg;
1971 	struct ath_node *an = ATH_NODE(in);
1972 	struct ieee80211_rateset *rs = &in->in_rates;
1973 	int32_t mod = 0, nrate, enough;
1974 
1975 	/*
1976 	 * Rate control(very primitive version).
1977 	 */
1978 	sc->sc_stats.ast_rate_calls++;
1979 
1980 	enough = (an->an_tx_ok + an->an_tx_err >= 10);
1981 
1982 	/* no packet reached -> down */
1983 	if (an->an_tx_err > 0 && an->an_tx_ok == 0)
1984 		mod = -1;
1985 
1986 	/* all packets needs retry in average -> down */
1987 	if (enough && an->an_tx_ok < an->an_tx_retr)
1988 		mod = -1;
1989 
1990 	/* no error and less than 10% of packets needs retry -> up */
1991 	if (enough && an->an_tx_err == 0 && an->an_tx_ok > an->an_tx_retr * 10)
1992 		mod = 1;
1993 
1994 	nrate = in->in_txrate;
1995 	switch (mod) {
1996 	case 0:
1997 		if (enough && an->an_tx_upper > 0)
1998 			an->an_tx_upper--;
1999 		break;
2000 	case -1:
2001 		if (nrate > 0) {
2002 			nrate--;
2003 			sc->sc_stats.ast_rate_drop++;
2004 		}
2005 		an->an_tx_upper = 0;
2006 		break;
2007 	case 1:
2008 		if (++an->an_tx_upper < 10)
2009 			break;
2010 		an->an_tx_upper = 0;
2011 		if (nrate + 1 < rs->ir_nrates) {
2012 			nrate++;
2013 			sc->sc_stats.ast_rate_raise++;
2014 		}
2015 		break;
2016 	}
2017 
2018 	if (nrate != in->in_txrate) {
2019 		ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl(): %dM -> %dM "
2020 		    "(%d ok, %d err, %d retr)\n",
2021 		    (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) / 2,
2022 		    (rs->ir_rates[nrate] & IEEE80211_RATE_VAL) / 2,
2023 		    an->an_tx_ok, an->an_tx_err, an->an_tx_retr));
2024 		arn_rate_update(sc, in, nrate);
2025 	} else if (enough)
2026 		an->an_tx_ok = an->an_tx_err = an->an_tx_retr = 0;
2027 }
2028 #endif /* ARN_LEGACY_RC */
2029