Merge branch 'for-2.6.37/drivers' into for-linus
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / net / wireless / ath / ath9k / ar9003_eeprom.c
1 /*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include "hw.h"
18 #include "ar9003_phy.h"
19 #include "ar9003_eeprom.h"
20
21 #define COMP_HDR_LEN 4
22 #define COMP_CKSUM_LEN 2
23
24 #define AR_CH0_TOP (0x00016288)
25 #define AR_CH0_TOP_XPABIASLVL (0x3)
26 #define AR_CH0_TOP_XPABIASLVL_S (8)
27
28 #define AR_CH0_THERM (0x00016290)
29 #define AR_CH0_THERM_SPARE (0x3f)
30 #define AR_CH0_THERM_SPARE_S (0)
31
32 #define AR_SWITCH_TABLE_COM_ALL (0xffff)
33 #define AR_SWITCH_TABLE_COM_ALL_S (0)
34
35 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
36 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
37
38 #define AR_SWITCH_TABLE_ALL (0xfff)
39 #define AR_SWITCH_TABLE_ALL_S (0)
40
41 #define LE16(x) __constant_cpu_to_le16(x)
42 #define LE32(x) __constant_cpu_to_le32(x)
43
44 /* Local defines to distinguish between extension and control CTL's */
45 #define EXT_ADDITIVE (0x8000)
46 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
47 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
48 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
49 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
50 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
51 #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */
52 #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */
53 #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */
54
55 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
56 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
57
58 static const struct ar9300_eeprom ar9300_default = {
59 .eepromVersion = 2,
60 .templateVersion = 2,
61 .macAddr = {1, 2, 3, 4, 5, 6},
62 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
64 .baseEepHeader = {
65 .regDmn = { LE16(0), LE16(0x1f) },
66 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
67 .opCapFlags = {
68 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
69 .eepMisc = 0,
70 },
71 .rfSilent = 0,
72 .blueToothOptions = 0,
73 .deviceCap = 0,
74 .deviceType = 5, /* takes lower byte in eeprom location */
75 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
76 .params_for_tuning_caps = {0, 0},
77 .featureEnable = 0x0c,
78 /*
79 * bit0 - enable tx temp comp - disabled
80 * bit1 - enable tx volt comp - disabled
81 * bit2 - enable fastClock - enabled
82 * bit3 - enable doubling - enabled
83 * bit4 - enable internal regulator - disabled
84 * bit5 - enable pa predistortion - disabled
85 */
86 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
87 .eepromWriteEnableGpio = 3,
88 .wlanDisableGpio = 0,
89 .wlanLedGpio = 8,
90 .rxBandSelectGpio = 0xff,
91 .txrxgain = 0,
92 .swreg = 0,
93 },
94 .modalHeader2G = {
95 /* ar9300_modal_eep_header 2g */
96 /* 4 idle,t1,t2,b(4 bits per setting) */
97 .antCtrlCommon = LE32(0x110),
98 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
99 .antCtrlCommon2 = LE32(0x22222),
100
101 /*
102 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
103 * rx1, rx12, b (2 bits each)
104 */
105 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
106
107 /*
108 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
109 * for ar9280 (0xa20c/b20c 5:0)
110 */
111 .xatten1DB = {0, 0, 0},
112
113 /*
114 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
115 * for ar9280 (0xa20c/b20c 16:12
116 */
117 .xatten1Margin = {0, 0, 0},
118 .tempSlope = 36,
119 .voltSlope = 0,
120
121 /*
122 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
123 * channels in usual fbin coding format
124 */
125 .spurChans = {0, 0, 0, 0, 0},
126
127 /*
128 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
129 * if the register is per chain
130 */
131 .noiseFloorThreshCh = {-1, 0, 0},
132 .ob = {1, 1, 1},/* 3 chain */
133 .db_stage2 = {1, 1, 1}, /* 3 chain */
134 .db_stage3 = {0, 0, 0},
135 .db_stage4 = {0, 0, 0},
136 .xpaBiasLvl = 0,
137 .txFrameToDataStart = 0x0e,
138 .txFrameToPaOn = 0x0e,
139 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
140 .antennaGain = 0,
141 .switchSettling = 0x2c,
142 .adcDesiredSize = -30,
143 .txEndToXpaOff = 0,
144 .txEndToRxOn = 0x2,
145 .txFrameToXpaOn = 0xe,
146 .thresh62 = 28,
147 .papdRateMaskHt20 = LE32(0x80c080),
148 .papdRateMaskHt40 = LE32(0x80c080),
149 .futureModal = {
150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
151 0, 0, 0, 0, 0, 0, 0, 0
152 },
153 },
154 .calFreqPier2G = {
155 FREQ2FBIN(2412, 1),
156 FREQ2FBIN(2437, 1),
157 FREQ2FBIN(2472, 1),
158 },
159 /* ar9300_cal_data_per_freq_op_loop 2g */
160 .calPierData2G = {
161 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
162 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
163 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
164 },
165 .calTarget_freqbin_Cck = {
166 FREQ2FBIN(2412, 1),
167 FREQ2FBIN(2484, 1),
168 },
169 .calTarget_freqbin_2G = {
170 FREQ2FBIN(2412, 1),
171 FREQ2FBIN(2437, 1),
172 FREQ2FBIN(2472, 1)
173 },
174 .calTarget_freqbin_2GHT20 = {
175 FREQ2FBIN(2412, 1),
176 FREQ2FBIN(2437, 1),
177 FREQ2FBIN(2472, 1)
178 },
179 .calTarget_freqbin_2GHT40 = {
180 FREQ2FBIN(2412, 1),
181 FREQ2FBIN(2437, 1),
182 FREQ2FBIN(2472, 1)
183 },
184 .calTargetPowerCck = {
185 /* 1L-5L,5S,11L,11S */
186 { {36, 36, 36, 36} },
187 { {36, 36, 36, 36} },
188 },
189 .calTargetPower2G = {
190 /* 6-24,36,48,54 */
191 { {32, 32, 28, 24} },
192 { {32, 32, 28, 24} },
193 { {32, 32, 28, 24} },
194 },
195 .calTargetPower2GHT20 = {
196 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
197 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
198 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
199 },
200 .calTargetPower2GHT40 = {
201 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
202 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
203 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
204 },
205 .ctlIndex_2G = {
206 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
207 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
208 },
209 .ctl_freqbin_2G = {
210 {
211 FREQ2FBIN(2412, 1),
212 FREQ2FBIN(2417, 1),
213 FREQ2FBIN(2457, 1),
214 FREQ2FBIN(2462, 1)
215 },
216 {
217 FREQ2FBIN(2412, 1),
218 FREQ2FBIN(2417, 1),
219 FREQ2FBIN(2462, 1),
220 0xFF,
221 },
222
223 {
224 FREQ2FBIN(2412, 1),
225 FREQ2FBIN(2417, 1),
226 FREQ2FBIN(2462, 1),
227 0xFF,
228 },
229 {
230 FREQ2FBIN(2422, 1),
231 FREQ2FBIN(2427, 1),
232 FREQ2FBIN(2447, 1),
233 FREQ2FBIN(2452, 1)
234 },
235
236 {
237 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
238 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
239 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
240 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
241 },
242
243 {
244 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
245 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
246 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
247 0,
248 },
249
250 {
251 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
252 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
253 FREQ2FBIN(2472, 1),
254 0,
255 },
256
257 {
258 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
259 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
260 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
261 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
262 },
263
264 {
265 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
266 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
267 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
268 },
269
270 {
271 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
272 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
273 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
274 0
275 },
276
277 {
278 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
279 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
280 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
281 0
282 },
283
284 {
285 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
286 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
287 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
288 /* Data[11].ctlEdges[3].bChannel */
289 FREQ2FBIN(2462, 1),
290 }
291 },
292 .ctlPowerData_2G = {
293 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
294 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
295 { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
296
297 { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
298 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
299 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
300
301 { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
302 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
303 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
304
305 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
306 { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
307 },
308 .modalHeader5G = {
309 /* 4 idle,t1,t2,b (4 bits per setting) */
310 .antCtrlCommon = LE32(0x110),
311 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
312 .antCtrlCommon2 = LE32(0x22222),
313 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
314 .antCtrlChain = {
315 LE16(0x000), LE16(0x000), LE16(0x000),
316 },
317 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
318 .xatten1DB = {0, 0, 0},
319
320 /*
321 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
322 * for merlin (0xa20c/b20c 16:12
323 */
324 .xatten1Margin = {0, 0, 0},
325 .tempSlope = 68,
326 .voltSlope = 0,
327 /* spurChans spur channels in usual fbin coding format */
328 .spurChans = {0, 0, 0, 0, 0},
329 /* noiseFloorThreshCh Check if the register is per chain */
330 .noiseFloorThreshCh = {-1, 0, 0},
331 .ob = {3, 3, 3}, /* 3 chain */
332 .db_stage2 = {3, 3, 3}, /* 3 chain */
333 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
334 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
335 .xpaBiasLvl = 0,
336 .txFrameToDataStart = 0x0e,
337 .txFrameToPaOn = 0x0e,
338 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
339 .antennaGain = 0,
340 .switchSettling = 0x2d,
341 .adcDesiredSize = -30,
342 .txEndToXpaOff = 0,
343 .txEndToRxOn = 0x2,
344 .txFrameToXpaOn = 0xe,
345 .thresh62 = 28,
346 .papdRateMaskHt20 = LE32(0xf0e0e0),
347 .papdRateMaskHt40 = LE32(0xf0e0e0),
348 .futureModal = {
349 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
350 0, 0, 0, 0, 0, 0, 0, 0
351 },
352 },
353 .calFreqPier5G = {
354 FREQ2FBIN(5180, 0),
355 FREQ2FBIN(5220, 0),
356 FREQ2FBIN(5320, 0),
357 FREQ2FBIN(5400, 0),
358 FREQ2FBIN(5500, 0),
359 FREQ2FBIN(5600, 0),
360 FREQ2FBIN(5725, 0),
361 FREQ2FBIN(5825, 0)
362 },
363 .calPierData5G = {
364 {
365 {0, 0, 0, 0, 0},
366 {0, 0, 0, 0, 0},
367 {0, 0, 0, 0, 0},
368 {0, 0, 0, 0, 0},
369 {0, 0, 0, 0, 0},
370 {0, 0, 0, 0, 0},
371 {0, 0, 0, 0, 0},
372 {0, 0, 0, 0, 0},
373 },
374 {
375 {0, 0, 0, 0, 0},
376 {0, 0, 0, 0, 0},
377 {0, 0, 0, 0, 0},
378 {0, 0, 0, 0, 0},
379 {0, 0, 0, 0, 0},
380 {0, 0, 0, 0, 0},
381 {0, 0, 0, 0, 0},
382 {0, 0, 0, 0, 0},
383 },
384 {
385 {0, 0, 0, 0, 0},
386 {0, 0, 0, 0, 0},
387 {0, 0, 0, 0, 0},
388 {0, 0, 0, 0, 0},
389 {0, 0, 0, 0, 0},
390 {0, 0, 0, 0, 0},
391 {0, 0, 0, 0, 0},
392 {0, 0, 0, 0, 0},
393 },
394
395 },
396 .calTarget_freqbin_5G = {
397 FREQ2FBIN(5180, 0),
398 FREQ2FBIN(5220, 0),
399 FREQ2FBIN(5320, 0),
400 FREQ2FBIN(5400, 0),
401 FREQ2FBIN(5500, 0),
402 FREQ2FBIN(5600, 0),
403 FREQ2FBIN(5725, 0),
404 FREQ2FBIN(5825, 0)
405 },
406 .calTarget_freqbin_5GHT20 = {
407 FREQ2FBIN(5180, 0),
408 FREQ2FBIN(5240, 0),
409 FREQ2FBIN(5320, 0),
410 FREQ2FBIN(5500, 0),
411 FREQ2FBIN(5700, 0),
412 FREQ2FBIN(5745, 0),
413 FREQ2FBIN(5725, 0),
414 FREQ2FBIN(5825, 0)
415 },
416 .calTarget_freqbin_5GHT40 = {
417 FREQ2FBIN(5180, 0),
418 FREQ2FBIN(5240, 0),
419 FREQ2FBIN(5320, 0),
420 FREQ2FBIN(5500, 0),
421 FREQ2FBIN(5700, 0),
422 FREQ2FBIN(5745, 0),
423 FREQ2FBIN(5725, 0),
424 FREQ2FBIN(5825, 0)
425 },
426 .calTargetPower5G = {
427 /* 6-24,36,48,54 */
428 { {20, 20, 20, 10} },
429 { {20, 20, 20, 10} },
430 { {20, 20, 20, 10} },
431 { {20, 20, 20, 10} },
432 { {20, 20, 20, 10} },
433 { {20, 20, 20, 10} },
434 { {20, 20, 20, 10} },
435 { {20, 20, 20, 10} },
436 },
437 .calTargetPower5GHT20 = {
438 /*
439 * 0_8_16,1-3_9-11_17-19,
440 * 4,5,6,7,12,13,14,15,20,21,22,23
441 */
442 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
443 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
444 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
445 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
446 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
447 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
448 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
449 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
450 },
451 .calTargetPower5GHT40 = {
452 /*
453 * 0_8_16,1-3_9-11_17-19,
454 * 4,5,6,7,12,13,14,15,20,21,22,23
455 */
456 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
457 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
458 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
459 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
460 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
461 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
462 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
463 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
464 },
465 .ctlIndex_5G = {
466 0x10, 0x16, 0x18, 0x40, 0x46,
467 0x48, 0x30, 0x36, 0x38
468 },
469 .ctl_freqbin_5G = {
470 {
471 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
472 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
473 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
474 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
475 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
476 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
477 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
478 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
479 },
480 {
481 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
482 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
483 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
484 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
485 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
486 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
487 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
488 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
489 },
490
491 {
492 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
493 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
494 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
495 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
496 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
497 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
498 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
499 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
500 },
501
502 {
503 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
504 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
505 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
506 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
507 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
508 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
509 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
510 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
511 },
512
513 {
514 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
515 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
516 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
517 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
518 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
519 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
520 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
521 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
522 },
523
524 {
525 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
526 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
527 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
528 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
529 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
530 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
531 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
532 /* Data[5].ctlEdges[7].bChannel */ 0xFF
533 },
534
535 {
536 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
537 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
538 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
539 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
540 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
541 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
542 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
543 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
544 },
545
546 {
547 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
548 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
549 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
550 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
551 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
552 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
553 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
554 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
555 },
556
557 {
558 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
559 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
560 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
561 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
562 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
563 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
564 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
565 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
566 }
567 },
568 .ctlPowerData_5G = {
569 {
570 {
571 {60, 1}, {60, 1}, {60, 1}, {60, 1},
572 {60, 1}, {60, 1}, {60, 1}, {60, 0},
573 }
574 },
575 {
576 {
577 {60, 1}, {60, 1}, {60, 1}, {60, 1},
578 {60, 1}, {60, 1}, {60, 1}, {60, 0},
579 }
580 },
581 {
582 {
583 {60, 0}, {60, 1}, {60, 0}, {60, 1},
584 {60, 1}, {60, 1}, {60, 1}, {60, 1},
585 }
586 },
587 {
588 {
589 {60, 0}, {60, 1}, {60, 1}, {60, 0},
590 {60, 1}, {60, 0}, {60, 0}, {60, 0},
591 }
592 },
593 {
594 {
595 {60, 1}, {60, 1}, {60, 1}, {60, 0},
596 {60, 0}, {60, 0}, {60, 0}, {60, 0},
597 }
598 },
599 {
600 {
601 {60, 1}, {60, 1}, {60, 1}, {60, 1},
602 {60, 1}, {60, 0}, {60, 0}, {60, 0},
603 }
604 },
605 {
606 {
607 {60, 1}, {60, 1}, {60, 1}, {60, 1},
608 {60, 1}, {60, 1}, {60, 1}, {60, 1},
609 }
610 },
611 {
612 {
613 {60, 1}, {60, 1}, {60, 0}, {60, 1},
614 {60, 1}, {60, 1}, {60, 1}, {60, 0},
615 }
616 },
617 {
618 {
619 {60, 1}, {60, 0}, {60, 1}, {60, 1},
620 {60, 1}, {60, 1}, {60, 0}, {60, 1},
621 }
622 },
623 }
624 };
625
626 static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
627 {
628 if (fbin == AR9300_BCHAN_UNUSED)
629 return fbin;
630
631 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
632 }
633
634 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
635 {
636 return 0;
637 }
638
639 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
640 enum eeprom_param param)
641 {
642 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
643 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
644
645 switch (param) {
646 case EEP_MAC_LSW:
647 return eep->macAddr[0] << 8 | eep->macAddr[1];
648 case EEP_MAC_MID:
649 return eep->macAddr[2] << 8 | eep->macAddr[3];
650 case EEP_MAC_MSW:
651 return eep->macAddr[4] << 8 | eep->macAddr[5];
652 case EEP_REG_0:
653 return le16_to_cpu(pBase->regDmn[0]);
654 case EEP_REG_1:
655 return le16_to_cpu(pBase->regDmn[1]);
656 case EEP_OP_CAP:
657 return pBase->deviceCap;
658 case EEP_OP_MODE:
659 return pBase->opCapFlags.opFlags;
660 case EEP_RF_SILENT:
661 return pBase->rfSilent;
662 case EEP_TX_MASK:
663 return (pBase->txrxMask >> 4) & 0xf;
664 case EEP_RX_MASK:
665 return pBase->txrxMask & 0xf;
666 case EEP_DRIVE_STRENGTH:
667 #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1
668 return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
669 case EEP_INTERNAL_REGULATOR:
670 /* Bit 4 is internal regulator flag */
671 return (pBase->featureEnable & 0x10) >> 4;
672 case EEP_SWREG:
673 return le32_to_cpu(pBase->swreg);
674 case EEP_PAPRD:
675 return !!(pBase->featureEnable & BIT(5));
676 default:
677 return 0;
678 }
679 }
680
681 static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
682 u8 *buffer)
683 {
684 u16 val;
685
686 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
687 return false;
688
689 *buffer = (val >> (8 * (address % 2))) & 0xff;
690 return true;
691 }
692
693 static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
694 u8 *buffer)
695 {
696 u16 val;
697
698 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
699 return false;
700
701 buffer[0] = val >> 8;
702 buffer[1] = val & 0xff;
703
704 return true;
705 }
706
707 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
708 int count)
709 {
710 struct ath_common *common = ath9k_hw_common(ah);
711 int i;
712
713 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
714 ath_print(common, ATH_DBG_EEPROM,
715 "eeprom address not in range\n");
716 return false;
717 }
718
719 /*
720 * Since we're reading the bytes in reverse order from a little-endian
721 * word stream, an even address means we only use the lower half of
722 * the 16-bit word at that address
723 */
724 if (address % 2 == 0) {
725 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
726 goto error;
727
728 count--;
729 }
730
731 for (i = 0; i < count / 2; i++) {
732 if (!ar9300_eeprom_read_word(common, address, buffer))
733 goto error;
734
735 address -= 2;
736 buffer += 2;
737 }
738
739 if (count % 2)
740 if (!ar9300_eeprom_read_byte(common, address, buffer))
741 goto error;
742
743 return true;
744
745 error:
746 ath_print(common, ATH_DBG_EEPROM,
747 "unable to read eeprom region at offset %d\n", address);
748 return false;
749 }
750
751 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
752 int *length, int *major, int *minor)
753 {
754 unsigned long value[4];
755
756 value[0] = best[0];
757 value[1] = best[1];
758 value[2] = best[2];
759 value[3] = best[3];
760 *code = ((value[0] >> 5) & 0x0007);
761 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
762 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
763 *major = (value[2] & 0x000f);
764 *minor = (value[3] & 0x00ff);
765 }
766
767 static u16 ar9300_comp_cksum(u8 *data, int dsize)
768 {
769 int it, checksum = 0;
770
771 for (it = 0; it < dsize; it++) {
772 checksum += data[it];
773 checksum &= 0xffff;
774 }
775
776 return checksum;
777 }
778
779 static bool ar9300_uncompress_block(struct ath_hw *ah,
780 u8 *mptr,
781 int mdataSize,
782 u8 *block,
783 int size)
784 {
785 int it;
786 int spot;
787 int offset;
788 int length;
789 struct ath_common *common = ath9k_hw_common(ah);
790
791 spot = 0;
792
793 for (it = 0; it < size; it += (length+2)) {
794 offset = block[it];
795 offset &= 0xff;
796 spot += offset;
797 length = block[it+1];
798 length &= 0xff;
799
800 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
801 ath_print(common, ATH_DBG_EEPROM,
802 "Restore at %d: spot=%d "
803 "offset=%d length=%d\n",
804 it, spot, offset, length);
805 memcpy(&mptr[spot], &block[it+2], length);
806 spot += length;
807 } else if (length > 0) {
808 ath_print(common, ATH_DBG_EEPROM,
809 "Bad restore at %d: spot=%d "
810 "offset=%d length=%d\n",
811 it, spot, offset, length);
812 return false;
813 }
814 }
815 return true;
816 }
817
818 static int ar9300_compress_decision(struct ath_hw *ah,
819 int it,
820 int code,
821 int reference,
822 u8 *mptr,
823 u8 *word, int length, int mdata_size)
824 {
825 struct ath_common *common = ath9k_hw_common(ah);
826 u8 *dptr;
827
828 switch (code) {
829 case _CompressNone:
830 if (length != mdata_size) {
831 ath_print(common, ATH_DBG_EEPROM,
832 "EEPROM structure size mismatch"
833 "memory=%d eeprom=%d\n", mdata_size, length);
834 return -1;
835 }
836 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
837 ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
838 " uncompressed, length %d\n", it, length);
839 break;
840 case _CompressBlock:
841 if (reference == 0) {
842 dptr = mptr;
843 } else {
844 if (reference != 2) {
845 ath_print(common, ATH_DBG_EEPROM,
846 "cant find reference eeprom"
847 "struct %d\n", reference);
848 return -1;
849 }
850 memcpy(mptr, &ar9300_default, mdata_size);
851 }
852 ath_print(common, ATH_DBG_EEPROM,
853 "restore eeprom %d: block, reference %d,"
854 " length %d\n", it, reference, length);
855 ar9300_uncompress_block(ah, mptr, mdata_size,
856 (u8 *) (word + COMP_HDR_LEN), length);
857 break;
858 default:
859 ath_print(common, ATH_DBG_EEPROM, "unknown compression"
860 " code %d\n", code);
861 return -1;
862 }
863 return 0;
864 }
865
866 /*
867 * Read the configuration data from the eeprom.
868 * The data can be put in any specified memory buffer.
869 *
870 * Returns -1 on error.
871 * Returns address of next memory location on success.
872 */
873 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
874 u8 *mptr, int mdata_size)
875 {
876 #define MDEFAULT 15
877 #define MSTATE 100
878 int cptr;
879 u8 *word;
880 int code;
881 int reference, length, major, minor;
882 int osize;
883 int it;
884 u16 checksum, mchecksum;
885 struct ath_common *common = ath9k_hw_common(ah);
886
887 word = kzalloc(2048, GFP_KERNEL);
888 if (!word)
889 return -1;
890
891 memcpy(mptr, &ar9300_default, mdata_size);
892
893 cptr = AR9300_BASE_ADDR;
894 for (it = 0; it < MSTATE; it++) {
895 if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
896 goto fail;
897
898 if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
899 word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
900 && word[2] == 0xff && word[3] == 0xff))
901 break;
902
903 ar9300_comp_hdr_unpack(word, &code, &reference,
904 &length, &major, &minor);
905 ath_print(common, ATH_DBG_EEPROM,
906 "Found block at %x: code=%d ref=%d"
907 "length=%d major=%d minor=%d\n", cptr, code,
908 reference, length, major, minor);
909 if (length >= 1024) {
910 ath_print(common, ATH_DBG_EEPROM,
911 "Skipping bad header\n");
912 cptr -= COMP_HDR_LEN;
913 continue;
914 }
915
916 osize = length;
917 ar9300_read_eeprom(ah, cptr, word,
918 COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
919 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
920 mchecksum = word[COMP_HDR_LEN + osize] |
921 (word[COMP_HDR_LEN + osize + 1] << 8);
922 ath_print(common, ATH_DBG_EEPROM,
923 "checksum %x %x\n", checksum, mchecksum);
924 if (checksum == mchecksum) {
925 ar9300_compress_decision(ah, it, code, reference, mptr,
926 word, length, mdata_size);
927 } else {
928 ath_print(common, ATH_DBG_EEPROM,
929 "skipping block with bad checksum\n");
930 }
931 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
932 }
933
934 kfree(word);
935 return cptr;
936
937 fail:
938 kfree(word);
939 return -1;
940 }
941
942 /*
943 * Restore the configuration structure by reading the eeprom.
944 * This function destroys any existing in-memory structure
945 * content.
946 */
947 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
948 {
949 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
950
951 if (ar9300_eeprom_restore_internal(ah, mptr,
952 sizeof(struct ar9300_eeprom)) < 0)
953 return false;
954
955 return true;
956 }
957
958 /* XXX: review hardware docs */
959 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
960 {
961 return ah->eeprom.ar9300_eep.eepromVersion;
962 }
963
964 /* XXX: could be read from the eepromVersion, not sure yet */
965 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
966 {
967 return 0;
968 }
969
970 static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
971 enum ath9k_hal_freq_band freq_band)
972 {
973 return 1;
974 }
975
976 static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
977 struct ath9k_channel *chan)
978 {
979 return -EINVAL;
980 }
981
982 static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
983 {
984 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
985
986 if (is2ghz)
987 return eep->modalHeader2G.xpaBiasLvl;
988 else
989 return eep->modalHeader5G.xpaBiasLvl;
990 }
991
992 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
993 {
994 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
995 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
996 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
997 ((bias >> 2) & 0x3));
998 }
999
1000 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
1001 {
1002 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1003 __le32 val;
1004
1005 if (is2ghz)
1006 val = eep->modalHeader2G.antCtrlCommon;
1007 else
1008 val = eep->modalHeader5G.antCtrlCommon;
1009 return le32_to_cpu(val);
1010 }
1011
1012 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
1013 {
1014 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1015 __le32 val;
1016
1017 if (is2ghz)
1018 val = eep->modalHeader2G.antCtrlCommon2;
1019 else
1020 val = eep->modalHeader5G.antCtrlCommon2;
1021 return le32_to_cpu(val);
1022 }
1023
1024 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
1025 int chain,
1026 bool is2ghz)
1027 {
1028 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1029 __le16 val = 0;
1030
1031 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
1032 if (is2ghz)
1033 val = eep->modalHeader2G.antCtrlChain[chain];
1034 else
1035 val = eep->modalHeader5G.antCtrlChain[chain];
1036 }
1037
1038 return le16_to_cpu(val);
1039 }
1040
1041 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
1042 {
1043 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
1044 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
1045
1046 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
1047 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
1048
1049 value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
1050 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
1051
1052 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
1053 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
1054
1055 value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
1056 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
1057 }
1058
1059 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
1060 {
1061 int drive_strength;
1062 unsigned long reg;
1063
1064 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
1065
1066 if (!drive_strength)
1067 return;
1068
1069 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
1070 reg &= ~0x00ffffc0;
1071 reg |= 0x5 << 21;
1072 reg |= 0x5 << 18;
1073 reg |= 0x5 << 15;
1074 reg |= 0x5 << 12;
1075 reg |= 0x5 << 9;
1076 reg |= 0x5 << 6;
1077 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
1078
1079 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
1080 reg &= ~0xffffffe0;
1081 reg |= 0x5 << 29;
1082 reg |= 0x5 << 26;
1083 reg |= 0x5 << 23;
1084 reg |= 0x5 << 20;
1085 reg |= 0x5 << 17;
1086 reg |= 0x5 << 14;
1087 reg |= 0x5 << 11;
1088 reg |= 0x5 << 8;
1089 reg |= 0x5 << 5;
1090 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
1091
1092 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
1093 reg &= ~0xff800000;
1094 reg |= 0x5 << 29;
1095 reg |= 0x5 << 26;
1096 reg |= 0x5 << 23;
1097 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
1098 }
1099
1100 static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
1101 {
1102 int internal_regulator =
1103 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
1104
1105 if (internal_regulator) {
1106 /* Internal regulator is ON. Write swreg register. */
1107 int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
1108 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1109 REG_READ(ah, AR_RTC_REG_CONTROL1) &
1110 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
1111 REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
1112 /* Set REG_CONTROL1.SWREG_PROGRAM */
1113 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1114 REG_READ(ah,
1115 AR_RTC_REG_CONTROL1) |
1116 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
1117 } else {
1118 REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1119 (REG_READ(ah,
1120 AR_RTC_SLEEP_CLK) |
1121 AR_RTC_FORCE_SWREG_PRD));
1122 }
1123 }
1124
1125 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
1126 struct ath9k_channel *chan)
1127 {
1128 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
1129 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
1130 ar9003_hw_drive_strength_apply(ah);
1131 ar9003_hw_internal_regulator_apply(ah);
1132 }
1133
1134 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
1135 struct ath9k_channel *chan)
1136 {
1137 }
1138
1139 /*
1140 * Returns the interpolated y value corresponding to the specified x value
1141 * from the np ordered pairs of data (px,py).
1142 * The pairs do not have to be in any order.
1143 * If the specified x value is less than any of the px,
1144 * the returned y value is equal to the py for the lowest px.
1145 * If the specified x value is greater than any of the px,
1146 * the returned y value is equal to the py for the highest px.
1147 */
1148 static int ar9003_hw_power_interpolate(int32_t x,
1149 int32_t *px, int32_t *py, u_int16_t np)
1150 {
1151 int ip = 0;
1152 int lx = 0, ly = 0, lhave = 0;
1153 int hx = 0, hy = 0, hhave = 0;
1154 int dx = 0;
1155 int y = 0;
1156
1157 lhave = 0;
1158 hhave = 0;
1159
1160 /* identify best lower and higher x calibration measurement */
1161 for (ip = 0; ip < np; ip++) {
1162 dx = x - px[ip];
1163
1164 /* this measurement is higher than our desired x */
1165 if (dx <= 0) {
1166 if (!hhave || dx > (x - hx)) {
1167 /* new best higher x measurement */
1168 hx = px[ip];
1169 hy = py[ip];
1170 hhave = 1;
1171 }
1172 }
1173 /* this measurement is lower than our desired x */
1174 if (dx >= 0) {
1175 if (!lhave || dx < (x - lx)) {
1176 /* new best lower x measurement */
1177 lx = px[ip];
1178 ly = py[ip];
1179 lhave = 1;
1180 }
1181 }
1182 }
1183
1184 /* the low x is good */
1185 if (lhave) {
1186 /* so is the high x */
1187 if (hhave) {
1188 /* they're the same, so just pick one */
1189 if (hx == lx)
1190 y = ly;
1191 else /* interpolate */
1192 y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
1193 } else /* only low is good, use it */
1194 y = ly;
1195 } else if (hhave) /* only high is good, use it */
1196 y = hy;
1197 else /* nothing is good,this should never happen unless np=0, ???? */
1198 y = -(1 << 30);
1199 return y;
1200 }
1201
1202 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
1203 u16 rateIndex, u16 freq, bool is2GHz)
1204 {
1205 u16 numPiers, i;
1206 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1207 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1208 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1209 struct cal_tgt_pow_legacy *pEepromTargetPwr;
1210 u8 *pFreqBin;
1211
1212 if (is2GHz) {
1213 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
1214 pEepromTargetPwr = eep->calTargetPower2G;
1215 pFreqBin = eep->calTarget_freqbin_2G;
1216 } else {
1217 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1218 pEepromTargetPwr = eep->calTargetPower5G;
1219 pFreqBin = eep->calTarget_freqbin_5G;
1220 }
1221
1222 /*
1223 * create array of channels and targetpower from
1224 * targetpower piers stored on eeprom
1225 */
1226 for (i = 0; i < numPiers; i++) {
1227 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1228 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1229 }
1230
1231 /* interpolate to get target power for given frequency */
1232 return (u8) ar9003_hw_power_interpolate((s32) freq,
1233 freqArray,
1234 targetPowerArray, numPiers);
1235 }
1236
1237 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
1238 u16 rateIndex,
1239 u16 freq, bool is2GHz)
1240 {
1241 u16 numPiers, i;
1242 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1243 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1244 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1245 struct cal_tgt_pow_ht *pEepromTargetPwr;
1246 u8 *pFreqBin;
1247
1248 if (is2GHz) {
1249 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
1250 pEepromTargetPwr = eep->calTargetPower2GHT20;
1251 pFreqBin = eep->calTarget_freqbin_2GHT20;
1252 } else {
1253 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1254 pEepromTargetPwr = eep->calTargetPower5GHT20;
1255 pFreqBin = eep->calTarget_freqbin_5GHT20;
1256 }
1257
1258 /*
1259 * create array of channels and targetpower
1260 * from targetpower piers stored on eeprom
1261 */
1262 for (i = 0; i < numPiers; i++) {
1263 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1264 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1265 }
1266
1267 /* interpolate to get target power for given frequency */
1268 return (u8) ar9003_hw_power_interpolate((s32) freq,
1269 freqArray,
1270 targetPowerArray, numPiers);
1271 }
1272
1273 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
1274 u16 rateIndex,
1275 u16 freq, bool is2GHz)
1276 {
1277 u16 numPiers, i;
1278 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
1279 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
1280 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1281 struct cal_tgt_pow_ht *pEepromTargetPwr;
1282 u8 *pFreqBin;
1283
1284 if (is2GHz) {
1285 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
1286 pEepromTargetPwr = eep->calTargetPower2GHT40;
1287 pFreqBin = eep->calTarget_freqbin_2GHT40;
1288 } else {
1289 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
1290 pEepromTargetPwr = eep->calTargetPower5GHT40;
1291 pFreqBin = eep->calTarget_freqbin_5GHT40;
1292 }
1293
1294 /*
1295 * create array of channels and targetpower from
1296 * targetpower piers stored on eeprom
1297 */
1298 for (i = 0; i < numPiers; i++) {
1299 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1300 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1301 }
1302
1303 /* interpolate to get target power for given frequency */
1304 return (u8) ar9003_hw_power_interpolate((s32) freq,
1305 freqArray,
1306 targetPowerArray, numPiers);
1307 }
1308
1309 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
1310 u16 rateIndex, u16 freq)
1311 {
1312 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
1313 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1314 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1315 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1316 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
1317 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
1318
1319 /*
1320 * create array of channels and targetpower from
1321 * targetpower piers stored on eeprom
1322 */
1323 for (i = 0; i < numPiers; i++) {
1324 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
1325 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1326 }
1327
1328 /* interpolate to get target power for given frequency */
1329 return (u8) ar9003_hw_power_interpolate((s32) freq,
1330 freqArray,
1331 targetPowerArray, numPiers);
1332 }
1333
1334 /* Set tx power registers to array of values passed in */
1335 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
1336 {
1337 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
1338 /* make sure forced gain is not set */
1339 REG_WRITE(ah, 0xa458, 0);
1340
1341 /* Write the OFDM power per rate set */
1342
1343 /* 6 (LSB), 9, 12, 18 (MSB) */
1344 REG_WRITE(ah, 0xa3c0,
1345 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
1346 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
1347 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
1348 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1349
1350 /* 24 (LSB), 36, 48, 54 (MSB) */
1351 REG_WRITE(ah, 0xa3c4,
1352 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
1353 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
1354 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
1355 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1356
1357 /* Write the CCK power per rate set */
1358
1359 /* 1L (LSB), reserved, 2L, 2S (MSB) */
1360 REG_WRITE(ah, 0xa3c8,
1361 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
1362 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
1363 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
1364 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
1365
1366 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
1367 REG_WRITE(ah, 0xa3cc,
1368 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
1369 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
1370 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
1371 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
1372 );
1373
1374 /* Write the HT20 power per rate set */
1375
1376 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
1377 REG_WRITE(ah, 0xa3d0,
1378 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
1379 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
1380 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
1381 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
1382 );
1383
1384 /* 6 (LSB), 7, 12, 13 (MSB) */
1385 REG_WRITE(ah, 0xa3d4,
1386 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
1387 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
1388 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
1389 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
1390 );
1391
1392 /* 14 (LSB), 15, 20, 21 */
1393 REG_WRITE(ah, 0xa3e4,
1394 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
1395 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
1396 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
1397 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
1398 );
1399
1400 /* Mixed HT20 and HT40 rates */
1401
1402 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
1403 REG_WRITE(ah, 0xa3e8,
1404 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
1405 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
1406 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
1407 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
1408 );
1409
1410 /*
1411 * Write the HT40 power per rate set
1412 * correct PAR difference between HT40 and HT20/LEGACY
1413 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
1414 */
1415 REG_WRITE(ah, 0xa3d8,
1416 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
1417 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
1418 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
1419 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
1420 );
1421
1422 /* 6 (LSB), 7, 12, 13 (MSB) */
1423 REG_WRITE(ah, 0xa3dc,
1424 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
1425 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
1426 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
1427 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
1428 );
1429
1430 /* 14 (LSB), 15, 20, 21 */
1431 REG_WRITE(ah, 0xa3ec,
1432 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
1433 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
1434 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
1435 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
1436 );
1437
1438 return 0;
1439 #undef POW_SM
1440 }
1441
1442 static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
1443 u8 *targetPowerValT2)
1444 {
1445 /* XXX: hard code for now, need to get from eeprom struct */
1446 u8 ht40PowerIncForPdadc = 0;
1447 bool is2GHz = false;
1448 unsigned int i = 0;
1449 struct ath_common *common = ath9k_hw_common(ah);
1450
1451 if (freq < 4000)
1452 is2GHz = true;
1453
1454 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
1455 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
1456 is2GHz);
1457 targetPowerValT2[ALL_TARGET_LEGACY_36] =
1458 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
1459 is2GHz);
1460 targetPowerValT2[ALL_TARGET_LEGACY_48] =
1461 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
1462 is2GHz);
1463 targetPowerValT2[ALL_TARGET_LEGACY_54] =
1464 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
1465 is2GHz);
1466 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
1467 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
1468 freq);
1469 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
1470 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
1471 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
1472 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
1473 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
1474 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
1475 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
1476 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1477 is2GHz);
1478 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
1479 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1480 freq, is2GHz);
1481 targetPowerValT2[ALL_TARGET_HT20_4] =
1482 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1483 is2GHz);
1484 targetPowerValT2[ALL_TARGET_HT20_5] =
1485 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1486 is2GHz);
1487 targetPowerValT2[ALL_TARGET_HT20_6] =
1488 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1489 is2GHz);
1490 targetPowerValT2[ALL_TARGET_HT20_7] =
1491 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1492 is2GHz);
1493 targetPowerValT2[ALL_TARGET_HT20_12] =
1494 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1495 is2GHz);
1496 targetPowerValT2[ALL_TARGET_HT20_13] =
1497 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1498 is2GHz);
1499 targetPowerValT2[ALL_TARGET_HT20_14] =
1500 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1501 is2GHz);
1502 targetPowerValT2[ALL_TARGET_HT20_15] =
1503 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1504 is2GHz);
1505 targetPowerValT2[ALL_TARGET_HT20_20] =
1506 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1507 is2GHz);
1508 targetPowerValT2[ALL_TARGET_HT20_21] =
1509 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1510 is2GHz);
1511 targetPowerValT2[ALL_TARGET_HT20_22] =
1512 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1513 is2GHz);
1514 targetPowerValT2[ALL_TARGET_HT20_23] =
1515 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1516 is2GHz);
1517 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
1518 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1519 is2GHz) + ht40PowerIncForPdadc;
1520 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
1521 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1522 freq,
1523 is2GHz) + ht40PowerIncForPdadc;
1524 targetPowerValT2[ALL_TARGET_HT40_4] =
1525 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1526 is2GHz) + ht40PowerIncForPdadc;
1527 targetPowerValT2[ALL_TARGET_HT40_5] =
1528 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1529 is2GHz) + ht40PowerIncForPdadc;
1530 targetPowerValT2[ALL_TARGET_HT40_6] =
1531 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1532 is2GHz) + ht40PowerIncForPdadc;
1533 targetPowerValT2[ALL_TARGET_HT40_7] =
1534 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1535 is2GHz) + ht40PowerIncForPdadc;
1536 targetPowerValT2[ALL_TARGET_HT40_12] =
1537 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1538 is2GHz) + ht40PowerIncForPdadc;
1539 targetPowerValT2[ALL_TARGET_HT40_13] =
1540 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1541 is2GHz) + ht40PowerIncForPdadc;
1542 targetPowerValT2[ALL_TARGET_HT40_14] =
1543 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1544 is2GHz) + ht40PowerIncForPdadc;
1545 targetPowerValT2[ALL_TARGET_HT40_15] =
1546 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1547 is2GHz) + ht40PowerIncForPdadc;
1548 targetPowerValT2[ALL_TARGET_HT40_20] =
1549 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1550 is2GHz) + ht40PowerIncForPdadc;
1551 targetPowerValT2[ALL_TARGET_HT40_21] =
1552 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1553 is2GHz) + ht40PowerIncForPdadc;
1554 targetPowerValT2[ALL_TARGET_HT40_22] =
1555 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1556 is2GHz) + ht40PowerIncForPdadc;
1557 targetPowerValT2[ALL_TARGET_HT40_23] =
1558 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1559 is2GHz) + ht40PowerIncForPdadc;
1560
1561 while (i < ar9300RateSize) {
1562 ath_print(common, ATH_DBG_EEPROM,
1563 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1564 i++;
1565
1566 ath_print(common, ATH_DBG_EEPROM,
1567 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1568 i++;
1569
1570 ath_print(common, ATH_DBG_EEPROM,
1571 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1572 i++;
1573
1574 ath_print(common, ATH_DBG_EEPROM,
1575 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
1576 i++;
1577 }
1578 }
1579
1580 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
1581 int mode,
1582 int ipier,
1583 int ichain,
1584 int *pfrequency,
1585 int *pcorrection,
1586 int *ptemperature, int *pvoltage)
1587 {
1588 u8 *pCalPier;
1589 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
1590 int is2GHz;
1591 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1592 struct ath_common *common = ath9k_hw_common(ah);
1593
1594 if (ichain >= AR9300_MAX_CHAINS) {
1595 ath_print(common, ATH_DBG_EEPROM,
1596 "Invalid chain index, must be less than %d\n",
1597 AR9300_MAX_CHAINS);
1598 return -1;
1599 }
1600
1601 if (mode) { /* 5GHz */
1602 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
1603 ath_print(common, ATH_DBG_EEPROM,
1604 "Invalid 5GHz cal pier index, must "
1605 "be less than %d\n",
1606 AR9300_NUM_5G_CAL_PIERS);
1607 return -1;
1608 }
1609 pCalPier = &(eep->calFreqPier5G[ipier]);
1610 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
1611 is2GHz = 0;
1612 } else {
1613 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
1614 ath_print(common, ATH_DBG_EEPROM,
1615 "Invalid 2GHz cal pier index, must "
1616 "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
1617 return -1;
1618 }
1619
1620 pCalPier = &(eep->calFreqPier2G[ipier]);
1621 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
1622 is2GHz = 1;
1623 }
1624
1625 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
1626 *pcorrection = pCalPierStruct->refPower;
1627 *ptemperature = pCalPierStruct->tempMeas;
1628 *pvoltage = pCalPierStruct->voltMeas;
1629
1630 return 0;
1631 }
1632
1633 static int ar9003_hw_power_control_override(struct ath_hw *ah,
1634 int frequency,
1635 int *correction,
1636 int *voltage, int *temperature)
1637 {
1638 int tempSlope = 0;
1639 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1640
1641 REG_RMW(ah, AR_PHY_TPC_11_B0,
1642 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1643 AR_PHY_TPC_OLPC_GAIN_DELTA);
1644 REG_RMW(ah, AR_PHY_TPC_11_B1,
1645 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1646 AR_PHY_TPC_OLPC_GAIN_DELTA);
1647 REG_RMW(ah, AR_PHY_TPC_11_B2,
1648 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1649 AR_PHY_TPC_OLPC_GAIN_DELTA);
1650
1651 /* enable open loop power control on chip */
1652 REG_RMW(ah, AR_PHY_TPC_6_B0,
1653 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1654 AR_PHY_TPC_6_ERROR_EST_MODE);
1655 REG_RMW(ah, AR_PHY_TPC_6_B1,
1656 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1657 AR_PHY_TPC_6_ERROR_EST_MODE);
1658 REG_RMW(ah, AR_PHY_TPC_6_B2,
1659 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1660 AR_PHY_TPC_6_ERROR_EST_MODE);
1661
1662 /*
1663 * enable temperature compensation
1664 * Need to use register names
1665 */
1666 if (frequency < 4000)
1667 tempSlope = eep->modalHeader2G.tempSlope;
1668 else
1669 tempSlope = eep->modalHeader5G.tempSlope;
1670
1671 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
1672 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
1673 temperature[0]);
1674
1675 return 0;
1676 }
1677
1678 /* Apply the recorded correction values. */
1679 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
1680 {
1681 int ichain, ipier, npier;
1682 int mode;
1683 int lfrequency[AR9300_MAX_CHAINS],
1684 lcorrection[AR9300_MAX_CHAINS],
1685 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
1686 int hfrequency[AR9300_MAX_CHAINS],
1687 hcorrection[AR9300_MAX_CHAINS],
1688 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
1689 int fdiff;
1690 int correction[AR9300_MAX_CHAINS],
1691 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
1692 int pfrequency, pcorrection, ptemperature, pvoltage;
1693 struct ath_common *common = ath9k_hw_common(ah);
1694
1695 mode = (frequency >= 4000);
1696 if (mode)
1697 npier = AR9300_NUM_5G_CAL_PIERS;
1698 else
1699 npier = AR9300_NUM_2G_CAL_PIERS;
1700
1701 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1702 lfrequency[ichain] = 0;
1703 hfrequency[ichain] = 100000;
1704 }
1705 /* identify best lower and higher frequency calibration measurement */
1706 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1707 for (ipier = 0; ipier < npier; ipier++) {
1708 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
1709 &pfrequency, &pcorrection,
1710 &ptemperature, &pvoltage)) {
1711 fdiff = frequency - pfrequency;
1712
1713 /*
1714 * this measurement is higher than
1715 * our desired frequency
1716 */
1717 if (fdiff <= 0) {
1718 if (hfrequency[ichain] <= 0 ||
1719 hfrequency[ichain] >= 100000 ||
1720 fdiff >
1721 (frequency - hfrequency[ichain])) {
1722 /*
1723 * new best higher
1724 * frequency measurement
1725 */
1726 hfrequency[ichain] = pfrequency;
1727 hcorrection[ichain] =
1728 pcorrection;
1729 htemperature[ichain] =
1730 ptemperature;
1731 hvoltage[ichain] = pvoltage;
1732 }
1733 }
1734 if (fdiff >= 0) {
1735 if (lfrequency[ichain] <= 0
1736 || fdiff <
1737 (frequency - lfrequency[ichain])) {
1738 /*
1739 * new best lower
1740 * frequency measurement
1741 */
1742 lfrequency[ichain] = pfrequency;
1743 lcorrection[ichain] =
1744 pcorrection;
1745 ltemperature[ichain] =
1746 ptemperature;
1747 lvoltage[ichain] = pvoltage;
1748 }
1749 }
1750 }
1751 }
1752 }
1753
1754 /* interpolate */
1755 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1756 ath_print(common, ATH_DBG_EEPROM,
1757 "ch=%d f=%d low=%d %d h=%d %d\n",
1758 ichain, frequency, lfrequency[ichain],
1759 lcorrection[ichain], hfrequency[ichain],
1760 hcorrection[ichain]);
1761 /* they're the same, so just pick one */
1762 if (hfrequency[ichain] == lfrequency[ichain]) {
1763 correction[ichain] = lcorrection[ichain];
1764 voltage[ichain] = lvoltage[ichain];
1765 temperature[ichain] = ltemperature[ichain];
1766 }
1767 /* the low frequency is good */
1768 else if (frequency - lfrequency[ichain] < 1000) {
1769 /* so is the high frequency, interpolate */
1770 if (hfrequency[ichain] - frequency < 1000) {
1771
1772 correction[ichain] = lcorrection[ichain] +
1773 (((frequency - lfrequency[ichain]) *
1774 (hcorrection[ichain] -
1775 lcorrection[ichain])) /
1776 (hfrequency[ichain] - lfrequency[ichain]));
1777
1778 temperature[ichain] = ltemperature[ichain] +
1779 (((frequency - lfrequency[ichain]) *
1780 (htemperature[ichain] -
1781 ltemperature[ichain])) /
1782 (hfrequency[ichain] - lfrequency[ichain]));
1783
1784 voltage[ichain] =
1785 lvoltage[ichain] +
1786 (((frequency -
1787 lfrequency[ichain]) * (hvoltage[ichain] -
1788 lvoltage[ichain]))
1789 / (hfrequency[ichain] -
1790 lfrequency[ichain]));
1791 }
1792 /* only low is good, use it */
1793 else {
1794 correction[ichain] = lcorrection[ichain];
1795 temperature[ichain] = ltemperature[ichain];
1796 voltage[ichain] = lvoltage[ichain];
1797 }
1798 }
1799 /* only high is good, use it */
1800 else if (hfrequency[ichain] - frequency < 1000) {
1801 correction[ichain] = hcorrection[ichain];
1802 temperature[ichain] = htemperature[ichain];
1803 voltage[ichain] = hvoltage[ichain];
1804 } else { /* nothing is good, presume 0???? */
1805 correction[ichain] = 0;
1806 temperature[ichain] = 0;
1807 voltage[ichain] = 0;
1808 }
1809 }
1810
1811 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
1812 temperature);
1813
1814 ath_print(common, ATH_DBG_EEPROM,
1815 "for frequency=%d, calibration correction = %d %d %d\n",
1816 frequency, correction[0], correction[1], correction[2]);
1817
1818 return 0;
1819 }
1820
1821 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
1822 int idx,
1823 int edge,
1824 bool is2GHz)
1825 {
1826 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
1827 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
1828
1829 if (is2GHz)
1830 return ctl_2g[idx].ctlEdges[edge].tPower;
1831 else
1832 return ctl_5g[idx].ctlEdges[edge].tPower;
1833 }
1834
1835 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
1836 int idx,
1837 unsigned int edge,
1838 u16 freq,
1839 bool is2GHz)
1840 {
1841 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
1842 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
1843
1844 u8 *ctl_freqbin = is2GHz ?
1845 &eep->ctl_freqbin_2G[idx][0] :
1846 &eep->ctl_freqbin_5G[idx][0];
1847
1848 if (is2GHz) {
1849 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
1850 ctl_2g[idx].ctlEdges[edge - 1].flag)
1851 return ctl_2g[idx].ctlEdges[edge - 1].tPower;
1852 } else {
1853 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
1854 ctl_5g[idx].ctlEdges[edge - 1].flag)
1855 return ctl_5g[idx].ctlEdges[edge - 1].tPower;
1856 }
1857
1858 return AR9300_MAX_RATE_POWER;
1859 }
1860
1861 /*
1862 * Find the maximum conformance test limit for the given channel and CTL info
1863 */
1864 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
1865 u16 freq, int idx, bool is2GHz)
1866 {
1867 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
1868 u8 *ctl_freqbin = is2GHz ?
1869 &eep->ctl_freqbin_2G[idx][0] :
1870 &eep->ctl_freqbin_5G[idx][0];
1871 u16 num_edges = is2GHz ?
1872 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
1873 unsigned int edge;
1874
1875 /* Get the edge power */
1876 for (edge = 0;
1877 (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED);
1878 edge++) {
1879 /*
1880 * If there's an exact channel match or an inband flag set
1881 * on the lower channel use the given rdEdgePower
1882 */
1883 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
1884 twiceMaxEdgePower =
1885 ar9003_hw_get_direct_edge_power(eep, idx,
1886 edge, is2GHz);
1887 break;
1888 } else if ((edge > 0) &&
1889 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
1890 is2GHz))) {
1891 twiceMaxEdgePower =
1892 ar9003_hw_get_indirect_edge_power(eep, idx,
1893 edge, freq,
1894 is2GHz);
1895 /*
1896 * Leave loop - no more affecting edges possible in
1897 * this monotonic increasing list
1898 */
1899 break;
1900 }
1901 }
1902 return twiceMaxEdgePower;
1903 }
1904
1905 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
1906 struct ath9k_channel *chan,
1907 u8 *pPwrArray, u16 cfgCtl,
1908 u8 twiceAntennaReduction,
1909 u8 twiceMaxRegulatoryPower,
1910 u16 powerLimit)
1911 {
1912 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1913 struct ath_common *common = ath9k_hw_common(ah);
1914 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
1915 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
1916 static const u16 tpScaleReductionTable[5] = {
1917 0, 3, 6, 9, AR9300_MAX_RATE_POWER
1918 };
1919 int i;
1920 int16_t twiceLargestAntenna;
1921 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
1922 u16 ctlModesFor11a[] = {
1923 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
1924 };
1925 u16 ctlModesFor11g[] = {
1926 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
1927 CTL_11G_EXT, CTL_2GHT40
1928 };
1929 u16 numCtlModes, *pCtlMode, ctlMode, freq;
1930 struct chan_centers centers;
1931 u8 *ctlIndex;
1932 u8 ctlNum;
1933 u16 twiceMinEdgePower;
1934 bool is2ghz = IS_CHAN_2GHZ(chan);
1935
1936 ath9k_hw_get_channel_centers(ah, chan, &centers);
1937
1938 /* Compute TxPower reduction due to Antenna Gain */
1939 if (is2ghz)
1940 twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
1941 else
1942 twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
1943
1944 twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
1945 twiceLargestAntenna, 0);
1946
1947 /*
1948 * scaledPower is the minimum of the user input power level
1949 * and the regulatory allowed power level
1950 */
1951 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
1952
1953 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
1954 maxRegAllowedPower -=
1955 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
1956 }
1957
1958 scaledPower = min(powerLimit, maxRegAllowedPower);
1959
1960 /*
1961 * Reduce scaled Power by number of chains active to get
1962 * to per chain tx power level
1963 */
1964 switch (ar5416_get_ntxchains(ah->txchainmask)) {
1965 case 1:
1966 break;
1967 case 2:
1968 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
1969 break;
1970 case 3:
1971 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
1972 break;
1973 }
1974
1975 scaledPower = max((u16)0, scaledPower);
1976
1977 /*
1978 * Get target powers from EEPROM - our baseline for TX Power
1979 */
1980 if (is2ghz) {
1981 /* Setup for CTL modes */
1982 /* CTL_11B, CTL_11G, CTL_2GHT20 */
1983 numCtlModes =
1984 ARRAY_SIZE(ctlModesFor11g) -
1985 SUB_NUM_CTL_MODES_AT_2G_40;
1986 pCtlMode = ctlModesFor11g;
1987 if (IS_CHAN_HT40(chan))
1988 /* All 2G CTL's */
1989 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
1990 } else {
1991 /* Setup for CTL modes */
1992 /* CTL_11A, CTL_5GHT20 */
1993 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
1994 SUB_NUM_CTL_MODES_AT_5G_40;
1995 pCtlMode = ctlModesFor11a;
1996 if (IS_CHAN_HT40(chan))
1997 /* All 5G CTL's */
1998 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
1999 }
2000
2001 /*
2002 * For MIMO, need to apply regulatory caps individually across
2003 * dynamically running modes: CCK, OFDM, HT20, HT40
2004 *
2005 * The outer loop walks through each possible applicable runtime mode.
2006 * The inner loop walks through each ctlIndex entry in EEPROM.
2007 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
2008 */
2009 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
2010 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
2011 (pCtlMode[ctlMode] == CTL_2GHT40);
2012 if (isHt40CtlMode)
2013 freq = centers.synth_center;
2014 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
2015 freq = centers.ext_center;
2016 else
2017 freq = centers.ctl_center;
2018
2019 ath_print(common, ATH_DBG_REGULATORY,
2020 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
2021 "EXT_ADDITIVE %d\n",
2022 ctlMode, numCtlModes, isHt40CtlMode,
2023 (pCtlMode[ctlMode] & EXT_ADDITIVE));
2024
2025 /* walk through each CTL index stored in EEPROM */
2026 if (is2ghz) {
2027 ctlIndex = pEepData->ctlIndex_2G;
2028 ctlNum = AR9300_NUM_CTLS_2G;
2029 } else {
2030 ctlIndex = pEepData->ctlIndex_5G;
2031 ctlNum = AR9300_NUM_CTLS_5G;
2032 }
2033
2034 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
2035 ath_print(common, ATH_DBG_REGULATORY,
2036 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
2037 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
2038 "chan %dn",
2039 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
2040 chan->channel);
2041
2042 /*
2043 * compare test group from regulatory
2044 * channel list with test mode from pCtlMode
2045 * list
2046 */
2047 if ((((cfgCtl & ~CTL_MODE_M) |
2048 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2049 ctlIndex[i]) ||
2050 (((cfgCtl & ~CTL_MODE_M) |
2051 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2052 ((ctlIndex[i] & CTL_MODE_M) |
2053 SD_NO_CTL))) {
2054 twiceMinEdgePower =
2055 ar9003_hw_get_max_edge_power(pEepData,
2056 freq, i,
2057 is2ghz);
2058
2059 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
2060 /*
2061 * Find the minimum of all CTL
2062 * edge powers that apply to
2063 * this channel
2064 */
2065 twiceMaxEdgePower =
2066 min(twiceMaxEdgePower,
2067 twiceMinEdgePower);
2068 else {
2069 /* specific */
2070 twiceMaxEdgePower =
2071 twiceMinEdgePower;
2072 break;
2073 }
2074 }
2075 }
2076
2077 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
2078
2079 ath_print(common, ATH_DBG_REGULATORY,
2080 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d "
2081 "sP %d minCtlPwr %d\n",
2082 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
2083 scaledPower, minCtlPower);
2084
2085 /* Apply ctl mode to correct target power set */
2086 switch (pCtlMode[ctlMode]) {
2087 case CTL_11B:
2088 for (i = ALL_TARGET_LEGACY_1L_5L;
2089 i <= ALL_TARGET_LEGACY_11S; i++)
2090 pPwrArray[i] =
2091 (u8)min((u16)pPwrArray[i],
2092 minCtlPower);
2093 break;
2094 case CTL_11A:
2095 case CTL_11G:
2096 for (i = ALL_TARGET_LEGACY_6_24;
2097 i <= ALL_TARGET_LEGACY_54; i++)
2098 pPwrArray[i] =
2099 (u8)min((u16)pPwrArray[i],
2100 minCtlPower);
2101 break;
2102 case CTL_5GHT20:
2103 case CTL_2GHT20:
2104 for (i = ALL_TARGET_HT20_0_8_16;
2105 i <= ALL_TARGET_HT20_21; i++)
2106 pPwrArray[i] =
2107 (u8)min((u16)pPwrArray[i],
2108 minCtlPower);
2109 pPwrArray[ALL_TARGET_HT20_22] =
2110 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
2111 minCtlPower);
2112 pPwrArray[ALL_TARGET_HT20_23] =
2113 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
2114 minCtlPower);
2115 break;
2116 case CTL_5GHT40:
2117 case CTL_2GHT40:
2118 for (i = ALL_TARGET_HT40_0_8_16;
2119 i <= ALL_TARGET_HT40_23; i++)
2120 pPwrArray[i] =
2121 (u8)min((u16)pPwrArray[i],
2122 minCtlPower);
2123 break;
2124 default:
2125 break;
2126 }
2127 } /* end ctl mode checking */
2128 }
2129
2130 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
2131 struct ath9k_channel *chan, u16 cfgCtl,
2132 u8 twiceAntennaReduction,
2133 u8 twiceMaxRegulatoryPower,
2134 u8 powerLimit)
2135 {
2136 struct ath_common *common = ath9k_hw_common(ah);
2137 u8 targetPowerValT2[ar9300RateSize];
2138 unsigned int i = 0;
2139
2140 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
2141 ar9003_hw_set_power_per_rate_table(ah, chan,
2142 targetPowerValT2, cfgCtl,
2143 twiceAntennaReduction,
2144 twiceMaxRegulatoryPower,
2145 powerLimit);
2146
2147 while (i < ar9300RateSize) {
2148 ath_print(common, ATH_DBG_EEPROM,
2149 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2150 i++;
2151 ath_print(common, ATH_DBG_EEPROM,
2152 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2153 i++;
2154 ath_print(common, ATH_DBG_EEPROM,
2155 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2156 i++;
2157 ath_print(common, ATH_DBG_EEPROM,
2158 "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]);
2159 i++;
2160 }
2161
2162 /* Write target power array to registers */
2163 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
2164
2165 /*
2166 * This is the TX power we send back to driver core,
2167 * and it can use to pass to userspace to display our
2168 * currently configured TX power setting.
2169 *
2170 * Since power is rate dependent, use one of the indices
2171 * from the AR9300_Rates enum to select an entry from
2172 * targetPowerValT2[] to report. Currently returns the
2173 * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
2174 * as CCK power is less interesting (?).
2175 */
2176 i = ALL_TARGET_LEGACY_6_24; /* legacy */
2177 if (IS_CHAN_HT40(chan))
2178 i = ALL_TARGET_HT40_0_8_16; /* ht40 */
2179 else if (IS_CHAN_HT20(chan))
2180 i = ALL_TARGET_HT20_0_8_16; /* ht20 */
2181
2182 ah->txpower_limit = targetPowerValT2[i];
2183
2184 ar9003_hw_calibration_apply(ah, chan->channel);
2185 }
2186
2187 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
2188 u16 i, bool is2GHz)
2189 {
2190 return AR_NO_SPUR;
2191 }
2192
2193 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
2194 {
2195 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2196
2197 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
2198 }
2199
2200 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
2201 {
2202 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2203
2204 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
2205 }
2206
2207 const struct eeprom_ops eep_ar9300_ops = {
2208 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
2209 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
2210 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
2211 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
2212 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
2213 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
2214 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
2215 .set_board_values = ath9k_hw_ar9300_set_board_values,
2216 .set_addac = ath9k_hw_ar9300_set_addac,
2217 .set_txpower = ath9k_hw_ar9300_set_txpower,
2218 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel
2219 };