rc.c 50.4 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 25
			5400, 0x0b, 0x00, 12,
			0, 2, 1, 0, 0, 0, 0, 0 },
S
Sujith 已提交
26
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
27 28
			7800,  0x0f, 0x00, 18,
			0, 3, 1, 1, 1, 1, 1, 0 },
S
Sujith 已提交
29
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
30 31
			10000, 0x0a, 0x00, 24,
			2, 4, 2, 2, 2, 2, 2, 0 },
S
Sujith 已提交
32
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
33 34
			13900, 0x0e, 0x00, 36,
			2, 6,  2, 3, 3, 3, 3, 0 },
S
Sujith 已提交
35
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
36 37
			17300, 0x09, 0x00, 48,
			4, 10, 3, 4, 4, 4, 4, 0 },
S
Sujith 已提交
38
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
39 40
			23000, 0x0d, 0x00, 72,
			4, 14, 3, 5, 5, 5, 5, 0 },
S
Sujith 已提交
41
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
42 43
			27400, 0x08, 0x00, 96,
			4, 20, 3, 6, 6, 6, 6, 0 },
S
Sujith 已提交
44
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
45 46
			29300, 0x0c, 0x00, 108,
			4, 23, 3, 7, 7, 7, 7, 0 },
S
Sujith 已提交
47
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
48 49
			6400, 0x80, 0x00, 0,
			0, 2, 3, 8, 24, 8, 24, 3216 },
S
Sujith 已提交
50
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
51 52
			12700, 0x81, 0x00, 1,
			2, 4, 3, 9, 25, 9, 25, 6434 },
S
Sujith 已提交
53
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
54 55
			18800, 0x82, 0x00, 2,
			2, 6, 3, 10, 26, 10, 26, 9650 },
S
Sujith 已提交
56
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
57 58
			25000, 0x83, 0x00, 3,
			4, 10, 3, 11, 27, 11, 27, 12868 },
S
Sujith 已提交
59
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
60 61
			36700, 0x84, 0x00, 4,
			4, 14, 3, 12, 28, 12, 28, 19304 },
S
Sujith 已提交
62
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
63 64
			48100, 0x85, 0x00, 5,
			4, 20, 3, 13, 29, 13, 29, 25740 },
S
Sujith 已提交
65
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
66 67
			53500, 0x86, 0x00, 6,
			4, 23, 3, 14, 30, 14, 30,  28956 },
S
Sujith 已提交
68
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
69 70
			59000, 0x87, 0x00, 7,
			4, 25, 3, 15, 31, 15, 32, 32180 },
S
Sujith 已提交
71
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
72 73
			12700, 0x88, 0x00,
			8, 0, 2, 3, 16, 33, 16, 33, 6430 },
S
Sujith 已提交
74
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
75 76
			24800, 0x89, 0x00, 9,
			2, 4, 3, 17, 34, 17, 34, 12860 },
S
Sujith 已提交
77
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
78 79
			36600, 0x8a, 0x00, 10,
			2, 6, 3, 18, 35, 18, 35, 19300 },
S
Sujith 已提交
80
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
81 82
			48100, 0x8b, 0x00, 11,
			4, 10, 3, 19, 36, 19, 36, 25736 },
S
Sujith 已提交
83
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
84 85
			69500, 0x8c, 0x00, 12,
			4, 14, 3, 20, 37, 20, 37, 38600 },
S
Sujith 已提交
86
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
87 88
			89500, 0x8d, 0x00, 13,
			4, 20, 3, 21, 38, 21, 38, 51472 },
S
Sujith 已提交
89
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
90 91
			98900, 0x8e, 0x00, 14,
			4, 23, 3, 22, 39, 22, 39, 57890 },
S
Sujith 已提交
92
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
93 94
			108300, 0x8f, 0x00, 15,
			4, 25, 3, 23, 40, 23, 41, 64320 },
S
Sujith 已提交
95
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
96 97
			13200, 0x80, 0x00, 0,
			0, 2, 3, 8, 24, 24, 24, 6684 },
S
Sujith 已提交
98
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
99 100
			25900, 0x81, 0x00, 1,
			2, 4, 3, 9, 25, 25, 25, 13368 },
S
Sujith 已提交
101
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
102 103
			38600, 0x82, 0x00, 2,
			2, 6, 3, 10, 26, 26, 26, 20052 },
S
Sujith 已提交
104
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
105 106
			49800, 0x83, 0x00, 3,
			4, 10, 3, 11, 27, 27, 27, 26738 },
S
Sujith 已提交
107
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
108 109
			72200, 0x84, 0x00, 4,
			4, 14, 3, 12, 28, 28, 28, 40104 },
S
Sujith 已提交
110
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
111 112
			92900, 0x85, 0x00, 5,
			4, 20, 3, 13, 29, 29, 29, 53476 },
S
Sujith 已提交
113
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
114 115
			102700, 0x86, 0x00, 6,
			4, 23, 3, 14, 30, 30, 30, 60156 },
S
Sujith 已提交
116
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
117 118
			112000, 0x87, 0x00, 7,
			4, 25, 3, 15, 31, 32, 32, 66840 },
S
Sujith 已提交
119
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
120 121
			122000, 0x87, 0x00, 7,
			4, 25, 3, 15, 31, 32, 32, 74200 },
S
Sujith 已提交
122
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
123 124
			25800, 0x88, 0x00, 8,
			0, 2, 3, 16, 33, 33, 33, 13360 },
S
Sujith 已提交
125
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
126 127
			49800, 0x89, 0x00, 9,
			2, 4, 3, 17, 34, 34, 34, 26720 },
S
Sujith 已提交
128
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
129 130
			71900, 0x8a, 0x00, 10,
			2, 6, 3, 18, 35, 35, 35, 40080 },
S
Sujith 已提交
131
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
132 133
			92500, 0x8b, 0x00, 11,
			4, 10, 3, 19, 36, 36, 36, 53440 },
S
Sujith 已提交
134
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
135 136
			130300, 0x8c, 0x00, 12,
			4, 14, 3, 20, 37, 37, 37, 80160 },
S
Sujith 已提交
137
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
138 139
			162800, 0x8d, 0x00, 13,
			4, 20, 3, 21, 38, 38, 38, 106880 },
S
Sujith 已提交
140
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
141 142
			178200, 0x8e, 0x00, 14,
			4, 23, 3, 22, 39, 39, 39, 120240 },
S
Sujith 已提交
143
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
144 145
			192100, 0x8f, 0x00, 15,
			4, 25, 3, 23, 40, 41, 41, 133600 },
S
Sujith 已提交
146
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
147 148 149 150 151 152 153 154 155 156 157
			207000, 0x8f, 0x00, 15,
			4, 25, 3, 23, 40, 41, 41, 148400 },
	},
	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 163
			900, 0x1b, 0x00, 2,
			0, 0, 1, 0, 0, 0, 0, 0 },
S
Sujith 已提交
164
		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
165 166
			1900, 0x1a, 0x04, 4,
			1, 1, 1, 1, 1, 1, 1, 0 },
S
Sujith 已提交
167
		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
168 169
			4900, 0x19, 0x04, 11,
			2, 2, 2, 2, 2, 2, 2, 0 },
S
Sujith 已提交
170
		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
171 172
			8100, 0x18, 0x04, 22,
			3, 3, 2, 3, 3, 3, 3, 0 },
S
Sujith 已提交
173
		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
174 175
			5400, 0x0b, 0x00, 12,
			4, 2, 1, 4, 4, 4, 4, 0 },
S
Sujith 已提交
176
		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
177 178
			7800, 0x0f, 0x00, 18,
			4, 3, 1, 5, 5, 5, 5, 0 },
S
Sujith 已提交
179
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
180 181
			10100, 0x0a, 0x00, 24,
			6, 4, 1, 6, 6, 6, 6, 0 },
S
Sujith 已提交
182
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
183 184
			14100,  0x0e, 0x00, 36,
			6, 6, 2, 7, 7, 7, 7, 0 },
S
Sujith 已提交
185
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
186 187
			17700, 0x09, 0x00, 48,
			8, 10, 3, 8, 8, 8, 8, 0 },
S
Sujith 已提交
188
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
189 190
			23700, 0x0d, 0x00, 72,
			8, 14, 3, 9, 9, 9, 9, 0 },
S
Sujith 已提交
191
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
192 193
			27400, 0x08, 0x00, 96,
			8, 20, 3, 10, 10, 10, 10, 0 },
S
Sujith 已提交
194
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
195 196
			30900, 0x0c, 0x00, 108,
			8, 23, 3, 11, 11, 11, 11, 0 },
S
Sujith 已提交
197
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
198 199
			6400, 0x80, 0x00, 0,
			4, 2, 3, 12, 28, 12, 28, 3216 },
S
Sujith 已提交
200
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
201 202
			12700, 0x81, 0x00, 1,
			6, 4, 3, 13, 29, 13, 29, 6434 },
S
Sujith 已提交
203
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
204 205
			18800, 0x82, 0x00, 2,
			6, 6, 3, 14, 30, 14, 30, 9650 },
S
Sujith 已提交
206
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
207 208
			25000, 0x83, 0x00, 3,
			8, 10, 3, 15, 31, 15, 31, 12868 },
S
Sujith 已提交
209
		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
210 211
			36700, 0x84, 0x00, 4,
			8, 14, 3, 16, 32, 16, 32, 19304 },
S
Sujith 已提交
212
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
213 214
			48100, 0x85, 0x00, 5,
			8, 20, 3, 17, 33, 17, 33, 25740 },
S
Sujith 已提交
215
		{ INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
216 217
			53500, 0x86, 0x00, 6,
			8, 23, 3, 18, 34, 18, 34, 28956 },
S
Sujith 已提交
218
		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
219 220
			59000, 0x87, 0x00, 7,
			8, 25, 3, 19, 35, 19, 36, 32180 },
S
Sujith 已提交
221
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
222 223
			12700, 0x88, 0x00, 8,
			4, 2, 3, 20, 37, 20, 37, 6430 },
S
Sujith 已提交
224
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
225 226
			24800, 0x89, 0x00, 9,
			6, 4, 3, 21, 38, 21, 38, 12860 },
S
Sujith 已提交
227
		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
228 229
			36600, 0x8a, 0x00, 10,
			6, 6, 3, 22, 39, 22, 39, 19300 },
S
Sujith 已提交
230
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
231 232
			48100, 0x8b, 0x00, 11,
			8, 10, 3, 23, 40, 23, 40, 25736 },
S
Sujith 已提交
233
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
234 235
			69500, 0x8c, 0x00, 12,
			8, 14, 3, 24, 41, 24, 41, 38600 },
S
Sujith 已提交
236
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
237 238
			89500, 0x8d, 0x00, 13,
			8, 20, 3, 25, 42, 25, 42, 51472 },
S
Sujith 已提交
239
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
240 241
			98900, 0x8e, 0x00, 14,
			8, 23, 3, 26, 43, 26, 44, 57890 },
S
Sujith 已提交
242
		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
243 244
			108300, 0x8f, 0x00, 15,
			8, 25, 3, 27, 44, 27, 45, 64320 },
S
Sujith 已提交
245
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
246 247
			13200, 0x80, 0x00, 0,
			8, 2, 3, 12, 28, 28, 28, 6684 },
S
Sujith 已提交
248
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
249 250
			25900, 0x81, 0x00, 1,
			8, 4, 3, 13, 29, 29, 29, 13368 },
S
Sujith 已提交
251
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
252 253
			38600, 0x82, 0x00, 2,
			8, 6, 3, 14, 30, 30, 30, 20052 },
S
Sujith 已提交
254
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
255 256
			49800, 0x83, 0x00, 3,
			8, 10, 3, 15, 31, 31, 31, 26738 },
S
Sujith 已提交
257
		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
258 259
			72200, 0x84, 0x00, 4,
			8, 14, 3, 16, 32, 32, 32, 40104 },
S
Sujith 已提交
260
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
261 262
			92900, 0x85, 0x00, 5,
			8, 20, 3, 17, 33, 33, 33, 53476 },
S
Sujith 已提交
263
		{ INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
264 265
			102700, 0x86, 0x00, 6,
			8, 23, 3, 18, 34, 34, 34, 60156 },
S
Sujith 已提交
266
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
267 268
			112000, 0x87, 0x00, 7,
			8, 23, 3, 19, 35, 36, 36, 66840 },
S
Sujith 已提交
269
		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
270 271
			122000, 0x87, 0x00, 7,
			8, 25, 3, 19, 35, 36, 36, 74200 },
S
Sujith 已提交
272
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
273 274
			25800, 0x88, 0x00, 8,
			8, 2, 3, 20, 37, 37, 37, 13360 },
S
Sujith 已提交
275
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
276 277
			49800, 0x89, 0x00, 9,
			8, 4, 3, 21, 38, 38, 38, 26720 },
S
Sujith 已提交
278
		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
279 280
			71900, 0x8a, 0x00, 10,
			8, 6, 3, 22, 39, 39, 39, 40080 },
S
Sujith 已提交
281
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
282 283
			92500, 0x8b, 0x00, 11,
			8, 10, 3, 23, 40, 40, 40, 53440 },
S
Sujith 已提交
284
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
285 286
			130300, 0x8c, 0x00, 12,
			8, 14, 3, 24, 41, 41, 41, 80160 },
S
Sujith 已提交
287
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
288 289
			162800, 0x8d, 0x00, 13,
			8, 20, 3, 25, 42, 42, 42, 106880 },
S
Sujith 已提交
290
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
291 292
			178200, 0x8e, 0x00, 14,
			8, 23, 3, 26, 43, 43, 43, 120240 },
S
Sujith 已提交
293
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
294 295
			192100, 0x8f, 0x00, 15,
			8, 23, 3, 27, 44, 45, 45, 133600 },
S
Sujith 已提交
296
		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
297 298 299 300 301 302 303 304
			207000, 0x8f, 0x00, 15,
			8, 25, 3, 27, 44, 45, 45, 148400 },
		},
	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 310
			5400, 0x0b, 0x00, (0x80|12),
			0, 2, 1, 0, 0 },
S
Sujith 已提交
311
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
312 313
			7800, 0x0f, 0x00, 18,
			0, 3, 1, 1, 0 },
S
Sujith 已提交
314
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
315 316
			10000, 0x0a, 0x00, (0x80|24),
			2, 4, 2, 2, 0 },
S
Sujith 已提交
317
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
318 319
			13900, 0x0e, 0x00, 36,
			2, 6, 2, 3, 0 },
S
Sujith 已提交
320
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
321 322
			17300, 0x09, 0x00, (0x80|48),
			4, 10, 3, 4, 0 },
S
Sujith 已提交
323
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
324 325
			23000, 0x0d, 0x00, 72,
			4, 14, 3, 5, 0 },
S
Sujith 已提交
326
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
327 328
			27400, 0x08, 0x00, 96,
			4, 19, 3, 6, 0 },
S
Sujith 已提交
329
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
330 331 332 333 334 335 336 337
			29300, 0x0c, 0x00, 108,
			4, 23, 3, 7, 0 },
	},
	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 343
			900, 0x1b, 0x00, 2,
			0, 0, 1, 0, 0 },
S
Sujith 已提交
344
		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
345 346
			1900, 0x1a, 0x04, 4,
			1, 1, 1, 1, 0 },
S
Sujith 已提交
347
		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
348 349
			4900, 0x19, 0x04, 11,
			2, 2, 2, 2, 0 },
S
Sujith 已提交
350
		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
351 352
			8100, 0x18, 0x04, 22,
			3, 3, 2, 3, 0 },
S
Sujith 已提交
353
		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
354 355
			5400, 0x0b, 0x00, 12,
			4, 2, 1, 4, 0 },
S
Sujith 已提交
356
		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
357 358
			7800, 0x0f, 0x00, 18,
			4, 3, 1, 5, 0 },
S
Sujith 已提交
359
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
360 361
			10000, 0x0a, 0x00, 24,
			6, 4, 1, 6, 0 },
S
Sujith 已提交
362
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
363 364
			13900, 0x0e, 0x00, 36,
			6, 6, 2, 7, 0 },
S
Sujith 已提交
365
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
366 367
			17300, 0x09, 0x00, 48,
			8, 10, 3, 8, 0 },
S
Sujith 已提交
368
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
369 370
			23000, 0x0d, 0x00, 72,
			8, 14, 3, 9, 0 },
S
Sujith 已提交
371
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
372 373
			27400, 0x08, 0x00, 96,
			8, 19, 3, 10, 0 },
S
Sujith 已提交
374
		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
375 376 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
			29300, 0x0c, 0x00, 108,
			8, 23, 3, 11, 0 },
	},
	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 611 612 613
{
	u32 dt, best_thruput, this_thruput, now_msec;
	u8 rate, next_rate, best_rate, maxindex, minindex;
	int8_t  rssi_last, rssi_reduce = 0, index = 0;

S
Sujith 已提交
614
	*is_probing = 0;
615

616 617 618
	rssi_last = median(ath_rc_priv->rssi_last,
			   ath_rc_priv->rssi_last_prev,
			   ath_rc_priv->rssi_last_prev2);
619 620 621 622 623 624 625 626 627 628 629

	/*
	 * Age (reduce) last ack rssi based on how old it is.
	 * The bizarre numbers are so the delta is 160msec,
	 * meaning we divide by 16.
	 *   0msec   <= dt <= 25msec:   don't derate
	 *   25msec  <= dt <= 185msec:  derate linearly from 0 to 10dB
	 *   185msec <= dt:             derate by 10dB
	 */

	now_msec = jiffies_to_msecs(jiffies);
630
	dt = now_msec - ath_rc_priv->rssi_time;
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648

	if (dt >= 185)
		rssi_reduce = 10;
	else if (dt >= 25)
		rssi_reduce = (u8)((dt - 25) >> 4);

	/* Now reduce rssi_last by rssi_reduce */
	if (rssi_last < rssi_reduce)
		rssi_last = 0;
	else
		rssi_last -= rssi_reduce;

	/*
	 * Now look up the rate in the rssi table and return it.
	 * If no rates match then we return 0 (lowest rate)
	 */

	best_thruput = 0;
649
	maxindex = ath_rc_priv->max_valid_rate-1;
650 651 652 653 654 655 656 657 658 659 660

	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;

661 662
		rate = ath_rc_priv->valid_rate_index[index];
		if (rate > ath_rc_priv->rate_max_phy)
663 664 665 666 667 668 669 670 671 672 673 674 675
			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.
		 */
676
		per_thres = ath_rc_priv->state[rate].per;
677 678 679 680 681 682 683 684 685 686 687 688 689
		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;
690
	ath_rc_priv->rssi_last_lookup = rssi_last;
691 692 693 694 695 696

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

S
Sujith 已提交
697
	if (rate >= ath_rc_priv->rate_max_phy) {
698
		rate = ath_rc_priv->rate_max_phy;
699 700 701

		/* Probe the next allowed phy state */
		if (ath_rc_get_nextvalid_txrate(rate_table,
S
Sujith 已提交
702
					ath_rc_priv, rate, &next_rate) &&
703
		    (now_msec - ath_rc_priv->probe_time >
704
		     rate_table->probe_interval) &&
705
		    (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
706
			rate = next_rate;
707 708 709
			ath_rc_priv->probe_rate = rate;
			ath_rc_priv->probe_time = now_msec;
			ath_rc_priv->hw_maxretry_pktcnt = 0;
S
Sujith 已提交
710
			*is_probing = 1;
711 712 713
		}
	}

714 715
	if (rate > (ath_rc_priv->rate_table_size - 1))
		rate = ath_rc_priv->rate_table_size - 1;
716

717 718 719 720 721 722 723 724 725 726 727 728
	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];
729 730 731 732

	return rate;
}

733
static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
S
Sujith 已提交
734
				   struct ieee80211_tx_rate *rate,
735
				   struct ieee80211_tx_rate_control *txrc,
S
Sujith 已提交
736
				   u8 tries, u8 rix, int rtsctsenable)
737
{
S
Sujith 已提交
738 739 740
	rate->count = tries;
	rate->idx = rix;

741 742 743
	if (txrc->short_preamble)
		rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
	if (txrc->rts || rtsctsenable)
S
Sujith 已提交
744 745 746 747 748 749 750
		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;
751 752
}

753
static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
754
				   const struct ath_rate_table *rate_table,
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
				   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;
}

789 790
static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
			 struct ieee80211_tx_rate_control *txrc)
791
{
792 793
	struct ath_softc *sc = priv;
	struct ath_rate_priv *ath_rc_priv = priv_sta;
794
	const struct ath_rate_table *rate_table;
S
Sujith 已提交
795 796
	struct sk_buff *skb = txrc->skb;
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
S
Sujith 已提交
797
	struct ieee80211_tx_rate *rates = tx_info->control.rates;
798 799
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	__le16 fc = hdr->frame_control;
800
	u8 try_per_rate, i = 0, rix, nrix;
S
Sujith 已提交
801
	int is_probe = 0;
802

803 804 805
	if (rate_control_send_low(sta, priv_sta, txrc))
		return;

806 807 808 809 810 811 812 813 814 815 816 817
	/*
	 * 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 已提交
818
	rate_table = sc->cur_rate_table;
819
	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
820 821
	nrix = rix;

S
Sujith 已提交
822
	if (is_probe) {
823 824
		/* set one try for probe rates. For the
		 * probes don't enable rts */
825
		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
S
Sujith 已提交
826
				       1, nrix, 0);
827 828 829 830

		/* Get the next tried/allowed rate. No RTS for the next series
		 * after the probe rate
		 */
831
		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
832
		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
S
Sujith 已提交
833
				       try_per_rate, nrix, 0);
834 835

		tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
836 837
	} else {
		/* Set the choosen rate. No RTS for first series entry. */
838
		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
S
Sujith 已提交
839
				       try_per_rate, nrix, 0);
840 841 842
	}

	/* Fill in the other rates for multirate retry */
S
Sujith 已提交
843
	for ( ; i < 4; i++) {
844 845 846 847
		/* Use twice the number of tries for the last MRR segment. */
		if (i + 1 == 4)
			try_per_rate = 4;

848
		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
849
		/* All other rates in the series have RTS enabled */
850
		ath_rc_rate_set_series(rate_table, &rates[i], txrc,
851
				       try_per_rate, nrix, 1);
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868
	}

	/*
	 * 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.
	 */
869
	if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
870
	    (conf_is_ht(&sc->hw->conf))) {
S
Sujith 已提交
871
		u8 dot11rate = rate_table->info[rix].dot11rate;
872 873 874
		u8 phy = rate_table->info[rix].phy;
		if (i == 4 &&
		    ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
S
Sujith 已提交
875
		     (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
S
Sujith 已提交
876 877
			rates[3].idx = rates[2].idx;
			rates[3].flags = rates[2].flags;
878 879
		}
	}
880 881 882 883 884 885 886 887

	/*
	 * 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
	 */
888 889
	if (ieee80211_has_morefrags(fc) ||
	    (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
890 891 892 893 894 895 896
		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);
897 898
}

S
Sujith 已提交
899
static bool ath_rc_update_per(struct ath_softc *sc,
900
			      const struct ath_rate_table *rate_table,
S
Sujith 已提交
901 902 903 904
			      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)
905
{
S
Sujith 已提交
906 907
	bool state_change = false;
	int count;
908 909 910 911 912 913 914 915 916 917 918 919 920 921
	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
	};

922
	last_per = ath_rc_priv->state[tx_rate].per;
923 924 925

	if (xretries) {
		if (xretries == 1) {
926 927 928
			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;
929 930
		} else {
			/* xretries == 2 */
931
			count = ARRAY_SIZE(nretry_to_per_lookup);
932 933
			if (retries >= count)
				retries = count - 1;
S
Sujith 已提交
934

935
			/* new_PER = 7/8*old_PER + 1/8*(currentPER) */
936
			ath_rc_priv->state[tx_rate].per =
S
Sujith 已提交
937
				(u8)(last_per - (last_per >> 3) + (100 >> 3));
938 939 940 941
		}

		/* xretries == 1 or 2 */

942 943
		if (ath_rc_priv->probe_rate == tx_rate)
			ath_rc_priv->probe_rate = 0;
944

S
Sujith 已提交
945
	} else { /* xretries == 0 */
946
		count = ARRAY_SIZE(nretry_to_per_lookup);
947 948
		if (retries >= count)
			retries = count - 1;
S
Sujith 已提交
949

S
Sujith 已提交
950
		if (tx_info_priv->n_bad_frames) {
S
Sujith 已提交
951
			/* new_PER = 7/8*old_PER + 1/8*(currentPER)
952 953 954 955 956 957 958 959 960 961 962
			 * 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 已提交
963 964 965 966 967 968 969 970 971 972 973
			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;
			}
974
		} else {
S
Sujith 已提交
975 976 977
			ath_rc_priv->state[tx_rate].per =
				(u8)(last_per - (last_per >> 3) +
				     (nretry_to_per_lookup[retries] >> 3));
978 979
		}

980 981
		ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
		ath_rc_priv->rssi_last_prev  = ath_rc_priv->rssi_last;
S
Sujith 已提交
982
		ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi;
983
		ath_rc_priv->rssi_time = now_msec;
984 985 986 987 988

		/*
		 * If we got at most one retry then increase the max rate if
		 * this was a probe.  Otherwise, ignore the probe.
		 */
989
		if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
S
Sujith 已提交
990 991
			if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
				tx_info_priv->n_frames) {
992 993 994 995 996 997 998
				/*
				 * 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.
				 */
999
				ath_rc_priv->probe_rate = 0;
1000 1001 1002
			} else {
				u8 probe_rate = 0;

S
Sujith 已提交
1003 1004
				ath_rc_priv->rate_max_phy =
					ath_rc_priv->probe_rate;
1005
				probe_rate = ath_rc_priv->probe_rate;
1006

1007 1008
				if (ath_rc_priv->state[probe_rate].per > 30)
					ath_rc_priv->state[probe_rate].per = 20;
1009

1010
				ath_rc_priv->probe_rate = 0;
1011 1012 1013 1014 1015 1016 1017

				/*
				 * 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 已提交
1018 1019
				ath_rc_priv->probe_time =
					now_msec - rate_table->probe_interval / 2;
1020 1021 1022 1023 1024 1025 1026 1027 1028
			}
		}

		if (retries > 0) {
			/*
			 * Don't update anything.  We don't know if
			 * this was because of collisions or poor signal.
			 *
			 * Later: if rssi_ack is close to
1029
			 * ath_rc_priv->state[txRate].rssi_thres and we see lots
1030
			 * of retries, then we could increase
1031
			 * ath_rc_priv->state[txRate].rssi_thres.
1032
			 */
1033
			ath_rc_priv->hw_maxretry_pktcnt = 0;
1034
		} else {
S
Sujith 已提交
1035 1036 1037 1038
			int32_t rssi_ackAvg;
			int8_t rssi_thres;
			int8_t rssi_ack_vmin;

1039 1040 1041 1042
			/*
			 * It worked with no retries. First ignore bogus (small)
			 * rssi_ack values.
			 */
1043 1044 1045
			if (tx_rate == ath_rc_priv->rate_max_phy &&
			    ath_rc_priv->hw_maxretry_pktcnt < 255) {
				ath_rc_priv->hw_maxretry_pktcnt++;
1046 1047
			}

S
Sujith 已提交
1048 1049 1050
			if (tx_info_priv->tx.ts_rssi <
			    rate_table->info[tx_rate].rssi_ack_validmin)
				goto exit;
1051

S
Sujith 已提交
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
			/* Average the rssi */
			if (tx_rate != ath_rc_priv->rssi_sum_rate) {
				ath_rc_priv->rssi_sum_rate = tx_rate;
				ath_rc_priv->rssi_sum =
					ath_rc_priv->rssi_sum_cnt = 0;
			}

			ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
			ath_rc_priv->rssi_sum_cnt++;

			if (ath_rc_priv->rssi_sum_cnt < 4)
				goto exit;

			rssi_ackAvg =
				(ath_rc_priv->rssi_sum + 2) / 4;
			rssi_thres =
				ath_rc_priv->state[tx_rate].rssi_thres;
			rssi_ack_vmin =
				rate_table->info[tx_rate].rssi_ack_validmin;

			ath_rc_priv->rssi_sum =
				ath_rc_priv->rssi_sum_cnt = 0;

			/* Now reduce the current rssi threshold */
			if ((rssi_ackAvg < rssi_thres + 2) &&
			    (rssi_thres > rssi_ack_vmin)) {
				ath_rc_priv->state[tx_rate].rssi_thres--;
1079
			}
S
Sujith 已提交
1080 1081

			state_change = true;
1082 1083
		}
	}
S
Sujith 已提交
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
exit:
	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)
{
#define CHK_RSSI(rate)					\
	((ath_rc_priv->state[(rate)].rssi_thres +	\
	  rate_table->info[(rate)].rssi_ack_deltamin) > \
	 ath_rc_priv->state[(rate)+1].rssi_thres)

	u32 now_msec = jiffies_to_msecs(jiffies);
	int rate;
	u8 last_per;
	bool state_change = false;
1105
	const struct ath_rate_table *rate_table = sc->cur_rate_table;
S
Sujith 已提交
1106 1107 1108 1109
	int size = ath_rc_priv->rate_table_size;

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

S
Sujith 已提交
1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
	/* To compensate for some imbalance between ctrl and ext. channel */

	if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
		tx_info_priv->tx.ts_rssi =
			tx_info_priv->tx.ts_rssi < 3 ? 0 :
			tx_info_priv->tx.ts_rssi - 3;

	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);
