rc.c 49.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Copyright (c) 2004 Video54 Technologies, Inc.
 * Copyright (c) 2004-2008 Atheros Communications, Inc.
 *
 * 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.
 */

#include "core.h"

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

S
Sujith 已提交
156 157 158 159
/* VALID_ALL - valid for 20/40/Legacy,
 * VALID - Legacy only,
 * VALID_20 - HT 20 only,
 * VALID_40 - HT 40 only */
160 161 162 163 164 165

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

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

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

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

static struct ath_rate_table ar5416_11b_ratetable = {
	4,
S
Sujith 已提交
394
	{0},
395
	{
S
Sujith 已提交
396
		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
397 398
			900, 0x1b,  0x00, (0x80|2),
			0, 0, 1, 0, 0 },
S
Sujith 已提交
399
		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
400 401
			1800, 0x1a, 0x04, (0x80|4),
			1, 1, 1, 1, 0 },
S
Sujith 已提交
402
		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
403 404
			4300, 0x19, 0x04, (0x80|11),
			1, 2, 2, 2, 0 },
S
Sujith 已提交
405
		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
			7100, 0x18, 0x04, (0x80|22),
			1, 4, 100, 3, 0 },
	},
	100, /* probe interval */
	100, /* 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;
	}
}

S
Sujith 已提交
433
static void ath_rc_sort_validrates(struct ath_rate_table *rate_table,
S
Sujith 已提交
434
				   struct ath_rate_priv *ath_rc_priv)
435 436 437
{
	u8 i, j, idx, idx_next;

438
	for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
439
		for (j = 0; j <= i-1; j++) {
440 441
			idx = ath_rc_priv->valid_rate_index[j];
			idx_next = ath_rc_priv->valid_rate_index[j+1];
442 443 444

			if (rate_table->info[idx].ratekbps >
				rate_table->info[idx_next].ratekbps) {
445 446
				ath_rc_priv->valid_rate_index[j] = idx_next;
				ath_rc_priv->valid_rate_index[j+1] = idx;
447 448 449 450 451
			}
		}
	}
}

S
Sujith 已提交
452
static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
453 454 455
{
	u8 i;

456
	for (i = 0; i < ath_rc_priv->rate_table_size; i++)
S
Sujith 已提交
457
		ath_rc_priv->valid_rate_index[i] = 0;
458 459
}

S
Sujith 已提交
460
static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
461 462
					   u8 index, int valid_tx_rate)
{
463
	ASSERT(index <= ath_rc_priv->rate_table_size);
S
Sujith 已提交
464
	ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
465 466
}

S
Sujith 已提交
467
static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
468 469
					u8 index)
{
470 471
	ASSERT(index <= ath_rc_priv->rate_table_size);
	return ath_rc_priv->valid_rate_index[index];
472 473 474
}

static inline int
S
Sujith 已提交
475
ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
S
Sujith 已提交
476
			    struct ath_rate_priv *ath_rc_priv,
477 478 479 480 481
			    u8 cur_valid_txrate,
			    u8 *next_idx)
{
	u8 i;

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

	/* No more valid rates */
	*next_idx = 0;
S
Sujith 已提交
491
	return 0;
492 493 494 495 496 497 498
}

/* Return true only for single stream */

static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
{
	if (WLAN_RC_PHY_HT(phy) & !(capflag & WLAN_RC_HT_FLAG))
S
Sujith 已提交
499
		return 0;
500
	if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
S
Sujith 已提交
501
		return 0;
502
	if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
S
Sujith 已提交
503
		return 0;
504 505
	if (!ignore_cw && WLAN_RC_PHY_HT(phy))
		if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
S
Sujith 已提交
506
			return 0;
507
		if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
S
Sujith 已提交
508 509
			return 0;
	return 1;
510 511 512
}

static inline int
S
Sujith 已提交
513
ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
S
Sujith 已提交
514
				 struct ath_rate_priv *ath_rc_priv,
515 516 517 518
				 u8 cur_valid_txrate, u8 *next_idx)
{
	int8_t i;

519 520 521
	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 已提交
522
			return 1;
523 524
		}
	}
S
Sujith 已提交
525
	return 0;
526 527 528
}

static u8
S
Sujith 已提交
529
ath_rc_sib_init_validrates(struct ath_rate_priv *ath_rc_priv,
S
Sujith 已提交
530
			   struct ath_rate_table *rate_table,
531 532 533 534 535 536 537
			   u32 capflag)
{
	u8 i, hi = 0;
	u32 valid;

	for (i = 0; i < rate_table->rate_cnt; i++) {
		valid = (ath_rc_priv->single_stream ?
S
Sujith 已提交
538 539
			 rate_table->info[i].valid_single_stream :
			 rate_table->info[i].valid);
S
Sujith 已提交
540
		if (valid == 1) {
541 542 543
			u32 phy = rate_table->info[i].phy;
			u8 valid_rate_count = 0;

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

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

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

static u8
S
Sujith 已提交
559
ath_rc_sib_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
S
Sujith 已提交
560
			  struct ath_rate_table *rate_table,
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
			  struct ath_rateset *rateset,
			  u32 capflag)
{
	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;
			u32 valid = (ath_rc_priv->single_stream ?
				rate_table->info[j].valid_single_stream :
				rate_table->info[j].valid);

			/* We allow a rate only if its valid and the
			 * capflag matches one of the validity
S
Sujith 已提交
576
			 * (VALID/VALID_20/VALID_40) flags */
577 578 579 580 581 582 583 584 585

			if (((rateset->rs_rates[i] & 0x7F) ==
				(rate_table->info[j].dot11rate & 0x7F)) &&
				((valid & WLAN_RC_CAP_MODE(capflag)) ==
				WLAN_RC_CAP_MODE(capflag)) &&
				!WLAN_RC_PHY_HT(phy)) {

				u8 valid_rate_count = 0;

S
Sujith 已提交
586
				if (!ath_rc_valid_phyrate(phy, capflag, 0))
587 588 589
					continue;

				valid_rate_count =
590
					ath_rc_priv->valid_phy_ratecnt[phy];
591

592
				ath_rc_priv->valid_phy_rateidx[phy]
593
					[valid_rate_count] = j;
594
				ath_rc_priv->valid_phy_ratecnt[phy] += 1;
S
Sujith 已提交
595
				ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
596 597 598 599 600 601 602 603
				hi = A_MAX(hi, j);
			}
		}
	}
	return hi;
}

static u8
S
Sujith 已提交
604
ath_rc_sib_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
S
Sujith 已提交
605
			    struct ath_rate_table *rate_table,
606 607 608 609 610 611 612 613 614
			    u8 *mcs_set, u32 capflag)
{
	u8 i, j, hi = 0;

	/* Use intersection of working rates and valid rates */
	for (i = 0; i <  ((struct ath_rateset *)mcs_set)->rs_nrates; i++) {
		for (j = 0; j < rate_table->rate_cnt; j++) {
			u32 phy = rate_table->info[j].phy;
			u32 valid = (ath_rc_priv->single_stream ?
S
Sujith 已提交
615 616
				     rate_table->info[j].valid_single_stream :
				     rate_table->info[j].valid);
617 618

			if (((((struct ath_rateset *)
S
Sujith 已提交
619 620 621 622
			       mcs_set)->rs_rates[i] & 0x7F) !=
			     (rate_table->info[j].dot11rate & 0x7F)) ||
			    !WLAN_RC_PHY_HT(phy) ||
			    !WLAN_RC_PHY_HT_VALID(valid, capflag))
623 624
				continue;

S
Sujith 已提交
625
			if (!ath_rc_valid_phyrate(phy, capflag, 0))
626 627
				continue;

628 629 630
			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 已提交
631
			ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
632 633 634 635 636 637 638
			hi = A_MAX(hi, j);
		}
	}
	return hi;
}

u8 ath_rate_findrateix(struct ath_softc *sc,
639
		       u8 dot11rate)
640
{
S
Sujith 已提交
641
	struct ath_rate_table *ratetable;
642 643
	int i;

S
Sujith 已提交
644
	ratetable = sc->hw_rate_table[sc->sc_curmode];
645 646 647 648 649 650 651 652 653 654 655 656 657

	if (WARN_ON(!ratetable))
		return 0;

	for (i = 0; i < ratetable->rate_cnt; i++) {
		if ((ratetable->info[i].dot11rate & 0x7f) == (dot11rate & 0x7f))
			return i;
	}

	return 0;
}

static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
S
Sujith 已提交
658
			     struct ath_rate_priv *ath_rc_priv,
S
Sujith 已提交
659
			     struct ath_rate_table *rate_table,
S
Sujith 已提交
660 661
			     int probe_allowed, int *is_probing,
			     int is_retry)
