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