Linux 4.2.1
[linux/fpc-iii.git] / drivers / net / wireless / ath / ath9k / ar9003_eeprom.c
blob8b4561e8ce1aacf0ff2523cad1069d67bf2ca15f
1 /*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
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.
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.
17 #include <asm/unaligned.h>
18 #include "hw.h"
19 #include "ar9003_phy.h"
20 #include "ar9003_eeprom.h"
21 #include "ar9003_mci.h"
23 #define COMP_HDR_LEN 4
24 #define COMP_CKSUM_LEN 2
26 #define LE16(x) cpu_to_le16(x)
27 #define LE32(x) cpu_to_le32(x)
29 /* Local defines to distinguish between extension and control CTL's */
30 #define EXT_ADDITIVE (0x8000)
31 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
32 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
33 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
35 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
36 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
38 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
40 #define EEPROM_DATA_LEN_9485 1088
42 static int ar9003_hw_power_interpolate(int32_t x,
43 int32_t *px, int32_t *py, u_int16_t np);
45 static const struct ar9300_eeprom ar9300_default = {
46 .eepromVersion = 2,
47 .templateVersion = 2,
48 .macAddr = {0, 2, 3, 4, 5, 6},
49 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
51 .baseEepHeader = {
52 .regDmn = { LE16(0), LE16(0x1f) },
53 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
54 .opCapFlags = {
55 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
56 .eepMisc = 0,
58 .rfSilent = 0,
59 .blueToothOptions = 0,
60 .deviceCap = 0,
61 .deviceType = 5, /* takes lower byte in eeprom location */
62 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
63 .params_for_tuning_caps = {0, 0},
64 .featureEnable = 0x0c,
66 * bit0 - enable tx temp comp - disabled
67 * bit1 - enable tx volt comp - disabled
68 * bit2 - enable fastClock - enabled
69 * bit3 - enable doubling - enabled
70 * bit4 - enable internal regulator - disabled
71 * bit5 - enable pa predistortion - disabled
73 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
74 .eepromWriteEnableGpio = 3,
75 .wlanDisableGpio = 0,
76 .wlanLedGpio = 8,
77 .rxBandSelectGpio = 0xff,
78 .txrxgain = 0,
79 .swreg = 0,
81 .modalHeader2G = {
82 /* ar9300_modal_eep_header 2g */
83 /* 4 idle,t1,t2,b(4 bits per setting) */
84 .antCtrlCommon = LE32(0x110),
85 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
86 .antCtrlCommon2 = LE32(0x22222),
89 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
90 * rx1, rx12, b (2 bits each)
92 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
95 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
96 * for ar9280 (0xa20c/b20c 5:0)
98 .xatten1DB = {0, 0, 0},
101 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
102 * for ar9280 (0xa20c/b20c 16:12
104 .xatten1Margin = {0, 0, 0},
105 .tempSlope = 36,
106 .voltSlope = 0,
109 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
110 * channels in usual fbin coding format
112 .spurChans = {0, 0, 0, 0, 0},
115 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
116 * if the register is per chain
118 .noiseFloorThreshCh = {-1, 0, 0},
119 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
120 .quick_drop = 0,
121 .xpaBiasLvl = 0,
122 .txFrameToDataStart = 0x0e,
123 .txFrameToPaOn = 0x0e,
124 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
125 .antennaGain = 0,
126 .switchSettling = 0x2c,
127 .adcDesiredSize = -30,
128 .txEndToXpaOff = 0,
129 .txEndToRxOn = 0x2,
130 .txFrameToXpaOn = 0xe,
131 .thresh62 = 28,
132 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
133 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
134 .switchcomspdt = 0,
135 .xlna_bias_strength = 0,
136 .futureModal = {
137 0, 0, 0, 0, 0, 0, 0,
140 .base_ext1 = {
141 .ant_div_control = 0,
142 .future = {0, 0},
143 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
145 .calFreqPier2G = {
146 FREQ2FBIN(2412, 1),
147 FREQ2FBIN(2437, 1),
148 FREQ2FBIN(2472, 1),
150 /* ar9300_cal_data_per_freq_op_loop 2g */
151 .calPierData2G = {
152 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
153 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
154 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
156 .calTarget_freqbin_Cck = {
157 FREQ2FBIN(2412, 1),
158 FREQ2FBIN(2484, 1),
160 .calTarget_freqbin_2G = {
161 FREQ2FBIN(2412, 1),
162 FREQ2FBIN(2437, 1),
163 FREQ2FBIN(2472, 1)
165 .calTarget_freqbin_2GHT20 = {
166 FREQ2FBIN(2412, 1),
167 FREQ2FBIN(2437, 1),
168 FREQ2FBIN(2472, 1)
170 .calTarget_freqbin_2GHT40 = {
171 FREQ2FBIN(2412, 1),
172 FREQ2FBIN(2437, 1),
173 FREQ2FBIN(2472, 1)
175 .calTargetPowerCck = {
176 /* 1L-5L,5S,11L,11S */
177 { {36, 36, 36, 36} },
178 { {36, 36, 36, 36} },
180 .calTargetPower2G = {
181 /* 6-24,36,48,54 */
182 { {32, 32, 28, 24} },
183 { {32, 32, 28, 24} },
184 { {32, 32, 28, 24} },
186 .calTargetPower2GHT20 = {
187 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
188 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
189 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
191 .calTargetPower2GHT40 = {
192 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
193 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
194 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
196 .ctlIndex_2G = {
197 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
198 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
200 .ctl_freqbin_2G = {
202 FREQ2FBIN(2412, 1),
203 FREQ2FBIN(2417, 1),
204 FREQ2FBIN(2457, 1),
205 FREQ2FBIN(2462, 1)
208 FREQ2FBIN(2412, 1),
209 FREQ2FBIN(2417, 1),
210 FREQ2FBIN(2462, 1),
211 0xFF,
215 FREQ2FBIN(2412, 1),
216 FREQ2FBIN(2417, 1),
217 FREQ2FBIN(2462, 1),
218 0xFF,
221 FREQ2FBIN(2422, 1),
222 FREQ2FBIN(2427, 1),
223 FREQ2FBIN(2447, 1),
224 FREQ2FBIN(2452, 1)
228 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
229 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
230 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
231 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
235 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
236 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
237 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
242 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
243 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
244 FREQ2FBIN(2472, 1),
249 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
250 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
251 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
252 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
256 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
257 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
258 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
262 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
263 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
264 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
269 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
270 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
271 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
276 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
277 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
278 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
279 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
282 .ctlPowerData_2G = {
283 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
284 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
285 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
287 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
288 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
289 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
291 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
292 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
293 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
295 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
296 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
297 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
299 .modalHeader5G = {
300 /* 4 idle,t1,t2,b (4 bits per setting) */
301 .antCtrlCommon = LE32(0x110),
302 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
303 .antCtrlCommon2 = LE32(0x22222),
304 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
305 .antCtrlChain = {
306 LE16(0x000), LE16(0x000), LE16(0x000),
308 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
309 .xatten1DB = {0, 0, 0},
312 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
313 * for merlin (0xa20c/b20c 16:12
315 .xatten1Margin = {0, 0, 0},
316 .tempSlope = 68,
317 .voltSlope = 0,
318 /* spurChans spur channels in usual fbin coding format */
319 .spurChans = {0, 0, 0, 0, 0},
320 /* noiseFloorThreshCh Check if the register is per chain */
321 .noiseFloorThreshCh = {-1, 0, 0},
322 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
323 .quick_drop = 0,
324 .xpaBiasLvl = 0,
325 .txFrameToDataStart = 0x0e,
326 .txFrameToPaOn = 0x0e,
327 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
328 .antennaGain = 0,
329 .switchSettling = 0x2d,
330 .adcDesiredSize = -30,
331 .txEndToXpaOff = 0,
332 .txEndToRxOn = 0x2,
333 .txFrameToXpaOn = 0xe,
334 .thresh62 = 28,
335 .papdRateMaskHt20 = LE32(0x0c80c080),
336 .papdRateMaskHt40 = LE32(0x0080c080),
337 .switchcomspdt = 0,
338 .xlna_bias_strength = 0,
339 .futureModal = {
340 0, 0, 0, 0, 0, 0, 0,
343 .base_ext2 = {
344 .tempSlopeLow = 0,
345 .tempSlopeHigh = 0,
346 .xatten1DBLow = {0, 0, 0},
347 .xatten1MarginLow = {0, 0, 0},
348 .xatten1DBHigh = {0, 0, 0},
349 .xatten1MarginHigh = {0, 0, 0}
351 .calFreqPier5G = {
352 FREQ2FBIN(5180, 0),
353 FREQ2FBIN(5220, 0),
354 FREQ2FBIN(5320, 0),
355 FREQ2FBIN(5400, 0),
356 FREQ2FBIN(5500, 0),
357 FREQ2FBIN(5600, 0),
358 FREQ2FBIN(5725, 0),
359 FREQ2FBIN(5825, 0)
361 .calPierData5G = {
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},
373 {0, 0, 0, 0, 0},
374 {0, 0, 0, 0, 0},
375 {0, 0, 0, 0, 0},
376 {0, 0, 0, 0, 0},
377 {0, 0, 0, 0, 0},
378 {0, 0, 0, 0, 0},
379 {0, 0, 0, 0, 0},
380 {0, 0, 0, 0, 0},
383 {0, 0, 0, 0, 0},
384 {0, 0, 0, 0, 0},
385 {0, 0, 0, 0, 0},
386 {0, 0, 0, 0, 0},
387 {0, 0, 0, 0, 0},
388 {0, 0, 0, 0, 0},
389 {0, 0, 0, 0, 0},
390 {0, 0, 0, 0, 0},
394 .calTarget_freqbin_5G = {
395 FREQ2FBIN(5180, 0),
396 FREQ2FBIN(5220, 0),
397 FREQ2FBIN(5320, 0),
398 FREQ2FBIN(5400, 0),
399 FREQ2FBIN(5500, 0),
400 FREQ2FBIN(5600, 0),
401 FREQ2FBIN(5725, 0),
402 FREQ2FBIN(5825, 0)
404 .calTarget_freqbin_5GHT20 = {
405 FREQ2FBIN(5180, 0),
406 FREQ2FBIN(5240, 0),
407 FREQ2FBIN(5320, 0),
408 FREQ2FBIN(5500, 0),
409 FREQ2FBIN(5700, 0),
410 FREQ2FBIN(5745, 0),
411 FREQ2FBIN(5725, 0),
412 FREQ2FBIN(5825, 0)
414 .calTarget_freqbin_5GHT40 = {
415 FREQ2FBIN(5180, 0),
416 FREQ2FBIN(5240, 0),
417 FREQ2FBIN(5320, 0),
418 FREQ2FBIN(5500, 0),
419 FREQ2FBIN(5700, 0),
420 FREQ2FBIN(5745, 0),
421 FREQ2FBIN(5725, 0),
422 FREQ2FBIN(5825, 0)
424 .calTargetPower5G = {
425 /* 6-24,36,48,54 */
426 { {20, 20, 20, 10} },
427 { {20, 20, 20, 10} },
428 { {20, 20, 20, 10} },
429 { {20, 20, 20, 10} },
430 { {20, 20, 20, 10} },
431 { {20, 20, 20, 10} },
432 { {20, 20, 20, 10} },
433 { {20, 20, 20, 10} },
435 .calTargetPower5GHT20 = {
437 * 0_8_16,1-3_9-11_17-19,
438 * 4,5,6,7,12,13,14,15,20,21,22,23
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 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
443 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
444 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
445 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
446 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
447 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
449 .calTargetPower5GHT40 = {
451 * 0_8_16,1-3_9-11_17-19,
452 * 4,5,6,7,12,13,14,15,20,21,22,23
454 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
455 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
456 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
457 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
458 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
459 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
460 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
461 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
463 .ctlIndex_5G = {
464 0x10, 0x16, 0x18, 0x40, 0x46,
465 0x48, 0x30, 0x36, 0x38
467 .ctl_freqbin_5G = {
469 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
470 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
471 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
472 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
473 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
474 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
475 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
476 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
479 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
480 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
481 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
482 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
483 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
484 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
485 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
486 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
490 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
491 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
492 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
493 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
494 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
495 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
496 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
497 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
501 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
502 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
503 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
504 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
505 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
506 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
507 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
508 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
512 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
513 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
514 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
515 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
516 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
517 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
518 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
519 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
523 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
524 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
525 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
526 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
527 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
528 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
529 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
530 /* Data[5].ctlEdges[7].bChannel */ 0xFF
534 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
535 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
536 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
537 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
538 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
539 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
540 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
541 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
545 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
546 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
547 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
548 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
549 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
550 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
551 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
552 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
556 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
557 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
558 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
559 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
560 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
561 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
562 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
563 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
566 .ctlPowerData_5G = {
569 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
570 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
575 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
576 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
581 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
582 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
587 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
588 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
593 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
594 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
599 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
600 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
605 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
606 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
611 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
612 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
617 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
618 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
624 static const struct ar9300_eeprom ar9300_x113 = {
625 .eepromVersion = 2,
626 .templateVersion = 6,
627 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
628 .custData = {"x113-023-f0000"},
629 .baseEepHeader = {
630 .regDmn = { LE16(0), LE16(0x1f) },
631 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
632 .opCapFlags = {
633 .opFlags = AR5416_OPFLAGS_11A,
634 .eepMisc = 0,
636 .rfSilent = 0,
637 .blueToothOptions = 0,
638 .deviceCap = 0,
639 .deviceType = 5, /* takes lower byte in eeprom location */
640 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
641 .params_for_tuning_caps = {0, 0},
642 .featureEnable = 0x0d,
644 * bit0 - enable tx temp comp - disabled
645 * bit1 - enable tx volt comp - disabled
646 * bit2 - enable fastClock - enabled
647 * bit3 - enable doubling - enabled
648 * bit4 - enable internal regulator - disabled
649 * bit5 - enable pa predistortion - disabled
651 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
652 .eepromWriteEnableGpio = 6,
653 .wlanDisableGpio = 0,
654 .wlanLedGpio = 8,
655 .rxBandSelectGpio = 0xff,
656 .txrxgain = 0x21,
657 .swreg = 0,
659 .modalHeader2G = {
660 /* ar9300_modal_eep_header 2g */
661 /* 4 idle,t1,t2,b(4 bits per setting) */
662 .antCtrlCommon = LE32(0x110),
663 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
664 .antCtrlCommon2 = LE32(0x44444),
667 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
668 * rx1, rx12, b (2 bits each)
670 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
673 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
674 * for ar9280 (0xa20c/b20c 5:0)
676 .xatten1DB = {0, 0, 0},
679 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
680 * for ar9280 (0xa20c/b20c 16:12
682 .xatten1Margin = {0, 0, 0},
683 .tempSlope = 25,
684 .voltSlope = 0,
687 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
688 * channels in usual fbin coding format
690 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
693 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
694 * if the register is per chain
696 .noiseFloorThreshCh = {-1, 0, 0},
697 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
698 .quick_drop = 0,
699 .xpaBiasLvl = 0,
700 .txFrameToDataStart = 0x0e,
701 .txFrameToPaOn = 0x0e,
702 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
703 .antennaGain = 0,
704 .switchSettling = 0x2c,
705 .adcDesiredSize = -30,
706 .txEndToXpaOff = 0,
707 .txEndToRxOn = 0x2,
708 .txFrameToXpaOn = 0xe,
709 .thresh62 = 28,
710 .papdRateMaskHt20 = LE32(0x0c80c080),
711 .papdRateMaskHt40 = LE32(0x0080c080),
712 .switchcomspdt = 0,
713 .xlna_bias_strength = 0,
714 .futureModal = {
715 0, 0, 0, 0, 0, 0, 0,
718 .base_ext1 = {
719 .ant_div_control = 0,
720 .future = {0, 0},
721 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
723 .calFreqPier2G = {
724 FREQ2FBIN(2412, 1),
725 FREQ2FBIN(2437, 1),
726 FREQ2FBIN(2472, 1),
728 /* ar9300_cal_data_per_freq_op_loop 2g */
729 .calPierData2G = {
730 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
731 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
732 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
734 .calTarget_freqbin_Cck = {
735 FREQ2FBIN(2412, 1),
736 FREQ2FBIN(2472, 1),
738 .calTarget_freqbin_2G = {
739 FREQ2FBIN(2412, 1),
740 FREQ2FBIN(2437, 1),
741 FREQ2FBIN(2472, 1)
743 .calTarget_freqbin_2GHT20 = {
744 FREQ2FBIN(2412, 1),
745 FREQ2FBIN(2437, 1),
746 FREQ2FBIN(2472, 1)
748 .calTarget_freqbin_2GHT40 = {
749 FREQ2FBIN(2412, 1),
750 FREQ2FBIN(2437, 1),
751 FREQ2FBIN(2472, 1)
753 .calTargetPowerCck = {
754 /* 1L-5L,5S,11L,11S */
755 { {34, 34, 34, 34} },
756 { {34, 34, 34, 34} },
758 .calTargetPower2G = {
759 /* 6-24,36,48,54 */
760 { {34, 34, 32, 32} },
761 { {34, 34, 32, 32} },
762 { {34, 34, 32, 32} },
764 .calTargetPower2GHT20 = {
765 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
766 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
767 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
769 .calTargetPower2GHT40 = {
770 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
771 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
772 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
774 .ctlIndex_2G = {
775 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
776 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
778 .ctl_freqbin_2G = {
780 FREQ2FBIN(2412, 1),
781 FREQ2FBIN(2417, 1),
782 FREQ2FBIN(2457, 1),
783 FREQ2FBIN(2462, 1)
786 FREQ2FBIN(2412, 1),
787 FREQ2FBIN(2417, 1),
788 FREQ2FBIN(2462, 1),
789 0xFF,
793 FREQ2FBIN(2412, 1),
794 FREQ2FBIN(2417, 1),
795 FREQ2FBIN(2462, 1),
796 0xFF,
799 FREQ2FBIN(2422, 1),
800 FREQ2FBIN(2427, 1),
801 FREQ2FBIN(2447, 1),
802 FREQ2FBIN(2452, 1)
806 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
807 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
808 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
809 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
813 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
814 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
815 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
820 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
821 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
822 FREQ2FBIN(2472, 1),
827 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
828 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
829 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
830 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
834 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
835 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
836 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
840 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
841 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
842 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
847 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
848 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
849 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
854 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
855 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
856 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
857 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
860 .ctlPowerData_2G = {
861 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
862 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
863 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
865 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
866 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
867 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
869 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
870 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
871 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
873 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
874 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
875 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
877 .modalHeader5G = {
878 /* 4 idle,t1,t2,b (4 bits per setting) */
879 .antCtrlCommon = LE32(0x220),
880 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
881 .antCtrlCommon2 = LE32(0x11111),
882 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
883 .antCtrlChain = {
884 LE16(0x150), LE16(0x150), LE16(0x150),
886 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
887 .xatten1DB = {0, 0, 0},
890 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
891 * for merlin (0xa20c/b20c 16:12
893 .xatten1Margin = {0, 0, 0},
894 .tempSlope = 68,
895 .voltSlope = 0,
896 /* spurChans spur channels in usual fbin coding format */
897 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
898 /* noiseFloorThreshCh Check if the register is per chain */
899 .noiseFloorThreshCh = {-1, 0, 0},
900 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
901 .quick_drop = 0,
902 .xpaBiasLvl = 0xf,
903 .txFrameToDataStart = 0x0e,
904 .txFrameToPaOn = 0x0e,
905 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
906 .antennaGain = 0,
907 .switchSettling = 0x2d,
908 .adcDesiredSize = -30,
909 .txEndToXpaOff = 0,
910 .txEndToRxOn = 0x2,
911 .txFrameToXpaOn = 0xe,
912 .thresh62 = 28,
913 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
914 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
915 .switchcomspdt = 0,
916 .xlna_bias_strength = 0,
917 .futureModal = {
918 0, 0, 0, 0, 0, 0, 0,
921 .base_ext2 = {
922 .tempSlopeLow = 72,
923 .tempSlopeHigh = 105,
924 .xatten1DBLow = {0, 0, 0},
925 .xatten1MarginLow = {0, 0, 0},
926 .xatten1DBHigh = {0, 0, 0},
927 .xatten1MarginHigh = {0, 0, 0}
929 .calFreqPier5G = {
930 FREQ2FBIN(5180, 0),
931 FREQ2FBIN(5240, 0),
932 FREQ2FBIN(5320, 0),
933 FREQ2FBIN(5400, 0),
934 FREQ2FBIN(5500, 0),
935 FREQ2FBIN(5600, 0),
936 FREQ2FBIN(5745, 0),
937 FREQ2FBIN(5785, 0)
939 .calPierData5G = {
941 {0, 0, 0, 0, 0},
942 {0, 0, 0, 0, 0},
943 {0, 0, 0, 0, 0},
944 {0, 0, 0, 0, 0},
945 {0, 0, 0, 0, 0},
946 {0, 0, 0, 0, 0},
947 {0, 0, 0, 0, 0},
948 {0, 0, 0, 0, 0},
951 {0, 0, 0, 0, 0},
952 {0, 0, 0, 0, 0},
953 {0, 0, 0, 0, 0},
954 {0, 0, 0, 0, 0},
955 {0, 0, 0, 0, 0},
956 {0, 0, 0, 0, 0},
957 {0, 0, 0, 0, 0},
958 {0, 0, 0, 0, 0},
961 {0, 0, 0, 0, 0},
962 {0, 0, 0, 0, 0},
963 {0, 0, 0, 0, 0},
964 {0, 0, 0, 0, 0},
965 {0, 0, 0, 0, 0},
966 {0, 0, 0, 0, 0},
967 {0, 0, 0, 0, 0},
968 {0, 0, 0, 0, 0},
972 .calTarget_freqbin_5G = {
973 FREQ2FBIN(5180, 0),
974 FREQ2FBIN(5220, 0),
975 FREQ2FBIN(5320, 0),
976 FREQ2FBIN(5400, 0),
977 FREQ2FBIN(5500, 0),
978 FREQ2FBIN(5600, 0),
979 FREQ2FBIN(5745, 0),
980 FREQ2FBIN(5785, 0)
982 .calTarget_freqbin_5GHT20 = {
983 FREQ2FBIN(5180, 0),
984 FREQ2FBIN(5240, 0),
985 FREQ2FBIN(5320, 0),
986 FREQ2FBIN(5400, 0),
987 FREQ2FBIN(5500, 0),
988 FREQ2FBIN(5700, 0),
989 FREQ2FBIN(5745, 0),
990 FREQ2FBIN(5825, 0)
992 .calTarget_freqbin_5GHT40 = {
993 FREQ2FBIN(5190, 0),
994 FREQ2FBIN(5230, 0),
995 FREQ2FBIN(5320, 0),
996 FREQ2FBIN(5410, 0),
997 FREQ2FBIN(5510, 0),
998 FREQ2FBIN(5670, 0),
999 FREQ2FBIN(5755, 0),
1000 FREQ2FBIN(5825, 0)
1002 .calTargetPower5G = {
1003 /* 6-24,36,48,54 */
1004 { {42, 40, 40, 34} },
1005 { {42, 40, 40, 34} },
1006 { {42, 40, 40, 34} },
1007 { {42, 40, 40, 34} },
1008 { {42, 40, 40, 34} },
1009 { {42, 40, 40, 34} },
1010 { {42, 40, 40, 34} },
1011 { {42, 40, 40, 34} },
1013 .calTargetPower5GHT20 = {
1015 * 0_8_16,1-3_9-11_17-19,
1016 * 4,5,6,7,12,13,14,15,20,21,22,23
1018 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1019 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1020 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1021 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1022 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1023 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1024 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1025 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1027 .calTargetPower5GHT40 = {
1029 * 0_8_16,1-3_9-11_17-19,
1030 * 4,5,6,7,12,13,14,15,20,21,22,23
1032 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1033 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1034 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1035 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1036 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1037 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1038 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1039 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1041 .ctlIndex_5G = {
1042 0x10, 0x16, 0x18, 0x40, 0x46,
1043 0x48, 0x30, 0x36, 0x38
1045 .ctl_freqbin_5G = {
1047 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1048 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1049 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1050 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1051 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1052 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1053 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1054 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1057 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1058 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1059 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1060 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1061 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1062 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1063 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1064 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1068 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1069 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1070 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1071 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1072 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1073 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1074 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1075 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1079 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1080 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1081 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1082 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1083 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1084 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1085 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1086 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1090 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1091 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1092 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1093 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1094 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1095 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1096 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1097 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1101 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1102 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1103 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1104 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1105 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1106 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1107 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1108 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1112 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1113 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1114 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1115 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1116 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1117 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1118 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1119 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1123 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1124 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1125 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1126 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1127 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1128 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1129 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1130 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1134 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1135 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1136 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1137 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1138 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1139 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1140 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1141 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1144 .ctlPowerData_5G = {
1147 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1148 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1153 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1154 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1159 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1160 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1165 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1166 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1171 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1172 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1177 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1178 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1183 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1184 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1189 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1190 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1195 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1196 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1203 static const struct ar9300_eeprom ar9300_h112 = {
1204 .eepromVersion = 2,
1205 .templateVersion = 3,
1206 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1207 .custData = {"h112-241-f0000"},
1208 .baseEepHeader = {
1209 .regDmn = { LE16(0), LE16(0x1f) },
1210 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1211 .opCapFlags = {
1212 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1213 .eepMisc = 0,
1215 .rfSilent = 0,
1216 .blueToothOptions = 0,
1217 .deviceCap = 0,
1218 .deviceType = 5, /* takes lower byte in eeprom location */
1219 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1220 .params_for_tuning_caps = {0, 0},
1221 .featureEnable = 0x0d,
1223 * bit0 - enable tx temp comp - disabled
1224 * bit1 - enable tx volt comp - disabled
1225 * bit2 - enable fastClock - enabled
1226 * bit3 - enable doubling - enabled
1227 * bit4 - enable internal regulator - disabled
1228 * bit5 - enable pa predistortion - disabled
1230 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1231 .eepromWriteEnableGpio = 6,
1232 .wlanDisableGpio = 0,
1233 .wlanLedGpio = 8,
1234 .rxBandSelectGpio = 0xff,
1235 .txrxgain = 0x10,
1236 .swreg = 0,
1238 .modalHeader2G = {
1239 /* ar9300_modal_eep_header 2g */
1240 /* 4 idle,t1,t2,b(4 bits per setting) */
1241 .antCtrlCommon = LE32(0x110),
1242 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1243 .antCtrlCommon2 = LE32(0x44444),
1246 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1247 * rx1, rx12, b (2 bits each)
1249 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1252 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1253 * for ar9280 (0xa20c/b20c 5:0)
1255 .xatten1DB = {0, 0, 0},
1258 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1259 * for ar9280 (0xa20c/b20c 16:12
1261 .xatten1Margin = {0, 0, 0},
1262 .tempSlope = 25,
1263 .voltSlope = 0,
1266 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1267 * channels in usual fbin coding format
1269 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1272 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1273 * if the register is per chain
1275 .noiseFloorThreshCh = {-1, 0, 0},
1276 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1277 .quick_drop = 0,
1278 .xpaBiasLvl = 0,
1279 .txFrameToDataStart = 0x0e,
1280 .txFrameToPaOn = 0x0e,
1281 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1282 .antennaGain = 0,
1283 .switchSettling = 0x2c,
1284 .adcDesiredSize = -30,
1285 .txEndToXpaOff = 0,
1286 .txEndToRxOn = 0x2,
1287 .txFrameToXpaOn = 0xe,
1288 .thresh62 = 28,
1289 .papdRateMaskHt20 = LE32(0x0c80c080),
1290 .papdRateMaskHt40 = LE32(0x0080c080),
1291 .switchcomspdt = 0,
1292 .xlna_bias_strength = 0,
1293 .futureModal = {
1294 0, 0, 0, 0, 0, 0, 0,
1297 .base_ext1 = {
1298 .ant_div_control = 0,
1299 .future = {0, 0},
1300 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1302 .calFreqPier2G = {
1303 FREQ2FBIN(2412, 1),
1304 FREQ2FBIN(2437, 1),
1305 FREQ2FBIN(2462, 1),
1307 /* ar9300_cal_data_per_freq_op_loop 2g */
1308 .calPierData2G = {
1309 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1310 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1311 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1313 .calTarget_freqbin_Cck = {
1314 FREQ2FBIN(2412, 1),
1315 FREQ2FBIN(2472, 1),
1317 .calTarget_freqbin_2G = {
1318 FREQ2FBIN(2412, 1),
1319 FREQ2FBIN(2437, 1),
1320 FREQ2FBIN(2472, 1)
1322 .calTarget_freqbin_2GHT20 = {
1323 FREQ2FBIN(2412, 1),
1324 FREQ2FBIN(2437, 1),
1325 FREQ2FBIN(2472, 1)
1327 .calTarget_freqbin_2GHT40 = {
1328 FREQ2FBIN(2412, 1),
1329 FREQ2FBIN(2437, 1),
1330 FREQ2FBIN(2472, 1)
1332 .calTargetPowerCck = {
1333 /* 1L-5L,5S,11L,11S */
1334 { {34, 34, 34, 34} },
1335 { {34, 34, 34, 34} },
1337 .calTargetPower2G = {
1338 /* 6-24,36,48,54 */
1339 { {34, 34, 32, 32} },
1340 { {34, 34, 32, 32} },
1341 { {34, 34, 32, 32} },
1343 .calTargetPower2GHT20 = {
1344 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1345 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1346 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1348 .calTargetPower2GHT40 = {
1349 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1350 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1351 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1353 .ctlIndex_2G = {
1354 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1355 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1357 .ctl_freqbin_2G = {
1359 FREQ2FBIN(2412, 1),
1360 FREQ2FBIN(2417, 1),
1361 FREQ2FBIN(2457, 1),
1362 FREQ2FBIN(2462, 1)
1365 FREQ2FBIN(2412, 1),
1366 FREQ2FBIN(2417, 1),
1367 FREQ2FBIN(2462, 1),
1368 0xFF,
1372 FREQ2FBIN(2412, 1),
1373 FREQ2FBIN(2417, 1),
1374 FREQ2FBIN(2462, 1),
1375 0xFF,
1378 FREQ2FBIN(2422, 1),
1379 FREQ2FBIN(2427, 1),
1380 FREQ2FBIN(2447, 1),
1381 FREQ2FBIN(2452, 1)
1385 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1386 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1387 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1388 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1392 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1393 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1394 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1399 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1400 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1401 FREQ2FBIN(2472, 1),
1406 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1407 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1408 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1409 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1413 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1414 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1415 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1419 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1420 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1421 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1426 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1427 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1428 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1433 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1434 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1435 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1436 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1439 .ctlPowerData_2G = {
1440 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1441 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1442 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1444 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
1445 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1446 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1448 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1449 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1450 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1452 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1453 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1454 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1456 .modalHeader5G = {
1457 /* 4 idle,t1,t2,b (4 bits per setting) */
1458 .antCtrlCommon = LE32(0x220),
1459 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1460 .antCtrlCommon2 = LE32(0x44444),
1461 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1462 .antCtrlChain = {
1463 LE16(0x150), LE16(0x150), LE16(0x150),
1465 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1466 .xatten1DB = {0, 0, 0},
1469 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1470 * for merlin (0xa20c/b20c 16:12
1472 .xatten1Margin = {0, 0, 0},
1473 .tempSlope = 45,
1474 .voltSlope = 0,
1475 /* spurChans spur channels in usual fbin coding format */
1476 .spurChans = {0, 0, 0, 0, 0},
1477 /* noiseFloorThreshCh Check if the register is per chain */
1478 .noiseFloorThreshCh = {-1, 0, 0},
1479 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1480 .quick_drop = 0,
1481 .xpaBiasLvl = 0,
1482 .txFrameToDataStart = 0x0e,
1483 .txFrameToPaOn = 0x0e,
1484 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1485 .antennaGain = 0,
1486 .switchSettling = 0x2d,
1487 .adcDesiredSize = -30,
1488 .txEndToXpaOff = 0,
1489 .txEndToRxOn = 0x2,
1490 .txFrameToXpaOn = 0xe,
1491 .thresh62 = 28,
1492 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1493 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1494 .switchcomspdt = 0,
1495 .xlna_bias_strength = 0,
1496 .futureModal = {
1497 0, 0, 0, 0, 0, 0, 0,
1500 .base_ext2 = {
1501 .tempSlopeLow = 40,
1502 .tempSlopeHigh = 50,
1503 .xatten1DBLow = {0, 0, 0},
1504 .xatten1MarginLow = {0, 0, 0},
1505 .xatten1DBHigh = {0, 0, 0},
1506 .xatten1MarginHigh = {0, 0, 0}
1508 .calFreqPier5G = {
1509 FREQ2FBIN(5180, 0),
1510 FREQ2FBIN(5220, 0),
1511 FREQ2FBIN(5320, 0),
1512 FREQ2FBIN(5400, 0),
1513 FREQ2FBIN(5500, 0),
1514 FREQ2FBIN(5600, 0),
1515 FREQ2FBIN(5700, 0),
1516 FREQ2FBIN(5785, 0)
1518 .calPierData5G = {
1520 {0, 0, 0, 0, 0},
1521 {0, 0, 0, 0, 0},
1522 {0, 0, 0, 0, 0},
1523 {0, 0, 0, 0, 0},
1524 {0, 0, 0, 0, 0},
1525 {0, 0, 0, 0, 0},
1526 {0, 0, 0, 0, 0},
1527 {0, 0, 0, 0, 0},
1530 {0, 0, 0, 0, 0},
1531 {0, 0, 0, 0, 0},
1532 {0, 0, 0, 0, 0},
1533 {0, 0, 0, 0, 0},
1534 {0, 0, 0, 0, 0},
1535 {0, 0, 0, 0, 0},
1536 {0, 0, 0, 0, 0},
1537 {0, 0, 0, 0, 0},
1540 {0, 0, 0, 0, 0},
1541 {0, 0, 0, 0, 0},
1542 {0, 0, 0, 0, 0},
1543 {0, 0, 0, 0, 0},
1544 {0, 0, 0, 0, 0},
1545 {0, 0, 0, 0, 0},
1546 {0, 0, 0, 0, 0},
1547 {0, 0, 0, 0, 0},
1551 .calTarget_freqbin_5G = {
1552 FREQ2FBIN(5180, 0),
1553 FREQ2FBIN(5240, 0),
1554 FREQ2FBIN(5320, 0),
1555 FREQ2FBIN(5400, 0),
1556 FREQ2FBIN(5500, 0),
1557 FREQ2FBIN(5600, 0),
1558 FREQ2FBIN(5700, 0),
1559 FREQ2FBIN(5825, 0)
1561 .calTarget_freqbin_5GHT20 = {
1562 FREQ2FBIN(5180, 0),
1563 FREQ2FBIN(5240, 0),
1564 FREQ2FBIN(5320, 0),
1565 FREQ2FBIN(5400, 0),
1566 FREQ2FBIN(5500, 0),
1567 FREQ2FBIN(5700, 0),
1568 FREQ2FBIN(5745, 0),
1569 FREQ2FBIN(5825, 0)
1571 .calTarget_freqbin_5GHT40 = {
1572 FREQ2FBIN(5180, 0),
1573 FREQ2FBIN(5240, 0),
1574 FREQ2FBIN(5320, 0),
1575 FREQ2FBIN(5400, 0),
1576 FREQ2FBIN(5500, 0),
1577 FREQ2FBIN(5700, 0),
1578 FREQ2FBIN(5745, 0),
1579 FREQ2FBIN(5825, 0)
1581 .calTargetPower5G = {
1582 /* 6-24,36,48,54 */
1583 { {30, 30, 28, 24} },
1584 { {30, 30, 28, 24} },
1585 { {30, 30, 28, 24} },
1586 { {30, 30, 28, 24} },
1587 { {30, 30, 28, 24} },
1588 { {30, 30, 28, 24} },
1589 { {30, 30, 28, 24} },
1590 { {30, 30, 28, 24} },
1592 .calTargetPower5GHT20 = {
1594 * 0_8_16,1-3_9-11_17-19,
1595 * 4,5,6,7,12,13,14,15,20,21,22,23
1597 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1598 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1599 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1600 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1601 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1602 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1603 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1604 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1606 .calTargetPower5GHT40 = {
1608 * 0_8_16,1-3_9-11_17-19,
1609 * 4,5,6,7,12,13,14,15,20,21,22,23
1611 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1612 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1613 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1614 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1615 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1616 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1617 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1618 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1620 .ctlIndex_5G = {
1621 0x10, 0x16, 0x18, 0x40, 0x46,
1622 0x48, 0x30, 0x36, 0x38
1624 .ctl_freqbin_5G = {
1626 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1627 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1628 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1629 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1630 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1631 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1632 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1633 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1636 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1637 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1638 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1639 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1640 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1641 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1642 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1643 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1647 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1648 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1649 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1650 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1651 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1652 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1653 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1654 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1658 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1659 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1660 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1661 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1662 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1663 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1664 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1665 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1669 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1670 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1671 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1672 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1673 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1674 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1675 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1676 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1680 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1681 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1682 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1683 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1684 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1685 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1686 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1687 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1691 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1692 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1693 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1694 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1695 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1696 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1697 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1698 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1702 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1703 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1704 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1705 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1706 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1707 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1708 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1709 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1713 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1714 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1715 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1716 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1717 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1718 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1719 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1720 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1723 .ctlPowerData_5G = {
1726 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1727 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1732 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1733 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1738 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1739 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1744 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1745 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1750 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1751 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1756 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1757 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1762 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1763 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1768 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1769 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1774 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1775 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1782 static const struct ar9300_eeprom ar9300_x112 = {
1783 .eepromVersion = 2,
1784 .templateVersion = 5,
1785 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1786 .custData = {"x112-041-f0000"},
1787 .baseEepHeader = {
1788 .regDmn = { LE16(0), LE16(0x1f) },
1789 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1790 .opCapFlags = {
1791 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1792 .eepMisc = 0,
1794 .rfSilent = 0,
1795 .blueToothOptions = 0,
1796 .deviceCap = 0,
1797 .deviceType = 5, /* takes lower byte in eeprom location */
1798 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1799 .params_for_tuning_caps = {0, 0},
1800 .featureEnable = 0x0d,
1802 * bit0 - enable tx temp comp - disabled
1803 * bit1 - enable tx volt comp - disabled
1804 * bit2 - enable fastclock - enabled
1805 * bit3 - enable doubling - enabled
1806 * bit4 - enable internal regulator - disabled
1807 * bit5 - enable pa predistortion - disabled
1809 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1810 .eepromWriteEnableGpio = 6,
1811 .wlanDisableGpio = 0,
1812 .wlanLedGpio = 8,
1813 .rxBandSelectGpio = 0xff,
1814 .txrxgain = 0x0,
1815 .swreg = 0,
1817 .modalHeader2G = {
1818 /* ar9300_modal_eep_header 2g */
1819 /* 4 idle,t1,t2,b(4 bits per setting) */
1820 .antCtrlCommon = LE32(0x110),
1821 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1822 .antCtrlCommon2 = LE32(0x22222),
1825 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1826 * rx1, rx12, b (2 bits each)
1828 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1831 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1832 * for ar9280 (0xa20c/b20c 5:0)
1834 .xatten1DB = {0x1b, 0x1b, 0x1b},
1837 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1838 * for ar9280 (0xa20c/b20c 16:12
1840 .xatten1Margin = {0x15, 0x15, 0x15},
1841 .tempSlope = 50,
1842 .voltSlope = 0,
1845 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1846 * channels in usual fbin coding format
1848 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1851 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1852 * if the register is per chain
1854 .noiseFloorThreshCh = {-1, 0, 0},
1855 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1856 .quick_drop = 0,
1857 .xpaBiasLvl = 0,
1858 .txFrameToDataStart = 0x0e,
1859 .txFrameToPaOn = 0x0e,
1860 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1861 .antennaGain = 0,
1862 .switchSettling = 0x2c,
1863 .adcDesiredSize = -30,
1864 .txEndToXpaOff = 0,
1865 .txEndToRxOn = 0x2,
1866 .txFrameToXpaOn = 0xe,
1867 .thresh62 = 28,
1868 .papdRateMaskHt20 = LE32(0x0c80c080),
1869 .papdRateMaskHt40 = LE32(0x0080c080),
1870 .switchcomspdt = 0,
1871 .xlna_bias_strength = 0,
1872 .futureModal = {
1873 0, 0, 0, 0, 0, 0, 0,
1876 .base_ext1 = {
1877 .ant_div_control = 0,
1878 .future = {0, 0},
1879 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1881 .calFreqPier2G = {
1882 FREQ2FBIN(2412, 1),
1883 FREQ2FBIN(2437, 1),
1884 FREQ2FBIN(2472, 1),
1886 /* ar9300_cal_data_per_freq_op_loop 2g */
1887 .calPierData2G = {
1888 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1889 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1890 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1892 .calTarget_freqbin_Cck = {
1893 FREQ2FBIN(2412, 1),
1894 FREQ2FBIN(2472, 1),
1896 .calTarget_freqbin_2G = {
1897 FREQ2FBIN(2412, 1),
1898 FREQ2FBIN(2437, 1),
1899 FREQ2FBIN(2472, 1)
1901 .calTarget_freqbin_2GHT20 = {
1902 FREQ2FBIN(2412, 1),
1903 FREQ2FBIN(2437, 1),
1904 FREQ2FBIN(2472, 1)
1906 .calTarget_freqbin_2GHT40 = {
1907 FREQ2FBIN(2412, 1),
1908 FREQ2FBIN(2437, 1),
1909 FREQ2FBIN(2472, 1)
1911 .calTargetPowerCck = {
1912 /* 1L-5L,5S,11L,11s */
1913 { {38, 38, 38, 38} },
1914 { {38, 38, 38, 38} },
1916 .calTargetPower2G = {
1917 /* 6-24,36,48,54 */
1918 { {38, 38, 36, 34} },
1919 { {38, 38, 36, 34} },
1920 { {38, 38, 34, 32} },
1922 .calTargetPower2GHT20 = {
1923 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1924 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1925 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1927 .calTargetPower2GHT40 = {
1928 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1929 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1930 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1932 .ctlIndex_2G = {
1933 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1934 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1936 .ctl_freqbin_2G = {
1938 FREQ2FBIN(2412, 1),
1939 FREQ2FBIN(2417, 1),
1940 FREQ2FBIN(2457, 1),
1941 FREQ2FBIN(2462, 1)
1944 FREQ2FBIN(2412, 1),
1945 FREQ2FBIN(2417, 1),
1946 FREQ2FBIN(2462, 1),
1947 0xFF,
1951 FREQ2FBIN(2412, 1),
1952 FREQ2FBIN(2417, 1),
1953 FREQ2FBIN(2462, 1),
1954 0xFF,
1957 FREQ2FBIN(2422, 1),
1958 FREQ2FBIN(2427, 1),
1959 FREQ2FBIN(2447, 1),
1960 FREQ2FBIN(2452, 1)
1964 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1965 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1966 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1967 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1971 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1972 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1973 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1978 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1979 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1980 FREQ2FBIN(2472, 1),
1985 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
1986 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
1987 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
1988 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
1992 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1993 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1994 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1998 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1999 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2000 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2005 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2006 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2007 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2012 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2013 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2014 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2015 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2018 .ctlPowerData_2G = {
2019 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2020 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2021 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2023 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2024 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2025 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2027 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2028 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2029 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2031 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2032 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2033 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2035 .modalHeader5G = {
2036 /* 4 idle,t1,t2,b (4 bits per setting) */
2037 .antCtrlCommon = LE32(0x110),
2038 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2039 .antCtrlCommon2 = LE32(0x22222),
2040 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2041 .antCtrlChain = {
2042 LE16(0x0), LE16(0x0), LE16(0x0),
2044 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2045 .xatten1DB = {0x13, 0x19, 0x17},
2048 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2049 * for merlin (0xa20c/b20c 16:12
2051 .xatten1Margin = {0x19, 0x19, 0x19},
2052 .tempSlope = 70,
2053 .voltSlope = 15,
2054 /* spurChans spur channels in usual fbin coding format */
2055 .spurChans = {0, 0, 0, 0, 0},
2056 /* noiseFloorThreshch check if the register is per chain */
2057 .noiseFloorThreshCh = {-1, 0, 0},
2058 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2059 .quick_drop = 0,
2060 .xpaBiasLvl = 0,
2061 .txFrameToDataStart = 0x0e,
2062 .txFrameToPaOn = 0x0e,
2063 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2064 .antennaGain = 0,
2065 .switchSettling = 0x2d,
2066 .adcDesiredSize = -30,
2067 .txEndToXpaOff = 0,
2068 .txEndToRxOn = 0x2,
2069 .txFrameToXpaOn = 0xe,
2070 .thresh62 = 28,
2071 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2072 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2073 .switchcomspdt = 0,
2074 .xlna_bias_strength = 0,
2075 .futureModal = {
2076 0, 0, 0, 0, 0, 0, 0,
2079 .base_ext2 = {
2080 .tempSlopeLow = 72,
2081 .tempSlopeHigh = 105,
2082 .xatten1DBLow = {0x10, 0x14, 0x10},
2083 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2084 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2085 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2087 .calFreqPier5G = {
2088 FREQ2FBIN(5180, 0),
2089 FREQ2FBIN(5220, 0),
2090 FREQ2FBIN(5320, 0),
2091 FREQ2FBIN(5400, 0),
2092 FREQ2FBIN(5500, 0),
2093 FREQ2FBIN(5600, 0),
2094 FREQ2FBIN(5700, 0),
2095 FREQ2FBIN(5785, 0)
2097 .calPierData5G = {
2099 {0, 0, 0, 0, 0},
2100 {0, 0, 0, 0, 0},
2101 {0, 0, 0, 0, 0},
2102 {0, 0, 0, 0, 0},
2103 {0, 0, 0, 0, 0},
2104 {0, 0, 0, 0, 0},
2105 {0, 0, 0, 0, 0},
2106 {0, 0, 0, 0, 0},
2109 {0, 0, 0, 0, 0},
2110 {0, 0, 0, 0, 0},
2111 {0, 0, 0, 0, 0},
2112 {0, 0, 0, 0, 0},
2113 {0, 0, 0, 0, 0},
2114 {0, 0, 0, 0, 0},
2115 {0, 0, 0, 0, 0},
2116 {0, 0, 0, 0, 0},
2119 {0, 0, 0, 0, 0},
2120 {0, 0, 0, 0, 0},
2121 {0, 0, 0, 0, 0},
2122 {0, 0, 0, 0, 0},
2123 {0, 0, 0, 0, 0},
2124 {0, 0, 0, 0, 0},
2125 {0, 0, 0, 0, 0},
2126 {0, 0, 0, 0, 0},
2130 .calTarget_freqbin_5G = {
2131 FREQ2FBIN(5180, 0),
2132 FREQ2FBIN(5220, 0),
2133 FREQ2FBIN(5320, 0),
2134 FREQ2FBIN(5400, 0),
2135 FREQ2FBIN(5500, 0),
2136 FREQ2FBIN(5600, 0),
2137 FREQ2FBIN(5725, 0),
2138 FREQ2FBIN(5825, 0)
2140 .calTarget_freqbin_5GHT20 = {
2141 FREQ2FBIN(5180, 0),
2142 FREQ2FBIN(5220, 0),
2143 FREQ2FBIN(5320, 0),
2144 FREQ2FBIN(5400, 0),
2145 FREQ2FBIN(5500, 0),
2146 FREQ2FBIN(5600, 0),
2147 FREQ2FBIN(5725, 0),
2148 FREQ2FBIN(5825, 0)
2150 .calTarget_freqbin_5GHT40 = {
2151 FREQ2FBIN(5180, 0),
2152 FREQ2FBIN(5220, 0),
2153 FREQ2FBIN(5320, 0),
2154 FREQ2FBIN(5400, 0),
2155 FREQ2FBIN(5500, 0),
2156 FREQ2FBIN(5600, 0),
2157 FREQ2FBIN(5725, 0),
2158 FREQ2FBIN(5825, 0)
2160 .calTargetPower5G = {
2161 /* 6-24,36,48,54 */
2162 { {32, 32, 28, 26} },
2163 { {32, 32, 28, 26} },
2164 { {32, 32, 28, 26} },
2165 { {32, 32, 26, 24} },
2166 { {32, 32, 26, 24} },
2167 { {32, 32, 24, 22} },
2168 { {30, 30, 24, 22} },
2169 { {30, 30, 24, 22} },
2171 .calTargetPower5GHT20 = {
2173 * 0_8_16,1-3_9-11_17-19,
2174 * 4,5,6,7,12,13,14,15,20,21,22,23
2176 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2177 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2178 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2179 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2180 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2181 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2182 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2183 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2185 .calTargetPower5GHT40 = {
2187 * 0_8_16,1-3_9-11_17-19,
2188 * 4,5,6,7,12,13,14,15,20,21,22,23
2190 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2191 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2192 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2193 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2194 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2195 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2196 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2197 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2199 .ctlIndex_5G = {
2200 0x10, 0x16, 0x18, 0x40, 0x46,
2201 0x48, 0x30, 0x36, 0x38
2203 .ctl_freqbin_5G = {
2205 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2206 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2207 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2208 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2209 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2210 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2211 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2212 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2215 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2216 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2217 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2218 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2219 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2220 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2221 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2222 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2226 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2227 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2228 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2229 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2230 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2231 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2232 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2233 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2237 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2238 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2239 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2240 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2241 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2242 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2243 /* Data[3].ctledges[6].bchannel */ 0xFF,
2244 /* Data[3].ctledges[7].bchannel */ 0xFF,
2248 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2249 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2250 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2251 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2252 /* Data[4].ctledges[4].bchannel */ 0xFF,
2253 /* Data[4].ctledges[5].bchannel */ 0xFF,
2254 /* Data[4].ctledges[6].bchannel */ 0xFF,
2255 /* Data[4].ctledges[7].bchannel */ 0xFF,
2259 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2260 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2261 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2262 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2263 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2264 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2265 /* Data[5].ctledges[6].bchannel */ 0xFF,
2266 /* Data[5].ctledges[7].bchannel */ 0xFF
2270 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2271 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2272 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2273 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2274 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2275 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2276 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2277 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2281 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2282 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2283 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2284 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2285 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2286 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2287 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2288 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2292 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2293 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2294 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2295 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2296 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2297 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2298 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2299 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2302 .ctlPowerData_5G = {
2305 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2306 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2311 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2312 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2317 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2318 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2323 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2324 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2329 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2330 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2335 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2336 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2341 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2342 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2347 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2348 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2353 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2354 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2360 static const struct ar9300_eeprom ar9300_h116 = {
2361 .eepromVersion = 2,
2362 .templateVersion = 4,
2363 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2364 .custData = {"h116-041-f0000"},
2365 .baseEepHeader = {
2366 .regDmn = { LE16(0), LE16(0x1f) },
2367 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2368 .opCapFlags = {
2369 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2370 .eepMisc = 0,
2372 .rfSilent = 0,
2373 .blueToothOptions = 0,
2374 .deviceCap = 0,
2375 .deviceType = 5, /* takes lower byte in eeprom location */
2376 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2377 .params_for_tuning_caps = {0, 0},
2378 .featureEnable = 0x0d,
2380 * bit0 - enable tx temp comp - disabled
2381 * bit1 - enable tx volt comp - disabled
2382 * bit2 - enable fastClock - enabled
2383 * bit3 - enable doubling - enabled
2384 * bit4 - enable internal regulator - disabled
2385 * bit5 - enable pa predistortion - disabled
2387 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2388 .eepromWriteEnableGpio = 6,
2389 .wlanDisableGpio = 0,
2390 .wlanLedGpio = 8,
2391 .rxBandSelectGpio = 0xff,
2392 .txrxgain = 0x10,
2393 .swreg = 0,
2395 .modalHeader2G = {
2396 /* ar9300_modal_eep_header 2g */
2397 /* 4 idle,t1,t2,b(4 bits per setting) */
2398 .antCtrlCommon = LE32(0x110),
2399 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2400 .antCtrlCommon2 = LE32(0x44444),
2403 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2404 * rx1, rx12, b (2 bits each)
2406 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2409 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2410 * for ar9280 (0xa20c/b20c 5:0)
2412 .xatten1DB = {0x1f, 0x1f, 0x1f},
2415 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2416 * for ar9280 (0xa20c/b20c 16:12
2418 .xatten1Margin = {0x12, 0x12, 0x12},
2419 .tempSlope = 25,
2420 .voltSlope = 0,
2423 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2424 * channels in usual fbin coding format
2426 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2429 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2430 * if the register is per chain
2432 .noiseFloorThreshCh = {-1, 0, 0},
2433 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2434 .quick_drop = 0,
2435 .xpaBiasLvl = 0,
2436 .txFrameToDataStart = 0x0e,
2437 .txFrameToPaOn = 0x0e,
2438 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2439 .antennaGain = 0,
2440 .switchSettling = 0x2c,
2441 .adcDesiredSize = -30,
2442 .txEndToXpaOff = 0,
2443 .txEndToRxOn = 0x2,
2444 .txFrameToXpaOn = 0xe,
2445 .thresh62 = 28,
2446 .papdRateMaskHt20 = LE32(0x0c80C080),
2447 .papdRateMaskHt40 = LE32(0x0080C080),
2448 .switchcomspdt = 0,
2449 .xlna_bias_strength = 0,
2450 .futureModal = {
2451 0, 0, 0, 0, 0, 0, 0,
2454 .base_ext1 = {
2455 .ant_div_control = 0,
2456 .future = {0, 0},
2457 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
2459 .calFreqPier2G = {
2460 FREQ2FBIN(2412, 1),
2461 FREQ2FBIN(2437, 1),
2462 FREQ2FBIN(2462, 1),
2464 /* ar9300_cal_data_per_freq_op_loop 2g */
2465 .calPierData2G = {
2466 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2467 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2468 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2470 .calTarget_freqbin_Cck = {
2471 FREQ2FBIN(2412, 1),
2472 FREQ2FBIN(2472, 1),
2474 .calTarget_freqbin_2G = {
2475 FREQ2FBIN(2412, 1),
2476 FREQ2FBIN(2437, 1),
2477 FREQ2FBIN(2472, 1)
2479 .calTarget_freqbin_2GHT20 = {
2480 FREQ2FBIN(2412, 1),
2481 FREQ2FBIN(2437, 1),
2482 FREQ2FBIN(2472, 1)
2484 .calTarget_freqbin_2GHT40 = {
2485 FREQ2FBIN(2412, 1),
2486 FREQ2FBIN(2437, 1),
2487 FREQ2FBIN(2472, 1)
2489 .calTargetPowerCck = {
2490 /* 1L-5L,5S,11L,11S */
2491 { {34, 34, 34, 34} },
2492 { {34, 34, 34, 34} },
2494 .calTargetPower2G = {
2495 /* 6-24,36,48,54 */
2496 { {34, 34, 32, 32} },
2497 { {34, 34, 32, 32} },
2498 { {34, 34, 32, 32} },
2500 .calTargetPower2GHT20 = {
2501 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2502 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2503 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2505 .calTargetPower2GHT40 = {
2506 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2507 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2508 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2510 .ctlIndex_2G = {
2511 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2512 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2514 .ctl_freqbin_2G = {
2516 FREQ2FBIN(2412, 1),
2517 FREQ2FBIN(2417, 1),
2518 FREQ2FBIN(2457, 1),
2519 FREQ2FBIN(2462, 1)
2522 FREQ2FBIN(2412, 1),
2523 FREQ2FBIN(2417, 1),
2524 FREQ2FBIN(2462, 1),
2525 0xFF,
2529 FREQ2FBIN(2412, 1),
2530 FREQ2FBIN(2417, 1),
2531 FREQ2FBIN(2462, 1),
2532 0xFF,
2535 FREQ2FBIN(2422, 1),
2536 FREQ2FBIN(2427, 1),
2537 FREQ2FBIN(2447, 1),
2538 FREQ2FBIN(2452, 1)
2542 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2543 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2544 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2545 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2549 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2550 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2551 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2556 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2557 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2558 FREQ2FBIN(2472, 1),
2563 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2564 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2565 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2566 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2570 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2571 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2572 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2576 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2577 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2578 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2583 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2584 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2585 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2590 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2591 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2592 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2593 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2596 .ctlPowerData_2G = {
2597 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2598 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2599 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2601 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2602 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2603 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2605 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2606 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2607 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2609 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2610 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2611 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2613 .modalHeader5G = {
2614 /* 4 idle,t1,t2,b (4 bits per setting) */
2615 .antCtrlCommon = LE32(0x220),
2616 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2617 .antCtrlCommon2 = LE32(0x44444),
2618 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2619 .antCtrlChain = {
2620 LE16(0x150), LE16(0x150), LE16(0x150),
2622 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2623 .xatten1DB = {0x19, 0x19, 0x19},
2626 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2627 * for merlin (0xa20c/b20c 16:12
2629 .xatten1Margin = {0x14, 0x14, 0x14},
2630 .tempSlope = 70,
2631 .voltSlope = 0,
2632 /* spurChans spur channels in usual fbin coding format */
2633 .spurChans = {0, 0, 0, 0, 0},
2634 /* noiseFloorThreshCh Check if the register is per chain */
2635 .noiseFloorThreshCh = {-1, 0, 0},
2636 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2637 .quick_drop = 0,
2638 .xpaBiasLvl = 0,
2639 .txFrameToDataStart = 0x0e,
2640 .txFrameToPaOn = 0x0e,
2641 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2642 .antennaGain = 0,
2643 .switchSettling = 0x2d,
2644 .adcDesiredSize = -30,
2645 .txEndToXpaOff = 0,
2646 .txEndToRxOn = 0x2,
2647 .txFrameToXpaOn = 0xe,
2648 .thresh62 = 28,
2649 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2650 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2651 .switchcomspdt = 0,
2652 .xlna_bias_strength = 0,
2653 .futureModal = {
2654 0, 0, 0, 0, 0, 0, 0,
2657 .base_ext2 = {
2658 .tempSlopeLow = 35,
2659 .tempSlopeHigh = 50,
2660 .xatten1DBLow = {0, 0, 0},
2661 .xatten1MarginLow = {0, 0, 0},
2662 .xatten1DBHigh = {0, 0, 0},
2663 .xatten1MarginHigh = {0, 0, 0}
2665 .calFreqPier5G = {
2666 FREQ2FBIN(5160, 0),
2667 FREQ2FBIN(5220, 0),
2668 FREQ2FBIN(5320, 0),
2669 FREQ2FBIN(5400, 0),
2670 FREQ2FBIN(5500, 0),
2671 FREQ2FBIN(5600, 0),
2672 FREQ2FBIN(5700, 0),
2673 FREQ2FBIN(5785, 0)
2675 .calPierData5G = {
2677 {0, 0, 0, 0, 0},
2678 {0, 0, 0, 0, 0},
2679 {0, 0, 0, 0, 0},
2680 {0, 0, 0, 0, 0},
2681 {0, 0, 0, 0, 0},
2682 {0, 0, 0, 0, 0},
2683 {0, 0, 0, 0, 0},
2684 {0, 0, 0, 0, 0},
2687 {0, 0, 0, 0, 0},
2688 {0, 0, 0, 0, 0},
2689 {0, 0, 0, 0, 0},
2690 {0, 0, 0, 0, 0},
2691 {0, 0, 0, 0, 0},
2692 {0, 0, 0, 0, 0},
2693 {0, 0, 0, 0, 0},
2694 {0, 0, 0, 0, 0},
2697 {0, 0, 0, 0, 0},
2698 {0, 0, 0, 0, 0},
2699 {0, 0, 0, 0, 0},
2700 {0, 0, 0, 0, 0},
2701 {0, 0, 0, 0, 0},
2702 {0, 0, 0, 0, 0},
2703 {0, 0, 0, 0, 0},
2704 {0, 0, 0, 0, 0},
2708 .calTarget_freqbin_5G = {
2709 FREQ2FBIN(5180, 0),
2710 FREQ2FBIN(5240, 0),
2711 FREQ2FBIN(5320, 0),
2712 FREQ2FBIN(5400, 0),
2713 FREQ2FBIN(5500, 0),
2714 FREQ2FBIN(5600, 0),
2715 FREQ2FBIN(5700, 0),
2716 FREQ2FBIN(5825, 0)
2718 .calTarget_freqbin_5GHT20 = {
2719 FREQ2FBIN(5180, 0),
2720 FREQ2FBIN(5240, 0),
2721 FREQ2FBIN(5320, 0),
2722 FREQ2FBIN(5400, 0),
2723 FREQ2FBIN(5500, 0),
2724 FREQ2FBIN(5700, 0),
2725 FREQ2FBIN(5745, 0),
2726 FREQ2FBIN(5825, 0)
2728 .calTarget_freqbin_5GHT40 = {
2729 FREQ2FBIN(5180, 0),
2730 FREQ2FBIN(5240, 0),
2731 FREQ2FBIN(5320, 0),
2732 FREQ2FBIN(5400, 0),
2733 FREQ2FBIN(5500, 0),
2734 FREQ2FBIN(5700, 0),
2735 FREQ2FBIN(5745, 0),
2736 FREQ2FBIN(5825, 0)
2738 .calTargetPower5G = {
2739 /* 6-24,36,48,54 */
2740 { {30, 30, 28, 24} },
2741 { {30, 30, 28, 24} },
2742 { {30, 30, 28, 24} },
2743 { {30, 30, 28, 24} },
2744 { {30, 30, 28, 24} },
2745 { {30, 30, 28, 24} },
2746 { {30, 30, 28, 24} },
2747 { {30, 30, 28, 24} },
2749 .calTargetPower5GHT20 = {
2751 * 0_8_16,1-3_9-11_17-19,
2752 * 4,5,6,7,12,13,14,15,20,21,22,23
2754 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2755 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2756 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2757 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2758 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2759 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2760 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2761 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2763 .calTargetPower5GHT40 = {
2765 * 0_8_16,1-3_9-11_17-19,
2766 * 4,5,6,7,12,13,14,15,20,21,22,23
2768 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2769 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2770 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2771 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2772 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2773 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2774 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2775 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2777 .ctlIndex_5G = {
2778 0x10, 0x16, 0x18, 0x40, 0x46,
2779 0x48, 0x30, 0x36, 0x38
2781 .ctl_freqbin_5G = {
2783 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2784 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2785 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2786 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2787 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2788 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2789 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2790 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2793 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2794 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2795 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2796 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2797 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2798 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2799 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2800 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2804 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2805 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2806 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2807 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2808 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2809 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2810 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2811 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2815 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2816 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2817 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2818 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2819 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2820 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2821 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2822 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2826 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2827 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2828 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2829 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2830 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2831 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2832 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2833 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2837 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2838 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2839 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2840 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2841 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2842 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2843 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2844 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2848 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2849 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2850 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2851 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2852 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2853 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2854 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2855 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2859 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2860 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2861 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2862 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2863 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2864 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2865 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2866 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2870 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2871 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2872 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2873 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2874 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2875 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2876 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2877 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2880 .ctlPowerData_5G = {
2883 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2884 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2889 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2890 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2895 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2896 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2901 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2902 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2907 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2908 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2913 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2914 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2919 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2920 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2925 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2926 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2931 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2932 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2939 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2940 &ar9300_default,
2941 &ar9300_x112,
2942 &ar9300_h116,
2943 &ar9300_h112,
2944 &ar9300_x113,
2947 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2949 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2950 int it;
2952 for (it = 0; it < N_LOOP; it++)
2953 if (ar9300_eep_templates[it]->templateVersion == id)
2954 return ar9300_eep_templates[it];
2955 return NULL;
2956 #undef N_LOOP
2959 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2961 return 0;
2964 static int interpolate(int x, int xa, int xb, int ya, int yb)
2966 int bf, factor, plus;
2968 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2969 factor = bf / 2;
2970 plus = bf % 2;
2971 return ya + factor + plus;
2974 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2975 enum eeprom_param param)
2977 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2978 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
2980 switch (param) {
2981 case EEP_MAC_LSW:
2982 return get_unaligned_be16(eep->macAddr);
2983 case EEP_MAC_MID:
2984 return get_unaligned_be16(eep->macAddr + 2);
2985 case EEP_MAC_MSW:
2986 return get_unaligned_be16(eep->macAddr + 4);
2987 case EEP_REG_0:
2988 return le16_to_cpu(pBase->regDmn[0]);
2989 case EEP_OP_CAP:
2990 return pBase->deviceCap;
2991 case EEP_OP_MODE:
2992 return pBase->opCapFlags.opFlags;
2993 case EEP_RF_SILENT:
2994 return pBase->rfSilent;
2995 case EEP_TX_MASK:
2996 return (pBase->txrxMask >> 4) & 0xf;
2997 case EEP_RX_MASK:
2998 return pBase->txrxMask & 0xf;
2999 case EEP_PAPRD:
3000 return !!(pBase->featureEnable & BIT(5));
3001 case EEP_CHAIN_MASK_REDUCE:
3002 return (pBase->miscConfiguration >> 0x3) & 0x1;
3003 case EEP_ANT_DIV_CTL1:
3004 if (AR_SREV_9565(ah))
3005 return AR9300_EEP_ANTDIV_CONTROL_DEFAULT_VALUE;
3006 else
3007 return eep->base_ext1.ant_div_control;
3008 case EEP_ANTENNA_GAIN_5G:
3009 return eep->modalHeader5G.antennaGain;
3010 case EEP_ANTENNA_GAIN_2G:
3011 return eep->modalHeader2G.antennaGain;
3012 default:
3013 return 0;
3017 static bool ar9300_eeprom_read_byte(struct ath_hw *ah, int address,
3018 u8 *buffer)
3020 u16 val;
3022 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3023 return false;
3025 *buffer = (val >> (8 * (address % 2))) & 0xff;
3026 return true;
3029 static bool ar9300_eeprom_read_word(struct ath_hw *ah, int address,
3030 u8 *buffer)
3032 u16 val;
3034 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3035 return false;
3037 buffer[0] = val >> 8;
3038 buffer[1] = val & 0xff;
3040 return true;
3043 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3044 int count)
3046 struct ath_common *common = ath9k_hw_common(ah);
3047 int i;
3049 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3050 ath_dbg(common, EEPROM, "eeprom address not in range\n");
3051 return false;
3055 * Since we're reading the bytes in reverse order from a little-endian
3056 * word stream, an even address means we only use the lower half of
3057 * the 16-bit word at that address
3059 if (address % 2 == 0) {
3060 if (!ar9300_eeprom_read_byte(ah, address--, buffer++))
3061 goto error;
3063 count--;
3066 for (i = 0; i < count / 2; i++) {
3067 if (!ar9300_eeprom_read_word(ah, address, buffer))
3068 goto error;
3070 address -= 2;
3071 buffer += 2;
3074 if (count % 2)
3075 if (!ar9300_eeprom_read_byte(ah, address, buffer))
3076 goto error;
3078 return true;
3080 error:
3081 ath_dbg(common, EEPROM, "unable to read eeprom region at offset %d\n",
3082 address);
3083 return false;
3086 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3088 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3090 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3091 AR9300_OTP_STATUS_VALID, 1000))
3092 return false;
3094 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3095 return true;
3098 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3099 int count)
3101 u32 data;
3102 int i;
3104 for (i = 0; i < count; i++) {
3105 int offset = 8 * ((address - i) % 4);
3106 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3107 return false;
3109 buffer[i] = (data >> offset) & 0xff;
3112 return true;
3116 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3117 int *length, int *major, int *minor)
3119 unsigned long value[4];
3121 value[0] = best[0];
3122 value[1] = best[1];
3123 value[2] = best[2];
3124 value[3] = best[3];
3125 *code = ((value[0] >> 5) & 0x0007);
3126 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3127 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3128 *major = (value[2] & 0x000f);
3129 *minor = (value[3] & 0x00ff);
3132 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3134 int it, checksum = 0;
3136 for (it = 0; it < dsize; it++) {
3137 checksum += data[it];
3138 checksum &= 0xffff;
3141 return checksum;
3144 static bool ar9300_uncompress_block(struct ath_hw *ah,
3145 u8 *mptr,
3146 int mdataSize,
3147 u8 *block,
3148 int size)
3150 int it;
3151 int spot;
3152 int offset;
3153 int length;
3154 struct ath_common *common = ath9k_hw_common(ah);
3156 spot = 0;
3158 for (it = 0; it < size; it += (length+2)) {
3159 offset = block[it];
3160 offset &= 0xff;
3161 spot += offset;
3162 length = block[it+1];
3163 length &= 0xff;
3165 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3166 ath_dbg(common, EEPROM,
3167 "Restore at %d: spot=%d offset=%d length=%d\n",
3168 it, spot, offset, length);
3169 memcpy(&mptr[spot], &block[it+2], length);
3170 spot += length;
3171 } else if (length > 0) {
3172 ath_dbg(common, EEPROM,
3173 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3174 it, spot, offset, length);
3175 return false;
3178 return true;
3181 static int ar9300_compress_decision(struct ath_hw *ah,
3182 int it,
3183 int code,
3184 int reference,
3185 u8 *mptr,
3186 u8 *word, int length, int mdata_size)
3188 struct ath_common *common = ath9k_hw_common(ah);
3189 const struct ar9300_eeprom *eep = NULL;
3191 switch (code) {
3192 case _CompressNone:
3193 if (length != mdata_size) {
3194 ath_dbg(common, EEPROM,
3195 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3196 mdata_size, length);
3197 return -1;
3199 memcpy(mptr, word + COMP_HDR_LEN, length);
3200 ath_dbg(common, EEPROM,
3201 "restored eeprom %d: uncompressed, length %d\n",
3202 it, length);
3203 break;
3204 case _CompressBlock:
3205 if (reference == 0) {
3206 } else {
3207 eep = ar9003_eeprom_struct_find_by_id(reference);
3208 if (eep == NULL) {
3209 ath_dbg(common, EEPROM,
3210 "can't find reference eeprom struct %d\n",
3211 reference);
3212 return -1;
3214 memcpy(mptr, eep, mdata_size);
3216 ath_dbg(common, EEPROM,
3217 "restore eeprom %d: block, reference %d, length %d\n",
3218 it, reference, length);
3219 ar9300_uncompress_block(ah, mptr, mdata_size,
3220 (word + COMP_HDR_LEN), length);
3221 break;
3222 default:
3223 ath_dbg(common, EEPROM, "unknown compression code %d\n", code);
3224 return -1;
3226 return 0;
3229 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3230 int count);
3232 static bool ar9300_check_header(void *data)
3234 u32 *word = data;
3235 return !(*word == 0 || *word == ~0);
3238 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3239 int base_addr)
3241 u8 header[4];
3243 if (!read(ah, base_addr, header, 4))
3244 return false;
3246 return ar9300_check_header(header);
3249 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3250 int mdata_size)
3252 u16 *data = (u16 *) mptr;
3253 int i;
3255 for (i = 0; i < mdata_size / 2; i++, data++)
3256 ath9k_hw_nvram_read(ah, i, data);
3258 return 0;
3261 * Read the configuration data from the eeprom.
3262 * The data can be put in any specified memory buffer.
3264 * Returns -1 on error.
3265 * Returns address of next memory location on success.
3267 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3268 u8 *mptr, int mdata_size)
3270 #define MDEFAULT 15
3271 #define MSTATE 100
3272 int cptr;
3273 u8 *word;
3274 int code;
3275 int reference, length, major, minor;
3276 int osize;
3277 int it;
3278 u16 checksum, mchecksum;
3279 struct ath_common *common = ath9k_hw_common(ah);
3280 struct ar9300_eeprom *eep;
3281 eeprom_read_op read;
3283 if (ath9k_hw_use_flash(ah)) {
3284 u8 txrx;
3286 ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3288 /* check if eeprom contains valid data */
3289 eep = (struct ar9300_eeprom *) mptr;
3290 txrx = eep->baseEepHeader.txrxMask;
3291 if (txrx != 0 && txrx != 0xff)
3292 return 0;
3295 word = kzalloc(2048, GFP_KERNEL);
3296 if (!word)
3297 return -ENOMEM;
3299 memcpy(mptr, &ar9300_default, mdata_size);
3301 read = ar9300_read_eeprom;
3302 if (AR_SREV_9485(ah))
3303 cptr = AR9300_BASE_ADDR_4K;
3304 else if (AR_SREV_9330(ah))
3305 cptr = AR9300_BASE_ADDR_512;
3306 else
3307 cptr = AR9300_BASE_ADDR;
3308 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3309 cptr);
3310 if (ar9300_check_eeprom_header(ah, read, cptr))
3311 goto found;
3313 cptr = AR9300_BASE_ADDR_512;
3314 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3315 cptr);
3316 if (ar9300_check_eeprom_header(ah, read, cptr))
3317 goto found;
3319 read = ar9300_read_otp;
3320 cptr = AR9300_BASE_ADDR;
3321 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3322 if (ar9300_check_eeprom_header(ah, read, cptr))
3323 goto found;
3325 cptr = AR9300_BASE_ADDR_512;
3326 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3327 if (ar9300_check_eeprom_header(ah, read, cptr))
3328 goto found;
3330 goto fail;
3332 found:
3333 ath_dbg(common, EEPROM, "Found valid EEPROM data\n");
3335 for (it = 0; it < MSTATE; it++) {
3336 if (!read(ah, cptr, word, COMP_HDR_LEN))
3337 goto fail;
3339 if (!ar9300_check_header(word))
3340 break;
3342 ar9300_comp_hdr_unpack(word, &code, &reference,
3343 &length, &major, &minor);
3344 ath_dbg(common, EEPROM,
3345 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3346 cptr, code, reference, length, major, minor);
3347 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3348 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3349 ath_dbg(common, EEPROM, "Skipping bad header\n");
3350 cptr -= COMP_HDR_LEN;
3351 continue;
3354 osize = length;
3355 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3356 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3357 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3358 ath_dbg(common, EEPROM, "checksum %x %x\n",
3359 checksum, mchecksum);
3360 if (checksum == mchecksum) {
3361 ar9300_compress_decision(ah, it, code, reference, mptr,
3362 word, length, mdata_size);
3363 } else {
3364 ath_dbg(common, EEPROM,
3365 "skipping block with bad checksum\n");
3367 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3370 kfree(word);
3371 return cptr;
3373 fail:
3374 kfree(word);
3375 return -1;
3379 * Restore the configuration structure by reading the eeprom.
3380 * This function destroys any existing in-memory structure
3381 * content.
3383 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3385 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3387 if (ar9300_eeprom_restore_internal(ah, mptr,
3388 sizeof(struct ar9300_eeprom)) < 0)
3389 return false;
3391 return true;
3394 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3395 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3396 struct ar9300_modal_eep_header *modal_hdr)
3398 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3399 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3400 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3401 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3402 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3403 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3404 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3405 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3406 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3407 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3408 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3409 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3410 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3411 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3412 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3413 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3414 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3415 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3416 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3417 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3418 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3419 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3420 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3421 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3422 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3423 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3424 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3425 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3426 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3427 PR_EEP("txClip", modal_hdr->txClip);
3428 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3430 return len;
3433 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3434 u8 *buf, u32 len, u32 size)
3436 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3437 struct ar9300_base_eep_hdr *pBase;
3439 if (!dump_base_hdr) {
3440 len += scnprintf(buf + len, size - len,
3441 "%20s :\n", "2GHz modal Header");
3442 len = ar9003_dump_modal_eeprom(buf, len, size,
3443 &eep->modalHeader2G);
3444 len += scnprintf(buf + len, size - len,
3445 "%20s :\n", "5GHz modal Header");
3446 len = ar9003_dump_modal_eeprom(buf, len, size,
3447 &eep->modalHeader5G);
3448 goto out;
3451 pBase = &eep->baseEepHeader;
3453 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3454 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3455 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3456 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3457 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3458 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3459 AR5416_OPFLAGS_11A));
3460 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3461 AR5416_OPFLAGS_11G));
3462 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3463 AR5416_OPFLAGS_N_2G_HT20));
3464 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3465 AR5416_OPFLAGS_N_2G_HT40));
3466 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3467 AR5416_OPFLAGS_N_5G_HT20));
3468 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3469 AR5416_OPFLAGS_N_5G_HT40));
3470 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3471 PR_EEP("RF Silent", pBase->rfSilent);
3472 PR_EEP("BT option", pBase->blueToothOptions);
3473 PR_EEP("Device Cap", pBase->deviceCap);
3474 PR_EEP("Device Type", pBase->deviceType);
3475 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3476 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3477 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3478 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3479 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3480 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3481 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3482 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3483 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3484 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3485 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3486 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3487 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3488 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3489 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3490 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3491 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3492 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3493 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3495 len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3496 ah->eeprom.ar9300_eep.macAddr);
3497 out:
3498 if (len > size)
3499 len = size;
3501 return len;
3503 #else
3504 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3505 u8 *buf, u32 len, u32 size)
3507 return 0;
3509 #endif
3511 /* XXX: review hardware docs */
3512 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3514 return ah->eeprom.ar9300_eep.eepromVersion;
3517 /* XXX: could be read from the eepromVersion, not sure yet */
3518 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3520 return 0;
3523 static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
3524 bool is2ghz)
3526 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3528 if (is2ghz)
3529 return &eep->modalHeader2G;
3530 else
3531 return &eep->modalHeader5G;
3534 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3536 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3538 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
3539 AR_SREV_9531(ah) || AR_SREV_9561(ah))
3540 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3541 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
3542 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3543 else {
3544 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3545 REG_RMW_FIELD(ah, AR_CH0_THERM,
3546 AR_CH0_THERM_XPABIASLVL_MSB,
3547 bias >> 2);
3548 REG_RMW_FIELD(ah, AR_CH0_THERM,
3549 AR_CH0_THERM_XPASHORT2GND, 1);
3553 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3555 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3558 u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3560 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3563 u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3565 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3568 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3569 bool is2ghz)
3571 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3572 return le16_to_cpu(val);
3575 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3577 struct ath_common *common = ath9k_hw_common(ah);
3578 struct ath9k_hw_capabilities *pCap = &ah->caps;
3579 int chain;
3580 u32 regval, value, gpio;
3581 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3582 AR_PHY_SWITCH_CHAIN_0,
3583 AR_PHY_SWITCH_CHAIN_1,
3584 AR_PHY_SWITCH_CHAIN_2,
3587 if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0)) {
3588 if (ah->config.xlna_gpio)
3589 gpio = ah->config.xlna_gpio;
3590 else
3591 gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
3593 ath9k_hw_cfg_output(ah, gpio,
3594 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
3597 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3599 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3600 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3601 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3602 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
3603 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3604 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3605 } else
3606 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3607 AR_SWITCH_TABLE_COM_ALL, value);
3611 * AR9462 defines new switch table for BT/WLAN,
3612 * here's new field name in XXX.ref for both 2G and 5G.
3613 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3614 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3615 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3617 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3618 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3620 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3621 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3623 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
3624 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3625 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3626 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3627 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3630 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3631 if (AR_SREV_9485(ah) && common->bt_ant_diversity) {
3632 value &= ~AR_SWITCH_TABLE_COM2_ALL;
3633 value |= ah->config.ant_ctrl_comm2g_switch_enable;
3636 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3638 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3639 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3640 REG_RMW_FIELD(ah, switch_chain_reg[0],
3641 AR_SWITCH_TABLE_ALL, value);
3644 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3645 if ((ah->rxchainmask & BIT(chain)) ||
3646 (ah->txchainmask & BIT(chain))) {
3647 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3648 is2ghz);
3649 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3650 AR_SWITCH_TABLE_ALL, value);
3654 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
3655 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3657 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3658 * are the fields present
3660 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3661 regval &= (~AR_ANT_DIV_CTRL_ALL);
3662 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3663 /* enable_lnadiv */
3664 regval &= (~AR_PHY_ANT_DIV_LNADIV);
3665 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
3667 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3668 regval |= AR_ANT_DIV_ENABLE;
3670 if (AR_SREV_9565(ah)) {
3671 if (common->bt_ant_diversity) {
3672 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S);
3674 REG_SET_BIT(ah, AR_PHY_RESTART,
3675 AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
3677 /* Force WLAN LNA diversity ON */
3678 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
3679 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3680 } else {
3681 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S);
3682 regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S);
3684 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL,
3685 (1 << AR_PHY_ANT_SW_RX_PROT_S));
3687 /* Force WLAN LNA diversity OFF */
3688 REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV,
3689 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3693 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3695 /* enable fast_div */
3696 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3697 regval &= (~AR_FAST_DIV_ENABLE);
3698 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
3700 if ((AR_SREV_9485(ah) || AR_SREV_9565(ah))
3701 && common->bt_ant_diversity)
3702 regval |= AR_FAST_DIV_ENABLE;
3704 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3706 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
3707 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3709 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3710 * main_tb, alt_tb
3712 regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
3713 AR_PHY_ANT_DIV_ALT_LNACONF |
3714 AR_PHY_ANT_DIV_ALT_GAINTB |
3715 AR_PHY_ANT_DIV_MAIN_GAINTB));
3716 /* by default use LNA1 for the main antenna */
3717 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
3718 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
3719 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
3720 AR_PHY_ANT_DIV_ALT_LNACONF_S);
3721 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3726 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3728 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3729 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3730 int drive_strength;
3731 unsigned long reg;
3733 drive_strength = pBase->miscConfiguration & BIT(0);
3734 if (!drive_strength)
3735 return;
3737 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3738 reg &= ~0x00ffffc0;
3739 reg |= 0x5 << 21;
3740 reg |= 0x5 << 18;
3741 reg |= 0x5 << 15;
3742 reg |= 0x5 << 12;
3743 reg |= 0x5 << 9;
3744 reg |= 0x5 << 6;
3745 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3747 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3748 reg &= ~0xffffffe0;
3749 reg |= 0x5 << 29;
3750 reg |= 0x5 << 26;
3751 reg |= 0x5 << 23;
3752 reg |= 0x5 << 20;
3753 reg |= 0x5 << 17;
3754 reg |= 0x5 << 14;
3755 reg |= 0x5 << 11;
3756 reg |= 0x5 << 8;
3757 reg |= 0x5 << 5;
3758 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3760 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3761 reg &= ~0xff800000;
3762 reg |= 0x5 << 29;
3763 reg |= 0x5 << 26;
3764 reg |= 0x5 << 23;
3765 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3768 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3769 struct ath9k_channel *chan)
3771 int f[3], t[3];
3772 u16 value;
3773 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3775 if (chain >= 0 && chain < 3) {
3776 if (IS_CHAN_2GHZ(chan))
3777 return eep->modalHeader2G.xatten1DB[chain];
3778 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3779 t[0] = eep->base_ext2.xatten1DBLow[chain];
3780 f[0] = 5180;
3781 t[1] = eep->modalHeader5G.xatten1DB[chain];
3782 f[1] = 5500;
3783 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3784 f[2] = 5785;
3785 value = ar9003_hw_power_interpolate((s32) chan->channel,
3786 f, t, 3);
3787 return value;
3788 } else
3789 return eep->modalHeader5G.xatten1DB[chain];
3792 return 0;
3796 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3797 struct ath9k_channel *chan)
3799 int f[3], t[3];
3800 u16 value;
3801 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3803 if (chain >= 0 && chain < 3) {
3804 if (IS_CHAN_2GHZ(chan))
3805 return eep->modalHeader2G.xatten1Margin[chain];
3806 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3807 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3808 f[0] = 5180;
3809 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3810 f[1] = 5500;
3811 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3812 f[2] = 5785;
3813 value = ar9003_hw_power_interpolate((s32) chan->channel,
3814 f, t, 3);
3815 return value;
3816 } else
3817 return eep->modalHeader5G.xatten1Margin[chain];
3820 return 0;
3823 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3825 int i;
3826 u16 value;
3827 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3828 AR_PHY_EXT_ATTEN_CTL_1,
3829 AR_PHY_EXT_ATTEN_CTL_2,
3832 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3833 value = ar9003_hw_atten_chain_get(ah, 1, chan);
3834 REG_RMW_FIELD(ah, ext_atten_reg[0],
3835 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3837 value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
3838 REG_RMW_FIELD(ah, ext_atten_reg[0],
3839 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3840 value);
3843 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3844 for (i = 0; i < 3; i++) {
3845 if (ah->txchainmask & BIT(i)) {
3846 value = ar9003_hw_atten_chain_get(ah, i, chan);
3847 REG_RMW_FIELD(ah, ext_atten_reg[i],
3848 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3850 if (AR_SREV_9485(ah) &&
3851 (ar9003_hw_get_rx_gain_idx(ah) == 0) &&
3852 ah->config.xatten_margin_cfg)
3853 value = 5;
3854 else
3855 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3857 if (ah->config.alt_mingainidx)
3858 REG_RMW_FIELD(ah, AR_PHY_EXT_ATTEN_CTL_0,
3859 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3860 value);
3862 REG_RMW_FIELD(ah, ext_atten_reg[i],
3863 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3864 value);
3869 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3871 int timeout = 100;
3873 while (pmu_set != REG_READ(ah, pmu_reg)) {
3874 if (timeout-- == 0)
3875 return false;
3876 REG_WRITE(ah, pmu_reg, pmu_set);
3877 udelay(10);
3880 return true;
3883 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3885 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3886 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3887 u32 reg_val;
3889 if (pBase->featureEnable & BIT(4)) {
3890 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3891 int reg_pmu_set;
3893 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3894 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3895 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3896 return;
3898 if (AR_SREV_9330(ah)) {
3899 if (ah->is_clk_25mhz) {
3900 reg_pmu_set = (3 << 1) | (8 << 4) |
3901 (3 << 8) | (1 << 14) |
3902 (6 << 17) | (1 << 20) |
3903 (3 << 24);
3904 } else {
3905 reg_pmu_set = (4 << 1) | (7 << 4) |
3906 (3 << 8) | (1 << 14) |
3907 (6 << 17) | (1 << 20) |
3908 (3 << 24);
3910 } else {
3911 reg_pmu_set = (5 << 1) | (7 << 4) |
3912 (2 << 8) | (2 << 14) |
3913 (6 << 17) | (1 << 20) |
3914 (3 << 24) | (1 << 28);
3917 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3918 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3919 return;
3921 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3922 | (4 << 26);
3923 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3924 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3925 return;
3927 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3928 | (1 << 21);
3929 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3930 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3931 return;
3932 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah) ||
3933 AR_SREV_9561(ah)) {
3934 reg_val = le32_to_cpu(pBase->swreg);
3935 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3937 if (AR_SREV_9561(ah))
3938 REG_WRITE(ah, AR_PHY_PMU2, 0x10200000);
3939 } else {
3940 /* Internal regulator is ON. Write swreg register. */
3941 reg_val = le32_to_cpu(pBase->swreg);
3942 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3943 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3944 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3945 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3946 /* Set REG_CONTROL1.SWREG_PROGRAM */
3947 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3948 REG_READ(ah,
3949 AR_RTC_REG_CONTROL1) |
3950 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3952 } else {
3953 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3954 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3955 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3956 AR_PHY_PMU2_PGM))
3957 udelay(10);
3959 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3960 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3961 AR_PHY_PMU1_PWD))
3962 udelay(10);
3963 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3964 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3965 AR_PHY_PMU2_PGM))
3966 udelay(10);
3967 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
3968 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3969 else {
3970 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3971 AR_RTC_FORCE_SWREG_PRD;
3972 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3978 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3980 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3981 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3983 if (AR_SREV_9340(ah) || AR_SREV_9531(ah))
3984 return;
3986 if (eep->baseEepHeader.featureEnable & 0x40) {
3987 tuning_caps_param &= 0x7f;
3988 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3989 tuning_caps_param);
3990 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3991 tuning_caps_param);
3995 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3997 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3998 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3999 int quick_drop;
4000 s32 t[3], f[3] = {5180, 5500, 5785};
4002 if (!(pBase->miscConfiguration & BIT(4)))
4003 return;
4005 if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) {
4006 if (freq < 4000) {
4007 quick_drop = eep->modalHeader2G.quick_drop;
4008 } else {
4009 t[0] = eep->base_ext1.quick_drop_low;
4010 t[1] = eep->modalHeader5G.quick_drop;
4011 t[2] = eep->base_ext1.quick_drop_high;
4012 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
4014 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
4018 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
4020 u32 value;
4022 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
4024 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4025 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
4026 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4027 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
4030 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
4032 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4033 u8 xpa_ctl;
4035 if (!(eep->baseEepHeader.featureEnable & 0x80))
4036 return;
4038 if (!AR_SREV_9300(ah) &&
4039 !AR_SREV_9340(ah) &&
4040 !AR_SREV_9580(ah) &&
4041 !AR_SREV_9531(ah) &&
4042 !AR_SREV_9561(ah))
4043 return;
4045 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
4046 if (is2ghz)
4047 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4048 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
4049 else
4050 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4051 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
4054 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
4056 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4057 u8 bias;
4059 if (!(eep->baseEepHeader.miscConfiguration & 0x40))
4060 return;
4062 if (!AR_SREV_9300(ah))
4063 return;
4065 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
4066 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4067 bias & 0x3);
4068 bias >>= 2;
4069 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4070 bias & 0x3);
4071 bias >>= 2;
4072 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4073 bias & 0x3);
4076 static int ar9003_hw_get_thermometer(struct ath_hw *ah)
4078 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4079 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4080 int thermometer = (pBase->miscConfiguration >> 1) & 0x3;
4082 return --thermometer;
4085 static void ar9003_hw_thermometer_apply(struct ath_hw *ah)
4087 struct ath9k_hw_capabilities *pCap = &ah->caps;
4088 int thermometer = ar9003_hw_get_thermometer(ah);
4089 u8 therm_on = (thermometer < 0) ? 0 : 1;
4091 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4092 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4093 if (pCap->chip_chainmask & BIT(1))
4094 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4095 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4096 if (pCap->chip_chainmask & BIT(2))
4097 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4098 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4100 therm_on = (thermometer < 0) ? 0 : (thermometer == 0);
4101 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4102 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4103 if (pCap->chip_chainmask & BIT(1)) {
4104 therm_on = (thermometer < 0) ? 0 : (thermometer == 1);
4105 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4106 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4108 if (pCap->chip_chainmask & BIT(2)) {
4109 therm_on = (thermometer < 0) ? 0 : (thermometer == 2);
4110 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4111 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4115 static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4117 u32 data, ko, kg;
4119 if (!AR_SREV_9462_20_OR_LATER(ah))
4120 return;
4122 ar9300_otp_read_word(ah, 1, &data);
4123 ko = data & 0xff;
4124 kg = (data >> 8) & 0xff;
4125 if (ko || kg) {
4126 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4127 AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko);
4128 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4129 AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN,
4130 kg + 256);
4134 static void ar9003_hw_apply_minccapwr_thresh(struct ath_hw *ah,
4135 bool is2ghz)
4137 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4138 const u_int32_t cca_ctrl[AR9300_MAX_CHAINS] = {
4139 AR_PHY_CCA_CTRL_0,
4140 AR_PHY_CCA_CTRL_1,
4141 AR_PHY_CCA_CTRL_2,
4143 int chain;
4144 u32 val;
4146 if (is2ghz) {
4147 if (!(eep->base_ext1.misc_enable & BIT(2)))
4148 return;
4149 } else {
4150 if (!(eep->base_ext1.misc_enable & BIT(3)))
4151 return;
4154 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
4155 if (!(ah->caps.tx_chainmask & BIT(chain)))
4156 continue;
4158 val = ar9003_modal_header(ah, is2ghz)->noiseFloorThreshCh[chain];
4159 REG_RMW_FIELD(ah, cca_ctrl[chain],
4160 AR_PHY_EXT_CCA0_THRESH62_1, val);
4165 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4166 struct ath9k_channel *chan)
4168 bool is2ghz = IS_CHAN_2GHZ(chan);
4169 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
4170 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
4171 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
4172 ar9003_hw_drive_strength_apply(ah);
4173 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
4174 ar9003_hw_atten_apply(ah, chan);
4175 ar9003_hw_quick_drop_apply(ah, chan->channel);
4176 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah))
4177 ar9003_hw_internal_regulator_apply(ah);
4178 ar9003_hw_apply_tuning_caps(ah);
4179 ar9003_hw_apply_minccapwr_thresh(ah, chan);
4180 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4181 ar9003_hw_thermometer_apply(ah);
4182 ar9003_hw_thermo_cal_apply(ah);
4185 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
4186 struct ath9k_channel *chan)
4191 * Returns the interpolated y value corresponding to the specified x value
4192 * from the np ordered pairs of data (px,py).
4193 * The pairs do not have to be in any order.
4194 * If the specified x value is less than any of the px,
4195 * the returned y value is equal to the py for the lowest px.
4196 * If the specified x value is greater than any of the px,
4197 * the returned y value is equal to the py for the highest px.
4199 static int ar9003_hw_power_interpolate(int32_t x,
4200 int32_t *px, int32_t *py, u_int16_t np)
4202 int ip = 0;
4203 int lx = 0, ly = 0, lhave = 0;
4204 int hx = 0, hy = 0, hhave = 0;
4205 int dx = 0;
4206 int y = 0;
4208 lhave = 0;
4209 hhave = 0;
4211 /* identify best lower and higher x calibration measurement */
4212 for (ip = 0; ip < np; ip++) {
4213 dx = x - px[ip];
4215 /* this measurement is higher than our desired x */
4216 if (dx <= 0) {
4217 if (!hhave || dx > (x - hx)) {
4218 /* new best higher x measurement */
4219 hx = px[ip];
4220 hy = py[ip];
4221 hhave = 1;
4224 /* this measurement is lower than our desired x */
4225 if (dx >= 0) {
4226 if (!lhave || dx < (x - lx)) {
4227 /* new best lower x measurement */
4228 lx = px[ip];
4229 ly = py[ip];
4230 lhave = 1;
4235 /* the low x is good */
4236 if (lhave) {
4237 /* so is the high x */
4238 if (hhave) {
4239 /* they're the same, so just pick one */
4240 if (hx == lx)
4241 y = ly;
4242 else /* interpolate */
4243 y = interpolate(x, lx, hx, ly, hy);
4244 } else /* only low is good, use it */
4245 y = ly;
4246 } else if (hhave) /* only high is good, use it */
4247 y = hy;
4248 else /* nothing is good,this should never happen unless np=0, ???? */
4249 y = -(1 << 30);
4250 return y;
4253 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4254 u16 rateIndex, u16 freq, bool is2GHz)
4256 u16 numPiers, i;
4257 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4258 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4259 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4260 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4261 u8 *pFreqBin;
4263 if (is2GHz) {
4264 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4265 pEepromTargetPwr = eep->calTargetPower2G;
4266 pFreqBin = eep->calTarget_freqbin_2G;
4267 } else {
4268 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4269 pEepromTargetPwr = eep->calTargetPower5G;
4270 pFreqBin = eep->calTarget_freqbin_5G;
4274 * create array of channels and targetpower from
4275 * targetpower piers stored on eeprom
4277 for (i = 0; i < numPiers; i++) {
4278 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4279 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4282 /* interpolate to get target power for given frequency */
4283 return (u8) ar9003_hw_power_interpolate((s32) freq,
4284 freqArray,
4285 targetPowerArray, numPiers);
4288 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4289 u16 rateIndex,
4290 u16 freq, bool is2GHz)
4292 u16 numPiers, i;
4293 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4294 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4295 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4296 struct cal_tgt_pow_ht *pEepromTargetPwr;
4297 u8 *pFreqBin;
4299 if (is2GHz) {
4300 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4301 pEepromTargetPwr = eep->calTargetPower2GHT20;
4302 pFreqBin = eep->calTarget_freqbin_2GHT20;
4303 } else {
4304 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4305 pEepromTargetPwr = eep->calTargetPower5GHT20;
4306 pFreqBin = eep->calTarget_freqbin_5GHT20;
4310 * create array of channels and targetpower
4311 * from targetpower piers stored on eeprom
4313 for (i = 0; i < numPiers; i++) {
4314 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4315 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4318 /* interpolate to get target power for given frequency */
4319 return (u8) ar9003_hw_power_interpolate((s32) freq,
4320 freqArray,
4321 targetPowerArray, numPiers);
4324 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4325 u16 rateIndex,
4326 u16 freq, bool is2GHz)
4328 u16 numPiers, i;
4329 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4330 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4331 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4332 struct cal_tgt_pow_ht *pEepromTargetPwr;
4333 u8 *pFreqBin;
4335 if (is2GHz) {
4336 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4337 pEepromTargetPwr = eep->calTargetPower2GHT40;
4338 pFreqBin = eep->calTarget_freqbin_2GHT40;
4339 } else {
4340 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4341 pEepromTargetPwr = eep->calTargetPower5GHT40;
4342 pFreqBin = eep->calTarget_freqbin_5GHT40;
4346 * create array of channels and targetpower from
4347 * targetpower piers stored on eeprom
4349 for (i = 0; i < numPiers; i++) {
4350 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4351 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4354 /* interpolate to get target power for given frequency */
4355 return (u8) ar9003_hw_power_interpolate((s32) freq,
4356 freqArray,
4357 targetPowerArray, numPiers);
4360 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4361 u16 rateIndex, u16 freq)
4363 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4364 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4365 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4366 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4367 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4368 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4371 * create array of channels and targetpower from
4372 * targetpower piers stored on eeprom
4374 for (i = 0; i < numPiers; i++) {
4375 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4376 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4379 /* interpolate to get target power for given frequency */
4380 return (u8) ar9003_hw_power_interpolate((s32) freq,
4381 freqArray,
4382 targetPowerArray, numPiers);
4385 static void ar9003_hw_selfgen_tpc_txpower(struct ath_hw *ah,
4386 struct ath9k_channel *chan,
4387 u8 *pwr_array)
4389 u32 val;
4391 /* target power values for self generated frames (ACK,RTS/CTS) */
4392 if (IS_CHAN_2GHZ(chan)) {
4393 val = SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_ACK) |
4394 SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_CTS) |
4395 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4396 } else {
4397 val = SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_ACK) |
4398 SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_CTS) |
4399 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4401 REG_WRITE(ah, AR_TPC, val);
4404 /* Set tx power registers to array of values passed in */
4405 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4407 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4408 /* make sure forced gain is not set */
4409 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4411 /* Write the OFDM power per rate set */
4413 /* 6 (LSB), 9, 12, 18 (MSB) */
4414 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4415 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4416 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4417 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4418 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4420 /* 24 (LSB), 36, 48, 54 (MSB) */
4421 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4422 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4423 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4424 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4425 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4427 /* Write the CCK power per rate set */
4429 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4430 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4431 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4432 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4433 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4434 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4436 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4437 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4438 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4439 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4440 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4441 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4444 /* Write the power for duplicated frames - HT40 */
4446 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4447 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4448 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4449 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4450 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4451 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4454 /* Write the HT20 power per rate set */
4456 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4457 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4458 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4459 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4460 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4461 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4464 /* 6 (LSB), 7, 12, 13 (MSB) */
4465 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4466 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4467 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4468 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4469 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4472 /* 14 (LSB), 15, 20, 21 */
4473 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4474 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4475 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4476 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4477 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4480 /* Mixed HT20 and HT40 rates */
4482 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4483 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4484 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4485 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4486 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4487 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4491 * Write the HT40 power per rate set
4492 * correct PAR difference between HT40 and HT20/LEGACY
4493 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4495 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4496 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4497 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4498 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4499 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4502 /* 6 (LSB), 7, 12, 13 (MSB) */
4503 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4504 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4505 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4506 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4507 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4510 /* 14 (LSB), 15, 20, 21 */
4511 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4512 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4513 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4514 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4515 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4518 return 0;
4519 #undef POW_SM
4522 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4523 u8 *targetPowerValT2,
4524 bool is2GHz)
4526 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4527 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4528 is2GHz);
4529 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4530 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4531 is2GHz);
4532 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4533 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4534 is2GHz);
4535 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4536 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4537 is2GHz);
4540 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4541 u8 *targetPowerValT2)
4543 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4544 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4545 freq);
4546 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4547 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4548 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4549 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4550 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4551 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4554 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4555 u8 *targetPowerValT2, bool is2GHz)
4557 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4558 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4559 is2GHz);
4560 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4561 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4562 freq, is2GHz);
4563 targetPowerValT2[ALL_TARGET_HT20_4] =
4564 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4565 is2GHz);
4566 targetPowerValT2[ALL_TARGET_HT20_5] =
4567 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4568 is2GHz);
4569 targetPowerValT2[ALL_TARGET_HT20_6] =
4570 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4571 is2GHz);
4572 targetPowerValT2[ALL_TARGET_HT20_7] =
4573 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4574 is2GHz);
4575 targetPowerValT2[ALL_TARGET_HT20_12] =
4576 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4577 is2GHz);
4578 targetPowerValT2[ALL_TARGET_HT20_13] =
4579 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4580 is2GHz);
4581 targetPowerValT2[ALL_TARGET_HT20_14] =
4582 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4583 is2GHz);
4584 targetPowerValT2[ALL_TARGET_HT20_15] =
4585 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4586 is2GHz);
4587 targetPowerValT2[ALL_TARGET_HT20_20] =
4588 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4589 is2GHz);
4590 targetPowerValT2[ALL_TARGET_HT20_21] =
4591 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4592 is2GHz);
4593 targetPowerValT2[ALL_TARGET_HT20_22] =
4594 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4595 is2GHz);
4596 targetPowerValT2[ALL_TARGET_HT20_23] =
4597 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4598 is2GHz);
4601 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4602 u16 freq,
4603 u8 *targetPowerValT2,
4604 bool is2GHz)
4606 /* XXX: hard code for now, need to get from eeprom struct */
4607 u8 ht40PowerIncForPdadc = 0;
4609 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4610 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4611 is2GHz) + ht40PowerIncForPdadc;
4612 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4613 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4614 freq,
4615 is2GHz) + ht40PowerIncForPdadc;
4616 targetPowerValT2[ALL_TARGET_HT40_4] =
4617 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4618 is2GHz) + ht40PowerIncForPdadc;
4619 targetPowerValT2[ALL_TARGET_HT40_5] =
4620 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4621 is2GHz) + ht40PowerIncForPdadc;
4622 targetPowerValT2[ALL_TARGET_HT40_6] =
4623 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4624 is2GHz) + ht40PowerIncForPdadc;
4625 targetPowerValT2[ALL_TARGET_HT40_7] =
4626 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4627 is2GHz) + ht40PowerIncForPdadc;
4628 targetPowerValT2[ALL_TARGET_HT40_12] =
4629 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4630 is2GHz) + ht40PowerIncForPdadc;
4631 targetPowerValT2[ALL_TARGET_HT40_13] =
4632 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4633 is2GHz) + ht40PowerIncForPdadc;
4634 targetPowerValT2[ALL_TARGET_HT40_14] =
4635 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4636 is2GHz) + ht40PowerIncForPdadc;
4637 targetPowerValT2[ALL_TARGET_HT40_15] =
4638 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4639 is2GHz) + ht40PowerIncForPdadc;
4640 targetPowerValT2[ALL_TARGET_HT40_20] =
4641 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4642 is2GHz) + ht40PowerIncForPdadc;
4643 targetPowerValT2[ALL_TARGET_HT40_21] =
4644 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4645 is2GHz) + ht40PowerIncForPdadc;
4646 targetPowerValT2[ALL_TARGET_HT40_22] =
4647 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4648 is2GHz) + ht40PowerIncForPdadc;
4649 targetPowerValT2[ALL_TARGET_HT40_23] =
4650 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4651 is2GHz) + ht40PowerIncForPdadc;
4654 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4655 struct ath9k_channel *chan,
4656 u8 *targetPowerValT2)
4658 bool is2GHz = IS_CHAN_2GHZ(chan);
4659 unsigned int i = 0;
4660 struct ath_common *common = ath9k_hw_common(ah);
4661 u16 freq = chan->channel;
4663 if (is2GHz)
4664 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4666 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4667 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4669 if (IS_CHAN_HT40(chan))
4670 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4671 is2GHz);
4673 for (i = 0; i < ar9300RateSize; i++) {
4674 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
4675 i, targetPowerValT2[i]);
4679 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4680 int mode,
4681 int ipier,
4682 int ichain,
4683 int *pfrequency,
4684 int *pcorrection,
4685 int *ptemperature, int *pvoltage)
4687 u8 *pCalPier;
4688 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4689 int is2GHz;
4690 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4691 struct ath_common *common = ath9k_hw_common(ah);
4693 if (ichain >= AR9300_MAX_CHAINS) {
4694 ath_dbg(common, EEPROM,
4695 "Invalid chain index, must be less than %d\n",
4696 AR9300_MAX_CHAINS);
4697 return -1;
4700 if (mode) { /* 5GHz */
4701 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4702 ath_dbg(common, EEPROM,
4703 "Invalid 5GHz cal pier index, must be less than %d\n",
4704 AR9300_NUM_5G_CAL_PIERS);
4705 return -1;
4707 pCalPier = &(eep->calFreqPier5G[ipier]);
4708 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4709 is2GHz = 0;
4710 } else {
4711 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4712 ath_dbg(common, EEPROM,
4713 "Invalid 2GHz cal pier index, must be less than %d\n",
4714 AR9300_NUM_2G_CAL_PIERS);
4715 return -1;
4718 pCalPier = &(eep->calFreqPier2G[ipier]);
4719 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4720 is2GHz = 1;
4723 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4724 *pcorrection = pCalPierStruct->refPower;
4725 *ptemperature = pCalPierStruct->tempMeas;
4726 *pvoltage = pCalPierStruct->voltMeas;
4728 return 0;
4731 static void ar9003_hw_power_control_override(struct ath_hw *ah,
4732 int frequency,
4733 int *correction,
4734 int *voltage, int *temperature)
4736 int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
4737 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4738 int f[8], t[8], t1[3], t2[3], i;
4740 REG_RMW(ah, AR_PHY_TPC_11_B0,
4741 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4742 AR_PHY_TPC_OLPC_GAIN_DELTA);
4743 if (ah->caps.tx_chainmask & BIT(1))
4744 REG_RMW(ah, AR_PHY_TPC_11_B1,
4745 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4746 AR_PHY_TPC_OLPC_GAIN_DELTA);
4747 if (ah->caps.tx_chainmask & BIT(2))
4748 REG_RMW(ah, AR_PHY_TPC_11_B2,
4749 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4750 AR_PHY_TPC_OLPC_GAIN_DELTA);
4752 /* enable open loop power control on chip */
4753 REG_RMW(ah, AR_PHY_TPC_6_B0,
4754 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4755 AR_PHY_TPC_6_ERROR_EST_MODE);
4756 if (ah->caps.tx_chainmask & BIT(1))
4757 REG_RMW(ah, AR_PHY_TPC_6_B1,
4758 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4759 AR_PHY_TPC_6_ERROR_EST_MODE);
4760 if (ah->caps.tx_chainmask & BIT(2))
4761 REG_RMW(ah, AR_PHY_TPC_6_B2,
4762 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4763 AR_PHY_TPC_6_ERROR_EST_MODE);
4766 * enable temperature compensation
4767 * Need to use register names
4769 if (frequency < 4000) {
4770 temp_slope = eep->modalHeader2G.tempSlope;
4771 } else {
4772 if (AR_SREV_9550(ah)) {
4773 t[0] = eep->base_ext1.tempslopextension[2];
4774 t1[0] = eep->base_ext1.tempslopextension[3];
4775 t2[0] = eep->base_ext1.tempslopextension[4];
4776 f[0] = 5180;
4778 t[1] = eep->modalHeader5G.tempSlope;
4779 t1[1] = eep->base_ext1.tempslopextension[0];
4780 t2[1] = eep->base_ext1.tempslopextension[1];
4781 f[1] = 5500;
4783 t[2] = eep->base_ext1.tempslopextension[5];
4784 t1[2] = eep->base_ext1.tempslopextension[6];
4785 t2[2] = eep->base_ext1.tempslopextension[7];
4786 f[2] = 5785;
4788 temp_slope = ar9003_hw_power_interpolate(frequency,
4789 f, t, 3);
4790 temp_slope1 = ar9003_hw_power_interpolate(frequency,
4791 f, t1, 3);
4792 temp_slope2 = ar9003_hw_power_interpolate(frequency,
4793 f, t2, 3);
4795 goto tempslope;
4798 if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4799 for (i = 0; i < 8; i++) {
4800 t[i] = eep->base_ext1.tempslopextension[i];
4801 f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4803 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4804 f, t, 8);
4805 } else if (eep->base_ext2.tempSlopeLow != 0) {
4806 t[0] = eep->base_ext2.tempSlopeLow;
4807 f[0] = 5180;
4808 t[1] = eep->modalHeader5G.tempSlope;
4809 f[1] = 5500;
4810 t[2] = eep->base_ext2.tempSlopeHigh;
4811 f[2] = 5785;
4812 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4813 f, t, 3);
4814 } else {
4815 temp_slope = eep->modalHeader5G.tempSlope;
4819 tempslope:
4820 if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
4821 u8 txmask = (eep->baseEepHeader.txrxMask & 0xf0) >> 4;
4824 * AR955x has tempSlope register for each chain.
4825 * Check whether temp_compensation feature is enabled or not.
4827 if (eep->baseEepHeader.featureEnable & 0x1) {
4828 if (frequency < 4000) {
4829 if (txmask & BIT(0))
4830 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4831 AR_PHY_TPC_19_ALPHA_THERM,
4832 eep->base_ext2.tempSlopeLow);
4833 if (txmask & BIT(1))
4834 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4835 AR_PHY_TPC_19_ALPHA_THERM,
4836 temp_slope);
4837 if (txmask & BIT(2))
4838 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4839 AR_PHY_TPC_19_ALPHA_THERM,
4840 eep->base_ext2.tempSlopeHigh);
4841 } else {
4842 if (txmask & BIT(0))
4843 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4844 AR_PHY_TPC_19_ALPHA_THERM,
4845 temp_slope);
4846 if (txmask & BIT(1))
4847 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4848 AR_PHY_TPC_19_ALPHA_THERM,
4849 temp_slope1);
4850 if (txmask & BIT(2))
4851 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4852 AR_PHY_TPC_19_ALPHA_THERM,
4853 temp_slope2);
4855 } else {
4857 * If temp compensation is not enabled,
4858 * set all registers to 0.
4860 if (txmask & BIT(0))
4861 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4862 AR_PHY_TPC_19_ALPHA_THERM, 0);
4863 if (txmask & BIT(1))
4864 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4865 AR_PHY_TPC_19_ALPHA_THERM, 0);
4866 if (txmask & BIT(2))
4867 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4868 AR_PHY_TPC_19_ALPHA_THERM, 0);
4870 } else {
4871 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4872 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4875 if (AR_SREV_9462_20_OR_LATER(ah))
4876 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4877 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4880 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4881 temperature[0]);
4884 /* Apply the recorded correction values. */
4885 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4887 int ichain, ipier, npier;
4888 int mode;
4889 int lfrequency[AR9300_MAX_CHAINS],
4890 lcorrection[AR9300_MAX_CHAINS],
4891 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4892 int hfrequency[AR9300_MAX_CHAINS],
4893 hcorrection[AR9300_MAX_CHAINS],
4894 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4895 int fdiff;
4896 int correction[AR9300_MAX_CHAINS],
4897 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4898 int pfrequency, pcorrection, ptemperature, pvoltage;
4899 struct ath_common *common = ath9k_hw_common(ah);
4901 mode = (frequency >= 4000);
4902 if (mode)
4903 npier = AR9300_NUM_5G_CAL_PIERS;
4904 else
4905 npier = AR9300_NUM_2G_CAL_PIERS;
4907 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4908 lfrequency[ichain] = 0;
4909 hfrequency[ichain] = 100000;
4911 /* identify best lower and higher frequency calibration measurement */
4912 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4913 for (ipier = 0; ipier < npier; ipier++) {
4914 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4915 &pfrequency, &pcorrection,
4916 &ptemperature, &pvoltage)) {
4917 fdiff = frequency - pfrequency;
4920 * this measurement is higher than
4921 * our desired frequency
4923 if (fdiff <= 0) {
4924 if (hfrequency[ichain] <= 0 ||
4925 hfrequency[ichain] >= 100000 ||
4926 fdiff >
4927 (frequency - hfrequency[ichain])) {
4929 * new best higher
4930 * frequency measurement
4932 hfrequency[ichain] = pfrequency;
4933 hcorrection[ichain] =
4934 pcorrection;
4935 htemperature[ichain] =
4936 ptemperature;
4937 hvoltage[ichain] = pvoltage;
4940 if (fdiff >= 0) {
4941 if (lfrequency[ichain] <= 0
4942 || fdiff <
4943 (frequency - lfrequency[ichain])) {
4945 * new best lower
4946 * frequency measurement
4948 lfrequency[ichain] = pfrequency;
4949 lcorrection[ichain] =
4950 pcorrection;
4951 ltemperature[ichain] =
4952 ptemperature;
4953 lvoltage[ichain] = pvoltage;
4960 /* interpolate */
4961 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4962 ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
4963 ichain, frequency, lfrequency[ichain],
4964 lcorrection[ichain], hfrequency[ichain],
4965 hcorrection[ichain]);
4966 /* they're the same, so just pick one */
4967 if (hfrequency[ichain] == lfrequency[ichain]) {
4968 correction[ichain] = lcorrection[ichain];
4969 voltage[ichain] = lvoltage[ichain];
4970 temperature[ichain] = ltemperature[ichain];
4972 /* the low frequency is good */
4973 else if (frequency - lfrequency[ichain] < 1000) {
4974 /* so is the high frequency, interpolate */
4975 if (hfrequency[ichain] - frequency < 1000) {
4977 correction[ichain] = interpolate(frequency,
4978 lfrequency[ichain],
4979 hfrequency[ichain],
4980 lcorrection[ichain],
4981 hcorrection[ichain]);
4983 temperature[ichain] = interpolate(frequency,
4984 lfrequency[ichain],
4985 hfrequency[ichain],
4986 ltemperature[ichain],
4987 htemperature[ichain]);
4989 voltage[ichain] = interpolate(frequency,
4990 lfrequency[ichain],
4991 hfrequency[ichain],
4992 lvoltage[ichain],
4993 hvoltage[ichain]);
4995 /* only low is good, use it */
4996 else {
4997 correction[ichain] = lcorrection[ichain];
4998 temperature[ichain] = ltemperature[ichain];
4999 voltage[ichain] = lvoltage[ichain];
5002 /* only high is good, use it */
5003 else if (hfrequency[ichain] - frequency < 1000) {
5004 correction[ichain] = hcorrection[ichain];
5005 temperature[ichain] = htemperature[ichain];
5006 voltage[ichain] = hvoltage[ichain];
5007 } else { /* nothing is good, presume 0???? */
5008 correction[ichain] = 0;
5009 temperature[ichain] = 0;
5010 voltage[ichain] = 0;
5014 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
5015 temperature);
5017 ath_dbg(common, EEPROM,
5018 "for frequency=%d, calibration correction = %d %d %d\n",
5019 frequency, correction[0], correction[1], correction[2]);
5021 return 0;
5024 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
5025 int idx,
5026 int edge,
5027 bool is2GHz)
5029 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5030 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5032 if (is2GHz)
5033 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
5034 else
5035 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
5038 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
5039 int idx,
5040 unsigned int edge,
5041 u16 freq,
5042 bool is2GHz)
5044 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5045 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5047 u8 *ctl_freqbin = is2GHz ?
5048 &eep->ctl_freqbin_2G[idx][0] :
5049 &eep->ctl_freqbin_5G[idx][0];
5051 if (is2GHz) {
5052 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
5053 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
5054 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
5055 } else {
5056 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
5057 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
5058 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
5061 return MAX_RATE_POWER;
5065 * Find the maximum conformance test limit for the given channel and CTL info
5067 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
5068 u16 freq, int idx, bool is2GHz)
5070 u16 twiceMaxEdgePower = MAX_RATE_POWER;
5071 u8 *ctl_freqbin = is2GHz ?
5072 &eep->ctl_freqbin_2G[idx][0] :
5073 &eep->ctl_freqbin_5G[idx][0];
5074 u16 num_edges = is2GHz ?
5075 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
5076 unsigned int edge;
5078 /* Get the edge power */
5079 for (edge = 0;
5080 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
5081 edge++) {
5083 * If there's an exact channel match or an inband flag set
5084 * on the lower channel use the given rdEdgePower
5086 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
5087 twiceMaxEdgePower =
5088 ar9003_hw_get_direct_edge_power(eep, idx,
5089 edge, is2GHz);
5090 break;
5091 } else if ((edge > 0) &&
5092 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
5093 is2GHz))) {
5094 twiceMaxEdgePower =
5095 ar9003_hw_get_indirect_edge_power(eep, idx,
5096 edge, freq,
5097 is2GHz);
5099 * Leave loop - no more affecting edges possible in
5100 * this monotonic increasing list
5102 break;
5106 if (is2GHz && !twiceMaxEdgePower)
5107 twiceMaxEdgePower = 60;
5109 return twiceMaxEdgePower;
5112 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
5113 struct ath9k_channel *chan,
5114 u8 *pPwrArray, u16 cfgCtl,
5115 u8 antenna_reduction,
5116 u16 powerLimit)
5118 struct ath_common *common = ath9k_hw_common(ah);
5119 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
5120 u16 twiceMaxEdgePower;
5121 int i;
5122 u16 scaledPower = 0, minCtlPower;
5123 static const u16 ctlModesFor11a[] = {
5124 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
5126 static const u16 ctlModesFor11g[] = {
5127 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
5128 CTL_11G_EXT, CTL_2GHT40
5130 u16 numCtlModes;
5131 const u16 *pCtlMode;
5132 u16 ctlMode, freq;
5133 struct chan_centers centers;
5134 u8 *ctlIndex;
5135 u8 ctlNum;
5136 u16 twiceMinEdgePower;
5137 bool is2ghz = IS_CHAN_2GHZ(chan);
5139 ath9k_hw_get_channel_centers(ah, chan, &centers);
5140 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
5141 antenna_reduction);
5143 if (is2ghz) {
5144 /* Setup for CTL modes */
5145 /* CTL_11B, CTL_11G, CTL_2GHT20 */
5146 numCtlModes =
5147 ARRAY_SIZE(ctlModesFor11g) -
5148 SUB_NUM_CTL_MODES_AT_2G_40;
5149 pCtlMode = ctlModesFor11g;
5150 if (IS_CHAN_HT40(chan))
5151 /* All 2G CTL's */
5152 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
5153 } else {
5154 /* Setup for CTL modes */
5155 /* CTL_11A, CTL_5GHT20 */
5156 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
5157 SUB_NUM_CTL_MODES_AT_5G_40;
5158 pCtlMode = ctlModesFor11a;
5159 if (IS_CHAN_HT40(chan))
5160 /* All 5G CTL's */
5161 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
5165 * For MIMO, need to apply regulatory caps individually across
5166 * dynamically running modes: CCK, OFDM, HT20, HT40
5168 * The outer loop walks through each possible applicable runtime mode.
5169 * The inner loop walks through each ctlIndex entry in EEPROM.
5170 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
5172 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
5173 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
5174 (pCtlMode[ctlMode] == CTL_2GHT40);
5175 if (isHt40CtlMode)
5176 freq = centers.synth_center;
5177 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
5178 freq = centers.ext_center;
5179 else
5180 freq = centers.ctl_center;
5182 ath_dbg(common, REGULATORY,
5183 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
5184 ctlMode, numCtlModes, isHt40CtlMode,
5185 (pCtlMode[ctlMode] & EXT_ADDITIVE));
5187 /* walk through each CTL index stored in EEPROM */
5188 if (is2ghz) {
5189 ctlIndex = pEepData->ctlIndex_2G;
5190 ctlNum = AR9300_NUM_CTLS_2G;
5191 } else {
5192 ctlIndex = pEepData->ctlIndex_5G;
5193 ctlNum = AR9300_NUM_CTLS_5G;
5196 twiceMaxEdgePower = MAX_RATE_POWER;
5197 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
5198 ath_dbg(common, REGULATORY,
5199 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
5200 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
5201 chan->channel);
5204 * compare test group from regulatory
5205 * channel list with test mode from pCtlMode
5206 * list
5208 if ((((cfgCtl & ~CTL_MODE_M) |
5209 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5210 ctlIndex[i]) ||
5211 (((cfgCtl & ~CTL_MODE_M) |
5212 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5213 ((ctlIndex[i] & CTL_MODE_M) |
5214 SD_NO_CTL))) {
5215 twiceMinEdgePower =
5216 ar9003_hw_get_max_edge_power(pEepData,
5217 freq, i,
5218 is2ghz);
5220 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
5222 * Find the minimum of all CTL
5223 * edge powers that apply to
5224 * this channel
5226 twiceMaxEdgePower =
5227 min(twiceMaxEdgePower,
5228 twiceMinEdgePower);
5229 else {
5230 /* specific */
5231 twiceMaxEdgePower = twiceMinEdgePower;
5232 break;
5237 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
5239 ath_dbg(common, REGULATORY,
5240 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
5241 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
5242 scaledPower, minCtlPower);
5244 /* Apply ctl mode to correct target power set */
5245 switch (pCtlMode[ctlMode]) {
5246 case CTL_11B:
5247 for (i = ALL_TARGET_LEGACY_1L_5L;
5248 i <= ALL_TARGET_LEGACY_11S; i++)
5249 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5250 minCtlPower);
5251 break;
5252 case CTL_11A:
5253 case CTL_11G:
5254 for (i = ALL_TARGET_LEGACY_6_24;
5255 i <= ALL_TARGET_LEGACY_54; i++)
5256 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5257 minCtlPower);
5258 break;
5259 case CTL_5GHT20:
5260 case CTL_2GHT20:
5261 for (i = ALL_TARGET_HT20_0_8_16;
5262 i <= ALL_TARGET_HT20_23; i++) {
5263 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5264 minCtlPower);
5265 if (ath9k_hw_mci_is_enabled(ah))
5266 pPwrArray[i] =
5267 (u8)min((u16)pPwrArray[i],
5268 ar9003_mci_get_max_txpower(ah,
5269 pCtlMode[ctlMode]));
5271 break;
5272 case CTL_5GHT40:
5273 case CTL_2GHT40:
5274 for (i = ALL_TARGET_HT40_0_8_16;
5275 i <= ALL_TARGET_HT40_23; i++) {
5276 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5277 minCtlPower);
5278 if (ath9k_hw_mci_is_enabled(ah))
5279 pPwrArray[i] =
5280 (u8)min((u16)pPwrArray[i],
5281 ar9003_mci_get_max_txpower(ah,
5282 pCtlMode[ctlMode]));
5284 break;
5285 default:
5286 break;
5288 } /* end ctl mode checking */
5291 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5293 u8 mod_idx = mcs_idx % 8;
5295 if (mod_idx <= 3)
5296 return mod_idx ? (base_pwridx + 1) : base_pwridx;
5297 else
5298 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5301 static void ar9003_paprd_set_txpower(struct ath_hw *ah,
5302 struct ath9k_channel *chan,
5303 u8 *targetPowerValT2)
5305 int i;
5307 if (!ar9003_is_paprd_enabled(ah))
5308 return;
5310 if (IS_CHAN_HT40(chan))
5311 i = ALL_TARGET_HT40_7;
5312 else
5313 i = ALL_TARGET_HT20_7;
5315 if (IS_CHAN_2GHZ(chan)) {
5316 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) &&
5317 !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) {
5318 if (IS_CHAN_HT40(chan))
5319 i = ALL_TARGET_HT40_0_8_16;
5320 else
5321 i = ALL_TARGET_HT20_0_8_16;
5325 ah->paprd_target_power = targetPowerValT2[i];
5328 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5329 struct ath9k_channel *chan, u16 cfgCtl,
5330 u8 twiceAntennaReduction,
5331 u8 powerLimit, bool test)
5333 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5334 struct ath_common *common = ath9k_hw_common(ah);
5335 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5336 struct ar9300_modal_eep_header *modal_hdr;
5337 u8 targetPowerValT2[ar9300RateSize];
5338 u8 target_power_val_t2_eep[ar9300RateSize];
5339 u8 targetPowerValT2_tpc[ar9300RateSize];
5340 unsigned int i = 0, paprd_scale_factor = 0;
5341 u8 pwr_idx, min_pwridx = 0;
5343 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5346 * Get target powers from EEPROM - our baseline for TX Power
5348 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5350 if (ar9003_is_paprd_enabled(ah)) {
5351 if (IS_CHAN_2GHZ(chan))
5352 modal_hdr = &eep->modalHeader2G;
5353 else
5354 modal_hdr = &eep->modalHeader5G;
5356 ah->paprd_ratemask =
5357 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5358 AR9300_PAPRD_RATE_MASK;
5360 ah->paprd_ratemask_ht40 =
5361 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5362 AR9300_PAPRD_RATE_MASK;
5364 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5365 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5366 ALL_TARGET_HT20_0_8_16;
5368 if (!ah->paprd_table_write_done) {
5369 memcpy(target_power_val_t2_eep, targetPowerValT2,
5370 sizeof(targetPowerValT2));
5371 for (i = 0; i < 24; i++) {
5372 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5373 if (ah->paprd_ratemask & (1 << i)) {
5374 if (targetPowerValT2[pwr_idx] &&
5375 targetPowerValT2[pwr_idx] ==
5376 target_power_val_t2_eep[pwr_idx])
5377 targetPowerValT2[pwr_idx] -=
5378 paprd_scale_factor;
5382 memcpy(target_power_val_t2_eep, targetPowerValT2,
5383 sizeof(targetPowerValT2));
5386 ar9003_hw_set_power_per_rate_table(ah, chan,
5387 targetPowerValT2, cfgCtl,
5388 twiceAntennaReduction,
5389 powerLimit);
5391 memcpy(targetPowerValT2_tpc, targetPowerValT2,
5392 sizeof(targetPowerValT2));
5394 if (ar9003_is_paprd_enabled(ah)) {
5395 for (i = 0; i < ar9300RateSize; i++) {
5396 if ((ah->paprd_ratemask & (1 << i)) &&
5397 (abs(targetPowerValT2[i] -
5398 target_power_val_t2_eep[i]) >
5399 paprd_scale_factor)) {
5400 ah->paprd_ratemask &= ~(1 << i);
5401 ath_dbg(common, EEPROM,
5402 "paprd disabled for mcs %d\n", i);
5407 regulatory->max_power_level = 0;
5408 for (i = 0; i < ar9300RateSize; i++) {
5409 if (targetPowerValT2[i] > regulatory->max_power_level)
5410 regulatory->max_power_level = targetPowerValT2[i];
5413 ath9k_hw_update_regulatory_maxpower(ah);
5415 if (test)
5416 return;
5418 for (i = 0; i < ar9300RateSize; i++) {
5419 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
5420 i, targetPowerValT2[i]);
5423 /* Write target power array to registers */
5424 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5425 ar9003_hw_calibration_apply(ah, chan->channel);
5426 ar9003_paprd_set_txpower(ah, chan, targetPowerValT2);
5428 ar9003_hw_selfgen_tpc_txpower(ah, chan, targetPowerValT2);
5430 /* TPC initializations */
5431 if (ah->tpc_enabled) {
5432 u32 val;
5434 ar9003_hw_init_rate_txpower(ah, targetPowerValT2_tpc, chan);
5436 /* Enable TPC */
5437 REG_WRITE(ah, AR_PHY_PWRTX_MAX,
5438 AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
5439 /* Disable per chain power reduction */
5440 val = REG_READ(ah, AR_PHY_POWER_TX_SUB);
5441 if (AR_SREV_9340(ah))
5442 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5443 val & 0xFFFFFFC0);
5444 else
5445 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5446 val & 0xFFFFF000);
5447 } else {
5448 /* Disable TPC */
5449 REG_WRITE(ah, AR_PHY_PWRTX_MAX, 0);
5453 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5454 u16 i, bool is2GHz)
5456 return AR_NO_SPUR;
5459 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5461 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5463 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5466 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5468 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5470 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5473 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5475 return ar9003_modal_header(ah, is2ghz)->spurChans;
5478 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5479 struct ath9k_channel *chan)
5481 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5483 if (IS_CHAN_2GHZ(chan))
5484 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5485 AR9300_PAPRD_SCALE_1);
5486 else {
5487 if (chan->channel >= 5700)
5488 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5489 AR9300_PAPRD_SCALE_1);
5490 else if (chan->channel >= 5400)
5491 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5492 AR9300_PAPRD_SCALE_2);
5493 else
5494 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5495 AR9300_PAPRD_SCALE_1);
5499 const struct eeprom_ops eep_ar9300_ops = {
5500 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5501 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5502 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5503 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5504 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5505 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5506 .set_board_values = ath9k_hw_ar9300_set_board_values,
5507 .set_addac = ath9k_hw_ar9300_set_addac,
5508 .set_txpower = ath9k_hw_ar9300_set_txpower,
5509 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel