rc.c 45.3 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 },
S
Sujith 已提交
47
		{ VALID_20, VALID_20, 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 157
	},
	50,  /* probe interval */
	50,  /* rssi reduce 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 */

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

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

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

402
static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
S
Sujith 已提交
403
				   struct ath_rate_priv *ath_rc_priv)
404 405 406
{
	u8 i, j, idx, idx_next;

407
	for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
408
		for (j = 0; j <= i-1; j++) {
409 410
			idx = ath_rc_priv->valid_rate_index[j];
			idx_next = ath_rc_priv->valid_rate_index[j+1];
411 412 413

			if (rate_table->info[idx].ratekbps >
				rate_table->info[idx_next].ratekbps) {
414 415
				ath_rc_priv->valid_rate_index[j] = idx_next;
				ath_rc_priv->valid_rate_index[j+1] = idx;
416 417 418 419 420
			}
		}
	}
}

S
Sujith 已提交
421
static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
422 423 424
{
	u8 i;

425
	for (i = 0; i < ath_rc_priv->rate_table_size; i++)
S
Sujith 已提交
426
		ath_rc_priv->valid_rate_index[i] = 0;
427 428
}

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

436 437 438 439 440
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)
441 442 443
{
	u8 i;

444 445 446
	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 已提交
447
			return 1;
448 449 450 451 452
		}
	}

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

S
Sujith 已提交
454
	return 0;
455 456 457 458 459 460
}

/* Return true only for single stream */

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

static inline int
476 477 478
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)
479 480 481
{
	int8_t i;

482 483 484
	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 已提交
485
			return 1;
486 487
		}
	}
S
Sujith 已提交
488

S
Sujith 已提交
489
	return 0;
490 491
}

S
Sujith 已提交
492
static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
493
				 const struct ath_rate_table *rate_table,
S
Sujith 已提交
494
				 u32 capflag)
495 496 497 498 499
{
	u8 i, hi = 0;
	u32 valid;

	for (i = 0; i < rate_table->rate_cnt; i++) {
500
		valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
S
Sujith 已提交
501 502
			 rate_table->info[i].valid_single_stream :
			 rate_table->info[i].valid);
S
Sujith 已提交
503
		if (valid == 1) {
504 505 506
			u32 phy = rate_table->info[i].phy;
			u8 valid_rate_count = 0;

S
Sujith 已提交
507
			if (!ath_rc_valid_phyrate(phy, capflag, 0))
508 509
				continue;

510
			valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
511

512 513
			ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
			ath_rc_priv->valid_phy_ratecnt[phy] += 1;
S
Sujith 已提交
514
			ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
515 516 517
			hi = A_MAX(hi, i);
		}
	}
S
Sujith 已提交
518

519 520 521
	return hi;
}

S
Sujith 已提交
522
static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
523
				const struct ath_rate_table *rate_table,
S
Sujith 已提交
524 525
				struct ath_rateset *rateset,
				u32 capflag)
526 527 528 529 530 531 532
{
	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;
533 534 535
			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 已提交
536 537
			u8 rate = rateset->rs_rates[i];
			u8 dot11rate = rate_table->info[j].dot11rate;
538 539 540

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

S
Sujith 已提交
543 544 545 546
			if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
			    ((valid & WLAN_RC_CAP_MODE(capflag)) ==
			     WLAN_RC_CAP_MODE(capflag)) &&
			    !WLAN_RC_PHY_HT(phy)) {
547 548
				u8 valid_rate_count = 0;

S
Sujith 已提交
549
				if (!ath_rc_valid_phyrate(phy, capflag, 0))
550 551 552
					continue;

				valid_rate_count =
553
					ath_rc_priv->valid_phy_ratecnt[phy];
554

555
				ath_rc_priv->valid_phy_rateidx[phy]
556
					[valid_rate_count] = j;
557
				ath_rc_priv->valid_phy_ratecnt[phy] += 1;
S
Sujith 已提交
558
				ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
559 560 561 562
				hi = A_MAX(hi, j);
			}
		}
	}
S
Sujith 已提交
563

564 565 566
	return hi;
}

S
Sujith 已提交
567
static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
568
				  const struct ath_rate_table *rate_table,
S
Sujith 已提交
569
				  u8 *mcs_set, u32 capflag)
570
{
S
Sujith 已提交
571 572
	struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;

573 574 575
	u8 i, j, hi = 0;

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

S
Sujith 已提交
585
			if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
S
Sujith 已提交
586 587
			    !WLAN_RC_PHY_HT(phy) ||
			    !WLAN_RC_PHY_HT_VALID(valid, capflag))
588 589
				continue;

S
Sujith 已提交
590
			if (!ath_rc_valid_phyrate(phy, capflag, 0))
591 592
				continue;

593 594 595
			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 已提交
596
			ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
597 598 599 600
			hi = A_MAX(hi, j);
		}
	}

S
Sujith 已提交
601
	return hi;
602 603
}

604 605 606 607 608
/* 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)
609
{
610
	u32 best_thruput, this_thruput, now_msec;
611
	u8 rate, next_rate, best_rate, maxindex, minindex;
612
	int8_t index = 0;
613 614

	now_msec = jiffies_to_msecs(jiffies);
615
	*is_probing = 0;
616
	best_thruput = 0;
617
	maxindex = ath_rc_priv->max_valid_rate-1;
618 619 620 621 622 623 624 625 626 627
	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;

628 629
		rate = ath_rc_priv->valid_rate_index[index];
		if (rate > ath_rc_priv->rate_max_phy)
630 631 632 633 634 635 636 637 638 639 640 641 642
			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.
		 */
643
		per_thres = ath_rc_priv->state[rate].per;
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
		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 已提交
663
	if (rate >= ath_rc_priv->rate_max_phy) {
664
		rate = ath_rc_priv->rate_max_phy;
665 666 667

		/* Probe the next allowed phy state */
		if (ath_rc_get_nextvalid_txrate(rate_table,
S
Sujith 已提交
668
					ath_rc_priv, rate, &next_rate) &&
669
		    (now_msec - ath_rc_priv->probe_time >
670
		     rate_table->probe_interval) &&
671
		    (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
672
			rate = next_rate;
673 674 675
			ath_rc_priv->probe_rate = rate;
			ath_rc_priv->probe_time = now_msec;
			ath_rc_priv->hw_maxretry_pktcnt = 0;
S
Sujith 已提交
676
			*is_probing = 1;
677 678 679
		}
	}

680 681
	if (rate > (ath_rc_priv->rate_table_size - 1))
		rate = ath_rc_priv->rate_table_size - 1;
682

683 684 685 686 687 688 689 690 691 692 693 694
	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 &&
	    !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG));
		return rate;

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

	rate = ath_rc_priv->valid_rate_index[0];
695 696 697 698

	return rate;
}

699
static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
S
Sujith 已提交
700
				   struct ieee80211_tx_rate *rate,
701
				   struct ieee80211_tx_rate_control *txrc,
S
Sujith 已提交
702
				   u8 tries, u8 rix, int rtsctsenable)
703
{
S
Sujith 已提交
704 705 706
	rate->count = tries;
	rate->idx = rix;

707 708 709
	if (txrc->short_preamble)
		rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
	if (txrc->rts || rtsctsenable)
S
Sujith 已提交
710 711 712 713 714 715 716
		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;
717 718
}

719
static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
720
				   const struct ath_rate_table *rate_table,
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 749 750 751 752 753 754
				   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;
}

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

769 770 771
	if (rate_control_send_low(sta, priv_sta, txrc))
		return;

772 773 774 775 776 777 778 779 780 781 782 783
	/*
	 * 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 已提交
784
	rate_table = sc->cur_rate_table;
785
	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
786 787
	nrix = rix;

S
Sujith 已提交
788
	if (is_probe) {
789 790
		/* set one try for probe rates. For the
		 * probes don't enable rts */
791
		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
S
Sujith 已提交
792
				       1, nrix, 0);
793 794 795 796

		/* Get the next tried/allowed rate. No RTS for the next series
		 * after the probe rate
		 */
797
		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
798
		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
S
Sujith 已提交
799
				       try_per_rate, nrix, 0);
800 801

		tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
802 803
	} else {
		/* Set the choosen rate. No RTS for first series entry. */
804
		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
S
Sujith 已提交
805
				       try_per_rate, nrix, 0);
806 807 808
	}

	/* Fill in the other rates for multirate retry */
S
Sujith 已提交
809
	for ( ; i < 4; i++) {
810 811 812 813
		/* Use twice the number of tries for the last MRR segment. */
		if (i + 1 == 4)
			try_per_rate = 4;

814
		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
815
		/* All other rates in the series have RTS enabled */
816
		ath_rc_rate_set_series(rate_table, &rates[i], txrc,
817
				       try_per_rate, nrix, 1);
818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
	}

	/*
	 * 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.
	 */
835
	if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
836
	    (conf_is_ht(&sc->hw->conf))) {
S
Sujith 已提交
837
		u8 dot11rate = rate_table->info[rix].dot11rate;
838 839 840
		u8 phy = rate_table->info[rix].phy;
		if (i == 4 &&
		    ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
S
Sujith 已提交
841
		     (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
S
Sujith 已提交
842 843
			rates[3].idx = rates[2].idx;
			rates[3].flags = rates[2].flags;
844 845
		}
	}
846 847 848 849 850 851 852 853

	/*
	 * 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
	 */
854 855
	if (ieee80211_has_morefrags(fc) ||
	    (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
856 857 858 859 860 861 862
		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);
863 864
}

S
Sujith 已提交
865
static bool ath_rc_update_per(struct ath_softc *sc,
866
			      const struct ath_rate_table *rate_table,
S
Sujith 已提交
867 868 869 870
			      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)
871
{
S
Sujith 已提交
872 873
	bool state_change = false;
	int count;
874 875 876 877 878 879 880 881 882 883 884 885 886 887
	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
	};

888
	last_per = ath_rc_priv->state[tx_rate].per;
889 890 891

	if (xretries) {
		if (xretries == 1) {
892 893 894
			ath_rc_priv->state[tx_rate].per += 30;
			if (ath_rc_priv->state[tx_rate].per > 100)
				ath_rc_priv->state[tx_rate].per = 100;
895 896
		} else {
			/* xretries == 2 */
897
			count = ARRAY_SIZE(nretry_to_per_lookup);
898 899
			if (retries >= count)
				retries = count - 1;
S
Sujith 已提交
900

901
			/* new_PER = 7/8*old_PER + 1/8*(currentPER) */
902
			ath_rc_priv->state[tx_rate].per =
S
Sujith 已提交
903
				(u8)(last_per - (last_per >> 3) + (100 >> 3));
904 905 906 907
		}

		/* xretries == 1 or 2 */

908 909
		if (ath_rc_priv->probe_rate == tx_rate)
			ath_rc_priv->probe_rate = 0;
910

S
Sujith 已提交
911
	} else { /* xretries == 0 */
912
		count = ARRAY_SIZE(nretry_to_per_lookup);
913 914
		if (retries >= count)
			retries = count - 1;
S
Sujith 已提交
915

S
Sujith 已提交
916
		if (tx_info_priv->n_bad_frames) {
S
Sujith 已提交
917
			/* new_PER = 7/8*old_PER + 1/8*(currentPER)
918 919 920 921 922 923 924 925 926 927 928
			 * 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 已提交
929 930 931 932 933 934 935 936 937 938 939
			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);
				ath_rc_priv->state[tx_rate].per = new_per;
			}
940
		} else {
S
Sujith 已提交
941 942 943
			ath_rc_priv->state[tx_rate].per =
				(u8)(last_per - (last_per >> 3) +
				     (nretry_to_per_lookup[retries] >> 3));
944 945 946 947 948 949 950
		}


		/*
		 * If we got at most one retry then increase the max rate if
		 * this was a probe.  Otherwise, ignore the probe.
		 */
951
		if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
S
Sujith 已提交
952 953
			if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
				tx_info_priv->n_frames) {
954 955 956 957 958 959 960
				/*
				 * 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.
				 */
961
				ath_rc_priv->probe_rate = 0;
962 963 964
			} else {
				u8 probe_rate = 0;

S
Sujith 已提交
965 966
				ath_rc_priv->rate_max_phy =
					ath_rc_priv->probe_rate;
967
				probe_rate = ath_rc_priv->probe_rate;
968

969 970
				if (ath_rc_priv->state[probe_rate].per > 30)
					ath_rc_priv->state[probe_rate].per = 20;
971

972
				ath_rc_priv->probe_rate = 0;
973 974 975 976 977 978 979

				/*
				 * 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 已提交
980 981
				ath_rc_priv->probe_time =
					now_msec - rate_table->probe_interval / 2;
982 983 984 985 986 987 988 989
			}
		}

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

		}
	}
1003

S
Sujith 已提交
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
	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;
1019
	const struct ath_rate_table *rate_table = sc->cur_rate_table;
S
Sujith 已提交
1020 1021 1022 1023
	int size = ath_rc_priv->rate_table_size;

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

S
Sujith 已提交
1025 1026 1027 1028 1029 1030
	last_per = ath_rc_priv->state[tx_rate].per;

	/* Update PER first */
	state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
					 tx_info_priv, tx_rate, xretries,
					 retries, now_msec);
1031 1032 1033 1034 1035

	/*
	 * If this rate looks bad (high PER) then stop using it for
	 * a while (except if we are probing).
	 */
1036
	if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
S
Sujith 已提交
1037
	    rate_table->info[tx_rate].ratekbps <=
1038
	    rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
1039 1040
		ath_rc_get_lower_rix(rate_table, ath_rc_priv,
				     (u8)tx_rate, &ath_rc_priv->rate_max_phy);
1041 1042

		/* Don't probe for a little while. */
1043
		ath_rc_priv->probe_time = now_msec;
1044 1045 1046 1047
	}

	/* Make sure the rates below this have lower PER */
	/* Monotonicity is kept only for rates below the current rate. */
1048
	if (ath_rc_priv->state[tx_rate].per < last_per) {
1049 1050
		for (rate = tx_rate - 1; rate >= 0; rate--) {
			if (rate_table->info[rate].phy !=
S
Sujith 已提交
1051
			    rate_table->info[tx_rate].phy)
1052 1053
				break;

1054 1055 1056 1057
			if (ath_rc_priv->state[rate].per >
			    ath_rc_priv->state[rate+1].per) {
				ath_rc_priv->state[rate].per =
					ath_rc_priv->state[rate+1].per;
1058 1059 1060 1061 1062
			}
		}
	}

	/* Maintain monotonicity for rates above the current rate */
S
Sujith 已提交
1063 1064 1065
	for (rate = tx_rate; rate < size - 1; rate++) {
		if (ath_rc_priv->state[rate+1].per <
		    ath_rc_priv->state[rate].per)
1066 1067
			ath_rc_priv->state[rate+1].per =
				ath_rc_priv->state[rate].per;
1068 1069 1070 1071
	}

	/* Every so often, we reduce the thresholds
	 * and PER (different for CCK and OFDM). */
1072
	if (now_msec - ath_rc_priv->per_down_time >=
S
Sujith 已提交
1073
	    rate_table->rssi_reduce_interval) {
S
Sujith 已提交
1074
		for (rate = 0; rate < size; rate++) {
1075 1076
			ath_rc_priv->state[rate].per =
				7 * ath_rc_priv->state[rate].per / 8;
1077 1078
		}

1079
		ath_rc_priv->per_down_time = now_msec;
1080
	}
S
Sujith 已提交
1081

S
Sujith 已提交
1082 1083
	ath_debug_stat_retries(sc, tx_rate, xretries, retries,
			       ath_rc_priv->state[tx_rate].per);
1084

S
Sujith 已提交
1085 1086
}

1087
static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
S
Sujith 已提交
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
				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;
1103 1104
}

S
Sujith 已提交
1105 1106 1107 1108
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)
1109
{
S
Sujith 已提交
1110
	struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
1111
	const struct ath_rate_table *rate_table;
S
Sujith 已提交
1112
	struct ieee80211_tx_rate *rates = tx_info->status.rates;
1113
	u8 flags;
S
Sujith 已提交
1114
	u32 i = 0, rix;
1115

S
Sujith 已提交
1116
	rate_table = sc->cur_rate_table;
1117 1118 1119 1120 1121 1122 1123

	/*
	 * 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 已提交
1124 1125 1126 1127
		for (i = 0; i < final_ts_idx ; i++) {
			if (rates[i].count != 0 && (rates[i].idx >= 0)) {
				flags = rates[i].flags;

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

S
Sujith 已提交
1131
				if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
S
Sujith 已提交
1132
				    !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1133
					return;
S
Sujith 已提交
1134

S
Sujith 已提交
1135
				rix = ath_rc_get_rateindex(rate_table, &rates[i]);
1136
				ath_rc_update_ht(sc, ath_rc_priv,
S
Sujith 已提交
1137
						tx_info_priv, rix,
1138
						xretries ? 1 : 2,
S
Sujith 已提交
1139
						rates[i].count);
1140 1141 1142 1143 1144 1145 1146 1147 1148
			}
		}
	} 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 已提交
1149
		if (rates[0].count == 1 && xretries == 1)
1150 1151 1152
			xretries = 2;
	}

S
Sujith 已提交
1153 1154
	flags = rates[i].flags;

1155
	/* If HT40 and we have switched mode from 40 to 20 => don't update */
S
Sujith 已提交
1156
	if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
S
Sujith 已提交
1157
	    !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1158 1159
		return;

S
Sujith 已提交
1160
	rix = ath_rc_get_rateindex(rate_table, &rates[i]);
S
Sujith 已提交
1161
	ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
S
Sujith 已提交
1162
			 xretries, long_retry);
1163 1164
}

1165 1166 1167 1168 1169
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)
1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
{
	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 已提交
1189
		DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n");
1190 1191 1192 1193 1194
		return NULL;
	}

	BUG_ON(mode >= ATH9K_MODE_MAX);

S
Sujith 已提交
1195
	DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode);
1196 1197 1198
	return sc->hw_rate_table[mode];
}

1199
static void ath_rc_init(struct ath_softc *sc,
S
Sujith 已提交
1200
			struct ath_rate_priv *ath_rc_priv,
1201
			struct ieee80211_supported_band *sband,
1202
			struct ieee80211_sta *sta,
1203
			const struct ath_rate_table *rate_table)
1204
{
1205 1206
	struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
	u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
1207 1208
	u8 i, j, k, hi = 0, hthi = 0;

1209 1210 1211 1212
	if (!rate_table) {
		DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
		return;
	}
1213

1214 1215
	/* Initial rate table size. Will change depending
	 * on the working rate set */
S
Sujith 已提交
1216
	ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
1217 1218

	/* Initialize thresholds according to the global rate table */
1219
	for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
1220
		ath_rc_priv->state[i].per = 0;
1221 1222 1223
	}

	/* Determine the valid rates */
1224
	ath_rc_init_valid_txmask(ath_rc_priv);
1225 1226 1227

	for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
		for (j = 0; j < MAX_TX_RATE_PHY; j++)
1228 1229
			ath_rc_priv->valid_phy_rateidx[i][j] = 0;
		ath_rc_priv->valid_phy_ratecnt[i] = 0;
1230 1231 1232 1233
	}

	if (!rateset->rs_nrates) {
		/* No working rate, just initialize valid rates */
S
Sujith 已提交
1234
		hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
1235
					    ath_rc_priv->ht_cap);
1236 1237
	} else {
		/* Use intersection of working rates and valid rates */
S
Sujith 已提交
1238
		hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
1239
					   rateset, ath_rc_priv->ht_cap);
1240
		if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
S
Sujith 已提交
1241
			hthi = ath_rc_setvalid_htrates(ath_rc_priv,
1242 1243 1244
						       rate_table,
						       ht_mcs,
						       ath_rc_priv->ht_cap);
1245 1246 1247 1248
		}
		hi = A_MAX(hi, hthi);
	}

1249 1250
	ath_rc_priv->rate_table_size = hi + 1;
	ath_rc_priv->rate_max_phy = 0;
S
Sujith 已提交
1251
	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
1252 1253

	for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1254 1255 1256
		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];
1257 1258
		}

S
Sujith 已提交
1259
		if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1)
1260
		    || !ath_rc_priv->valid_phy_ratecnt[i])
1261 1262
			continue;

1263
		ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
1264
	}
S
Sujith 已提交
1265 1266
	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
	ASSERT(k <= RATE_TABLE_SIZE);
1267

1268 1269 1270
	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 已提交
1271
	sc->cur_rate_table = rate_table;
1272 1273 1274

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

1277 1278
static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
			       bool is_cw40, bool is_sgi40)
1279 1280 1281
{
	u8 caps = 0;

1282
	if (sta->ht_cap.ht_supported) {
1283 1284
		caps = WLAN_RC_HT_FLAG;
		if (sc->sc_ah->caps.tx_chainmask != 1 &&
1285 1286 1287 1288
		    ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
			if (sta->ht_cap.mcs.rx_mask[1])
				caps |= WLAN_RC_DS_FLAG;
		}
1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
		if (is_cw40)
			caps |= WLAN_RC_40_FLAG;
		if (is_sgi40)
			caps |= WLAN_RC_SGI_FLAG;
	}

	return caps;
}

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

1302 1303
static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
			  struct ieee80211_sta *sta, void *priv_sta,
1304 1305 1306
			  struct sk_buff *skb)
{
	struct ath_softc *sc = priv;
S
Sujith 已提交
1307 1308
	struct ath_rate_priv *ath_rc_priv = priv_sta;
	struct ath_tx_info_priv *tx_info_priv = NULL;
1309 1310
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ieee80211_hdr *hdr;
S
Sujith 已提交
1311
	int final_ts_idx, tx_status = 0, is_underrun = 0;
1312 1313 1314 1315
	__le16 fc;

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

S
Sujith 已提交
1319
	if (!priv_sta || !ieee80211_is_data(fc) ||
1320
	    !tx_info_priv->update_rc)
S
Sujith 已提交
1321
		goto exit;
1322

S
Sujith 已提交
1323 1324
	if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
		goto exit;
1325

S
Sujith 已提交
1326 1327 1328
	/*
	 * If underrun error is seen assume it as an excessive retry only
	 * if prefetch trigger level have reached the max (0x3f for 5416)
1329
	 * Adjust the long retry as if the frame was tried hw->max_rate_tries
S
Sujith 已提交
1330 1331 1332 1333
	 * 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) &&
1334
	    ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
S
Sujith 已提交
1335 1336 1337 1338 1339 1340 1341 1342 1343
		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,
1344
			 (is_underrun) ? sc->hw->max_rate_tries :
S
Sujith 已提交
1345 1346
			 tx_info_priv->tx.ts_longretry);

S
Sujith 已提交
1347
	/* Check if aggregation has to be enabled for this tid */
1348 1349
	if (conf_is_ht(&sc->hw->conf) &&
	    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
S
Sujith 已提交
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361
		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);
		}
	}
1362 1363

	ath_debug_stat_rc(sc, skb);
S
Sujith 已提交
1364
exit:
1365
	kfree(tx_info_priv);
1366 1367
}

1368 1369
static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
                          struct ieee80211_sta *sta, void *priv_sta)
1370
{
1371
	struct ath_softc *sc = priv;
S
Sujith 已提交
1372
	struct ath_rate_priv *ath_rc_priv = priv_sta;
1373
	const struct ath_rate_table *rate_table = NULL;
1374
	bool is_cw40, is_sgi40;
1375 1376
	int i, j = 0;

S
Sujith 已提交
1377 1378 1379 1380 1381 1382 1383 1384
	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;
1385

1386
	if (sta->ht_cap.ht_supported) {
S
Sujith 已提交
1387
		for (i = 0, j = 0; i < 77; i++) {
J
Johannes Berg 已提交
1388
			if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
S
Sujith 已提交
1389
				ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
1390 1391 1392
			if (j == ATH_RATE_MAX)
				break;
		}
S
Sujith 已提交
1393
		ath_rc_priv->neg_ht_rates.rs_nrates = j;
1394
	}
S
Sujith 已提交
1395

1396 1397 1398 1399 1400 1401
	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) ||
1402
	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
1403 1404 1405 1406 1407 1408 1409 1410 1411
	    (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;
	}

1412
	ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
1413 1414 1415 1416 1417 1418 1419 1420 1421
	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;
1422
	const struct ath_rate_table *rate_table = NULL;
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445
	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);
1446
			ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
1447 1448 1449 1450 1451 1452 1453 1454
						   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);
		}
	}
1455 1456
}

1457
static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1458
{
1459 1460
	struct ath_wiphy *aphy = hw->priv;
	return aphy->sc;
1461 1462 1463 1464 1465 1466 1467
}

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

1468
static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
1469 1470
{
	struct ath_softc *sc = priv;
S
Sujith 已提交
1471
	struct ath_rate_priv *rate_priv;
1472

S
Sujith 已提交
1473
	rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
1474
	if (!rate_priv) {
S
Sujith 已提交
1475
		DPRINTF(sc, ATH_DBG_FATAL,
S
Sujith 已提交
1476
			"Unable to allocate private rc structure\n");
1477 1478
		return NULL;
	}
S
Sujith 已提交
1479

1480
	rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
S
Sujith 已提交
1481

1482 1483 1484
	return rate_priv;
}

1485 1486
static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
			      void *priv_sta)
1487
{
S
Sujith 已提交
1488
	struct ath_rate_priv *rate_priv = priv_sta;
S
Sujith 已提交
1489
	kfree(rate_priv);
1490 1491 1492 1493 1494 1495 1496 1497
}

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,
1498
	.rate_update = ath_rate_update,
1499 1500 1501
	.alloc = ath_rate_alloc,
	.free = ath_rate_free,
	.alloc_sta = ath_rate_alloc_sta,
1502
	.free_sta = ath_rate_free_sta,
1503 1504
};

S
Sujith 已提交
1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
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;
}

1525 1526 1527 1528 1529 1530 1531 1532 1533
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);
}