1124 1125 1126 1127 1128

	/*
	 * If this rate looks bad (high PER) then stop using it for
	 * a while (except if we are probing).
	 */
1129
	if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
S
Sujith 已提交
1130
	    rate_table->info[tx_rate].ratekbps <=
1131
	    rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
1132 1133
		ath_rc_get_lower_rix(rate_table, ath_rc_priv,
				     (u8)tx_rate, &ath_rc_priv->rate_max_phy);
1134 1135

		/* Don't probe for a little while. */
1136
		ath_rc_priv->probe_time = now_msec;
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
	}

	if (state_change) {
		/*
		 * Make sure the rates above this have higher rssi thresholds.
		 * (Note:  Monotonicity is kept within the OFDM rates and
		 *         within the CCK rates. However, no adjustment is
		 *         made to keep the rssi thresholds monotonically
		 *         increasing between the CCK and OFDM rates.)
		 */
S
Sujith 已提交
1147
		for (rate = tx_rate; rate < size - 1; rate++) {
1148
			if (rate_table->info[rate+1].phy !=
S
Sujith 已提交
1149
			    rate_table->info[tx_rate].phy)
1150 1151
				break;

S
Sujith 已提交
1152
			if (CHK_RSSI(rate)) {
1153
				ath_rc_priv->state[rate+1].rssi_thres =
S
Sujith 已提交
1154 1155
					ath_rc_priv->state[rate].rssi_thres +
					rate_table->info[rate].rssi_ack_deltamin;
1156 1157 1158 1159 1160 1161
			}
		}

		/* Make sure the rates below this have lower rssi thresholds. */
		for (rate = tx_rate - 1; rate >= 0; rate--) {
			if (rate_table->info[rate].phy !=
S
Sujith 已提交
1162
			    rate_table->info[tx_rate].phy)
1163 1164
				break;

S
Sujith 已提交
1165
			if (CHK_RSSI(rate)) {
1166
				if (ath_rc_priv->state[rate+1].rssi_thres <
S
Sujith 已提交
1167
				    rate_table->info[rate].rssi_ack_deltamin)
1168
					ath_rc_priv->state[rate].rssi_thres = 0;
1169
				else {
1170
					ath_rc_priv->state[rate].rssi_thres =
S
Sujith 已提交
1171 1172
					ath_rc_priv->state[rate+1].rssi_thres -
					rate_table->info[rate].rssi_ack_deltamin;
1173 1174
				}

1175
				if (ath_rc_priv->state[rate].rssi_thres <
S
Sujith 已提交
1176
				    rate_table->info[rate].rssi_ack_validmin) {
1177
					ath_rc_priv->state[rate].rssi_thres =
S
Sujith 已提交
1178
					rate_table->info[rate].rssi_ack_validmin;
1179 1180 1181 1182 1183 1184 1185
				}
			}
		}
	}

	/* Make sure the rates below this have lower PER */
	/* Monotonicity is kept only for rates below the current rate. */
1186
	if (ath_rc_priv->state[tx_rate].per < last_per) {
1187 1188
		for (rate = tx_rate - 1; rate >= 0; rate--) {
			if (rate_table->info[rate].phy !=
S
Sujith 已提交
1189
			    rate_table->info[tx_rate].phy)
1190 1191
				break;

1192 1193 1194 1195
			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;
1196 1197 1198 1199 1200
			}
		}
	}

	/* Maintain monotonicity for rates above the current rate */
S
Sujith 已提交
1201 1202 1203
	for (rate = tx_rate; rate < size - 1; rate++) {
		if (ath_rc_priv->state[rate+1].per <
		    ath_rc_priv->state[rate].per)
1204 1205
			ath_rc_priv->state[rate+1].per =
				ath_rc_priv->state[rate].per;
1206 1207 1208 1209
	}

	/* Every so often, we reduce the thresholds and
	 * PER (different for CCK and OFDM). */
1210
	if (now_msec - ath_rc_priv->rssi_down_time >=
S
Sujith 已提交
1211
	    rate_table->rssi_reduce_interval) {
1212

S
Sujith 已提交
1213
		for (rate = 0; rate < size; rate++) {
1214
			if (ath_rc_priv->state[rate].rssi_thres >
S
Sujith 已提交
1215
			    rate_table->info[rate].rssi_ack_validmin)
1216
				ath_rc_priv->state[rate].rssi_thres -= 1;
1217
		}
1218
		ath_rc_priv->rssi_down_time = now_msec;
1219 1220 1221 1222
	}

	/* Every so often, we reduce the thresholds
	 * and PER (different for CCK and OFDM). */
1223
	if (now_msec - ath_rc_priv->per_down_time >=
S
Sujith 已提交
1224
	    rate_table->rssi_reduce_interval) {
S
Sujith 已提交
1225
		for (rate = 0; rate < size; rate++) {
1226 1227
			ath_rc_priv->state[rate].per =
				7 * ath_rc_priv->state[rate].per / 8;
1228 1229
		}

1230
		ath_rc_priv->per_down_time = now_msec;
1231
	}
S
Sujith 已提交
1232

S
Sujith 已提交
1233 1234
	ath_debug_stat_retries(sc, tx_rate, xretries, retries,
			       ath_rc_priv->state[tx_rate].per);
1235

S
Sujith 已提交
1236 1237 1238
#undef CHK_RSSI
}

1239
static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
S
Sujith 已提交
1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
				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;
1255 1256
}

S
Sujith 已提交
1257 1258 1259 1260
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)
1261
{
S
Sujith 已提交
1262
	struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
1263
	const struct ath_rate_table *rate_table;
S
Sujith 已提交
1264
	struct ieee80211_tx_rate *rates = tx_info->status.rates;
1265
	u8 flags;
S
Sujith 已提交
1266
	u32 i = 0, rix;
1267

S
Sujith 已提交
1268
	rate_table = sc->cur_rate_table;
1269 1270 1271 1272 1273 1274 1275

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

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

S
Sujith 已提交
1283
				if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
S
Sujith 已提交
1284
				    !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1285
					return;
S
Sujith 已提交
1286

S
Sujith 已提交
1287
				rix = ath_rc_get_rateindex(rate_table, &rates[i]);
1288
				ath_rc_update_ht(sc, ath_rc_priv,
S
Sujith 已提交
1289
						tx_info_priv, rix,
1290
						xretries ? 1 : 2,
S
Sujith 已提交
1291
						rates[i].count);
1292 1293 1294 1295 1296 1297 1298 1299 1300
			}
		}
	} 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 已提交
1301
		if (rates[0].count == 1 && xretries == 1)
1302 1303 1304
			xretries = 2;
	}

S
Sujith 已提交
1305 1306
	flags = rates[i].flags;

1307
	/* If HT40 and we have switched mode from 40 to 20 => don't update */
S
Sujith 已提交
1308
	if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
S
Sujith 已提交
1309
	    !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1310 1311
		return;

S
Sujith 已提交
1312
	rix = ath_rc_get_rateindex(rate_table, &rates[i]);
S
Sujith 已提交
1313
	ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
S
Sujith 已提交
1314
			 xretries, long_retry);
1315 1316
}

1317 1318 1319 1320 1321
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)
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340
{
	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 已提交
1341
		DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n");
1342 1343 1344 1345 1346
		return NULL;
	}

	BUG_ON(mode >= ATH9K_MODE_MAX);

S
Sujith 已提交
1347
	DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode);
1348 1349 1350
	return sc->hw_rate_table[mode];
}

1351
static void ath_rc_init(struct ath_softc *sc,
S
Sujith 已提交
1352
			struct ath_rate_priv *ath_rc_priv,
1353
			struct ieee80211_supported_band *sband,
1354
			struct ieee80211_sta *sta,
1355
			const struct ath_rate_table *rate_table)
1356
{
1357 1358
	struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
	u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
1359 1360
	u8 i, j, k, hi = 0, hthi = 0;

1361 1362 1363 1364
	if (!rate_table) {
		DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
		return;
	}
1365

1366 1367
	/* Initial rate table size. Will change depending
	 * on the working rate set */
S
Sujith 已提交
1368
	ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
1369 1370

	/* Initialize thresholds according to the global rate table */
1371
	for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
1372
		ath_rc_priv->state[i].rssi_thres =
1373
			rate_table->info[i].rssi_ack_validmin;
1374
		ath_rc_priv->state[i].per = 0;
1375 1376 1377
	}

	/* Determine the valid rates */
1378
	ath_rc_init_valid_txmask(ath_rc_priv);
1379 1380 1381

	for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
		for (j = 0; j < MAX_TX_RATE_PHY; j++)
1382 1383
			ath_rc_priv->valid_phy_rateidx[i][j] = 0;
		ath_rc_priv->valid_phy_ratecnt[i] = 0;
1384 1385 1386 1387
	}

	if (!rateset->rs_nrates) {
		/* No working rate, just initialize valid rates */
S
Sujith 已提交
1388
		hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
1389
					    ath_rc_priv->ht_cap);
1390 1391
	} else {
		/* Use intersection of working rates and valid rates */
S
Sujith 已提交
1392
		hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
1393
					   rateset, ath_rc_priv->ht_cap);
1394
		if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
S
Sujith 已提交
1395
			hthi = ath_rc_setvalid_htrates(ath_rc_priv,
1396 1397 1398
						       rate_table,
						       ht_mcs,
						       ath_rc_priv->ht_cap);
1399 1400 1401 1402
		}
		hi = A_MAX(hi, hthi);
	}

1403 1404
	ath_rc_priv->rate_table_size = hi + 1;
	ath_rc_priv->rate_max_phy = 0;
S
Sujith 已提交
1405
	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
1406 1407

	for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1408 1409 1410
		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];
1411 1412
		}

S
Sujith 已提交
1413
		if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1)
1414
		    || !ath_rc_priv->valid_phy_ratecnt[i])
1415 1416
			continue;

1417
		ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
1418
	}