662 663 664 665 666
{
	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 已提交
667
	*is_probing = 0;
668

669 670 671
	rssi_last = median(ath_rc_priv->rssi_last,
			   ath_rc_priv->rssi_last_prev,
			   ath_rc_priv->rssi_last_prev2);
672 673 674 675 676 677 678 679 680 681 682

	/*
	 * 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);
683
	dt = now_msec - ath_rc_priv->rssi_time;
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701

	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;
702
	maxindex = ath_rc_priv->max_valid_rate-1;
703 704 705 706 707 708 709 710 711 712 713

	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;

714 715
		rate = ath_rc_priv->valid_rate_index[index];
		if (rate > ath_rc_priv->rate_max_phy)
716 717 718 719 720 721 722 723 724 725 726 727 728
			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.
		 */
729
		per_thres = ath_rc_priv->state[rate].per;
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747
		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;

	/* if we are retrying for more than half the number
	 * of max retries, use the min rate for the next retry
	 */
	if (is_retry)
748
		rate = ath_rc_priv->valid_rate_index[minindex];
749

750
	ath_rc_priv->rssi_last_lookup = rssi_last;
751 752 753 754 755 756

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

757 758
	if (rate >= ath_rc_priv->rate_max_phy && probe_allowed) {
		rate = ath_rc_priv->rate_max_phy;
759 760 761 762

		/* Probe the next allowed phy state */
		/* FIXME:XXXX Check to make sure ratMax is checked properly */
		if (ath_rc_get_nextvalid_txrate(rate_table,
763 764
						ath_rc_priv, rate, &next_rate) &&
		    (now_msec - ath_rc_priv->probe_time >
765
		     rate_table->probe_interval) &&
766
		    (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
767
			rate = next_rate;
768 769 770
			ath_rc_priv->probe_rate = rate;
			ath_rc_priv->probe_time = now_msec;
			ath_rc_priv->hw_maxretry_pktcnt = 0;
S
Sujith 已提交
771
			*is_probing = 1;
772 773 774
		}
	}

775 776
	if (rate > (ath_rc_priv->rate_table_size - 1))
		rate = ath_rc_priv->rate_table_size - 1;
777 778

	ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) ||
S
Sujith 已提交
779 780
	       (rate_table->info[rate].valid_single_stream &&
		ath_rc_priv->single_stream));
781 782 783 784

	return rate;
}

S
Sujith 已提交
785
static void ath_rc_rate_set_series(struct ath_rate_table *rate_table ,
S
Sujith 已提交
786
				   struct ieee80211_tx_rate *rate,
787 788 789 790
				   u8 tries,
				   u8 rix,
				   int rtsctsenable)
{
S
Sujith 已提交
791 792 793 794 795 796 797 798 799 800 801
	rate->count = tries;
	rate->idx = rix;

	if (rtsctsenable)
		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;
802 803 804
}

static u8 ath_rc_rate_getidx(struct ath_softc *sc,
S
Sujith 已提交
805
			     struct ath_rate_priv *ath_rc_priv,
S
Sujith 已提交
806
			     struct ath_rate_table *rate_table,
S
Sujith 已提交
807 808
			     u8 rix, u16 stepdown,
			     u16 min_rate)
809 810 811 812 813 814 815
{
	u32 j;
	u8 nextindex;

	if (min_rate) {
		for (j = RATE_TABLE_SIZE; j > 0; j--) {
			if (ath_rc_get_nextlowervalid_txrate(rate_table,
816
						ath_rc_priv, rix, &nextindex))
817 818 819 820 821 822 823
				rix = nextindex;
			else
				break;
		}
	} else {
		for (j = stepdown; j > 0; j--) {
			if (ath_rc_get_nextlowervalid_txrate(rate_table,
824
						ath_rc_priv, rix, &nextindex))
825 826 827 828 829 830 831 832 833
				rix = nextindex;
			else
				break;
		}
	}
	return rix;
}

static void ath_rc_ratefind(struct ath_softc *sc,
S
Sujith 已提交
834 835
			    struct ath_rate_priv *ath_rc_priv,
			    int num_tries, int num_rates,
S
Sujith 已提交
836
			    struct ieee80211_tx_info *tx_info, int *is_probe,
837 838 839 840
			    int is_retry)
{
	u8 try_per_rate = 0, i = 0, rix, nrix;
	struct ath_rate_table *rate_table;
S
Sujith 已提交
841
	struct ieee80211_tx_rate *rates = tx_info->control.rates;
842

S
Sujith 已提交
843
	rate_table = sc->hw_rate_table[sc->sc_curmode];
S
Sujith 已提交
844
	rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1,
S
Sujith 已提交
845
				 is_probe, is_retry);
846 847
	nrix = rix;

S
Sujith 已提交
848
	if (*is_probe) {
849 850 851
		/* set one try for probe rates. For the
		 * probes don't enable rts */
		ath_rc_rate_set_series(rate_table,
S
Sujith 已提交
852
			&rates[i++], 1, nrix, 0);
853 854 855 856 857 858

		try_per_rate = (num_tries/num_rates);
		/* Get the next tried/allowed rate. No RTS for the next series
		 * after the probe rate
		 */
		nrix = ath_rc_rate_getidx(sc,
S
Sujith 已提交
859
			ath_rc_priv, rate_table, nrix, 1, 0);
860
		ath_rc_rate_set_series(rate_table,
S
Sujith 已提交
861
			&rates[i++], try_per_rate, nrix, 0);
862 863 864 865
	} else {
		try_per_rate = (num_tries/num_rates);
		/* Set the choosen rate. No RTS for first series entry. */
		ath_rc_rate_set_series(rate_table,
S
Sujith 已提交
866
			&rates[i++], try_per_rate, nrix, 0);
867 868 869 870 871 872 873 874 875
	}

	/* Fill in the other rates for multirate retry */
	for ( ; i < num_rates; i++) {
		u8 try_num;
		u8 min_rate;

		try_num = ((i + 1) == num_rates) ?
			num_tries - (try_per_rate * i) : try_per_rate ;
S
Sujith 已提交
876
		min_rate = (((i + 1) == num_rates) && 0);
877 878

		nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
S
Sujith 已提交
879
					  rate_table, nrix, 1, min_rate);
