x86/xen: resume timer irqs early
[linux/fpc-iii.git] / drivers / net / wireless / ath / ath9k / ar9003_eeprom.c
blobe493150d50c339eee6d574143823f3242c66f2b3
1 /*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <asm/unaligned.h>
18 #include "hw.h"
19 #include "ar9003_phy.h"
20 #include "ar9003_eeprom.h"
21 #include "ar9003_mci.h"
23 #define COMP_HDR_LEN 4
24 #define COMP_CKSUM_LEN 2
26 #define LE16(x) __constant_cpu_to_le16(x)
27 #define LE32(x) __constant_cpu_to_le32(x)
29 /* Local defines to distinguish between extension and control CTL's */
30 #define EXT_ADDITIVE (0x8000)
31 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
32 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
33 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
35 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
36 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
38 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
40 #define EEPROM_DATA_LEN_9485 1088
42 static int ar9003_hw_power_interpolate(int32_t x,
43 int32_t *px, int32_t *py, u_int16_t np);
45 static const struct ar9300_eeprom ar9300_default = {
46 .eepromVersion = 2,
47 .templateVersion = 2,
48 .macAddr = {0, 2, 3, 4, 5, 6},
49 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
51 .baseEepHeader = {
52 .regDmn = { LE16(0), LE16(0x1f) },
53 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
54 .opCapFlags = {
55 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
56 .eepMisc = 0,
58 .rfSilent = 0,
59 .blueToothOptions = 0,
60 .deviceCap = 0,
61 .deviceType = 5, /* takes lower byte in eeprom location */
62 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
63 .params_for_tuning_caps = {0, 0},
64 .featureEnable = 0x0c,
66 * bit0 - enable tx temp comp - disabled
67 * bit1 - enable tx volt comp - disabled
68 * bit2 - enable fastClock - enabled
69 * bit3 - enable doubling - enabled
70 * bit4 - enable internal regulator - disabled
71 * bit5 - enable pa predistortion - disabled
73 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
74 .eepromWriteEnableGpio = 3,
75 .wlanDisableGpio = 0,
76 .wlanLedGpio = 8,
77 .rxBandSelectGpio = 0xff,
78 .txrxgain = 0,
79 .swreg = 0,
81 .modalHeader2G = {
82 /* ar9300_modal_eep_header 2g */
83 /* 4 idle,t1,t2,b(4 bits per setting) */
84 .antCtrlCommon = LE32(0x110),
85 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
86 .antCtrlCommon2 = LE32(0x22222),
89 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
90 * rx1, rx12, b (2 bits each)
92 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
95 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
96 * for ar9280 (0xa20c/b20c 5:0)
98 .xatten1DB = {0, 0, 0},
101 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
102 * for ar9280 (0xa20c/b20c 16:12
104 .xatten1Margin = {0, 0, 0},
105 .tempSlope = 36,
106 .voltSlope = 0,
109 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
110 * channels in usual fbin coding format
112 .spurChans = {0, 0, 0, 0, 0},
115 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
116 * if the register is per chain
118 .noiseFloorThreshCh = {-1, 0, 0},
119 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
120 .quick_drop = 0,
121 .xpaBiasLvl = 0,
122 .txFrameToDataStart = 0x0e,
123 .txFrameToPaOn = 0x0e,
124 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
125 .antennaGain = 0,
126 .switchSettling = 0x2c,
127 .adcDesiredSize = -30,
128 .txEndToXpaOff = 0,
129 .txEndToRxOn = 0x2,
130 .txFrameToXpaOn = 0xe,
131 .thresh62 = 28,
132 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
133 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
134 .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},
142 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
144 .calFreqPier2G = {
145 FREQ2FBIN(2412, 1),
146 FREQ2FBIN(2437, 1),
147 FREQ2FBIN(2472, 1),
149 /* ar9300_cal_data_per_freq_op_loop 2g */
150 .calPierData2G = {
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} },
153 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
155 .calTarget_freqbin_Cck = {
156 FREQ2FBIN(2412, 1),
157 FREQ2FBIN(2484, 1),
159 .calTarget_freqbin_2G = {
160 FREQ2FBIN(2412, 1),
161 FREQ2FBIN(2437, 1),
162 FREQ2FBIN(2472, 1)
164 .calTarget_freqbin_2GHT20 = {
165 FREQ2FBIN(2412, 1),
166 FREQ2FBIN(2437, 1),
167 FREQ2FBIN(2472, 1)
169 .calTarget_freqbin_2GHT40 = {
170 FREQ2FBIN(2412, 1),
171 FREQ2FBIN(2437, 1),
172 FREQ2FBIN(2472, 1)
174 .calTargetPowerCck = {
175 /* 1L-5L,5S,11L,11S */
176 { {36, 36, 36, 36} },
177 { {36, 36, 36, 36} },
179 .calTargetPower2G = {
180 /* 6-24,36,48,54 */
181 { {32, 32, 28, 24} },
182 { {32, 32, 28, 24} },
183 { {32, 32, 28, 24} },
185 .calTargetPower2GHT20 = {
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} },
188 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
190 .calTargetPower2GHT40 = {
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} },
193 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
195 .ctlIndex_2G = {
196 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
197 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
199 .ctl_freqbin_2G = {
201 FREQ2FBIN(2412, 1),
202 FREQ2FBIN(2417, 1),
203 FREQ2FBIN(2457, 1),
204 FREQ2FBIN(2462, 1)
207 FREQ2FBIN(2412, 1),
208 FREQ2FBIN(2417, 1),
209 FREQ2FBIN(2462, 1),
210 0xFF,
214 FREQ2FBIN(2412, 1),
215 FREQ2FBIN(2417, 1),
216 FREQ2FBIN(2462, 1),
217 0xFF,
220 FREQ2FBIN(2422, 1),
221 FREQ2FBIN(2427, 1),
222 FREQ2FBIN(2447, 1),
223 FREQ2FBIN(2452, 1)
227 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
228 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
229 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
230 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
234 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
235 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
236 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
241 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
242 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
243 FREQ2FBIN(2472, 1),
248 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
249 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
250 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
251 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
255 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
256 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
257 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
261 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
262 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
263 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
268 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
269 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
270 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
275 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
276 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
277 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
278 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
281 .ctlPowerData_2G = {
282 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
283 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
284 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
286 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
287 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
288 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
290 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
291 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
292 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
294 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
295 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
296 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
298 .modalHeader5G = {
299 /* 4 idle,t1,t2,b (4 bits per setting) */
300 .antCtrlCommon = LE32(0x110),
301 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
302 .antCtrlCommon2 = LE32(0x22222),
303 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
304 .antCtrlChain = {
305 LE16(0x000), LE16(0x000), LE16(0x000),
307 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
308 .xatten1DB = {0, 0, 0},
311 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
312 * for merlin (0xa20c/b20c 16:12
314 .xatten1Margin = {0, 0, 0},
315 .tempSlope = 68,
316 .voltSlope = 0,
317 /* spurChans spur channels in usual fbin coding format */
318 .spurChans = {0, 0, 0, 0, 0},
319 /* noiseFloorThreshCh Check if the register is per chain */
320 .noiseFloorThreshCh = {-1, 0, 0},
321 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
322 .quick_drop = 0,
323 .xpaBiasLvl = 0,
324 .txFrameToDataStart = 0x0e,
325 .txFrameToPaOn = 0x0e,
326 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
327 .antennaGain = 0,
328 .switchSettling = 0x2d,
329 .adcDesiredSize = -30,
330 .txEndToXpaOff = 0,
331 .txEndToRxOn = 0x2,
332 .txFrameToXpaOn = 0xe,
333 .thresh62 = 28,
334 .papdRateMaskHt20 = LE32(0x0c80c080),
335 .papdRateMaskHt40 = LE32(0x0080c080),
336 .xlna_bias_strength = 0,
337 .futureModal = {
338 0, 0, 0, 0, 0, 0, 0,
341 .base_ext2 = {
342 .tempSlopeLow = 0,
343 .tempSlopeHigh = 0,
344 .xatten1DBLow = {0, 0, 0},
345 .xatten1MarginLow = {0, 0, 0},
346 .xatten1DBHigh = {0, 0, 0},
347 .xatten1MarginHigh = {0, 0, 0}
349 .calFreqPier5G = {
350 FREQ2FBIN(5180, 0),
351 FREQ2FBIN(5220, 0),
352 FREQ2FBIN(5320, 0),
353 FREQ2FBIN(5400, 0),
354 FREQ2FBIN(5500, 0),
355 FREQ2FBIN(5600, 0),
356 FREQ2FBIN(5725, 0),
357 FREQ2FBIN(5825, 0)
359 .calPierData5G = {
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},
368 {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},
378 {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},
388 {0, 0, 0, 0, 0},
392 .calTarget_freqbin_5G = {
393 FREQ2FBIN(5180, 0),
394 FREQ2FBIN(5220, 0),
395 FREQ2FBIN(5320, 0),
396 FREQ2FBIN(5400, 0),
397 FREQ2FBIN(5500, 0),
398 FREQ2FBIN(5600, 0),
399 FREQ2FBIN(5725, 0),
400 FREQ2FBIN(5825, 0)
402 .calTarget_freqbin_5GHT20 = {
403 FREQ2FBIN(5180, 0),
404 FREQ2FBIN(5240, 0),
405 FREQ2FBIN(5320, 0),
406 FREQ2FBIN(5500, 0),
407 FREQ2FBIN(5700, 0),
408 FREQ2FBIN(5745, 0),
409 FREQ2FBIN(5725, 0),
410 FREQ2FBIN(5825, 0)
412 .calTarget_freqbin_5GHT40 = {
413 FREQ2FBIN(5180, 0),
414 FREQ2FBIN(5240, 0),
415 FREQ2FBIN(5320, 0),
416 FREQ2FBIN(5500, 0),
417 FREQ2FBIN(5700, 0),
418 FREQ2FBIN(5745, 0),
419 FREQ2FBIN(5725, 0),
420 FREQ2FBIN(5825, 0)
422 .calTargetPower5G = {
423 /* 6-24,36,48,54 */
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} },
431 { {20, 20, 20, 10} },
433 .calTargetPower5GHT20 = {
435 * 0_8_16,1-3_9-11_17-19,
436 * 4,5,6,7,12,13,14,15,20,21,22,23
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} },
445 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
447 .calTargetPower5GHT40 = {
449 * 0_8_16,1-3_9-11_17-19,
450 * 4,5,6,7,12,13,14,15,20,21,22,23
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} },
459 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
461 .ctlIndex_5G = {
462 0x10, 0x16, 0x18, 0x40, 0x46,
463 0x48, 0x30, 0x36, 0x38
465 .ctl_freqbin_5G = {
467 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
468 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
469 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
470 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
471 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
472 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
473 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
474 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
477 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
478 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
479 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
480 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
481 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
482 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
483 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
484 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
488 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
489 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
490 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
491 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
492 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
493 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
494 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
495 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
499 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
500 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
501 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
502 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
503 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
504 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
505 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
506 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
510 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
511 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
512 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
513 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
514 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
515 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
516 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
517 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
521 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
522 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
523 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
524 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
525 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
526 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
527 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
528 /* Data[5].ctlEdges[7].bChannel */ 0xFF
532 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
533 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
534 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
535 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
536 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
537 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
538 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
539 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
543 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
544 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
545 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
546 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
547 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
548 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
549 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
550 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
554 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
555 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
556 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
557 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
558 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
559 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
560 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
561 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
564 .ctlPowerData_5G = {
567 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
568 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
573 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
574 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
579 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
580 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
585 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
586 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
591 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
592 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
597 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
598 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
603 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
604 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
609 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
610 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
615 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
616 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
622 static const struct ar9300_eeprom ar9300_x113 = {
623 .eepromVersion = 2,
624 .templateVersion = 6,
625 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
626 .custData = {"x113-023-f0000"},
627 .baseEepHeader = {
628 .regDmn = { LE16(0), LE16(0x1f) },
629 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
630 .opCapFlags = {
631 .opFlags = AR5416_OPFLAGS_11A,
632 .eepMisc = 0,
634 .rfSilent = 0,
635 .blueToothOptions = 0,
636 .deviceCap = 0,
637 .deviceType = 5, /* takes lower byte in eeprom location */
638 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
639 .params_for_tuning_caps = {0, 0},
640 .featureEnable = 0x0d,
642 * bit0 - enable tx temp comp - disabled
643 * bit1 - enable tx volt comp - disabled
644 * bit2 - enable fastClock - enabled
645 * bit3 - enable doubling - enabled
646 * bit4 - enable internal regulator - disabled
647 * bit5 - enable pa predistortion - disabled
649 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
650 .eepromWriteEnableGpio = 6,
651 .wlanDisableGpio = 0,
652 .wlanLedGpio = 8,
653 .rxBandSelectGpio = 0xff,
654 .txrxgain = 0x21,
655 .swreg = 0,
657 .modalHeader2G = {
658 /* ar9300_modal_eep_header 2g */
659 /* 4 idle,t1,t2,b(4 bits per setting) */
660 .antCtrlCommon = LE32(0x110),
661 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
662 .antCtrlCommon2 = LE32(0x44444),
665 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
666 * rx1, rx12, b (2 bits each)
668 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
671 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
672 * for ar9280 (0xa20c/b20c 5:0)
674 .xatten1DB = {0, 0, 0},
677 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
678 * for ar9280 (0xa20c/b20c 16:12
680 .xatten1Margin = {0, 0, 0},
681 .tempSlope = 25,
682 .voltSlope = 0,
685 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
686 * channels in usual fbin coding format
688 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
691 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
692 * if the register is per chain
694 .noiseFloorThreshCh = {-1, 0, 0},
695 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
696 .quick_drop = 0,
697 .xpaBiasLvl = 0,
698 .txFrameToDataStart = 0x0e,
699 .txFrameToPaOn = 0x0e,
700 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
701 .antennaGain = 0,
702 .switchSettling = 0x2c,
703 .adcDesiredSize = -30,
704 .txEndToXpaOff = 0,
705 .txEndToRxOn = 0x2,
706 .txFrameToXpaOn = 0xe,
707 .thresh62 = 28,
708 .papdRateMaskHt20 = LE32(0x0c80c080),
709 .papdRateMaskHt40 = LE32(0x0080c080),
710 .xlna_bias_strength = 0,
711 .futureModal = {
712 0, 0, 0, 0, 0, 0, 0,
715 .base_ext1 = {
716 .ant_div_control = 0,
717 .future = {0, 0, 0},
718 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
720 .calFreqPier2G = {
721 FREQ2FBIN(2412, 1),
722 FREQ2FBIN(2437, 1),
723 FREQ2FBIN(2472, 1),
725 /* ar9300_cal_data_per_freq_op_loop 2g */
726 .calPierData2G = {
727 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
728 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
729 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
731 .calTarget_freqbin_Cck = {
732 FREQ2FBIN(2412, 1),
733 FREQ2FBIN(2472, 1),
735 .calTarget_freqbin_2G = {
736 FREQ2FBIN(2412, 1),
737 FREQ2FBIN(2437, 1),
738 FREQ2FBIN(2472, 1)
740 .calTarget_freqbin_2GHT20 = {
741 FREQ2FBIN(2412, 1),
742 FREQ2FBIN(2437, 1),
743 FREQ2FBIN(2472, 1)
745 .calTarget_freqbin_2GHT40 = {
746 FREQ2FBIN(2412, 1),
747 FREQ2FBIN(2437, 1),
748 FREQ2FBIN(2472, 1)
750 .calTargetPowerCck = {
751 /* 1L-5L,5S,11L,11S */
752 { {34, 34, 34, 34} },
753 { {34, 34, 34, 34} },
755 .calTargetPower2G = {
756 /* 6-24,36,48,54 */
757 { {34, 34, 32, 32} },
758 { {34, 34, 32, 32} },
759 { {34, 34, 32, 32} },
761 .calTargetPower2GHT20 = {
762 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
763 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
764 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
766 .calTargetPower2GHT40 = {
767 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
768 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
769 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
771 .ctlIndex_2G = {
772 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
773 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
775 .ctl_freqbin_2G = {
777 FREQ2FBIN(2412, 1),
778 FREQ2FBIN(2417, 1),
779 FREQ2FBIN(2457, 1),
780 FREQ2FBIN(2462, 1)
783 FREQ2FBIN(2412, 1),
784 FREQ2FBIN(2417, 1),
785 FREQ2FBIN(2462, 1),
786 0xFF,
790 FREQ2FBIN(2412, 1),
791 FREQ2FBIN(2417, 1),
792 FREQ2FBIN(2462, 1),
793 0xFF,
796 FREQ2FBIN(2422, 1),
797 FREQ2FBIN(2427, 1),
798 FREQ2FBIN(2447, 1),
799 FREQ2FBIN(2452, 1)
803 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
804 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
805 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
806 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
810 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
811 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
812 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
817 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
818 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
819 FREQ2FBIN(2472, 1),
824 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
825 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
826 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
827 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
831 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
832 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
833 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
837 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
838 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
839 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
844 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
845 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
846 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
851 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
852 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
853 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
854 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
857 .ctlPowerData_2G = {
858 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
859 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
860 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
862 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
863 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
864 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
866 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
867 { { 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) } },
870 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
871 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
872 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
874 .modalHeader5G = {
875 /* 4 idle,t1,t2,b (4 bits per setting) */
876 .antCtrlCommon = LE32(0x220),
877 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
878 .antCtrlCommon2 = LE32(0x11111),
879 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
880 .antCtrlChain = {
881 LE16(0x150), LE16(0x150), LE16(0x150),
883 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
884 .xatten1DB = {0, 0, 0},
887 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
888 * for merlin (0xa20c/b20c 16:12
890 .xatten1Margin = {0, 0, 0},
891 .tempSlope = 68,
892 .voltSlope = 0,
893 /* spurChans spur channels in usual fbin coding format */
894 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
895 /* noiseFloorThreshCh Check if the register is per chain */
896 .noiseFloorThreshCh = {-1, 0, 0},
897 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
898 .quick_drop = 0,
899 .xpaBiasLvl = 0xf,
900 .txFrameToDataStart = 0x0e,
901 .txFrameToPaOn = 0x0e,
902 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
903 .antennaGain = 0,
904 .switchSettling = 0x2d,
905 .adcDesiredSize = -30,
906 .txEndToXpaOff = 0,
907 .txEndToRxOn = 0x2,
908 .txFrameToXpaOn = 0xe,
909 .thresh62 = 28,
910 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
911 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
912 .xlna_bias_strength = 0,
913 .futureModal = {
914 0, 0, 0, 0, 0, 0, 0,
917 .base_ext2 = {
918 .tempSlopeLow = 72,
919 .tempSlopeHigh = 105,
920 .xatten1DBLow = {0, 0, 0},
921 .xatten1MarginLow = {0, 0, 0},
922 .xatten1DBHigh = {0, 0, 0},
923 .xatten1MarginHigh = {0, 0, 0}
925 .calFreqPier5G = {
926 FREQ2FBIN(5180, 0),
927 FREQ2FBIN(5240, 0),
928 FREQ2FBIN(5320, 0),
929 FREQ2FBIN(5400, 0),
930 FREQ2FBIN(5500, 0),
931 FREQ2FBIN(5600, 0),
932 FREQ2FBIN(5745, 0),
933 FREQ2FBIN(5785, 0)
935 .calPierData5G = {
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},
943 {0, 0, 0, 0, 0},
944 {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},
953 {0, 0, 0, 0, 0},
954 {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},
963 {0, 0, 0, 0, 0},
964 {0, 0, 0, 0, 0},
968 .calTarget_freqbin_5G = {
969 FREQ2FBIN(5180, 0),
970 FREQ2FBIN(5220, 0),
971 FREQ2FBIN(5320, 0),
972 FREQ2FBIN(5400, 0),
973 FREQ2FBIN(5500, 0),
974 FREQ2FBIN(5600, 0),
975 FREQ2FBIN(5745, 0),
976 FREQ2FBIN(5785, 0)
978 .calTarget_freqbin_5GHT20 = {
979 FREQ2FBIN(5180, 0),
980 FREQ2FBIN(5240, 0),
981 FREQ2FBIN(5320, 0),
982 FREQ2FBIN(5400, 0),
983 FREQ2FBIN(5500, 0),
984 FREQ2FBIN(5700, 0),
985 FREQ2FBIN(5745, 0),
986 FREQ2FBIN(5825, 0)
988 .calTarget_freqbin_5GHT40 = {
989 FREQ2FBIN(5190, 0),
990 FREQ2FBIN(5230, 0),
991 FREQ2FBIN(5320, 0),
992 FREQ2FBIN(5410, 0),
993 FREQ2FBIN(5510, 0),
994 FREQ2FBIN(5670, 0),
995 FREQ2FBIN(5755, 0),
996 FREQ2FBIN(5825, 0)
998 .calTargetPower5G = {
999 /* 6-24,36,48,54 */
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} },
1006 { {42, 40, 40, 34} },
1007 { {42, 40, 40, 34} },
1009 .calTargetPower5GHT20 = {
1011 * 0_8_16,1-3_9-11_17-19,
1012 * 4,5,6,7,12,13,14,15,20,21,22,23
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 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1019 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1020 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1021 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1023 .calTargetPower5GHT40 = {
1025 * 0_8_16,1-3_9-11_17-19,
1026 * 4,5,6,7,12,13,14,15,20,21,22,23
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 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1033 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1034 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1035 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1037 .ctlIndex_5G = {
1038 0x10, 0x16, 0x18, 0x40, 0x46,
1039 0x48, 0x30, 0x36, 0x38
1041 .ctl_freqbin_5G = {
1043 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1044 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1045 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1046 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1047 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1048 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1049 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1050 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1053 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1054 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1055 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1056 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1057 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1058 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1059 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1060 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1064 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1065 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1066 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1067 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1068 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1069 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1070 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1071 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1075 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1076 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1077 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1078 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1079 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1080 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1081 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1082 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1086 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1087 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1088 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1089 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1090 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1091 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1092 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1093 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1097 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1098 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1099 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1100 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1101 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1102 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1103 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1104 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1108 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1109 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1110 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1111 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1112 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1113 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1114 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1115 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1119 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1120 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1121 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1122 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1123 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1124 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1125 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1126 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1130 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1131 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1132 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1133 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1134 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1135 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1136 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1137 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1140 .ctlPowerData_5G = {
1143 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1144 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1149 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1150 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1155 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1156 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1161 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1162 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1167 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1168 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1173 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1174 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1179 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1180 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1185 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1186 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1191 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1192 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1199 static const struct ar9300_eeprom ar9300_h112 = {
1200 .eepromVersion = 2,
1201 .templateVersion = 3,
1202 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1203 .custData = {"h112-241-f0000"},
1204 .baseEepHeader = {
1205 .regDmn = { LE16(0), LE16(0x1f) },
1206 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1207 .opCapFlags = {
1208 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1209 .eepMisc = 0,
1211 .rfSilent = 0,
1212 .blueToothOptions = 0,
1213 .deviceCap = 0,
1214 .deviceType = 5, /* takes lower byte in eeprom location */
1215 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1216 .params_for_tuning_caps = {0, 0},
1217 .featureEnable = 0x0d,
1219 * bit0 - enable tx temp comp - disabled
1220 * bit1 - enable tx volt comp - disabled
1221 * bit2 - enable fastClock - enabled
1222 * bit3 - enable doubling - enabled
1223 * bit4 - enable internal regulator - disabled
1224 * bit5 - enable pa predistortion - disabled
1226 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1227 .eepromWriteEnableGpio = 6,
1228 .wlanDisableGpio = 0,
1229 .wlanLedGpio = 8,
1230 .rxBandSelectGpio = 0xff,
1231 .txrxgain = 0x10,
1232 .swreg = 0,
1234 .modalHeader2G = {
1235 /* ar9300_modal_eep_header 2g */
1236 /* 4 idle,t1,t2,b(4 bits per setting) */
1237 .antCtrlCommon = LE32(0x110),
1238 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1239 .antCtrlCommon2 = LE32(0x44444),
1242 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1243 * rx1, rx12, b (2 bits each)
1245 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1248 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1249 * for ar9280 (0xa20c/b20c 5:0)
1251 .xatten1DB = {0, 0, 0},
1254 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1255 * for ar9280 (0xa20c/b20c 16:12
1257 .xatten1Margin = {0, 0, 0},
1258 .tempSlope = 25,
1259 .voltSlope = 0,
1262 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1263 * channels in usual fbin coding format
1265 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1268 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1269 * if the register is per chain
1271 .noiseFloorThreshCh = {-1, 0, 0},
1272 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1273 .quick_drop = 0,
1274 .xpaBiasLvl = 0,
1275 .txFrameToDataStart = 0x0e,
1276 .txFrameToPaOn = 0x0e,
1277 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1278 .antennaGain = 0,
1279 .switchSettling = 0x2c,
1280 .adcDesiredSize = -30,
1281 .txEndToXpaOff = 0,
1282 .txEndToRxOn = 0x2,
1283 .txFrameToXpaOn = 0xe,
1284 .thresh62 = 28,
1285 .papdRateMaskHt20 = LE32(0x0c80c080),
1286 .papdRateMaskHt40 = LE32(0x0080c080),
1287 .xlna_bias_strength = 0,
1288 .futureModal = {
1289 0, 0, 0, 0, 0, 0, 0,
1292 .base_ext1 = {
1293 .ant_div_control = 0,
1294 .future = {0, 0, 0},
1295 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1297 .calFreqPier2G = {
1298 FREQ2FBIN(2412, 1),
1299 FREQ2FBIN(2437, 1),
1300 FREQ2FBIN(2462, 1),
1302 /* ar9300_cal_data_per_freq_op_loop 2g */
1303 .calPierData2G = {
1304 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1305 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1306 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1308 .calTarget_freqbin_Cck = {
1309 FREQ2FBIN(2412, 1),
1310 FREQ2FBIN(2472, 1),
1312 .calTarget_freqbin_2G = {
1313 FREQ2FBIN(2412, 1),
1314 FREQ2FBIN(2437, 1),
1315 FREQ2FBIN(2472, 1)
1317 .calTarget_freqbin_2GHT20 = {
1318 FREQ2FBIN(2412, 1),
1319 FREQ2FBIN(2437, 1),
1320 FREQ2FBIN(2472, 1)
1322 .calTarget_freqbin_2GHT40 = {
1323 FREQ2FBIN(2412, 1),
1324 FREQ2FBIN(2437, 1),
1325 FREQ2FBIN(2472, 1)
1327 .calTargetPowerCck = {
1328 /* 1L-5L,5S,11L,11S */
1329 { {34, 34, 34, 34} },
1330 { {34, 34, 34, 34} },
1332 .calTargetPower2G = {
1333 /* 6-24,36,48,54 */
1334 { {34, 34, 32, 32} },
1335 { {34, 34, 32, 32} },
1336 { {34, 34, 32, 32} },
1338 .calTargetPower2GHT20 = {
1339 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1340 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1341 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1343 .calTargetPower2GHT40 = {
1344 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1345 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1346 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1348 .ctlIndex_2G = {
1349 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1350 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1352 .ctl_freqbin_2G = {
1354 FREQ2FBIN(2412, 1),
1355 FREQ2FBIN(2417, 1),
1356 FREQ2FBIN(2457, 1),
1357 FREQ2FBIN(2462, 1)
1360 FREQ2FBIN(2412, 1),
1361 FREQ2FBIN(2417, 1),
1362 FREQ2FBIN(2462, 1),
1363 0xFF,
1367 FREQ2FBIN(2412, 1),
1368 FREQ2FBIN(2417, 1),
1369 FREQ2FBIN(2462, 1),
1370 0xFF,
1373 FREQ2FBIN(2422, 1),
1374 FREQ2FBIN(2427, 1),
1375 FREQ2FBIN(2447, 1),
1376 FREQ2FBIN(2452, 1)
1380 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1381 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1382 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1383 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1387 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1388 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1389 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1394 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1395 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1396 FREQ2FBIN(2472, 1),
1401 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1402 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1403 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1404 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1408 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1409 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1410 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1414 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1415 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1416 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1421 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1422 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1423 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1428 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1429 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1430 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1431 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1434 .ctlPowerData_2G = {
1435 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1436 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1437 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1439 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
1440 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1441 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1443 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), 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, 0), CTL(60, 0) } },
1447 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1448 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1449 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1451 .modalHeader5G = {
1452 /* 4 idle,t1,t2,b (4 bits per setting) */
1453 .antCtrlCommon = LE32(0x220),
1454 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1455 .antCtrlCommon2 = LE32(0x44444),
1456 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1457 .antCtrlChain = {
1458 LE16(0x150), LE16(0x150), LE16(0x150),
1460 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1461 .xatten1DB = {0, 0, 0},
1464 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1465 * for merlin (0xa20c/b20c 16:12
1467 .xatten1Margin = {0, 0, 0},
1468 .tempSlope = 45,
1469 .voltSlope = 0,
1470 /* spurChans spur channels in usual fbin coding format */
1471 .spurChans = {0, 0, 0, 0, 0},
1472 /* noiseFloorThreshCh Check if the register is per chain */
1473 .noiseFloorThreshCh = {-1, 0, 0},
1474 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1475 .quick_drop = 0,
1476 .xpaBiasLvl = 0,
1477 .txFrameToDataStart = 0x0e,
1478 .txFrameToPaOn = 0x0e,
1479 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1480 .antennaGain = 0,
1481 .switchSettling = 0x2d,
1482 .adcDesiredSize = -30,
1483 .txEndToXpaOff = 0,
1484 .txEndToRxOn = 0x2,
1485 .txFrameToXpaOn = 0xe,
1486 .thresh62 = 28,
1487 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1488 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1489 .xlna_bias_strength = 0,
1490 .futureModal = {
1491 0, 0, 0, 0, 0, 0, 0,
1494 .base_ext2 = {
1495 .tempSlopeLow = 40,
1496 .tempSlopeHigh = 50,
1497 .xatten1DBLow = {0, 0, 0},
1498 .xatten1MarginLow = {0, 0, 0},
1499 .xatten1DBHigh = {0, 0, 0},
1500 .xatten1MarginHigh = {0, 0, 0}
1502 .calFreqPier5G = {
1503 FREQ2FBIN(5180, 0),
1504 FREQ2FBIN(5220, 0),
1505 FREQ2FBIN(5320, 0),
1506 FREQ2FBIN(5400, 0),
1507 FREQ2FBIN(5500, 0),
1508 FREQ2FBIN(5600, 0),
1509 FREQ2FBIN(5700, 0),
1510 FREQ2FBIN(5785, 0)
1512 .calPierData5G = {
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},
1519 {0, 0, 0, 0, 0},
1520 {0, 0, 0, 0, 0},
1521 {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},
1529 {0, 0, 0, 0, 0},
1530 {0, 0, 0, 0, 0},
1531 {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},
1539 {0, 0, 0, 0, 0},
1540 {0, 0, 0, 0, 0},
1541 {0, 0, 0, 0, 0},
1545 .calTarget_freqbin_5G = {
1546 FREQ2FBIN(5180, 0),
1547 FREQ2FBIN(5240, 0),
1548 FREQ2FBIN(5320, 0),
1549 FREQ2FBIN(5400, 0),
1550 FREQ2FBIN(5500, 0),
1551 FREQ2FBIN(5600, 0),
1552 FREQ2FBIN(5700, 0),
1553 FREQ2FBIN(5825, 0)
1555 .calTarget_freqbin_5GHT20 = {
1556 FREQ2FBIN(5180, 0),
1557 FREQ2FBIN(5240, 0),
1558 FREQ2FBIN(5320, 0),
1559 FREQ2FBIN(5400, 0),
1560 FREQ2FBIN(5500, 0),
1561 FREQ2FBIN(5700, 0),
1562 FREQ2FBIN(5745, 0),
1563 FREQ2FBIN(5825, 0)
1565 .calTarget_freqbin_5GHT40 = {
1566 FREQ2FBIN(5180, 0),
1567 FREQ2FBIN(5240, 0),
1568 FREQ2FBIN(5320, 0),
1569 FREQ2FBIN(5400, 0),
1570 FREQ2FBIN(5500, 0),
1571 FREQ2FBIN(5700, 0),
1572 FREQ2FBIN(5745, 0),
1573 FREQ2FBIN(5825, 0)
1575 .calTargetPower5G = {
1576 /* 6-24,36,48,54 */
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} },
1582 { {30, 30, 28, 24} },
1583 { {30, 30, 28, 24} },
1584 { {30, 30, 28, 24} },
1586 .calTargetPower5GHT20 = {
1588 * 0_8_16,1-3_9-11_17-19,
1589 * 4,5,6,7,12,13,14,15,20,21,22,23
1591 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1592 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1593 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1594 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1595 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1596 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1597 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1598 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1600 .calTargetPower5GHT40 = {
1602 * 0_8_16,1-3_9-11_17-19,
1603 * 4,5,6,7,12,13,14,15,20,21,22,23
1605 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1606 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1607 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1608 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1609 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1610 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1611 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1612 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1614 .ctlIndex_5G = {
1615 0x10, 0x16, 0x18, 0x40, 0x46,
1616 0x48, 0x30, 0x36, 0x38
1618 .ctl_freqbin_5G = {
1620 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1621 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1622 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1623 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1624 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1625 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1626 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1627 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1630 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1631 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1632 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1633 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1634 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1635 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1636 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1637 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1641 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1642 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1643 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1644 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1645 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1646 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1647 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1648 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1652 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1653 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1654 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1655 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1656 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1657 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1658 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1659 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1663 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1664 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1665 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1666 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1667 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1668 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1669 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1670 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1674 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1675 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1676 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1677 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1678 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1679 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1680 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1681 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1685 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1686 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1687 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1688 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1689 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1690 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1691 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1692 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1696 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1697 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1698 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1699 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1700 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1701 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1702 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1703 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1707 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1708 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1709 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1710 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1711 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1712 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1713 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1714 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1717 .ctlPowerData_5G = {
1720 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1721 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1726 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1727 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1732 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1733 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1738 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1739 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1744 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1745 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1750 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1751 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1756 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1757 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1762 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1763 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1768 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1769 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1776 static const struct ar9300_eeprom ar9300_x112 = {
1777 .eepromVersion = 2,
1778 .templateVersion = 5,
1779 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1780 .custData = {"x112-041-f0000"},
1781 .baseEepHeader = {
1782 .regDmn = { LE16(0), LE16(0x1f) },
1783 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1784 .opCapFlags = {
1785 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1786 .eepMisc = 0,
1788 .rfSilent = 0,
1789 .blueToothOptions = 0,
1790 .deviceCap = 0,
1791 .deviceType = 5, /* takes lower byte in eeprom location */
1792 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1793 .params_for_tuning_caps = {0, 0},
1794 .featureEnable = 0x0d,
1796 * bit0 - enable tx temp comp - disabled
1797 * bit1 - enable tx volt comp - disabled
1798 * bit2 - enable fastclock - enabled
1799 * bit3 - enable doubling - enabled
1800 * bit4 - enable internal regulator - disabled
1801 * bit5 - enable pa predistortion - disabled
1803 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1804 .eepromWriteEnableGpio = 6,
1805 .wlanDisableGpio = 0,
1806 .wlanLedGpio = 8,
1807 .rxBandSelectGpio = 0xff,
1808 .txrxgain = 0x0,
1809 .swreg = 0,
1811 .modalHeader2G = {
1812 /* ar9300_modal_eep_header 2g */
1813 /* 4 idle,t1,t2,b(4 bits per setting) */
1814 .antCtrlCommon = LE32(0x110),
1815 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1816 .antCtrlCommon2 = LE32(0x22222),
1819 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1820 * rx1, rx12, b (2 bits each)
1822 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1825 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1826 * for ar9280 (0xa20c/b20c 5:0)
1828 .xatten1DB = {0x1b, 0x1b, 0x1b},
1831 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1832 * for ar9280 (0xa20c/b20c 16:12
1834 .xatten1Margin = {0x15, 0x15, 0x15},
1835 .tempSlope = 50,
1836 .voltSlope = 0,
1839 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1840 * channels in usual fbin coding format
1842 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1845 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1846 * if the register is per chain
1848 .noiseFloorThreshCh = {-1, 0, 0},
1849 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1850 .quick_drop = 0,
1851 .xpaBiasLvl = 0,
1852 .txFrameToDataStart = 0x0e,
1853 .txFrameToPaOn = 0x0e,
1854 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1855 .antennaGain = 0,
1856 .switchSettling = 0x2c,
1857 .adcDesiredSize = -30,
1858 .txEndToXpaOff = 0,
1859 .txEndToRxOn = 0x2,
1860 .txFrameToXpaOn = 0xe,
1861 .thresh62 = 28,
1862 .papdRateMaskHt20 = LE32(0x0c80c080),
1863 .papdRateMaskHt40 = LE32(0x0080c080),
1864 .xlna_bias_strength = 0,
1865 .futureModal = {
1866 0, 0, 0, 0, 0, 0, 0,
1869 .base_ext1 = {
1870 .ant_div_control = 0,
1871 .future = {0, 0, 0},
1872 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1874 .calFreqPier2G = {
1875 FREQ2FBIN(2412, 1),
1876 FREQ2FBIN(2437, 1),
1877 FREQ2FBIN(2472, 1),
1879 /* ar9300_cal_data_per_freq_op_loop 2g */
1880 .calPierData2G = {
1881 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1882 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1883 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1885 .calTarget_freqbin_Cck = {
1886 FREQ2FBIN(2412, 1),
1887 FREQ2FBIN(2472, 1),
1889 .calTarget_freqbin_2G = {
1890 FREQ2FBIN(2412, 1),
1891 FREQ2FBIN(2437, 1),
1892 FREQ2FBIN(2472, 1)
1894 .calTarget_freqbin_2GHT20 = {
1895 FREQ2FBIN(2412, 1),
1896 FREQ2FBIN(2437, 1),
1897 FREQ2FBIN(2472, 1)
1899 .calTarget_freqbin_2GHT40 = {
1900 FREQ2FBIN(2412, 1),
1901 FREQ2FBIN(2437, 1),
1902 FREQ2FBIN(2472, 1)
1904 .calTargetPowerCck = {
1905 /* 1L-5L,5S,11L,11s */
1906 { {38, 38, 38, 38} },
1907 { {38, 38, 38, 38} },
1909 .calTargetPower2G = {
1910 /* 6-24,36,48,54 */
1911 { {38, 38, 36, 34} },
1912 { {38, 38, 36, 34} },
1913 { {38, 38, 34, 32} },
1915 .calTargetPower2GHT20 = {
1916 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1917 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1918 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1920 .calTargetPower2GHT40 = {
1921 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1922 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1923 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1925 .ctlIndex_2G = {
1926 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1927 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1929 .ctl_freqbin_2G = {
1931 FREQ2FBIN(2412, 1),
1932 FREQ2FBIN(2417, 1),
1933 FREQ2FBIN(2457, 1),
1934 FREQ2FBIN(2462, 1)
1937 FREQ2FBIN(2412, 1),
1938 FREQ2FBIN(2417, 1),
1939 FREQ2FBIN(2462, 1),
1940 0xFF,
1944 FREQ2FBIN(2412, 1),
1945 FREQ2FBIN(2417, 1),
1946 FREQ2FBIN(2462, 1),
1947 0xFF,
1950 FREQ2FBIN(2422, 1),
1951 FREQ2FBIN(2427, 1),
1952 FREQ2FBIN(2447, 1),
1953 FREQ2FBIN(2452, 1)
1957 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1958 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1959 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1960 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1964 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1965 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1966 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1971 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1972 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1973 FREQ2FBIN(2472, 1),
1978 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
1979 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
1980 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
1981 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
1985 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1986 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1987 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1991 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1992 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1993 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1998 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1999 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2000 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2005 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2006 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2007 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2008 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2011 .ctlPowerData_2G = {
2012 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2013 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2014 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2016 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), 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, 1), CTL(60, 0) } },
2021 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2022 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2024 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2025 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2026 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2028 .modalHeader5G = {
2029 /* 4 idle,t1,t2,b (4 bits per setting) */
2030 .antCtrlCommon = LE32(0x110),
2031 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2032 .antCtrlCommon2 = LE32(0x22222),
2033 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2034 .antCtrlChain = {
2035 LE16(0x0), LE16(0x0), LE16(0x0),
2037 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2038 .xatten1DB = {0x13, 0x19, 0x17},
2041 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2042 * for merlin (0xa20c/b20c 16:12
2044 .xatten1Margin = {0x19, 0x19, 0x19},
2045 .tempSlope = 70,
2046 .voltSlope = 15,
2047 /* spurChans spur channels in usual fbin coding format */
2048 .spurChans = {0, 0, 0, 0, 0},
2049 /* noiseFloorThreshch check if the register is per chain */
2050 .noiseFloorThreshCh = {-1, 0, 0},
2051 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2052 .quick_drop = 0,
2053 .xpaBiasLvl = 0,
2054 .txFrameToDataStart = 0x0e,
2055 .txFrameToPaOn = 0x0e,
2056 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2057 .antennaGain = 0,
2058 .switchSettling = 0x2d,
2059 .adcDesiredSize = -30,
2060 .txEndToXpaOff = 0,
2061 .txEndToRxOn = 0x2,
2062 .txFrameToXpaOn = 0xe,
2063 .thresh62 = 28,
2064 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2065 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2066 .xlna_bias_strength = 0,
2067 .futureModal = {
2068 0, 0, 0, 0, 0, 0, 0,
2071 .base_ext2 = {
2072 .tempSlopeLow = 72,
2073 .tempSlopeHigh = 105,
2074 .xatten1DBLow = {0x10, 0x14, 0x10},
2075 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2076 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2077 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2079 .calFreqPier5G = {
2080 FREQ2FBIN(5180, 0),
2081 FREQ2FBIN(5220, 0),
2082 FREQ2FBIN(5320, 0),
2083 FREQ2FBIN(5400, 0),
2084 FREQ2FBIN(5500, 0),
2085 FREQ2FBIN(5600, 0),
2086 FREQ2FBIN(5700, 0),
2087 FREQ2FBIN(5785, 0)
2089 .calPierData5G = {
2091 {0, 0, 0, 0, 0},
2092 {0, 0, 0, 0, 0},
2093 {0, 0, 0, 0, 0},
2094 {0, 0, 0, 0, 0},
2095 {0, 0, 0, 0, 0},
2096 {0, 0, 0, 0, 0},
2097 {0, 0, 0, 0, 0},
2098 {0, 0, 0, 0, 0},
2101 {0, 0, 0, 0, 0},
2102 {0, 0, 0, 0, 0},
2103 {0, 0, 0, 0, 0},
2104 {0, 0, 0, 0, 0},
2105 {0, 0, 0, 0, 0},
2106 {0, 0, 0, 0, 0},
2107 {0, 0, 0, 0, 0},
2108 {0, 0, 0, 0, 0},
2111 {0, 0, 0, 0, 0},
2112 {0, 0, 0, 0, 0},
2113 {0, 0, 0, 0, 0},
2114 {0, 0, 0, 0, 0},
2115 {0, 0, 0, 0, 0},
2116 {0, 0, 0, 0, 0},
2117 {0, 0, 0, 0, 0},
2118 {0, 0, 0, 0, 0},
2122 .calTarget_freqbin_5G = {
2123 FREQ2FBIN(5180, 0),
2124 FREQ2FBIN(5220, 0),
2125 FREQ2FBIN(5320, 0),
2126 FREQ2FBIN(5400, 0),
2127 FREQ2FBIN(5500, 0),
2128 FREQ2FBIN(5600, 0),
2129 FREQ2FBIN(5725, 0),
2130 FREQ2FBIN(5825, 0)
2132 .calTarget_freqbin_5GHT20 = {
2133 FREQ2FBIN(5180, 0),
2134 FREQ2FBIN(5220, 0),
2135 FREQ2FBIN(5320, 0),
2136 FREQ2FBIN(5400, 0),
2137 FREQ2FBIN(5500, 0),
2138 FREQ2FBIN(5600, 0),
2139 FREQ2FBIN(5725, 0),
2140 FREQ2FBIN(5825, 0)
2142 .calTarget_freqbin_5GHT40 = {
2143 FREQ2FBIN(5180, 0),
2144 FREQ2FBIN(5220, 0),
2145 FREQ2FBIN(5320, 0),
2146 FREQ2FBIN(5400, 0),
2147 FREQ2FBIN(5500, 0),
2148 FREQ2FBIN(5600, 0),
2149 FREQ2FBIN(5725, 0),
2150 FREQ2FBIN(5825, 0)
2152 .calTargetPower5G = {
2153 /* 6-24,36,48,54 */
2154 { {32, 32, 28, 26} },
2155 { {32, 32, 28, 26} },
2156 { {32, 32, 28, 26} },
2157 { {32, 32, 26, 24} },
2158 { {32, 32, 26, 24} },
2159 { {32, 32, 24, 22} },
2160 { {30, 30, 24, 22} },
2161 { {30, 30, 24, 22} },
2163 .calTargetPower5GHT20 = {
2165 * 0_8_16,1-3_9-11_17-19,
2166 * 4,5,6,7,12,13,14,15,20,21,22,23
2168 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2169 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2170 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2171 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2172 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2173 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2174 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2175 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2177 .calTargetPower5GHT40 = {
2179 * 0_8_16,1-3_9-11_17-19,
2180 * 4,5,6,7,12,13,14,15,20,21,22,23
2182 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2183 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2184 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2185 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2186 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2187 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2188 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2189 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2191 .ctlIndex_5G = {
2192 0x10, 0x16, 0x18, 0x40, 0x46,
2193 0x48, 0x30, 0x36, 0x38
2195 .ctl_freqbin_5G = {
2197 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2198 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2199 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2200 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2201 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2202 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2203 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2204 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2207 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2208 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2209 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2210 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2211 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2212 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2213 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2214 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2218 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2219 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2220 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2221 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2222 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2223 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2224 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2225 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2229 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2230 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2231 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2232 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2233 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2234 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2235 /* Data[3].ctledges[6].bchannel */ 0xFF,
2236 /* Data[3].ctledges[7].bchannel */ 0xFF,
2240 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2241 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2242 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2243 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2244 /* Data[4].ctledges[4].bchannel */ 0xFF,
2245 /* Data[4].ctledges[5].bchannel */ 0xFF,
2246 /* Data[4].ctledges[6].bchannel */ 0xFF,
2247 /* Data[4].ctledges[7].bchannel */ 0xFF,
2251 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2252 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2253 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2254 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2255 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2256 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2257 /* Data[5].ctledges[6].bchannel */ 0xFF,
2258 /* Data[5].ctledges[7].bchannel */ 0xFF
2262 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2263 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2264 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2265 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2266 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2267 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2268 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2269 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2273 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2274 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2275 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2276 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2277 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2278 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2279 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2280 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2284 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2285 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2286 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2287 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2288 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2289 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2290 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2291 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2294 .ctlPowerData_5G = {
2297 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2298 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2303 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2304 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2309 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2310 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2315 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2316 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2321 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2322 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2327 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2328 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2333 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2334 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2339 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2340 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2345 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2346 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2352 static const struct ar9300_eeprom ar9300_h116 = {
2353 .eepromVersion = 2,
2354 .templateVersion = 4,
2355 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2356 .custData = {"h116-041-f0000"},
2357 .baseEepHeader = {
2358 .regDmn = { LE16(0), LE16(0x1f) },
2359 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2360 .opCapFlags = {
2361 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2362 .eepMisc = 0,
2364 .rfSilent = 0,
2365 .blueToothOptions = 0,
2366 .deviceCap = 0,
2367 .deviceType = 5, /* takes lower byte in eeprom location */
2368 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2369 .params_for_tuning_caps = {0, 0},
2370 .featureEnable = 0x0d,
2372 * bit0 - enable tx temp comp - disabled
2373 * bit1 - enable tx volt comp - disabled
2374 * bit2 - enable fastClock - enabled
2375 * bit3 - enable doubling - enabled
2376 * bit4 - enable internal regulator - disabled
2377 * bit5 - enable pa predistortion - disabled
2379 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2380 .eepromWriteEnableGpio = 6,
2381 .wlanDisableGpio = 0,
2382 .wlanLedGpio = 8,
2383 .rxBandSelectGpio = 0xff,
2384 .txrxgain = 0x10,
2385 .swreg = 0,
2387 .modalHeader2G = {
2388 /* ar9300_modal_eep_header 2g */
2389 /* 4 idle,t1,t2,b(4 bits per setting) */
2390 .antCtrlCommon = LE32(0x110),
2391 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2392 .antCtrlCommon2 = LE32(0x44444),
2395 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2396 * rx1, rx12, b (2 bits each)
2398 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2401 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2402 * for ar9280 (0xa20c/b20c 5:0)
2404 .xatten1DB = {0x1f, 0x1f, 0x1f},
2407 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2408 * for ar9280 (0xa20c/b20c 16:12
2410 .xatten1Margin = {0x12, 0x12, 0x12},
2411 .tempSlope = 25,
2412 .voltSlope = 0,
2415 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2416 * channels in usual fbin coding format
2418 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2421 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2422 * if the register is per chain
2424 .noiseFloorThreshCh = {-1, 0, 0},
2425 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2426 .quick_drop = 0,
2427 .xpaBiasLvl = 0,
2428 .txFrameToDataStart = 0x0e,
2429 .txFrameToPaOn = 0x0e,
2430 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2431 .antennaGain = 0,
2432 .switchSettling = 0x2c,
2433 .adcDesiredSize = -30,
2434 .txEndToXpaOff = 0,
2435 .txEndToRxOn = 0x2,
2436 .txFrameToXpaOn = 0xe,
2437 .thresh62 = 28,
2438 .papdRateMaskHt20 = LE32(0x0c80C080),
2439 .papdRateMaskHt40 = LE32(0x0080C080),
2440 .xlna_bias_strength = 0,
2441 .futureModal = {
2442 0, 0, 0, 0, 0, 0, 0,
2445 .base_ext1 = {
2446 .ant_div_control = 0,
2447 .future = {0, 0, 0},
2448 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
2450 .calFreqPier2G = {
2451 FREQ2FBIN(2412, 1),
2452 FREQ2FBIN(2437, 1),
2453 FREQ2FBIN(2462, 1),
2455 /* ar9300_cal_data_per_freq_op_loop 2g */
2456 .calPierData2G = {
2457 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2458 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2459 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2461 .calTarget_freqbin_Cck = {
2462 FREQ2FBIN(2412, 1),
2463 FREQ2FBIN(2472, 1),
2465 .calTarget_freqbin_2G = {
2466 FREQ2FBIN(2412, 1),
2467 FREQ2FBIN(2437, 1),
2468 FREQ2FBIN(2472, 1)
2470 .calTarget_freqbin_2GHT20 = {
2471 FREQ2FBIN(2412, 1),
2472 FREQ2FBIN(2437, 1),
2473 FREQ2FBIN(2472, 1)
2475 .calTarget_freqbin_2GHT40 = {
2476 FREQ2FBIN(2412, 1),
2477 FREQ2FBIN(2437, 1),
2478 FREQ2FBIN(2472, 1)
2480 .calTargetPowerCck = {
2481 /* 1L-5L,5S,11L,11S */
2482 { {34, 34, 34, 34} },
2483 { {34, 34, 34, 34} },
2485 .calTargetPower2G = {
2486 /* 6-24,36,48,54 */
2487 { {34, 34, 32, 32} },
2488 { {34, 34, 32, 32} },
2489 { {34, 34, 32, 32} },
2491 .calTargetPower2GHT20 = {
2492 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2493 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2494 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2496 .calTargetPower2GHT40 = {
2497 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2498 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2499 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2501 .ctlIndex_2G = {
2502 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2503 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2505 .ctl_freqbin_2G = {
2507 FREQ2FBIN(2412, 1),
2508 FREQ2FBIN(2417, 1),
2509 FREQ2FBIN(2457, 1),
2510 FREQ2FBIN(2462, 1)
2513 FREQ2FBIN(2412, 1),
2514 FREQ2FBIN(2417, 1),
2515 FREQ2FBIN(2462, 1),
2516 0xFF,
2520 FREQ2FBIN(2412, 1),
2521 FREQ2FBIN(2417, 1),
2522 FREQ2FBIN(2462, 1),
2523 0xFF,
2526 FREQ2FBIN(2422, 1),
2527 FREQ2FBIN(2427, 1),
2528 FREQ2FBIN(2447, 1),
2529 FREQ2FBIN(2452, 1)
2533 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2534 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2535 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2536 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2540 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2541 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2542 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2547 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2548 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2549 FREQ2FBIN(2472, 1),
2554 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2555 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2556 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2557 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2561 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2562 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2563 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2567 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2568 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2569 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2574 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2575 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2576 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2581 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2582 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2583 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2584 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2587 .ctlPowerData_2G = {
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) } },
2590 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2592 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2593 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2594 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2596 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2597 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2598 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2600 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2601 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2602 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2604 .modalHeader5G = {
2605 /* 4 idle,t1,t2,b (4 bits per setting) */
2606 .antCtrlCommon = LE32(0x220),
2607 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2608 .antCtrlCommon2 = LE32(0x44444),
2609 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2610 .antCtrlChain = {
2611 LE16(0x150), LE16(0x150), LE16(0x150),
2613 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2614 .xatten1DB = {0x19, 0x19, 0x19},
2617 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2618 * for merlin (0xa20c/b20c 16:12
2620 .xatten1Margin = {0x14, 0x14, 0x14},
2621 .tempSlope = 70,
2622 .voltSlope = 0,
2623 /* spurChans spur channels in usual fbin coding format */
2624 .spurChans = {0, 0, 0, 0, 0},
2625 /* noiseFloorThreshCh Check if the register is per chain */
2626 .noiseFloorThreshCh = {-1, 0, 0},
2627 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2628 .quick_drop = 0,
2629 .xpaBiasLvl = 0,
2630 .txFrameToDataStart = 0x0e,
2631 .txFrameToPaOn = 0x0e,
2632 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2633 .antennaGain = 0,
2634 .switchSettling = 0x2d,
2635 .adcDesiredSize = -30,
2636 .txEndToXpaOff = 0,
2637 .txEndToRxOn = 0x2,
2638 .txFrameToXpaOn = 0xe,
2639 .thresh62 = 28,
2640 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2641 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2642 .xlna_bias_strength = 0,
2643 .futureModal = {
2644 0, 0, 0, 0, 0, 0, 0,
2647 .base_ext2 = {
2648 .tempSlopeLow = 35,
2649 .tempSlopeHigh = 50,
2650 .xatten1DBLow = {0, 0, 0},
2651 .xatten1MarginLow = {0, 0, 0},
2652 .xatten1DBHigh = {0, 0, 0},
2653 .xatten1MarginHigh = {0, 0, 0}
2655 .calFreqPier5G = {
2656 FREQ2FBIN(5160, 0),
2657 FREQ2FBIN(5220, 0),
2658 FREQ2FBIN(5320, 0),
2659 FREQ2FBIN(5400, 0),
2660 FREQ2FBIN(5500, 0),
2661 FREQ2FBIN(5600, 0),
2662 FREQ2FBIN(5700, 0),
2663 FREQ2FBIN(5785, 0)
2665 .calPierData5G = {
2667 {0, 0, 0, 0, 0},
2668 {0, 0, 0, 0, 0},
2669 {0, 0, 0, 0, 0},
2670 {0, 0, 0, 0, 0},
2671 {0, 0, 0, 0, 0},
2672 {0, 0, 0, 0, 0},
2673 {0, 0, 0, 0, 0},
2674 {0, 0, 0, 0, 0},
2677 {0, 0, 0, 0, 0},
2678 {0, 0, 0, 0, 0},
2679 {0, 0, 0, 0, 0},
2680 {0, 0, 0, 0, 0},
2681 {0, 0, 0, 0, 0},
2682 {0, 0, 0, 0, 0},
2683 {0, 0, 0, 0, 0},
2684 {0, 0, 0, 0, 0},
2687 {0, 0, 0, 0, 0},
2688 {0, 0, 0, 0, 0},
2689 {0, 0, 0, 0, 0},
2690 {0, 0, 0, 0, 0},
2691 {0, 0, 0, 0, 0},
2692 {0, 0, 0, 0, 0},
2693 {0, 0, 0, 0, 0},
2694 {0, 0, 0, 0, 0},
2698 .calTarget_freqbin_5G = {
2699 FREQ2FBIN(5180, 0),
2700 FREQ2FBIN(5240, 0),
2701 FREQ2FBIN(5320, 0),
2702 FREQ2FBIN(5400, 0),
2703 FREQ2FBIN(5500, 0),
2704 FREQ2FBIN(5600, 0),
2705 FREQ2FBIN(5700, 0),
2706 FREQ2FBIN(5825, 0)
2708 .calTarget_freqbin_5GHT20 = {
2709 FREQ2FBIN(5180, 0),
2710 FREQ2FBIN(5240, 0),
2711 FREQ2FBIN(5320, 0),
2712 FREQ2FBIN(5400, 0),
2713 FREQ2FBIN(5500, 0),
2714 FREQ2FBIN(5700, 0),
2715 FREQ2FBIN(5745, 0),
2716 FREQ2FBIN(5825, 0)
2718 .calTarget_freqbin_5GHT40 = {
2719 FREQ2FBIN(5180, 0),
2720 FREQ2FBIN(5240, 0),
2721 FREQ2FBIN(5320, 0),
2722 FREQ2FBIN(5400, 0),
2723 FREQ2FBIN(5500, 0),
2724 FREQ2FBIN(5700, 0),
2725 FREQ2FBIN(5745, 0),
2726 FREQ2FBIN(5825, 0)
2728 .calTargetPower5G = {
2729 /* 6-24,36,48,54 */
2730 { {30, 30, 28, 24} },
2731 { {30, 30, 28, 24} },
2732 { {30, 30, 28, 24} },
2733 { {30, 30, 28, 24} },
2734 { {30, 30, 28, 24} },
2735 { {30, 30, 28, 24} },
2736 { {30, 30, 28, 24} },
2737 { {30, 30, 28, 24} },
2739 .calTargetPower5GHT20 = {
2741 * 0_8_16,1-3_9-11_17-19,
2742 * 4,5,6,7,12,13,14,15,20,21,22,23
2744 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2745 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2746 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2747 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2748 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2749 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2750 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2751 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2753 .calTargetPower5GHT40 = {
2755 * 0_8_16,1-3_9-11_17-19,
2756 * 4,5,6,7,12,13,14,15,20,21,22,23
2758 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2759 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2760 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2761 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2762 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2763 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2764 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2765 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2767 .ctlIndex_5G = {
2768 0x10, 0x16, 0x18, 0x40, 0x46,
2769 0x48, 0x30, 0x36, 0x38
2771 .ctl_freqbin_5G = {
2773 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2774 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2775 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2776 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2777 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2778 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2779 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2780 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2783 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2784 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2785 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2786 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2787 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2788 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2789 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2790 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2794 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2795 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2796 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2797 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2798 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2799 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2800 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2801 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2805 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2806 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2807 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2808 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2809 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2810 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2811 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2812 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2816 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2817 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2818 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2819 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2820 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2821 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2822 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2823 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2827 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2828 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2829 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2830 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2831 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2832 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2833 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2834 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2838 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2839 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2840 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2841 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2842 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2843 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2844 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2845 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2849 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2850 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2851 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2852 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2853 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2854 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2855 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2856 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2860 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2861 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2862 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2863 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2864 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2865 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2866 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2867 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2870 .ctlPowerData_5G = {
2873 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2874 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2879 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2880 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2885 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2886 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2891 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2892 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2897 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2898 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2903 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2904 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2909 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2910 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2915 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2916 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2921 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2922 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2929 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2930 &ar9300_default,
2931 &ar9300_x112,
2932 &ar9300_h116,
2933 &ar9300_h112,
2934 &ar9300_x113,
2937 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2939 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2940 int it;
2942 for (it = 0; it < N_LOOP; it++)
2943 if (ar9300_eep_templates[it]->templateVersion == id)
2944 return ar9300_eep_templates[it];
2945 return NULL;
2946 #undef N_LOOP
2949 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2951 return 0;
2954 static int interpolate(int x, int xa, int xb, int ya, int yb)
2956 int bf, factor, plus;
2958 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2959 factor = bf / 2;
2960 plus = bf % 2;
2961 return ya + factor + plus;
2964 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2965 enum eeprom_param param)
2967 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2968 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
2970 switch (param) {
2971 case EEP_MAC_LSW:
2972 return get_unaligned_be16(eep->macAddr);
2973 case EEP_MAC_MID:
2974 return get_unaligned_be16(eep->macAddr + 2);
2975 case EEP_MAC_MSW:
2976 return get_unaligned_be16(eep->macAddr + 4);
2977 case EEP_REG_0:
2978 return le16_to_cpu(pBase->regDmn[0]);
2979 case EEP_OP_CAP:
2980 return pBase->deviceCap;
2981 case EEP_OP_MODE:
2982 return pBase->opCapFlags.opFlags;
2983 case EEP_RF_SILENT:
2984 return pBase->rfSilent;
2985 case EEP_TX_MASK:
2986 return (pBase->txrxMask >> 4) & 0xf;
2987 case EEP_RX_MASK:
2988 return pBase->txrxMask & 0xf;
2989 case EEP_PAPRD:
2990 return !!(pBase->featureEnable & BIT(5));
2991 case EEP_CHAIN_MASK_REDUCE:
2992 return (pBase->miscConfiguration >> 0x3) & 0x1;
2993 case EEP_ANT_DIV_CTL1:
2994 return eep->base_ext1.ant_div_control;
2995 case EEP_ANTENNA_GAIN_5G:
2996 return eep->modalHeader5G.antennaGain;
2997 case EEP_ANTENNA_GAIN_2G:
2998 return eep->modalHeader2G.antennaGain;
2999 default:
3000 return 0;
3004 static bool ar9300_eeprom_read_byte(struct ath_hw *ah, int address,
3005 u8 *buffer)
3007 u16 val;
3009 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3010 return false;
3012 *buffer = (val >> (8 * (address % 2))) & 0xff;
3013 return true;
3016 static bool ar9300_eeprom_read_word(struct ath_hw *ah, int address,
3017 u8 *buffer)
3019 u16 val;
3021 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3022 return false;
3024 buffer[0] = val >> 8;
3025 buffer[1] = val & 0xff;
3027 return true;
3030 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3031 int count)
3033 struct ath_common *common = ath9k_hw_common(ah);
3034 int i;
3036 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3037 ath_dbg(common, EEPROM, "eeprom address not in range\n");
3038 return false;
3042 * Since we're reading the bytes in reverse order from a little-endian
3043 * word stream, an even address means we only use the lower half of
3044 * the 16-bit word at that address
3046 if (address % 2 == 0) {
3047 if (!ar9300_eeprom_read_byte(ah, address--, buffer++))
3048 goto error;
3050 count--;
3053 for (i = 0; i < count / 2; i++) {
3054 if (!ar9300_eeprom_read_word(ah, address, buffer))
3055 goto error;
3057 address -= 2;
3058 buffer += 2;
3061 if (count % 2)
3062 if (!ar9300_eeprom_read_byte(ah, address, buffer))
3063 goto error;
3065 return true;
3067 error:
3068 ath_dbg(common, EEPROM, "unable to read eeprom region at offset %d\n",
3069 address);
3070 return false;
3073 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3075 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3077 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3078 AR9300_OTP_STATUS_VALID, 1000))
3079 return false;
3081 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3082 return true;
3085 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3086 int count)
3088 u32 data;
3089 int i;
3091 for (i = 0; i < count; i++) {
3092 int offset = 8 * ((address - i) % 4);
3093 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3094 return false;
3096 buffer[i] = (data >> offset) & 0xff;
3099 return true;
3103 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3104 int *length, int *major, int *minor)
3106 unsigned long value[4];
3108 value[0] = best[0];
3109 value[1] = best[1];
3110 value[2] = best[2];
3111 value[3] = best[3];
3112 *code = ((value[0] >> 5) & 0x0007);
3113 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3114 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3115 *major = (value[2] & 0x000f);
3116 *minor = (value[3] & 0x00ff);
3119 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3121 int it, checksum = 0;
3123 for (it = 0; it < dsize; it++) {
3124 checksum += data[it];
3125 checksum &= 0xffff;
3128 return checksum;
3131 static bool ar9300_uncompress_block(struct ath_hw *ah,
3132 u8 *mptr,
3133 int mdataSize,
3134 u8 *block,
3135 int size)
3137 int it;
3138 int spot;
3139 int offset;
3140 int length;
3141 struct ath_common *common = ath9k_hw_common(ah);
3143 spot = 0;
3145 for (it = 0; it < size; it += (length+2)) {
3146 offset = block[it];
3147 offset &= 0xff;
3148 spot += offset;
3149 length = block[it+1];
3150 length &= 0xff;
3152 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3153 ath_dbg(common, EEPROM,
3154 "Restore at %d: spot=%d offset=%d length=%d\n",
3155 it, spot, offset, length);
3156 memcpy(&mptr[spot], &block[it+2], length);
3157 spot += length;
3158 } else if (length > 0) {
3159 ath_dbg(common, EEPROM,
3160 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3161 it, spot, offset, length);
3162 return false;
3165 return true;
3168 static int ar9300_compress_decision(struct ath_hw *ah,
3169 int it,
3170 int code,
3171 int reference,
3172 u8 *mptr,
3173 u8 *word, int length, int mdata_size)
3175 struct ath_common *common = ath9k_hw_common(ah);
3176 const struct ar9300_eeprom *eep = NULL;
3178 switch (code) {
3179 case _CompressNone:
3180 if (length != mdata_size) {
3181 ath_dbg(common, EEPROM,
3182 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3183 mdata_size, length);
3184 return -1;
3186 memcpy(mptr, word + COMP_HDR_LEN, length);
3187 ath_dbg(common, EEPROM,
3188 "restored eeprom %d: uncompressed, length %d\n",
3189 it, length);
3190 break;
3191 case _CompressBlock:
3192 if (reference == 0) {
3193 } else {
3194 eep = ar9003_eeprom_struct_find_by_id(reference);
3195 if (eep == NULL) {
3196 ath_dbg(common, EEPROM,
3197 "can't find reference eeprom struct %d\n",
3198 reference);
3199 return -1;
3201 memcpy(mptr, eep, mdata_size);
3203 ath_dbg(common, EEPROM,
3204 "restore eeprom %d: block, reference %d, length %d\n",
3205 it, reference, length);
3206 ar9300_uncompress_block(ah, mptr, mdata_size,
3207 (word + COMP_HDR_LEN), length);
3208 break;
3209 default:
3210 ath_dbg(common, EEPROM, "unknown compression code %d\n", code);
3211 return -1;
3213 return 0;
3216 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3217 int count);
3219 static bool ar9300_check_header(void *data)
3221 u32 *word = data;
3222 return !(*word == 0 || *word == ~0);
3225 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3226 int base_addr)
3228 u8 header[4];
3230 if (!read(ah, base_addr, header, 4))
3231 return false;
3233 return ar9300_check_header(header);
3236 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3237 int mdata_size)
3239 u16 *data = (u16 *) mptr;
3240 int i;
3242 for (i = 0; i < mdata_size / 2; i++, data++)
3243 ath9k_hw_nvram_read(ah, 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) || AR_SREV_9565(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);
3544 u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3546 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3549 u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3551 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3554 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3555 bool is2ghz)
3557 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3558 return le16_to_cpu(val);
3561 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3563 struct ath_common *common = ath9k_hw_common(ah);
3564 struct ath9k_hw_capabilities *pCap = &ah->caps;
3565 int chain;
3566 u32 regval, value, gpio;
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 if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0)) {
3574 if (ah->config.xlna_gpio)
3575 gpio = ah->config.xlna_gpio;
3576 else
3577 gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
3579 ath9k_hw_cfg_output(ah, gpio,
3580 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
3583 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3585 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3586 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3587 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3588 } else if (AR_SREV_9550(ah)) {
3589 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3590 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3591 } else
3592 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3593 AR_SWITCH_TABLE_COM_ALL, value);
3597 * AR9462 defines new switch table for BT/WLAN,
3598 * here's new field name in XXX.ref for both 2G and 5G.
3599 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3600 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3601 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3603 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3604 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3606 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3607 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3609 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
3610 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3611 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3612 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3613 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3616 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3617 if (AR_SREV_9485(ah) && common->bt_ant_diversity) {
3618 value &= ~AR_SWITCH_TABLE_COM2_ALL;
3619 value |= ah->config.ant_ctrl_comm2g_switch_enable;
3622 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3624 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3625 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3626 REG_RMW_FIELD(ah, switch_chain_reg[0],
3627 AR_SWITCH_TABLE_ALL, value);
3630 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3631 if ((ah->rxchainmask & BIT(chain)) ||
3632 (ah->txchainmask & BIT(chain))) {
3633 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3634 is2ghz);
3635 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3636 AR_SWITCH_TABLE_ALL, value);
3640 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
3641 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3643 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3644 * are the fields present
3646 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3647 regval &= (~AR_ANT_DIV_CTRL_ALL);
3648 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3649 /* enable_lnadiv */
3650 regval &= (~AR_PHY_ANT_DIV_LNADIV);
3651 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
3653 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3654 regval |= AR_ANT_DIV_ENABLE;
3656 if (AR_SREV_9565(ah)) {
3657 if (common->bt_ant_diversity) {
3658 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S);
3659 } else {
3660 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S);
3661 regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S);
3665 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3667 /* enable fast_div */
3668 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3669 regval &= (~AR_FAST_DIV_ENABLE);
3670 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
3672 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3673 regval |= AR_FAST_DIV_ENABLE;
3675 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3677 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
3678 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3680 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3681 * main_tb, alt_tb
3683 regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
3684 AR_PHY_ANT_DIV_ALT_LNACONF |
3685 AR_PHY_ANT_DIV_ALT_GAINTB |
3686 AR_PHY_ANT_DIV_MAIN_GAINTB));
3687 /* by default use LNA1 for the main antenna */
3688 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
3689 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
3690 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
3691 AR_PHY_ANT_DIV_ALT_LNACONF_S);
3692 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3697 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3699 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3700 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3701 int drive_strength;
3702 unsigned long reg;
3704 drive_strength = pBase->miscConfiguration & BIT(0);
3705 if (!drive_strength)
3706 return;
3708 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3709 reg &= ~0x00ffffc0;
3710 reg |= 0x5 << 21;
3711 reg |= 0x5 << 18;
3712 reg |= 0x5 << 15;
3713 reg |= 0x5 << 12;
3714 reg |= 0x5 << 9;
3715 reg |= 0x5 << 6;
3716 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3718 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3719 reg &= ~0xffffffe0;
3720 reg |= 0x5 << 29;
3721 reg |= 0x5 << 26;
3722 reg |= 0x5 << 23;
3723 reg |= 0x5 << 20;
3724 reg |= 0x5 << 17;
3725 reg |= 0x5 << 14;
3726 reg |= 0x5 << 11;
3727 reg |= 0x5 << 8;
3728 reg |= 0x5 << 5;
3729 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3731 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3732 reg &= ~0xff800000;
3733 reg |= 0x5 << 29;
3734 reg |= 0x5 << 26;
3735 reg |= 0x5 << 23;
3736 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3739 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3740 struct ath9k_channel *chan)
3742 int f[3], t[3];
3743 u16 value;
3744 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3746 if (chain >= 0 && chain < 3) {
3747 if (IS_CHAN_2GHZ(chan))
3748 return eep->modalHeader2G.xatten1DB[chain];
3749 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3750 t[0] = eep->base_ext2.xatten1DBLow[chain];
3751 f[0] = 5180;
3752 t[1] = eep->modalHeader5G.xatten1DB[chain];
3753 f[1] = 5500;
3754 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3755 f[2] = 5785;
3756 value = ar9003_hw_power_interpolate((s32) chan->channel,
3757 f, t, 3);
3758 return value;
3759 } else
3760 return eep->modalHeader5G.xatten1DB[chain];
3763 return 0;
3767 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3768 struct ath9k_channel *chan)
3770 int f[3], t[3];
3771 u16 value;
3772 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3774 if (chain >= 0 && chain < 3) {
3775 if (IS_CHAN_2GHZ(chan))
3776 return eep->modalHeader2G.xatten1Margin[chain];
3777 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3778 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3779 f[0] = 5180;
3780 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3781 f[1] = 5500;
3782 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3783 f[2] = 5785;
3784 value = ar9003_hw_power_interpolate((s32) chan->channel,
3785 f, t, 3);
3786 return value;
3787 } else
3788 return eep->modalHeader5G.xatten1Margin[chain];
3791 return 0;
3794 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3796 int i;
3797 u16 value;
3798 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3799 AR_PHY_EXT_ATTEN_CTL_1,
3800 AR_PHY_EXT_ATTEN_CTL_2,
3803 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3804 value = ar9003_hw_atten_chain_get(ah, 1, chan);
3805 REG_RMW_FIELD(ah, ext_atten_reg[0],
3806 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3808 value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
3809 REG_RMW_FIELD(ah, ext_atten_reg[0],
3810 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3811 value);
3814 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3815 for (i = 0; i < 3; i++) {
3816 if (ah->txchainmask & BIT(i)) {
3817 value = ar9003_hw_atten_chain_get(ah, i, chan);
3818 REG_RMW_FIELD(ah, ext_atten_reg[i],
3819 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3821 if (AR_SREV_9485(ah) &&
3822 (ar9003_hw_get_rx_gain_idx(ah) == 0) &&
3823 ah->config.xatten_margin_cfg)
3824 value = 5;
3825 else
3826 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3828 if (ah->config.alt_mingainidx)
3829 REG_RMW_FIELD(ah, AR_PHY_EXT_ATTEN_CTL_0,
3830 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3831 value);
3833 REG_RMW_FIELD(ah, ext_atten_reg[i],
3834 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3835 value);
3840 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3842 int timeout = 100;
3844 while (pmu_set != REG_READ(ah, pmu_reg)) {
3845 if (timeout-- == 0)
3846 return false;
3847 REG_WRITE(ah, pmu_reg, pmu_set);
3848 udelay(10);
3851 return true;
3854 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3856 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3857 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3858 u32 reg_val;
3860 if (pBase->featureEnable & BIT(4)) {
3861 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3862 int reg_pmu_set;
3864 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3865 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3866 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3867 return;
3869 if (AR_SREV_9330(ah)) {
3870 if (ah->is_clk_25mhz) {
3871 reg_pmu_set = (3 << 1) | (8 << 4) |
3872 (3 << 8) | (1 << 14) |
3873 (6 << 17) | (1 << 20) |
3874 (3 << 24);
3875 } else {
3876 reg_pmu_set = (4 << 1) | (7 << 4) |
3877 (3 << 8) | (1 << 14) |
3878 (6 << 17) | (1 << 20) |
3879 (3 << 24);
3881 } else {
3882 reg_pmu_set = (5 << 1) | (7 << 4) |
3883 (2 << 8) | (2 << 14) |
3884 (6 << 17) | (1 << 20) |
3885 (3 << 24) | (1 << 28);
3888 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3889 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3890 return;
3892 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3893 | (4 << 26);
3894 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3895 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3896 return;
3898 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3899 | (1 << 21);
3900 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3901 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3902 return;
3903 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3904 reg_val = le32_to_cpu(pBase->swreg);
3905 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3906 } else {
3907 /* Internal regulator is ON. Write swreg register. */
3908 reg_val = le32_to_cpu(pBase->swreg);
3909 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3910 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3911 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3912 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3913 /* Set REG_CONTROL1.SWREG_PROGRAM */
3914 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3915 REG_READ(ah,
3916 AR_RTC_REG_CONTROL1) |
3917 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3919 } else {
3920 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3921 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3922 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3923 AR_PHY_PMU2_PGM))
3924 udelay(10);
3926 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3927 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3928 AR_PHY_PMU1_PWD))
3929 udelay(10);
3930 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3931 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3932 AR_PHY_PMU2_PGM))
3933 udelay(10);
3934 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
3935 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3936 else {
3937 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3938 AR_RTC_FORCE_SWREG_PRD;
3939 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3945 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3947 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3948 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3950 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3951 return;
3953 if (eep->baseEepHeader.featureEnable & 0x40) {
3954 tuning_caps_param &= 0x7f;
3955 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3956 tuning_caps_param);
3957 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3958 tuning_caps_param);
3962 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3964 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3965 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3966 int quick_drop;
3967 s32 t[3], f[3] = {5180, 5500, 5785};
3969 if (!(pBase->miscConfiguration & BIT(4)))
3970 return;
3972 if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) {
3973 if (freq < 4000) {
3974 quick_drop = eep->modalHeader2G.quick_drop;
3975 } else {
3976 t[0] = eep->base_ext1.quick_drop_low;
3977 t[1] = eep->modalHeader5G.quick_drop;
3978 t[2] = eep->base_ext1.quick_drop_high;
3979 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
3981 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
3985 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
3987 u32 value;
3989 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
3991 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3992 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
3993 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3994 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
3997 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
3999 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4000 u8 xpa_ctl;
4002 if (!(eep->baseEepHeader.featureEnable & 0x80))
4003 return;
4005 if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah))
4006 return;
4008 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
4009 if (is2ghz)
4010 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4011 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
4012 else
4013 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4014 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
4017 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
4019 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4020 u8 bias;
4022 if (!(eep->baseEepHeader.miscConfiguration & 0x40))
4023 return;
4025 if (!AR_SREV_9300(ah))
4026 return;
4028 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
4029 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4030 bias & 0x3);
4031 bias >>= 2;
4032 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4033 bias & 0x3);
4034 bias >>= 2;
4035 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4036 bias & 0x3);
4039 static int ar9003_hw_get_thermometer(struct ath_hw *ah)
4041 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4042 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4043 int thermometer = (pBase->miscConfiguration >> 1) & 0x3;
4045 return --thermometer;
4048 static void ar9003_hw_thermometer_apply(struct ath_hw *ah)
4050 int thermometer = ar9003_hw_get_thermometer(ah);
4051 u8 therm_on = (thermometer < 0) ? 0 : 1;
4053 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4054 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4055 if (ah->caps.tx_chainmask & BIT(1))
4056 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4057 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4058 if (ah->caps.tx_chainmask & BIT(2))
4059 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4060 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4062 therm_on = (thermometer < 0) ? 0 : (thermometer == 0);
4063 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4064 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4065 if (ah->caps.tx_chainmask & BIT(1)) {
4066 therm_on = (thermometer < 0) ? 0 : (thermometer == 1);
4067 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4068 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4070 if (ah->caps.tx_chainmask & BIT(2)) {
4071 therm_on = (thermometer < 0) ? 0 : (thermometer == 2);
4072 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4073 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4077 static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4079 u32 data, ko, kg;
4081 if (!AR_SREV_9462_20_OR_LATER(ah))
4082 return;
4084 ar9300_otp_read_word(ah, 1, &data);
4085 ko = data & 0xff;
4086 kg = (data >> 8) & 0xff;
4087 if (ko || kg) {
4088 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4089 AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko);
4090 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4091 AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN,
4092 kg + 256);
4096 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4097 struct ath9k_channel *chan)
4099 bool is2ghz = IS_CHAN_2GHZ(chan);
4100 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
4101 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
4102 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
4103 ar9003_hw_drive_strength_apply(ah);
4104 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
4105 ar9003_hw_atten_apply(ah, chan);
4106 ar9003_hw_quick_drop_apply(ah, chan->channel);
4107 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah))
4108 ar9003_hw_internal_regulator_apply(ah);
4109 ar9003_hw_apply_tuning_caps(ah);
4110 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4111 ar9003_hw_thermometer_apply(ah);
4112 ar9003_hw_thermo_cal_apply(ah);
4115 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
4116 struct ath9k_channel *chan)
4121 * Returns the interpolated y value corresponding to the specified x value
4122 * from the np ordered pairs of data (px,py).
4123 * The pairs do not have to be in any order.
4124 * If the specified x value is less than any of the px,
4125 * the returned y value is equal to the py for the lowest px.
4126 * If the specified x value is greater than any of the px,
4127 * the returned y value is equal to the py for the highest px.
4129 static int ar9003_hw_power_interpolate(int32_t x,
4130 int32_t *px, int32_t *py, u_int16_t np)
4132 int ip = 0;
4133 int lx = 0, ly = 0, lhave = 0;
4134 int hx = 0, hy = 0, hhave = 0;
4135 int dx = 0;
4136 int y = 0;
4138 lhave = 0;
4139 hhave = 0;
4141 /* identify best lower and higher x calibration measurement */
4142 for (ip = 0; ip < np; ip++) {
4143 dx = x - px[ip];
4145 /* this measurement is higher than our desired x */
4146 if (dx <= 0) {
4147 if (!hhave || dx > (x - hx)) {
4148 /* new best higher x measurement */
4149 hx = px[ip];
4150 hy = py[ip];
4151 hhave = 1;
4154 /* this measurement is lower than our desired x */
4155 if (dx >= 0) {
4156 if (!lhave || dx < (x - lx)) {
4157 /* new best lower x measurement */
4158 lx = px[ip];
4159 ly = py[ip];
4160 lhave = 1;
4165 /* the low x is good */
4166 if (lhave) {
4167 /* so is the high x */
4168 if (hhave) {
4169 /* they're the same, so just pick one */
4170 if (hx == lx)
4171 y = ly;
4172 else /* interpolate */
4173 y = interpolate(x, lx, hx, ly, hy);
4174 } else /* only low is good, use it */
4175 y = ly;
4176 } else if (hhave) /* only high is good, use it */
4177 y = hy;
4178 else /* nothing is good,this should never happen unless np=0, ???? */
4179 y = -(1 << 30);
4180 return y;
4183 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4184 u16 rateIndex, u16 freq, bool is2GHz)
4186 u16 numPiers, i;
4187 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4188 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4189 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4190 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4191 u8 *pFreqBin;
4193 if (is2GHz) {
4194 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4195 pEepromTargetPwr = eep->calTargetPower2G;
4196 pFreqBin = eep->calTarget_freqbin_2G;
4197 } else {
4198 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4199 pEepromTargetPwr = eep->calTargetPower5G;
4200 pFreqBin = eep->calTarget_freqbin_5G;
4204 * create array of channels and targetpower from
4205 * targetpower piers stored on eeprom
4207 for (i = 0; i < numPiers; i++) {
4208 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4209 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4212 /* interpolate to get target power for given frequency */
4213 return (u8) ar9003_hw_power_interpolate((s32) freq,
4214 freqArray,
4215 targetPowerArray, numPiers);
4218 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4219 u16 rateIndex,
4220 u16 freq, bool is2GHz)
4222 u16 numPiers, i;
4223 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4224 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4225 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4226 struct cal_tgt_pow_ht *pEepromTargetPwr;
4227 u8 *pFreqBin;
4229 if (is2GHz) {
4230 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4231 pEepromTargetPwr = eep->calTargetPower2GHT20;
4232 pFreqBin = eep->calTarget_freqbin_2GHT20;
4233 } else {
4234 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4235 pEepromTargetPwr = eep->calTargetPower5GHT20;
4236 pFreqBin = eep->calTarget_freqbin_5GHT20;
4240 * create array of channels and targetpower
4241 * from targetpower piers stored on eeprom
4243 for (i = 0; i < numPiers; i++) {
4244 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4245 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4248 /* interpolate to get target power for given frequency */
4249 return (u8) ar9003_hw_power_interpolate((s32) freq,
4250 freqArray,
4251 targetPowerArray, numPiers);
4254 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4255 u16 rateIndex,
4256 u16 freq, bool is2GHz)
4258 u16 numPiers, i;
4259 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4260 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4261 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4262 struct cal_tgt_pow_ht *pEepromTargetPwr;
4263 u8 *pFreqBin;
4265 if (is2GHz) {
4266 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4267 pEepromTargetPwr = eep->calTargetPower2GHT40;
4268 pFreqBin = eep->calTarget_freqbin_2GHT40;
4269 } else {
4270 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4271 pEepromTargetPwr = eep->calTargetPower5GHT40;
4272 pFreqBin = eep->calTarget_freqbin_5GHT40;
4276 * create array of channels and targetpower from
4277 * targetpower piers stored on eeprom
4279 for (i = 0; i < numPiers; i++) {
4280 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4281 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4284 /* interpolate to get target power for given frequency */
4285 return (u8) ar9003_hw_power_interpolate((s32) freq,
4286 freqArray,
4287 targetPowerArray, numPiers);
4290 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4291 u16 rateIndex, u16 freq)
4293 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4294 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4295 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4296 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4297 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4298 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4301 * create array of channels and targetpower from
4302 * targetpower piers stored on eeprom
4304 for (i = 0; i < numPiers; i++) {
4305 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4306 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4309 /* interpolate to get target power for given frequency */
4310 return (u8) ar9003_hw_power_interpolate((s32) freq,
4311 freqArray,
4312 targetPowerArray, numPiers);
4315 /* Set tx power registers to array of values passed in */
4316 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4318 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4319 /* make sure forced gain is not set */
4320 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4322 /* Write the OFDM power per rate set */
4324 /* 6 (LSB), 9, 12, 18 (MSB) */
4325 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4326 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4327 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4328 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4329 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4331 /* 24 (LSB), 36, 48, 54 (MSB) */
4332 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4333 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4334 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4335 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4336 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4338 /* Write the CCK power per rate set */
4340 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4341 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4342 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4343 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4344 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4345 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4347 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4348 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4349 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4350 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4351 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4352 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4355 /* Write the power for duplicated frames - HT40 */
4357 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4358 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4359 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4360 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4361 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4362 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4365 /* Write the HT20 power per rate set */
4367 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4368 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4369 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4370 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4371 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4372 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4375 /* 6 (LSB), 7, 12, 13 (MSB) */
4376 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4377 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4378 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4379 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4380 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4383 /* 14 (LSB), 15, 20, 21 */
4384 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4385 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4386 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4387 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4388 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4391 /* Mixed HT20 and HT40 rates */
4393 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4394 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4395 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4396 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4397 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4398 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4402 * Write the HT40 power per rate set
4403 * correct PAR difference between HT40 and HT20/LEGACY
4404 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4406 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4407 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4408 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4409 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4410 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4413 /* 6 (LSB), 7, 12, 13 (MSB) */
4414 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4415 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4416 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4417 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4418 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4421 /* 14 (LSB), 15, 20, 21 */
4422 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4423 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4424 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4425 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4426 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4429 return 0;
4430 #undef POW_SM
4433 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4434 u8 *targetPowerValT2,
4435 bool is2GHz)
4437 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4438 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4439 is2GHz);
4440 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4441 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4442 is2GHz);
4443 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4444 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4445 is2GHz);
4446 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4447 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4448 is2GHz);
4451 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4452 u8 *targetPowerValT2)
4454 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4455 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4456 freq);
4457 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4458 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4459 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4460 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4461 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4462 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4465 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4466 u8 *targetPowerValT2, bool is2GHz)
4468 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4469 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4470 is2GHz);
4471 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4472 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4473 freq, is2GHz);
4474 targetPowerValT2[ALL_TARGET_HT20_4] =
4475 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4476 is2GHz);
4477 targetPowerValT2[ALL_TARGET_HT20_5] =
4478 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4479 is2GHz);
4480 targetPowerValT2[ALL_TARGET_HT20_6] =
4481 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4482 is2GHz);
4483 targetPowerValT2[ALL_TARGET_HT20_7] =
4484 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4485 is2GHz);
4486 targetPowerValT2[ALL_TARGET_HT20_12] =
4487 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4488 is2GHz);
4489 targetPowerValT2[ALL_TARGET_HT20_13] =
4490 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4491 is2GHz);
4492 targetPowerValT2[ALL_TARGET_HT20_14] =
4493 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4494 is2GHz);
4495 targetPowerValT2[ALL_TARGET_HT20_15] =
4496 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4497 is2GHz);
4498 targetPowerValT2[ALL_TARGET_HT20_20] =
4499 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4500 is2GHz);
4501 targetPowerValT2[ALL_TARGET_HT20_21] =
4502 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4503 is2GHz);
4504 targetPowerValT2[ALL_TARGET_HT20_22] =
4505 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4506 is2GHz);
4507 targetPowerValT2[ALL_TARGET_HT20_23] =
4508 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4509 is2GHz);
4512 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4513 u16 freq,
4514 u8 *targetPowerValT2,
4515 bool is2GHz)
4517 /* XXX: hard code for now, need to get from eeprom struct */
4518 u8 ht40PowerIncForPdadc = 0;
4520 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4521 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4522 is2GHz) + ht40PowerIncForPdadc;
4523 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4524 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4525 freq,
4526 is2GHz) + ht40PowerIncForPdadc;
4527 targetPowerValT2[ALL_TARGET_HT40_4] =
4528 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4529 is2GHz) + ht40PowerIncForPdadc;
4530 targetPowerValT2[ALL_TARGET_HT40_5] =
4531 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4532 is2GHz) + ht40PowerIncForPdadc;
4533 targetPowerValT2[ALL_TARGET_HT40_6] =
4534 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4535 is2GHz) + ht40PowerIncForPdadc;
4536 targetPowerValT2[ALL_TARGET_HT40_7] =
4537 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4538 is2GHz) + ht40PowerIncForPdadc;
4539 targetPowerValT2[ALL_TARGET_HT40_12] =
4540 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4541 is2GHz) + ht40PowerIncForPdadc;
4542 targetPowerValT2[ALL_TARGET_HT40_13] =
4543 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4544 is2GHz) + ht40PowerIncForPdadc;
4545 targetPowerValT2[ALL_TARGET_HT40_14] =
4546 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4547 is2GHz) + ht40PowerIncForPdadc;
4548 targetPowerValT2[ALL_TARGET_HT40_15] =
4549 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4550 is2GHz) + ht40PowerIncForPdadc;
4551 targetPowerValT2[ALL_TARGET_HT40_20] =
4552 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4553 is2GHz) + ht40PowerIncForPdadc;
4554 targetPowerValT2[ALL_TARGET_HT40_21] =
4555 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4556 is2GHz) + ht40PowerIncForPdadc;
4557 targetPowerValT2[ALL_TARGET_HT40_22] =
4558 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4559 is2GHz) + ht40PowerIncForPdadc;
4560 targetPowerValT2[ALL_TARGET_HT40_23] =
4561 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4562 is2GHz) + ht40PowerIncForPdadc;
4565 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4566 struct ath9k_channel *chan,
4567 u8 *targetPowerValT2)
4569 bool is2GHz = IS_CHAN_2GHZ(chan);
4570 unsigned int i = 0;
4571 struct ath_common *common = ath9k_hw_common(ah);
4572 u16 freq = chan->channel;
4574 if (is2GHz)
4575 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4577 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4578 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4580 if (IS_CHAN_HT40(chan))
4581 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4582 is2GHz);
4584 for (i = 0; i < ar9300RateSize; i++) {
4585 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
4586 i, targetPowerValT2[i]);
4590 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4591 int mode,
4592 int ipier,
4593 int ichain,
4594 int *pfrequency,
4595 int *pcorrection,
4596 int *ptemperature, int *pvoltage)
4598 u8 *pCalPier;
4599 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4600 int is2GHz;
4601 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4602 struct ath_common *common = ath9k_hw_common(ah);
4604 if (ichain >= AR9300_MAX_CHAINS) {
4605 ath_dbg(common, EEPROM,
4606 "Invalid chain index, must be less than %d\n",
4607 AR9300_MAX_CHAINS);
4608 return -1;
4611 if (mode) { /* 5GHz */
4612 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4613 ath_dbg(common, EEPROM,
4614 "Invalid 5GHz cal pier index, must be less than %d\n",
4615 AR9300_NUM_5G_CAL_PIERS);
4616 return -1;
4618 pCalPier = &(eep->calFreqPier5G[ipier]);
4619 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4620 is2GHz = 0;
4621 } else {
4622 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4623 ath_dbg(common, EEPROM,
4624 "Invalid 2GHz cal pier index, must be less than %d\n",
4625 AR9300_NUM_2G_CAL_PIERS);
4626 return -1;
4629 pCalPier = &(eep->calFreqPier2G[ipier]);
4630 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4631 is2GHz = 1;
4634 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4635 *pcorrection = pCalPierStruct->refPower;
4636 *ptemperature = pCalPierStruct->tempMeas;
4637 *pvoltage = pCalPierStruct->voltMeas;
4639 return 0;
4642 static void ar9003_hw_power_control_override(struct ath_hw *ah,
4643 int frequency,
4644 int *correction,
4645 int *voltage, int *temperature)
4647 int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
4648 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4649 int f[8], t[8], t1[3], t2[3], i;
4651 REG_RMW(ah, AR_PHY_TPC_11_B0,
4652 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4653 AR_PHY_TPC_OLPC_GAIN_DELTA);
4654 if (ah->caps.tx_chainmask & BIT(1))
4655 REG_RMW(ah, AR_PHY_TPC_11_B1,
4656 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4657 AR_PHY_TPC_OLPC_GAIN_DELTA);
4658 if (ah->caps.tx_chainmask & BIT(2))
4659 REG_RMW(ah, AR_PHY_TPC_11_B2,
4660 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4661 AR_PHY_TPC_OLPC_GAIN_DELTA);
4663 /* enable open loop power control on chip */
4664 REG_RMW(ah, AR_PHY_TPC_6_B0,
4665 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4666 AR_PHY_TPC_6_ERROR_EST_MODE);
4667 if (ah->caps.tx_chainmask & BIT(1))
4668 REG_RMW(ah, AR_PHY_TPC_6_B1,
4669 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4670 AR_PHY_TPC_6_ERROR_EST_MODE);
4671 if (ah->caps.tx_chainmask & BIT(2))
4672 REG_RMW(ah, AR_PHY_TPC_6_B2,
4673 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4674 AR_PHY_TPC_6_ERROR_EST_MODE);
4677 * enable temperature compensation
4678 * Need to use register names
4680 if (frequency < 4000) {
4681 temp_slope = eep->modalHeader2G.tempSlope;
4682 } else {
4683 if (AR_SREV_9550(ah)) {
4684 t[0] = eep->base_ext1.tempslopextension[2];
4685 t1[0] = eep->base_ext1.tempslopextension[3];
4686 t2[0] = eep->base_ext1.tempslopextension[4];
4687 f[0] = 5180;
4689 t[1] = eep->modalHeader5G.tempSlope;
4690 t1[1] = eep->base_ext1.tempslopextension[0];
4691 t2[1] = eep->base_ext1.tempslopextension[1];
4692 f[1] = 5500;
4694 t[2] = eep->base_ext1.tempslopextension[5];
4695 t1[2] = eep->base_ext1.tempslopextension[6];
4696 t2[2] = eep->base_ext1.tempslopextension[7];
4697 f[2] = 5785;
4699 temp_slope = ar9003_hw_power_interpolate(frequency,
4700 f, t, 3);
4701 temp_slope1 = ar9003_hw_power_interpolate(frequency,
4702 f, t1, 3);
4703 temp_slope2 = ar9003_hw_power_interpolate(frequency,
4704 f, t2, 3);
4706 goto tempslope;
4709 if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4710 for (i = 0; i < 8; i++) {
4711 t[i] = eep->base_ext1.tempslopextension[i];
4712 f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4714 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4715 f, t, 8);
4716 } else if (eep->base_ext2.tempSlopeLow != 0) {
4717 t[0] = eep->base_ext2.tempSlopeLow;
4718 f[0] = 5180;
4719 t[1] = eep->modalHeader5G.tempSlope;
4720 f[1] = 5500;
4721 t[2] = eep->base_ext2.tempSlopeHigh;
4722 f[2] = 5785;
4723 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4724 f, t, 3);
4725 } else {
4726 temp_slope = eep->modalHeader5G.tempSlope;
4730 tempslope:
4731 if (AR_SREV_9550(ah)) {
4733 * AR955x has tempSlope register for each chain.
4734 * Check whether temp_compensation feature is enabled or not.
4736 if (eep->baseEepHeader.featureEnable & 0x1) {
4737 if (frequency < 4000) {
4738 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4739 AR_PHY_TPC_19_ALPHA_THERM,
4740 eep->base_ext2.tempSlopeLow);
4741 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4742 AR_PHY_TPC_19_ALPHA_THERM,
4743 temp_slope);
4744 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4745 AR_PHY_TPC_19_ALPHA_THERM,
4746 eep->base_ext2.tempSlopeHigh);
4747 } else {
4748 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4749 AR_PHY_TPC_19_ALPHA_THERM,
4750 temp_slope);
4751 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4752 AR_PHY_TPC_19_ALPHA_THERM,
4753 temp_slope1);
4754 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4755 AR_PHY_TPC_19_ALPHA_THERM,
4756 temp_slope2);
4758 } else {
4760 * If temp compensation is not enabled,
4761 * set all registers to 0.
4763 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4764 AR_PHY_TPC_19_ALPHA_THERM, 0);
4765 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4766 AR_PHY_TPC_19_ALPHA_THERM, 0);
4767 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4768 AR_PHY_TPC_19_ALPHA_THERM, 0);
4770 } else {
4771 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4772 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4775 if (AR_SREV_9462_20_OR_LATER(ah))
4776 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4777 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4780 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4781 temperature[0]);
4784 /* Apply the recorded correction values. */
4785 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4787 int ichain, ipier, npier;
4788 int mode;
4789 int lfrequency[AR9300_MAX_CHAINS],
4790 lcorrection[AR9300_MAX_CHAINS],
4791 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4792 int hfrequency[AR9300_MAX_CHAINS],
4793 hcorrection[AR9300_MAX_CHAINS],
4794 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4795 int fdiff;
4796 int correction[AR9300_MAX_CHAINS],
4797 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4798 int pfrequency, pcorrection, ptemperature, pvoltage;
4799 struct ath_common *common = ath9k_hw_common(ah);
4801 mode = (frequency >= 4000);
4802 if (mode)
4803 npier = AR9300_NUM_5G_CAL_PIERS;
4804 else
4805 npier = AR9300_NUM_2G_CAL_PIERS;
4807 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4808 lfrequency[ichain] = 0;
4809 hfrequency[ichain] = 100000;
4811 /* identify best lower and higher frequency calibration measurement */
4812 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4813 for (ipier = 0; ipier < npier; ipier++) {
4814 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4815 &pfrequency, &pcorrection,
4816 &ptemperature, &pvoltage)) {
4817 fdiff = frequency - pfrequency;
4820 * this measurement is higher than
4821 * our desired frequency
4823 if (fdiff <= 0) {
4824 if (hfrequency[ichain] <= 0 ||
4825 hfrequency[ichain] >= 100000 ||
4826 fdiff >
4827 (frequency - hfrequency[ichain])) {
4829 * new best higher
4830 * frequency measurement
4832 hfrequency[ichain] = pfrequency;
4833 hcorrection[ichain] =
4834 pcorrection;
4835 htemperature[ichain] =
4836 ptemperature;
4837 hvoltage[ichain] = pvoltage;
4840 if (fdiff >= 0) {
4841 if (lfrequency[ichain] <= 0
4842 || fdiff <
4843 (frequency - lfrequency[ichain])) {
4845 * new best lower
4846 * frequency measurement
4848 lfrequency[ichain] = pfrequency;
4849 lcorrection[ichain] =
4850 pcorrection;
4851 ltemperature[ichain] =
4852 ptemperature;
4853 lvoltage[ichain] = pvoltage;
4860 /* interpolate */
4861 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4862 ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
4863 ichain, frequency, lfrequency[ichain],
4864 lcorrection[ichain], hfrequency[ichain],
4865 hcorrection[ichain]);
4866 /* they're the same, so just pick one */
4867 if (hfrequency[ichain] == lfrequency[ichain]) {
4868 correction[ichain] = lcorrection[ichain];
4869 voltage[ichain] = lvoltage[ichain];
4870 temperature[ichain] = ltemperature[ichain];
4872 /* the low frequency is good */
4873 else if (frequency - lfrequency[ichain] < 1000) {
4874 /* so is the high frequency, interpolate */
4875 if (hfrequency[ichain] - frequency < 1000) {
4877 correction[ichain] = interpolate(frequency,
4878 lfrequency[ichain],
4879 hfrequency[ichain],
4880 lcorrection[ichain],
4881 hcorrection[ichain]);
4883 temperature[ichain] = interpolate(frequency,
4884 lfrequency[ichain],
4885 hfrequency[ichain],
4886 ltemperature[ichain],
4887 htemperature[ichain]);
4889 voltage[ichain] = interpolate(frequency,
4890 lfrequency[ichain],
4891 hfrequency[ichain],
4892 lvoltage[ichain],
4893 hvoltage[ichain]);
4895 /* only low is good, use it */
4896 else {
4897 correction[ichain] = lcorrection[ichain];
4898 temperature[ichain] = ltemperature[ichain];
4899 voltage[ichain] = lvoltage[ichain];
4902 /* only high is good, use it */
4903 else if (hfrequency[ichain] - frequency < 1000) {
4904 correction[ichain] = hcorrection[ichain];
4905 temperature[ichain] = htemperature[ichain];
4906 voltage[ichain] = hvoltage[ichain];
4907 } else { /* nothing is good, presume 0???? */
4908 correction[ichain] = 0;
4909 temperature[ichain] = 0;
4910 voltage[ichain] = 0;
4914 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4915 temperature);
4917 ath_dbg(common, EEPROM,
4918 "for frequency=%d, calibration correction = %d %d %d\n",
4919 frequency, correction[0], correction[1], correction[2]);
4921 return 0;
4924 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4925 int idx,
4926 int edge,
4927 bool is2GHz)
4929 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4930 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4932 if (is2GHz)
4933 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4934 else
4935 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4938 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4939 int idx,
4940 unsigned int edge,
4941 u16 freq,
4942 bool is2GHz)
4944 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4945 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4947 u8 *ctl_freqbin = is2GHz ?
4948 &eep->ctl_freqbin_2G[idx][0] :
4949 &eep->ctl_freqbin_5G[idx][0];
4951 if (is2GHz) {
4952 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4953 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4954 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4955 } else {
4956 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4957 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4958 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4961 return MAX_RATE_POWER;
4965 * Find the maximum conformance test limit for the given channel and CTL info
4967 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4968 u16 freq, int idx, bool is2GHz)
4970 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4971 u8 *ctl_freqbin = is2GHz ?
4972 &eep->ctl_freqbin_2G[idx][0] :
4973 &eep->ctl_freqbin_5G[idx][0];
4974 u16 num_edges = is2GHz ?
4975 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4976 unsigned int edge;
4978 /* Get the edge power */
4979 for (edge = 0;
4980 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
4981 edge++) {
4983 * If there's an exact channel match or an inband flag set
4984 * on the lower channel use the given rdEdgePower
4986 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
4987 twiceMaxEdgePower =
4988 ar9003_hw_get_direct_edge_power(eep, idx,
4989 edge, is2GHz);
4990 break;
4991 } else if ((edge > 0) &&
4992 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
4993 is2GHz))) {
4994 twiceMaxEdgePower =
4995 ar9003_hw_get_indirect_edge_power(eep, idx,
4996 edge, freq,
4997 is2GHz);
4999 * Leave loop - no more affecting edges possible in
5000 * this monotonic increasing list
5002 break;
5005 return twiceMaxEdgePower;
5008 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
5009 struct ath9k_channel *chan,
5010 u8 *pPwrArray, u16 cfgCtl,
5011 u8 antenna_reduction,
5012 u16 powerLimit)
5014 struct ath_common *common = ath9k_hw_common(ah);
5015 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
5016 u16 twiceMaxEdgePower;
5017 int i;
5018 u16 scaledPower = 0, minCtlPower;
5019 static const u16 ctlModesFor11a[] = {
5020 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
5022 static const u16 ctlModesFor11g[] = {
5023 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
5024 CTL_11G_EXT, CTL_2GHT40
5026 u16 numCtlModes;
5027 const u16 *pCtlMode;
5028 u16 ctlMode, freq;
5029 struct chan_centers centers;
5030 u8 *ctlIndex;
5031 u8 ctlNum;
5032 u16 twiceMinEdgePower;
5033 bool is2ghz = IS_CHAN_2GHZ(chan);
5035 ath9k_hw_get_channel_centers(ah, chan, &centers);
5036 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
5037 antenna_reduction);
5039 if (is2ghz) {
5040 /* Setup for CTL modes */
5041 /* CTL_11B, CTL_11G, CTL_2GHT20 */
5042 numCtlModes =
5043 ARRAY_SIZE(ctlModesFor11g) -
5044 SUB_NUM_CTL_MODES_AT_2G_40;
5045 pCtlMode = ctlModesFor11g;
5046 if (IS_CHAN_HT40(chan))
5047 /* All 2G CTL's */
5048 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
5049 } else {
5050 /* Setup for CTL modes */
5051 /* CTL_11A, CTL_5GHT20 */
5052 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
5053 SUB_NUM_CTL_MODES_AT_5G_40;
5054 pCtlMode = ctlModesFor11a;
5055 if (IS_CHAN_HT40(chan))
5056 /* All 5G CTL's */
5057 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
5061 * For MIMO, need to apply regulatory caps individually across
5062 * dynamically running modes: CCK, OFDM, HT20, HT40
5064 * The outer loop walks through each possible applicable runtime mode.
5065 * The inner loop walks through each ctlIndex entry in EEPROM.
5066 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
5068 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
5069 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
5070 (pCtlMode[ctlMode] == CTL_2GHT40);
5071 if (isHt40CtlMode)
5072 freq = centers.synth_center;
5073 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
5074 freq = centers.ext_center;
5075 else
5076 freq = centers.ctl_center;
5078 ath_dbg(common, REGULATORY,
5079 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
5080 ctlMode, numCtlModes, isHt40CtlMode,
5081 (pCtlMode[ctlMode] & EXT_ADDITIVE));
5083 /* walk through each CTL index stored in EEPROM */
5084 if (is2ghz) {
5085 ctlIndex = pEepData->ctlIndex_2G;
5086 ctlNum = AR9300_NUM_CTLS_2G;
5087 } else {
5088 ctlIndex = pEepData->ctlIndex_5G;
5089 ctlNum = AR9300_NUM_CTLS_5G;
5092 twiceMaxEdgePower = MAX_RATE_POWER;
5093 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
5094 ath_dbg(common, REGULATORY,
5095 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
5096 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
5097 chan->channel);
5100 * compare test group from regulatory
5101 * channel list with test mode from pCtlMode
5102 * list
5104 if ((((cfgCtl & ~CTL_MODE_M) |
5105 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5106 ctlIndex[i]) ||
5107 (((cfgCtl & ~CTL_MODE_M) |
5108 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5109 ((ctlIndex[i] & CTL_MODE_M) |
5110 SD_NO_CTL))) {
5111 twiceMinEdgePower =
5112 ar9003_hw_get_max_edge_power(pEepData,
5113 freq, i,
5114 is2ghz);
5116 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
5118 * Find the minimum of all CTL
5119 * edge powers that apply to
5120 * this channel
5122 twiceMaxEdgePower =
5123 min(twiceMaxEdgePower,
5124 twiceMinEdgePower);
5125 else {
5126 /* specific */
5127 twiceMaxEdgePower = twiceMinEdgePower;
5128 break;
5133 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
5135 ath_dbg(common, REGULATORY,
5136 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
5137 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
5138 scaledPower, minCtlPower);
5140 /* Apply ctl mode to correct target power set */
5141 switch (pCtlMode[ctlMode]) {
5142 case CTL_11B:
5143 for (i = ALL_TARGET_LEGACY_1L_5L;
5144 i <= ALL_TARGET_LEGACY_11S; i++)
5145 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5146 minCtlPower);
5147 break;
5148 case CTL_11A:
5149 case CTL_11G:
5150 for (i = ALL_TARGET_LEGACY_6_24;
5151 i <= ALL_TARGET_LEGACY_54; i++)
5152 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5153 minCtlPower);
5154 break;
5155 case CTL_5GHT20:
5156 case CTL_2GHT20:
5157 for (i = ALL_TARGET_HT20_0_8_16;
5158 i <= ALL_TARGET_HT20_23; i++) {
5159 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5160 minCtlPower);
5161 if (ath9k_hw_mci_is_enabled(ah))
5162 pPwrArray[i] =
5163 (u8)min((u16)pPwrArray[i],
5164 ar9003_mci_get_max_txpower(ah,
5165 pCtlMode[ctlMode]));
5167 break;
5168 case CTL_5GHT40:
5169 case CTL_2GHT40:
5170 for (i = ALL_TARGET_HT40_0_8_16;
5171 i <= ALL_TARGET_HT40_23; i++) {
5172 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5173 minCtlPower);
5174 if (ath9k_hw_mci_is_enabled(ah))
5175 pPwrArray[i] =
5176 (u8)min((u16)pPwrArray[i],
5177 ar9003_mci_get_max_txpower(ah,
5178 pCtlMode[ctlMode]));
5180 break;
5181 default:
5182 break;
5184 } /* end ctl mode checking */
5187 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5189 u8 mod_idx = mcs_idx % 8;
5191 if (mod_idx <= 3)
5192 return mod_idx ? (base_pwridx + 1) : base_pwridx;
5193 else
5194 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5197 static void ar9003_paprd_set_txpower(struct ath_hw *ah,
5198 struct ath9k_channel *chan,
5199 u8 *targetPowerValT2)
5201 int i;
5203 if (!ar9003_is_paprd_enabled(ah))
5204 return;
5206 if (IS_CHAN_HT40(chan))
5207 i = ALL_TARGET_HT40_7;
5208 else
5209 i = ALL_TARGET_HT20_7;
5211 if (IS_CHAN_2GHZ(chan)) {
5212 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) &&
5213 !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) {
5214 if (IS_CHAN_HT40(chan))
5215 i = ALL_TARGET_HT40_0_8_16;
5216 else
5217 i = ALL_TARGET_HT20_0_8_16;
5221 ah->paprd_target_power = targetPowerValT2[i];
5224 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5225 struct ath9k_channel *chan, u16 cfgCtl,
5226 u8 twiceAntennaReduction,
5227 u8 powerLimit, bool test)
5229 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5230 struct ath_common *common = ath9k_hw_common(ah);
5231 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5232 struct ar9300_modal_eep_header *modal_hdr;
5233 u8 targetPowerValT2[ar9300RateSize];
5234 u8 target_power_val_t2_eep[ar9300RateSize];
5235 unsigned int i = 0, paprd_scale_factor = 0;
5236 u8 pwr_idx, min_pwridx = 0;
5238 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5241 * Get target powers from EEPROM - our baseline for TX Power
5243 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5245 if (ar9003_is_paprd_enabled(ah)) {
5246 if (IS_CHAN_2GHZ(chan))
5247 modal_hdr = &eep->modalHeader2G;
5248 else
5249 modal_hdr = &eep->modalHeader5G;
5251 ah->paprd_ratemask =
5252 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5253 AR9300_PAPRD_RATE_MASK;
5255 ah->paprd_ratemask_ht40 =
5256 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5257 AR9300_PAPRD_RATE_MASK;
5259 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5260 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5261 ALL_TARGET_HT20_0_8_16;
5263 if (!ah->paprd_table_write_done) {
5264 memcpy(target_power_val_t2_eep, targetPowerValT2,
5265 sizeof(targetPowerValT2));
5266 for (i = 0; i < 24; i++) {
5267 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5268 if (ah->paprd_ratemask & (1 << i)) {
5269 if (targetPowerValT2[pwr_idx] &&
5270 targetPowerValT2[pwr_idx] ==
5271 target_power_val_t2_eep[pwr_idx])
5272 targetPowerValT2[pwr_idx] -=
5273 paprd_scale_factor;
5277 memcpy(target_power_val_t2_eep, targetPowerValT2,
5278 sizeof(targetPowerValT2));
5281 ar9003_hw_set_power_per_rate_table(ah, chan,
5282 targetPowerValT2, cfgCtl,
5283 twiceAntennaReduction,
5284 powerLimit);
5286 if (ar9003_is_paprd_enabled(ah)) {
5287 for (i = 0; i < ar9300RateSize; i++) {
5288 if ((ah->paprd_ratemask & (1 << i)) &&
5289 (abs(targetPowerValT2[i] -
5290 target_power_val_t2_eep[i]) >
5291 paprd_scale_factor)) {
5292 ah->paprd_ratemask &= ~(1 << i);
5293 ath_dbg(common, EEPROM,
5294 "paprd disabled for mcs %d\n", i);
5299 regulatory->max_power_level = 0;
5300 for (i = 0; i < ar9300RateSize; i++) {
5301 if (targetPowerValT2[i] > regulatory->max_power_level)
5302 regulatory->max_power_level = targetPowerValT2[i];
5305 ath9k_hw_update_regulatory_maxpower(ah);
5307 if (test)
5308 return;
5310 for (i = 0; i < ar9300RateSize; i++) {
5311 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
5312 i, targetPowerValT2[i]);
5315 /* Write target power array to registers */
5316 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5317 ar9003_hw_calibration_apply(ah, chan->channel);
5318 ar9003_paprd_set_txpower(ah, chan, targetPowerValT2);
5321 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5322 u16 i, bool is2GHz)
5324 return AR_NO_SPUR;
5327 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5329 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5331 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5334 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5336 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5338 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5341 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5343 return ar9003_modal_header(ah, is2ghz)->spurChans;
5346 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5347 struct ath9k_channel *chan)
5349 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5351 if (IS_CHAN_2GHZ(chan))
5352 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5353 AR9300_PAPRD_SCALE_1);
5354 else {
5355 if (chan->channel >= 5700)
5356 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5357 AR9300_PAPRD_SCALE_1);
5358 else if (chan->channel >= 5400)
5359 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5360 AR9300_PAPRD_SCALE_2);
5361 else
5362 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5363 AR9300_PAPRD_SCALE_1);
5367 const struct eeprom_ops eep_ar9300_ops = {
5368 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5369 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5370 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5371 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5372 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5373 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5374 .set_board_values = ath9k_hw_ar9300_set_board_values,
5375 .set_addac = ath9k_hw_ar9300_set_addac,
5376 .set_txpower = ath9k_hw_ar9300_set_txpower,
5377 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel