]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
ath9k_hw: add the AR9300 SREV hw name print
[mirror_ubuntu-hirsute-kernel.git] / drivers / net / wireless / ath / ath9k / ar9003_eeprom.c
CommitLineData
15c9ee7a
SB
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
41static const struct ar9300_eeprom ar9300_default = {
42 .eepromVersion = 2,
43 .templateVersion = 2,
44 .macAddr = {1, 2, 3, 4, 5, 6},
45 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
47 .baseEepHeader = {
48 .regDmn = {0, 0x1f},
49 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
50 .opCapFlags = {
51 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
52 .eepMisc = 0,
53 },
54 .rfSilent = 0,
55 .blueToothOptions = 0,
56 .deviceCap = 0,
57 .deviceType = 5, /* takes lower byte in eeprom location */
58 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
59 .params_for_tuning_caps = {0, 0},
60 .featureEnable = 0x0c,
61 /*
62 * bit0 - enable tx temp comp - disabled
63 * bit1 - enable tx volt comp - disabled
64 * bit2 - enable fastClock - enabled
65 * bit3 - enable doubling - enabled
66 * bit4 - enable internal regulator - disabled
67 */
68 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
69 .eepromWriteEnableGpio = 3,
70 .wlanDisableGpio = 0,
71 .wlanLedGpio = 8,
72 .rxBandSelectGpio = 0xff,
73 .txrxgain = 0,
74 .swreg = 0,
75 },
76 .modalHeader2G = {
77 /* ar9300_modal_eep_header 2g */
78 /* 4 idle,t1,t2,b(4 bits per setting) */
79 .antCtrlCommon = 0x110,
80 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
81 .antCtrlCommon2 = 0x22222,
82
83 /*
84 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
85 * rx1, rx12, b (2 bits each)
86 */
87 .antCtrlChain = {0x150, 0x150, 0x150},
88
89 /*
90 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
91 * for ar9280 (0xa20c/b20c 5:0)
92 */
93 .xatten1DB = {0, 0, 0},
94
95 /*
96 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
97 * for ar9280 (0xa20c/b20c 16:12
98 */
99 .xatten1Margin = {0, 0, 0},
100 .tempSlope = 36,
101 .voltSlope = 0,
102
103 /*
104 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
105 * channels in usual fbin coding format
106 */
107 .spurChans = {0, 0, 0, 0, 0},
108
109 /*
110 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
111 * if the register is per chain
112 */
113 .noiseFloorThreshCh = {-1, 0, 0},
114 .ob = {1, 1, 1},/* 3 chain */
115 .db_stage2 = {1, 1, 1}, /* 3 chain */
116 .db_stage3 = {0, 0, 0},
117 .db_stage4 = {0, 0, 0},
118 .xpaBiasLvl = 0,
119 .txFrameToDataStart = 0x0e,
120 .txFrameToPaOn = 0x0e,
121 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
122 .antennaGain = 0,
123 .switchSettling = 0x2c,
124 .adcDesiredSize = -30,
125 .txEndToXpaOff = 0,
126 .txEndToRxOn = 0x2,
127 .txFrameToXpaOn = 0xe,
128 .thresh62 = 28,
129 .futureModal = { /* [32] */
130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
132 },
133 },
134 .calFreqPier2G = {
135 FREQ2FBIN(2412, 1),
136 FREQ2FBIN(2437, 1),
137 FREQ2FBIN(2472, 1),
138 },
139 /* ar9300_cal_data_per_freq_op_loop 2g */
140 .calPierData2G = {
141 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
142 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
143 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
144 },
145 .calTarget_freqbin_Cck = {
146 FREQ2FBIN(2412, 1),
147 FREQ2FBIN(2484, 1),
148 },
149 .calTarget_freqbin_2G = {
150 FREQ2FBIN(2412, 1),
151 FREQ2FBIN(2437, 1),
152 FREQ2FBIN(2472, 1)
153 },
154 .calTarget_freqbin_2GHT20 = {
155 FREQ2FBIN(2412, 1),
156 FREQ2FBIN(2437, 1),
157 FREQ2FBIN(2472, 1)
158 },
159 .calTarget_freqbin_2GHT40 = {
160 FREQ2FBIN(2412, 1),
161 FREQ2FBIN(2437, 1),
162 FREQ2FBIN(2472, 1)
163 },
164 .calTargetPowerCck = {
165 /* 1L-5L,5S,11L,11S */
166 { {36, 36, 36, 36} },
167 { {36, 36, 36, 36} },
168 },
169 .calTargetPower2G = {
170 /* 6-24,36,48,54 */
171 { {32, 32, 28, 24} },
172 { {32, 32, 28, 24} },
173 { {32, 32, 28, 24} },
174 },
175 .calTargetPower2GHT20 = {
176 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
177 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
178 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
179 },
180 .calTargetPower2GHT40 = {
181 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
182 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
183 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
184 },
185 .ctlIndex_2G = {
186 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
187 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
188 },
189 .ctl_freqbin_2G = {
190 {
191 FREQ2FBIN(2412, 1),
192 FREQ2FBIN(2417, 1),
193 FREQ2FBIN(2457, 1),
194 FREQ2FBIN(2462, 1)
195 },
196 {
197 FREQ2FBIN(2412, 1),
198 FREQ2FBIN(2417, 1),
199 FREQ2FBIN(2462, 1),
200 0xFF,
201 },
202
203 {
204 FREQ2FBIN(2412, 1),
205 FREQ2FBIN(2417, 1),
206 FREQ2FBIN(2462, 1),
207 0xFF,
208 },
209 {
210 FREQ2FBIN(2422, 1),
211 FREQ2FBIN(2427, 1),
212 FREQ2FBIN(2447, 1),
213 FREQ2FBIN(2452, 1)
214 },
215
216 {
217 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
218 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
219 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
220 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
221 },
222
223 {
224 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
225 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
226 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
227 0,
228 },
229
230 {
231 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
232 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
233 FREQ2FBIN(2472, 1),
234 0,
235 },
236
237 {
238 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
239 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
240 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
241 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
242 },
243
244 {
245 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
246 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
247 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
248 },
249
250 {
251 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
252 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
253 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
254 0
255 },
256
257 {
258 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
259 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
260 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
261 0
262 },
263
264 {
265 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
266 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
267 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
268 /* Data[11].ctlEdges[3].bChannel */
269 FREQ2FBIN(2462, 1),
270 }
271 },
272 .ctlPowerData_2G = {
273 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
274 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
275 { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
276
277 { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
278 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
279 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
280
281 { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
282 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
283 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
284
285 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
286 { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
287 },
288 .modalHeader5G = {
289 /* 4 idle,t1,t2,b (4 bits per setting) */
290 .antCtrlCommon = 0x110,
291 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
292 .antCtrlCommon2 = 0x22222,
293 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
294 .antCtrlChain = {
295 0x000, 0x000, 0x000,
296 },
297 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
298 .xatten1DB = {0, 0, 0},
299
300 /*
301 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
302 * for merlin (0xa20c/b20c 16:12
303 */
304 .xatten1Margin = {0, 0, 0},
305 .tempSlope = 68,
306 .voltSlope = 0,
307 /* spurChans spur channels in usual fbin coding format */
308 .spurChans = {0, 0, 0, 0, 0},
309 /* noiseFloorThreshCh Check if the register is per chain */
310 .noiseFloorThreshCh = {-1, 0, 0},
311 .ob = {3, 3, 3}, /* 3 chain */
312 .db_stage2 = {3, 3, 3}, /* 3 chain */
313 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
314 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
315 .xpaBiasLvl = 0,
316 .txFrameToDataStart = 0x0e,
317 .txFrameToPaOn = 0x0e,
318 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
319 .antennaGain = 0,
320 .switchSettling = 0x2d,
321 .adcDesiredSize = -30,
322 .txEndToXpaOff = 0,
323 .txEndToRxOn = 0x2,
324 .txFrameToXpaOn = 0xe,
325 .thresh62 = 28,
326 .futureModal = {
327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
328 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
329 },
330 },
331 .calFreqPier5G = {
332 FREQ2FBIN(5180, 0),
333 FREQ2FBIN(5220, 0),
334 FREQ2FBIN(5320, 0),
335 FREQ2FBIN(5400, 0),
336 FREQ2FBIN(5500, 0),
337 FREQ2FBIN(5600, 0),
338 FREQ2FBIN(5725, 0),
339 FREQ2FBIN(5825, 0)
340 },
341 .calPierData5G = {
342 {
343 {0, 0, 0, 0, 0},
344 {0, 0, 0, 0, 0},
345 {0, 0, 0, 0, 0},
346 {0, 0, 0, 0, 0},
347 {0, 0, 0, 0, 0},
348 {0, 0, 0, 0, 0},
349 {0, 0, 0, 0, 0},
350 {0, 0, 0, 0, 0},
351 },
352 {
353 {0, 0, 0, 0, 0},
354 {0, 0, 0, 0, 0},
355 {0, 0, 0, 0, 0},
356 {0, 0, 0, 0, 0},
357 {0, 0, 0, 0, 0},
358 {0, 0, 0, 0, 0},
359 {0, 0, 0, 0, 0},
360 {0, 0, 0, 0, 0},
361 },
362 {
363 {0, 0, 0, 0, 0},
364 {0, 0, 0, 0, 0},
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 },
372
373 },
374 .calTarget_freqbin_5G = {
375 FREQ2FBIN(5180, 0),
376 FREQ2FBIN(5220, 0),
377 FREQ2FBIN(5320, 0),
378 FREQ2FBIN(5400, 0),
379 FREQ2FBIN(5500, 0),
380 FREQ2FBIN(5600, 0),
381 FREQ2FBIN(5725, 0),
382 FREQ2FBIN(5825, 0)
383 },
384 .calTarget_freqbin_5GHT20 = {
385 FREQ2FBIN(5180, 0),
386 FREQ2FBIN(5240, 0),
387 FREQ2FBIN(5320, 0),
388 FREQ2FBIN(5500, 0),
389 FREQ2FBIN(5700, 0),
390 FREQ2FBIN(5745, 0),
391 FREQ2FBIN(5725, 0),
392 FREQ2FBIN(5825, 0)
393 },
394 .calTarget_freqbin_5GHT40 = {
395 FREQ2FBIN(5180, 0),
396 FREQ2FBIN(5240, 0),
397 FREQ2FBIN(5320, 0),
398 FREQ2FBIN(5500, 0),
399 FREQ2FBIN(5700, 0),
400 FREQ2FBIN(5745, 0),
401 FREQ2FBIN(5725, 0),
402 FREQ2FBIN(5825, 0)
403 },
404 .calTargetPower5G = {
405 /* 6-24,36,48,54 */
406 { {20, 20, 20, 10} },
407 { {20, 20, 20, 10} },
408 { {20, 20, 20, 10} },
409 { {20, 20, 20, 10} },
410 { {20, 20, 20, 10} },
411 { {20, 20, 20, 10} },
412 { {20, 20, 20, 10} },
413 { {20, 20, 20, 10} },
414 },
415 .calTargetPower5GHT20 = {
416 /*
417 * 0_8_16,1-3_9-11_17-19,
418 * 4,5,6,7,12,13,14,15,20,21,22,23
419 */
420 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
421 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
422 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
423 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
424 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
425 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
426 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
427 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
428 },
429 .calTargetPower5GHT40 = {
430 /*
431 * 0_8_16,1-3_9-11_17-19,
432 * 4,5,6,7,12,13,14,15,20,21,22,23
433 */
434 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
435 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
436 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
437 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
438 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
439 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
440 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
441 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
442 },
443 .ctlIndex_5G = {
444 0x10, 0x16, 0x18, 0x40, 0x46,
445 0x48, 0x30, 0x36, 0x38
446 },
447 .ctl_freqbin_5G = {
448 {
449 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
450 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
451 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
452 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
453 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
454 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
455 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
456 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
457 },
458 {
459 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
460 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
461 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
462 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
463 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
464 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
465 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
466 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
467 },
468
469 {
470 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
471 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
472 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
473 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
474 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
475 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
476 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
477 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
478 },
479
480 {
481 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
482 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
483 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
484 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
485 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
486 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
487 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
488 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
489 },
490
491 {
492 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
493 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
494 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
495 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
496 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
497 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
498 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
499 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
500 },
501
502 {
503 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
504 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
505 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
506 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
507 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
508 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
509 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
510 /* Data[5].ctlEdges[7].bChannel */ 0xFF
511 },
512
513 {
514 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
515 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
516 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
517 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
518 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
519 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
520 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
521 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
522 },
523
524 {
525 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
526 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
527 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
528 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
529 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
530 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
531 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
532 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
533 },
534
535 {
536 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
537 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
538 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
539 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
540 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
541 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
542 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
543 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
544 }
545 },
546 .ctlPowerData_5G = {
547 {
548 {
549 {60, 1}, {60, 1}, {60, 1}, {60, 1},
550 {60, 1}, {60, 1}, {60, 1}, {60, 0},
551 }
552 },
553 {
554 {
555 {60, 1}, {60, 1}, {60, 1}, {60, 1},
556 {60, 1}, {60, 1}, {60, 1}, {60, 0},
557 }
558 },
559 {
560 {
561 {60, 0}, {60, 1}, {60, 0}, {60, 1},
562 {60, 1}, {60, 1}, {60, 1}, {60, 1},
563 }
564 },
565 {
566 {
567 {60, 0}, {60, 1}, {60, 1}, {60, 0},
568 {60, 1}, {60, 0}, {60, 0}, {60, 0},
569 }
570 },
571 {
572 {
573 {60, 1}, {60, 1}, {60, 1}, {60, 0},
574 {60, 0}, {60, 0}, {60, 0}, {60, 0},
575 }
576 },
577 {
578 {
579 {60, 1}, {60, 1}, {60, 1}, {60, 1},
580 {60, 1}, {60, 0}, {60, 0}, {60, 0},
581 }
582 },
583 {
584 {
585 {60, 1}, {60, 1}, {60, 1}, {60, 1},
586 {60, 1}, {60, 1}, {60, 1}, {60, 1},
587 }
588 },
589 {
590 {
591 {60, 1}, {60, 1}, {60, 0}, {60, 1},
592 {60, 1}, {60, 1}, {60, 1}, {60, 0},
593 }
594 },
595 {
596 {
597 {60, 1}, {60, 0}, {60, 1}, {60, 1},
598 {60, 1}, {60, 1}, {60, 0}, {60, 1},
599 }
600 },
601 }
602};
603
604static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
605{
606 return 0;
607}
608
609static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
610 enum eeprom_param param)
611{
612 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
613 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
614
615 switch (param) {
616 case EEP_MAC_LSW:
617 return eep->macAddr[0] << 8 | eep->macAddr[1];
618 case EEP_MAC_MID:
619 return eep->macAddr[2] << 8 | eep->macAddr[3];
620 case EEP_MAC_MSW:
621 return eep->macAddr[4] << 8 | eep->macAddr[5];
622 case EEP_REG_0:
623 return pBase->regDmn[0];
624 case EEP_REG_1:
625 return pBase->regDmn[1];
626 case EEP_OP_CAP:
627 return pBase->deviceCap;
628 case EEP_OP_MODE:
629 return pBase->opCapFlags.opFlags;
630 case EEP_RF_SILENT:
631 return pBase->rfSilent;
632 case EEP_TX_MASK:
633 return (pBase->txrxMask >> 4) & 0xf;
634 case EEP_RX_MASK:
635 return pBase->txrxMask & 0xf;
636 case EEP_DRIVE_STRENGTH:
637#define AR9300_EEP_BASE_DRIV_STRENGTH 0x1
638 return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
639 case EEP_INTERNAL_REGULATOR:
640 /* Bit 4 is internal regulator flag */
641 return (pBase->featureEnable & 0x10) >> 4;
642 case EEP_SWREG:
643 return pBase->swreg;
644 default:
645 return 0;
646 }
647}
648
649#ifdef __BIG_ENDIAN
650static void ar9300_swap_eeprom(struct ar9300_eeprom *eep)
651{
652 u32 dword;
653 u16 word;
654 int i;
655
656 word = swab16(eep->baseEepHeader.regDmn[0]);
657 eep->baseEepHeader.regDmn[0] = word;
658
659 word = swab16(eep->baseEepHeader.regDmn[1]);
660 eep->baseEepHeader.regDmn[1] = word;
661
662 dword = swab32(eep->modalHeader2G.antCtrlCommon);
663 eep->modalHeader2G.antCtrlCommon = dword;
664
665 dword = swab32(eep->modalHeader2G.antCtrlCommon2);
666 eep->modalHeader2G.antCtrlCommon2 = dword;
667
668 dword = swab32(eep->modalHeader5G.antCtrlCommon);
669 eep->modalHeader5G.antCtrlCommon = dword;
670
671 dword = swab32(eep->modalHeader5G.antCtrlCommon2);
672 eep->modalHeader5G.antCtrlCommon2 = dword;
673
674 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
675 word = swab16(eep->modalHeader2G.antCtrlChain[i]);
676 eep->modalHeader2G.antCtrlChain[i] = word;
677
678 word = swab16(eep->modalHeader5G.antCtrlChain[i]);
679 eep->modalHeader5G.antCtrlChain[i] = word;
680 }
681}
682#endif
683
684static bool ar9300_hw_read_eeprom(struct ath_hw *ah,
685 long address, u8 *buffer, int many)
686{
687 int i;
688 u8 value[2];
689 unsigned long eepAddr;
690 unsigned long byteAddr;
691 u16 *svalue;
692 struct ath_common *common = ath9k_hw_common(ah);
693
694 if ((address < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) {
695 ath_print(common, ATH_DBG_EEPROM,
696 "eeprom address not in range\n");
697 return false;
698 }
699
700 for (i = 0; i < many; i++) {
701 eepAddr = (u16) (address + i) / 2;
702 byteAddr = (u16) (address + i) % 2;
703 svalue = (u16 *) value;
704 if (!ath9k_hw_nvram_read(common, eepAddr, svalue)) {
705 ath_print(common, ATH_DBG_EEPROM,
706 "unable to read eeprom region\n");
707 return false;
708 }
709 *svalue = le16_to_cpu(*svalue);
710 buffer[i] = value[byteAddr];
711 }
712
713 return true;
714}
715
716static bool ar9300_read_eeprom(struct ath_hw *ah,
717 int address, u8 *buffer, int many)
718{
719 int it;
720
721 for (it = 0; it < many; it++)
722 if (!ar9300_hw_read_eeprom(ah,
723 (address - it),
724 (buffer + it), 1))
725 return false;
726 return true;
727}
728
729static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
730 int *length, int *major, int *minor)
731{
732 unsigned long value[4];
733
734 value[0] = best[0];
735 value[1] = best[1];
736 value[2] = best[2];
737 value[3] = best[3];
738 *code = ((value[0] >> 5) & 0x0007);
739 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
740 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
741 *major = (value[2] & 0x000f);
742 *minor = (value[3] & 0x00ff);
743}
744
745static u16 ar9300_comp_cksum(u8 *data, int dsize)
746{
747 int it, checksum = 0;
748
749 for (it = 0; it < dsize; it++) {
750 checksum += data[it];
751 checksum &= 0xffff;
752 }
753
754 return checksum;
755}
756
757static bool ar9300_uncompress_block(struct ath_hw *ah,
758 u8 *mptr,
759 int mdataSize,
760 u8 *block,
761 int size)
762{
763 int it;
764 int spot;
765 int offset;
766 int length;
767 struct ath_common *common = ath9k_hw_common(ah);
768
769 spot = 0;
770
771 for (it = 0; it < size; it += (length+2)) {
772 offset = block[it];
773 offset &= 0xff;
774 spot += offset;
775 length = block[it+1];
776 length &= 0xff;
777
778 if (length > 0 && spot >= 0 && spot+length < mdataSize) {
779 ath_print(common, ATH_DBG_EEPROM,
780 "Restore at %d: spot=%d "
781 "offset=%d length=%d\n",
782 it, spot, offset, length);
783 memcpy(&mptr[spot], &block[it+2], length);
784 spot += length;
785 } else if (length > 0) {
786 ath_print(common, ATH_DBG_EEPROM,
787 "Bad restore at %d: spot=%d "
788 "offset=%d length=%d\n",
789 it, spot, offset, length);
790 return false;
791 }
792 }
793 return true;
794}
795
796static int ar9300_compress_decision(struct ath_hw *ah,
797 int it,
798 int code,
799 int reference,
800 u8 *mptr,
801 u8 *word, int length, int mdata_size)
802{
803 struct ath_common *common = ath9k_hw_common(ah);
804 u8 *dptr;
805
806 switch (code) {
807 case _CompressNone:
808 if (length != mdata_size) {
809 ath_print(common, ATH_DBG_EEPROM,
810 "EEPROM structure size mismatch"
811 "memory=%d eeprom=%d\n", mdata_size, length);
812 return -1;
813 }
814 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
815 ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
816 " uncompressed, length %d\n", it, length);
817 break;
818 case _CompressBlock:
819 if (reference == 0) {
820 dptr = mptr;
821 } else {
822 if (reference != 2) {
823 ath_print(common, ATH_DBG_EEPROM,
824 "cant find reference eeprom"
825 "struct %d\n", reference);
826 return -1;
827 }
828 memcpy(mptr, &ar9300_default, mdata_size);
829 }
830 ath_print(common, ATH_DBG_EEPROM,
831 "restore eeprom %d: block, reference %d,"
832 " length %d\n", it, reference, length);
833 ar9300_uncompress_block(ah, mptr, mdata_size,
834 (u8 *) (word + COMP_HDR_LEN), length);
835 break;
836 default:
837 ath_print(common, ATH_DBG_EEPROM, "unknown compression"
838 " code %d\n", code);
839 return -1;
840 }
841 return 0;
842}
843
844/*
845 * Read the configuration data from the eeprom.
846 * The data can be put in any specified memory buffer.
847 *
848 * Returns -1 on error.
849 * Returns address of next memory location on success.
850 */
851static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
852 u8 *mptr, int mdata_size)
853{
854#define MDEFAULT 15
855#define MSTATE 100
856 int cptr;
857 u8 *word;
858 int code;
859 int reference, length, major, minor;
860 int osize;
861 int it;
862 u16 checksum, mchecksum;
863 struct ath_common *common = ath9k_hw_common(ah);
864
865 word = kzalloc(2048, GFP_KERNEL);
866 if (!word)
867 return -1;
868
869 memcpy(mptr, &ar9300_default, mdata_size);
870
871 cptr = AR9300_BASE_ADDR;
872 for (it = 0; it < MSTATE; it++) {
873 if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
874 goto fail;
875
876 if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
877 word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
878 && word[2] == 0xff && word[3] == 0xff))
879 break;
880
881 ar9300_comp_hdr_unpack(word, &code, &reference,
882 &length, &major, &minor);
883 ath_print(common, ATH_DBG_EEPROM,
884 "Found block at %x: code=%d ref=%d"
885 "length=%d major=%d minor=%d\n", cptr, code,
886 reference, length, major, minor);
887 if (length >= 1024) {
888 ath_print(common, ATH_DBG_EEPROM,
889 "Skipping bad header\n");
890 cptr -= COMP_HDR_LEN;
891 continue;
892 }
893
894 osize = length;
895 ar9300_read_eeprom(ah, cptr, word,
896 COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
897 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
898 mchecksum = word[COMP_HDR_LEN + osize] |
899 (word[COMP_HDR_LEN + osize + 1] << 8);
900 ath_print(common, ATH_DBG_EEPROM,
901 "checksum %x %x\n", checksum, mchecksum);
902 if (checksum == mchecksum) {
903 ar9300_compress_decision(ah, it, code, reference, mptr,
904 word, length, mdata_size);
905 } else {
906 ath_print(common, ATH_DBG_EEPROM,
907 "skipping block with bad checksum\n");
908 }
909 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
910 }
911
912 kfree(word);
913 return cptr;
914
915fail:
916 kfree(word);
917 return -1;
918}
919
920/*
921 * Restore the configuration structure by reading the eeprom.
922 * This function destroys any existing in-memory structure
923 * content.
924 */
925static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
926{
927 u8 *mptr = NULL;
928 int mdata_size;
929
930 mptr = (u8 *) &ah->eeprom.ar9300_eep;
931 mdata_size = sizeof(struct ar9300_eeprom);
932
933 if (mptr && mdata_size > 0) {
934 /* At this point, mptr points to the eeprom data structure
935 * in it's "default" state. If this is big endian, swap the
936 * data structures back to "little endian"
937 */
938 /* First swap, default to Little Endian */
939#ifdef __BIG_ENDIAN
940 ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
941#endif
942 if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0)
943 return true;
944
945 /* Second Swap, back to Big Endian */
946#ifdef __BIG_ENDIAN
947 ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
948#endif
949 }
950 return false;
951}
952
953/* XXX: review hardware docs */
954static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
955{
956 return ah->eeprom.ar9300_eep.eepromVersion;
957}
958
959/* XXX: could be read from the eepromVersion, not sure yet */
960static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
961{
962 return 0;
963}
964
965static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
966 enum ieee80211_band freq_band)
967{
968 return 1;
969}
970
971static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
972 struct ath9k_channel *chan)
973{
974 return -EINVAL;
975}
976
977static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
978{
979 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
980
981 if (is2ghz)
982 return eep->modalHeader2G.xpaBiasLvl;
983 else
984 return eep->modalHeader5G.xpaBiasLvl;
985}
986
987static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
988{
989 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
990 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
991 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
992 ((bias >> 2) & 0x3));
993}
994
995static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
996{
997 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
998
999 if (is2ghz)
1000 return eep->modalHeader2G.antCtrlCommon;
1001 else
1002 return eep->modalHeader5G.antCtrlCommon;
1003}
1004
1005static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
1006{
1007 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1008
1009 if (is2ghz)
1010 return eep->modalHeader2G.antCtrlCommon2;
1011 else
1012 return eep->modalHeader5G.antCtrlCommon2;
1013}
1014
1015static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
1016 int chain,
1017 bool is2ghz)
1018{
1019 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1020
1021 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
1022 if (is2ghz)
1023 return eep->modalHeader2G.antCtrlChain[chain];
1024 else
1025 return eep->modalHeader5G.antCtrlChain[chain];
1026 }
1027
1028 return 0;
1029}
1030
1031static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
1032{
1033 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
1034 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
1035
1036 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
1037 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
1038
1039 value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
1040 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
1041
1042 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
1043 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
1044
1045 value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
1046 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
1047}
1048
1049static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
1050{
1051 int drive_strength;
1052 unsigned long reg;
1053
1054 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
1055
1056 if (!drive_strength)
1057 return;
1058
1059 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
1060 reg &= ~0x00ffffc0;
1061 reg |= 0x5 << 21;
1062 reg |= 0x5 << 18;
1063 reg |= 0x5 << 15;
1064 reg |= 0x5 << 12;
1065 reg |= 0x5 << 9;
1066 reg |= 0x5 << 6;
1067 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
1068
1069 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
1070 reg &= ~0xffffffe0;
1071 reg |= 0x5 << 29;
1072 reg |= 0x5 << 26;
1073 reg |= 0x5 << 23;
1074 reg |= 0x5 << 20;
1075 reg |= 0x5 << 17;
1076 reg |= 0x5 << 14;
1077 reg |= 0x5 << 11;
1078 reg |= 0x5 << 8;
1079 reg |= 0x5 << 5;
1080 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
1081
1082 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
1083 reg &= ~0xff800000;
1084 reg |= 0x5 << 29;
1085 reg |= 0x5 << 26;
1086 reg |= 0x5 << 23;
1087 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
1088}
1089
1090static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
1091{
1092 int internal_regulator =
1093 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
1094
1095 if (internal_regulator) {
1096 /* Internal regulator is ON. Write swreg register. */
1097 int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
1098 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1099 REG_READ(ah, AR_RTC_REG_CONTROL1) &
1100 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
1101 REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
1102 /* Set REG_CONTROL1.SWREG_PROGRAM */
1103 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1104 REG_READ(ah,
1105 AR_RTC_REG_CONTROL1) |
1106 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
1107 } else {
1108 REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1109 (REG_READ(ah,
1110 AR_RTC_SLEEP_CLK) |
1111 AR_RTC_FORCE_SWREG_PRD));
1112 }
1113}
1114
1115static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
1116 struct ath9k_channel *chan)
1117{
1118 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
1119 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
1120 ar9003_hw_drive_strength_apply(ah);
1121 ar9003_hw_internal_regulator_apply(ah);
1122}
1123
1124static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
1125 struct ath9k_channel *chan)
1126{
1127}
1128
1129/*
1130 * Returns the interpolated y value corresponding to the specified x value
1131 * from the np ordered pairs of data (px,py).
1132 * The pairs do not have to be in any order.
1133 * If the specified x value is less than any of the px,
1134 * the returned y value is equal to the py for the lowest px.
1135 * If the specified x value is greater than any of the px,
1136 * the returned y value is equal to the py for the highest px.
1137 */
1138static int ar9003_hw_power_interpolate(int32_t x,
1139 int32_t *px, int32_t *py, u_int16_t np)
1140{
1141 int ip = 0;
1142 int lx = 0, ly = 0, lhave = 0;
1143 int hx = 0, hy = 0, hhave = 0;
1144 int dx = 0;
1145 int y = 0;
1146
1147 lhave = 0;
1148 hhave = 0;
1149
1150 /* identify best lower and higher x calibration measurement */
1151 for (ip = 0; ip < np; ip++) {
1152 dx = x - px[ip];
1153
1154 /* this measurement is higher than our desired x */
1155 if (dx <= 0) {
1156 if (!hhave || dx > (x - hx)) {
1157 /* new best higher x measurement */
1158 hx = px[ip];
1159 hy = py[ip];
1160 hhave = 1;
1161 }
1162 }
1163 /* this measurement is lower than our desired x */
1164 if (dx >= 0) {
1165 if (!lhave || dx < (x - lx)) {
1166 /* new best lower x measurement */
1167 lx = px[ip];
1168 ly = py[ip];
1169 lhave = 1;
1170 }
1171 }
1172 }
1173
1174 /* the low x is good */
1175 if (lhave) {
1176 /* so is the high x */
1177 if (hhave) {
1178 /* they're the same, so just pick one */
1179 if (hx == lx)
1180 y = ly;
1181 else /* interpolate */
1182 y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
1183 } else /* only low is good, use it */
1184 y = ly;
1185 } else if (hhave) /* only high is good, use it */
1186 y = hy;
1187 else /* nothing is good,this should never happen unless np=0, ???? */
1188 y = -(1 << 30);
1189 return y;
1190}
1191
1192static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
1193 u16 rateIndex, u16 freq, bool is2GHz)
1194{
1195 u16 numPiers, i;
1196 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1197 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1198 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1199 struct cal_tgt_pow_legacy *pEepromTargetPwr;
1200 u8 *pFreqBin;
1201
1202 if (is2GHz) {
1203 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1204 pEepromTargetPwr = eep->calTargetPower2G;
1205 pFreqBin = eep->calTarget_freqbin_2G;
1206 } else {
1207 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1208 pEepromTargetPwr = eep->calTargetPower5G;
1209 pFreqBin = eep->calTarget_freqbin_5G;
1210 }
1211
1212 /*
1213 * create array of channels and targetpower from
1214 * targetpower piers stored on eeprom
1215 */
1216 for (i = 0; i < numPiers; i++) {
1217 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1218 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1219 }
1220
1221 /* interpolate to get target power for given frequency */
1222 return (u8) ar9003_hw_power_interpolate((s32) freq,
1223 freqArray,
1224 targetPowerArray, numPiers);
1225}
1226
1227static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
1228 u16 rateIndex,
1229 u16 freq, bool is2GHz)
1230{
1231 u16 numPiers, i;
1232 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1233 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1234 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1235 struct cal_tgt_pow_ht *pEepromTargetPwr;
1236 u8 *pFreqBin;
1237
1238 if (is2GHz) {
1239 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1240 pEepromTargetPwr = eep->calTargetPower2GHT20;
1241 pFreqBin = eep->calTarget_freqbin_2GHT20;
1242 } else {
1243 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1244 pEepromTargetPwr = eep->calTargetPower5GHT20;
1245 pFreqBin = eep->calTarget_freqbin_5GHT20;
1246 }
1247
1248 /*
1249 * create array of channels and targetpower
1250 * from targetpower piers stored on eeprom
1251 */
1252 for (i = 0; i < numPiers; i++) {
1253 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1254 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1255 }
1256
1257 /* interpolate to get target power for given frequency */
1258 return (u8) ar9003_hw_power_interpolate((s32) freq,
1259 freqArray,
1260 targetPowerArray, numPiers);
1261}
1262
1263static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
1264 u16 rateIndex,
1265 u16 freq, bool is2GHz)
1266{
1267 u16 numPiers, i;
1268 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
1269 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
1270 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1271 struct cal_tgt_pow_ht *pEepromTargetPwr;
1272 u8 *pFreqBin;
1273
1274 if (is2GHz) {
1275 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
1276 pEepromTargetPwr = eep->calTargetPower2GHT40;
1277 pFreqBin = eep->calTarget_freqbin_2GHT40;
1278 } else {
1279 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
1280 pEepromTargetPwr = eep->calTargetPower5GHT40;
1281 pFreqBin = eep->calTarget_freqbin_5GHT40;
1282 }
1283
1284 /*
1285 * create array of channels and targetpower from
1286 * targetpower piers stored on eeprom
1287 */
1288 for (i = 0; i < numPiers; i++) {
1289 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1290 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1291 }
1292
1293 /* interpolate to get target power for given frequency */
1294 return (u8) ar9003_hw_power_interpolate((s32) freq,
1295 freqArray,
1296 targetPowerArray, numPiers);
1297}
1298
1299static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
1300 u16 rateIndex, u16 freq)
1301{
1302 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
1303 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1304 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1305 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1306 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
1307 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
1308
1309 /*
1310 * create array of channels and targetpower from
1311 * targetpower piers stored on eeprom
1312 */
1313 for (i = 0; i < numPiers; i++) {
1314 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
1315 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1316 }
1317
1318 /* interpolate to get target power for given frequency */
1319 return (u8) ar9003_hw_power_interpolate((s32) freq,
1320 freqArray,
1321 targetPowerArray, numPiers);
1322}
1323
1324/* Set tx power registers to array of values passed in */
1325static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
1326{
1327#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
1328 /* make sure forced gain is not set */
1329 REG_WRITE(ah, 0xa458, 0);
1330
1331 /* Write the OFDM power per rate set */
1332
1333 /* 6 (LSB), 9, 12, 18 (MSB) */
1334 REG_WRITE(ah, 0xa3c0,
1335 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
1336 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
1337 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
1338 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1339
1340 /* 24 (LSB), 36, 48, 54 (MSB) */
1341 REG_WRITE(ah, 0xa3c4,
1342 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
1343 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
1344 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
1345 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1346
1347 /* Write the CCK power per rate set */
1348
1349 /* 1L (LSB), reserved, 2L, 2S (MSB) */
1350 REG_WRITE(ah, 0xa3c8,
1351 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
1352 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
1353 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
1354 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
1355
1356 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
1357 REG_WRITE(ah, 0xa3cc,
1358 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
1359 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
1360 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
1361 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
1362 );
1363
1364 /* Write the HT20 power per rate set */
1365
1366 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
1367 REG_WRITE(ah, 0xa3d0,
1368 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
1369 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
1370 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
1371 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
1372 );
1373
1374 /* 6 (LSB), 7, 12, 13 (MSB) */
1375 REG_WRITE(ah, 0xa3d4,
1376 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
1377 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
1378 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
1379 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
1380 );
1381
1382 /* 14 (LSB), 15, 20, 21 */
1383 REG_WRITE(ah, 0xa3e4,
1384 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
1385 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
1386 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
1387 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
1388 );
1389
1390 /* Mixed HT20 and HT40 rates */
1391
1392 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
1393 REG_WRITE(ah, 0xa3e8,
1394 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
1395 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
1396 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
1397 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
1398 );
1399
1400 /*
1401 * Write the HT40 power per rate set
1402 * correct PAR difference between HT40 and HT20/LEGACY
1403 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
1404 */
1405 REG_WRITE(ah, 0xa3d8,
1406 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
1407 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
1408 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
1409 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
1410 );
1411
1412 /* 6 (LSB), 7, 12, 13 (MSB) */
1413 REG_WRITE(ah, 0xa3dc,
1414 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
1415 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
1416 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
1417 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
1418 );
1419
1420 /* 14 (LSB), 15, 20, 21 */
1421 REG_WRITE(ah, 0xa3ec,
1422 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
1423 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
1424 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
1425 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
1426 );
1427
1428 return 0;
1429#undef POW_SM
1430}
1431
1432static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq)
1433{
1434 u8 targetPowerValT2[ar9300RateSize];
1435 /* XXX: hard code for now, need to get from eeprom struct */
1436 u8 ht40PowerIncForPdadc = 0;
1437 bool is2GHz = false;
1438 unsigned int i = 0;
1439 struct ath_common *common = ath9k_hw_common(ah);
1440
1441 if (freq < 4000)
1442 is2GHz = true;
1443
1444 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
1445 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
1446 is2GHz);
1447 targetPowerValT2[ALL_TARGET_LEGACY_36] =
1448 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
1449 is2GHz);
1450 targetPowerValT2[ALL_TARGET_LEGACY_48] =
1451 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
1452 is2GHz);
1453 targetPowerValT2[ALL_TARGET_LEGACY_54] =
1454 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
1455 is2GHz);
1456 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
1457 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
1458 freq);
1459 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
1460 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
1461 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
1462 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
1463 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
1464 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
1465 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
1466 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1467 is2GHz);
1468 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
1469 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1470 freq, is2GHz);
1471 targetPowerValT2[ALL_TARGET_HT20_4] =
1472 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1473 is2GHz);
1474 targetPowerValT2[ALL_TARGET_HT20_5] =
1475 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1476 is2GHz);
1477 targetPowerValT2[ALL_TARGET_HT20_6] =
1478 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1479 is2GHz);
1480 targetPowerValT2[ALL_TARGET_HT20_7] =
1481 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1482 is2GHz);
1483 targetPowerValT2[ALL_TARGET_HT20_12] =
1484 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1485 is2GHz);
1486 targetPowerValT2[ALL_TARGET_HT20_13] =
1487 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1488 is2GHz);
1489 targetPowerValT2[ALL_TARGET_HT20_14] =
1490 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1491 is2GHz);
1492 targetPowerValT2[ALL_TARGET_HT20_15] =
1493 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1494 is2GHz);
1495 targetPowerValT2[ALL_TARGET_HT20_20] =
1496 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1497 is2GHz);
1498 targetPowerValT2[ALL_TARGET_HT20_21] =
1499 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1500 is2GHz);
1501 targetPowerValT2[ALL_TARGET_HT20_22] =
1502 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1503 is2GHz);
1504 targetPowerValT2[ALL_TARGET_HT20_23] =
1505 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1506 is2GHz);
1507 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
1508 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1509 is2GHz) + ht40PowerIncForPdadc;
1510 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
1511 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1512 freq,
1513 is2GHz) + ht40PowerIncForPdadc;
1514 targetPowerValT2[ALL_TARGET_HT40_4] =
1515 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1516 is2GHz) + ht40PowerIncForPdadc;
1517 targetPowerValT2[ALL_TARGET_HT40_5] =
1518 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1519 is2GHz) + ht40PowerIncForPdadc;
1520 targetPowerValT2[ALL_TARGET_HT40_6] =
1521 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1522 is2GHz) + ht40PowerIncForPdadc;
1523 targetPowerValT2[ALL_TARGET_HT40_7] =
1524 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1525 is2GHz) + ht40PowerIncForPdadc;
1526 targetPowerValT2[ALL_TARGET_HT40_12] =
1527 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1528 is2GHz) + ht40PowerIncForPdadc;
1529 targetPowerValT2[ALL_TARGET_HT40_13] =
1530 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1531 is2GHz) + ht40PowerIncForPdadc;
1532 targetPowerValT2[ALL_TARGET_HT40_14] =
1533 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1534 is2GHz) + ht40PowerIncForPdadc;
1535 targetPowerValT2[ALL_TARGET_HT40_15] =
1536 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1537 is2GHz) + ht40PowerIncForPdadc;
1538 targetPowerValT2[ALL_TARGET_HT40_20] =
1539 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1540 is2GHz) + ht40PowerIncForPdadc;
1541 targetPowerValT2[ALL_TARGET_HT40_21] =
1542 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1543 is2GHz) + ht40PowerIncForPdadc;
1544 targetPowerValT2[ALL_TARGET_HT40_22] =
1545 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1546 is2GHz) + ht40PowerIncForPdadc;
1547 targetPowerValT2[ALL_TARGET_HT40_23] =
1548 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1549 is2GHz) + ht40PowerIncForPdadc;
1550
1551 while (i < ar9300RateSize) {
1552 ath_print(common, ATH_DBG_EEPROM,
1553 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1554 i++;
1555
1556 ath_print(common, ATH_DBG_EEPROM,
1557 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1558 i++;
1559
1560 ath_print(common, ATH_DBG_EEPROM,
1561 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1562 i++;
1563
1564 ath_print(common, ATH_DBG_EEPROM,
1565 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
1566 i++;
1567 }
1568
1569 /* Write target power array to registers */
1570 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
1571}
1572
1573static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
1574 int mode,
1575 int ipier,
1576 int ichain,
1577 int *pfrequency,
1578 int *pcorrection,
1579 int *ptemperature, int *pvoltage)
1580{
1581 u8 *pCalPier;
1582 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
1583 int is2GHz;
1584 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1585 struct ath_common *common = ath9k_hw_common(ah);
1586
1587 if (ichain >= AR9300_MAX_CHAINS) {
1588 ath_print(common, ATH_DBG_EEPROM,
1589 "Invalid chain index, must be less than %d\n",
1590 AR9300_MAX_CHAINS);
1591 return -1;
1592 }
1593
1594 if (mode) { /* 5GHz */
1595 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
1596 ath_print(common, ATH_DBG_EEPROM,
1597 "Invalid 5GHz cal pier index, must "
1598 "be less than %d\n",
1599 AR9300_NUM_5G_CAL_PIERS);
1600 return -1;
1601 }
1602 pCalPier = &(eep->calFreqPier5G[ipier]);
1603 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
1604 is2GHz = 0;
1605 } else {
1606 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
1607 ath_print(common, ATH_DBG_EEPROM,
1608 "Invalid 2GHz cal pier index, must "
1609 "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
1610 return -1;
1611 }
1612
1613 pCalPier = &(eep->calFreqPier2G[ipier]);
1614 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
1615 is2GHz = 1;
1616 }
1617
1618 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
1619 *pcorrection = pCalPierStruct->refPower;
1620 *ptemperature = pCalPierStruct->tempMeas;
1621 *pvoltage = pCalPierStruct->voltMeas;
1622
1623 return 0;
1624}
1625
1626static int ar9003_hw_power_control_override(struct ath_hw *ah,
1627 int frequency,
1628 int *correction,
1629 int *voltage, int *temperature)
1630{
1631 int tempSlope = 0;
1632 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1633
1634 REG_RMW(ah, AR_PHY_TPC_11_B0,
1635 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1636 AR_PHY_TPC_OLPC_GAIN_DELTA);
1637 REG_RMW(ah, AR_PHY_TPC_11_B1,
1638 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1639 AR_PHY_TPC_OLPC_GAIN_DELTA);
1640 REG_RMW(ah, AR_PHY_TPC_11_B2,
1641 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1642 AR_PHY_TPC_OLPC_GAIN_DELTA);
1643
1644 /* enable open loop power control on chip */
1645 REG_RMW(ah, AR_PHY_TPC_6_B0,
1646 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1647 AR_PHY_TPC_6_ERROR_EST_MODE);
1648 REG_RMW(ah, AR_PHY_TPC_6_B1,
1649 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1650 AR_PHY_TPC_6_ERROR_EST_MODE);
1651 REG_RMW(ah, AR_PHY_TPC_6_B2,
1652 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1653 AR_PHY_TPC_6_ERROR_EST_MODE);
1654
1655 /*
1656 * enable temperature compensation
1657 * Need to use register names
1658 */
1659 if (frequency < 4000)
1660 tempSlope = eep->modalHeader2G.tempSlope;
1661 else
1662 tempSlope = eep->modalHeader5G.tempSlope;
1663
1664 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
1665 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
1666 temperature[0]);
1667
1668 return 0;
1669}
1670
1671/* Apply the recorded correction values. */
1672static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
1673{
1674 int ichain, ipier, npier;
1675 int mode;
1676 int lfrequency[AR9300_MAX_CHAINS],
1677 lcorrection[AR9300_MAX_CHAINS],
1678 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
1679 int hfrequency[AR9300_MAX_CHAINS],
1680 hcorrection[AR9300_MAX_CHAINS],
1681 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
1682 int fdiff;
1683 int correction[AR9300_MAX_CHAINS],
1684 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
1685 int pfrequency, pcorrection, ptemperature, pvoltage;
1686 struct ath_common *common = ath9k_hw_common(ah);
1687
1688 mode = (frequency >= 4000);
1689 if (mode)
1690 npier = AR9300_NUM_5G_CAL_PIERS;
1691 else
1692 npier = AR9300_NUM_2G_CAL_PIERS;
1693
1694 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1695 lfrequency[ichain] = 0;
1696 hfrequency[ichain] = 100000;
1697 }
1698 /* identify best lower and higher frequency calibration measurement */
1699 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1700 for (ipier = 0; ipier < npier; ipier++) {
1701 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
1702 &pfrequency, &pcorrection,
1703 &ptemperature, &pvoltage)) {
1704 fdiff = frequency - pfrequency;
1705
1706 /*
1707 * this measurement is higher than
1708 * our desired frequency
1709 */
1710 if (fdiff <= 0) {
1711 if (hfrequency[ichain] <= 0 ||
1712 hfrequency[ichain] >= 100000 ||
1713 fdiff >
1714 (frequency - hfrequency[ichain])) {
1715 /*
1716 * new best higher
1717 * frequency measurement
1718 */
1719 hfrequency[ichain] = pfrequency;
1720 hcorrection[ichain] =
1721 pcorrection;
1722 htemperature[ichain] =
1723 ptemperature;
1724 hvoltage[ichain] = pvoltage;
1725 }
1726 }
1727 if (fdiff >= 0) {
1728 if (lfrequency[ichain] <= 0
1729 || fdiff <
1730 (frequency - lfrequency[ichain])) {
1731 /*
1732 * new best lower
1733 * frequency measurement
1734 */
1735 lfrequency[ichain] = pfrequency;
1736 lcorrection[ichain] =
1737 pcorrection;
1738 ltemperature[ichain] =
1739 ptemperature;
1740 lvoltage[ichain] = pvoltage;
1741 }
1742 }
1743 }
1744 }
1745 }
1746
1747 /* interpolate */
1748 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1749 ath_print(common, ATH_DBG_EEPROM,
1750 "ch=%d f=%d low=%d %d h=%d %d\n",
1751 ichain, frequency, lfrequency[ichain],
1752 lcorrection[ichain], hfrequency[ichain],
1753 hcorrection[ichain]);
1754 /* they're the same, so just pick one */
1755 if (hfrequency[ichain] == lfrequency[ichain]) {
1756 correction[ichain] = lcorrection[ichain];
1757 voltage[ichain] = lvoltage[ichain];
1758 temperature[ichain] = ltemperature[ichain];
1759 }
1760 /* the low frequency is good */
1761 else if (frequency - lfrequency[ichain] < 1000) {
1762 /* so is the high frequency, interpolate */
1763 if (hfrequency[ichain] - frequency < 1000) {
1764
1765 correction[ichain] = lcorrection[ichain] +
1766 (((frequency - lfrequency[ichain]) *
1767 (hcorrection[ichain] -
1768 lcorrection[ichain])) /
1769 (hfrequency[ichain] - lfrequency[ichain]));
1770
1771 temperature[ichain] = ltemperature[ichain] +
1772 (((frequency - lfrequency[ichain]) *
1773 (htemperature[ichain] -
1774 ltemperature[ichain])) /
1775 (hfrequency[ichain] - lfrequency[ichain]));
1776
1777 voltage[ichain] =
1778 lvoltage[ichain] +
1779 (((frequency -
1780 lfrequency[ichain]) * (hvoltage[ichain] -
1781 lvoltage[ichain]))
1782 / (hfrequency[ichain] -
1783 lfrequency[ichain]));
1784 }
1785 /* only low is good, use it */
1786 else {
1787 correction[ichain] = lcorrection[ichain];
1788 temperature[ichain] = ltemperature[ichain];
1789 voltage[ichain] = lvoltage[ichain];
1790 }
1791 }
1792 /* only high is good, use it */
1793 else if (hfrequency[ichain] - frequency < 1000) {
1794 correction[ichain] = hcorrection[ichain];
1795 temperature[ichain] = htemperature[ichain];
1796 voltage[ichain] = hvoltage[ichain];
1797 } else { /* nothing is good, presume 0???? */
1798 correction[ichain] = 0;
1799 temperature[ichain] = 0;
1800 voltage[ichain] = 0;
1801 }
1802 }
1803
1804 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
1805 temperature);
1806
1807 ath_print(common, ATH_DBG_EEPROM,
1808 "for frequency=%d, calibration correction = %d %d %d\n",
1809 frequency, correction[0], correction[1], correction[2]);
1810
1811 return 0;
1812}
1813
1814static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
1815 struct ath9k_channel *chan, u16 cfgCtl,
1816 u8 twiceAntennaReduction,
1817 u8 twiceMaxRegulatoryPower,
1818 u8 powerLimit)
1819{
1820 ar9003_hw_set_target_power_eeprom(ah, chan->channel);
1821 ar9003_hw_calibration_apply(ah, chan->channel);
1822}
1823
1824static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
1825 u16 i, bool is2GHz)
1826{
1827 return AR_NO_SPUR;
1828}
1829
1830const struct eeprom_ops eep_ar9300_ops = {
1831 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
1832 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
1833 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
1834 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
1835 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
1836 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
1837 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
1838 .set_board_values = ath9k_hw_ar9300_set_board_values,
1839 .set_addac = ath9k_hw_ar9300_set_addac,
1840 .set_txpower = ath9k_hw_ar9300_set_txpower,
1841 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel
1842};