rc.c 44.9 KB
Newer Older
1 2
/*
 * Copyright (c) 2004 Video54 Technologies, Inc.
3
 * Copyright (c) 2004-2009 Atheros Communications, Inc.
4 5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

S
Sujith 已提交
18
#include "ath9k.h"
19

20
static const struct ath_rate_table ar5416_11na_ratetable = {
21 22
	42,
	{
S
Sujith 已提交
23
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
24
			5400, 0x0b, 0x00, 12,
25
			0, 0, 0, 0, 0, 0 },
S
Sujith 已提交
26
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
27
			7800,  0x0f, 0x00, 18,
28
			0, 1, 1, 1, 1, 0 },
S
Sujith 已提交
29
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
30
			10000, 0x0a, 0x00, 24,
31
			2, 2, 2, 2, 2, 0 },
S
Sujith 已提交
32
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
33
			13900, 0x0e, 0x00, 36,
34
			2,  3, 3, 3, 3, 0 },
S
Sujith 已提交
35
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
36
			17300, 0x09, 0x00, 48,
37
			4,  4, 4, 4, 4, 0 },
S
Sujith 已提交
38
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
39
			23000, 0x0d, 0x00, 72,
40
			4,  5, 5, 5, 5, 0 },
S
Sujith 已提交
41
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
42
			27400, 0x08, 0x00, 96,
43
			4,  6, 6, 6, 6, 0 },
S
Sujith 已提交
44
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
45
			29300, 0x0c, 0x00, 108,
46
			4,  7, 7, 7, 7, 0 },
47
		{ VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
48
			6400, 0x80, 0x00, 0,
49
			0, 8, 24, 8, 24, 3216 },
S
Sujith 已提交
50
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
51
			12700, 0x81, 0x00, 1,
52
			2, 9, 25, 9, 25, 6434 },
S
Sujith 已提交
53
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
54
			18800, 0x82, 0x00, 2,
55
			2, 10, 26, 10, 26, 9650 },
S
Sujith 已提交
56
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
57
			25000, 0x83, 0x00, 3,
58
			4,  11, 27, 11, 27, 12868 },
S
Sujith 已提交
59
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
60
			36700, 0x84, 0x00, 4,
61
			4,  12, 28, 12, 28, 19304 },
S
Sujith 已提交
62
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
63
			48100, 0x85, 0x00, 5,
64
			4,  13, 29, 13, 29, 25740 },
S
Sujith 已提交
65
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
66
			53500, 0x86, 0x00, 6,
67
			4,  14, 30, 14, 30,  28956 },
S
Sujith 已提交
68
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
69
			59000, 0x87, 0x00, 7,
70
			4,  15, 31, 15, 32, 32180 },
S
Sujith 已提交
71
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
72
			12700, 0x88, 0x00,
73
			8, 3, 16, 33, 16, 33, 6430 },
S
Sujith 已提交
74
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
75
			24800, 0x89, 0x00, 9,
76
			2, 17, 34, 17, 34, 12860 },
S
Sujith 已提交
77
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
78
			36600, 0x8a, 0x00, 10,
79
			2, 18, 35, 18, 35, 19300 },
S
Sujith 已提交
80
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
81
			48100, 0x8b, 0x00, 11,
82
			4,  19, 36, 19, 36, 25736 },
S
Sujith 已提交
83
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
84
			69500, 0x8c, 0x00, 12,
85
			4,  20, 37, 20, 37, 38600 },
S
Sujith 已提交
86
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
87
			89500, 0x8d, 0x00, 13,
88
			4,  21, 38, 21, 38, 51472 },
S
Sujith 已提交
89
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
90
			98900, 0x8e, 0x00, 14,
91
			4,  22, 39, 22, 39, 57890 },
S
Sujith 已提交
92
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
93
			108300, 0x8f, 0x00, 15,
94
			4,  23, 40, 23, 41, 64320 },
S
Sujith 已提交
95
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
96
			13200, 0x80, 0x00, 0,
97
			0, 8, 24, 24, 24, 6684 },
S
Sujith 已提交
98
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
99
			25900, 0x81, 0x00, 1,
100
			2, 9, 25, 25, 25, 13368 },
S
Sujith 已提交
101
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
102
			38600, 0x82, 0x00, 2,
103
			2, 10, 26, 26, 26, 20052 },
S
Sujith 已提交
104
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
105
			49800, 0x83, 0x00, 3,
106
			4,  11, 27, 27, 27, 26738 },
S
Sujith 已提交
107
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
108
			72200, 0x84, 0x00, 4,
109
			4,  12, 28, 28, 28, 40104 },
S
Sujith 已提交
110
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
111
			92900, 0x85, 0x00, 5,
112
			4,  13, 29, 29, 29, 53476 },
S
Sujith 已提交
113
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
114
			102700, 0x86, 0x00, 6,
115
			4,  14, 30, 30, 30, 60156 },
S
Sujith 已提交
116
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
117
			112000, 0x87, 0x00, 7,
118
			4,  15, 31, 32, 32, 66840 },
S
Sujith 已提交
119
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
120
			122000, 0x87, 0x00, 7,
121
			4,  15, 31, 32, 32, 74200 },
S
Sujith 已提交
122
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
123
			25800, 0x88, 0x00, 8,
124
			0, 16, 33, 33, 33, 13360 },
S
Sujith 已提交
125
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
126
			49800, 0x89, 0x00, 9,
127
			2, 17, 34, 34, 34, 26720 },
S
Sujith 已提交
128
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
129
			71900, 0x8a, 0x00, 10,
130
			2, 18, 35, 35, 35, 40080 },
S
Sujith 已提交
131
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
132
			92500, 0x8b, 0x00, 11,
133
			4,  19, 36, 36, 36, 53440 },
S
Sujith 已提交
134
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
135
			130300, 0x8c, 0x00, 12,
136
			4,  20, 37, 37, 37, 80160 },
S
Sujith 已提交
137
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
138
			162800, 0x8d, 0x00, 13,
139
			4,  21, 38, 38, 38, 106880 },
S
Sujith 已提交
140
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
141
			178200, 0x8e, 0x00, 14,
142
			4,  22, 39, 39, 39, 120240 },
S
Sujith 已提交
143
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
144
			192100, 0x8f, 0x00, 15,
145
			4,  23, 40, 41, 41, 133600 },
S
Sujith 已提交
146
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
147
			207000, 0x8f, 0x00, 15,
148
			4,  23, 40, 41, 41, 148400 },
149 150 151 152 153 154 155 156
	},
	50,  /* probe interval */
	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
};

/* 4ms frame limit not used for NG mode.  The values filled
 * for HT are the 64K max aggregate limit */

157
static const struct ath_rate_table ar5416_11ng_ratetable = {
158 159
	46,
	{
S
Sujith 已提交
160
		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
161
			900, 0x1b, 0x00, 2,
162
			0, 0, 0, 0, 0, 0 },
S
Sujith 已提交
163
		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
164
			1900, 0x1a, 0x04, 4,
165
			1, 1, 1, 1, 1, 0 },
S
Sujith 已提交
166
		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
167
			4900, 0x19, 0x04, 11,
168
			2, 2, 2, 2, 2, 0 },
S
Sujith 已提交
169
		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
170
			8100, 0x18, 0x04, 22,
171
			3, 3, 3, 3, 3, 0 },
S
Sujith 已提交
172
		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
173
			5400, 0x0b, 0x00, 12,
174
			4, 4, 4, 4, 4, 0 },
S
Sujith 已提交
175
		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
176
			7800, 0x0f, 0x00, 18,
177
			4, 5, 5, 5, 5, 0 },
S
Sujith 已提交
178
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
179
			10100, 0x0a, 0x00, 24,
180
			6, 6, 6, 6, 6, 0 },
S
Sujith 已提交
181
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
182
			14100,  0x0e, 0x00, 36,
183
			6, 7, 7, 7, 7, 0 },
S
Sujith 已提交
184
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
185
			17700, 0x09, 0x00, 48,
186
			8,  8, 8, 8, 8, 0 },
S
Sujith 已提交
187
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
188
			23700, 0x0d, 0x00, 72,
189
			8,  9, 9, 9, 9, 0 },
S
Sujith 已提交
190
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
191
			27400, 0x08, 0x00, 96,
192
			8,  10, 10, 10, 10, 0 },
S
Sujith 已提交
193
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
194
			30900, 0x0c, 0x00, 108,
195
			8,  11, 11, 11, 11, 0 },
S
Sujith 已提交
196
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
197
			6400, 0x80, 0x00, 0,
198
			4, 12, 28, 12, 28, 3216 },
S
Sujith 已提交
199
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
200
			12700, 0x81, 0x00, 1,
201
			6, 13, 29, 13, 29, 6434 },
S
Sujith 已提交
202
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
203
			18800, 0x82, 0x00, 2,
204
			6, 14, 30, 14, 30, 9650 },
S
Sujith 已提交
205
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
206
			25000, 0x83, 0x00, 3,
207
			8,  15, 31, 15, 31, 12868 },
S
Sujith 已提交
208
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
209
			36700, 0x84, 0x00, 4,
210
			8,  16, 32, 16, 32, 19304 },
S
Sujith 已提交
211
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
212
			48100, 0x85, 0x00, 5,
213
			8,  17, 33, 17, 33, 25740 },
S
Sujith 已提交
214
		{ INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
215
			53500, 0x86, 0x00, 6,
216
			8,  18, 34, 18, 34, 28956 },
S
Sujith 已提交
217
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
218
			59000, 0x87, 0x00, 7,
219
			8,  19, 35, 19, 36, 32180 },
S
Sujith 已提交
220
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
221
			12700, 0x88, 0x00, 8,
222
			4, 20, 37, 20, 37, 6430 },
S
Sujith 已提交
223
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
224
			24800, 0x89, 0x00, 9,
225
			6, 21, 38, 21, 38, 12860 },
S
Sujith 已提交
226
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
227
			36600, 0x8a, 0x00, 10,
228
			6, 22, 39, 22, 39, 19300 },
S
Sujith 已提交
229
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
230
			48100, 0x8b, 0x00, 11,
231
			8,  23, 40, 23, 40, 25736 },
S
Sujith 已提交
232
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
233
			69500, 0x8c, 0x00, 12,
234
			8,  24, 41, 24, 41, 38600 },
S
Sujith 已提交
235
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
236
			89500, 0x8d, 0x00, 13,
237
			8,  25, 42, 25, 42, 51472 },
S
Sujith 已提交
238
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
239
			98900, 0x8e, 0x00, 14,
240
			8,  26, 43, 26, 44, 57890 },
S
Sujith 已提交
241
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
242
			108300, 0x8f, 0x00, 15,
243
			8,  27, 44, 27, 45, 64320 },
S
Sujith 已提交
244
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
245
			13200, 0x80, 0x00, 0,
246
			8, 12, 28, 28, 28, 6684 },
S
Sujith 已提交
247
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
248
			25900, 0x81, 0x00, 1,
249
			8, 13, 29, 29, 29, 13368 },
S
Sujith 已提交
250
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
251
			38600, 0x82, 0x00, 2,
252
			8, 14, 30, 30, 30, 20052 },
S
Sujith 已提交
253
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
254
			49800, 0x83, 0x00, 3,
255
			8,  15, 31, 31, 31, 26738 },
S
Sujith 已提交
256
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
257
			72200, 0x84, 0x00, 4,
258
			8,  16, 32, 32, 32, 40104 },
S
Sujith 已提交
259
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
260
			92900, 0x85, 0x00, 5,
261
			8,  17, 33, 33, 33, 53476 },
S
Sujith 已提交
262
		{ INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
263
			102700, 0x86, 0x00, 6,
264
			8,  18, 34, 34, 34, 60156 },
S
Sujith 已提交
265
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
266
			112000, 0x87, 0x00, 7,
267
			8,  19, 35, 36, 36, 66840 },
S
Sujith 已提交
268
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
269
			122000, 0x87, 0x00, 7,
270
			8,  19, 35, 36, 36, 74200 },
S
Sujith 已提交
271
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
272
			25800, 0x88, 0x00, 8,
273
			8, 20, 37, 37, 37, 13360 },
S
Sujith 已提交
274
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
275
			49800, 0x89, 0x00, 9,
276
			8, 21, 38, 38, 38, 26720 },
S
Sujith 已提交
277
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
278
			71900, 0x8a, 0x00, 10,
279
			8, 22, 39, 39, 39, 40080 },
S
Sujith 已提交
280
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
281
			92500, 0x8b, 0x00, 11,
282
			8,  23, 40, 40, 40, 53440 },
S
Sujith 已提交
283
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
284
			130300, 0x8c, 0x00, 12,
285
			8,  24, 41, 41, 41, 80160 },
S
Sujith 已提交
286
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
287
			162800, 0x8d, 0x00, 13,
288
			8,  25, 42, 42, 42, 106880 },
S
Sujith 已提交
289
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
290
			178200, 0x8e, 0x00, 14,
291
			8,  26, 43, 43, 43, 120240 },
S
Sujith 已提交
292
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
293
			192100, 0x8f, 0x00, 15,
294
			8,  27, 44, 45, 45, 133600 },
S
Sujith 已提交
295
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
296
			207000, 0x8f, 0x00, 15,
297
			8,  27, 44, 45, 45, 148400 },
298 299 300 301 302
		},
	50,  /* probe interval */
	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
};

303
static const struct ath_rate_table ar5416_11a_ratetable = {
304 305
	8,
	{
S
Sujith 已提交
306
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
307
			5400, 0x0b, 0x00, (0x80|12),
308
			0, 0, 0 },
S
Sujith 已提交
309
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
310
			7800, 0x0f, 0x00, 18,
311
			0, 1, 0 },
S
Sujith 已提交
312
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
313
			10000, 0x0a, 0x00, (0x80|24),
314
			2, 2, 0 },
S
Sujith 已提交
315
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
316
			13900, 0x0e, 0x00, 36,
317
			2, 3, 0 },
S
Sujith 已提交
318
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
319
			17300, 0x09, 0x00, (0x80|48),
320
			4,  4, 0 },
S
Sujith 已提交
321
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
322
			23000, 0x0d, 0x00, 72,
323
			4,  5, 0 },
S
Sujith 已提交
324
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
325
			27400, 0x08, 0x00, 96,
326
			4,  6, 0 },
S
Sujith 已提交
327
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
328
			29300, 0x0c, 0x00, 108,
329
			4,  7, 0 },
330 331 332 333 334
	},
	50,  /* probe interval */
	0,   /* Phy rates allowed initially */
};

335
static const struct ath_rate_table ar5416_11g_ratetable = {
336 337
	12,
	{
S
Sujith 已提交
338
		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
339
			900, 0x1b, 0x00, 2,
340
			0, 0, 0 },
S
Sujith 已提交
341
		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
342
			1900, 0x1a, 0x04, 4,
343
			1, 1, 0 },
S
Sujith 已提交
344
		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
345
			4900, 0x19, 0x04, 11,
346
			2, 2, 0 },
S
Sujith 已提交
347
		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
348
			8100, 0x18, 0x04, 22,
349
			3, 3, 0 },
S
Sujith 已提交
350
		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
351
			5400, 0x0b, 0x00, 12,
352
			4, 4, 0 },
S
Sujith 已提交
353
		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
354
			7800, 0x0f, 0x00, 18,
355
			4, 5, 0 },
S
Sujith 已提交
356
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
357
			10000, 0x0a, 0x00, 24,
358
			6, 6, 0 },
S
Sujith 已提交
359
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
360
			13900, 0x0e, 0x00, 36,
361
			6, 7, 0 },
S
Sujith 已提交
362
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
363
			17300, 0x09, 0x00, 48,
364
			8,  8, 0 },
S
Sujith 已提交
365
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
366
			23000, 0x0d, 0x00, 72,
367
			8,  9, 0 },
S
Sujith 已提交
368
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
369
			27400, 0x08, 0x00, 96,
370
			8,  10, 0 },
S
Sujith 已提交
371
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
372
			29300, 0x0c, 0x00, 108,
373
			8,  11, 0 },
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
	},
	50,  /* probe interval */
	0,   /* Phy rates allowed initially */
};

static inline int8_t median(int8_t a, int8_t b, int8_t c)
{
	if (a >= b) {
		if (b >= c)
			return b;
		else if (a > c)
			return c;
		else
			return a;
	} else {
		if (a >= c)
			return a;
		else if (b >= c)
			return c;
		else
			return b;
	}
}

398
static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
S
Sujith 已提交
399
				   struct ath_rate_priv *ath_rc_priv)
400 401 402
{
	u8 i, j, idx, idx_next;

403
	for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
404
		for (j = 0; j <= i-1; j++) {
405 406
			idx = ath_rc_priv->valid_rate_index[j];
			idx_next = ath_rc_priv->valid_rate_index[j+1];
407 408 409

			if (rate_table->info[idx].ratekbps >
				rate_table->info[idx_next].ratekbps) {
410 411
				ath_rc_priv->valid_rate_index[j] = idx_next;
				ath_rc_priv->valid_rate_index[j+1] = idx;
412 413 414 415 416
			}
		}
	}
}

S
Sujith 已提交
417
static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
418 419 420
{
	u8 i;

421
	for (i = 0; i < ath_rc_priv->rate_table_size; i++)
S
Sujith 已提交
422
		ath_rc_priv->valid_rate_index[i] = 0;
423 424
}

S
Sujith 已提交
425
static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
426 427
					   u8 index, int valid_tx_rate)
{
428
	ASSERT(index <= ath_rc_priv->rate_table_size);
S
Sujith 已提交
429
	ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
430 431
}

432 433 434 435 436
static inline
int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
				struct ath_rate_priv *ath_rc_priv,
				u8 cur_valid_txrate,
				u8 *next_idx)
437 438 439
{
	u8 i;

440 441 442
	for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) {
		if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
			*next_idx = ath_rc_priv->valid_rate_index[i+1];
S
Sujith 已提交
443
			return 1;
444 445 446 447 448
		}
	}

	/* No more valid rates */
	*next_idx = 0;
S
Sujith 已提交
449

S
Sujith 已提交
450
	return 0;
451 452 453 454 455 456
}

/* Return true only for single stream */

static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
{
457
	if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
S
Sujith 已提交
458
		return 0;
459
	if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
S
Sujith 已提交
460
		return 0;
461
	if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
S
Sujith 已提交
462
		return 0;
463 464
	if (!ignore_cw && WLAN_RC_PHY_HT(phy))
		if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
S
Sujith 已提交
465 466
			return 0;
	return 1;
467 468 469
}

static inline int
470 471 472
ath_rc_get_lower_rix(const struct ath_rate_table *rate_table,
		     struct ath_rate_priv *ath_rc_priv,
		     u8 cur_valid_txrate, u8 *next_idx)
473 474 475
{
	int8_t i;

476 477 478
	for (i = 1; i < ath_rc_priv->max_valid_rate ; i++) {
		if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
			*next_idx = ath_rc_priv->valid_rate_index[i-1];
S
Sujith 已提交
479
			return 1;
480 481
		}
	}
S
Sujith 已提交
482

S
Sujith 已提交
483
	return 0;
484 485
}

S
Sujith 已提交
486
static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
487
				 const struct ath_rate_table *rate_table,
S
Sujith 已提交
488
				 u32 capflag)
489 490 491 492 493
{
	u8 i, hi = 0;
	u32 valid;

	for (i = 0; i < rate_table->rate_cnt; i++) {
494
		valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
S
Sujith 已提交
495 496
			 rate_table->info[i].valid_single_stream :
			 rate_table->info[i].valid);
S
Sujith 已提交
497
		if (valid == 1) {
498 499 500
			u32 phy = rate_table->info[i].phy;
			u8 valid_rate_count = 0;

S
Sujith 已提交
501
			if (!ath_rc_valid_phyrate(phy, capflag, 0))
502 503
				continue;

504
			valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
505

506 507
			ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
			ath_rc_priv->valid_phy_ratecnt[phy] += 1;
S
Sujith 已提交
508
			ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
509 510 511
			hi = A_MAX(hi, i);
		}
	}
S
Sujith 已提交
512

513 514 515
	return hi;
}

S
Sujith 已提交
516
static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
517
				const struct ath_rate_table *rate_table,
S
Sujith 已提交
518 519
				struct ath_rateset *rateset,
				u32 capflag)
520 521 522 523 524 525 526
{
	u8 i, j, hi = 0;

	/* Use intersection of working rates and valid rates */
	for (i = 0; i < rateset->rs_nrates; i++) {
		for (j = 0; j < rate_table->rate_cnt; j++) {
			u32 phy = rate_table->info[j].phy;
527 528 529
			u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
				     rate_table->info[j].valid_single_stream :
				     rate_table->info[j].valid);
S
Sujith 已提交
530 531
			u8 rate = rateset->rs_rates[i];
			u8 dot11rate = rate_table->info[j].dot11rate;
532 533 534

			/* We allow a rate only if its valid and the
			 * capflag matches one of the validity
S
Sujith 已提交
535
			 * (VALID/VALID_20/VALID_40) flags */
536

S
Sujith 已提交
537 538 539 540
			if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
			    ((valid & WLAN_RC_CAP_MODE(capflag)) ==
			     WLAN_RC_CAP_MODE(capflag)) &&
			    !WLAN_RC_PHY_HT(phy)) {
541 542
				u8 valid_rate_count = 0;

S
Sujith 已提交
543
				if (!ath_rc_valid_phyrate(phy, capflag, 0))
544 545 546
					continue;

				valid_rate_count =
547
					ath_rc_priv->valid_phy_ratecnt[phy];
548

549
				ath_rc_priv->valid_phy_rateidx[phy]
550
					[valid_rate_count] = j;
551
				ath_rc_priv->valid_phy_ratecnt[phy] += 1;
S
Sujith 已提交
552
				ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
553 554 555 556
				hi = A_MAX(hi, j);
			}
		}
	}
S
Sujith 已提交
557

558 559 560
	return hi;
}

S
Sujith 已提交
561
static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
562
				  const struct ath_rate_table *rate_table,
S
Sujith 已提交
563
				  u8 *mcs_set, u32 capflag)
564
{
S
Sujith 已提交
565 566
	struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;

567 568 569
	u8 i, j, hi = 0;

	/* Use intersection of working rates and valid rates */
S
Sujith 已提交
570
	for (i = 0; i < rateset->rs_nrates; i++) {
571 572
		for (j = 0; j < rate_table->rate_cnt; j++) {
			u32 phy = rate_table->info[j].phy;
573
			u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
S
Sujith 已提交
574 575
				     rate_table->info[j].valid_single_stream :
				     rate_table->info[j].valid);
S
Sujith 已提交
576 577
			u8 rate = rateset->rs_rates[i];
			u8 dot11rate = rate_table->info[j].dot11rate;
578

S
Sujith 已提交
579
			if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
S
Sujith 已提交
580 581
			    !WLAN_RC_PHY_HT(phy) ||
			    !WLAN_RC_PHY_HT_VALID(valid, capflag))
582 583
				continue;

S
Sujith 已提交
584
			if (!ath_rc_valid_phyrate(phy, capflag, 0))
585 586
				continue;

587 588 589
			ath_rc_priv->valid_phy_rateidx[phy]
				[ath_rc_priv->valid_phy_ratecnt[phy]] = j;
			ath_rc_priv->valid_phy_ratecnt[phy] += 1;
S
Sujith 已提交
590
			ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
591 592 593 594
			hi = A_MAX(hi, j);
		}
	}

S
Sujith 已提交
595
	return hi;
596 597
}

598 599 600 601 602
/* Finds the highest rate index we can use */
static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
			         struct ath_rate_priv *ath_rc_priv,
				 const struct ath_rate_table *rate_table,
				 int *is_probing)
603
{
604
	u32 best_thruput, this_thruput, now_msec;
605
	u8 rate, next_rate, best_rate, maxindex, minindex;
606
	int8_t index = 0;
607 608

	now_msec = jiffies_to_msecs(jiffies);
609
	*is_probing = 0;
610
	best_thruput = 0;
611
	maxindex = ath_rc_priv->max_valid_rate-1;
612 613 614 615 616 617 618 619 620 621
	minindex = 0;
	best_rate = minindex;

	/*
	 * Try the higher rate first. It will reduce memory moving time
	 * if we have very good channel characteristics.
	 */
	for (index = maxindex; index >= minindex ; index--) {
		u8 per_thres;

622 623
		rate = ath_rc_priv->valid_rate_index[index];
		if (rate > ath_rc_priv->rate_max_phy)
624 625 626 627 628 629 630 631 632 633 634 635 636
			continue;

		/*
		 * For TCP the average collision rate is around 11%,
		 * so we ignore PERs less than this.  This is to
		 * prevent the rate we are currently using (whose
		 * PER might be in the 10-15 range because of TCP
		 * collisions) looking worse than the next lower
		 * rate whose PER has decayed close to 0.  If we
		 * used to next lower rate, its PER would grow to
		 * 10-15 and we would be worse off then staying
		 * at the current rate.
		 */
637
		per_thres = ath_rc_priv->per[rate];
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
		if (per_thres < 12)
			per_thres = 12;

		this_thruput = rate_table->info[rate].user_ratekbps *
			(100 - per_thres);

		if (best_thruput <= this_thruput) {
			best_thruput = this_thruput;
			best_rate    = rate;
		}
	}

	rate = best_rate;

	/*
	 * Must check the actual rate (ratekbps) to account for
	 * non-monoticity of 11g's rate table
	 */

S
Sujith 已提交
657
	if (rate >= ath_rc_priv->rate_max_phy) {
658
		rate = ath_rc_priv->rate_max_phy;
659 660 661

		/* Probe the next allowed phy state */
		if (ath_rc_get_nextvalid_txrate(rate_table,
S
Sujith 已提交
662
					ath_rc_priv, rate, &next_rate) &&
663
		    (now_msec - ath_rc_priv->probe_time >
664
		     rate_table->probe_interval) &&
665
		    (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
666
			rate = next_rate;
667 668 669
			ath_rc_priv->probe_rate = rate;
			ath_rc_priv->probe_time = now_msec;
			ath_rc_priv->hw_maxretry_pktcnt = 0;
S
Sujith 已提交
670
			*is_probing = 1;
671 672 673
		}
	}

674 675
	if (rate > (ath_rc_priv->rate_table_size - 1))
		rate = ath_rc_priv->rate_table_size - 1;
676

677 678 679 680 681
	if (rate_table->info[rate].valid &&
	    (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
		return rate;

	if (rate_table->info[rate].valid_single_stream &&
682
	    !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
683 684 685 686 687 688
		return rate;

	/* This should not happen */
	WARN_ON(1);

	rate = ath_rc_priv->valid_rate_index[0];
689 690 691 692

	return rate;
}

693
static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
S
Sujith 已提交
694
				   struct ieee80211_tx_rate *rate,
695
				   struct ieee80211_tx_rate_control *txrc,
S
Sujith 已提交
696
				   u8 tries, u8 rix, int rtsctsenable)
697
{
S
Sujith 已提交
698 699 700
	rate->count = tries;
	rate->idx = rix;

701 702 703
	if (txrc->short_preamble)
		rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
	if (txrc->rts || rtsctsenable)
S
Sujith 已提交
704 705 706 707 708 709 710
		rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
	if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
		rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
	if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
		rate->flags |= IEEE80211_TX_RC_SHORT_GI;
	if (WLAN_RC_PHY_HT(rate_table->info[rix].phy))
		rate->flags |= IEEE80211_TX_RC_MCS;
711 712
}

713
static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
714
				   const struct ath_rate_table *rate_table,
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
				   struct ieee80211_tx_info *tx_info)
{
	struct ieee80211_tx_rate *rates = tx_info->control.rates;
	int i = 0, rix = 0, cix, enable_g_protection = 0;

	/* get the cix for the lowest valid rix */
	for (i = 3; i >= 0; i--) {
		if (rates[i].count && (rates[i].idx >= 0)) {
			rix = rates[i].idx;
			break;
		}
	}
	cix = rate_table->info[rix].ctrl_rate;

	/* All protection frames are transmited at 2Mb/s for 802.11g,
	 * otherwise we transmit them at 1Mb/s */
	if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
	    !conf_is_ht(&sc->hw->conf))
		enable_g_protection = 1;

	/*
	 * If 802.11g protection is enabled, determine whether to use RTS/CTS or
	 * just CTS.  Note that this is only done for OFDM/HT unicast frames.
	 */
	if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
	    (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
	     WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
		rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
		cix = rate_table->info[enable_g_protection].ctrl_rate;
	}

	tx_info->control.rts_cts_rate_idx = cix;
}

749 750
static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
			 struct ieee80211_tx_rate_control *txrc)
751
{
752 753
	struct ath_softc *sc = priv;
	struct ath_rate_priv *ath_rc_priv = priv_sta;
754
	const struct ath_rate_table *rate_table;
S
Sujith 已提交
755 756
	struct sk_buff *skb = txrc->skb;
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
S
Sujith 已提交
757
	struct ieee80211_tx_rate *rates = tx_info->control.rates;
758 759
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	__le16 fc = hdr->frame_control;
760
	u8 try_per_rate, i = 0, rix, nrix;
S
Sujith 已提交
761
	int is_probe = 0;
762

763 764 765
	if (rate_control_send_low(sta, priv_sta, txrc))
		return;

766 767 768 769 770 771 772 773 774 775 776 777
	/*
	 * For Multi Rate Retry we use a different number of
	 * retry attempt counts. This ends up looking like this:
	 *
	 * MRR[0] = 2
	 * MRR[1] = 2
	 * MRR[2] = 2
	 * MRR[3] = 4
	 *
	 */
	try_per_rate = sc->hw->max_rate_tries;

S
Sujith 已提交
778
	rate_table = sc->cur_rate_table;
779
	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
780 781
	nrix = rix;

S
Sujith 已提交
782
	if (is_probe) {
783 784
		/* set one try for probe rates. For the
		 * probes don't enable rts */
785
		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
S
Sujith 已提交
786
				       1, nrix, 0);
787 788 789 790

		/* Get the next tried/allowed rate. No RTS for the next series
		 * after the probe rate
		 */
791
		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
792
		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
S
Sujith 已提交
793
				       try_per_rate, nrix, 0);
794 795

		tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
796 797
	} else {
		/* Set the choosen rate. No RTS for first series entry. */
798
		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
S
Sujith 已提交
799
				       try_per_rate, nrix, 0);
800 801 802
	}

	/* Fill in the other rates for multirate retry */
S
Sujith 已提交
803
	for ( ; i < 4; i++) {
804 805 806 807
		/* Use twice the number of tries for the last MRR segment. */
		if (i + 1 == 4)
			try_per_rate = 4;

808
		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
809
		/* All other rates in the series have RTS enabled */
810
		ath_rc_rate_set_series(rate_table, &rates[i], txrc,
811
				       try_per_rate, nrix, 1);
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
	}

	/*
	 * NB:Change rate series to enable aggregation when operating
	 * at lower MCS rates. When first rate in series is MCS2
	 * in HT40 @ 2.4GHz, series should look like:
	 *
	 * {MCS2, MCS1, MCS0, MCS0}.
	 *
	 * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should
	 * look like:
	 *
	 * {MCS3, MCS2, MCS1, MCS1}
	 *
	 * So, set fourth rate in series to be same as third one for
	 * above conditions.
	 */
829
	if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
830
	    (conf_is_ht(&sc->hw->conf))) {
S
Sujith 已提交
831
		u8 dot11rate = rate_table->info[rix].dot11rate;
832 833 834
		u8 phy = rate_table->info[rix].phy;
		if (i == 4 &&
		    ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
S
Sujith 已提交
835
		     (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
S
Sujith 已提交
836 837
			rates[3].idx = rates[2].idx;
			rates[3].flags = rates[2].flags;
838 839
		}
	}
840 841 842 843 844 845 846 847

	/*
	 * Force hardware to use computed duration for next
	 * fragment by disabling multi-rate retry, which
	 * updates duration based on the multi-rate duration table.
	 *
	 * FIXME: Fix duration
	 */
848 849
	if (ieee80211_has_morefrags(fc) ||
	    (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
850 851 852 853 854 855 856
		rates[1].count = rates[2].count = rates[3].count = 0;
		rates[1].idx = rates[2].idx = rates[3].idx = 0;
		rates[0].count = ATH_TXMAXTRY;
	}

	/* Setup RTS/CTS */
	ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
857 858
}

S
Sujith 已提交
859
static bool ath_rc_update_per(struct ath_softc *sc,
860
			      const struct ath_rate_table *rate_table,
S
Sujith 已提交
861 862 863 864
			      struct ath_rate_priv *ath_rc_priv,
			      struct ath_tx_info_priv *tx_info_priv,
			      int tx_rate, int xretries, int retries,
			      u32 now_msec)
865
{
S
Sujith 已提交
866 867
	bool state_change = false;
	int count;
868 869 870 871 872 873 874 875 876 877 878 879 880 881
	u8 last_per;
	static u32 nretry_to_per_lookup[10] = {
		100 * 0 / 1,
		100 * 1 / 4,
		100 * 1 / 2,
		100 * 3 / 4,
		100 * 4 / 5,
		100 * 5 / 6,
		100 * 6 / 7,
		100 * 7 / 8,
		100 * 8 / 9,
		100 * 9 / 10
	};

882
	last_per = ath_rc_priv->per[tx_rate];
883 884 885

	if (xretries) {
		if (xretries == 1) {
886 887 888
			ath_rc_priv->per[tx_rate] += 30;
			if (ath_rc_priv->per[tx_rate] > 100)
				ath_rc_priv->per[tx_rate] = 100;
889 890
		} else {
			/* xretries == 2 */
891
			count = ARRAY_SIZE(nretry_to_per_lookup);
892 893
			if (retries >= count)
				retries = count - 1;
S
Sujith 已提交
894

895
			/* new_PER = 7/8*old_PER + 1/8*(currentPER) */
896
			ath_rc_priv->per[tx_rate] =
S
Sujith 已提交
897
				(u8)(last_per - (last_per >> 3) + (100 >> 3));
898 899 900 901
		}

		/* xretries == 1 or 2 */

902 903
		if (ath_rc_priv->probe_rate == tx_rate)
			ath_rc_priv->probe_rate = 0;
904

S
Sujith 已提交
905
	} else { /* xretries == 0 */
906
		count = ARRAY_SIZE(nretry_to_per_lookup);
907 908
		if (retries >= count)
			retries = count - 1;
S
Sujith 已提交
909

S
Sujith 已提交
910
		if (tx_info_priv->n_bad_frames) {
S
Sujith 已提交
911
			/* new_PER = 7/8*old_PER + 1/8*(currentPER)
912 913 914 915 916 917 918 919 920 921 922
			 * Assuming that n_frames is not 0.  The current PER
			 * from the retries is 100 * retries / (retries+1),
			 * since the first retries attempts failed, and the
			 * next one worked.  For the one that worked,
			 * n_bad_frames subframes out of n_frames wored,
			 * so the PER for that part is
			 * 100 * n_bad_frames / n_frames, and it contributes
			 * 100 * n_bad_frames / (n_frames * (retries+1)) to
			 * the above PER.  The expression below is a
			 * simplified version of the sum of these two terms.
			 */
S
Sujith 已提交
923 924 925 926 927 928 929 930 931
			if (tx_info_priv->n_frames > 0) {
				int n_frames, n_bad_frames;
				u8 cur_per, new_per;

				n_bad_frames = retries * tx_info_priv->n_frames +
					tx_info_priv->n_bad_frames;
				n_frames = tx_info_priv->n_frames * (retries + 1);
				cur_per = (100 * n_bad_frames / n_frames) >> 3;
				new_per = (u8)(last_per - (last_per >> 3) + cur_per);
932
				ath_rc_priv->per[tx_rate] = new_per;
S
Sujith 已提交
933
			}
934
		} else {
935
			ath_rc_priv->per[tx_rate] =
S
Sujith 已提交
936 937
				(u8)(last_per - (last_per >> 3) +
				     (nretry_to_per_lookup[retries] >> 3));
938 939 940 941 942 943 944
		}


		/*
		 * If we got at most one retry then increase the max rate if
		 * this was a probe.  Otherwise, ignore the probe.
		 */
945
		if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
S
Sujith 已提交
946 947
			if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
				tx_info_priv->n_frames) {
948 949 950 951 952 953 954
				/*
				 * Since we probed with just a single attempt,
				 * any retries means the probe failed.  Also,
				 * if the attempt worked, but more than half
				 * the subframes were bad then also consider
				 * the probe a failure.
				 */
955
				ath_rc_priv->probe_rate = 0;
956 957 958
			} else {
				u8 probe_rate = 0;

S
Sujith 已提交
959 960
				ath_rc_priv->rate_max_phy =
					ath_rc_priv->probe_rate;
961
				probe_rate = ath_rc_priv->probe_rate;
962

963 964
				if (ath_rc_priv->per[probe_rate] > 30)
					ath_rc_priv->per[probe_rate] = 20;
965

966
				ath_rc_priv->probe_rate = 0;
967 968 969 970 971 972 973

				/*
				 * Since this probe succeeded, we allow the next
				 * probe twice as soon.  This allows the maxRate
				 * to move up faster if the probes are
				 * succesful.
				 */
S
Sujith 已提交
974 975
				ath_rc_priv->probe_time =
					now_msec - rate_table->probe_interval / 2;
976 977 978 979 980 981 982 983
			}
		}

		if (retries > 0) {
			/*
			 * Don't update anything.  We don't know if
			 * this was because of collisions or poor signal.
			 */
984
			ath_rc_priv->hw_maxretry_pktcnt = 0;
985 986 987 988 989
		} else {
			/*
			 * It worked with no retries. First ignore bogus (small)
			 * rssi_ack values.
			 */
990 991 992
			if (tx_rate == ath_rc_priv->rate_max_phy &&
			    ath_rc_priv->hw_maxretry_pktcnt < 255) {
				ath_rc_priv->hw_maxretry_pktcnt++;
993 994 995 996
			}

		}
	}