880 881
		/* All other rates in the series have RTS enabled */
		ath_rc_rate_set_series(rate_table,
S
Sujith 已提交
882
				       &rates[i], try_num, nrix, 1);
883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899
	}

	/*
	 * 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.
	 */
S
Sujith 已提交
900
	if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) ||
S
Sujith 已提交
901 902
	    (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) ||
	    (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) {
903 904 905 906
		u8  dot11rate = rate_table->info[rix].dot11rate;
		u8 phy = rate_table->info[rix].phy;
		if (i == 4 &&
		    ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
S
Sujith 已提交
907
		     (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
S
Sujith 已提交
908 909
			rates[3].idx = rates[2].idx;
			rates[3].flags = rates[2].flags;
910 911 912 913 914
		}
	}
}

static void ath_rc_update_ht(struct ath_softc *sc,
S
Sujith 已提交
915 916
			     struct ath_rate_priv *ath_rc_priv,
			     struct ath_tx_info_priv *tx_info_priv,
917 918 919
			     int tx_rate, int xretries, int retries)
{
	u32 now_msec = jiffies_to_msecs(jiffies);
S
Sujith 已提交
920
	int state_change = 0, rate, count;
921
	u8 last_per;
S
Sujith 已提交
922
	struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945
	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
	};

	if (!ath_rc_priv)
		return;

	ASSERT(tx_rate >= 0);
	if (tx_rate < 0)
		return;

	/* To compensate for some imbalance between ctrl and ext. channel */

	if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
S
Sujith 已提交
946 947 948
		tx_info_priv->tx.ts_rssi =
			tx_info_priv->tx.ts_rssi < 3 ? 0 :
			tx_info_priv->tx.ts_rssi - 3;
949

950
	last_per = ath_rc_priv->state[tx_rate].per;
951 952 953 954

	if (xretries) {
		/* Update the PER. */
		if (xretries == 1) {
955 956 957
			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;
958 959
		} else {
			/* xretries == 2 */
960
			count = ARRAY_SIZE(nretry_to_per_lookup);
961 962 963
			if (retries >= count)
				retries = count - 1;
			/* new_PER = 7/8*old_PER + 1/8*(currentPER) */
964 965 966
			ath_rc_priv->state[tx_rate].per =
				(u8)(ath_rc_priv->state[tx_rate].per -
				     (ath_rc_priv->state[tx_rate].per >> 3) +
S
Sujith 已提交
967
				     ((100) >> 3));
968 969 970 971
		}

		/* xretries == 1 or 2 */

972 973
		if (ath_rc_priv->probe_rate == tx_rate)
			ath_rc_priv->probe_rate = 0;
974 975 976 977

	} else {	/* xretries == 0 */
		/* Update the PER. */
		/* Make sure it doesn't index out of array's bounds. */
978
		count = ARRAY_SIZE(nretry_to_per_lookup);
979 980
		if (retries >= count)
			retries = count - 1;
S
Sujith 已提交
981
		if (tx_info_priv->n_bad_frames) {
S
Sujith 已提交
982
			/* new_PER = 7/8*old_PER + 1/8*(currentPER)
983 984 985 986 987 988 989 990 991 992 993
			 * 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 已提交
994
			if (tx_info_priv->n_frames > 0)
995
				ath_rc_priv->state[tx_rate].per
996
				      = (u8)
997 998
					(ath_rc_priv->state[tx_rate].per -
					(ath_rc_priv->state[tx_rate].per >> 3) +
S
Sujith 已提交
999 1000 1001
					((100*(retries*tx_info_priv->n_frames +
					tx_info_priv->n_bad_frames) /
					(tx_info_priv->n_frames *
1002 1003 1004 1005
						(retries+1))) >> 3));
		} else {
			/* new_PER = 7/8*old_PER + 1/8*(currentPER) */

1006 1007 1008
			ath_rc_priv->state[tx_rate].per = (u8)
				(ath_rc_priv->state[tx_rate].per -
				(ath_rc_priv->state[tx_rate].per >> 3) +
1009 1010 1011
				(nretry_to_per_lookup[retries] >> 3));
		}

1012 1013
		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 已提交
1014
		ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi;
1015
		ath_rc_priv->rssi_time = now_msec;
1016 1017 1018 1019 1020 1021

		/*
		 * If we got at most one retry then increase the max rate if
		 * this was a probe.  Otherwise, ignore the probe.
		 */

1022
		if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
S
Sujith 已提交
1023 1024
			if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
				tx_info_priv->n_frames) {
1025 1026 1027 1028 1029 1030 1031
				/*
				 * 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.
				 */
1032
				ath_rc_priv->probe_rate = 0;
1033 1034 1035
			} else {
				u8 probe_rate = 0;

1036 1037
				ath_rc_priv->rate_max_phy = ath_rc_priv->probe_rate;
				probe_rate = ath_rc_priv->probe_rate;
1038

1039 1040
				if (ath_rc_priv->state[probe_rate].per > 30)
					ath_rc_priv->state[probe_rate].per = 20;
1041

1042
				ath_rc_priv->probe_rate = 0;
1043 1044 1045 1046 1047 1048 1049

				/*
				 * 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.
				 */
1050
				ath_rc_priv->probe_time = now_msec -
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
					rate_table->probe_interval / 2;
			}
		}

		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
1061
			 * ath_rc_priv->state[txRate].rssi_thres and we see lots
1062
			 * of retries, then we could increase
1063
			 * ath_rc_priv->state[txRate].rssi_thres.
1064
			 */
1065
			ath_rc_priv->hw_maxretry_pktcnt = 0;
1066 1067 1068 1069 1070
		} else {
			/*
			 * It worked with no retries. First ignore bogus (small)
			 * rssi_ack values.
			 */
1071 1072 1073
			if (tx_rate == ath_rc_priv->rate_max_phy &&
			    ath_rc_priv->hw_maxretry_pktcnt < 255) {
				ath_rc_priv->hw_maxretry_pktcnt++;
1074 1075
			}

S
Sujith 已提交
1076
			if (tx_info_priv->tx.ts_rssi >=
1077 1078
				rate_table->info[tx_rate].rssi_ack_validmin) {
				/* Average the rssi */
1079 1080 1081 1082
				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;
1083 1084
				}

S
Sujith 已提交
1085
				ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
1086
				ath_rc_priv->rssi_sum_cnt++;
1087

1088
				if (ath_rc_priv->rssi_sum_cnt > 4) {
1089
					int32_t rssi_ackAvg =
1090
						(ath_rc_priv->rssi_sum + 2) / 4;
1091
					int8_t rssi_thres =
1092
						ath_rc_priv->state[tx_rate].
1093 1094 1095 1096 1097
						rssi_thres;
					int8_t rssi_ack_vmin =
						rate_table->info[tx_rate].
						rssi_ack_validmin;

1098 1099
					ath_rc_priv->rssi_sum =
						ath_rc_priv->rssi_sum_cnt = 0;
1100 1101 1102 1103

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

S
Sujith 已提交
1109
					state_change = 1;
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
				}
			}
		}
	}

	/* For all cases */

	/*
	 * If this rate looks bad (high PER) then stop using it for
	 * a while (except if we are probing).
	 */
1121
	if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
S
Sujith 已提交
1122
	    rate_table->info[tx_rate].ratekbps <=
1123 1124 1125
	    rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
		ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
				 (u8) tx_rate, &ath_rc_priv->rate_max_phy);
1126 1127

		/* Don't probe for a little while. */
1128
		ath_rc_priv->probe_time = now_msec;
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
	}

	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.)
		 */
		for (rate = tx_rate; rate <
1140
				ath_rc_priv->rate_table_size - 1; rate++) {
1141 1142 1143 1144
			if (rate_table->info[rate+1].phy !=
				rate_table->info[tx_rate].phy)
				break;

1145
			if (ath_rc_priv->state[rate].rssi_thres +
S
Sujith 已提交
1146
			    rate_table->info[rate].rssi_ack_deltamin >
1147 1148 1149
			    ath_rc_priv->state[rate+1].rssi_thres) {
				ath_rc_priv->state[rate+1].rssi_thres =
					ath_rc_priv->state[rate].
S
Sujith 已提交
1150
					rssi_thres +
1151
					rate_table->info[rate].
S
Sujith 已提交
1152
					rssi_ack_deltamin;
1153 1154 1155 1156 1157 1158
			}
		}

		/* 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 已提交
1159
			    rate_table->info[tx_rate].phy)
1160 1161
				break;

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

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

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

1196 1197 1198 1199
			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;
1200 1201 1202 1203 1204
			}
		}
	}

	/* Maintain monotonicity for rates above the current rate */
1205 1206 1207 1208
	for (rate = tx_rate; rate < ath_rc_priv->rate_table_size - 1; rate++) {
		if (ath_rc_priv->state[rate+1].per < ath_rc_priv->state[rate].per)
			ath_rc_priv->state[rate+1].per =
				ath_rc_priv->state[rate].per;
1209 1210 1211 1212
	}

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

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

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

1233
		ath_rc_priv->per_down_time = now_msec;
1234 1235 1236
	}
}

S
Sujith 已提交
1237 1238 1239 1240
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)
1241
{
S
Sujith 已提交
1242
	struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
1243
	struct ath_rate_table *rate_table;
S
Sujith 已提交
1244
	struct ieee80211_tx_rate *rates = tx_info->status.rates;
1245 1246 1247
	u8 flags;
	u32 series = 0, rix;

S
Sujith 已提交
1248
	rate_table = sc->hw_rate_table[sc->sc_curmode];
1249 1250 1251 1252 1253 1254 1255 1256

	/*
	 * 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.*/
		for (series = 0; series < final_ts_idx ; series++) {
S
Sujith 已提交
1257
			if (rates[series].count != 0 && (rates[series].idx >= 0)) {
S
Sujith 已提交
1258
				flags = rates[series].flags;
1259 1260
				/* If HT40 and we have switched mode from
				 * 40 to 20 => don't update */
S
Sujith 已提交
1261
				if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
S
Sujith 已提交
1262
				    (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG))
1263
					return;
S
Sujith 已提交
1264

S
Sujith 已提交
1265 1266
				if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
					(flags & IEEE80211_TX_RC_SHORT_GI))
1267
					rix = rate_table->info[
S
Sujith 已提交
1268 1269
						rates[series].idx].ht_index;
				else if (flags & IEEE80211_TX_RC_SHORT_GI)
1270
					rix = rate_table->info[
S
Sujith 已提交
1271 1272
						rates[series].idx].sgi_index;
				else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1273
					rix = rate_table->info[
S
Sujith 已提交
1274
						rates[series].idx].cw40index;
1275 1276
				else
					rix = rate_table->info[
S
Sujith 已提交
1277
						rates[series].idx].base_index;
1278
				ath_rc_update_ht(sc, ath_rc_priv,
S
Sujith 已提交
1279
						tx_info_priv, rix,
1280
						xretries ? 1 : 2,
S
Sujith 已提交
1281
						rates[series].count);
1282 1283 1284 1285 1286 1287 1288 1289 1290
			}
		}
	} 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 已提交
1291
		if (rates[0].count == 1 && xretries == 1)
1292 1293 1294
			xretries = 2;
	}

S
Sujith 已提交
1295
	flags = rates[series].flags;
1296
	/* If HT40 and we have switched mode from 40 to 20 => don't update */
S
Sujith 已提交
1297
	if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
S
Sujith 已提交
1298
	    (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) {
1299
		return;
S
Sujith 已提交
1300
	}
1301

S
Sujith 已提交
1302 1303 1304 1305 1306 1307
	if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (flags & IEEE80211_TX_RC_SHORT_GI))
		rix = rate_table->info[rates[series].idx].ht_index;
	else if (flags & IEEE80211_TX_RC_SHORT_GI)
		rix = rate_table->info[rates[series].idx].sgi_index;
	else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
		rix = rate_table->info[rates[series].idx].cw40index;
1308
	else
S
Sujith 已提交
1309
		rix = rate_table->info[rates[series].idx].base_index;
1310

S
Sujith 已提交
1311
	ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
1312 1313 1314
		xretries, long_retry);
}

1315
static void ath_rc_init(struct ath_softc *sc,
S
Sujith 已提交
1316
			struct ath_rate_priv *ath_rc_priv,
1317 1318
			struct ieee80211_supported_band *sband,
			struct ieee80211_sta *sta)
1319 1320
{
	struct ath_rate_table *rate_table = NULL;
1321 1322
	struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
	u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
1323 1324
	u8 i, j, k, hi = 0, hthi = 0;

S
Sujith 已提交
1325
	rate_table = sc->hw_rate_table[sc->sc_curmode];
1326

1327 1328
	if (sta->ht_cap.ht_supported) {
		if (sband->band == IEEE80211_BAND_2GHZ)
S
Sujith 已提交
1329
			rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
1330
		else
S
Sujith 已提交
1331
			rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
1332 1333

		ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG);
S
Sujith 已提交
1334

1335 1336 1337 1338
		if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
			ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG;
	}

1339 1340
	/* Initial rate table size. Will change depending
	 * on the working rate set */
S
Sujith 已提交
1341
	ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
1342 1343

	/* Initialize thresholds according to the global rate table */
1344
	for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
1345
		ath_rc_priv->state[i].rssi_thres =
1346
			rate_table->info[i].rssi_ack_validmin;
1347
		ath_rc_priv->state[i].per = 0;
1348 1349 1350
	}

	/* Determine the valid rates */
1351
	ath_rc_init_valid_txmask(ath_rc_priv);
1352 1353 1354

	for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
		for (j = 0; j < MAX_TX_RATE_PHY; j++)
1355 1356
			ath_rc_priv->valid_phy_rateidx[i][j] = 0;
		ath_rc_priv->valid_phy_ratecnt[i] = 0;
