]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
Merge branch 'wireless-2.6' into wireless-next-2.6
[mirror_ubuntu-artful-kernel.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 static 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
604 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
605 {
606 return 0;
607 }
608
609 static 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
650 static 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->baseEepHeader.swreg);
663 eep->baseEepHeader.swreg = dword;
664
665 dword = swab32(eep->modalHeader2G.antCtrlCommon);
666 eep->modalHeader2G.antCtrlCommon = dword;
667
668 dword = swab32(eep->modalHeader2G.antCtrlCommon2);
669 eep->modalHeader2G.antCtrlCommon2 = dword;
670
671 dword = swab32(eep->modalHeader5G.antCtrlCommon);
672 eep->modalHeader5G.antCtrlCommon = dword;
673
674 dword = swab32(eep->modalHeader5G.antCtrlCommon2);
675 eep->modalHeader5G.antCtrlCommon2 = dword;
676
677 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
678 word = swab16(eep->modalHeader2G.antCtrlChain[i]);
679 eep->modalHeader2G.antCtrlChain[i] = word;
680
681 word = swab16(eep->modalHeader5G.antCtrlChain[i]);
682 eep->modalHeader5G.antCtrlChain[i] = word;
683 }
684 }
685 #endif
686
687 static bool ar9300_hw_read_eeprom(struct ath_hw *ah,
688 long address, u8 *buffer, int many)
689 {
690 int i;
691 u8 value[2];
692 unsigned long eepAddr;
693 unsigned long byteAddr;
694 u16 *svalue;
695 struct ath_common *common = ath9k_hw_common(ah);
696
697 if ((address < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) {
698 ath_print(common, ATH_DBG_EEPROM,
699 "eeprom address not in range\n");
700 return false;
701 }
702
703 for (i = 0; i < many; i++) {
704 eepAddr = (u16) (address + i) / 2;
705 byteAddr = (u16) (address + i) % 2;
706 svalue = (u16 *) value;
707 if (!ath9k_hw_nvram_read(common, eepAddr, svalue)) {
708 ath_print(common, ATH_DBG_EEPROM,
709 "unable to read eeprom region\n");
710 return false;
711 }
712 *svalue = le16_to_cpu(*svalue);
713 buffer[i] = value[byteAddr];
714 }
715
716 return true;
717 }
718
719 static bool ar9300_read_eeprom(struct ath_hw *ah,
720 int address, u8 *buffer, int many)
721 {
722 int it;
723
724 for (it = 0; it < many; it++)
725 if (!ar9300_hw_read_eeprom(ah,
726 (address - it),
727 (buffer + it), 1))
728 return false;
729 return true;
730 }
731
732 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
733 int *length, int *major, int *minor)
734 {
735 unsigned long value[4];
736
737 value[0] = best[0];
738 value[1] = best[1];
739 value[2] = best[2];
740 value[3] = best[3];
741 *code = ((value[0] >> 5) & 0x0007);
742 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
743 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
744 *major = (value[2] & 0x000f);
745 *minor = (value[3] & 0x00ff);
746 }
747
748 static u16 ar9300_comp_cksum(u8 *data, int dsize)
749 {
750 int it, checksum = 0;
751
752 for (it = 0; it < dsize; it++) {
753 checksum += data[it];
754 checksum &= 0xffff;
755 }
756
757 return checksum;
758 }
759
760 static bool ar9300_uncompress_block(struct ath_hw *ah,
761 u8 *mptr,
762 int mdataSize,
763 u8 *block,
764 int size)
765 {
766 int it;
767 int spot;
768 int offset;
769 int length;
770 struct ath_common *common = ath9k_hw_common(ah);
771
772 spot = 0;
773
774 for (it = 0; it < size; it += (length+2)) {
775 offset = block[it];
776 offset &= 0xff;
777 spot += offset;
778 length = block[it+1];
779 length &= 0xff;
780
781 if (length > 0 && spot >= 0 && spot+length < mdataSize) {
782 ath_print(common, ATH_DBG_EEPROM,
783 "Restore at %d: spot=%d "
784 "offset=%d length=%d\n",
785 it, spot, offset, length);
786 memcpy(&mptr[spot], &block[it+2], length);
787 spot += length;
788 } else if (length > 0) {
789 ath_print(common, ATH_DBG_EEPROM,
790 "Bad restore at %d: spot=%d "
791 "offset=%d length=%d\n",
792 it, spot, offset, length);
793 return false;
794 }
795 }
796 return true;
797 }
798
799 static int ar9300_compress_decision(struct ath_hw *ah,
800 int it,
801 int code,
802 int reference,
803 u8 *mptr,
804 u8 *word, int length, int mdata_size)
805 {
806 struct ath_common *common = ath9k_hw_common(ah);
807 u8 *dptr;
808
809 switch (code) {
810 case _CompressNone:
811 if (length != mdata_size) {
812 ath_print(common, ATH_DBG_EEPROM,
813 "EEPROM structure size mismatch"
814 "memory=%d eeprom=%d\n", mdata_size, length);
815 return -1;
816 }
817 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
818 ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
819 " uncompressed, length %d\n", it, length);
820 break;
821 case _CompressBlock:
822 if (reference == 0) {
823 dptr = mptr;
824 } else {
825 if (reference != 2) {
826 ath_print(common, ATH_DBG_EEPROM,
827 "cant find reference eeprom"
828 "struct %d\n", reference);
829 return -1;
830 }
831 memcpy(mptr, &ar9300_default, mdata_size);
832 }
833 ath_print(common, ATH_DBG_EEPROM,
834 "restore eeprom %d: block, reference %d,"
835 " length %d\n", it, reference, length);
836 ar9300_uncompress_block(ah, mptr, mdata_size,
837 (u8 *) (word + COMP_HDR_LEN), length);
838 break;
839 default:
840 ath_print(common, ATH_DBG_EEPROM, "unknown compression"
841 " code %d\n", code);
842 return -1;
843 }
844 return 0;
845 }
846
847 /*
848 * Read the configuration data from the eeprom.
849 * The data can be put in any specified memory buffer.
850 *
851 * Returns -1 on error.
852 * Returns address of next memory location on success.
853 */
854 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
855 u8 *mptr, int mdata_size)
856 {
857 #define MDEFAULT 15
858 #define MSTATE 100
859 int cptr;
860 u8 *word;
861 int code;
862 int reference, length, major, minor;
863 int osize;
864 int it;
865 u16 checksum, mchecksum;
866 struct ath_common *common = ath9k_hw_common(ah);
867
868 word = kzalloc(2048, GFP_KERNEL);
869 if (!word)
870 return -1;
871
872 memcpy(mptr, &ar9300_default, mdata_size);
873
874 cptr = AR9300_BASE_ADDR;
875 for (it = 0; it < MSTATE; it++) {
876 if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
877 goto fail;
878
879 if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
880 word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
881 && word[2] == 0xff && word[3] == 0xff))
882 break;
883
884 ar9300_comp_hdr_unpack(word, &code, &reference,
885 &length, &major, &minor);
886 ath_print(common, ATH_DBG_EEPROM,
887 "Found block at %x: code=%d ref=%d"
888 "length=%d major=%d minor=%d\n", cptr, code,
889 reference, length, major, minor);
890 if (length >= 1024) {
891 ath_print(common, ATH_DBG_EEPROM,
892 "Skipping bad header\n");
893 cptr -= COMP_HDR_LEN;
894 continue;
895 }
896
897 osize = length;
898 ar9300_read_eeprom(ah, cptr, word,
899 COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
900 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
901 mchecksum = word[COMP_HDR_LEN + osize] |
902 (word[COMP_HDR_LEN + osize + 1] << 8);
903 ath_print(common, ATH_DBG_EEPROM,
904 "checksum %x %x\n", checksum, mchecksum);
905 if (checksum == mchecksum) {
906 ar9300_compress_decision(ah, it, code, reference, mptr,
907 word, length, mdata_size);
908 } else {
909 ath_print(common, ATH_DBG_EEPROM,
910 "skipping block with bad checksum\n");
911 }
912 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
913 }
914
915 kfree(word);
916 return cptr;
917
918 fail:
919 kfree(word);
920 return -1;
921 }
922
923 /*
924 * Restore the configuration structure by reading the eeprom.
925 * This function destroys any existing in-memory structure
926 * content.
927 */
928 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
929 {
930 u8 *mptr = NULL;
931 int mdata_size;
932
933 mptr = (u8 *) &ah->eeprom.ar9300_eep;
934 mdata_size = sizeof(struct ar9300_eeprom);
935
936 if (mptr && mdata_size > 0) {
937 /* At this point, mptr points to the eeprom data structure
938 * in it's "default" state. If this is big endian, swap the
939 * data structures back to "little endian"
940 */
941 /* First swap, default to Little Endian */
942 #ifdef __BIG_ENDIAN
943 ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
944 #endif
945 if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0)
946 return true;
947
948 /* Second Swap, back to Big Endian */
949 #ifdef __BIG_ENDIAN
950 ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
951 #endif
952 }
953 return false;
954 }
955
956 /* XXX: review hardware docs */
957 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
958 {
959 return ah->eeprom.ar9300_eep.eepromVersion;
960 }
961
962 /* XXX: could be read from the eepromVersion, not sure yet */
963 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
964 {
965 return 0;
966 }
967
968 static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
969 enum ieee80211_band freq_band)
970 {
971 return 1;
972 }
973
974 static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
975 struct ath9k_channel *chan)
976 {
977 return -EINVAL;
978 }
979
980 static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
981 {
982 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
983
984 if (is2ghz)
985 return eep->modalHeader2G.xpaBiasLvl;
986 else
987 return eep->modalHeader5G.xpaBiasLvl;
988 }
989
990 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
991 {
992 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
993 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
994 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
995 ((bias >> 2) & 0x3));
996 }
997
998 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
999 {
1000 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1001
1002 if (is2ghz)
1003 return eep->modalHeader2G.antCtrlCommon;
1004 else
1005 return eep->modalHeader5G.antCtrlCommon;
1006 }
1007
1008 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
1009 {
1010 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1011
1012 if (is2ghz)
1013 return eep->modalHeader2G.antCtrlCommon2;
1014 else
1015 return eep->modalHeader5G.antCtrlCommon2;
1016 }
1017
1018 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
1019 int chain,
1020 bool is2ghz)
1021 {
1022 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1023
1024 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
1025 if (is2ghz)
1026 return eep->modalHeader2G.antCtrlChain[chain];
1027 else
1028 return eep->modalHeader5G.antCtrlChain[chain];
1029 }
1030
1031 return 0;
1032 }
1033
1034 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
1035 {
1036 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
1037 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
1038
1039 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
1040 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
1041
1042 value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
1043 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
1044
1045 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
1046 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
1047
1048 value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
1049 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
1050 }
1051
1052 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
1053 {
1054 int drive_strength;
1055 unsigned long reg;
1056
1057 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
1058
1059 if (!drive_strength)
1060 return;
1061
1062 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
1063 reg &= ~0x00ffffc0;
1064 reg |= 0x5 << 21;
1065 reg |= 0x5 << 18;
1066 reg |= 0x5 << 15;
1067 reg |= 0x5 << 12;
1068 reg |= 0x5 << 9;
1069 reg |= 0x5 << 6;
1070 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
1071
1072 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
1073 reg &= ~0xffffffe0;
1074 reg |= 0x5 << 29;
1075 reg |= 0x5 << 26;
1076 reg |= 0x5 << 23;
1077 reg |= 0x5 << 20;
1078 reg |= 0x5 << 17;
1079 reg |= 0x5 << 14;
1080 reg |= 0x5 << 11;
1081 reg |= 0x5 << 8;
1082 reg |= 0x5 << 5;
1083 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
1084
1085 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
1086 reg &= ~0xff800000;
1087 reg |= 0x5 << 29;
1088 reg |= 0x5 << 26;
1089 reg |= 0x5 << 23;
1090 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
1091 }
1092
1093 static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
1094 {
1095 int internal_regulator =
1096 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
1097
1098 if (internal_regulator) {
1099 /* Internal regulator is ON. Write swreg register. */
1100 int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
1101 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1102 REG_READ(ah, AR_RTC_REG_CONTROL1) &
1103 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
1104 REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
1105 /* Set REG_CONTROL1.SWREG_PROGRAM */
1106 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1107 REG_READ(ah,
1108 AR_RTC_REG_CONTROL1) |
1109 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
1110 } else {
1111 REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1112 (REG_READ(ah,
1113 AR_RTC_SLEEP_CLK) |
1114 AR_RTC_FORCE_SWREG_PRD));
1115 }
1116 }
1117
1118 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
1119 struct ath9k_channel *chan)
1120 {
1121 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
1122 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
1123 ar9003_hw_drive_strength_apply(ah);
1124 ar9003_hw_internal_regulator_apply(ah);
1125 }
1126
1127 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
1128 struct ath9k_channel *chan)
1129 {
1130 }
1131
1132 /*
1133 * Returns the interpolated y value corresponding to the specified x value
1134 * from the np ordered pairs of data (px,py).
1135 * The pairs do not have to be in any order.
1136 * If the specified x value is less than any of the px,
1137 * the returned y value is equal to the py for the lowest px.
1138 * If the specified x value is greater than any of the px,
1139 * the returned y value is equal to the py for the highest px.
1140 */
1141 static int ar9003_hw_power_interpolate(int32_t x,
1142 int32_t *px, int32_t *py, u_int16_t np)
1143 {
1144 int ip = 0;
1145 int lx = 0, ly = 0, lhave = 0;
1146 int hx = 0, hy = 0, hhave = 0;
1147 int dx = 0;
1148 int y = 0;
1149
1150 lhave = 0;
1151 hhave = 0;
1152
1153 /* identify best lower and higher x calibration measurement */
1154 for (ip = 0; ip < np; ip++) {
1155 dx = x - px[ip];
1156
1157 /* this measurement is higher than our desired x */
1158 if (dx <= 0) {
1159 if (!hhave || dx > (x - hx)) {
1160 /* new best higher x measurement */
1161 hx = px[ip];
1162 hy = py[ip];
1163 hhave = 1;
1164 }
1165 }
1166 /* this measurement is lower than our desired x */
1167 if (dx >= 0) {
1168 if (!lhave || dx < (x - lx)) {
1169 /* new best lower x measurement */
1170 lx = px[ip];
1171 ly = py[ip];
1172 lhave = 1;
1173 }
1174 }
1175 }
1176
1177 /* the low x is good */
1178 if (lhave) {
1179 /* so is the high x */
1180 if (hhave) {
1181 /* they're the same, so just pick one */
1182 if (hx == lx)
1183 y = ly;
1184 else /* interpolate */
1185 y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
1186 } else /* only low is good, use it */
1187 y = ly;
1188 } else if (hhave) /* only high is good, use it */
1189 y = hy;
1190 else /* nothing is good,this should never happen unless np=0, ???? */
1191 y = -(1 << 30);
1192 return y;
1193 }
1194
1195 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
1196 u16 rateIndex, u16 freq, bool is2GHz)
1197 {
1198 u16 numPiers, i;
1199 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1200 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1201 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1202 struct cal_tgt_pow_legacy *pEepromTargetPwr;
1203 u8 *pFreqBin;
1204
1205 if (is2GHz) {
1206 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
1207 pEepromTargetPwr = eep->calTargetPower2G;
1208 pFreqBin = eep->calTarget_freqbin_2G;
1209 } else {
1210 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1211 pEepromTargetPwr = eep->calTargetPower5G;
1212 pFreqBin = eep->calTarget_freqbin_5G;
1213 }
1214
1215 /*
1216 * create array of channels and targetpower from
1217 * targetpower piers stored on eeprom
1218 */
1219 for (i = 0; i < numPiers; i++) {
1220 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1221 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1222 }
1223
1224 /* interpolate to get target power for given frequency */
1225 return (u8) ar9003_hw_power_interpolate((s32) freq,
1226 freqArray,
1227 targetPowerArray, numPiers);
1228 }
1229
1230 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
1231 u16 rateIndex,
1232 u16 freq, bool is2GHz)
1233 {
1234 u16 numPiers, i;
1235 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1236 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1237 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1238 struct cal_tgt_pow_ht *pEepromTargetPwr;
1239 u8 *pFreqBin;
1240
1241 if (is2GHz) {
1242 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
1243 pEepromTargetPwr = eep->calTargetPower2GHT20;
1244 pFreqBin = eep->calTarget_freqbin_2GHT20;
1245 } else {
1246 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1247 pEepromTargetPwr = eep->calTargetPower5GHT20;
1248 pFreqBin = eep->calTarget_freqbin_5GHT20;
1249 }
1250
1251 /*
1252 * create array of channels and targetpower
1253 * from targetpower piers stored on eeprom
1254 */
1255 for (i = 0; i < numPiers; i++) {
1256 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1257 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1258 }
1259
1260 /* interpolate to get target power for given frequency */
1261 return (u8) ar9003_hw_power_interpolate((s32) freq,
1262 freqArray,
1263 targetPowerArray, numPiers);
1264 }
1265
1266 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
1267 u16 rateIndex,
1268 u16 freq, bool is2GHz)
1269 {
1270 u16 numPiers, i;
1271 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
1272 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
1273 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1274 struct cal_tgt_pow_ht *pEepromTargetPwr;
1275 u8 *pFreqBin;
1276
1277 if (is2GHz) {
1278 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
1279 pEepromTargetPwr = eep->calTargetPower2GHT40;
1280 pFreqBin = eep->calTarget_freqbin_2GHT40;
1281 } else {
1282 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
1283 pEepromTargetPwr = eep->calTargetPower5GHT40;
1284 pFreqBin = eep->calTarget_freqbin_5GHT40;
1285 }
1286
1287 /*
1288 * create array of channels and targetpower from
1289 * targetpower piers stored on eeprom
1290 */
1291 for (i = 0; i < numPiers; i++) {
1292 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1293 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1294 }
1295
1296 /* interpolate to get target power for given frequency */
1297 return (u8) ar9003_hw_power_interpolate((s32) freq,
1298 freqArray,
1299 targetPowerArray, numPiers);
1300 }
1301
1302 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
1303 u16 rateIndex, u16 freq)
1304 {
1305 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
1306 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1307 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1308 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1309 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
1310 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
1311
1312 /*
1313 * create array of channels and targetpower from
1314 * targetpower piers stored on eeprom
1315 */
1316 for (i = 0; i < numPiers; i++) {
1317 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
1318 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1319 }
1320
1321 /* interpolate to get target power for given frequency */
1322 return (u8) ar9003_hw_power_interpolate((s32) freq,
1323 freqArray,
1324 targetPowerArray, numPiers);
1325 }
1326
1327 /* Set tx power registers to array of values passed in */
1328 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
1329 {
1330 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
1331 /* make sure forced gain is not set */
1332 REG_WRITE(ah, 0xa458, 0);
1333
1334 /* Write the OFDM power per rate set */
1335
1336 /* 6 (LSB), 9, 12, 18 (MSB) */
1337 REG_WRITE(ah, 0xa3c0,
1338 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
1339 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
1340 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
1341 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1342
1343 /* 24 (LSB), 36, 48, 54 (MSB) */
1344 REG_WRITE(ah, 0xa3c4,
1345 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
1346 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
1347 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
1348 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1349
1350 /* Write the CCK power per rate set */
1351
1352 /* 1L (LSB), reserved, 2L, 2S (MSB) */
1353 REG_WRITE(ah, 0xa3c8,
1354 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
1355 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
1356 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
1357 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
1358
1359 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
1360 REG_WRITE(ah, 0xa3cc,
1361 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
1362 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
1363 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
1364 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
1365 );
1366
1367 /* Write the HT20 power per rate set */
1368
1369 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
1370 REG_WRITE(ah, 0xa3d0,
1371 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
1372 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
1373 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
1374 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
1375 );
1376
1377 /* 6 (LSB), 7, 12, 13 (MSB) */
1378 REG_WRITE(ah, 0xa3d4,
1379 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
1380 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
1381 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
1382 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
1383 );
1384
1385 /* 14 (LSB), 15, 20, 21 */
1386 REG_WRITE(ah, 0xa3e4,
1387 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
1388 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
1389 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
1390 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
1391 );
1392
1393 /* Mixed HT20 and HT40 rates */
1394
1395 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
1396 REG_WRITE(ah, 0xa3e8,
1397 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
1398 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
1399 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
1400 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
1401 );
1402
1403 /*
1404 * Write the HT40 power per rate set
1405 * correct PAR difference between HT40 and HT20/LEGACY
1406 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
1407 */
1408 REG_WRITE(ah, 0xa3d8,
1409 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
1410 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
1411 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
1412 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
1413 );
1414
1415 /* 6 (LSB), 7, 12, 13 (MSB) */
1416 REG_WRITE(ah, 0xa3dc,
1417 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
1418 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
1419 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
1420 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
1421 );
1422
1423 /* 14 (LSB), 15, 20, 21 */
1424 REG_WRITE(ah, 0xa3ec,
1425 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
1426 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
1427 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
1428 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
1429 );
1430
1431 return 0;
1432 #undef POW_SM
1433 }
1434
1435 static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq)
1436 {
1437 u8 targetPowerValT2[ar9300RateSize];
1438 /* XXX: hard code for now, need to get from eeprom struct */
1439 u8 ht40PowerIncForPdadc = 0;
1440 bool is2GHz = false;
1441 unsigned int i = 0;
1442 struct ath_common *common = ath9k_hw_common(ah);
1443
1444 if (freq < 4000)
1445 is2GHz = true;
1446
1447 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
1448 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
1449 is2GHz);
1450 targetPowerValT2[ALL_TARGET_LEGACY_36] =
1451 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
1452 is2GHz);
1453 targetPowerValT2[ALL_TARGET_LEGACY_48] =
1454 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
1455 is2GHz);
1456 targetPowerValT2[ALL_TARGET_LEGACY_54] =
1457 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
1458 is2GHz);
1459 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
1460 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
1461 freq);
1462 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
1463 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
1464 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
1465 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
1466 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
1467 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
1468 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
1469 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1470 is2GHz);
1471 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
1472 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1473 freq, is2GHz);
1474 targetPowerValT2[ALL_TARGET_HT20_4] =
1475 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1476 is2GHz);
1477 targetPowerValT2[ALL_TARGET_HT20_5] =
1478 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1479 is2GHz);
1480 targetPowerValT2[ALL_TARGET_HT20_6] =
1481 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1482 is2GHz);
1483 targetPowerValT2[ALL_TARGET_HT20_7] =
1484 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1485 is2GHz);
1486 targetPowerValT2[ALL_TARGET_HT20_12] =
1487 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1488 is2GHz);
1489 targetPowerValT2[ALL_TARGET_HT20_13] =
1490 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1491 is2GHz);
1492 targetPowerValT2[ALL_TARGET_HT20_14] =
1493 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1494 is2GHz);
1495 targetPowerValT2[ALL_TARGET_HT20_15] =
1496 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1497 is2GHz);
1498 targetPowerValT2[ALL_TARGET_HT20_20] =
1499 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1500 is2GHz);
1501 targetPowerValT2[ALL_TARGET_HT20_21] =
1502 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1503 is2GHz);
1504 targetPowerValT2[ALL_TARGET_HT20_22] =
1505 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1506 is2GHz);
1507 targetPowerValT2[ALL_TARGET_HT20_23] =
1508 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1509 is2GHz);
1510 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
1511 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1512 is2GHz) + ht40PowerIncForPdadc;
1513 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
1514 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1515 freq,
1516 is2GHz) + ht40PowerIncForPdadc;
1517 targetPowerValT2[ALL_TARGET_HT40_4] =
1518 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1519 is2GHz) + ht40PowerIncForPdadc;
1520 targetPowerValT2[ALL_TARGET_HT40_5] =
1521 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1522 is2GHz) + ht40PowerIncForPdadc;
1523 targetPowerValT2[ALL_TARGET_HT40_6] =
1524 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1525 is2GHz) + ht40PowerIncForPdadc;
1526 targetPowerValT2[ALL_TARGET_HT40_7] =
1527 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1528 is2GHz) + ht40PowerIncForPdadc;
1529 targetPowerValT2[ALL_TARGET_HT40_12] =
1530 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1531 is2GHz) + ht40PowerIncForPdadc;
1532 targetPowerValT2[ALL_TARGET_HT40_13] =
1533 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1534 is2GHz) + ht40PowerIncForPdadc;
1535 targetPowerValT2[ALL_TARGET_HT40_14] =
1536 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1537 is2GHz) + ht40PowerIncForPdadc;
1538 targetPowerValT2[ALL_TARGET_HT40_15] =
1539 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1540 is2GHz) + ht40PowerIncForPdadc;
1541 targetPowerValT2[ALL_TARGET_HT40_20] =
1542 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1543 is2GHz) + ht40PowerIncForPdadc;
1544 targetPowerValT2[ALL_TARGET_HT40_21] =
1545 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1546 is2GHz) + ht40PowerIncForPdadc;
1547 targetPowerValT2[ALL_TARGET_HT40_22] =
1548 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1549 is2GHz) + ht40PowerIncForPdadc;
1550 targetPowerValT2[ALL_TARGET_HT40_23] =
1551 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1552 is2GHz) + ht40PowerIncForPdadc;
1553
1554 while (i < ar9300RateSize) {
1555 ath_print(common, ATH_DBG_EEPROM,
1556 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1557 i++;
1558
1559 ath_print(common, ATH_DBG_EEPROM,
1560 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1561 i++;
1562
1563 ath_print(common, ATH_DBG_EEPROM,
1564 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1565 i++;
1566
1567 ath_print(common, ATH_DBG_EEPROM,
1568 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
1569 i++;
1570 }
1571
1572 /* Write target power array to registers */
1573 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
1574 }
1575
1576 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
1577 int mode,
1578 int ipier,
1579 int ichain,
1580 int *pfrequency,
1581 int *pcorrection,
1582 int *ptemperature, int *pvoltage)
1583 {
1584 u8 *pCalPier;
1585 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
1586 int is2GHz;
1587 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1588 struct ath_common *common = ath9k_hw_common(ah);
1589
1590 if (ichain >= AR9300_MAX_CHAINS) {
1591 ath_print(common, ATH_DBG_EEPROM,
1592 "Invalid chain index, must be less than %d\n",
1593 AR9300_MAX_CHAINS);
1594 return -1;
1595 }
1596
1597 if (mode) { /* 5GHz */
1598 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
1599 ath_print(common, ATH_DBG_EEPROM,
1600 "Invalid 5GHz cal pier index, must "
1601 "be less than %d\n",
1602 AR9300_NUM_5G_CAL_PIERS);
1603 return -1;
1604 }
1605 pCalPier = &(eep->calFreqPier5G[ipier]);
1606 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
1607 is2GHz = 0;
1608 } else {
1609 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
1610 ath_print(common, ATH_DBG_EEPROM,
1611 "Invalid 2GHz cal pier index, must "
1612 "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
1613 return -1;
1614 }
1615
1616 pCalPier = &(eep->calFreqPier2G[ipier]);
1617 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
1618 is2GHz = 1;
1619 }
1620
1621 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
1622 *pcorrection = pCalPierStruct->refPower;
1623 *ptemperature = pCalPierStruct->tempMeas;
1624 *pvoltage = pCalPierStruct->voltMeas;
1625
1626 return 0;
1627 }
1628
1629 static int ar9003_hw_power_control_override(struct ath_hw *ah,
1630 int frequency,
1631 int *correction,
1632 int *voltage, int *temperature)
1633 {
1634 int tempSlope = 0;
1635 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1636
1637 REG_RMW(ah, AR_PHY_TPC_11_B0,
1638 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1639 AR_PHY_TPC_OLPC_GAIN_DELTA);
1640 REG_RMW(ah, AR_PHY_TPC_11_B1,
1641 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1642 AR_PHY_TPC_OLPC_GAIN_DELTA);
1643 REG_RMW(ah, AR_PHY_TPC_11_B2,
1644 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1645 AR_PHY_TPC_OLPC_GAIN_DELTA);
1646
1647 /* enable open loop power control on chip */
1648 REG_RMW(ah, AR_PHY_TPC_6_B0,
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_B1,
1652 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1653 AR_PHY_TPC_6_ERROR_EST_MODE);
1654 REG_RMW(ah, AR_PHY_TPC_6_B2,
1655 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1656 AR_PHY_TPC_6_ERROR_EST_MODE);
1657
1658 /*
1659 * enable temperature compensation
1660 * Need to use register names
1661 */
1662 if (frequency < 4000)
1663 tempSlope = eep->modalHeader2G.tempSlope;
1664 else
1665 tempSlope = eep->modalHeader5G.tempSlope;
1666
1667 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
1668 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
1669 temperature[0]);
1670
1671 return 0;
1672 }
1673
1674 /* Apply the recorded correction values. */
1675 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
1676 {
1677 int ichain, ipier, npier;
1678 int mode;
1679 int lfrequency[AR9300_MAX_CHAINS],
1680 lcorrection[AR9300_MAX_CHAINS],
1681 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
1682 int hfrequency[AR9300_MAX_CHAINS],
1683 hcorrection[AR9300_MAX_CHAINS],
1684 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
1685 int fdiff;
1686 int correction[AR9300_MAX_CHAINS],
1687 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
1688 int pfrequency, pcorrection, ptemperature, pvoltage;
1689 struct ath_common *common = ath9k_hw_common(ah);
1690
1691 mode = (frequency >= 4000);
1692 if (mode)
1693 npier = AR9300_NUM_5G_CAL_PIERS;
1694 else
1695 npier = AR9300_NUM_2G_CAL_PIERS;
1696
1697 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1698 lfrequency[ichain] = 0;
1699 hfrequency[ichain] = 100000;
1700 }
1701 /* identify best lower and higher frequency calibration measurement */
1702 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1703 for (ipier = 0; ipier < npier; ipier++) {
1704 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
1705 &pfrequency, &pcorrection,
1706 &ptemperature, &pvoltage)) {
1707 fdiff = frequency - pfrequency;
1708
1709 /*
1710 * this measurement is higher than
1711 * our desired frequency
1712 */
1713 if (fdiff <= 0) {
1714 if (hfrequency[ichain] <= 0 ||
1715 hfrequency[ichain] >= 100000 ||
1716 fdiff >
1717 (frequency - hfrequency[ichain])) {
1718 /*
1719 * new best higher
1720 * frequency measurement
1721 */
1722 hfrequency[ichain] = pfrequency;
1723 hcorrection[ichain] =
1724 pcorrection;
1725 htemperature[ichain] =
1726 ptemperature;
1727 hvoltage[ichain] = pvoltage;
1728 }
1729 }
1730 if (fdiff >= 0) {
1731 if (lfrequency[ichain] <= 0
1732 || fdiff <
1733 (frequency - lfrequency[ichain])) {
1734 /*
1735 * new best lower
1736 * frequency measurement
1737 */
1738 lfrequency[ichain] = pfrequency;
1739 lcorrection[ichain] =
1740 pcorrection;
1741 ltemperature[ichain] =
1742 ptemperature;
1743 lvoltage[ichain] = pvoltage;
1744 }
1745 }
1746 }
1747 }
1748 }
1749
1750 /* interpolate */
1751 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1752 ath_print(common, ATH_DBG_EEPROM,
1753 "ch=%d f=%d low=%d %d h=%d %d\n",
1754 ichain, frequency, lfrequency[ichain],
1755 lcorrection[ichain], hfrequency[ichain],
1756 hcorrection[ichain]);
1757 /* they're the same, so just pick one */
1758 if (hfrequency[ichain] == lfrequency[ichain]) {
1759 correction[ichain] = lcorrection[ichain];
1760 voltage[ichain] = lvoltage[ichain];
1761 temperature[ichain] = ltemperature[ichain];
1762 }
1763 /* the low frequency is good */
1764 else if (frequency - lfrequency[ichain] < 1000) {
1765 /* so is the high frequency, interpolate */
1766 if (hfrequency[ichain] - frequency < 1000) {
1767
1768 correction[ichain] = lcorrection[ichain] +
1769 (((frequency - lfrequency[ichain]) *
1770 (hcorrection[ichain] -
1771 lcorrection[ichain])) /
1772 (hfrequency[ichain] - lfrequency[ichain]));
1773
1774 temperature[ichain] = ltemperature[ichain] +
1775 (((frequency - lfrequency[ichain]) *
1776 (htemperature[ichain] -
1777 ltemperature[ichain])) /
1778 (hfrequency[ichain] - lfrequency[ichain]));
1779
1780 voltage[ichain] =
1781 lvoltage[ichain] +
1782 (((frequency -
1783 lfrequency[ichain]) * (hvoltage[ichain] -
1784 lvoltage[ichain]))
1785 / (hfrequency[ichain] -
1786 lfrequency[ichain]));
1787 }
1788 /* only low is good, use it */
1789 else {
1790 correction[ichain] = lcorrection[ichain];
1791 temperature[ichain] = ltemperature[ichain];
1792 voltage[ichain] = lvoltage[ichain];
1793 }
1794 }
1795 /* only high is good, use it */
1796 else if (hfrequency[ichain] - frequency < 1000) {
1797 correction[ichain] = hcorrection[ichain];
1798 temperature[ichain] = htemperature[ichain];
1799 voltage[ichain] = hvoltage[ichain];
1800 } else { /* nothing is good, presume 0???? */
1801 correction[ichain] = 0;
1802 temperature[ichain] = 0;
1803 voltage[ichain] = 0;
1804 }
1805 }
1806
1807 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
1808 temperature);
1809
1810 ath_print(common, ATH_DBG_EEPROM,
1811 "for frequency=%d, calibration correction = %d %d %d\n",
1812 frequency, correction[0], correction[1], correction[2]);
1813
1814 return 0;
1815 }
1816
1817 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
1818 struct ath9k_channel *chan, u16 cfgCtl,
1819 u8 twiceAntennaReduction,
1820 u8 twiceMaxRegulatoryPower,
1821 u8 powerLimit)
1822 {
1823 ah->txpower_limit = powerLimit;
1824 ar9003_hw_set_target_power_eeprom(ah, chan->channel);
1825 ar9003_hw_calibration_apply(ah, chan->channel);
1826 }
1827
1828 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
1829 u16 i, bool is2GHz)
1830 {
1831 return AR_NO_SPUR;
1832 }
1833
1834 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
1835 {
1836 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1837
1838 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
1839 }
1840
1841 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
1842 {
1843 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1844
1845 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
1846 }
1847
1848 const struct eeprom_ops eep_ar9300_ops = {
1849 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
1850 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
1851 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
1852 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
1853 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
1854 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
1855 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
1856 .set_board_values = ath9k_hw_ar9300_set_board_values,
1857 .set_addac = ath9k_hw_ar9300_set_addac,
1858 .set_txpower = ath9k_hw_ar9300_set_txpower,
1859 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel
1860 };