997

S
Sujith 已提交
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
	return state_change;
}

/* Update PER, RSSI and whatever else that the code thinks it is doing.
   If you can make sense of all this, you really need to go out more. */

static void ath_rc_update_ht(struct ath_softc *sc,
			     struct ath_rate_priv *ath_rc_priv,
			     struct ath_tx_info_priv *tx_info_priv,
			     int tx_rate, int xretries, int retries)
{
	u32 now_msec = jiffies_to_msecs(jiffies);
	int rate;
	u8 last_per;
	bool state_change = false;
1013
	const struct ath_rate_table *rate_table = sc->cur_rate_table;
S
Sujith 已提交
1014 1015 1016 1017
	int size = ath_rc_priv->rate_table_size;

	if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
		return;
1018

1019
	last_per = ath_rc_priv->per[tx_rate];
S
Sujith 已提交
1020 1021 1022 1023 1024

	/* Update PER first */
	state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
					 tx_info_priv, tx_rate, xretries,
					 retries, now_msec);
1025 1026 1027 1028 1029

	/*
	 * If this rate looks bad (high PER) then stop using it for
	 * a while (except if we are probing).
	 */
1030
	if (ath_rc_priv->per[tx_rate] >= 55 && tx_rate > 0 &&
S
Sujith 已提交
1031
	    rate_table->info[tx_rate].ratekbps <=
1032
	    rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
1033 1034
		ath_rc_get_lower_rix(rate_table, ath_rc_priv,
				     (u8)tx_rate, &ath_rc_priv->rate_max_phy);
1035 1036

		/* Don't probe for a little while. */
1037
		ath_rc_priv->probe_time = now_msec;
1038 1039 1040 1041
	}

	/* Make sure the rates below this have lower PER */
	/* Monotonicity is kept only for rates below the current rate. */
1042
	if (ath_rc_priv->per[tx_rate] < last_per) {
1043 1044
		for (rate = tx_rate - 1; rate >= 0; rate--) {

1045 1046 1047 1048
			if (ath_rc_priv->per[rate] >
			    ath_rc_priv->per[rate+1]) {
				ath_rc_priv->per[rate] =
					ath_rc_priv->per[rate+1];
1049 1050 1051 1052 1053
			}
		}
	}

	/* Maintain monotonicity for rates above the current rate */
S
Sujith 已提交
1054
	for (rate = tx_rate; rate < size - 1; rate++) {
1055 1056 1057 1058
		if (ath_rc_priv->per[rate+1] <
		    ath_rc_priv->per[rate])
			ath_rc_priv->per[rate+1] =
				ath_rc_priv->per[rate];
1059 1060 1061 1062
	}

	/* Every so often, we reduce the thresholds
	 * and PER (different for CCK and OFDM). */
1063
	if (now_msec - ath_rc_priv->per_down_time >=
1064
	    rate_table->probe_interval) {
S
Sujith 已提交
1065
		for (rate = 0; rate < size; rate++) {
1066 1067
			ath_rc_priv->per[rate] =
				7 * ath_rc_priv->per[rate] / 8;
1068 1069
		}

1070
		ath_rc_priv->per_down_time = now_msec;
1071
	}
S
Sujith 已提交
1072

S
Sujith 已提交
1073
	ath_debug_stat_retries(sc, tx_rate, xretries, retries,
1074
			       ath_rc_priv->per[tx_rate]);
1075

S
Sujith 已提交
1076 1077
}

1078
static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
S
Sujith 已提交
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
				struct ieee80211_tx_rate *rate)
{
	int rix;

	if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
	    (rate->flags & IEEE80211_TX_RC_SHORT_GI))
		rix = rate_table->info[rate->idx].ht_index;
	else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
		rix = rate_table->info[rate->idx].sgi_index;
	else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
		rix = rate_table->info[rate->idx].cw40index;
	else
		rix = rate_table->info[rate->idx].base_index;

	return rix;
1094 1095
}

S
Sujith 已提交
1096 1097 1098 1099
static void ath_rc_tx_status(struct ath_softc *sc,
			     struct ath_rate_priv *ath_rc_priv,
			     struct ieee80211_tx_info *tx_info,
			     int final_ts_idx, int xretries, int long_retry)