S
Sujith 已提交
1419 1420
	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
	ASSERT(k <= RATE_TABLE_SIZE);
1421

1422 1423 1424
	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 已提交
1425
	sc->cur_rate_table = rate_table;
1426 1427 1428

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

1431 1432
static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
			       bool is_cw40, bool is_sgi40)
1433 1434 1435
{
	u8 caps = 0;

1436
	if (sta->ht_cap.ht_supported) {
1437 1438
		caps = WLAN_RC_HT_FLAG;
		if (sc->sc_ah->caps.tx_chainmask != 1 &&
1439 1440 1441 1442
		    ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
			if (sta->ht_cap.mcs.rx_mask[1])
				caps |= WLAN_RC_DS_FLAG;
		}
1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455
		if (is_cw40)
			caps |= WLAN_RC_40_FLAG;
		if (is_sgi40)
			caps |= WLAN_RC_SGI_FLAG;
	}

	return caps;
}

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

1456 1457
static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
			  struct ieee80211_sta *sta, void *priv_sta,
1458 1459 1460
			  struct sk_buff *skb)
{
	struct ath_softc *sc = priv;
S
Sujith 已提交
1461 1462
	struct ath_rate_priv *ath_rc_priv = priv_sta;
	struct ath_tx_info_priv *tx_info_priv = NULL;
1463 1464
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ieee80211_hdr *hdr;
S
Sujith 已提交
1465
	int final_ts_idx, tx_status = 0, is_underrun = 0;
1466 1467 1468 1469
	__le16 fc;

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

S
Sujith 已提交
1473
	if (!priv_sta || !ieee80211_is_data(fc) ||
1474
	    !tx_info_priv->update_rc)
S
Sujith 已提交
1475
		goto exit;
1476

S
Sujith 已提交
1477 1478
	if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
		goto exit;
1479

S
Sujith 已提交
1480 1481 1482
	/*
	 * If underrun error is seen assume it as an excessive retry only
	 * if prefetch trigger level have reached the max (0x3f for 5416)
1483
	 * Adjust the long retry as if the frame was tried hw->max_rate_tries
S
Sujith 已提交
1484 1485 1486 1487
	 * 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) &&
1488
	    ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
S
Sujith 已提交
1489 1490 1491 1492 1493 1494 1495 1496 1497
		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,
1498
			 (is_underrun) ? sc->hw->max_rate_tries :
S
Sujith 已提交
1499 1500
			 tx_info_priv->tx.ts_longretry);

S
Sujith 已提交
1501
	/* Check if aggregation has to be enabled for this tid */
1502 1503
	if (conf_is_ht(&sc->hw->conf) &&
	    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
S
Sujith 已提交
1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515
		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);
		}
	}
1516 1517

	ath_debug_stat_rc(sc, skb);
S
Sujith 已提交
1518
exit:
1519
	kfree(tx_info_priv);
1520 1521
}

1522 1523
static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
                          struct ieee80211_sta *sta, void *priv_sta)
1524
{
1525
	struct ath_softc *sc = priv;
S
Sujith 已提交
1526
	struct ath_rate_priv *ath_rc_priv = priv_sta;
1527
	const struct ath_rate_table *rate_table = NULL;
1528
	bool is_cw40, is_sgi40;
1529 1530
	int i, j = 0;

S
Sujith 已提交
1531 1532 1533 1534 1535 1536 1537 1538
	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;
1539

1540
	if (sta->ht_cap.ht_supported) {
S
Sujith 已提交
1541
		for (i = 0, j = 0; i < 77; i++) {
J
Johannes Berg 已提交
1542
			if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
S
Sujith 已提交
1543
				ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
1544 1545 1546
			if (j == ATH_RATE_MAX)
				break;
		}
S
Sujith 已提交
1547
		ath_rc_priv->neg_ht_rates.rs_nrates = j;
1548
	}
S
Sujith 已提交
1549

1550 1551 1552 1553 1554 1555
	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) ||
1556
	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
1557 1558 1559 1560 1561 1562 1563 1564 1565
	    (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;
	}

1566
	ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
1567 1568 1569 1570 1571 1572 1573 1574 1575
	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;
1576
	const struct ath_rate_table *rate_table = NULL;
1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599
	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);
1600
			ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
1601 1602 1603 1604 1605 1606 1607 1608
						   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);
		}
	}
1609 1610
}

1611
static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1612
{
1613 1614
	struct ath_wiphy *aphy = hw->priv;
	return aphy->sc;
1615 1616 1617 1618 1619 1620 1621
}

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

1622
static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
1623 1624
{
	struct ath_softc *sc = priv;
S
Sujith 已提交
1625
	struct ath_rate_priv *rate_priv;
1626

S
Sujith 已提交
1627
	rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
1628
	if (!rate_priv) {
S
Sujith 已提交
1629
		DPRINTF(sc, ATH_DBG_FATAL,
S
Sujith 已提交
1630
			"Unable to allocate private rc structure\n");
1631 1632
		return NULL;
	}
S
Sujith 已提交
1633 1634

	rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
1635
	rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
S
Sujith 已提交
1636

1637 1638 1639
	return rate_priv;
}

1640 1641
static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
			      void *priv_sta)
1642
{
S
Sujith 已提交
1643
	struct ath_rate_priv *rate_priv = priv_sta;
S
Sujith 已提交
1644
	kfree(rate_priv);
1645 1646 1647 1648 1649 1650 1651 1652
}

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,
1653
	.rate_update = ath_rate_update,
1654 1655 1656
	.alloc = ath_rate_alloc,
	.free = ath_rate_free,
	.alloc_sta = ath_rate_alloc_sta,
1657
	.free_sta = ath_rate_free_sta,
1658 1659
};

S
Sujith 已提交
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679
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;
}

1680 1681 1682 1683 1684 1685 1686 1687 1688
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);
}