1357
	}
1358
	ath_rc_priv->rc_phy_mode = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG);
1359 1360

	/* Set stream capability */
1361
	ath_rc_priv->single_stream = (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1;
1362 1363 1364 1365

	if (!rateset->rs_nrates) {
		/* No working rate, just initialize valid rates */
		hi = ath_rc_sib_init_validrates(ath_rc_priv, rate_table,
1366
						ath_rc_priv->ht_cap);
1367 1368 1369
	} else {
		/* Use intersection of working rates and valid rates */
		hi = ath_rc_sib_setvalid_rates(ath_rc_priv, rate_table,
1370 1371
					       rateset, ath_rc_priv->ht_cap);
		if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
1372 1373 1374
			hthi = ath_rc_sib_setvalid_htrates(ath_rc_priv,
							   rate_table,
							   ht_mcs,
1375
							   ath_rc_priv->ht_cap);
1376 1377 1378 1379
		}
		hi = A_MAX(hi, hthi);
	}

1380 1381
	ath_rc_priv->rate_table_size = hi + 1;
	ath_rc_priv->rate_max_phy = 0;
S
Sujith 已提交
1382
	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
1383 1384

	for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1385 1386 1387
		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];
1388 1389
		}

S
Sujith 已提交
1390
		if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1)
1391
		    || !ath_rc_priv->valid_phy_ratecnt[i])
1392 1393
			continue;

1394
		ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
1395
	}
S
Sujith 已提交
1396 1397
	ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
	ASSERT(k <= RATE_TABLE_SIZE);
1398

1399 1400 1401
	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];
1402 1403 1404
}

/* Rate Control callbacks */
1405 1406
static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
			  struct ieee80211_sta *sta, void *priv_sta,
1407 1408 1409
			  struct sk_buff *skb)
{
	struct ath_softc *sc = priv;
S
Sujith 已提交
1410 1411
	struct ath_rate_priv *ath_rc_priv = priv_sta;
	struct ath_tx_info_priv *tx_info_priv = NULL;
1412 1413 1414
	struct ath_node *an;
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ieee80211_hdr *hdr;
S
Sujith 已提交
1415
	int final_ts_idx, tx_status = 0, is_underrun = 0;
1416 1417 1418 1419
	__le16 fc;

	hdr = (struct ieee80211_hdr *)skb->data;
	fc = hdr->frame_control;
S
Sujith 已提交
1420
	tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
S
Sujith 已提交
1421
	an = (struct ath_node *)sta->drv_priv;
S
Sujith 已提交
1422
	final_ts_idx = tx_info_priv->tx.ts_rateindex;
1423

S
Sujith 已提交
1424 1425
	if (!an || !priv_sta || !ieee80211_is_data(fc))
		goto exit;
1426

S
Sujith 已提交
1427 1428
	if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
		goto exit;
1429

S
Sujith 已提交
1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456
	if (tx_info_priv->tx.ts_rssi > 0) {
		ATH_RSSI_LPF(an->an_chainmask_sel.tx_avgrssi,
			     tx_info_priv->tx.ts_rssi);
	}

	/*
	 * If underrun error is seen assume it as an excessive retry only
	 * if prefetch trigger level have reached the max (0x3f for 5416)
	 * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
	 * 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) &&
	    ((sc->sc_ah->ah_txTrigLevel) >= ath_rc_priv->tx_triglevel_max)) {
		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,
			 (is_underrun) ? ATH_11N_TXMAXTRY :
			 tx_info_priv->tx.ts_longretry);

exit:
1457
	kfree(tx_info_priv);
1458 1459
}

1460 1461
static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
			 struct ieee80211_tx_rate_control *txrc)
1462
{
1463 1464
	struct ieee80211_supported_band *sband = txrc->sband;
	struct sk_buff *skb = txrc->skb;
1465
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1466
	struct ath_softc *sc = priv;
1467
	struct ieee80211_hw *hw = sc->hw;
S
Sujith 已提交
1468
	struct ath_rate_priv *ath_rc_priv = priv_sta;
1469
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
S
Sujith 已提交
1470
	int is_probe = 0;
1471 1472 1473
	__le16 fc = hdr->frame_control;

	/* lowest rate for management and multicast/broadcast frames */
S
Sujith 已提交
1474 1475 1476 1477
	if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
		tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
		tx_info->control.rates[0].count =
			is_multicast_ether_addr(hdr->addr1) ? 1 : ATH_MGT_TXMAXTRY;
1478 1479 1480 1481
		return;
	}

	/* Find tx rate for unicast frames */
S
Sujith 已提交
1482 1483
	ath_rc_ratefind(sc, ath_rc_priv, ATH_11N_TXMAXTRY, 4,
			tx_info, &is_probe, false);
1484 1485

	/* Check if aggregation has to be enabled for this tid */
J
Johannes Berg 已提交
1486
	if (hw->conf.ht.enabled) {
1487
		if (ieee80211_is_data_qos(fc)) {
S
Sujith 已提交
1488 1489 1490
			u8 *qc, tid;
			struct ath_node *an;

1491 1492
			qc = ieee80211_get_qos_ctl(hdr);
			tid = qc[0] & 0xf;
S
Sujith 已提交
1493
			an = (struct ath_node *)sta->drv_priv;
1494

S
Sujith 已提交
1495 1496
			if(ath_tx_aggr_check(sc, an, tid))
				ieee80211_start_tx_ba_session(hw, hdr->addr1, tid);
1497 1498 1499 1500
		}
	}
}

1501 1502
static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
                          struct ieee80211_sta *sta, void *priv_sta)
1503
{
1504
	struct ath_softc *sc = priv;
S
Sujith 已提交
1505
	struct ath_rate_priv *ath_rc_priv = priv_sta;
1506 1507
	int i, j = 0;

S
Sujith 已提交
1508 1509 1510 1511 1512 1513 1514 1515
	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;
1516

1517
	if (sta->ht_cap.ht_supported) {
S
Sujith 已提交
1518
		for (i = 0, j = 0; i < 77; i++) {
J
Johannes Berg 已提交
1519
			if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
S
Sujith 已提交
1520
				ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
1521 1522 1523
			if (j == ATH_RATE_MAX)
				break;
		}
S
Sujith 已提交
1524
		ath_rc_priv->neg_ht_rates.rs_nrates = j;
1525
	}
S
Sujith 已提交
1526

1527
	ath_rc_init(sc, priv_sta, sband, sta);
1528 1529
}

1530
static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1531
{
1532
	return hw->priv;
1533 1534 1535 1536 1537 1538 1539
}

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

1540
static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
1541 1542
{
	struct ath_softc *sc = priv;
S
Sujith 已提交
1543
	struct ath_rate_priv *rate_priv;
1544

S
Sujith 已提交
1545
	rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
1546
	if (!rate_priv) {
S
Sujith 已提交
1547 1548 1549
		DPRINTF(sc, ATH_DBG_FATAL,
			"%s: Unable to allocate private rc structure\n",
			__func__);
1550 1551
		return NULL;
	}
S
Sujith 已提交
1552 1553

	rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
S
Sujith 已提交
1554
	rate_priv->tx_triglevel_max = sc->sc_ah->ah_caps.tx_triglevel_max;
S
Sujith 已提交
1555

1556 1557 1558
	return rate_priv;
}

1559 1560
static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
			      void *priv_sta)
1561
{
S
Sujith 已提交
1562
	struct ath_rate_priv *rate_priv = priv_sta;
S
Sujith 已提交
1563
	kfree(rate_priv);
1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574
}

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,
	.alloc = ath_rate_alloc,
	.free = ath_rate_free,
	.alloc_sta = ath_rate_alloc_sta,
1575
	.free_sta = ath_rate_free_sta,
1576 1577
};

S
Sujith 已提交
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606
static void ath_setup_rate_table(struct ath_softc *sc,
				 struct ath_rate_table *rate_table)
{
	int i;

	for (i = 0; i < 256; i++)
		rate_table->rateCodeToIndex[i] = (u8)-1;

	for (i = 0; i < rate_table->rate_cnt; i++) {
		u8 code = rate_table->info[i].ratecode;
		u8 cix = rate_table->info[i].ctrl_rate;
		u8 sh = rate_table->info[i].short_preamble;

		rate_table->rateCodeToIndex[code] = i;
		rate_table->rateCodeToIndex[code | sh] = i;

		rate_table->info[i].lpAckDuration =
			ath9k_hw_computetxtime(sc->sc_ah, rate_table,
					       WLAN_CTRL_FRAME_SIZE,
					       cix,
					       false);
		rate_table->info[i].spAckDuration =
			ath9k_hw_computetxtime(sc->sc_ah, rate_table,
					       WLAN_CTRL_FRAME_SIZE,
					       cix,
					       true);
	}
}

S
Sujith 已提交
1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626
void ath_rate_attach(struct ath_softc *sc)
{
	sc->hw_rate_table[ATH9K_MODE_11B] =
		&ar5416_11b_ratetable;
	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;
S
Sujith 已提交
1627 1628 1629 1630 1631 1632

	ath_setup_rate_table(sc, &ar5416_11b_ratetable);
	ath_setup_rate_table(sc, &ar5416_11a_ratetable);
	ath_setup_rate_table(sc, &ar5416_11g_ratetable);
	ath_setup_rate_table(sc, &ar5416_11na_ratetable);
	ath_setup_rate_table(sc, &ar5416_11ng_ratetable);
S
Sujith 已提交
1633 1634
}

1635 1636 1637 1638 1639 1640 1641 1642 1643
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);
}