1100
{
S
Sujith 已提交
1101
	struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
1102
	const struct ath_rate_table *rate_table;
S
Sujith 已提交
1103
	struct ieee80211_tx_rate *rates = tx_info->status.rates;
1104
	u8 flags;
S
Sujith 已提交
1105
	u32 i = 0, rix;
1106

S
Sujith 已提交
1107
	rate_table = sc->cur_rate_table;
1108 1109 1110 1111 1112 1113 1114

	/*
	 * If the first rate is not the final index, there
	 * are intermediate rate failures to be processed.
	 */
	if (final_ts_idx != 0) {
		/* Process intermediate rates that failed.*/
S
Sujith 已提交
1115 1116 1117 1118
		for (i = 0; i < final_ts_idx ; i++) {
			if (rates[i].count != 0 && (rates[i].idx >= 0)) {
				flags = rates[i].flags;

1119 1120
				/* If HT40 and we have switched mode from
				 * 40 to 20 => don't update */
S
Sujith 已提交
1121

S
Sujith 已提交
1122
				if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
S
Sujith 已提交
1123
				    !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1124
					return;
S
Sujith 已提交
1125

S
Sujith 已提交
1126
				rix = ath_rc_get_rateindex(rate_table, &rates[i]);
1127
				ath_rc_update_ht(sc, ath_rc_priv,
S
Sujith 已提交
1128
						tx_info_priv, rix,
1129
						xretries ? 1 : 2,
S
Sujith 已提交
1130
						rates[i].count);
1131 1132 1133 1134 1135 1136 1137 1138 1139
			}
		}
	} else {
		/*
		 * Handle the special case of MIMO PS burst, where the second
		 * aggregate is sent out with only one rate and one try.
		 * Treating it as an excessive retry penalizes the rate
		 * inordinately.
		 */
S
Sujith 已提交
1140
		if (rates[0].count == 1 && xretries == 1)
1141 1142 1143
			xretries = 2;
	}

S
Sujith 已提交
1144 1145
	flags = rates[i].flags;

1146
	/* If HT40 and we have switched mode from 40 to 20 => don't update */
S
Sujith 已提交
1147
	if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
S
Sujith 已提交
1148
	    !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1149 1150
		return;

S
Sujith 已提交
1151
	rix = ath_rc_get_rateindex(rate_table, &rates[i]);
S
Sujith 已提交
1152
	ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
S
Sujith 已提交
1153
			 xretries, long_retry);
1154 1155
}

1156 1157 1158 1159 1160
static const
struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
					     enum ieee80211_band band,
					     bool is_ht,
					     bool is_cw_40)
1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179
{
	int mode = 0;

	switch(band) {
	case IEEE80211_BAND_2GHZ:
		mode = ATH9K_MODE_11G;
		if (is_ht)
			mode = ATH9K_MODE_11NG_HT20;
		if (is_cw_40)
			mode = ATH9K_MODE_11NG_HT40PLUS;
		break;
	case IEEE80211_BAND_5GHZ:
		mode = ATH9K_MODE_11A;
		if (is_ht)
			mode = ATH9K_MODE_11NA_HT20;
		if (is_cw_40)
			mode = ATH9K_MODE_11NA_HT40PLUS;
		break;
	default:
S
Sujith 已提交
1180
		DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n");
1181 1182 1183 1184 1185
		return NULL;
	}

	BUG_ON(mode >= ATH9K_MODE_MAX);

S
Sujith 已提交
1186
	DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode);
1187 1188 1189
	return sc->hw_rate_table[mode];
}

1190
static void ath_rc_init(struct ath_softc *sc,
S
Sujith 已提交
1191
			struct ath_rate_priv *ath_rc_priv,
1192
			struct ieee80211_supported_band *sband,
1193
			struct ieee80211_sta *sta,
1194
			const struct ath_rate_table *rate_table)
1195
{
1196 1197
	struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
	u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
1198 1199
	u8 i, j, k, hi = 0, hthi = 0;

1200 1201 1202 1203
	if (!rate_table) {
		DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
		return;
	}
1204

1205 1206
	/* Initial rate table size. Will change depending
	 * on the working rate set */
S
Sujith 已提交
1207
	ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
1208 1209

	/* Initialize thresholds according to the global rate table */
1210
	for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
1211
		ath_rc_priv->per[i] = 0;
1212 1213 1214
	}

	/* Determine the valid rates */
1215
	ath_rc_init_valid_txmask(ath_rc_priv);
1216 1217 1218

	for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
		for (j = 0; j < MAX_TX_RATE_PHY; j++)
1219 1220
			ath_rc_priv->valid_phy_rateidx[i][j] = 0;
		ath_rc_priv->valid_phy_ratecnt[i] = 0;
1221 1222 1223 1224
	}

	if (!rateset->rs_nrates) {
		/* No working rate, just initialize valid rates */
S
Sujith 已提交
1225
		hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
1226
					    ath_rc_priv->ht_cap);
1227 1228
	} else {
		/* Use intersection of working rates and valid rates */
S
Sujith 已提交
1229
		hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
1230
					   rateset, ath_rc_priv->ht_cap);
1231
		if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
S
Sujith 已提交
1232
			hthi = ath_rc_setvalid_htrates(ath_rc_priv,
1233 1234 1235
						       rate_table,
						       ht_mcs,
						       ath_rc_priv->ht_cap);
1236 1237 1238 1239
		}
		hi = A_MAX(hi, hthi);
	}

1240 1241
	ath_rc_priv->rate_table_size = hi + 1;
	ath_rc_priv->rate_max_phy = 0;
S
Sujith 已提交
1242
	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
1243 1244

	for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1245 1246 1247
		for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
			ath_rc_priv->valid_rate_index[k++] =
				ath_rc_priv->valid_phy_rateidx[i][j];
1248 1249
		}

S
Sujith 已提交
1250
		if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1)
1251
		    || !ath_rc_priv->valid_phy_ratecnt[i])
1252 1253
			continue;

1254
		ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
1255
	}
S
Sujith 已提交
1256 1257
	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
	ASSERT(k <= RATE_TABLE_SIZE);
1258

1259 1260 1261
	ath_rc_priv->max_valid_rate = k;
	ath_rc_sort_validrates(rate_table, ath_rc_priv);
	ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
S
Sujith 已提交
1262
	sc->cur_rate_table = rate_table;
1263 1264 1265

	DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n",
		ath_rc_priv->ht_cap);
1266 1267
}

1268 1269
static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
			       bool is_cw40, bool is_sgi40)
1270 1271 1272
{
	u8 caps = 0;

1273
	if (sta->ht_cap.ht_supported) {
1274 1275
		caps = WLAN_RC_HT_FLAG;
		if (sc->sc_ah->caps.tx_chainmask != 1 &&
1276 1277 1278 1279
		    ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
			if (sta->ht_cap.mcs.rx_mask[1])
				caps |= WLAN_RC_DS_FLAG;
		}
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292
		if (is_cw40)
			caps |= WLAN_RC_40_FLAG;
		if (is_sgi40)
			caps |= WLAN_RC_SGI_FLAG;
	}

	return caps;
}

/***********************************/
/* mac80211 Rate Control callbacks */
/***********************************/

1293 1294
static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
			  struct ieee80211_sta *sta, void *priv_sta,
1295 1296 1297
			  struct sk_buff *skb)
{
	struct ath_softc *sc = priv;
S
Sujith 已提交
1298 1299
	struct ath_rate_priv *ath_rc_priv = priv_sta;
	struct ath_tx_info_priv *tx_info_priv = NULL;
1300 1301
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ieee80211_hdr *hdr;
S
Sujith 已提交
1302
	int final_ts_idx, tx_status = 0, is_underrun = 0;
1303 1304 1305 1306
	__le16 fc;

	hdr = (struct ieee80211_hdr *)skb->data;
	fc = hdr->frame_control;
S
Sujith 已提交
1307 1308
	tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
	final_ts_idx = tx_info_priv->tx.ts_rateindex;
1309

S
Sujith 已提交
1310
	if (!priv_sta || !ieee80211_is_data(fc) ||
1311
	    !tx_info_priv->update_rc)
S
Sujith 已提交
1312
		goto exit;
1313

S
Sujith 已提交
1314 1315
	if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
		goto exit;
1316

S
Sujith 已提交
1317 1318 1319
	/*
	 * If underrun error is seen assume it as an excessive retry only
	 * if prefetch trigger level have reached the max (0x3f for 5416)
1320
	 * Adjust the long retry as if the frame was tried hw->max_rate_tries
S
Sujith 已提交
1321 1322 1323 1324
	 * times. This affects how ratectrl updates PER for the failed rate.
	 */
	if (tx_info_priv->tx.ts_flags &
	    (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
1325
	    ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
S
Sujith 已提交
1326 1327 1328 1329 1330 1331 1332 1333 1334
		tx_status = 1;
		is_underrun = 1;
	}

	if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) ||
	    (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
		tx_status = 1;

	ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
1335
			 (is_underrun) ? sc->hw->max_rate_tries :
S
Sujith 已提交
1336 1337
			 tx_info_priv->tx.ts_longretry);

S
Sujith 已提交
1338
	/* Check if aggregation has to be enabled for this tid */
1339 1340
	if (conf_is_ht(&sc->hw->conf) &&
	    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
S
Sujith 已提交
1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
		if (ieee80211_is_data_qos(fc)) {
			u8 *qc, tid;
			struct ath_node *an;

			qc = ieee80211_get_qos_ctl(hdr);
			tid = qc[0] & 0xf;
			an = (struct ath_node *)sta->drv_priv;

			if(ath_tx_aggr_check(sc, an, tid))
				ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid);
		}
	}
1353 1354

	ath_debug_stat_rc(sc, skb);
S
Sujith 已提交
1355
exit:
1356
	kfree(tx_info_priv);
1357 1358
}

1359 1360
static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
                          struct ieee80211_sta *sta, void *priv_sta)
1361
{
1362
	struct ath_softc *sc = priv;
S
Sujith 已提交
1363
	struct ath_rate_priv *ath_rc_priv = priv_sta;
1364
	const struct ath_rate_table *rate_table = NULL;
1365
	bool is_cw40, is_sgi40;
1366 1367
	int i, j = 0;

S
Sujith 已提交
1368 1369 1370 1371 1372 1373 1374 1375
	for (i = 0; i < sband->n_bitrates; i++) {
		if (sta->supp_rates[sband->band] & BIT(i)) {
			ath_rc_priv->neg_rates.rs_rates[j]
				= (sband->bitrates[i].bitrate * 2) / 10;
			j++;
		}
	}
	ath_rc_priv->neg_rates.rs_nrates = j;
1376

1377
	if (sta->ht_cap.ht_supported) {
S
Sujith 已提交
1378
		for (i = 0, j = 0; i < 77; i++) {
J
Johannes Berg 已提交
1379
			if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
S
Sujith 已提交
1380
				ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
1381 1382 1383
			if (j == ATH_RATE_MAX)
				break;
		}
S
Sujith 已提交
1384
		ath_rc_priv->neg_ht_rates.rs_nrates = j;
1385
	}
S
Sujith 已提交
1386

1387 1388 1389 1390 1391 1392
	is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
	is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;

	/* Choose rate table first */

	if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
1393
	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
1394 1395 1396 1397 1398 1399 1400 1401 1402
	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
		rate_table = ath_choose_rate_table(sc, sband->band,
						   sta->ht_cap.ht_supported,
						   is_cw40);
	} else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
		/* cur_rate_table would be set on init through config() */
		rate_table = sc->cur_rate_table;
	}

1403
	ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
1404 1405 1406 1407 1408 1409 1410 1411 1412
	ath_rc_init(sc, priv_sta, sband, sta, rate_table);
}

static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
			    struct ieee80211_sta *sta, void *priv_sta,
			    u32 changed)
{
	struct ath_softc *sc = priv;
	struct ath_rate_priv *ath_rc_priv = priv_sta;
1413
	const struct ath_rate_table *rate_table = NULL;
1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436
	bool oper_cw40 = false, oper_sgi40;
	bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
		true : false;
	bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
		true : false;

	/* FIXME: Handle AP mode later when we support CWM */

	if (changed & IEEE80211_RC_HT_CHANGED) {
		if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
			return;

		if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
		    sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
			oper_cw40 = true;

		oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
			true : false;

		if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
			rate_table = ath_choose_rate_table(sc, sband->band,
						   sta->ht_cap.ht_supported,
						   oper_cw40);
1437
			ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
1438 1439 1440 1441 1442 1443 1444 1445
						   oper_cw40, oper_sgi40);
			ath_rc_init(sc, priv_sta, sband, sta, rate_table);

			DPRINTF(sc, ATH_DBG_CONFIG,
				"Operating HT Bandwidth changed to: %d\n",
				sc->hw->conf.channel_type);
		}
	}
1446 1447
}

1448
static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1449
{
1450 1451
	struct ath_wiphy *aphy = hw->priv;
	return aphy->sc;
1452 1453 1454 1455 1456 1457 1458
}

static void ath_rate_free(void *priv)
{
	return;
}

1459
static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
1460 1461
{
	struct ath_softc *sc = priv;
S
Sujith 已提交
1462
	struct ath_rate_priv *rate_priv;
1463

S
Sujith 已提交
1464
	rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
1465
	if (!rate_priv) {
S
Sujith 已提交
1466
		DPRINTF(sc, ATH_DBG_FATAL,
S
Sujith 已提交
1467
			"Unable to allocate private rc structure\n");
1468 1469
		return NULL;
	}
S
Sujith 已提交
1470

1471
	rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
S
Sujith 已提交
1472

1473 1474 1475
	return rate_priv;
}

1476 1477
static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
			      void *priv_sta)
1478
{
S
Sujith 已提交
1479
	struct ath_rate_priv *rate_priv = priv_sta;
S
Sujith 已提交
1480
	kfree(rate_priv);
1481 1482 1483 1484 1485 1486 1487 1488
}

static struct rate_control_ops ath_rate_ops = {
	.module = NULL,
	.name = "ath9k_rate_control",
	.tx_status = ath_tx_status,
	.get_rate = ath_get_rate,
	.rate_init = ath_rate_init,
1489
	.rate_update = ath_rate_update,
1490 1491 1492
	.alloc = ath_rate_alloc,
	.free = ath_rate_free,
	.alloc_sta = ath_rate_alloc_sta,
1493
	.free_sta = ath_rate_free_sta,
1494 1495
};

S
Sujith 已提交
1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515
void ath_rate_attach(struct ath_softc *sc)
{
	sc->hw_rate_table[ATH9K_MODE_11A] =
		&ar5416_11a_ratetable;
	sc->hw_rate_table[ATH9K_MODE_11G] =
		&ar5416_11g_ratetable;
	sc->hw_rate_table[ATH9K_MODE_11NA_HT20] =
		&ar5416_11na_ratetable;
	sc->hw_rate_table[ATH9K_MODE_11NG_HT20] =
		&ar5416_11ng_ratetable;
	sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
		&ar5416_11na_ratetable;
	sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
		&ar5416_11na_ratetable;
	sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
		&ar5416_11ng_ratetable;
	sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
		&ar5416_11ng_ratetable;
}

1516 1517 1518 1519 1520 1521 1522 1523 1524
int ath_rate_control_register(void)
{
	return ieee80211_rate_control_register(&ath_rate_ops);
}

void ath_rate_control_unregister(void)
{
	ieee80211_rate_control_unregister(&ath_rate_ops);
}