Adding support for MOXA ART SoC. Testing port of linux-2.6.32.60-moxart.
[linux-3.6.7-moxart.git] / drivers / net / wireless / ath / ath9k / ar9003_eeprom.c
blobd066f2516e4753617aa55f1522427eb96f4a1115
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"
22 #define COMP_HDR_LEN 4
23 #define COMP_CKSUM_LEN 2
25 #define LE16(x) __constant_cpu_to_le16(x)
26 #define LE32(x) __constant_cpu_to_le32(x)
28 /* Local defines to distinguish between extension and control CTL's */
29 #define EXT_ADDITIVE (0x8000)
30 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
31 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
32 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
34 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
35 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
37 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
39 #define EEPROM_DATA_LEN_9485 1088
41 static int ar9003_hw_power_interpolate(int32_t x,
42 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 .xlna_bias_strength = 0,
135 .futureModal = {
136 0, 0, 0, 0, 0, 0, 0,
139 .base_ext1 = {
140 .ant_div_control = 0,
141 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
143 .calFreqPier2G = {
144 FREQ2FBIN(2412, 1),
145 FREQ2FBIN(2437, 1),
146 FREQ2FBIN(2472, 1),
148 /* ar9300_cal_data_per_freq_op_loop 2g */
149 .calPierData2G = {
150 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
151 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
152 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
154 .calTarget_freqbin_Cck = {
155 FREQ2FBIN(2412, 1),
156 FREQ2FBIN(2484, 1),
158 .calTarget_freqbin_2G = {
159 FREQ2FBIN(2412, 1),
160 FREQ2FBIN(2437, 1),
161 FREQ2FBIN(2472, 1)
163 .calTarget_freqbin_2GHT20 = {
164 FREQ2FBIN(2412, 1),
165 FREQ2FBIN(2437, 1),
166 FREQ2FBIN(2472, 1)
168 .calTarget_freqbin_2GHT40 = {
169 FREQ2FBIN(2412, 1),
170 FREQ2FBIN(2437, 1),
171 FREQ2FBIN(2472, 1)
173 .calTargetPowerCck = {
174 /* 1L-5L,5S,11L,11S */
175 { {36, 36, 36, 36} },
176 { {36, 36, 36, 36} },
178 .calTargetPower2G = {
179 /* 6-24,36,48,54 */
180 { {32, 32, 28, 24} },
181 { {32, 32, 28, 24} },
182 { {32, 32, 28, 24} },
184 .calTargetPower2GHT20 = {
185 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
186 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
187 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
189 .calTargetPower2GHT40 = {
190 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
191 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
192 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
194 .ctlIndex_2G = {
195 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
196 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
198 .ctl_freqbin_2G = {
200 FREQ2FBIN(2412, 1),
201 FREQ2FBIN(2417, 1),
202 FREQ2FBIN(2457, 1),
203 FREQ2FBIN(2462, 1)
206 FREQ2FBIN(2412, 1),
207 FREQ2FBIN(2417, 1),
208 FREQ2FBIN(2462, 1),
209 0xFF,
213 FREQ2FBIN(2412, 1),
214 FREQ2FBIN(2417, 1),
215 FREQ2FBIN(2462, 1),
216 0xFF,
219 FREQ2FBIN(2422, 1),
220 FREQ2FBIN(2427, 1),
221 FREQ2FBIN(2447, 1),
222 FREQ2FBIN(2452, 1)
226 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
227 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
228 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
229 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
233 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
234 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
235 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
240 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
241 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
242 FREQ2FBIN(2472, 1),
247 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
248 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
249 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
250 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
254 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
255 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
256 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
260 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
261 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
262 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
267 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
268 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
269 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
274 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
275 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
276 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
277 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
280 .ctlPowerData_2G = {
281 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
282 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
283 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
285 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
286 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
287 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
289 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
290 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
291 { { 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) } },
294 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
295 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
297 .modalHeader5G = {
298 /* 4 idle,t1,t2,b (4 bits per setting) */
299 .antCtrlCommon = LE32(0x110),
300 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
301 .antCtrlCommon2 = LE32(0x22222),
302 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
303 .antCtrlChain = {
304 LE16(0x000), LE16(0x000), LE16(0x000),
306 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
307 .xatten1DB = {0, 0, 0},
310 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
311 * for merlin (0xa20c/b20c 16:12
313 .xatten1Margin = {0, 0, 0},
314 .tempSlope = 68,
315 .voltSlope = 0,
316 /* spurChans spur channels in usual fbin coding format */
317 .spurChans = {0, 0, 0, 0, 0},
318 /* noiseFloorThreshCh Check if the register is per chain */
319 .noiseFloorThreshCh = {-1, 0, 0},
320 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
321 .quick_drop = 0,
322 .xpaBiasLvl = 0,
323 .txFrameToDataStart = 0x0e,
324 .txFrameToPaOn = 0x0e,
325 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
326 .antennaGain = 0,
327 .switchSettling = 0x2d,
328 .adcDesiredSize = -30,
329 .txEndToXpaOff = 0,
330 .txEndToRxOn = 0x2,
331 .txFrameToXpaOn = 0xe,
332 .thresh62 = 28,
333 .papdRateMaskHt20 = LE32(0x0c80c080),
334 .papdRateMaskHt40 = LE32(0x0080c080),
335 .xlna_bias_strength = 0,
336 .futureModal = {
337 0, 0, 0, 0, 0, 0, 0,
340 .base_ext2 = {
341 .tempSlopeLow = 0,
342 .tempSlopeHigh = 0,
343 .xatten1DBLow = {0, 0, 0},
344 .xatten1MarginLow = {0, 0, 0},
345 .xatten1DBHigh = {0, 0, 0},
346 .xatten1MarginHigh = {0, 0, 0}
348 .calFreqPier5G = {
349 FREQ2FBIN(5180, 0),
350 FREQ2FBIN(5220, 0),
351 FREQ2FBIN(5320, 0),
352 FREQ2FBIN(5400, 0),
353 FREQ2FBIN(5500, 0),
354 FREQ2FBIN(5600, 0),
355 FREQ2FBIN(5725, 0),
356 FREQ2FBIN(5825, 0)
358 .calPierData5G = {
360 {0, 0, 0, 0, 0},
361 {0, 0, 0, 0, 0},
362 {0, 0, 0, 0, 0},
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},
370 {0, 0, 0, 0, 0},
371 {0, 0, 0, 0, 0},
372 {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},
380 {0, 0, 0, 0, 0},
381 {0, 0, 0, 0, 0},
382 {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},
391 .calTarget_freqbin_5G = {
392 FREQ2FBIN(5180, 0),
393 FREQ2FBIN(5220, 0),
394 FREQ2FBIN(5320, 0),
395 FREQ2FBIN(5400, 0),
396 FREQ2FBIN(5500, 0),
397 FREQ2FBIN(5600, 0),
398 FREQ2FBIN(5725, 0),
399 FREQ2FBIN(5825, 0)
401 .calTarget_freqbin_5GHT20 = {
402 FREQ2FBIN(5180, 0),
403 FREQ2FBIN(5240, 0),
404 FREQ2FBIN(5320, 0),
405 FREQ2FBIN(5500, 0),
406 FREQ2FBIN(5700, 0),
407 FREQ2FBIN(5745, 0),
408 FREQ2FBIN(5725, 0),
409 FREQ2FBIN(5825, 0)
411 .calTarget_freqbin_5GHT40 = {
412 FREQ2FBIN(5180, 0),
413 FREQ2FBIN(5240, 0),
414 FREQ2FBIN(5320, 0),
415 FREQ2FBIN(5500, 0),
416 FREQ2FBIN(5700, 0),
417 FREQ2FBIN(5745, 0),
418 FREQ2FBIN(5725, 0),
419 FREQ2FBIN(5825, 0)
421 .calTargetPower5G = {
422 /* 6-24,36,48,54 */
423 { {20, 20, 20, 10} },
424 { {20, 20, 20, 10} },
425 { {20, 20, 20, 10} },
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} },
432 .calTargetPower5GHT20 = {
434 * 0_8_16,1-3_9-11_17-19,
435 * 4,5,6,7,12,13,14,15,20,21,22,23
437 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
438 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
439 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
440 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
441 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
442 { {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} },
446 .calTargetPower5GHT40 = {
448 * 0_8_16,1-3_9-11_17-19,
449 * 4,5,6,7,12,13,14,15,20,21,22,23
451 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
452 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
453 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
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} },
460 .ctlIndex_5G = {
461 0x10, 0x16, 0x18, 0x40, 0x46,
462 0x48, 0x30, 0x36, 0x38
464 .ctl_freqbin_5G = {
466 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
467 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
468 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
469 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
470 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
471 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
472 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
473 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
476 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
477 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
478 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
479 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
480 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
481 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
482 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
483 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
487 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
488 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
489 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
490 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
491 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
492 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
493 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
494 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
498 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
499 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
500 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
501 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
502 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
503 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
504 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
505 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
509 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
510 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
511 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
512 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
513 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
514 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
515 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
516 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
520 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
521 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
522 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
523 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
524 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
525 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
526 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
527 /* Data[5].ctlEdges[7].bChannel */ 0xFF
531 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
532 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
533 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
534 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
535 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
536 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
537 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
538 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
542 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
543 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
544 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
545 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
546 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
547 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
548 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
549 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
553 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
554 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
555 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
556 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
557 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
558 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
559 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
560 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
563 .ctlPowerData_5G = {
566 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
567 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
572 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
573 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
578 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
579 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
584 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
585 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
590 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
591 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
596 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
597 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
602 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
603 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
608 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
609 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
614 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
615 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
621 static const struct ar9300_eeprom ar9300_x113 = {
622 .eepromVersion = 2,
623 .templateVersion = 6,
624 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
625 .custData = {"x113-023-f0000"},
626 .baseEepHeader = {
627 .regDmn = { LE16(0), LE16(0x1f) },
628 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
629 .opCapFlags = {
630 .opFlags = AR5416_OPFLAGS_11A,
631 .eepMisc = 0,
633 .rfSilent = 0,
634 .blueToothOptions = 0,
635 .deviceCap = 0,
636 .deviceType = 5, /* takes lower byte in eeprom location */
637 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
638 .params_for_tuning_caps = {0, 0},
639 .featureEnable = 0x0d,
641 * bit0 - enable tx temp comp - disabled
642 * bit1 - enable tx volt comp - disabled
643 * bit2 - enable fastClock - enabled
644 * bit3 - enable doubling - enabled
645 * bit4 - enable internal regulator - disabled
646 * bit5 - enable pa predistortion - disabled
648 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
649 .eepromWriteEnableGpio = 6,
650 .wlanDisableGpio = 0,
651 .wlanLedGpio = 8,
652 .rxBandSelectGpio = 0xff,
653 .txrxgain = 0x21,
654 .swreg = 0,
656 .modalHeader2G = {
657 /* ar9300_modal_eep_header 2g */
658 /* 4 idle,t1,t2,b(4 bits per setting) */
659 .antCtrlCommon = LE32(0x110),
660 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
661 .antCtrlCommon2 = LE32(0x44444),
664 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
665 * rx1, rx12, b (2 bits each)
667 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
670 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
671 * for ar9280 (0xa20c/b20c 5:0)
673 .xatten1DB = {0, 0, 0},
676 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
677 * for ar9280 (0xa20c/b20c 16:12
679 .xatten1Margin = {0, 0, 0},
680 .tempSlope = 25,
681 .voltSlope = 0,
684 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
685 * channels in usual fbin coding format
687 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
690 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
691 * if the register is per chain
693 .noiseFloorThreshCh = {-1, 0, 0},
694 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
695 .quick_drop = 0,
696 .xpaBiasLvl = 0,
697 .txFrameToDataStart = 0x0e,
698 .txFrameToPaOn = 0x0e,
699 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
700 .antennaGain = 0,
701 .switchSettling = 0x2c,
702 .adcDesiredSize = -30,
703 .txEndToXpaOff = 0,
704 .txEndToRxOn = 0x2,
705 .txFrameToXpaOn = 0xe,
706 .thresh62 = 28,
707 .papdRateMaskHt20 = LE32(0x0c80c080),
708 .papdRateMaskHt40 = LE32(0x0080c080),
709 .xlna_bias_strength = 0,
710 .futureModal = {
711 0, 0, 0, 0, 0, 0, 0,
714 .base_ext1 = {
715 .ant_div_control = 0,
716 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
718 .calFreqPier2G = {
719 FREQ2FBIN(2412, 1),
720 FREQ2FBIN(2437, 1),
721 FREQ2FBIN(2472, 1),
723 /* ar9300_cal_data_per_freq_op_loop 2g */
724 .calPierData2G = {
725 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
726 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
727 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
729 .calTarget_freqbin_Cck = {
730 FREQ2FBIN(2412, 1),
731 FREQ2FBIN(2472, 1),
733 .calTarget_freqbin_2G = {
734 FREQ2FBIN(2412, 1),
735 FREQ2FBIN(2437, 1),
736 FREQ2FBIN(2472, 1)
738 .calTarget_freqbin_2GHT20 = {
739 FREQ2FBIN(2412, 1),
740 FREQ2FBIN(2437, 1),
741 FREQ2FBIN(2472, 1)
743 .calTarget_freqbin_2GHT40 = {
744 FREQ2FBIN(2412, 1),
745 FREQ2FBIN(2437, 1),
746 FREQ2FBIN(2472, 1)
748 .calTargetPowerCck = {
749 /* 1L-5L,5S,11L,11S */
750 { {34, 34, 34, 34} },
751 { {34, 34, 34, 34} },
753 .calTargetPower2G = {
754 /* 6-24,36,48,54 */
755 { {34, 34, 32, 32} },
756 { {34, 34, 32, 32} },
757 { {34, 34, 32, 32} },
759 .calTargetPower2GHT20 = {
760 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
761 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
762 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
764 .calTargetPower2GHT40 = {
765 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
766 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
767 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
769 .ctlIndex_2G = {
770 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
771 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
773 .ctl_freqbin_2G = {
775 FREQ2FBIN(2412, 1),
776 FREQ2FBIN(2417, 1),
777 FREQ2FBIN(2457, 1),
778 FREQ2FBIN(2462, 1)
781 FREQ2FBIN(2412, 1),
782 FREQ2FBIN(2417, 1),
783 FREQ2FBIN(2462, 1),
784 0xFF,
788 FREQ2FBIN(2412, 1),
789 FREQ2FBIN(2417, 1),
790 FREQ2FBIN(2462, 1),
791 0xFF,
794 FREQ2FBIN(2422, 1),
795 FREQ2FBIN(2427, 1),
796 FREQ2FBIN(2447, 1),
797 FREQ2FBIN(2452, 1)
801 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
802 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
803 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
804 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
808 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
809 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
810 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
815 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
816 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
817 FREQ2FBIN(2472, 1),
822 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
823 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
824 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
825 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
829 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
830 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
831 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
835 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
836 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
837 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
842 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
843 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
844 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
849 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
850 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
851 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
852 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
855 .ctlPowerData_2G = {
856 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
857 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
858 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
860 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
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) } },
864 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
865 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
866 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
868 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
869 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
870 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
872 .modalHeader5G = {
873 /* 4 idle,t1,t2,b (4 bits per setting) */
874 .antCtrlCommon = LE32(0x220),
875 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
876 .antCtrlCommon2 = LE32(0x11111),
877 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
878 .antCtrlChain = {
879 LE16(0x150), LE16(0x150), LE16(0x150),
881 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
882 .xatten1DB = {0, 0, 0},
885 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
886 * for merlin (0xa20c/b20c 16:12
888 .xatten1Margin = {0, 0, 0},
889 .tempSlope = 68,
890 .voltSlope = 0,
891 /* spurChans spur channels in usual fbin coding format */
892 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
893 /* noiseFloorThreshCh Check if the register is per chain */
894 .noiseFloorThreshCh = {-1, 0, 0},
895 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
896 .quick_drop = 0,
897 .xpaBiasLvl = 0xf,
898 .txFrameToDataStart = 0x0e,
899 .txFrameToPaOn = 0x0e,
900 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
901 .antennaGain = 0,
902 .switchSettling = 0x2d,
903 .adcDesiredSize = -30,
904 .txEndToXpaOff = 0,
905 .txEndToRxOn = 0x2,
906 .txFrameToXpaOn = 0xe,
907 .thresh62 = 28,
908 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
909 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
910 .xlna_bias_strength = 0,
911 .futureModal = {
912 0, 0, 0, 0, 0, 0, 0,
915 .base_ext2 = {
916 .tempSlopeLow = 72,
917 .tempSlopeHigh = 105,
918 .xatten1DBLow = {0, 0, 0},
919 .xatten1MarginLow = {0, 0, 0},
920 .xatten1DBHigh = {0, 0, 0},
921 .xatten1MarginHigh = {0, 0, 0}
923 .calFreqPier5G = {
924 FREQ2FBIN(5180, 0),
925 FREQ2FBIN(5240, 0),
926 FREQ2FBIN(5320, 0),
927 FREQ2FBIN(5400, 0),
928 FREQ2FBIN(5500, 0),
929 FREQ2FBIN(5600, 0),
930 FREQ2FBIN(5745, 0),
931 FREQ2FBIN(5785, 0)
933 .calPierData5G = {
935 {0, 0, 0, 0, 0},
936 {0, 0, 0, 0, 0},
937 {0, 0, 0, 0, 0},
938 {0, 0, 0, 0, 0},
939 {0, 0, 0, 0, 0},
940 {0, 0, 0, 0, 0},
941 {0, 0, 0, 0, 0},
942 {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},
949 {0, 0, 0, 0, 0},
950 {0, 0, 0, 0, 0},
951 {0, 0, 0, 0, 0},
952 {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},
959 {0, 0, 0, 0, 0},
960 {0, 0, 0, 0, 0},
961 {0, 0, 0, 0, 0},
962 {0, 0, 0, 0, 0},
966 .calTarget_freqbin_5G = {
967 FREQ2FBIN(5180, 0),
968 FREQ2FBIN(5220, 0),
969 FREQ2FBIN(5320, 0),
970 FREQ2FBIN(5400, 0),
971 FREQ2FBIN(5500, 0),
972 FREQ2FBIN(5600, 0),
973 FREQ2FBIN(5745, 0),
974 FREQ2FBIN(5785, 0)
976 .calTarget_freqbin_5GHT20 = {
977 FREQ2FBIN(5180, 0),
978 FREQ2FBIN(5240, 0),
979 FREQ2FBIN(5320, 0),
980 FREQ2FBIN(5400, 0),
981 FREQ2FBIN(5500, 0),
982 FREQ2FBIN(5700, 0),
983 FREQ2FBIN(5745, 0),
984 FREQ2FBIN(5825, 0)
986 .calTarget_freqbin_5GHT40 = {
987 FREQ2FBIN(5190, 0),
988 FREQ2FBIN(5230, 0),
989 FREQ2FBIN(5320, 0),
990 FREQ2FBIN(5410, 0),
991 FREQ2FBIN(5510, 0),
992 FREQ2FBIN(5670, 0),
993 FREQ2FBIN(5755, 0),
994 FREQ2FBIN(5825, 0)
996 .calTargetPower5G = {
997 /* 6-24,36,48,54 */
998 { {42, 40, 40, 34} },
999 { {42, 40, 40, 34} },
1000 { {42, 40, 40, 34} },
1001 { {42, 40, 40, 34} },
1002 { {42, 40, 40, 34} },
1003 { {42, 40, 40, 34} },
1004 { {42, 40, 40, 34} },
1005 { {42, 40, 40, 34} },
1007 .calTargetPower5GHT20 = {
1009 * 0_8_16,1-3_9-11_17-19,
1010 * 4,5,6,7,12,13,14,15,20,21,22,23
1012 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1013 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1014 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1015 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1016 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1017 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1018 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1019 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1021 .calTargetPower5GHT40 = {
1023 * 0_8_16,1-3_9-11_17-19,
1024 * 4,5,6,7,12,13,14,15,20,21,22,23
1026 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1027 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1028 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1029 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1030 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1031 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1032 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1033 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1035 .ctlIndex_5G = {
1036 0x10, 0x16, 0x18, 0x40, 0x46,
1037 0x48, 0x30, 0x36, 0x38
1039 .ctl_freqbin_5G = {
1041 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1042 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1043 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1044 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1045 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1046 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1047 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1048 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1051 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1052 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1053 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1054 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1055 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1056 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1057 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1058 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1062 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1063 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1064 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1065 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1066 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1067 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1068 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1069 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1073 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1074 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1075 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1076 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1077 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1078 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1079 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1080 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1084 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1085 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1086 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1087 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1088 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1089 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1090 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1091 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1095 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1096 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1097 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1098 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1099 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1100 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1101 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1102 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1106 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1107 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1108 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1109 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1110 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1111 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1112 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1113 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1117 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1118 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1119 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1120 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1121 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1122 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1123 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1124 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1128 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1129 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1130 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1131 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1132 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1133 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1134 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1135 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1138 .ctlPowerData_5G = {
1141 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1142 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
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, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1154 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1159 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1160 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1165 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1166 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1171 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1172 CTL(60, 1), 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, 1), CTL(60, 1), CTL(60, 1),
1183 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1184 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1189 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1190 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1197 static const struct ar9300_eeprom ar9300_h112 = {
1198 .eepromVersion = 2,
1199 .templateVersion = 3,
1200 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1201 .custData = {"h112-241-f0000"},
1202 .baseEepHeader = {
1203 .regDmn = { LE16(0), LE16(0x1f) },
1204 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1205 .opCapFlags = {
1206 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1207 .eepMisc = 0,
1209 .rfSilent = 0,
1210 .blueToothOptions = 0,
1211 .deviceCap = 0,
1212 .deviceType = 5, /* takes lower byte in eeprom location */
1213 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1214 .params_for_tuning_caps = {0, 0},
1215 .featureEnable = 0x0d,
1217 * bit0 - enable tx temp comp - disabled
1218 * bit1 - enable tx volt comp - disabled
1219 * bit2 - enable fastClock - enabled
1220 * bit3 - enable doubling - enabled
1221 * bit4 - enable internal regulator - disabled
1222 * bit5 - enable pa predistortion - disabled
1224 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1225 .eepromWriteEnableGpio = 6,
1226 .wlanDisableGpio = 0,
1227 .wlanLedGpio = 8,
1228 .rxBandSelectGpio = 0xff,
1229 .txrxgain = 0x10,
1230 .swreg = 0,
1232 .modalHeader2G = {
1233 /* ar9300_modal_eep_header 2g */
1234 /* 4 idle,t1,t2,b(4 bits per setting) */
1235 .antCtrlCommon = LE32(0x110),
1236 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1237 .antCtrlCommon2 = LE32(0x44444),
1240 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1241 * rx1, rx12, b (2 bits each)
1243 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1246 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1247 * for ar9280 (0xa20c/b20c 5:0)
1249 .xatten1DB = {0, 0, 0},
1252 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1253 * for ar9280 (0xa20c/b20c 16:12
1255 .xatten1Margin = {0, 0, 0},
1256 .tempSlope = 25,
1257 .voltSlope = 0,
1260 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1261 * channels in usual fbin coding format
1263 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1266 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1267 * if the register is per chain
1269 .noiseFloorThreshCh = {-1, 0, 0},
1270 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1271 .quick_drop = 0,
1272 .xpaBiasLvl = 0,
1273 .txFrameToDataStart = 0x0e,
1274 .txFrameToPaOn = 0x0e,
1275 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1276 .antennaGain = 0,
1277 .switchSettling = 0x2c,
1278 .adcDesiredSize = -30,
1279 .txEndToXpaOff = 0,
1280 .txEndToRxOn = 0x2,
1281 .txFrameToXpaOn = 0xe,
1282 .thresh62 = 28,
1283 .papdRateMaskHt20 = LE32(0x0c80c080),
1284 .papdRateMaskHt40 = LE32(0x0080c080),
1285 .xlna_bias_strength = 0,
1286 .futureModal = {
1287 0, 0, 0, 0, 0, 0, 0,
1290 .base_ext1 = {
1291 .ant_div_control = 0,
1292 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1294 .calFreqPier2G = {
1295 FREQ2FBIN(2412, 1),
1296 FREQ2FBIN(2437, 1),
1297 FREQ2FBIN(2462, 1),
1299 /* ar9300_cal_data_per_freq_op_loop 2g */
1300 .calPierData2G = {
1301 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1302 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1303 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1305 .calTarget_freqbin_Cck = {
1306 FREQ2FBIN(2412, 1),
1307 FREQ2FBIN(2472, 1),
1309 .calTarget_freqbin_2G = {
1310 FREQ2FBIN(2412, 1),
1311 FREQ2FBIN(2437, 1),
1312 FREQ2FBIN(2472, 1)
1314 .calTarget_freqbin_2GHT20 = {
1315 FREQ2FBIN(2412, 1),
1316 FREQ2FBIN(2437, 1),
1317 FREQ2FBIN(2472, 1)
1319 .calTarget_freqbin_2GHT40 = {
1320 FREQ2FBIN(2412, 1),
1321 FREQ2FBIN(2437, 1),
1322 FREQ2FBIN(2472, 1)
1324 .calTargetPowerCck = {
1325 /* 1L-5L,5S,11L,11S */
1326 { {34, 34, 34, 34} },
1327 { {34, 34, 34, 34} },
1329 .calTargetPower2G = {
1330 /* 6-24,36,48,54 */
1331 { {34, 34, 32, 32} },
1332 { {34, 34, 32, 32} },
1333 { {34, 34, 32, 32} },
1335 .calTargetPower2GHT20 = {
1336 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1337 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1338 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1340 .calTargetPower2GHT40 = {
1341 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1342 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1343 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1345 .ctlIndex_2G = {
1346 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1347 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1349 .ctl_freqbin_2G = {
1351 FREQ2FBIN(2412, 1),
1352 FREQ2FBIN(2417, 1),
1353 FREQ2FBIN(2457, 1),
1354 FREQ2FBIN(2462, 1)
1357 FREQ2FBIN(2412, 1),
1358 FREQ2FBIN(2417, 1),
1359 FREQ2FBIN(2462, 1),
1360 0xFF,
1364 FREQ2FBIN(2412, 1),
1365 FREQ2FBIN(2417, 1),
1366 FREQ2FBIN(2462, 1),
1367 0xFF,
1370 FREQ2FBIN(2422, 1),
1371 FREQ2FBIN(2427, 1),
1372 FREQ2FBIN(2447, 1),
1373 FREQ2FBIN(2452, 1)
1377 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1378 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1379 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1380 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1384 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1385 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1386 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1391 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1392 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1393 FREQ2FBIN(2472, 1),
1398 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1399 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1400 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1401 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1405 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1406 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1407 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1411 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1412 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1413 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1418 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1419 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1420 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1425 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1426 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1427 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1428 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1431 .ctlPowerData_2G = {
1432 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1433 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1434 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1436 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
1437 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1438 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1440 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1441 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1442 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1444 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1445 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1446 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1448 .modalHeader5G = {
1449 /* 4 idle,t1,t2,b (4 bits per setting) */
1450 .antCtrlCommon = LE32(0x220),
1451 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1452 .antCtrlCommon2 = LE32(0x44444),
1453 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1454 .antCtrlChain = {
1455 LE16(0x150), LE16(0x150), LE16(0x150),
1457 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1458 .xatten1DB = {0, 0, 0},
1461 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1462 * for merlin (0xa20c/b20c 16:12
1464 .xatten1Margin = {0, 0, 0},
1465 .tempSlope = 45,
1466 .voltSlope = 0,
1467 /* spurChans spur channels in usual fbin coding format */
1468 .spurChans = {0, 0, 0, 0, 0},
1469 /* noiseFloorThreshCh Check if the register is per chain */
1470 .noiseFloorThreshCh = {-1, 0, 0},
1471 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1472 .quick_drop = 0,
1473 .xpaBiasLvl = 0,
1474 .txFrameToDataStart = 0x0e,
1475 .txFrameToPaOn = 0x0e,
1476 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1477 .antennaGain = 0,
1478 .switchSettling = 0x2d,
1479 .adcDesiredSize = -30,
1480 .txEndToXpaOff = 0,
1481 .txEndToRxOn = 0x2,
1482 .txFrameToXpaOn = 0xe,
1483 .thresh62 = 28,
1484 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1485 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1486 .xlna_bias_strength = 0,
1487 .futureModal = {
1488 0, 0, 0, 0, 0, 0, 0,
1491 .base_ext2 = {
1492 .tempSlopeLow = 40,
1493 .tempSlopeHigh = 50,
1494 .xatten1DBLow = {0, 0, 0},
1495 .xatten1MarginLow = {0, 0, 0},
1496 .xatten1DBHigh = {0, 0, 0},
1497 .xatten1MarginHigh = {0, 0, 0}
1499 .calFreqPier5G = {
1500 FREQ2FBIN(5180, 0),
1501 FREQ2FBIN(5220, 0),
1502 FREQ2FBIN(5320, 0),
1503 FREQ2FBIN(5400, 0),
1504 FREQ2FBIN(5500, 0),
1505 FREQ2FBIN(5600, 0),
1506 FREQ2FBIN(5700, 0),
1507 FREQ2FBIN(5785, 0)
1509 .calPierData5G = {
1511 {0, 0, 0, 0, 0},
1512 {0, 0, 0, 0, 0},
1513 {0, 0, 0, 0, 0},
1514 {0, 0, 0, 0, 0},
1515 {0, 0, 0, 0, 0},
1516 {0, 0, 0, 0, 0},
1517 {0, 0, 0, 0, 0},
1518 {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},
1528 {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},
1538 {0, 0, 0, 0, 0},
1542 .calTarget_freqbin_5G = {
1543 FREQ2FBIN(5180, 0),
1544 FREQ2FBIN(5240, 0),
1545 FREQ2FBIN(5320, 0),
1546 FREQ2FBIN(5400, 0),
1547 FREQ2FBIN(5500, 0),
1548 FREQ2FBIN(5600, 0),
1549 FREQ2FBIN(5700, 0),
1550 FREQ2FBIN(5825, 0)
1552 .calTarget_freqbin_5GHT20 = {
1553 FREQ2FBIN(5180, 0),
1554 FREQ2FBIN(5240, 0),
1555 FREQ2FBIN(5320, 0),
1556 FREQ2FBIN(5400, 0),
1557 FREQ2FBIN(5500, 0),
1558 FREQ2FBIN(5700, 0),
1559 FREQ2FBIN(5745, 0),
1560 FREQ2FBIN(5825, 0)
1562 .calTarget_freqbin_5GHT40 = {
1563 FREQ2FBIN(5180, 0),
1564 FREQ2FBIN(5240, 0),
1565 FREQ2FBIN(5320, 0),
1566 FREQ2FBIN(5400, 0),
1567 FREQ2FBIN(5500, 0),
1568 FREQ2FBIN(5700, 0),
1569 FREQ2FBIN(5745, 0),
1570 FREQ2FBIN(5825, 0)
1572 .calTargetPower5G = {
1573 /* 6-24,36,48,54 */
1574 { {30, 30, 28, 24} },
1575 { {30, 30, 28, 24} },
1576 { {30, 30, 28, 24} },
1577 { {30, 30, 28, 24} },
1578 { {30, 30, 28, 24} },
1579 { {30, 30, 28, 24} },
1580 { {30, 30, 28, 24} },
1581 { {30, 30, 28, 24} },
1583 .calTargetPower5GHT20 = {
1585 * 0_8_16,1-3_9-11_17-19,
1586 * 4,5,6,7,12,13,14,15,20,21,22,23
1588 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1589 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1590 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1591 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1592 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1593 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1594 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1595 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1597 .calTargetPower5GHT40 = {
1599 * 0_8_16,1-3_9-11_17-19,
1600 * 4,5,6,7,12,13,14,15,20,21,22,23
1602 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1603 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1604 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1605 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1606 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1607 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1608 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1609 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1611 .ctlIndex_5G = {
1612 0x10, 0x16, 0x18, 0x40, 0x46,
1613 0x48, 0x30, 0x36, 0x38
1615 .ctl_freqbin_5G = {
1617 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1618 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1619 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1620 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1621 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1622 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1623 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1624 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1627 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1628 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1629 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1630 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1631 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1632 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1633 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1634 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1638 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1639 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1640 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1641 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1642 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1643 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1644 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1645 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1649 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1650 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1651 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1652 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1653 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1654 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1655 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1656 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1660 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1661 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1662 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1663 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1664 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1665 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1666 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1667 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1671 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1672 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1673 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1674 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1675 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1676 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1677 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1678 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1682 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1683 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1684 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1685 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1686 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1687 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1688 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1689 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1693 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1694 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1695 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1696 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1697 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1698 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1699 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1700 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1704 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1705 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1706 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1707 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1708 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1709 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1710 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1711 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1714 .ctlPowerData_5G = {
1717 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1718 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1723 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1724 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1729 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1730 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1735 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1736 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1741 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1742 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1747 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1748 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1753 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1754 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1759 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1760 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1765 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1766 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1773 static const struct ar9300_eeprom ar9300_x112 = {
1774 .eepromVersion = 2,
1775 .templateVersion = 5,
1776 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1777 .custData = {"x112-041-f0000"},
1778 .baseEepHeader = {
1779 .regDmn = { LE16(0), LE16(0x1f) },
1780 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1781 .opCapFlags = {
1782 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1783 .eepMisc = 0,
1785 .rfSilent = 0,
1786 .blueToothOptions = 0,
1787 .deviceCap = 0,
1788 .deviceType = 5, /* takes lower byte in eeprom location */
1789 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1790 .params_for_tuning_caps = {0, 0},
1791 .featureEnable = 0x0d,
1793 * bit0 - enable tx temp comp - disabled
1794 * bit1 - enable tx volt comp - disabled
1795 * bit2 - enable fastclock - enabled
1796 * bit3 - enable doubling - enabled
1797 * bit4 - enable internal regulator - disabled
1798 * bit5 - enable pa predistortion - disabled
1800 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1801 .eepromWriteEnableGpio = 6,
1802 .wlanDisableGpio = 0,
1803 .wlanLedGpio = 8,
1804 .rxBandSelectGpio = 0xff,
1805 .txrxgain = 0x0,
1806 .swreg = 0,
1808 .modalHeader2G = {
1809 /* ar9300_modal_eep_header 2g */
1810 /* 4 idle,t1,t2,b(4 bits per setting) */
1811 .antCtrlCommon = LE32(0x110),
1812 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1813 .antCtrlCommon2 = LE32(0x22222),
1816 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1817 * rx1, rx12, b (2 bits each)
1819 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1822 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1823 * for ar9280 (0xa20c/b20c 5:0)
1825 .xatten1DB = {0x1b, 0x1b, 0x1b},
1828 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1829 * for ar9280 (0xa20c/b20c 16:12
1831 .xatten1Margin = {0x15, 0x15, 0x15},
1832 .tempSlope = 50,
1833 .voltSlope = 0,
1836 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1837 * channels in usual fbin coding format
1839 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1842 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1843 * if the register is per chain
1845 .noiseFloorThreshCh = {-1, 0, 0},
1846 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1847 .quick_drop = 0,
1848 .xpaBiasLvl = 0,
1849 .txFrameToDataStart = 0x0e,
1850 .txFrameToPaOn = 0x0e,
1851 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1852 .antennaGain = 0,
1853 .switchSettling = 0x2c,
1854 .adcDesiredSize = -30,
1855 .txEndToXpaOff = 0,
1856 .txEndToRxOn = 0x2,
1857 .txFrameToXpaOn = 0xe,
1858 .thresh62 = 28,
1859 .papdRateMaskHt20 = LE32(0x0c80c080),
1860 .papdRateMaskHt40 = LE32(0x0080c080),
1861 .xlna_bias_strength = 0,
1862 .futureModal = {
1863 0, 0, 0, 0, 0, 0, 0,
1866 .base_ext1 = {
1867 .ant_div_control = 0,
1868 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1870 .calFreqPier2G = {
1871 FREQ2FBIN(2412, 1),
1872 FREQ2FBIN(2437, 1),
1873 FREQ2FBIN(2472, 1),
1875 /* ar9300_cal_data_per_freq_op_loop 2g */
1876 .calPierData2G = {
1877 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1878 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1879 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1881 .calTarget_freqbin_Cck = {
1882 FREQ2FBIN(2412, 1),
1883 FREQ2FBIN(2472, 1),
1885 .calTarget_freqbin_2G = {
1886 FREQ2FBIN(2412, 1),
1887 FREQ2FBIN(2437, 1),
1888 FREQ2FBIN(2472, 1)
1890 .calTarget_freqbin_2GHT20 = {
1891 FREQ2FBIN(2412, 1),
1892 FREQ2FBIN(2437, 1),
1893 FREQ2FBIN(2472, 1)
1895 .calTarget_freqbin_2GHT40 = {
1896 FREQ2FBIN(2412, 1),
1897 FREQ2FBIN(2437, 1),
1898 FREQ2FBIN(2472, 1)
1900 .calTargetPowerCck = {
1901 /* 1L-5L,5S,11L,11s */
1902 { {38, 38, 38, 38} },
1903 { {38, 38, 38, 38} },
1905 .calTargetPower2G = {
1906 /* 6-24,36,48,54 */
1907 { {38, 38, 36, 34} },
1908 { {38, 38, 36, 34} },
1909 { {38, 38, 34, 32} },
1911 .calTargetPower2GHT20 = {
1912 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1913 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1914 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1916 .calTargetPower2GHT40 = {
1917 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1918 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1919 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1921 .ctlIndex_2G = {
1922 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1923 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1925 .ctl_freqbin_2G = {
1927 FREQ2FBIN(2412, 1),
1928 FREQ2FBIN(2417, 1),
1929 FREQ2FBIN(2457, 1),
1930 FREQ2FBIN(2462, 1)
1933 FREQ2FBIN(2412, 1),
1934 FREQ2FBIN(2417, 1),
1935 FREQ2FBIN(2462, 1),
1936 0xFF,
1940 FREQ2FBIN(2412, 1),
1941 FREQ2FBIN(2417, 1),
1942 FREQ2FBIN(2462, 1),
1943 0xFF,
1946 FREQ2FBIN(2422, 1),
1947 FREQ2FBIN(2427, 1),
1948 FREQ2FBIN(2447, 1),
1949 FREQ2FBIN(2452, 1)
1953 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1954 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1955 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1956 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1960 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1961 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1962 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1967 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1968 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1969 FREQ2FBIN(2472, 1),
1974 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
1975 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
1976 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
1977 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
1981 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1982 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1983 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1987 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1988 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1989 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1994 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1995 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1996 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2001 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2002 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2003 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2004 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2007 .ctlPowerData_2G = {
2008 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2009 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2010 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2012 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2013 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2014 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2016 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2017 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2018 { { 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, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2022 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2024 .modalHeader5G = {
2025 /* 4 idle,t1,t2,b (4 bits per setting) */
2026 .antCtrlCommon = LE32(0x110),
2027 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2028 .antCtrlCommon2 = LE32(0x22222),
2029 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2030 .antCtrlChain = {
2031 LE16(0x0), LE16(0x0), LE16(0x0),
2033 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2034 .xatten1DB = {0x13, 0x19, 0x17},
2037 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2038 * for merlin (0xa20c/b20c 16:12
2040 .xatten1Margin = {0x19, 0x19, 0x19},
2041 .tempSlope = 70,
2042 .voltSlope = 15,
2043 /* spurChans spur channels in usual fbin coding format */
2044 .spurChans = {0, 0, 0, 0, 0},
2045 /* noiseFloorThreshch check if the register is per chain */
2046 .noiseFloorThreshCh = {-1, 0, 0},
2047 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2048 .quick_drop = 0,
2049 .xpaBiasLvl = 0,
2050 .txFrameToDataStart = 0x0e,
2051 .txFrameToPaOn = 0x0e,
2052 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2053 .antennaGain = 0,
2054 .switchSettling = 0x2d,
2055 .adcDesiredSize = -30,
2056 .txEndToXpaOff = 0,
2057 .txEndToRxOn = 0x2,
2058 .txFrameToXpaOn = 0xe,
2059 .thresh62 = 28,
2060 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2061 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2062 .xlna_bias_strength = 0,
2063 .futureModal = {
2064 0, 0, 0, 0, 0, 0, 0,
2067 .base_ext2 = {
2068 .tempSlopeLow = 72,
2069 .tempSlopeHigh = 105,
2070 .xatten1DBLow = {0x10, 0x14, 0x10},
2071 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2072 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2073 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2075 .calFreqPier5G = {
2076 FREQ2FBIN(5180, 0),
2077 FREQ2FBIN(5220, 0),
2078 FREQ2FBIN(5320, 0),
2079 FREQ2FBIN(5400, 0),
2080 FREQ2FBIN(5500, 0),
2081 FREQ2FBIN(5600, 0),
2082 FREQ2FBIN(5700, 0),
2083 FREQ2FBIN(5785, 0)
2085 .calPierData5G = {
2087 {0, 0, 0, 0, 0},
2088 {0, 0, 0, 0, 0},
2089 {0, 0, 0, 0, 0},
2090 {0, 0, 0, 0, 0},
2091 {0, 0, 0, 0, 0},
2092 {0, 0, 0, 0, 0},
2093 {0, 0, 0, 0, 0},
2094 {0, 0, 0, 0, 0},
2097 {0, 0, 0, 0, 0},
2098 {0, 0, 0, 0, 0},
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},
2107 {0, 0, 0, 0, 0},
2108 {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},
2118 .calTarget_freqbin_5G = {
2119 FREQ2FBIN(5180, 0),
2120 FREQ2FBIN(5220, 0),
2121 FREQ2FBIN(5320, 0),
2122 FREQ2FBIN(5400, 0),
2123 FREQ2FBIN(5500, 0),
2124 FREQ2FBIN(5600, 0),
2125 FREQ2FBIN(5725, 0),
2126 FREQ2FBIN(5825, 0)
2128 .calTarget_freqbin_5GHT20 = {
2129 FREQ2FBIN(5180, 0),
2130 FREQ2FBIN(5220, 0),
2131 FREQ2FBIN(5320, 0),
2132 FREQ2FBIN(5400, 0),
2133 FREQ2FBIN(5500, 0),
2134 FREQ2FBIN(5600, 0),
2135 FREQ2FBIN(5725, 0),
2136 FREQ2FBIN(5825, 0)
2138 .calTarget_freqbin_5GHT40 = {
2139 FREQ2FBIN(5180, 0),
2140 FREQ2FBIN(5220, 0),
2141 FREQ2FBIN(5320, 0),
2142 FREQ2FBIN(5400, 0),
2143 FREQ2FBIN(5500, 0),
2144 FREQ2FBIN(5600, 0),
2145 FREQ2FBIN(5725, 0),
2146 FREQ2FBIN(5825, 0)
2148 .calTargetPower5G = {
2149 /* 6-24,36,48,54 */
2150 { {32, 32, 28, 26} },
2151 { {32, 32, 28, 26} },
2152 { {32, 32, 28, 26} },
2153 { {32, 32, 26, 24} },
2154 { {32, 32, 26, 24} },
2155 { {32, 32, 24, 22} },
2156 { {30, 30, 24, 22} },
2157 { {30, 30, 24, 22} },
2159 .calTargetPower5GHT20 = {
2161 * 0_8_16,1-3_9-11_17-19,
2162 * 4,5,6,7,12,13,14,15,20,21,22,23
2164 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2165 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2166 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2167 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2168 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2169 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2170 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2171 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2173 .calTargetPower5GHT40 = {
2175 * 0_8_16,1-3_9-11_17-19,
2176 * 4,5,6,7,12,13,14,15,20,21,22,23
2178 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2179 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2180 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2181 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2182 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2183 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2184 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2185 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2187 .ctlIndex_5G = {
2188 0x10, 0x16, 0x18, 0x40, 0x46,
2189 0x48, 0x30, 0x36, 0x38
2191 .ctl_freqbin_5G = {
2193 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2194 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2195 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2196 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2197 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2198 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2199 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2200 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2203 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2204 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2205 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2206 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2207 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2208 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2209 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2210 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2214 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2215 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2216 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2217 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2218 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2219 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2220 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2221 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2225 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2226 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2227 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2228 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2229 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2230 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2231 /* Data[3].ctledges[6].bchannel */ 0xFF,
2232 /* Data[3].ctledges[7].bchannel */ 0xFF,
2236 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2237 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2238 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2239 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2240 /* Data[4].ctledges[4].bchannel */ 0xFF,
2241 /* Data[4].ctledges[5].bchannel */ 0xFF,
2242 /* Data[4].ctledges[6].bchannel */ 0xFF,
2243 /* Data[4].ctledges[7].bchannel */ 0xFF,
2247 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2248 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2249 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2250 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2251 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2252 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2253 /* Data[5].ctledges[6].bchannel */ 0xFF,
2254 /* Data[5].ctledges[7].bchannel */ 0xFF
2258 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2259 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2260 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2261 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2262 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2263 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2264 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2265 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2269 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2270 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2271 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2272 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2273 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2274 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2275 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2276 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2280 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2281 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2282 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2283 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2284 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2285 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2286 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2287 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2290 .ctlPowerData_5G = {
2293 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2294 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2299 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2300 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2305 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2306 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2311 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2312 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2317 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2318 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2323 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
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, 1),
2330 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2335 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2336 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2341 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2342 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2348 static const struct ar9300_eeprom ar9300_h116 = {
2349 .eepromVersion = 2,
2350 .templateVersion = 4,
2351 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2352 .custData = {"h116-041-f0000"},
2353 .baseEepHeader = {
2354 .regDmn = { LE16(0), LE16(0x1f) },
2355 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2356 .opCapFlags = {
2357 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2358 .eepMisc = 0,
2360 .rfSilent = 0,
2361 .blueToothOptions = 0,
2362 .deviceCap = 0,
2363 .deviceType = 5, /* takes lower byte in eeprom location */
2364 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2365 .params_for_tuning_caps = {0, 0},
2366 .featureEnable = 0x0d,
2368 * bit0 - enable tx temp comp - disabled
2369 * bit1 - enable tx volt comp - disabled
2370 * bit2 - enable fastClock - enabled
2371 * bit3 - enable doubling - enabled
2372 * bit4 - enable internal regulator - disabled
2373 * bit5 - enable pa predistortion - disabled
2375 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2376 .eepromWriteEnableGpio = 6,
2377 .wlanDisableGpio = 0,
2378 .wlanLedGpio = 8,
2379 .rxBandSelectGpio = 0xff,
2380 .txrxgain = 0x10,
2381 .swreg = 0,
2383 .modalHeader2G = {
2384 /* ar9300_modal_eep_header 2g */
2385 /* 4 idle,t1,t2,b(4 bits per setting) */
2386 .antCtrlCommon = LE32(0x110),
2387 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2388 .antCtrlCommon2 = LE32(0x44444),
2391 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2392 * rx1, rx12, b (2 bits each)
2394 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2397 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2398 * for ar9280 (0xa20c/b20c 5:0)
2400 .xatten1DB = {0x1f, 0x1f, 0x1f},
2403 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2404 * for ar9280 (0xa20c/b20c 16:12
2406 .xatten1Margin = {0x12, 0x12, 0x12},
2407 .tempSlope = 25,
2408 .voltSlope = 0,
2411 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2412 * channels in usual fbin coding format
2414 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2417 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2418 * if the register is per chain
2420 .noiseFloorThreshCh = {-1, 0, 0},
2421 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2422 .quick_drop = 0,
2423 .xpaBiasLvl = 0,
2424 .txFrameToDataStart = 0x0e,
2425 .txFrameToPaOn = 0x0e,
2426 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2427 .antennaGain = 0,
2428 .switchSettling = 0x2c,
2429 .adcDesiredSize = -30,
2430 .txEndToXpaOff = 0,
2431 .txEndToRxOn = 0x2,
2432 .txFrameToXpaOn = 0xe,
2433 .thresh62 = 28,
2434 .papdRateMaskHt20 = LE32(0x0c80C080),
2435 .papdRateMaskHt40 = LE32(0x0080C080),
2436 .xlna_bias_strength = 0,
2437 .futureModal = {
2438 0, 0, 0, 0, 0, 0, 0,
2441 .base_ext1 = {
2442 .ant_div_control = 0,
2443 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2445 .calFreqPier2G = {
2446 FREQ2FBIN(2412, 1),
2447 FREQ2FBIN(2437, 1),
2448 FREQ2FBIN(2462, 1),
2450 /* ar9300_cal_data_per_freq_op_loop 2g */
2451 .calPierData2G = {
2452 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2453 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2454 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2456 .calTarget_freqbin_Cck = {
2457 FREQ2FBIN(2412, 1),
2458 FREQ2FBIN(2472, 1),
2460 .calTarget_freqbin_2G = {
2461 FREQ2FBIN(2412, 1),
2462 FREQ2FBIN(2437, 1),
2463 FREQ2FBIN(2472, 1)
2465 .calTarget_freqbin_2GHT20 = {
2466 FREQ2FBIN(2412, 1),
2467 FREQ2FBIN(2437, 1),
2468 FREQ2FBIN(2472, 1)
2470 .calTarget_freqbin_2GHT40 = {
2471 FREQ2FBIN(2412, 1),
2472 FREQ2FBIN(2437, 1),
2473 FREQ2FBIN(2472, 1)
2475 .calTargetPowerCck = {
2476 /* 1L-5L,5S,11L,11S */
2477 { {34, 34, 34, 34} },
2478 { {34, 34, 34, 34} },
2480 .calTargetPower2G = {
2481 /* 6-24,36,48,54 */
2482 { {34, 34, 32, 32} },
2483 { {34, 34, 32, 32} },
2484 { {34, 34, 32, 32} },
2486 .calTargetPower2GHT20 = {
2487 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2488 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2489 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2491 .calTargetPower2GHT40 = {
2492 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2493 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2494 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2496 .ctlIndex_2G = {
2497 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2498 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2500 .ctl_freqbin_2G = {
2502 FREQ2FBIN(2412, 1),
2503 FREQ2FBIN(2417, 1),
2504 FREQ2FBIN(2457, 1),
2505 FREQ2FBIN(2462, 1)
2508 FREQ2FBIN(2412, 1),
2509 FREQ2FBIN(2417, 1),
2510 FREQ2FBIN(2462, 1),
2511 0xFF,
2515 FREQ2FBIN(2412, 1),
2516 FREQ2FBIN(2417, 1),
2517 FREQ2FBIN(2462, 1),
2518 0xFF,
2521 FREQ2FBIN(2422, 1),
2522 FREQ2FBIN(2427, 1),
2523 FREQ2FBIN(2447, 1),
2524 FREQ2FBIN(2452, 1)
2528 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2529 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2530 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2531 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2535 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2536 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2537 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2542 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2543 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2544 FREQ2FBIN(2472, 1),
2549 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2550 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2551 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2552 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2556 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2557 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2558 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2562 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2563 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2564 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2569 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2570 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2571 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2576 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2577 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2578 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2579 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2582 .ctlPowerData_2G = {
2583 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2584 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2585 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2587 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2588 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2589 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2591 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2592 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2593 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2595 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2596 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2597 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2599 .modalHeader5G = {
2600 /* 4 idle,t1,t2,b (4 bits per setting) */
2601 .antCtrlCommon = LE32(0x220),
2602 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2603 .antCtrlCommon2 = LE32(0x44444),
2604 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2605 .antCtrlChain = {
2606 LE16(0x150), LE16(0x150), LE16(0x150),
2608 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2609 .xatten1DB = {0x19, 0x19, 0x19},
2612 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2613 * for merlin (0xa20c/b20c 16:12
2615 .xatten1Margin = {0x14, 0x14, 0x14},
2616 .tempSlope = 70,
2617 .voltSlope = 0,
2618 /* spurChans spur channels in usual fbin coding format */
2619 .spurChans = {0, 0, 0, 0, 0},
2620 /* noiseFloorThreshCh Check if the register is per chain */
2621 .noiseFloorThreshCh = {-1, 0, 0},
2622 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2623 .quick_drop = 0,
2624 .xpaBiasLvl = 0,
2625 .txFrameToDataStart = 0x0e,
2626 .txFrameToPaOn = 0x0e,
2627 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2628 .antennaGain = 0,
2629 .switchSettling = 0x2d,
2630 .adcDesiredSize = -30,
2631 .txEndToXpaOff = 0,
2632 .txEndToRxOn = 0x2,
2633 .txFrameToXpaOn = 0xe,
2634 .thresh62 = 28,
2635 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2636 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2637 .xlna_bias_strength = 0,
2638 .futureModal = {
2639 0, 0, 0, 0, 0, 0, 0,
2642 .base_ext2 = {
2643 .tempSlopeLow = 35,
2644 .tempSlopeHigh = 50,
2645 .xatten1DBLow = {0, 0, 0},
2646 .xatten1MarginLow = {0, 0, 0},
2647 .xatten1DBHigh = {0, 0, 0},
2648 .xatten1MarginHigh = {0, 0, 0}
2650 .calFreqPier5G = {
2651 FREQ2FBIN(5160, 0),
2652 FREQ2FBIN(5220, 0),
2653 FREQ2FBIN(5320, 0),
2654 FREQ2FBIN(5400, 0),
2655 FREQ2FBIN(5500, 0),
2656 FREQ2FBIN(5600, 0),
2657 FREQ2FBIN(5700, 0),
2658 FREQ2FBIN(5785, 0)
2660 .calPierData5G = {
2662 {0, 0, 0, 0, 0},
2663 {0, 0, 0, 0, 0},
2664 {0, 0, 0, 0, 0},
2665 {0, 0, 0, 0, 0},
2666 {0, 0, 0, 0, 0},
2667 {0, 0, 0, 0, 0},
2668 {0, 0, 0, 0, 0},
2669 {0, 0, 0, 0, 0},
2672 {0, 0, 0, 0, 0},
2673 {0, 0, 0, 0, 0},
2674 {0, 0, 0, 0, 0},
2675 {0, 0, 0, 0, 0},
2676 {0, 0, 0, 0, 0},
2677 {0, 0, 0, 0, 0},
2678 {0, 0, 0, 0, 0},
2679 {0, 0, 0, 0, 0},
2682 {0, 0, 0, 0, 0},
2683 {0, 0, 0, 0, 0},
2684 {0, 0, 0, 0, 0},
2685 {0, 0, 0, 0, 0},
2686 {0, 0, 0, 0, 0},
2687 {0, 0, 0, 0, 0},
2688 {0, 0, 0, 0, 0},
2689 {0, 0, 0, 0, 0},
2693 .calTarget_freqbin_5G = {
2694 FREQ2FBIN(5180, 0),
2695 FREQ2FBIN(5240, 0),
2696 FREQ2FBIN(5320, 0),
2697 FREQ2FBIN(5400, 0),
2698 FREQ2FBIN(5500, 0),
2699 FREQ2FBIN(5600, 0),
2700 FREQ2FBIN(5700, 0),
2701 FREQ2FBIN(5825, 0)
2703 .calTarget_freqbin_5GHT20 = {
2704 FREQ2FBIN(5180, 0),
2705 FREQ2FBIN(5240, 0),
2706 FREQ2FBIN(5320, 0),
2707 FREQ2FBIN(5400, 0),
2708 FREQ2FBIN(5500, 0),
2709 FREQ2FBIN(5700, 0),
2710 FREQ2FBIN(5745, 0),
2711 FREQ2FBIN(5825, 0)
2713 .calTarget_freqbin_5GHT40 = {
2714 FREQ2FBIN(5180, 0),
2715 FREQ2FBIN(5240, 0),
2716 FREQ2FBIN(5320, 0),
2717 FREQ2FBIN(5400, 0),
2718 FREQ2FBIN(5500, 0),
2719 FREQ2FBIN(5700, 0),
2720 FREQ2FBIN(5745, 0),
2721 FREQ2FBIN(5825, 0)
2723 .calTargetPower5G = {
2724 /* 6-24,36,48,54 */
2725 { {30, 30, 28, 24} },
2726 { {30, 30, 28, 24} },
2727 { {30, 30, 28, 24} },
2728 { {30, 30, 28, 24} },
2729 { {30, 30, 28, 24} },
2730 { {30, 30, 28, 24} },
2731 { {30, 30, 28, 24} },
2732 { {30, 30, 28, 24} },
2734 .calTargetPower5GHT20 = {
2736 * 0_8_16,1-3_9-11_17-19,
2737 * 4,5,6,7,12,13,14,15,20,21,22,23
2739 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2740 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2741 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2742 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2743 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2744 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2745 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2746 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2748 .calTargetPower5GHT40 = {
2750 * 0_8_16,1-3_9-11_17-19,
2751 * 4,5,6,7,12,13,14,15,20,21,22,23
2753 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2754 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2755 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2756 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2757 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2758 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2759 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2760 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2762 .ctlIndex_5G = {
2763 0x10, 0x16, 0x18, 0x40, 0x46,
2764 0x48, 0x30, 0x36, 0x38
2766 .ctl_freqbin_5G = {
2768 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2769 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2770 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2771 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2772 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2773 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2774 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2775 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2778 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2779 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2780 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2781 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2782 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2783 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2784 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2785 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2789 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2790 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2791 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2792 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2793 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2794 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2795 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2796 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2800 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2801 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2802 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2803 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2804 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2805 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2806 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2807 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2811 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2812 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2813 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2814 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2815 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2816 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2817 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2818 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2822 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2823 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2824 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2825 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2826 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2827 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2828 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2829 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2833 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2834 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2835 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2836 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2837 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2838 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2839 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2840 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2844 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2845 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2846 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2847 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2848 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2849 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2850 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2851 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2855 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2856 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2857 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2858 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2859 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2860 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2861 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2862 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2865 .ctlPowerData_5G = {
2868 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2869 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2874 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2875 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2880 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2881 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2886 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2887 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2892 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2893 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2898 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2899 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2904 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2905 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2910 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2911 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2916 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2917 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2924 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2925 &ar9300_default,
2926 &ar9300_x112,
2927 &ar9300_h116,
2928 &ar9300_h112,
2929 &ar9300_x113,
2932 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2934 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2935 int it;
2937 for (it = 0; it < N_LOOP; it++)
2938 if (ar9300_eep_templates[it]->templateVersion == id)
2939 return ar9300_eep_templates[it];
2940 return NULL;
2941 #undef N_LOOP
2944 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2946 return 0;
2949 static int interpolate(int x, int xa, int xb, int ya, int yb)
2951 int bf, factor, plus;
2953 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2954 factor = bf / 2;
2955 plus = bf % 2;
2956 return ya + factor + plus;
2959 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2960 enum eeprom_param param)
2962 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2963 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
2965 switch (param) {
2966 case EEP_MAC_LSW:
2967 return get_unaligned_be16(eep->macAddr);
2968 case EEP_MAC_MID:
2969 return get_unaligned_be16(eep->macAddr + 2);
2970 case EEP_MAC_MSW:
2971 return get_unaligned_be16(eep->macAddr + 4);
2972 case EEP_REG_0:
2973 return le16_to_cpu(pBase->regDmn[0]);
2974 case EEP_OP_CAP:
2975 return pBase->deviceCap;
2976 case EEP_OP_MODE:
2977 return pBase->opCapFlags.opFlags;
2978 case EEP_RF_SILENT:
2979 return pBase->rfSilent;
2980 case EEP_TX_MASK:
2981 return (pBase->txrxMask >> 4) & 0xf;
2982 case EEP_RX_MASK:
2983 return pBase->txrxMask & 0xf;
2984 case EEP_PAPRD:
2985 if (AR_SREV_9462(ah))
2986 return false;
2987 if (!ah->config.enable_paprd);
2988 return false;
2989 return !!(pBase->featureEnable & BIT(5));
2990 case EEP_CHAIN_MASK_REDUCE:
2991 return (pBase->miscConfiguration >> 0x3) & 0x1;
2992 case EEP_ANT_DIV_CTL1:
2993 return eep->base_ext1.ant_div_control;
2994 case EEP_ANTENNA_GAIN_5G:
2995 return eep->modalHeader5G.antennaGain;
2996 case EEP_ANTENNA_GAIN_2G:
2997 return eep->modalHeader2G.antennaGain;
2998 default:
2999 return 0;
3003 static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
3004 u8 *buffer)
3006 u16 val;
3008 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3009 return false;
3011 *buffer = (val >> (8 * (address % 2))) & 0xff;
3012 return true;
3015 static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
3016 u8 *buffer)
3018 u16 val;
3020 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3021 return false;
3023 buffer[0] = val >> 8;
3024 buffer[1] = val & 0xff;
3026 return true;
3029 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3030 int count)
3032 struct ath_common *common = ath9k_hw_common(ah);
3033 int i;
3035 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3036 ath_dbg(common, EEPROM, "eeprom address not in range\n");
3037 return false;
3041 * Since we're reading the bytes in reverse order from a little-endian
3042 * word stream, an even address means we only use the lower half of
3043 * the 16-bit word at that address
3045 if (address % 2 == 0) {
3046 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
3047 goto error;
3049 count--;
3052 for (i = 0; i < count / 2; i++) {
3053 if (!ar9300_eeprom_read_word(common, address, buffer))
3054 goto error;
3056 address -= 2;
3057 buffer += 2;
3060 if (count % 2)
3061 if (!ar9300_eeprom_read_byte(common, address, buffer))
3062 goto error;
3064 return true;
3066 error:
3067 ath_dbg(common, EEPROM, "unable to read eeprom region at offset %d\n",
3068 address);
3069 return false;
3072 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3074 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3076 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3077 AR9300_OTP_STATUS_VALID, 1000))
3078 return false;
3080 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3081 return true;
3084 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3085 int count)
3087 u32 data;
3088 int i;
3090 for (i = 0; i < count; i++) {
3091 int offset = 8 * ((address - i) % 4);
3092 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3093 return false;
3095 buffer[i] = (data >> offset) & 0xff;
3098 return true;
3102 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3103 int *length, int *major, int *minor)
3105 unsigned long value[4];
3107 value[0] = best[0];
3108 value[1] = best[1];
3109 value[2] = best[2];
3110 value[3] = best[3];
3111 *code = ((value[0] >> 5) & 0x0007);
3112 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3113 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3114 *major = (value[2] & 0x000f);
3115 *minor = (value[3] & 0x00ff);
3118 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3120 int it, checksum = 0;
3122 for (it = 0; it < dsize; it++) {
3123 checksum += data[it];
3124 checksum &= 0xffff;
3127 return checksum;
3130 static bool ar9300_uncompress_block(struct ath_hw *ah,
3131 u8 *mptr,
3132 int mdataSize,
3133 u8 *block,
3134 int size)
3136 int it;
3137 int spot;
3138 int offset;
3139 int length;
3140 struct ath_common *common = ath9k_hw_common(ah);
3142 spot = 0;
3144 for (it = 0; it < size; it += (length+2)) {
3145 offset = block[it];
3146 offset &= 0xff;
3147 spot += offset;
3148 length = block[it+1];
3149 length &= 0xff;
3151 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3152 ath_dbg(common, EEPROM,
3153 "Restore at %d: spot=%d offset=%d length=%d\n",
3154 it, spot, offset, length);
3155 memcpy(&mptr[spot], &block[it+2], length);
3156 spot += length;
3157 } else if (length > 0) {
3158 ath_dbg(common, EEPROM,
3159 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3160 it, spot, offset, length);
3161 return false;
3164 return true;
3167 static int ar9300_compress_decision(struct ath_hw *ah,
3168 int it,
3169 int code,
3170 int reference,
3171 u8 *mptr,
3172 u8 *word, int length, int mdata_size)
3174 struct ath_common *common = ath9k_hw_common(ah);
3175 const struct ar9300_eeprom *eep = NULL;
3177 switch (code) {
3178 case _CompressNone:
3179 if (length != mdata_size) {
3180 ath_dbg(common, EEPROM,
3181 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3182 mdata_size, length);
3183 return -1;
3185 memcpy(mptr, word + COMP_HDR_LEN, length);
3186 ath_dbg(common, EEPROM,
3187 "restored eeprom %d: uncompressed, length %d\n",
3188 it, length);
3189 break;
3190 case _CompressBlock:
3191 if (reference == 0) {
3192 } else {
3193 eep = ar9003_eeprom_struct_find_by_id(reference);
3194 if (eep == NULL) {
3195 ath_dbg(common, EEPROM,
3196 "can't find reference eeprom struct %d\n",
3197 reference);
3198 return -1;
3200 memcpy(mptr, eep, mdata_size);
3202 ath_dbg(common, EEPROM,
3203 "restore eeprom %d: block, reference %d, length %d\n",
3204 it, reference, length);
3205 ar9300_uncompress_block(ah, mptr, mdata_size,
3206 (word + COMP_HDR_LEN), length);
3207 break;
3208 default:
3209 ath_dbg(common, EEPROM, "unknown compression code %d\n", code);
3210 return -1;
3212 return 0;
3215 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3216 int count);
3218 static bool ar9300_check_header(void *data)
3220 u32 *word = data;
3221 return !(*word == 0 || *word == ~0);
3224 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3225 int base_addr)
3227 u8 header[4];
3229 if (!read(ah, base_addr, header, 4))
3230 return false;
3232 return ar9300_check_header(header);
3235 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3236 int mdata_size)
3238 struct ath_common *common = ath9k_hw_common(ah);
3239 u16 *data = (u16 *) mptr;
3240 int i;
3242 for (i = 0; i < mdata_size / 2; i++, data++)
3243 ath9k_hw_nvram_read(common, i, data);
3245 return 0;
3248 * Read the configuration data from the eeprom.
3249 * The data can be put in any specified memory buffer.
3251 * Returns -1 on error.
3252 * Returns address of next memory location on success.
3254 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3255 u8 *mptr, int mdata_size)
3257 #define MDEFAULT 15
3258 #define MSTATE 100
3259 int cptr;
3260 u8 *word;
3261 int code;
3262 int reference, length, major, minor;
3263 int osize;
3264 int it;
3265 u16 checksum, mchecksum;
3266 struct ath_common *common = ath9k_hw_common(ah);
3267 struct ar9300_eeprom *eep;
3268 eeprom_read_op read;
3270 if (ath9k_hw_use_flash(ah)) {
3271 u8 txrx;
3273 ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3275 /* check if eeprom contains valid data */
3276 eep = (struct ar9300_eeprom *) mptr;
3277 txrx = eep->baseEepHeader.txrxMask;
3278 if (txrx != 0 && txrx != 0xff)
3279 return 0;
3282 word = kzalloc(2048, GFP_KERNEL);
3283 if (!word)
3284 return -ENOMEM;
3286 memcpy(mptr, &ar9300_default, mdata_size);
3288 read = ar9300_read_eeprom;
3289 if (AR_SREV_9485(ah))
3290 cptr = AR9300_BASE_ADDR_4K;
3291 else if (AR_SREV_9330(ah))
3292 cptr = AR9300_BASE_ADDR_512;
3293 else
3294 cptr = AR9300_BASE_ADDR;
3295 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3296 cptr);
3297 if (ar9300_check_eeprom_header(ah, read, cptr))
3298 goto found;
3300 cptr = AR9300_BASE_ADDR_512;
3301 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3302 cptr);
3303 if (ar9300_check_eeprom_header(ah, read, cptr))
3304 goto found;
3306 read = ar9300_read_otp;
3307 cptr = AR9300_BASE_ADDR;
3308 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3309 if (ar9300_check_eeprom_header(ah, read, cptr))
3310 goto found;
3312 cptr = AR9300_BASE_ADDR_512;
3313 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3314 if (ar9300_check_eeprom_header(ah, read, cptr))
3315 goto found;
3317 goto fail;
3319 found:
3320 ath_dbg(common, EEPROM, "Found valid EEPROM data\n");
3322 for (it = 0; it < MSTATE; it++) {
3323 if (!read(ah, cptr, word, COMP_HDR_LEN))
3324 goto fail;
3326 if (!ar9300_check_header(word))
3327 break;
3329 ar9300_comp_hdr_unpack(word, &code, &reference,
3330 &length, &major, &minor);
3331 ath_dbg(common, EEPROM,
3332 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3333 cptr, code, reference, length, major, minor);
3334 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3335 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3336 ath_dbg(common, EEPROM, "Skipping bad header\n");
3337 cptr -= COMP_HDR_LEN;
3338 continue;
3341 osize = length;
3342 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3343 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3344 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3345 ath_dbg(common, EEPROM, "checksum %x %x\n",
3346 checksum, mchecksum);
3347 if (checksum == mchecksum) {
3348 ar9300_compress_decision(ah, it, code, reference, mptr,
3349 word, length, mdata_size);
3350 } else {
3351 ath_dbg(common, EEPROM,
3352 "skipping block with bad checksum\n");
3354 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3357 kfree(word);
3358 return cptr;
3360 fail:
3361 kfree(word);
3362 return -1;
3366 * Restore the configuration structure by reading the eeprom.
3367 * This function destroys any existing in-memory structure
3368 * content.
3370 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3372 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3374 if (ar9300_eeprom_restore_internal(ah, mptr,
3375 sizeof(struct ar9300_eeprom)) < 0)
3376 return false;
3378 return true;
3381 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3382 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3383 struct ar9300_modal_eep_header *modal_hdr)
3385 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3386 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3387 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3388 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3389 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3390 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3391 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3392 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3393 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3394 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3395 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3396 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3397 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3398 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3399 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3400 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3401 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3402 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3403 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3404 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3405 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3406 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3407 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3408 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3409 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3410 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3411 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3412 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3413 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3414 PR_EEP("txClip", modal_hdr->txClip);
3415 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3417 return len;
3420 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3421 u8 *buf, u32 len, u32 size)
3423 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3424 struct ar9300_base_eep_hdr *pBase;
3426 if (!dump_base_hdr) {
3427 len += snprintf(buf + len, size - len,
3428 "%20s :\n", "2GHz modal Header");
3429 len = ar9003_dump_modal_eeprom(buf, len, size,
3430 &eep->modalHeader2G);
3431 len += snprintf(buf + len, size - len,
3432 "%20s :\n", "5GHz modal Header");
3433 len = ar9003_dump_modal_eeprom(buf, len, size,
3434 &eep->modalHeader5G);
3435 goto out;
3438 pBase = &eep->baseEepHeader;
3440 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3441 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3442 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3443 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3444 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3445 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3446 AR5416_OPFLAGS_11A));
3447 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3448 AR5416_OPFLAGS_11G));
3449 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3450 AR5416_OPFLAGS_N_2G_HT20));
3451 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3452 AR5416_OPFLAGS_N_2G_HT40));
3453 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3454 AR5416_OPFLAGS_N_5G_HT20));
3455 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3456 AR5416_OPFLAGS_N_5G_HT40));
3457 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3458 PR_EEP("RF Silent", pBase->rfSilent);
3459 PR_EEP("BT option", pBase->blueToothOptions);
3460 PR_EEP("Device Cap", pBase->deviceCap);
3461 PR_EEP("Device Type", pBase->deviceType);
3462 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3463 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3464 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3465 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3466 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3467 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3468 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3469 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3470 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3471 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3472 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3473 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3474 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3475 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3476 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3477 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3478 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3479 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3480 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3482 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3483 ah->eeprom.ar9300_eep.macAddr);
3484 out:
3485 if (len > size)
3486 len = size;
3488 return len;
3490 #else
3491 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3492 u8 *buf, u32 len, u32 size)
3494 return 0;
3496 #endif
3498 /* XXX: review hardware docs */
3499 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3501 return ah->eeprom.ar9300_eep.eepromVersion;
3504 /* XXX: could be read from the eepromVersion, not sure yet */
3505 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3507 return 0;
3510 static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
3511 bool is2ghz)
3513 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3515 if (is2ghz)
3516 return &eep->modalHeader2G;
3517 else
3518 return &eep->modalHeader5G;
3521 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3523 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3525 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3526 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3527 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah))
3528 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3529 else {
3530 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3531 REG_RMW_FIELD(ah, AR_CH0_THERM,
3532 AR_CH0_THERM_XPABIASLVL_MSB,
3533 bias >> 2);
3534 REG_RMW_FIELD(ah, AR_CH0_THERM,
3535 AR_CH0_THERM_XPASHORT2GND, 1);
3539 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3541 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3545 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3547 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3550 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3552 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3555 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3556 bool is2ghz)
3558 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3559 return le16_to_cpu(val);
3562 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3564 int chain;
3565 u32 regval;
3566 u32 ant_div_ctl1;
3567 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3568 AR_PHY_SWITCH_CHAIN_0,
3569 AR_PHY_SWITCH_CHAIN_1,
3570 AR_PHY_SWITCH_CHAIN_2,
3573 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3575 if (AR_SREV_9462(ah)) {
3576 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3577 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3578 } else if (AR_SREV_9550(ah)) {
3579 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3580 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3581 } else
3582 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3583 AR_SWITCH_TABLE_COM_ALL, value);
3587 * AR9462 defines new switch table for BT/WLAN,
3588 * here's new field name in XXX.ref for both 2G and 5G.
3589 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3590 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3591 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3593 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3594 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3596 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3597 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3599 if (AR_SREV_9462_20_OR_LATER(ah)) {
3600 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3601 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3602 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3603 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3606 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3607 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3609 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3610 if ((ah->rxchainmask & BIT(chain)) ||
3611 (ah->txchainmask & BIT(chain))) {
3612 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3613 is2ghz);
3614 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3615 AR_SWITCH_TABLE_ALL, value);
3619 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3620 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3622 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3623 * are the fields present
3625 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3626 regval &= (~AR_ANT_DIV_CTRL_ALL);
3627 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3628 /* enable_lnadiv */
3629 regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
3630 regval |= ((value >> 6) & 0x1) <<
3631 AR_PHY_9485_ANT_DIV_LNADIV_S;
3632 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3634 /*enable fast_div */
3635 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3636 regval &= (~AR_FAST_DIV_ENABLE);
3637 regval |= ((value >> 7) & 0x1) <<
3638 AR_FAST_DIV_ENABLE_S;
3639 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3640 ant_div_ctl1 =
3641 ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
3642 /* check whether antenna diversity is enabled */
3643 if ((ant_div_ctl1 >> 0x6) == 0x3) {
3644 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3646 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3647 * main_tb, alt_tb
3649 regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
3650 AR_PHY_9485_ANT_DIV_ALT_LNACONF |
3651 AR_PHY_9485_ANT_DIV_ALT_GAINTB |
3652 AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
3653 /* by default use LNA1 for the main antenna */
3654 regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
3655 AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
3656 regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
3657 AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
3658 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3666 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3668 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3669 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3670 int drive_strength;
3671 unsigned long reg;
3673 drive_strength = pBase->miscConfiguration & BIT(0);
3674 if (!drive_strength)
3675 return;
3677 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3678 reg &= ~0x00ffffc0;
3679 reg |= 0x5 << 21;
3680 reg |= 0x5 << 18;
3681 reg |= 0x5 << 15;
3682 reg |= 0x5 << 12;
3683 reg |= 0x5 << 9;
3684 reg |= 0x5 << 6;
3685 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3687 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3688 reg &= ~0xffffffe0;
3689 reg |= 0x5 << 29;
3690 reg |= 0x5 << 26;
3691 reg |= 0x5 << 23;
3692 reg |= 0x5 << 20;
3693 reg |= 0x5 << 17;
3694 reg |= 0x5 << 14;
3695 reg |= 0x5 << 11;
3696 reg |= 0x5 << 8;
3697 reg |= 0x5 << 5;
3698 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3700 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3701 reg &= ~0xff800000;
3702 reg |= 0x5 << 29;
3703 reg |= 0x5 << 26;
3704 reg |= 0x5 << 23;
3705 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3708 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3709 struct ath9k_channel *chan)
3711 int f[3], t[3];
3712 u16 value;
3713 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3715 if (chain >= 0 && chain < 3) {
3716 if (IS_CHAN_2GHZ(chan))
3717 return eep->modalHeader2G.xatten1DB[chain];
3718 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3719 t[0] = eep->base_ext2.xatten1DBLow[chain];
3720 f[0] = 5180;
3721 t[1] = eep->modalHeader5G.xatten1DB[chain];
3722 f[1] = 5500;
3723 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3724 f[2] = 5785;
3725 value = ar9003_hw_power_interpolate((s32) chan->channel,
3726 f, t, 3);
3727 return value;
3728 } else
3729 return eep->modalHeader5G.xatten1DB[chain];
3732 return 0;
3736 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3737 struct ath9k_channel *chan)
3739 int f[3], t[3];
3740 u16 value;
3741 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3743 if (chain >= 0 && chain < 3) {
3744 if (IS_CHAN_2GHZ(chan))
3745 return eep->modalHeader2G.xatten1Margin[chain];
3746 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3747 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3748 f[0] = 5180;
3749 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3750 f[1] = 5500;
3751 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3752 f[2] = 5785;
3753 value = ar9003_hw_power_interpolate((s32) chan->channel,
3754 f, t, 3);
3755 return value;
3756 } else
3757 return eep->modalHeader5G.xatten1Margin[chain];
3760 return 0;
3763 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3765 int i;
3766 u16 value;
3767 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3768 AR_PHY_EXT_ATTEN_CTL_1,
3769 AR_PHY_EXT_ATTEN_CTL_2,
3772 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3773 for (i = 0; i < 3; i++) {
3774 if (ah->txchainmask & BIT(i)) {
3775 value = ar9003_hw_atten_chain_get(ah, i, chan);
3776 REG_RMW_FIELD(ah, ext_atten_reg[i],
3777 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3779 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3780 REG_RMW_FIELD(ah, ext_atten_reg[i],
3781 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3782 value);
3787 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3789 int timeout = 100;
3791 while (pmu_set != REG_READ(ah, pmu_reg)) {
3792 if (timeout-- == 0)
3793 return false;
3794 REG_WRITE(ah, pmu_reg, pmu_set);
3795 udelay(10);
3798 return true;
3801 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3803 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3804 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3805 u32 reg_val;
3807 if (pBase->featureEnable & BIT(4)) {
3808 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3809 int reg_pmu_set;
3811 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3812 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3813 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3814 return;
3816 if (AR_SREV_9330(ah)) {
3817 if (ah->is_clk_25mhz) {
3818 reg_pmu_set = (3 << 1) | (8 << 4) |
3819 (3 << 8) | (1 << 14) |
3820 (6 << 17) | (1 << 20) |
3821 (3 << 24);
3822 } else {
3823 reg_pmu_set = (4 << 1) | (7 << 4) |
3824 (3 << 8) | (1 << 14) |
3825 (6 << 17) | (1 << 20) |
3826 (3 << 24);
3828 } else {
3829 reg_pmu_set = (5 << 1) | (7 << 4) |
3830 (2 << 8) | (2 << 14) |
3831 (6 << 17) | (1 << 20) |
3832 (3 << 24) | (1 << 28);
3835 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3836 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3837 return;
3839 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3840 | (4 << 26);
3841 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3842 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3843 return;
3845 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3846 | (1 << 21);
3847 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3848 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3849 return;
3850 } else if (AR_SREV_9462(ah)) {
3851 reg_val = le32_to_cpu(pBase->swreg);
3852 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3853 } else {
3854 /* Internal regulator is ON. Write swreg register. */
3855 reg_val = le32_to_cpu(pBase->swreg);
3856 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3857 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3858 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3859 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3860 /* Set REG_CONTROL1.SWREG_PROGRAM */
3861 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3862 REG_READ(ah,
3863 AR_RTC_REG_CONTROL1) |
3864 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3866 } else {
3867 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3868 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3869 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3870 AR_PHY_PMU2_PGM))
3871 udelay(10);
3873 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3874 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3875 AR_PHY_PMU1_PWD))
3876 udelay(10);
3877 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3878 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3879 AR_PHY_PMU2_PGM))
3880 udelay(10);
3881 } else if (AR_SREV_9462(ah))
3882 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3883 else {
3884 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3885 AR_RTC_FORCE_SWREG_PRD;
3886 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3892 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3894 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3895 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3897 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3898 return;
3900 if (eep->baseEepHeader.featureEnable & 0x40) {
3901 tuning_caps_param &= 0x7f;
3902 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3903 tuning_caps_param);
3904 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3905 tuning_caps_param);
3909 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3911 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3912 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3913 int quick_drop;
3914 s32 t[3], f[3] = {5180, 5500, 5785};
3916 if (!(pBase->miscConfiguration & BIT(1)))
3917 return;
3919 if (freq < 4000)
3920 quick_drop = eep->modalHeader2G.quick_drop;
3921 else {
3922 t[0] = eep->base_ext1.quick_drop_low;
3923 t[1] = eep->modalHeader5G.quick_drop;
3924 t[2] = eep->base_ext1.quick_drop_high;
3925 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
3927 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
3930 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
3932 u32 value;
3934 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
3936 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3937 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
3938 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3939 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
3942 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
3944 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3945 u8 xpa_ctl;
3947 if (!(eep->baseEepHeader.featureEnable & 0x80))
3948 return;
3950 if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah))
3951 return;
3953 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
3954 if (is2ghz)
3955 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3956 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
3957 else
3958 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3959 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
3962 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
3964 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3965 u8 bias;
3967 if (!(eep->baseEepHeader.featureEnable & 0x40))
3968 return;
3970 if (!AR_SREV_9300(ah))
3971 return;
3973 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
3974 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
3975 bias & 0x3);
3976 bias >>= 2;
3977 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
3978 bias & 0x3);
3979 bias >>= 2;
3980 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
3981 bias & 0x3);
3984 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3985 struct ath9k_channel *chan)
3987 bool is2ghz = IS_CHAN_2GHZ(chan);
3988 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
3989 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
3990 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
3991 ar9003_hw_drive_strength_apply(ah);
3992 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
3993 ar9003_hw_atten_apply(ah, chan);
3994 ar9003_hw_quick_drop_apply(ah, chan->channel);
3995 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah))
3996 ar9003_hw_internal_regulator_apply(ah);
3997 ar9003_hw_apply_tuning_caps(ah);
3998 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4001 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
4002 struct ath9k_channel *chan)
4007 * Returns the interpolated y value corresponding to the specified x value
4008 * from the np ordered pairs of data (px,py).
4009 * The pairs do not have to be in any order.
4010 * If the specified x value is less than any of the px,
4011 * the returned y value is equal to the py for the lowest px.
4012 * If the specified x value is greater than any of the px,
4013 * the returned y value is equal to the py for the highest px.
4015 static int ar9003_hw_power_interpolate(int32_t x,
4016 int32_t *px, int32_t *py, u_int16_t np)
4018 int ip = 0;
4019 int lx = 0, ly = 0, lhave = 0;
4020 int hx = 0, hy = 0, hhave = 0;
4021 int dx = 0;
4022 int y = 0;
4024 lhave = 0;
4025 hhave = 0;
4027 /* identify best lower and higher x calibration measurement */
4028 for (ip = 0; ip < np; ip++) {
4029 dx = x - px[ip];
4031 /* this measurement is higher than our desired x */
4032 if (dx <= 0) {
4033 if (!hhave || dx > (x - hx)) {
4034 /* new best higher x measurement */
4035 hx = px[ip];
4036 hy = py[ip];
4037 hhave = 1;
4040 /* this measurement is lower than our desired x */
4041 if (dx >= 0) {
4042 if (!lhave || dx < (x - lx)) {
4043 /* new best lower x measurement */
4044 lx = px[ip];
4045 ly = py[ip];
4046 lhave = 1;
4051 /* the low x is good */
4052 if (lhave) {
4053 /* so is the high x */
4054 if (hhave) {
4055 /* they're the same, so just pick one */
4056 if (hx == lx)
4057 y = ly;
4058 else /* interpolate */
4059 y = interpolate(x, lx, hx, ly, hy);
4060 } else /* only low is good, use it */
4061 y = ly;
4062 } else if (hhave) /* only high is good, use it */
4063 y = hy;
4064 else /* nothing is good,this should never happen unless np=0, ???? */
4065 y = -(1 << 30);
4066 return y;
4069 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4070 u16 rateIndex, u16 freq, bool is2GHz)
4072 u16 numPiers, i;
4073 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4074 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4075 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4076 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4077 u8 *pFreqBin;
4079 if (is2GHz) {
4080 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4081 pEepromTargetPwr = eep->calTargetPower2G;
4082 pFreqBin = eep->calTarget_freqbin_2G;
4083 } else {
4084 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4085 pEepromTargetPwr = eep->calTargetPower5G;
4086 pFreqBin = eep->calTarget_freqbin_5G;
4090 * create array of channels and targetpower from
4091 * targetpower piers stored on eeprom
4093 for (i = 0; i < numPiers; i++) {
4094 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4095 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4098 /* interpolate to get target power for given frequency */
4099 return (u8) ar9003_hw_power_interpolate((s32) freq,
4100 freqArray,
4101 targetPowerArray, numPiers);
4104 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4105 u16 rateIndex,
4106 u16 freq, bool is2GHz)
4108 u16 numPiers, i;
4109 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4110 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4111 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4112 struct cal_tgt_pow_ht *pEepromTargetPwr;
4113 u8 *pFreqBin;
4115 if (is2GHz) {
4116 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4117 pEepromTargetPwr = eep->calTargetPower2GHT20;
4118 pFreqBin = eep->calTarget_freqbin_2GHT20;
4119 } else {
4120 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4121 pEepromTargetPwr = eep->calTargetPower5GHT20;
4122 pFreqBin = eep->calTarget_freqbin_5GHT20;
4126 * create array of channels and targetpower
4127 * from targetpower piers stored on eeprom
4129 for (i = 0; i < numPiers; i++) {
4130 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4131 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4134 /* interpolate to get target power for given frequency */
4135 return (u8) ar9003_hw_power_interpolate((s32) freq,
4136 freqArray,
4137 targetPowerArray, numPiers);
4140 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4141 u16 rateIndex,
4142 u16 freq, bool is2GHz)
4144 u16 numPiers, i;
4145 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4146 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4147 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4148 struct cal_tgt_pow_ht *pEepromTargetPwr;
4149 u8 *pFreqBin;
4151 if (is2GHz) {
4152 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4153 pEepromTargetPwr = eep->calTargetPower2GHT40;
4154 pFreqBin = eep->calTarget_freqbin_2GHT40;
4155 } else {
4156 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4157 pEepromTargetPwr = eep->calTargetPower5GHT40;
4158 pFreqBin = eep->calTarget_freqbin_5GHT40;
4162 * create array of channels and targetpower from
4163 * targetpower piers stored on eeprom
4165 for (i = 0; i < numPiers; i++) {
4166 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4167 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4170 /* interpolate to get target power for given frequency */
4171 return (u8) ar9003_hw_power_interpolate((s32) freq,
4172 freqArray,
4173 targetPowerArray, numPiers);
4176 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4177 u16 rateIndex, u16 freq)
4179 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4180 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4181 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4182 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4183 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4184 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4187 * create array of channels and targetpower from
4188 * targetpower piers stored on eeprom
4190 for (i = 0; i < numPiers; i++) {
4191 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4192 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4195 /* interpolate to get target power for given frequency */
4196 return (u8) ar9003_hw_power_interpolate((s32) freq,
4197 freqArray,
4198 targetPowerArray, numPiers);
4201 /* Set tx power registers to array of values passed in */
4202 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4204 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4205 /* make sure forced gain is not set */
4206 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4208 /* Write the OFDM power per rate set */
4210 /* 6 (LSB), 9, 12, 18 (MSB) */
4211 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4212 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4213 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4214 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4215 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4217 /* 24 (LSB), 36, 48, 54 (MSB) */
4218 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4219 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4220 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4221 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4222 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4224 /* Write the CCK power per rate set */
4226 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4227 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4228 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4229 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4230 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4231 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4233 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4234 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4235 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4236 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4237 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4238 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4241 /* Write the power for duplicated frames - HT40 */
4243 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4244 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4245 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4246 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4247 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4248 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4251 /* Write the HT20 power per rate set */
4253 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4254 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4255 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4256 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4257 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4258 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4261 /* 6 (LSB), 7, 12, 13 (MSB) */
4262 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4263 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4264 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4265 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4266 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4269 /* 14 (LSB), 15, 20, 21 */
4270 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4271 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4272 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4273 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4274 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4277 /* Mixed HT20 and HT40 rates */
4279 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4280 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4281 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4282 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4283 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4284 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4288 * Write the HT40 power per rate set
4289 * correct PAR difference between HT40 and HT20/LEGACY
4290 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4292 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4293 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4294 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4295 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4296 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4299 /* 6 (LSB), 7, 12, 13 (MSB) */
4300 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4301 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4302 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4303 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4304 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4307 /* 14 (LSB), 15, 20, 21 */
4308 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4309 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4310 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4311 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4312 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4315 return 0;
4316 #undef POW_SM
4319 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4320 u8 *targetPowerValT2,
4321 bool is2GHz)
4323 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4324 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4325 is2GHz);
4326 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4327 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4328 is2GHz);
4329 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4330 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4331 is2GHz);
4332 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4333 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4334 is2GHz);
4337 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4338 u8 *targetPowerValT2)
4340 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4341 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4342 freq);
4343 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4344 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4345 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4346 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4347 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4348 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4351 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4352 u8 *targetPowerValT2, bool is2GHz)
4354 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4355 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4356 is2GHz);
4357 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4358 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4359 freq, is2GHz);
4360 targetPowerValT2[ALL_TARGET_HT20_4] =
4361 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4362 is2GHz);
4363 targetPowerValT2[ALL_TARGET_HT20_5] =
4364 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4365 is2GHz);
4366 targetPowerValT2[ALL_TARGET_HT20_6] =
4367 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4368 is2GHz);
4369 targetPowerValT2[ALL_TARGET_HT20_7] =
4370 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4371 is2GHz);
4372 targetPowerValT2[ALL_TARGET_HT20_12] =
4373 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4374 is2GHz);
4375 targetPowerValT2[ALL_TARGET_HT20_13] =
4376 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4377 is2GHz);
4378 targetPowerValT2[ALL_TARGET_HT20_14] =
4379 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4380 is2GHz);
4381 targetPowerValT2[ALL_TARGET_HT20_15] =
4382 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4383 is2GHz);
4384 targetPowerValT2[ALL_TARGET_HT20_20] =
4385 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4386 is2GHz);
4387 targetPowerValT2[ALL_TARGET_HT20_21] =
4388 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4389 is2GHz);
4390 targetPowerValT2[ALL_TARGET_HT20_22] =
4391 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4392 is2GHz);
4393 targetPowerValT2[ALL_TARGET_HT20_23] =
4394 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4395 is2GHz);
4398 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4399 u16 freq,
4400 u8 *targetPowerValT2,
4401 bool is2GHz)
4403 /* XXX: hard code for now, need to get from eeprom struct */
4404 u8 ht40PowerIncForPdadc = 0;
4406 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4407 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4408 is2GHz) + ht40PowerIncForPdadc;
4409 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4410 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4411 freq,
4412 is2GHz) + ht40PowerIncForPdadc;
4413 targetPowerValT2[ALL_TARGET_HT40_4] =
4414 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4415 is2GHz) + ht40PowerIncForPdadc;
4416 targetPowerValT2[ALL_TARGET_HT40_5] =
4417 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4418 is2GHz) + ht40PowerIncForPdadc;
4419 targetPowerValT2[ALL_TARGET_HT40_6] =
4420 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4421 is2GHz) + ht40PowerIncForPdadc;
4422 targetPowerValT2[ALL_TARGET_HT40_7] =
4423 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4424 is2GHz) + ht40PowerIncForPdadc;
4425 targetPowerValT2[ALL_TARGET_HT40_12] =
4426 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4427 is2GHz) + ht40PowerIncForPdadc;
4428 targetPowerValT2[ALL_TARGET_HT40_13] =
4429 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4430 is2GHz) + ht40PowerIncForPdadc;
4431 targetPowerValT2[ALL_TARGET_HT40_14] =
4432 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4433 is2GHz) + ht40PowerIncForPdadc;
4434 targetPowerValT2[ALL_TARGET_HT40_15] =
4435 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4436 is2GHz) + ht40PowerIncForPdadc;
4437 targetPowerValT2[ALL_TARGET_HT40_20] =
4438 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4439 is2GHz) + ht40PowerIncForPdadc;
4440 targetPowerValT2[ALL_TARGET_HT40_21] =
4441 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4442 is2GHz) + ht40PowerIncForPdadc;
4443 targetPowerValT2[ALL_TARGET_HT40_22] =
4444 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4445 is2GHz) + ht40PowerIncForPdadc;
4446 targetPowerValT2[ALL_TARGET_HT40_23] =
4447 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4448 is2GHz) + ht40PowerIncForPdadc;
4451 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4452 struct ath9k_channel *chan,
4453 u8 *targetPowerValT2)
4455 bool is2GHz = IS_CHAN_2GHZ(chan);
4456 unsigned int i = 0;
4457 struct ath_common *common = ath9k_hw_common(ah);
4458 u16 freq = chan->channel;
4460 if (is2GHz)
4461 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4463 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4464 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4466 if (IS_CHAN_HT40(chan))
4467 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4468 is2GHz);
4470 for (i = 0; i < ar9300RateSize; i++) {
4471 ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n",
4472 i, targetPowerValT2[i]);
4476 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4477 int mode,
4478 int ipier,
4479 int ichain,
4480 int *pfrequency,
4481 int *pcorrection,
4482 int *ptemperature, int *pvoltage)
4484 u8 *pCalPier;
4485 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4486 int is2GHz;
4487 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4488 struct ath_common *common = ath9k_hw_common(ah);
4490 if (ichain >= AR9300_MAX_CHAINS) {
4491 ath_dbg(common, EEPROM,
4492 "Invalid chain index, must be less than %d\n",
4493 AR9300_MAX_CHAINS);
4494 return -1;
4497 if (mode) { /* 5GHz */
4498 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4499 ath_dbg(common, EEPROM,
4500 "Invalid 5GHz cal pier index, must be less than %d\n",
4501 AR9300_NUM_5G_CAL_PIERS);
4502 return -1;
4504 pCalPier = &(eep->calFreqPier5G[ipier]);
4505 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4506 is2GHz = 0;
4507 } else {
4508 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4509 ath_dbg(common, EEPROM,
4510 "Invalid 2GHz cal pier index, must be less than %d\n",
4511 AR9300_NUM_2G_CAL_PIERS);
4512 return -1;
4515 pCalPier = &(eep->calFreqPier2G[ipier]);
4516 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4517 is2GHz = 1;
4520 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4521 *pcorrection = pCalPierStruct->refPower;
4522 *ptemperature = pCalPierStruct->tempMeas;
4523 *pvoltage = pCalPierStruct->voltMeas;
4525 return 0;
4528 static int ar9003_hw_power_control_override(struct ath_hw *ah,
4529 int frequency,
4530 int *correction,
4531 int *voltage, int *temperature)
4533 int tempSlope = 0;
4534 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4535 int f[3], t[3];
4537 REG_RMW(ah, AR_PHY_TPC_11_B0,
4538 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4539 AR_PHY_TPC_OLPC_GAIN_DELTA);
4540 if (ah->caps.tx_chainmask & BIT(1))
4541 REG_RMW(ah, AR_PHY_TPC_11_B1,
4542 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4543 AR_PHY_TPC_OLPC_GAIN_DELTA);
4544 if (ah->caps.tx_chainmask & BIT(2))
4545 REG_RMW(ah, AR_PHY_TPC_11_B2,
4546 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4547 AR_PHY_TPC_OLPC_GAIN_DELTA);
4549 /* enable open loop power control on chip */
4550 REG_RMW(ah, AR_PHY_TPC_6_B0,
4551 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4552 AR_PHY_TPC_6_ERROR_EST_MODE);
4553 if (ah->caps.tx_chainmask & BIT(1))
4554 REG_RMW(ah, AR_PHY_TPC_6_B1,
4555 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4556 AR_PHY_TPC_6_ERROR_EST_MODE);
4557 if (ah->caps.tx_chainmask & BIT(2))
4558 REG_RMW(ah, AR_PHY_TPC_6_B2,
4559 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4560 AR_PHY_TPC_6_ERROR_EST_MODE);
4563 * enable temperature compensation
4564 * Need to use register names
4566 if (frequency < 4000)
4567 tempSlope = eep->modalHeader2G.tempSlope;
4568 else if (eep->base_ext2.tempSlopeLow != 0) {
4569 t[0] = eep->base_ext2.tempSlopeLow;
4570 f[0] = 5180;
4571 t[1] = eep->modalHeader5G.tempSlope;
4572 f[1] = 5500;
4573 t[2] = eep->base_ext2.tempSlopeHigh;
4574 f[2] = 5785;
4575 tempSlope = ar9003_hw_power_interpolate((s32) frequency,
4576 f, t, 3);
4577 } else
4578 tempSlope = eep->modalHeader5G.tempSlope;
4580 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
4582 if (AR_SREV_9462_20(ah))
4583 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4584 AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope);
4587 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4588 temperature[0]);
4590 return 0;
4593 /* Apply the recorded correction values. */
4594 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4596 int ichain, ipier, npier;
4597 int mode;
4598 int lfrequency[AR9300_MAX_CHAINS],
4599 lcorrection[AR9300_MAX_CHAINS],
4600 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4601 int hfrequency[AR9300_MAX_CHAINS],
4602 hcorrection[AR9300_MAX_CHAINS],
4603 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4604 int fdiff;
4605 int correction[AR9300_MAX_CHAINS],
4606 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4607 int pfrequency, pcorrection, ptemperature, pvoltage;
4608 struct ath_common *common = ath9k_hw_common(ah);
4610 mode = (frequency >= 4000);
4611 if (mode)
4612 npier = AR9300_NUM_5G_CAL_PIERS;
4613 else
4614 npier = AR9300_NUM_2G_CAL_PIERS;
4616 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4617 lfrequency[ichain] = 0;
4618 hfrequency[ichain] = 100000;
4620 /* identify best lower and higher frequency calibration measurement */
4621 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4622 for (ipier = 0; ipier < npier; ipier++) {
4623 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4624 &pfrequency, &pcorrection,
4625 &ptemperature, &pvoltage)) {
4626 fdiff = frequency - pfrequency;
4629 * this measurement is higher than
4630 * our desired frequency
4632 if (fdiff <= 0) {
4633 if (hfrequency[ichain] <= 0 ||
4634 hfrequency[ichain] >= 100000 ||
4635 fdiff >
4636 (frequency - hfrequency[ichain])) {
4638 * new best higher
4639 * frequency measurement
4641 hfrequency[ichain] = pfrequency;
4642 hcorrection[ichain] =
4643 pcorrection;
4644 htemperature[ichain] =
4645 ptemperature;
4646 hvoltage[ichain] = pvoltage;
4649 if (fdiff >= 0) {
4650 if (lfrequency[ichain] <= 0
4651 || fdiff <
4652 (frequency - lfrequency[ichain])) {
4654 * new best lower
4655 * frequency measurement
4657 lfrequency[ichain] = pfrequency;
4658 lcorrection[ichain] =
4659 pcorrection;
4660 ltemperature[ichain] =
4661 ptemperature;
4662 lvoltage[ichain] = pvoltage;
4669 /* interpolate */
4670 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4671 ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
4672 ichain, frequency, lfrequency[ichain],
4673 lcorrection[ichain], hfrequency[ichain],
4674 hcorrection[ichain]);
4675 /* they're the same, so just pick one */
4676 if (hfrequency[ichain] == lfrequency[ichain]) {
4677 correction[ichain] = lcorrection[ichain];
4678 voltage[ichain] = lvoltage[ichain];
4679 temperature[ichain] = ltemperature[ichain];
4681 /* the low frequency is good */
4682 else if (frequency - lfrequency[ichain] < 1000) {
4683 /* so is the high frequency, interpolate */
4684 if (hfrequency[ichain] - frequency < 1000) {
4686 correction[ichain] = interpolate(frequency,
4687 lfrequency[ichain],
4688 hfrequency[ichain],
4689 lcorrection[ichain],
4690 hcorrection[ichain]);
4692 temperature[ichain] = interpolate(frequency,
4693 lfrequency[ichain],
4694 hfrequency[ichain],
4695 ltemperature[ichain],
4696 htemperature[ichain]);
4698 voltage[ichain] = interpolate(frequency,
4699 lfrequency[ichain],
4700 hfrequency[ichain],
4701 lvoltage[ichain],
4702 hvoltage[ichain]);
4704 /* only low is good, use it */
4705 else {
4706 correction[ichain] = lcorrection[ichain];
4707 temperature[ichain] = ltemperature[ichain];
4708 voltage[ichain] = lvoltage[ichain];
4711 /* only high is good, use it */
4712 else if (hfrequency[ichain] - frequency < 1000) {
4713 correction[ichain] = hcorrection[ichain];
4714 temperature[ichain] = htemperature[ichain];
4715 voltage[ichain] = hvoltage[ichain];
4716 } else { /* nothing is good, presume 0???? */
4717 correction[ichain] = 0;
4718 temperature[ichain] = 0;
4719 voltage[ichain] = 0;
4723 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4724 temperature);
4726 ath_dbg(common, EEPROM,
4727 "for frequency=%d, calibration correction = %d %d %d\n",
4728 frequency, correction[0], correction[1], correction[2]);
4730 return 0;
4733 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4734 int idx,
4735 int edge,
4736 bool is2GHz)
4738 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4739 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4741 if (is2GHz)
4742 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4743 else
4744 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4747 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4748 int idx,
4749 unsigned int edge,
4750 u16 freq,
4751 bool is2GHz)
4753 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4754 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4756 u8 *ctl_freqbin = is2GHz ?
4757 &eep->ctl_freqbin_2G[idx][0] :
4758 &eep->ctl_freqbin_5G[idx][0];
4760 if (is2GHz) {
4761 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4762 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4763 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4764 } else {
4765 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4766 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4767 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4770 return MAX_RATE_POWER;
4774 * Find the maximum conformance test limit for the given channel and CTL info
4776 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4777 u16 freq, int idx, bool is2GHz)
4779 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4780 u8 *ctl_freqbin = is2GHz ?
4781 &eep->ctl_freqbin_2G[idx][0] :
4782 &eep->ctl_freqbin_5G[idx][0];
4783 u16 num_edges = is2GHz ?
4784 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4785 unsigned int edge;
4787 /* Get the edge power */
4788 for (edge = 0;
4789 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
4790 edge++) {
4792 * If there's an exact channel match or an inband flag set
4793 * on the lower channel use the given rdEdgePower
4795 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
4796 twiceMaxEdgePower =
4797 ar9003_hw_get_direct_edge_power(eep, idx,
4798 edge, is2GHz);
4799 break;
4800 } else if ((edge > 0) &&
4801 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
4802 is2GHz))) {
4803 twiceMaxEdgePower =
4804 ar9003_hw_get_indirect_edge_power(eep, idx,
4805 edge, freq,
4806 is2GHz);
4808 * Leave loop - no more affecting edges possible in
4809 * this monotonic increasing list
4811 break;
4814 return twiceMaxEdgePower;
4817 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4818 struct ath9k_channel *chan,
4819 u8 *pPwrArray, u16 cfgCtl,
4820 u8 antenna_reduction,
4821 u16 powerLimit)
4823 struct ath_common *common = ath9k_hw_common(ah);
4824 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4825 u16 twiceMaxEdgePower;
4826 int i;
4827 u16 scaledPower = 0, minCtlPower;
4828 static const u16 ctlModesFor11a[] = {
4829 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4831 static const u16 ctlModesFor11g[] = {
4832 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
4833 CTL_11G_EXT, CTL_2GHT40
4835 u16 numCtlModes;
4836 const u16 *pCtlMode;
4837 u16 ctlMode, freq;
4838 struct chan_centers centers;
4839 u8 *ctlIndex;
4840 u8 ctlNum;
4841 u16 twiceMinEdgePower;
4842 bool is2ghz = IS_CHAN_2GHZ(chan);
4844 ath9k_hw_get_channel_centers(ah, chan, &centers);
4845 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
4846 antenna_reduction);
4848 if (is2ghz) {
4849 /* Setup for CTL modes */
4850 /* CTL_11B, CTL_11G, CTL_2GHT20 */
4851 numCtlModes =
4852 ARRAY_SIZE(ctlModesFor11g) -
4853 SUB_NUM_CTL_MODES_AT_2G_40;
4854 pCtlMode = ctlModesFor11g;
4855 if (IS_CHAN_HT40(chan))
4856 /* All 2G CTL's */
4857 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4858 } else {
4859 /* Setup for CTL modes */
4860 /* CTL_11A, CTL_5GHT20 */
4861 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
4862 SUB_NUM_CTL_MODES_AT_5G_40;
4863 pCtlMode = ctlModesFor11a;
4864 if (IS_CHAN_HT40(chan))
4865 /* All 5G CTL's */
4866 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4870 * For MIMO, need to apply regulatory caps individually across
4871 * dynamically running modes: CCK, OFDM, HT20, HT40
4873 * The outer loop walks through each possible applicable runtime mode.
4874 * The inner loop walks through each ctlIndex entry in EEPROM.
4875 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
4877 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4878 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
4879 (pCtlMode[ctlMode] == CTL_2GHT40);
4880 if (isHt40CtlMode)
4881 freq = centers.synth_center;
4882 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4883 freq = centers.ext_center;
4884 else
4885 freq = centers.ctl_center;
4887 ath_dbg(common, REGULATORY,
4888 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
4889 ctlMode, numCtlModes, isHt40CtlMode,
4890 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4892 /* walk through each CTL index stored in EEPROM */
4893 if (is2ghz) {
4894 ctlIndex = pEepData->ctlIndex_2G;
4895 ctlNum = AR9300_NUM_CTLS_2G;
4896 } else {
4897 ctlIndex = pEepData->ctlIndex_5G;
4898 ctlNum = AR9300_NUM_CTLS_5G;
4901 twiceMaxEdgePower = MAX_RATE_POWER;
4902 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
4903 ath_dbg(common, REGULATORY,
4904 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
4905 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
4906 chan->channel);
4909 * compare test group from regulatory
4910 * channel list with test mode from pCtlMode
4911 * list
4913 if ((((cfgCtl & ~CTL_MODE_M) |
4914 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4915 ctlIndex[i]) ||
4916 (((cfgCtl & ~CTL_MODE_M) |
4917 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4918 ((ctlIndex[i] & CTL_MODE_M) |
4919 SD_NO_CTL))) {
4920 twiceMinEdgePower =
4921 ar9003_hw_get_max_edge_power(pEepData,
4922 freq, i,
4923 is2ghz);
4925 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
4927 * Find the minimum of all CTL
4928 * edge powers that apply to
4929 * this channel
4931 twiceMaxEdgePower =
4932 min(twiceMaxEdgePower,
4933 twiceMinEdgePower);
4934 else {
4935 /* specific */
4936 twiceMaxEdgePower =
4937 twiceMinEdgePower;
4938 break;
4943 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
4945 ath_dbg(common, REGULATORY,
4946 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
4947 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4948 scaledPower, minCtlPower);
4950 /* Apply ctl mode to correct target power set */
4951 switch (pCtlMode[ctlMode]) {
4952 case CTL_11B:
4953 for (i = ALL_TARGET_LEGACY_1L_5L;
4954 i <= ALL_TARGET_LEGACY_11S; i++)
4955 pPwrArray[i] =
4956 (u8)min((u16)pPwrArray[i],
4957 minCtlPower);
4958 break;
4959 case CTL_11A:
4960 case CTL_11G:
4961 for (i = ALL_TARGET_LEGACY_6_24;
4962 i <= ALL_TARGET_LEGACY_54; i++)
4963 pPwrArray[i] =
4964 (u8)min((u16)pPwrArray[i],
4965 minCtlPower);
4966 break;
4967 case CTL_5GHT20:
4968 case CTL_2GHT20:
4969 for (i = ALL_TARGET_HT20_0_8_16;
4970 i <= ALL_TARGET_HT20_21; i++)
4971 pPwrArray[i] =
4972 (u8)min((u16)pPwrArray[i],
4973 minCtlPower);
4974 pPwrArray[ALL_TARGET_HT20_22] =
4975 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
4976 minCtlPower);
4977 pPwrArray[ALL_TARGET_HT20_23] =
4978 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
4979 minCtlPower);
4980 break;
4981 case CTL_5GHT40:
4982 case CTL_2GHT40:
4983 for (i = ALL_TARGET_HT40_0_8_16;
4984 i <= ALL_TARGET_HT40_23; i++)
4985 pPwrArray[i] =
4986 (u8)min((u16)pPwrArray[i],
4987 minCtlPower);
4988 break;
4989 default:
4990 break;
4992 } /* end ctl mode checking */
4995 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
4997 u8 mod_idx = mcs_idx % 8;
4999 if (mod_idx <= 3)
5000 return mod_idx ? (base_pwridx + 1) : base_pwridx;
5001 else
5002 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5005 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5006 struct ath9k_channel *chan, u16 cfgCtl,
5007 u8 twiceAntennaReduction,
5008 u8 powerLimit, bool test)
5010 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5011 struct ath_common *common = ath9k_hw_common(ah);
5012 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5013 struct ar9300_modal_eep_header *modal_hdr;
5014 u8 targetPowerValT2[ar9300RateSize];
5015 u8 target_power_val_t2_eep[ar9300RateSize];
5016 unsigned int i = 0, paprd_scale_factor = 0;
5017 u8 pwr_idx, min_pwridx = 0;
5019 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5022 * Get target powers from EEPROM - our baseline for TX Power
5024 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5026 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
5027 if (IS_CHAN_2GHZ(chan))
5028 modal_hdr = &eep->modalHeader2G;
5029 else
5030 modal_hdr = &eep->modalHeader5G;
5032 ah->paprd_ratemask =
5033 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5034 AR9300_PAPRD_RATE_MASK;
5036 ah->paprd_ratemask_ht40 =
5037 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5038 AR9300_PAPRD_RATE_MASK;
5040 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5041 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5042 ALL_TARGET_HT20_0_8_16;
5044 if (!ah->paprd_table_write_done) {
5045 memcpy(target_power_val_t2_eep, targetPowerValT2,
5046 sizeof(targetPowerValT2));
5047 for (i = 0; i < 24; i++) {
5048 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5049 if (ah->paprd_ratemask & (1 << i)) {
5050 if (targetPowerValT2[pwr_idx] &&
5051 targetPowerValT2[pwr_idx] ==
5052 target_power_val_t2_eep[pwr_idx])
5053 targetPowerValT2[pwr_idx] -=
5054 paprd_scale_factor;
5058 memcpy(target_power_val_t2_eep, targetPowerValT2,
5059 sizeof(targetPowerValT2));
5062 ar9003_hw_set_power_per_rate_table(ah, chan,
5063 targetPowerValT2, cfgCtl,
5064 twiceAntennaReduction,
5065 powerLimit);
5067 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
5068 for (i = 0; i < ar9300RateSize; i++) {
5069 if ((ah->paprd_ratemask & (1 << i)) &&
5070 (abs(targetPowerValT2[i] -
5071 target_power_val_t2_eep[i]) >
5072 paprd_scale_factor)) {
5073 ah->paprd_ratemask &= ~(1 << i);
5074 ath_dbg(common, EEPROM,
5075 "paprd disabled for mcs %d\n", i);
5080 regulatory->max_power_level = 0;
5081 for (i = 0; i < ar9300RateSize; i++) {
5082 if (targetPowerValT2[i] > regulatory->max_power_level)
5083 regulatory->max_power_level = targetPowerValT2[i];
5086 ath9k_hw_update_regulatory_maxpower(ah);
5088 if (test)
5089 return;
5091 for (i = 0; i < ar9300RateSize; i++) {
5092 ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n",
5093 i, targetPowerValT2[i]);
5096 /* Write target power array to registers */
5097 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5098 ar9003_hw_calibration_apply(ah, chan->channel);
5100 if (IS_CHAN_2GHZ(chan)) {
5101 if (IS_CHAN_HT40(chan))
5102 i = ALL_TARGET_HT40_0_8_16;
5103 else
5104 i = ALL_TARGET_HT20_0_8_16;
5105 } else {
5106 if (IS_CHAN_HT40(chan))
5107 i = ALL_TARGET_HT40_7;
5108 else
5109 i = ALL_TARGET_HT20_7;
5111 ah->paprd_target_power = targetPowerValT2[i];
5114 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5115 u16 i, bool is2GHz)
5117 return AR_NO_SPUR;
5120 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5122 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5124 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5127 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5129 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5131 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5134 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5136 return ar9003_modal_header(ah, is2ghz)->spurChans;
5139 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5140 struct ath9k_channel *chan)
5142 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5144 if (IS_CHAN_2GHZ(chan))
5145 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5146 AR9300_PAPRD_SCALE_1);
5147 else {
5148 if (chan->channel >= 5700)
5149 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5150 AR9300_PAPRD_SCALE_1);
5151 else if (chan->channel >= 5400)
5152 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5153 AR9300_PAPRD_SCALE_2);
5154 else
5155 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5156 AR9300_PAPRD_SCALE_1);
5160 const struct eeprom_ops eep_ar9300_ops = {
5161 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5162 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5163 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5164 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5165 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5166 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5167 .set_board_values = ath9k_hw_ar9300_set_board_values,
5168 .set_addac = ath9k_hw_ar9300_set_addac,
5169 .set_txpower = ath9k_hw_ar9300_set_txpower,
5170 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel