treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / net / wireless / ath / ath9k / ar9003_eeprom.c
blobb4885a700296e4fd418558c66831338803613cd2
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 <linux/kernel.h>
19 #include "hw.h"
20 #include "ar9003_phy.h"
21 #include "ar9003_eeprom.h"
22 #include "ar9003_mci.h"
24 #define COMP_HDR_LEN 4
25 #define COMP_CKSUM_LEN 2
27 #define LE16(x) cpu_to_le16(x)
28 #define LE32(x) cpu_to_le32(x)
30 /* Local defines to distinguish between extension and control CTL's */
31 #define EXT_ADDITIVE (0x8000)
32 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
33 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
34 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
36 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
37 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
39 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
41 #define EEPROM_DATA_LEN_9485 1088
43 static int ar9003_hw_power_interpolate(int32_t x,
44 int32_t *px, int32_t *py, u_int16_t np);
46 static const struct ar9300_eeprom ar9300_default = {
47 .eepromVersion = 2,
48 .templateVersion = 2,
49 .macAddr = {0, 2, 3, 4, 5, 6},
50 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
52 .baseEepHeader = {
53 .regDmn = { LE16(0), LE16(0x1f) },
54 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
55 .opCapFlags = {
56 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
57 .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
59 .rfSilent = 0,
60 .blueToothOptions = 0,
61 .deviceCap = 0,
62 .deviceType = 5, /* takes lower byte in eeprom location */
63 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
64 .params_for_tuning_caps = {0, 0},
65 .featureEnable = 0x0c,
67 * bit0 - enable tx temp comp - disabled
68 * bit1 - enable tx volt comp - disabled
69 * bit2 - enable fastClock - enabled
70 * bit3 - enable doubling - enabled
71 * bit4 - enable internal regulator - disabled
72 * bit5 - enable pa predistortion - disabled
74 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
75 .eepromWriteEnableGpio = 3,
76 .wlanDisableGpio = 0,
77 .wlanLedGpio = 8,
78 .rxBandSelectGpio = 0xff,
79 .txrxgain = 0,
80 .swreg = 0,
82 .modalHeader2G = {
83 /* ar9300_modal_eep_header 2g */
84 /* 4 idle,t1,t2,b(4 bits per setting) */
85 .antCtrlCommon = LE32(0x110),
86 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
87 .antCtrlCommon2 = LE32(0x22222),
90 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
91 * rx1, rx12, b (2 bits each)
93 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
96 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
97 * for ar9280 (0xa20c/b20c 5:0)
99 .xatten1DB = {0, 0, 0},
102 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
103 * for ar9280 (0xa20c/b20c 16:12
105 .xatten1Margin = {0, 0, 0},
106 .tempSlope = 36,
107 .voltSlope = 0,
110 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
111 * channels in usual fbin coding format
113 .spurChans = {0, 0, 0, 0, 0},
116 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
117 * if the register is per chain
119 .noiseFloorThreshCh = {-1, 0, 0},
120 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
121 .quick_drop = 0,
122 .xpaBiasLvl = 0,
123 .txFrameToDataStart = 0x0e,
124 .txFrameToPaOn = 0x0e,
125 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
126 .antennaGain = 0,
127 .switchSettling = 0x2c,
128 .adcDesiredSize = -30,
129 .txEndToXpaOff = 0,
130 .txEndToRxOn = 0x2,
131 .txFrameToXpaOn = 0xe,
132 .thresh62 = 28,
133 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
134 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
135 .switchcomspdt = 0,
136 .xlna_bias_strength = 0,
137 .futureModal = {
138 0, 0, 0, 0, 0, 0, 0,
141 .base_ext1 = {
142 .ant_div_control = 0,
143 .future = {0, 0},
144 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
146 .calFreqPier2G = {
147 FREQ2FBIN(2412, 1),
148 FREQ2FBIN(2437, 1),
149 FREQ2FBIN(2472, 1),
151 /* ar9300_cal_data_per_freq_op_loop 2g */
152 .calPierData2G = {
153 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
154 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
155 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
157 .calTarget_freqbin_Cck = {
158 FREQ2FBIN(2412, 1),
159 FREQ2FBIN(2484, 1),
161 .calTarget_freqbin_2G = {
162 FREQ2FBIN(2412, 1),
163 FREQ2FBIN(2437, 1),
164 FREQ2FBIN(2472, 1)
166 .calTarget_freqbin_2GHT20 = {
167 FREQ2FBIN(2412, 1),
168 FREQ2FBIN(2437, 1),
169 FREQ2FBIN(2472, 1)
171 .calTarget_freqbin_2GHT40 = {
172 FREQ2FBIN(2412, 1),
173 FREQ2FBIN(2437, 1),
174 FREQ2FBIN(2472, 1)
176 .calTargetPowerCck = {
177 /* 1L-5L,5S,11L,11S */
178 { {36, 36, 36, 36} },
179 { {36, 36, 36, 36} },
181 .calTargetPower2G = {
182 /* 6-24,36,48,54 */
183 { {32, 32, 28, 24} },
184 { {32, 32, 28, 24} },
185 { {32, 32, 28, 24} },
187 .calTargetPower2GHT20 = {
188 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
189 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
190 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
192 .calTargetPower2GHT40 = {
193 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
194 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
195 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
197 .ctlIndex_2G = {
198 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
199 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
201 .ctl_freqbin_2G = {
203 FREQ2FBIN(2412, 1),
204 FREQ2FBIN(2417, 1),
205 FREQ2FBIN(2457, 1),
206 FREQ2FBIN(2462, 1)
209 FREQ2FBIN(2412, 1),
210 FREQ2FBIN(2417, 1),
211 FREQ2FBIN(2462, 1),
212 0xFF,
216 FREQ2FBIN(2412, 1),
217 FREQ2FBIN(2417, 1),
218 FREQ2FBIN(2462, 1),
219 0xFF,
222 FREQ2FBIN(2422, 1),
223 FREQ2FBIN(2427, 1),
224 FREQ2FBIN(2447, 1),
225 FREQ2FBIN(2452, 1)
229 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
230 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
231 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
232 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
236 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
237 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
238 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
243 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
244 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
245 FREQ2FBIN(2472, 1),
250 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
251 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
252 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
253 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
257 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
258 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
259 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
263 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
264 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
265 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
270 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
271 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
272 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
277 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
278 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
279 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
280 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
283 .ctlPowerData_2G = {
284 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
285 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
286 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
288 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
289 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
290 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
292 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
293 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
294 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
296 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
297 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
298 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
300 .modalHeader5G = {
301 /* 4 idle,t1,t2,b (4 bits per setting) */
302 .antCtrlCommon = LE32(0x110),
303 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
304 .antCtrlCommon2 = LE32(0x22222),
305 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
306 .antCtrlChain = {
307 LE16(0x000), LE16(0x000), LE16(0x000),
309 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
310 .xatten1DB = {0, 0, 0},
313 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
314 * for merlin (0xa20c/b20c 16:12
316 .xatten1Margin = {0, 0, 0},
317 .tempSlope = 68,
318 .voltSlope = 0,
319 /* spurChans spur channels in usual fbin coding format */
320 .spurChans = {0, 0, 0, 0, 0},
321 /* noiseFloorThreshCh Check if the register is per chain */
322 .noiseFloorThreshCh = {-1, 0, 0},
323 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
324 .quick_drop = 0,
325 .xpaBiasLvl = 0,
326 .txFrameToDataStart = 0x0e,
327 .txFrameToPaOn = 0x0e,
328 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
329 .antennaGain = 0,
330 .switchSettling = 0x2d,
331 .adcDesiredSize = -30,
332 .txEndToXpaOff = 0,
333 .txEndToRxOn = 0x2,
334 .txFrameToXpaOn = 0xe,
335 .thresh62 = 28,
336 .papdRateMaskHt20 = LE32(0x0c80c080),
337 .papdRateMaskHt40 = LE32(0x0080c080),
338 .switchcomspdt = 0,
339 .xlna_bias_strength = 0,
340 .futureModal = {
341 0, 0, 0, 0, 0, 0, 0,
344 .base_ext2 = {
345 .tempSlopeLow = 0,
346 .tempSlopeHigh = 0,
347 .xatten1DBLow = {0, 0, 0},
348 .xatten1MarginLow = {0, 0, 0},
349 .xatten1DBHigh = {0, 0, 0},
350 .xatten1MarginHigh = {0, 0, 0}
352 .calFreqPier5G = {
353 FREQ2FBIN(5180, 0),
354 FREQ2FBIN(5220, 0),
355 FREQ2FBIN(5320, 0),
356 FREQ2FBIN(5400, 0),
357 FREQ2FBIN(5500, 0),
358 FREQ2FBIN(5600, 0),
359 FREQ2FBIN(5725, 0),
360 FREQ2FBIN(5825, 0)
362 .calPierData5G = {
364 {0, 0, 0, 0, 0},
365 {0, 0, 0, 0, 0},
366 {0, 0, 0, 0, 0},
367 {0, 0, 0, 0, 0},
368 {0, 0, 0, 0, 0},
369 {0, 0, 0, 0, 0},
370 {0, 0, 0, 0, 0},
371 {0, 0, 0, 0, 0},
374 {0, 0, 0, 0, 0},
375 {0, 0, 0, 0, 0},
376 {0, 0, 0, 0, 0},
377 {0, 0, 0, 0, 0},
378 {0, 0, 0, 0, 0},
379 {0, 0, 0, 0, 0},
380 {0, 0, 0, 0, 0},
381 {0, 0, 0, 0, 0},
384 {0, 0, 0, 0, 0},
385 {0, 0, 0, 0, 0},
386 {0, 0, 0, 0, 0},
387 {0, 0, 0, 0, 0},
388 {0, 0, 0, 0, 0},
389 {0, 0, 0, 0, 0},
390 {0, 0, 0, 0, 0},
391 {0, 0, 0, 0, 0},
395 .calTarget_freqbin_5G = {
396 FREQ2FBIN(5180, 0),
397 FREQ2FBIN(5220, 0),
398 FREQ2FBIN(5320, 0),
399 FREQ2FBIN(5400, 0),
400 FREQ2FBIN(5500, 0),
401 FREQ2FBIN(5600, 0),
402 FREQ2FBIN(5725, 0),
403 FREQ2FBIN(5825, 0)
405 .calTarget_freqbin_5GHT20 = {
406 FREQ2FBIN(5180, 0),
407 FREQ2FBIN(5240, 0),
408 FREQ2FBIN(5320, 0),
409 FREQ2FBIN(5500, 0),
410 FREQ2FBIN(5700, 0),
411 FREQ2FBIN(5745, 0),
412 FREQ2FBIN(5725, 0),
413 FREQ2FBIN(5825, 0)
415 .calTarget_freqbin_5GHT40 = {
416 FREQ2FBIN(5180, 0),
417 FREQ2FBIN(5240, 0),
418 FREQ2FBIN(5320, 0),
419 FREQ2FBIN(5500, 0),
420 FREQ2FBIN(5700, 0),
421 FREQ2FBIN(5745, 0),
422 FREQ2FBIN(5725, 0),
423 FREQ2FBIN(5825, 0)
425 .calTargetPower5G = {
426 /* 6-24,36,48,54 */
427 { {20, 20, 20, 10} },
428 { {20, 20, 20, 10} },
429 { {20, 20, 20, 10} },
430 { {20, 20, 20, 10} },
431 { {20, 20, 20, 10} },
432 { {20, 20, 20, 10} },
433 { {20, 20, 20, 10} },
434 { {20, 20, 20, 10} },
436 .calTargetPower5GHT20 = {
438 * 0_8_16,1-3_9-11_17-19,
439 * 4,5,6,7,12,13,14,15,20,21,22,23
441 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
442 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
443 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
444 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
445 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
446 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
447 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
448 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
450 .calTargetPower5GHT40 = {
452 * 0_8_16,1-3_9-11_17-19,
453 * 4,5,6,7,12,13,14,15,20,21,22,23
455 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
456 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
457 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
458 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
459 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
460 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
461 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
462 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
464 .ctlIndex_5G = {
465 0x10, 0x16, 0x18, 0x40, 0x46,
466 0x48, 0x30, 0x36, 0x38
468 .ctl_freqbin_5G = {
470 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
471 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
472 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
473 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
474 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
475 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
476 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
477 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
480 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
481 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
482 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
483 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
484 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
485 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
486 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
487 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
491 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
492 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
493 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
494 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
495 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
496 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
497 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
498 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
502 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
503 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
504 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
505 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
506 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
507 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
508 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
509 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
513 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
514 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
515 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
516 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
517 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
518 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
519 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
520 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
524 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
525 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
526 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
527 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
528 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
529 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
530 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
531 /* Data[5].ctlEdges[7].bChannel */ 0xFF
535 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
536 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
537 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
538 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
539 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
540 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
541 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
542 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
546 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
547 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
548 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
549 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
550 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
551 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
552 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
553 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
557 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
558 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
559 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
560 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
561 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
562 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
563 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
564 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
567 .ctlPowerData_5G = {
570 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
571 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
576 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
577 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
582 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
583 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
588 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
589 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
594 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
595 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
600 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
601 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
606 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
607 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
612 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
613 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
618 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
619 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
625 static const struct ar9300_eeprom ar9300_x113 = {
626 .eepromVersion = 2,
627 .templateVersion = 6,
628 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
629 .custData = {"x113-023-f0000"},
630 .baseEepHeader = {
631 .regDmn = { LE16(0), LE16(0x1f) },
632 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
633 .opCapFlags = {
634 .opFlags = AR5416_OPFLAGS_11A,
635 .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
637 .rfSilent = 0,
638 .blueToothOptions = 0,
639 .deviceCap = 0,
640 .deviceType = 5, /* takes lower byte in eeprom location */
641 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
642 .params_for_tuning_caps = {0, 0},
643 .featureEnable = 0x0d,
645 * bit0 - enable tx temp comp - disabled
646 * bit1 - enable tx volt comp - disabled
647 * bit2 - enable fastClock - enabled
648 * bit3 - enable doubling - enabled
649 * bit4 - enable internal regulator - disabled
650 * bit5 - enable pa predistortion - disabled
652 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
653 .eepromWriteEnableGpio = 6,
654 .wlanDisableGpio = 0,
655 .wlanLedGpio = 8,
656 .rxBandSelectGpio = 0xff,
657 .txrxgain = 0x21,
658 .swreg = 0,
660 .modalHeader2G = {
661 /* ar9300_modal_eep_header 2g */
662 /* 4 idle,t1,t2,b(4 bits per setting) */
663 .antCtrlCommon = LE32(0x110),
664 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
665 .antCtrlCommon2 = LE32(0x44444),
668 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
669 * rx1, rx12, b (2 bits each)
671 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
674 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
675 * for ar9280 (0xa20c/b20c 5:0)
677 .xatten1DB = {0, 0, 0},
680 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
681 * for ar9280 (0xa20c/b20c 16:12
683 .xatten1Margin = {0, 0, 0},
684 .tempSlope = 25,
685 .voltSlope = 0,
688 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
689 * channels in usual fbin coding format
691 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
694 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
695 * if the register is per chain
697 .noiseFloorThreshCh = {-1, 0, 0},
698 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
699 .quick_drop = 0,
700 .xpaBiasLvl = 0,
701 .txFrameToDataStart = 0x0e,
702 .txFrameToPaOn = 0x0e,
703 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
704 .antennaGain = 0,
705 .switchSettling = 0x2c,
706 .adcDesiredSize = -30,
707 .txEndToXpaOff = 0,
708 .txEndToRxOn = 0x2,
709 .txFrameToXpaOn = 0xe,
710 .thresh62 = 28,
711 .papdRateMaskHt20 = LE32(0x0c80c080),
712 .papdRateMaskHt40 = LE32(0x0080c080),
713 .switchcomspdt = 0,
714 .xlna_bias_strength = 0,
715 .futureModal = {
716 0, 0, 0, 0, 0, 0, 0,
719 .base_ext1 = {
720 .ant_div_control = 0,
721 .future = {0, 0},
722 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
724 .calFreqPier2G = {
725 FREQ2FBIN(2412, 1),
726 FREQ2FBIN(2437, 1),
727 FREQ2FBIN(2472, 1),
729 /* ar9300_cal_data_per_freq_op_loop 2g */
730 .calPierData2G = {
731 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
732 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
733 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
735 .calTarget_freqbin_Cck = {
736 FREQ2FBIN(2412, 1),
737 FREQ2FBIN(2472, 1),
739 .calTarget_freqbin_2G = {
740 FREQ2FBIN(2412, 1),
741 FREQ2FBIN(2437, 1),
742 FREQ2FBIN(2472, 1)
744 .calTarget_freqbin_2GHT20 = {
745 FREQ2FBIN(2412, 1),
746 FREQ2FBIN(2437, 1),
747 FREQ2FBIN(2472, 1)
749 .calTarget_freqbin_2GHT40 = {
750 FREQ2FBIN(2412, 1),
751 FREQ2FBIN(2437, 1),
752 FREQ2FBIN(2472, 1)
754 .calTargetPowerCck = {
755 /* 1L-5L,5S,11L,11S */
756 { {34, 34, 34, 34} },
757 { {34, 34, 34, 34} },
759 .calTargetPower2G = {
760 /* 6-24,36,48,54 */
761 { {34, 34, 32, 32} },
762 { {34, 34, 32, 32} },
763 { {34, 34, 32, 32} },
765 .calTargetPower2GHT20 = {
766 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
767 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
768 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
770 .calTargetPower2GHT40 = {
771 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
772 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
773 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
775 .ctlIndex_2G = {
776 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
777 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
779 .ctl_freqbin_2G = {
781 FREQ2FBIN(2412, 1),
782 FREQ2FBIN(2417, 1),
783 FREQ2FBIN(2457, 1),
784 FREQ2FBIN(2462, 1)
787 FREQ2FBIN(2412, 1),
788 FREQ2FBIN(2417, 1),
789 FREQ2FBIN(2462, 1),
790 0xFF,
794 FREQ2FBIN(2412, 1),
795 FREQ2FBIN(2417, 1),
796 FREQ2FBIN(2462, 1),
797 0xFF,
800 FREQ2FBIN(2422, 1),
801 FREQ2FBIN(2427, 1),
802 FREQ2FBIN(2447, 1),
803 FREQ2FBIN(2452, 1)
807 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
808 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
809 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
810 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
814 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
815 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
816 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
821 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
822 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
823 FREQ2FBIN(2472, 1),
828 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
829 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
830 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
831 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
835 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
836 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
837 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
841 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
842 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
843 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
848 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
849 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
850 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
855 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
856 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
857 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
858 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
861 .ctlPowerData_2G = {
862 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
863 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
864 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
866 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), 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, 1), CTL(60, 0) } },
871 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
872 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
874 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
875 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
876 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
878 .modalHeader5G = {
879 /* 4 idle,t1,t2,b (4 bits per setting) */
880 .antCtrlCommon = LE32(0x220),
881 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
882 .antCtrlCommon2 = LE32(0x11111),
883 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
884 .antCtrlChain = {
885 LE16(0x150), LE16(0x150), LE16(0x150),
887 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
888 .xatten1DB = {0, 0, 0},
891 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
892 * for merlin (0xa20c/b20c 16:12
894 .xatten1Margin = {0, 0, 0},
895 .tempSlope = 68,
896 .voltSlope = 0,
897 /* spurChans spur channels in usual fbin coding format */
898 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
899 /* noiseFloorThreshCh Check if the register is per chain */
900 .noiseFloorThreshCh = {-1, 0, 0},
901 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
902 .quick_drop = 0,
903 .xpaBiasLvl = 0xf,
904 .txFrameToDataStart = 0x0e,
905 .txFrameToPaOn = 0x0e,
906 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
907 .antennaGain = 0,
908 .switchSettling = 0x2d,
909 .adcDesiredSize = -30,
910 .txEndToXpaOff = 0,
911 .txEndToRxOn = 0x2,
912 .txFrameToXpaOn = 0xe,
913 .thresh62 = 28,
914 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
915 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
916 .switchcomspdt = 0,
917 .xlna_bias_strength = 0,
918 .futureModal = {
919 0, 0, 0, 0, 0, 0, 0,
922 .base_ext2 = {
923 .tempSlopeLow = 72,
924 .tempSlopeHigh = 105,
925 .xatten1DBLow = {0, 0, 0},
926 .xatten1MarginLow = {0, 0, 0},
927 .xatten1DBHigh = {0, 0, 0},
928 .xatten1MarginHigh = {0, 0, 0}
930 .calFreqPier5G = {
931 FREQ2FBIN(5180, 0),
932 FREQ2FBIN(5240, 0),
933 FREQ2FBIN(5320, 0),
934 FREQ2FBIN(5400, 0),
935 FREQ2FBIN(5500, 0),
936 FREQ2FBIN(5600, 0),
937 FREQ2FBIN(5745, 0),
938 FREQ2FBIN(5785, 0)
940 .calPierData5G = {
942 {0, 0, 0, 0, 0},
943 {0, 0, 0, 0, 0},
944 {0, 0, 0, 0, 0},
945 {0, 0, 0, 0, 0},
946 {0, 0, 0, 0, 0},
947 {0, 0, 0, 0, 0},
948 {0, 0, 0, 0, 0},
949 {0, 0, 0, 0, 0},
952 {0, 0, 0, 0, 0},
953 {0, 0, 0, 0, 0},
954 {0, 0, 0, 0, 0},
955 {0, 0, 0, 0, 0},
956 {0, 0, 0, 0, 0},
957 {0, 0, 0, 0, 0},
958 {0, 0, 0, 0, 0},
959 {0, 0, 0, 0, 0},
962 {0, 0, 0, 0, 0},
963 {0, 0, 0, 0, 0},
964 {0, 0, 0, 0, 0},
965 {0, 0, 0, 0, 0},
966 {0, 0, 0, 0, 0},
967 {0, 0, 0, 0, 0},
968 {0, 0, 0, 0, 0},
969 {0, 0, 0, 0, 0},
973 .calTarget_freqbin_5G = {
974 FREQ2FBIN(5180, 0),
975 FREQ2FBIN(5220, 0),
976 FREQ2FBIN(5320, 0),
977 FREQ2FBIN(5400, 0),
978 FREQ2FBIN(5500, 0),
979 FREQ2FBIN(5600, 0),
980 FREQ2FBIN(5745, 0),
981 FREQ2FBIN(5785, 0)
983 .calTarget_freqbin_5GHT20 = {
984 FREQ2FBIN(5180, 0),
985 FREQ2FBIN(5240, 0),
986 FREQ2FBIN(5320, 0),
987 FREQ2FBIN(5400, 0),
988 FREQ2FBIN(5500, 0),
989 FREQ2FBIN(5700, 0),
990 FREQ2FBIN(5745, 0),
991 FREQ2FBIN(5825, 0)
993 .calTarget_freqbin_5GHT40 = {
994 FREQ2FBIN(5190, 0),
995 FREQ2FBIN(5230, 0),
996 FREQ2FBIN(5320, 0),
997 FREQ2FBIN(5410, 0),
998 FREQ2FBIN(5510, 0),
999 FREQ2FBIN(5670, 0),
1000 FREQ2FBIN(5755, 0),
1001 FREQ2FBIN(5825, 0)
1003 .calTargetPower5G = {
1004 /* 6-24,36,48,54 */
1005 { {42, 40, 40, 34} },
1006 { {42, 40, 40, 34} },
1007 { {42, 40, 40, 34} },
1008 { {42, 40, 40, 34} },
1009 { {42, 40, 40, 34} },
1010 { {42, 40, 40, 34} },
1011 { {42, 40, 40, 34} },
1012 { {42, 40, 40, 34} },
1014 .calTargetPower5GHT20 = {
1016 * 0_8_16,1-3_9-11_17-19,
1017 * 4,5,6,7,12,13,14,15,20,21,22,23
1019 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1020 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1021 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1022 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1023 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1024 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1025 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1026 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1028 .calTargetPower5GHT40 = {
1030 * 0_8_16,1-3_9-11_17-19,
1031 * 4,5,6,7,12,13,14,15,20,21,22,23
1033 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1034 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1035 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1036 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1037 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1038 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1039 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1040 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1042 .ctlIndex_5G = {
1043 0x10, 0x16, 0x18, 0x40, 0x46,
1044 0x48, 0x30, 0x36, 0x38
1046 .ctl_freqbin_5G = {
1048 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1049 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1050 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1051 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1052 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1053 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1054 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1055 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1058 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1059 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1060 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1061 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1062 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1063 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1064 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1065 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1069 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1070 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1071 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1072 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1073 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1074 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1075 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1076 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1080 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1081 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1082 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1083 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1084 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1085 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1086 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1087 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1091 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1092 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1093 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1094 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1095 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1096 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1097 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1098 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1102 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1103 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1104 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1105 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1106 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1107 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1108 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1109 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1113 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1114 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1115 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1116 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1117 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1118 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1119 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1120 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1124 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1125 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1126 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1127 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1128 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1129 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1130 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1131 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1135 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1136 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1137 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1138 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1139 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1140 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1141 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1142 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1145 .ctlPowerData_5G = {
1148 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1149 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1154 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1155 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1160 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1161 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1166 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1167 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1172 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1173 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1178 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1179 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1184 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1185 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1190 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1191 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1196 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1197 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1204 static const struct ar9300_eeprom ar9300_h112 = {
1205 .eepromVersion = 2,
1206 .templateVersion = 3,
1207 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1208 .custData = {"h112-241-f0000"},
1209 .baseEepHeader = {
1210 .regDmn = { LE16(0), LE16(0x1f) },
1211 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1212 .opCapFlags = {
1213 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1214 .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
1216 .rfSilent = 0,
1217 .blueToothOptions = 0,
1218 .deviceCap = 0,
1219 .deviceType = 5, /* takes lower byte in eeprom location */
1220 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1221 .params_for_tuning_caps = {0, 0},
1222 .featureEnable = 0x0d,
1224 * bit0 - enable tx temp comp - disabled
1225 * bit1 - enable tx volt comp - disabled
1226 * bit2 - enable fastClock - enabled
1227 * bit3 - enable doubling - enabled
1228 * bit4 - enable internal regulator - disabled
1229 * bit5 - enable pa predistortion - disabled
1231 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1232 .eepromWriteEnableGpio = 6,
1233 .wlanDisableGpio = 0,
1234 .wlanLedGpio = 8,
1235 .rxBandSelectGpio = 0xff,
1236 .txrxgain = 0x10,
1237 .swreg = 0,
1239 .modalHeader2G = {
1240 /* ar9300_modal_eep_header 2g */
1241 /* 4 idle,t1,t2,b(4 bits per setting) */
1242 .antCtrlCommon = LE32(0x110),
1243 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1244 .antCtrlCommon2 = LE32(0x44444),
1247 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1248 * rx1, rx12, b (2 bits each)
1250 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1253 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1254 * for ar9280 (0xa20c/b20c 5:0)
1256 .xatten1DB = {0, 0, 0},
1259 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1260 * for ar9280 (0xa20c/b20c 16:12
1262 .xatten1Margin = {0, 0, 0},
1263 .tempSlope = 25,
1264 .voltSlope = 0,
1267 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1268 * channels in usual fbin coding format
1270 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1273 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1274 * if the register is per chain
1276 .noiseFloorThreshCh = {-1, 0, 0},
1277 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1278 .quick_drop = 0,
1279 .xpaBiasLvl = 0,
1280 .txFrameToDataStart = 0x0e,
1281 .txFrameToPaOn = 0x0e,
1282 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1283 .antennaGain = 0,
1284 .switchSettling = 0x2c,
1285 .adcDesiredSize = -30,
1286 .txEndToXpaOff = 0,
1287 .txEndToRxOn = 0x2,
1288 .txFrameToXpaOn = 0xe,
1289 .thresh62 = 28,
1290 .papdRateMaskHt20 = LE32(0x0c80c080),
1291 .papdRateMaskHt40 = LE32(0x0080c080),
1292 .switchcomspdt = 0,
1293 .xlna_bias_strength = 0,
1294 .futureModal = {
1295 0, 0, 0, 0, 0, 0, 0,
1298 .base_ext1 = {
1299 .ant_div_control = 0,
1300 .future = {0, 0},
1301 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1303 .calFreqPier2G = {
1304 FREQ2FBIN(2412, 1),
1305 FREQ2FBIN(2437, 1),
1306 FREQ2FBIN(2462, 1),
1308 /* ar9300_cal_data_per_freq_op_loop 2g */
1309 .calPierData2G = {
1310 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1311 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1312 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1314 .calTarget_freqbin_Cck = {
1315 FREQ2FBIN(2412, 1),
1316 FREQ2FBIN(2472, 1),
1318 .calTarget_freqbin_2G = {
1319 FREQ2FBIN(2412, 1),
1320 FREQ2FBIN(2437, 1),
1321 FREQ2FBIN(2472, 1)
1323 .calTarget_freqbin_2GHT20 = {
1324 FREQ2FBIN(2412, 1),
1325 FREQ2FBIN(2437, 1),
1326 FREQ2FBIN(2472, 1)
1328 .calTarget_freqbin_2GHT40 = {
1329 FREQ2FBIN(2412, 1),
1330 FREQ2FBIN(2437, 1),
1331 FREQ2FBIN(2472, 1)
1333 .calTargetPowerCck = {
1334 /* 1L-5L,5S,11L,11S */
1335 { {34, 34, 34, 34} },
1336 { {34, 34, 34, 34} },
1338 .calTargetPower2G = {
1339 /* 6-24,36,48,54 */
1340 { {34, 34, 32, 32} },
1341 { {34, 34, 32, 32} },
1342 { {34, 34, 32, 32} },
1344 .calTargetPower2GHT20 = {
1345 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1346 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1347 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1349 .calTargetPower2GHT40 = {
1350 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1351 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1352 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1354 .ctlIndex_2G = {
1355 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1356 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1358 .ctl_freqbin_2G = {
1360 FREQ2FBIN(2412, 1),
1361 FREQ2FBIN(2417, 1),
1362 FREQ2FBIN(2457, 1),
1363 FREQ2FBIN(2462, 1)
1366 FREQ2FBIN(2412, 1),
1367 FREQ2FBIN(2417, 1),
1368 FREQ2FBIN(2462, 1),
1369 0xFF,
1373 FREQ2FBIN(2412, 1),
1374 FREQ2FBIN(2417, 1),
1375 FREQ2FBIN(2462, 1),
1376 0xFF,
1379 FREQ2FBIN(2422, 1),
1380 FREQ2FBIN(2427, 1),
1381 FREQ2FBIN(2447, 1),
1382 FREQ2FBIN(2452, 1)
1386 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1387 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1388 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1389 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1393 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1394 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1395 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1400 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1401 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1402 FREQ2FBIN(2472, 1),
1407 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1408 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1409 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1410 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1414 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1415 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1416 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1420 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1421 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1422 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1427 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1428 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1429 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1434 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1435 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1436 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1437 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1440 .ctlPowerData_2G = {
1441 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1442 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1443 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1445 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
1446 { { 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) } },
1449 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1450 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1451 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1453 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1454 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1455 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1457 .modalHeader5G = {
1458 /* 4 idle,t1,t2,b (4 bits per setting) */
1459 .antCtrlCommon = LE32(0x220),
1460 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1461 .antCtrlCommon2 = LE32(0x44444),
1462 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1463 .antCtrlChain = {
1464 LE16(0x150), LE16(0x150), LE16(0x150),
1466 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1467 .xatten1DB = {0, 0, 0},
1470 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1471 * for merlin (0xa20c/b20c 16:12
1473 .xatten1Margin = {0, 0, 0},
1474 .tempSlope = 45,
1475 .voltSlope = 0,
1476 /* spurChans spur channels in usual fbin coding format */
1477 .spurChans = {0, 0, 0, 0, 0},
1478 /* noiseFloorThreshCh Check if the register is per chain */
1479 .noiseFloorThreshCh = {-1, 0, 0},
1480 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1481 .quick_drop = 0,
1482 .xpaBiasLvl = 0,
1483 .txFrameToDataStart = 0x0e,
1484 .txFrameToPaOn = 0x0e,
1485 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1486 .antennaGain = 0,
1487 .switchSettling = 0x2d,
1488 .adcDesiredSize = -30,
1489 .txEndToXpaOff = 0,
1490 .txEndToRxOn = 0x2,
1491 .txFrameToXpaOn = 0xe,
1492 .thresh62 = 28,
1493 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1494 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1495 .switchcomspdt = 0,
1496 .xlna_bias_strength = 0,
1497 .futureModal = {
1498 0, 0, 0, 0, 0, 0, 0,
1501 .base_ext2 = {
1502 .tempSlopeLow = 40,
1503 .tempSlopeHigh = 50,
1504 .xatten1DBLow = {0, 0, 0},
1505 .xatten1MarginLow = {0, 0, 0},
1506 .xatten1DBHigh = {0, 0, 0},
1507 .xatten1MarginHigh = {0, 0, 0}
1509 .calFreqPier5G = {
1510 FREQ2FBIN(5180, 0),
1511 FREQ2FBIN(5220, 0),
1512 FREQ2FBIN(5320, 0),
1513 FREQ2FBIN(5400, 0),
1514 FREQ2FBIN(5500, 0),
1515 FREQ2FBIN(5600, 0),
1516 FREQ2FBIN(5700, 0),
1517 FREQ2FBIN(5785, 0)
1519 .calPierData5G = {
1521 {0, 0, 0, 0, 0},
1522 {0, 0, 0, 0, 0},
1523 {0, 0, 0, 0, 0},
1524 {0, 0, 0, 0, 0},
1525 {0, 0, 0, 0, 0},
1526 {0, 0, 0, 0, 0},
1527 {0, 0, 0, 0, 0},
1528 {0, 0, 0, 0, 0},
1531 {0, 0, 0, 0, 0},
1532 {0, 0, 0, 0, 0},
1533 {0, 0, 0, 0, 0},
1534 {0, 0, 0, 0, 0},
1535 {0, 0, 0, 0, 0},
1536 {0, 0, 0, 0, 0},
1537 {0, 0, 0, 0, 0},
1538 {0, 0, 0, 0, 0},
1541 {0, 0, 0, 0, 0},
1542 {0, 0, 0, 0, 0},
1543 {0, 0, 0, 0, 0},
1544 {0, 0, 0, 0, 0},
1545 {0, 0, 0, 0, 0},
1546 {0, 0, 0, 0, 0},
1547 {0, 0, 0, 0, 0},
1548 {0, 0, 0, 0, 0},
1552 .calTarget_freqbin_5G = {
1553 FREQ2FBIN(5180, 0),
1554 FREQ2FBIN(5240, 0),
1555 FREQ2FBIN(5320, 0),
1556 FREQ2FBIN(5400, 0),
1557 FREQ2FBIN(5500, 0),
1558 FREQ2FBIN(5600, 0),
1559 FREQ2FBIN(5700, 0),
1560 FREQ2FBIN(5825, 0)
1562 .calTarget_freqbin_5GHT20 = {
1563 FREQ2FBIN(5180, 0),
1564 FREQ2FBIN(5240, 0),
1565 FREQ2FBIN(5320, 0),
1566 FREQ2FBIN(5400, 0),
1567 FREQ2FBIN(5500, 0),
1568 FREQ2FBIN(5700, 0),
1569 FREQ2FBIN(5745, 0),
1570 FREQ2FBIN(5825, 0)
1572 .calTarget_freqbin_5GHT40 = {
1573 FREQ2FBIN(5180, 0),
1574 FREQ2FBIN(5240, 0),
1575 FREQ2FBIN(5320, 0),
1576 FREQ2FBIN(5400, 0),
1577 FREQ2FBIN(5500, 0),
1578 FREQ2FBIN(5700, 0),
1579 FREQ2FBIN(5745, 0),
1580 FREQ2FBIN(5825, 0)
1582 .calTargetPower5G = {
1583 /* 6-24,36,48,54 */
1584 { {30, 30, 28, 24} },
1585 { {30, 30, 28, 24} },
1586 { {30, 30, 28, 24} },
1587 { {30, 30, 28, 24} },
1588 { {30, 30, 28, 24} },
1589 { {30, 30, 28, 24} },
1590 { {30, 30, 28, 24} },
1591 { {30, 30, 28, 24} },
1593 .calTargetPower5GHT20 = {
1595 * 0_8_16,1-3_9-11_17-19,
1596 * 4,5,6,7,12,13,14,15,20,21,22,23
1598 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1599 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1600 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1601 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1602 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1603 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1604 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1605 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1607 .calTargetPower5GHT40 = {
1609 * 0_8_16,1-3_9-11_17-19,
1610 * 4,5,6,7,12,13,14,15,20,21,22,23
1612 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1613 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1614 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1615 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1616 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1617 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1618 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1619 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1621 .ctlIndex_5G = {
1622 0x10, 0x16, 0x18, 0x40, 0x46,
1623 0x48, 0x30, 0x36, 0x38
1625 .ctl_freqbin_5G = {
1627 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1628 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1629 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1630 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1631 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1632 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1633 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1634 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1637 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1638 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1639 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1640 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1641 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1642 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1643 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1644 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1648 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1649 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1650 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1651 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1652 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1653 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1654 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1655 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1659 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1660 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1661 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1662 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1663 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1664 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1665 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1666 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1670 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1671 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1672 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1673 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1674 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1675 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1676 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1677 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1681 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1682 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1683 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1684 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1685 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1686 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1687 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1688 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1692 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1693 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1694 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1695 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1696 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1697 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1698 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1699 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1703 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1704 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1705 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1706 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1707 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1708 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1709 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1710 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1714 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1715 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1716 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1717 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1718 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1719 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1720 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1721 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1724 .ctlPowerData_5G = {
1727 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1728 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1733 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1734 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1739 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1740 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1745 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1746 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1751 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1752 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1757 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1758 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1763 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1764 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1769 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1770 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1775 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1776 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1783 static const struct ar9300_eeprom ar9300_x112 = {
1784 .eepromVersion = 2,
1785 .templateVersion = 5,
1786 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1787 .custData = {"x112-041-f0000"},
1788 .baseEepHeader = {
1789 .regDmn = { LE16(0), LE16(0x1f) },
1790 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1791 .opCapFlags = {
1792 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1793 .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
1795 .rfSilent = 0,
1796 .blueToothOptions = 0,
1797 .deviceCap = 0,
1798 .deviceType = 5, /* takes lower byte in eeprom location */
1799 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1800 .params_for_tuning_caps = {0, 0},
1801 .featureEnable = 0x0d,
1803 * bit0 - enable tx temp comp - disabled
1804 * bit1 - enable tx volt comp - disabled
1805 * bit2 - enable fastclock - enabled
1806 * bit3 - enable doubling - enabled
1807 * bit4 - enable internal regulator - disabled
1808 * bit5 - enable pa predistortion - disabled
1810 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1811 .eepromWriteEnableGpio = 6,
1812 .wlanDisableGpio = 0,
1813 .wlanLedGpio = 8,
1814 .rxBandSelectGpio = 0xff,
1815 .txrxgain = 0x0,
1816 .swreg = 0,
1818 .modalHeader2G = {
1819 /* ar9300_modal_eep_header 2g */
1820 /* 4 idle,t1,t2,b(4 bits per setting) */
1821 .antCtrlCommon = LE32(0x110),
1822 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1823 .antCtrlCommon2 = LE32(0x22222),
1826 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1827 * rx1, rx12, b (2 bits each)
1829 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1832 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1833 * for ar9280 (0xa20c/b20c 5:0)
1835 .xatten1DB = {0x1b, 0x1b, 0x1b},
1838 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1839 * for ar9280 (0xa20c/b20c 16:12
1841 .xatten1Margin = {0x15, 0x15, 0x15},
1842 .tempSlope = 50,
1843 .voltSlope = 0,
1846 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1847 * channels in usual fbin coding format
1849 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1852 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1853 * if the register is per chain
1855 .noiseFloorThreshCh = {-1, 0, 0},
1856 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1857 .quick_drop = 0,
1858 .xpaBiasLvl = 0,
1859 .txFrameToDataStart = 0x0e,
1860 .txFrameToPaOn = 0x0e,
1861 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1862 .antennaGain = 0,
1863 .switchSettling = 0x2c,
1864 .adcDesiredSize = -30,
1865 .txEndToXpaOff = 0,
1866 .txEndToRxOn = 0x2,
1867 .txFrameToXpaOn = 0xe,
1868 .thresh62 = 28,
1869 .papdRateMaskHt20 = LE32(0x0c80c080),
1870 .papdRateMaskHt40 = LE32(0x0080c080),
1871 .switchcomspdt = 0,
1872 .xlna_bias_strength = 0,
1873 .futureModal = {
1874 0, 0, 0, 0, 0, 0, 0,
1877 .base_ext1 = {
1878 .ant_div_control = 0,
1879 .future = {0, 0},
1880 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1882 .calFreqPier2G = {
1883 FREQ2FBIN(2412, 1),
1884 FREQ2FBIN(2437, 1),
1885 FREQ2FBIN(2472, 1),
1887 /* ar9300_cal_data_per_freq_op_loop 2g */
1888 .calPierData2G = {
1889 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1890 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1891 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1893 .calTarget_freqbin_Cck = {
1894 FREQ2FBIN(2412, 1),
1895 FREQ2FBIN(2472, 1),
1897 .calTarget_freqbin_2G = {
1898 FREQ2FBIN(2412, 1),
1899 FREQ2FBIN(2437, 1),
1900 FREQ2FBIN(2472, 1)
1902 .calTarget_freqbin_2GHT20 = {
1903 FREQ2FBIN(2412, 1),
1904 FREQ2FBIN(2437, 1),
1905 FREQ2FBIN(2472, 1)
1907 .calTarget_freqbin_2GHT40 = {
1908 FREQ2FBIN(2412, 1),
1909 FREQ2FBIN(2437, 1),
1910 FREQ2FBIN(2472, 1)
1912 .calTargetPowerCck = {
1913 /* 1L-5L,5S,11L,11s */
1914 { {38, 38, 38, 38} },
1915 { {38, 38, 38, 38} },
1917 .calTargetPower2G = {
1918 /* 6-24,36,48,54 */
1919 { {38, 38, 36, 34} },
1920 { {38, 38, 36, 34} },
1921 { {38, 38, 34, 32} },
1923 .calTargetPower2GHT20 = {
1924 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1925 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1926 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1928 .calTargetPower2GHT40 = {
1929 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1930 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1931 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1933 .ctlIndex_2G = {
1934 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1935 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1937 .ctl_freqbin_2G = {
1939 FREQ2FBIN(2412, 1),
1940 FREQ2FBIN(2417, 1),
1941 FREQ2FBIN(2457, 1),
1942 FREQ2FBIN(2462, 1)
1945 FREQ2FBIN(2412, 1),
1946 FREQ2FBIN(2417, 1),
1947 FREQ2FBIN(2462, 1),
1948 0xFF,
1952 FREQ2FBIN(2412, 1),
1953 FREQ2FBIN(2417, 1),
1954 FREQ2FBIN(2462, 1),
1955 0xFF,
1958 FREQ2FBIN(2422, 1),
1959 FREQ2FBIN(2427, 1),
1960 FREQ2FBIN(2447, 1),
1961 FREQ2FBIN(2452, 1)
1965 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1966 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1967 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1968 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1972 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1973 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1974 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1979 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1980 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1981 FREQ2FBIN(2472, 1),
1986 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
1987 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
1988 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
1989 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
1993 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1994 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1995 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1999 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2000 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2001 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2006 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2007 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2008 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2013 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2014 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2015 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2016 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2019 .ctlPowerData_2G = {
2020 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2021 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2022 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2024 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2025 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2026 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2028 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2029 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2030 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2032 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2033 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2034 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2036 .modalHeader5G = {
2037 /* 4 idle,t1,t2,b (4 bits per setting) */
2038 .antCtrlCommon = LE32(0x110),
2039 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2040 .antCtrlCommon2 = LE32(0x22222),
2041 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2042 .antCtrlChain = {
2043 LE16(0x0), LE16(0x0), LE16(0x0),
2045 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2046 .xatten1DB = {0x13, 0x19, 0x17},
2049 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2050 * for merlin (0xa20c/b20c 16:12
2052 .xatten1Margin = {0x19, 0x19, 0x19},
2053 .tempSlope = 70,
2054 .voltSlope = 15,
2055 /* spurChans spur channels in usual fbin coding format */
2056 .spurChans = {0, 0, 0, 0, 0},
2057 /* noiseFloorThreshch check if the register is per chain */
2058 .noiseFloorThreshCh = {-1, 0, 0},
2059 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2060 .quick_drop = 0,
2061 .xpaBiasLvl = 0,
2062 .txFrameToDataStart = 0x0e,
2063 .txFrameToPaOn = 0x0e,
2064 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2065 .antennaGain = 0,
2066 .switchSettling = 0x2d,
2067 .adcDesiredSize = -30,
2068 .txEndToXpaOff = 0,
2069 .txEndToRxOn = 0x2,
2070 .txFrameToXpaOn = 0xe,
2071 .thresh62 = 28,
2072 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2073 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2074 .switchcomspdt = 0,
2075 .xlna_bias_strength = 0,
2076 .futureModal = {
2077 0, 0, 0, 0, 0, 0, 0,
2080 .base_ext2 = {
2081 .tempSlopeLow = 72,
2082 .tempSlopeHigh = 105,
2083 .xatten1DBLow = {0x10, 0x14, 0x10},
2084 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2085 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2086 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2088 .calFreqPier5G = {
2089 FREQ2FBIN(5180, 0),
2090 FREQ2FBIN(5220, 0),
2091 FREQ2FBIN(5320, 0),
2092 FREQ2FBIN(5400, 0),
2093 FREQ2FBIN(5500, 0),
2094 FREQ2FBIN(5600, 0),
2095 FREQ2FBIN(5700, 0),
2096 FREQ2FBIN(5785, 0)
2098 .calPierData5G = {
2100 {0, 0, 0, 0, 0},
2101 {0, 0, 0, 0, 0},
2102 {0, 0, 0, 0, 0},
2103 {0, 0, 0, 0, 0},
2104 {0, 0, 0, 0, 0},
2105 {0, 0, 0, 0, 0},
2106 {0, 0, 0, 0, 0},
2107 {0, 0, 0, 0, 0},
2110 {0, 0, 0, 0, 0},
2111 {0, 0, 0, 0, 0},
2112 {0, 0, 0, 0, 0},
2113 {0, 0, 0, 0, 0},
2114 {0, 0, 0, 0, 0},
2115 {0, 0, 0, 0, 0},
2116 {0, 0, 0, 0, 0},
2117 {0, 0, 0, 0, 0},
2120 {0, 0, 0, 0, 0},
2121 {0, 0, 0, 0, 0},
2122 {0, 0, 0, 0, 0},
2123 {0, 0, 0, 0, 0},
2124 {0, 0, 0, 0, 0},
2125 {0, 0, 0, 0, 0},
2126 {0, 0, 0, 0, 0},
2127 {0, 0, 0, 0, 0},
2131 .calTarget_freqbin_5G = {
2132 FREQ2FBIN(5180, 0),
2133 FREQ2FBIN(5220, 0),
2134 FREQ2FBIN(5320, 0),
2135 FREQ2FBIN(5400, 0),
2136 FREQ2FBIN(5500, 0),
2137 FREQ2FBIN(5600, 0),
2138 FREQ2FBIN(5725, 0),
2139 FREQ2FBIN(5825, 0)
2141 .calTarget_freqbin_5GHT20 = {
2142 FREQ2FBIN(5180, 0),
2143 FREQ2FBIN(5220, 0),
2144 FREQ2FBIN(5320, 0),
2145 FREQ2FBIN(5400, 0),
2146 FREQ2FBIN(5500, 0),
2147 FREQ2FBIN(5600, 0),
2148 FREQ2FBIN(5725, 0),
2149 FREQ2FBIN(5825, 0)
2151 .calTarget_freqbin_5GHT40 = {
2152 FREQ2FBIN(5180, 0),
2153 FREQ2FBIN(5220, 0),
2154 FREQ2FBIN(5320, 0),
2155 FREQ2FBIN(5400, 0),
2156 FREQ2FBIN(5500, 0),
2157 FREQ2FBIN(5600, 0),
2158 FREQ2FBIN(5725, 0),
2159 FREQ2FBIN(5825, 0)
2161 .calTargetPower5G = {
2162 /* 6-24,36,48,54 */
2163 { {32, 32, 28, 26} },
2164 { {32, 32, 28, 26} },
2165 { {32, 32, 28, 26} },
2166 { {32, 32, 26, 24} },
2167 { {32, 32, 26, 24} },
2168 { {32, 32, 24, 22} },
2169 { {30, 30, 24, 22} },
2170 { {30, 30, 24, 22} },
2172 .calTargetPower5GHT20 = {
2174 * 0_8_16,1-3_9-11_17-19,
2175 * 4,5,6,7,12,13,14,15,20,21,22,23
2177 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2178 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2179 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2180 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2181 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2182 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2183 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2184 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2186 .calTargetPower5GHT40 = {
2188 * 0_8_16,1-3_9-11_17-19,
2189 * 4,5,6,7,12,13,14,15,20,21,22,23
2191 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2192 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2193 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2194 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2195 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2196 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2197 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2198 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2200 .ctlIndex_5G = {
2201 0x10, 0x16, 0x18, 0x40, 0x46,
2202 0x48, 0x30, 0x36, 0x38
2204 .ctl_freqbin_5G = {
2206 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2207 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2208 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2209 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2210 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2211 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2212 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2213 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2216 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2217 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2218 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2219 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2220 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2221 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2222 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2223 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2227 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2228 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2229 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2230 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2231 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2232 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2233 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2234 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2238 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2239 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2240 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2241 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2242 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2243 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2244 /* Data[3].ctledges[6].bchannel */ 0xFF,
2245 /* Data[3].ctledges[7].bchannel */ 0xFF,
2249 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2250 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2251 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2252 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2253 /* Data[4].ctledges[4].bchannel */ 0xFF,
2254 /* Data[4].ctledges[5].bchannel */ 0xFF,
2255 /* Data[4].ctledges[6].bchannel */ 0xFF,
2256 /* Data[4].ctledges[7].bchannel */ 0xFF,
2260 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2261 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2262 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2263 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2264 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2265 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2266 /* Data[5].ctledges[6].bchannel */ 0xFF,
2267 /* Data[5].ctledges[7].bchannel */ 0xFF
2271 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2272 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2273 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2274 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2275 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2276 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2277 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2278 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2282 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2283 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2284 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2285 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2286 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2287 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2288 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2289 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2293 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2294 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2295 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2296 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2297 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2298 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2299 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2300 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2303 .ctlPowerData_5G = {
2306 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2307 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2312 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2313 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2318 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2319 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2324 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2325 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2330 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2331 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2336 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2337 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2342 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2343 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2348 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2349 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2354 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2355 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2361 static const struct ar9300_eeprom ar9300_h116 = {
2362 .eepromVersion = 2,
2363 .templateVersion = 4,
2364 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2365 .custData = {"h116-041-f0000"},
2366 .baseEepHeader = {
2367 .regDmn = { LE16(0), LE16(0x1f) },
2368 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2369 .opCapFlags = {
2370 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2371 .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
2373 .rfSilent = 0,
2374 .blueToothOptions = 0,
2375 .deviceCap = 0,
2376 .deviceType = 5, /* takes lower byte in eeprom location */
2377 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2378 .params_for_tuning_caps = {0, 0},
2379 .featureEnable = 0x0d,
2381 * bit0 - enable tx temp comp - disabled
2382 * bit1 - enable tx volt comp - disabled
2383 * bit2 - enable fastClock - enabled
2384 * bit3 - enable doubling - enabled
2385 * bit4 - enable internal regulator - disabled
2386 * bit5 - enable pa predistortion - disabled
2388 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2389 .eepromWriteEnableGpio = 6,
2390 .wlanDisableGpio = 0,
2391 .wlanLedGpio = 8,
2392 .rxBandSelectGpio = 0xff,
2393 .txrxgain = 0x10,
2394 .swreg = 0,
2396 .modalHeader2G = {
2397 /* ar9300_modal_eep_header 2g */
2398 /* 4 idle,t1,t2,b(4 bits per setting) */
2399 .antCtrlCommon = LE32(0x110),
2400 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2401 .antCtrlCommon2 = LE32(0x44444),
2404 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2405 * rx1, rx12, b (2 bits each)
2407 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2410 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2411 * for ar9280 (0xa20c/b20c 5:0)
2413 .xatten1DB = {0x1f, 0x1f, 0x1f},
2416 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2417 * for ar9280 (0xa20c/b20c 16:12
2419 .xatten1Margin = {0x12, 0x12, 0x12},
2420 .tempSlope = 25,
2421 .voltSlope = 0,
2424 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2425 * channels in usual fbin coding format
2427 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2430 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2431 * if the register is per chain
2433 .noiseFloorThreshCh = {-1, 0, 0},
2434 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2435 .quick_drop = 0,
2436 .xpaBiasLvl = 0,
2437 .txFrameToDataStart = 0x0e,
2438 .txFrameToPaOn = 0x0e,
2439 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2440 .antennaGain = 0,
2441 .switchSettling = 0x2c,
2442 .adcDesiredSize = -30,
2443 .txEndToXpaOff = 0,
2444 .txEndToRxOn = 0x2,
2445 .txFrameToXpaOn = 0xe,
2446 .thresh62 = 28,
2447 .papdRateMaskHt20 = LE32(0x0c80C080),
2448 .papdRateMaskHt40 = LE32(0x0080C080),
2449 .switchcomspdt = 0,
2450 .xlna_bias_strength = 0,
2451 .futureModal = {
2452 0, 0, 0, 0, 0, 0, 0,
2455 .base_ext1 = {
2456 .ant_div_control = 0,
2457 .future = {0, 0},
2458 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
2460 .calFreqPier2G = {
2461 FREQ2FBIN(2412, 1),
2462 FREQ2FBIN(2437, 1),
2463 FREQ2FBIN(2462, 1),
2465 /* ar9300_cal_data_per_freq_op_loop 2g */
2466 .calPierData2G = {
2467 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2468 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2469 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2471 .calTarget_freqbin_Cck = {
2472 FREQ2FBIN(2412, 1),
2473 FREQ2FBIN(2472, 1),
2475 .calTarget_freqbin_2G = {
2476 FREQ2FBIN(2412, 1),
2477 FREQ2FBIN(2437, 1),
2478 FREQ2FBIN(2472, 1)
2480 .calTarget_freqbin_2GHT20 = {
2481 FREQ2FBIN(2412, 1),
2482 FREQ2FBIN(2437, 1),
2483 FREQ2FBIN(2472, 1)
2485 .calTarget_freqbin_2GHT40 = {
2486 FREQ2FBIN(2412, 1),
2487 FREQ2FBIN(2437, 1),
2488 FREQ2FBIN(2472, 1)
2490 .calTargetPowerCck = {
2491 /* 1L-5L,5S,11L,11S */
2492 { {34, 34, 34, 34} },
2493 { {34, 34, 34, 34} },
2495 .calTargetPower2G = {
2496 /* 6-24,36,48,54 */
2497 { {34, 34, 32, 32} },
2498 { {34, 34, 32, 32} },
2499 { {34, 34, 32, 32} },
2501 .calTargetPower2GHT20 = {
2502 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2503 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2504 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2506 .calTargetPower2GHT40 = {
2507 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2508 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2509 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2511 .ctlIndex_2G = {
2512 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2513 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2515 .ctl_freqbin_2G = {
2517 FREQ2FBIN(2412, 1),
2518 FREQ2FBIN(2417, 1),
2519 FREQ2FBIN(2457, 1),
2520 FREQ2FBIN(2462, 1)
2523 FREQ2FBIN(2412, 1),
2524 FREQ2FBIN(2417, 1),
2525 FREQ2FBIN(2462, 1),
2526 0xFF,
2530 FREQ2FBIN(2412, 1),
2531 FREQ2FBIN(2417, 1),
2532 FREQ2FBIN(2462, 1),
2533 0xFF,
2536 FREQ2FBIN(2422, 1),
2537 FREQ2FBIN(2427, 1),
2538 FREQ2FBIN(2447, 1),
2539 FREQ2FBIN(2452, 1)
2543 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2544 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2545 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2546 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2550 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2551 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2552 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2557 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2558 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2559 FREQ2FBIN(2472, 1),
2564 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2565 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2566 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2567 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2571 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2572 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2573 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2577 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2578 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2579 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2584 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2585 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2586 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2591 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2592 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2593 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2594 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2597 .ctlPowerData_2G = {
2598 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2599 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2600 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2602 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2603 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2604 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2606 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2607 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2608 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2610 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2611 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2612 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2614 .modalHeader5G = {
2615 /* 4 idle,t1,t2,b (4 bits per setting) */
2616 .antCtrlCommon = LE32(0x220),
2617 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2618 .antCtrlCommon2 = LE32(0x44444),
2619 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2620 .antCtrlChain = {
2621 LE16(0x150), LE16(0x150), LE16(0x150),
2623 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2624 .xatten1DB = {0x19, 0x19, 0x19},
2627 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2628 * for merlin (0xa20c/b20c 16:12
2630 .xatten1Margin = {0x14, 0x14, 0x14},
2631 .tempSlope = 70,
2632 .voltSlope = 0,
2633 /* spurChans spur channels in usual fbin coding format */
2634 .spurChans = {0, 0, 0, 0, 0},
2635 /* noiseFloorThreshCh Check if the register is per chain */
2636 .noiseFloorThreshCh = {-1, 0, 0},
2637 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2638 .quick_drop = 0,
2639 .xpaBiasLvl = 0,
2640 .txFrameToDataStart = 0x0e,
2641 .txFrameToPaOn = 0x0e,
2642 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2643 .antennaGain = 0,
2644 .switchSettling = 0x2d,
2645 .adcDesiredSize = -30,
2646 .txEndToXpaOff = 0,
2647 .txEndToRxOn = 0x2,
2648 .txFrameToXpaOn = 0xe,
2649 .thresh62 = 28,
2650 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2651 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2652 .switchcomspdt = 0,
2653 .xlna_bias_strength = 0,
2654 .futureModal = {
2655 0, 0, 0, 0, 0, 0, 0,
2658 .base_ext2 = {
2659 .tempSlopeLow = 35,
2660 .tempSlopeHigh = 50,
2661 .xatten1DBLow = {0, 0, 0},
2662 .xatten1MarginLow = {0, 0, 0},
2663 .xatten1DBHigh = {0, 0, 0},
2664 .xatten1MarginHigh = {0, 0, 0}
2666 .calFreqPier5G = {
2667 FREQ2FBIN(5160, 0),
2668 FREQ2FBIN(5220, 0),
2669 FREQ2FBIN(5320, 0),
2670 FREQ2FBIN(5400, 0),
2671 FREQ2FBIN(5500, 0),
2672 FREQ2FBIN(5600, 0),
2673 FREQ2FBIN(5700, 0),
2674 FREQ2FBIN(5785, 0)
2676 .calPierData5G = {
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},
2685 {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},
2695 {0, 0, 0, 0, 0},
2698 {0, 0, 0, 0, 0},
2699 {0, 0, 0, 0, 0},
2700 {0, 0, 0, 0, 0},
2701 {0, 0, 0, 0, 0},
2702 {0, 0, 0, 0, 0},
2703 {0, 0, 0, 0, 0},
2704 {0, 0, 0, 0, 0},
2705 {0, 0, 0, 0, 0},
2709 .calTarget_freqbin_5G = {
2710 FREQ2FBIN(5180, 0),
2711 FREQ2FBIN(5240, 0),
2712 FREQ2FBIN(5320, 0),
2713 FREQ2FBIN(5400, 0),
2714 FREQ2FBIN(5500, 0),
2715 FREQ2FBIN(5600, 0),
2716 FREQ2FBIN(5700, 0),
2717 FREQ2FBIN(5825, 0)
2719 .calTarget_freqbin_5GHT20 = {
2720 FREQ2FBIN(5180, 0),
2721 FREQ2FBIN(5240, 0),
2722 FREQ2FBIN(5320, 0),
2723 FREQ2FBIN(5400, 0),
2724 FREQ2FBIN(5500, 0),
2725 FREQ2FBIN(5700, 0),
2726 FREQ2FBIN(5745, 0),
2727 FREQ2FBIN(5825, 0)
2729 .calTarget_freqbin_5GHT40 = {
2730 FREQ2FBIN(5180, 0),
2731 FREQ2FBIN(5240, 0),
2732 FREQ2FBIN(5320, 0),
2733 FREQ2FBIN(5400, 0),
2734 FREQ2FBIN(5500, 0),
2735 FREQ2FBIN(5700, 0),
2736 FREQ2FBIN(5745, 0),
2737 FREQ2FBIN(5825, 0)
2739 .calTargetPower5G = {
2740 /* 6-24,36,48,54 */
2741 { {30, 30, 28, 24} },
2742 { {30, 30, 28, 24} },
2743 { {30, 30, 28, 24} },
2744 { {30, 30, 28, 24} },
2745 { {30, 30, 28, 24} },
2746 { {30, 30, 28, 24} },
2747 { {30, 30, 28, 24} },
2748 { {30, 30, 28, 24} },
2750 .calTargetPower5GHT20 = {
2752 * 0_8_16,1-3_9-11_17-19,
2753 * 4,5,6,7,12,13,14,15,20,21,22,23
2755 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2756 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2757 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2758 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2759 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2760 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2761 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2762 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2764 .calTargetPower5GHT40 = {
2766 * 0_8_16,1-3_9-11_17-19,
2767 * 4,5,6,7,12,13,14,15,20,21,22,23
2769 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2770 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2771 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2772 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2773 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2774 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2775 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2776 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2778 .ctlIndex_5G = {
2779 0x10, 0x16, 0x18, 0x40, 0x46,
2780 0x48, 0x30, 0x36, 0x38
2782 .ctl_freqbin_5G = {
2784 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2785 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2786 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2787 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2788 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2789 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2790 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2791 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2794 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2795 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2796 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2797 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2798 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2799 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2800 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2801 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2805 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2806 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2807 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2808 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2809 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2810 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2811 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2812 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2816 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2817 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2818 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2819 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2820 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2821 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2822 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2823 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2827 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2828 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2829 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2830 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2831 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2832 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2833 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2834 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2838 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2839 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2840 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2841 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2842 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2843 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2844 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2845 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2849 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2850 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2851 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2852 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2853 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2854 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2855 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2856 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2860 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2861 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2862 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2863 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2864 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2865 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2866 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2867 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2871 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2872 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2873 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2874 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2875 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2876 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2877 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2878 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2881 .ctlPowerData_5G = {
2884 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2885 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2890 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2891 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2896 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2897 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2902 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2903 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2908 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2909 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2914 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2915 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2920 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2921 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2926 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2927 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2932 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2933 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2940 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2941 &ar9300_default,
2942 &ar9300_x112,
2943 &ar9300_h116,
2944 &ar9300_h112,
2945 &ar9300_x113,
2948 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2950 int it;
2952 for (it = 0; it < ARRAY_SIZE(ar9300_eep_templates); it++)
2953 if (ar9300_eep_templates[it]->templateVersion == id)
2954 return ar9300_eep_templates[it];
2955 return NULL;
2958 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2960 return 0;
2963 static int interpolate(int x, int xa, int xb, int ya, int yb)
2965 int bf, factor, plus;
2967 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2968 factor = bf / 2;
2969 plus = bf % 2;
2970 return ya + factor + plus;
2973 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2974 enum eeprom_param param)
2976 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2977 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
2979 switch (param) {
2980 case EEP_MAC_LSW:
2981 return get_unaligned_be16(eep->macAddr);
2982 case EEP_MAC_MID:
2983 return get_unaligned_be16(eep->macAddr + 2);
2984 case EEP_MAC_MSW:
2985 return get_unaligned_be16(eep->macAddr + 4);
2986 case EEP_REG_0:
2987 return le16_to_cpu(pBase->regDmn[0]);
2988 case EEP_OP_CAP:
2989 return pBase->deviceCap;
2990 case EEP_OP_MODE:
2991 return pBase->opCapFlags.opFlags;
2992 case EEP_RF_SILENT:
2993 return pBase->rfSilent;
2994 case EEP_TX_MASK:
2995 return (pBase->txrxMask >> 4) & 0xf;
2996 case EEP_RX_MASK:
2997 return pBase->txrxMask & 0xf;
2998 case EEP_PAPRD:
2999 return !!(pBase->featureEnable & BIT(5));
3000 case EEP_CHAIN_MASK_REDUCE:
3001 return (pBase->miscConfiguration >> 0x3) & 0x1;
3002 case EEP_ANT_DIV_CTL1:
3003 if (AR_SREV_9565(ah))
3004 return AR9300_EEP_ANTDIV_CONTROL_DEFAULT_VALUE;
3005 else
3006 return eep->base_ext1.ant_div_control;
3007 case EEP_ANTENNA_GAIN_5G:
3008 return eep->modalHeader5G.antennaGain;
3009 case EEP_ANTENNA_GAIN_2G:
3010 return eep->modalHeader2G.antennaGain;
3011 default:
3012 return 0;
3016 static bool ar9300_eeprom_read_byte(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 = (val >> (8 * (address % 2))) & 0xff;
3025 return true;
3028 static bool ar9300_eeprom_read_word(struct ath_hw *ah, int address,
3029 u8 *buffer)
3031 u16 val;
3033 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3034 return false;
3036 buffer[0] = val >> 8;
3037 buffer[1] = val & 0xff;
3039 return true;
3042 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3043 int count)
3045 struct ath_common *common = ath9k_hw_common(ah);
3046 int i;
3048 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3049 ath_dbg(common, EEPROM, "eeprom address not in range\n");
3050 return false;
3054 * Since we're reading the bytes in reverse order from a little-endian
3055 * word stream, an even address means we only use the lower half of
3056 * the 16-bit word at that address
3058 if (address % 2 == 0) {
3059 if (!ar9300_eeprom_read_byte(ah, address--, buffer++))
3060 goto error;
3062 count--;
3065 for (i = 0; i < count / 2; i++) {
3066 if (!ar9300_eeprom_read_word(ah, address, buffer))
3067 goto error;
3069 address -= 2;
3070 buffer += 2;
3073 if (count % 2)
3074 if (!ar9300_eeprom_read_byte(ah, address, buffer))
3075 goto error;
3077 return true;
3079 error:
3080 ath_dbg(common, EEPROM, "unable to read eeprom region at offset %d\n",
3081 address);
3082 return false;
3085 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3087 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3089 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3090 AR9300_OTP_STATUS_VALID, 1000))
3091 return false;
3093 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3094 return true;
3097 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3098 int count)
3100 u32 data;
3101 int i;
3103 for (i = 0; i < count; i++) {
3104 int offset = 8 * ((address - i) % 4);
3105 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3106 return false;
3108 buffer[i] = (data >> offset) & 0xff;
3111 return true;
3115 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3116 int *length, int *major, int *minor)
3118 unsigned long value[4];
3120 value[0] = best[0];
3121 value[1] = best[1];
3122 value[2] = best[2];
3123 value[3] = best[3];
3124 *code = ((value[0] >> 5) & 0x0007);
3125 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3126 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3127 *major = (value[2] & 0x000f);
3128 *minor = (value[3] & 0x00ff);
3131 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3133 int it, checksum = 0;
3135 for (it = 0; it < dsize; it++) {
3136 checksum += data[it];
3137 checksum &= 0xffff;
3140 return checksum;
3143 static bool ar9300_uncompress_block(struct ath_hw *ah,
3144 u8 *mptr,
3145 int mdataSize,
3146 u8 *block,
3147 int size)
3149 int it;
3150 int spot;
3151 int offset;
3152 int length;
3153 struct ath_common *common = ath9k_hw_common(ah);
3155 spot = 0;
3157 for (it = 0; it < size; it += (length+2)) {
3158 offset = block[it];
3159 offset &= 0xff;
3160 spot += offset;
3161 length = block[it+1];
3162 length &= 0xff;
3164 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3165 ath_dbg(common, EEPROM,
3166 "Restore at %d: spot=%d offset=%d length=%d\n",
3167 it, spot, offset, length);
3168 memcpy(&mptr[spot], &block[it+2], length);
3169 spot += length;
3170 } else if (length > 0) {
3171 ath_dbg(common, EEPROM,
3172 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3173 it, spot, offset, length);
3174 return false;
3177 return true;
3180 static int ar9300_compress_decision(struct ath_hw *ah,
3181 int it,
3182 int code,
3183 int reference,
3184 u8 *mptr,
3185 u8 *word, int length, int mdata_size)
3187 struct ath_common *common = ath9k_hw_common(ah);
3188 const struct ar9300_eeprom *eep = NULL;
3190 switch (code) {
3191 case _CompressNone:
3192 if (length != mdata_size) {
3193 ath_dbg(common, EEPROM,
3194 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3195 mdata_size, length);
3196 return -1;
3198 memcpy(mptr, word + COMP_HDR_LEN, length);
3199 ath_dbg(common, EEPROM,
3200 "restored eeprom %d: uncompressed, length %d\n",
3201 it, length);
3202 break;
3203 case _CompressBlock:
3204 if (reference != 0) {
3205 eep = ar9003_eeprom_struct_find_by_id(reference);
3206 if (eep == NULL) {
3207 ath_dbg(common, EEPROM,
3208 "can't find reference eeprom struct %d\n",
3209 reference);
3210 return -1;
3212 memcpy(mptr, eep, mdata_size);
3214 ath_dbg(common, EEPROM,
3215 "restore eeprom %d: block, reference %d, length %d\n",
3216 it, reference, length);
3217 ar9300_uncompress_block(ah, mptr, mdata_size,
3218 (word + COMP_HDR_LEN), length);
3219 break;
3220 default:
3221 ath_dbg(common, EEPROM, "unknown compression code %d\n", code);
3222 return -1;
3224 return 0;
3227 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3228 int count);
3230 static bool ar9300_check_header(void *data)
3232 u32 *word = data;
3233 return !(*word == 0 || *word == ~0);
3236 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3237 int base_addr)
3239 u8 header[4];
3241 if (!read(ah, base_addr, header, 4))
3242 return false;
3244 return ar9300_check_header(header);
3247 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3248 int mdata_size)
3250 u16 *data = (u16 *) mptr;
3251 int i;
3253 for (i = 0; i < mdata_size / 2; i++, data++)
3254 if (!ath9k_hw_nvram_read(ah, i, data))
3255 return -EIO;
3257 return 0;
3260 * Read the configuration data from the eeprom.
3261 * The data can be put in any specified memory buffer.
3263 * Returns -1 on error.
3264 * Returns address of next memory location on success.
3266 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3267 u8 *mptr, int mdata_size)
3269 #define MDEFAULT 15
3270 #define MSTATE 100
3271 int cptr;
3272 u8 *word;
3273 int code;
3274 int reference, length, major, minor;
3275 int osize;
3276 int it;
3277 u16 checksum, mchecksum;
3278 struct ath_common *common = ath9k_hw_common(ah);
3279 struct ar9300_eeprom *eep;
3280 eeprom_read_op read;
3282 if (ath9k_hw_use_flash(ah)) {
3283 u8 txrx;
3285 if (ar9300_eeprom_restore_flash(ah, mptr, mdata_size))
3286 return -EIO;
3288 /* check if eeprom contains valid data */
3289 eep = (struct ar9300_eeprom *) mptr;
3290 txrx = eep->baseEepHeader.txrxMask;
3291 if (txrx != 0 && txrx != 0xff)
3292 return 0;
3295 word = kzalloc(2048, GFP_KERNEL);
3296 if (!word)
3297 return -ENOMEM;
3299 memcpy(mptr, &ar9300_default, mdata_size);
3301 read = ar9300_read_eeprom;
3302 if (AR_SREV_9485(ah))
3303 cptr = AR9300_BASE_ADDR_4K;
3304 else if (AR_SREV_9330(ah))
3305 cptr = AR9300_BASE_ADDR_512;
3306 else
3307 cptr = AR9300_BASE_ADDR;
3308 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3309 cptr);
3310 if (ar9300_check_eeprom_header(ah, read, cptr))
3311 goto found;
3313 cptr = AR9300_BASE_ADDR_4K;
3314 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3315 cptr);
3316 if (ar9300_check_eeprom_header(ah, read, cptr))
3317 goto found;
3319 cptr = AR9300_BASE_ADDR_512;
3320 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3321 cptr);
3322 if (ar9300_check_eeprom_header(ah, read, cptr))
3323 goto found;
3325 read = ar9300_read_otp;
3326 cptr = AR9300_BASE_ADDR;
3327 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3328 if (ar9300_check_eeprom_header(ah, read, cptr))
3329 goto found;
3331 cptr = AR9300_BASE_ADDR_512;
3332 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3333 if (ar9300_check_eeprom_header(ah, read, cptr))
3334 goto found;
3336 goto fail;
3338 found:
3339 ath_dbg(common, EEPROM, "Found valid EEPROM data\n");
3341 for (it = 0; it < MSTATE; it++) {
3342 if (!read(ah, cptr, word, COMP_HDR_LEN))
3343 goto fail;
3345 if (!ar9300_check_header(word))
3346 break;
3348 ar9300_comp_hdr_unpack(word, &code, &reference,
3349 &length, &major, &minor);
3350 ath_dbg(common, EEPROM,
3351 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3352 cptr, code, reference, length, major, minor);
3353 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3354 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3355 ath_dbg(common, EEPROM, "Skipping bad header\n");
3356 cptr -= COMP_HDR_LEN;
3357 continue;
3360 osize = length;
3361 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3362 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3363 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3364 ath_dbg(common, EEPROM, "checksum %x %x\n",
3365 checksum, mchecksum);
3366 if (checksum == mchecksum) {
3367 ar9300_compress_decision(ah, it, code, reference, mptr,
3368 word, length, mdata_size);
3369 } else {
3370 ath_dbg(common, EEPROM,
3371 "skipping block with bad checksum\n");
3373 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3376 kfree(word);
3377 return cptr;
3379 fail:
3380 kfree(word);
3381 return -1;
3385 * Restore the configuration structure by reading the eeprom.
3386 * This function destroys any existing in-memory structure
3387 * content.
3389 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3391 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3393 if (ar9300_eeprom_restore_internal(ah, mptr,
3394 sizeof(struct ar9300_eeprom)) < 0)
3395 return false;
3397 return true;
3400 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3401 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3402 struct ar9300_modal_eep_header *modal_hdr)
3404 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3405 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3406 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3407 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3408 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3409 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3410 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3411 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3412 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3413 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3414 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3415 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3416 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3417 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3418 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3419 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3420 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3421 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3422 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3423 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3424 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3425 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3426 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3427 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3428 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3429 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3430 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3431 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3432 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3433 PR_EEP("txClip", modal_hdr->txClip);
3434 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3436 return len;
3439 static u32 ar9003_dump_cal_data(struct ath_hw *ah, char *buf, u32 len, u32 size,
3440 bool is_2g)
3442 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3443 struct ar9300_base_eep_hdr *pBase;
3444 struct ar9300_cal_data_per_freq_op_loop *cal_pier;
3445 int cal_pier_nr;
3446 int freq;
3447 int i, j;
3449 pBase = &eep->baseEepHeader;
3451 if (is_2g)
3452 cal_pier_nr = AR9300_NUM_2G_CAL_PIERS;
3453 else
3454 cal_pier_nr = AR9300_NUM_5G_CAL_PIERS;
3456 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
3457 if (!((pBase->txrxMask >> i) & 1))
3458 continue;
3460 len += scnprintf(buf + len, size - len, "Chain %d\n", i);
3462 len += scnprintf(buf + len, size - len,
3463 "Freq\t ref\tvolt\ttemp\tnf_cal\tnf_pow\trx_temp\n");
3465 for (j = 0; j < cal_pier_nr; j++) {
3466 if (is_2g) {
3467 cal_pier = &eep->calPierData2G[i][j];
3468 freq = 2300 + eep->calFreqPier2G[j];
3469 } else {
3470 cal_pier = &eep->calPierData5G[i][j];
3471 freq = 4800 + eep->calFreqPier5G[j] * 5;
3474 len += scnprintf(buf + len, size - len,
3475 "%d\t", freq);
3477 len += scnprintf(buf + len, size - len,
3478 "%d\t%d\t%d\t%d\t%d\t%d\n",
3479 cal_pier->refPower,
3480 cal_pier->voltMeas,
3481 cal_pier->tempMeas,
3482 cal_pier->rxTempMeas ?
3483 N2DBM(cal_pier->rxNoisefloorCal) : 0,
3484 cal_pier->rxTempMeas ?
3485 N2DBM(cal_pier->rxNoisefloorPower) : 0,
3486 cal_pier->rxTempMeas);
3490 return len;
3493 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3494 u8 *buf, u32 len, u32 size)
3496 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3497 struct ar9300_base_eep_hdr *pBase;
3499 if (!dump_base_hdr) {
3500 len += scnprintf(buf + len, size - len,
3501 "%20s :\n", "2GHz modal Header");
3502 len = ar9003_dump_modal_eeprom(buf, len, size,
3503 &eep->modalHeader2G);
3505 len += scnprintf(buf + len, size - len, "Calibration data\n");
3506 len = ar9003_dump_cal_data(ah, buf, len, size, true);
3508 len += scnprintf(buf + len, size - len,
3509 "%20s :\n", "5GHz modal Header");
3510 len = ar9003_dump_modal_eeprom(buf, len, size,
3511 &eep->modalHeader5G);
3513 len += scnprintf(buf + len, size - len, "Calibration data\n");
3514 len = ar9003_dump_cal_data(ah, buf, len, size, false);
3516 goto out;
3519 pBase = &eep->baseEepHeader;
3521 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3522 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3523 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3524 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3525 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3526 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3527 AR5416_OPFLAGS_11A));
3528 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3529 AR5416_OPFLAGS_11G));
3530 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3531 AR5416_OPFLAGS_N_2G_HT20));
3532 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3533 AR5416_OPFLAGS_N_2G_HT40));
3534 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3535 AR5416_OPFLAGS_N_5G_HT20));
3536 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3537 AR5416_OPFLAGS_N_5G_HT40));
3538 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc &
3539 AR5416_EEPMISC_BIG_ENDIAN));
3540 PR_EEP("RF Silent", pBase->rfSilent);
3541 PR_EEP("BT option", pBase->blueToothOptions);
3542 PR_EEP("Device Cap", pBase->deviceCap);
3543 PR_EEP("Device Type", pBase->deviceType);
3544 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3545 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3546 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3547 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3548 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3549 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3550 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3551 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3552 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3553 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3554 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3555 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3556 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3557 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3558 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3559 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3560 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3561 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3562 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3564 len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3565 ah->eeprom.ar9300_eep.macAddr);
3566 out:
3567 if (len > size)
3568 len = size;
3570 return len;
3572 #else
3573 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3574 u8 *buf, u32 len, u32 size)
3576 return 0;
3578 #endif
3580 /* XXX: review hardware docs */
3581 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3583 return ah->eeprom.ar9300_eep.eepromVersion;
3586 /* XXX: could be read from the eepromVersion, not sure yet */
3587 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3589 return 0;
3592 static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
3593 bool is2ghz)
3595 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3597 if (is2ghz)
3598 return &eep->modalHeader2G;
3599 else
3600 return &eep->modalHeader5G;
3603 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3605 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3607 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
3608 AR_SREV_9531(ah) || AR_SREV_9561(ah))
3609 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3610 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
3611 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3612 else {
3613 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3614 REG_RMW_FIELD(ah, AR_CH0_THERM,
3615 AR_CH0_THERM_XPABIASLVL_MSB,
3616 bias >> 2);
3617 REG_RMW_FIELD(ah, AR_CH0_THERM,
3618 AR_CH0_THERM_XPASHORT2GND, 1);
3622 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3624 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3627 u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3629 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3632 u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3634 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3637 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3638 bool is2ghz)
3640 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3641 return le16_to_cpu(val);
3644 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3646 struct ath_common *common = ath9k_hw_common(ah);
3647 struct ath9k_hw_capabilities *pCap = &ah->caps;
3648 int chain;
3649 u32 regval, value, gpio;
3650 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3651 AR_PHY_SWITCH_CHAIN_0,
3652 AR_PHY_SWITCH_CHAIN_1,
3653 AR_PHY_SWITCH_CHAIN_2,
3656 if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0)) {
3657 if (ah->config.xlna_gpio)
3658 gpio = ah->config.xlna_gpio;
3659 else
3660 gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
3662 ath9k_hw_gpio_request_out(ah, gpio, NULL,
3663 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
3666 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3668 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3669 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3670 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3671 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
3672 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3673 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3674 } else
3675 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3676 AR_SWITCH_TABLE_COM_ALL, value);
3680 * AR9462 defines new switch table for BT/WLAN,
3681 * here's new field name in XXX.ref for both 2G and 5G.
3682 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3683 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3684 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3686 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3687 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3689 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3690 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3692 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
3693 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3694 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3695 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3696 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3699 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3700 if (AR_SREV_9485(ah) && common->bt_ant_diversity) {
3701 value &= ~AR_SWITCH_TABLE_COM2_ALL;
3702 value |= ah->config.ant_ctrl_comm2g_switch_enable;
3705 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3707 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3708 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3709 REG_RMW_FIELD(ah, switch_chain_reg[0],
3710 AR_SWITCH_TABLE_ALL, value);
3713 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3714 if ((ah->rxchainmask & BIT(chain)) ||
3715 (ah->txchainmask & BIT(chain))) {
3716 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3717 is2ghz);
3718 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3719 AR_SWITCH_TABLE_ALL, value);
3723 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
3724 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3726 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3727 * are the fields present
3729 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3730 regval &= (~AR_ANT_DIV_CTRL_ALL);
3731 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3732 /* enable_lnadiv */
3733 regval &= (~AR_PHY_ANT_DIV_LNADIV);
3734 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
3736 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3737 regval |= AR_ANT_DIV_ENABLE;
3739 if (AR_SREV_9565(ah)) {
3740 if (common->bt_ant_diversity) {
3741 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S);
3743 REG_SET_BIT(ah, AR_PHY_RESTART,
3744 AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
3746 /* Force WLAN LNA diversity ON */
3747 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
3748 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3749 } else {
3750 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S);
3751 regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S);
3753 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL,
3754 (1 << AR_PHY_ANT_SW_RX_PROT_S));
3756 /* Force WLAN LNA diversity OFF */
3757 REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV,
3758 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3762 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3764 /* enable fast_div */
3765 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3766 regval &= (~AR_FAST_DIV_ENABLE);
3767 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
3769 if ((AR_SREV_9485(ah) || AR_SREV_9565(ah))
3770 && common->bt_ant_diversity)
3771 regval |= AR_FAST_DIV_ENABLE;
3773 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3775 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
3776 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3778 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3779 * main_tb, alt_tb
3781 regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
3782 AR_PHY_ANT_DIV_ALT_LNACONF |
3783 AR_PHY_ANT_DIV_ALT_GAINTB |
3784 AR_PHY_ANT_DIV_MAIN_GAINTB));
3785 /* by default use LNA1 for the main antenna */
3786 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
3787 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
3788 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
3789 AR_PHY_ANT_DIV_ALT_LNACONF_S);
3790 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3795 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3797 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3798 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3799 int drive_strength;
3800 unsigned long reg;
3802 drive_strength = pBase->miscConfiguration & BIT(0);
3803 if (!drive_strength)
3804 return;
3806 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3807 reg &= ~0x00ffffc0;
3808 reg |= 0x5 << 21;
3809 reg |= 0x5 << 18;
3810 reg |= 0x5 << 15;
3811 reg |= 0x5 << 12;
3812 reg |= 0x5 << 9;
3813 reg |= 0x5 << 6;
3814 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3816 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3817 reg &= ~0xffffffe0;
3818 reg |= 0x5 << 29;
3819 reg |= 0x5 << 26;
3820 reg |= 0x5 << 23;
3821 reg |= 0x5 << 20;
3822 reg |= 0x5 << 17;
3823 reg |= 0x5 << 14;
3824 reg |= 0x5 << 11;
3825 reg |= 0x5 << 8;
3826 reg |= 0x5 << 5;
3827 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3829 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3830 reg &= ~0xff800000;
3831 reg |= 0x5 << 29;
3832 reg |= 0x5 << 26;
3833 reg |= 0x5 << 23;
3834 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3837 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3838 struct ath9k_channel *chan)
3840 int f[3], t[3];
3841 u16 value;
3842 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3844 if (chain >= 0 && chain < 3) {
3845 if (IS_CHAN_2GHZ(chan))
3846 return eep->modalHeader2G.xatten1DB[chain];
3847 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3848 t[0] = eep->base_ext2.xatten1DBLow[chain];
3849 f[0] = 5180;
3850 t[1] = eep->modalHeader5G.xatten1DB[chain];
3851 f[1] = 5500;
3852 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3853 f[2] = 5785;
3854 value = ar9003_hw_power_interpolate((s32) chan->channel,
3855 f, t, 3);
3856 return value;
3857 } else
3858 return eep->modalHeader5G.xatten1DB[chain];
3861 return 0;
3865 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3866 struct ath9k_channel *chan)
3868 int f[3], t[3];
3869 u16 value;
3870 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3872 if (chain >= 0 && chain < 3) {
3873 if (IS_CHAN_2GHZ(chan))
3874 return eep->modalHeader2G.xatten1Margin[chain];
3875 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3876 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3877 f[0] = 5180;
3878 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3879 f[1] = 5500;
3880 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3881 f[2] = 5785;
3882 value = ar9003_hw_power_interpolate((s32) chan->channel,
3883 f, t, 3);
3884 return value;
3885 } else
3886 return eep->modalHeader5G.xatten1Margin[chain];
3889 return 0;
3892 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3894 int i;
3895 u16 value;
3896 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3897 AR_PHY_EXT_ATTEN_CTL_1,
3898 AR_PHY_EXT_ATTEN_CTL_2,
3901 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3902 value = ar9003_hw_atten_chain_get(ah, 1, chan);
3903 REG_RMW_FIELD(ah, ext_atten_reg[0],
3904 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3906 value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
3907 REG_RMW_FIELD(ah, ext_atten_reg[0],
3908 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3909 value);
3912 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3913 for (i = 0; i < 3; i++) {
3914 if (ah->txchainmask & BIT(i)) {
3915 value = ar9003_hw_atten_chain_get(ah, i, chan);
3916 REG_RMW_FIELD(ah, ext_atten_reg[i],
3917 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3919 if (AR_SREV_9485(ah) &&
3920 (ar9003_hw_get_rx_gain_idx(ah) == 0) &&
3921 ah->config.xatten_margin_cfg)
3922 value = 5;
3923 else
3924 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3926 if (ah->config.alt_mingainidx)
3927 REG_RMW_FIELD(ah, AR_PHY_EXT_ATTEN_CTL_0,
3928 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3929 value);
3931 REG_RMW_FIELD(ah, ext_atten_reg[i],
3932 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3933 value);
3938 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3940 int timeout = 100;
3942 while (pmu_set != REG_READ(ah, pmu_reg)) {
3943 if (timeout-- == 0)
3944 return false;
3945 REG_WRITE(ah, pmu_reg, pmu_set);
3946 udelay(10);
3949 return true;
3952 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3954 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3955 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3956 u32 reg_val;
3958 if (pBase->featureEnable & BIT(4)) {
3959 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3960 int reg_pmu_set;
3962 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3963 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3964 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3965 return;
3967 if (AR_SREV_9330(ah)) {
3968 if (ah->is_clk_25mhz) {
3969 reg_pmu_set = (3 << 1) | (8 << 4) |
3970 (3 << 8) | (1 << 14) |
3971 (6 << 17) | (1 << 20) |
3972 (3 << 24);
3973 } else {
3974 reg_pmu_set = (4 << 1) | (7 << 4) |
3975 (3 << 8) | (1 << 14) |
3976 (6 << 17) | (1 << 20) |
3977 (3 << 24);
3979 } else {
3980 reg_pmu_set = (5 << 1) | (7 << 4) |
3981 (2 << 8) | (2 << 14) |
3982 (6 << 17) | (1 << 20) |
3983 (3 << 24) | (1 << 28);
3986 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3987 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3988 return;
3990 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3991 | (4 << 26);
3992 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3993 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3994 return;
3996 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3997 | (1 << 21);
3998 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3999 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
4000 return;
4001 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah) ||
4002 AR_SREV_9561(ah)) {
4003 reg_val = le32_to_cpu(pBase->swreg);
4004 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
4006 if (AR_SREV_9561(ah))
4007 REG_WRITE(ah, AR_PHY_PMU2, 0x10200000);
4008 } else {
4009 /* Internal regulator is ON. Write swreg register. */
4010 reg_val = le32_to_cpu(pBase->swreg);
4011 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
4012 REG_READ(ah, AR_RTC_REG_CONTROL1) &
4013 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
4014 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
4015 /* Set REG_CONTROL1.SWREG_PROGRAM */
4016 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
4017 REG_READ(ah,
4018 AR_RTC_REG_CONTROL1) |
4019 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
4021 } else {
4022 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
4023 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
4024 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
4025 AR_PHY_PMU2_PGM))
4026 udelay(10);
4028 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
4029 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
4030 AR_PHY_PMU1_PWD))
4031 udelay(10);
4032 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
4033 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
4034 AR_PHY_PMU2_PGM))
4035 udelay(10);
4036 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
4037 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
4038 else {
4039 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
4040 AR_RTC_FORCE_SWREG_PRD;
4041 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
4047 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
4049 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4050 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
4052 if (AR_SREV_9340(ah) || AR_SREV_9531(ah))
4053 return;
4055 if (eep->baseEepHeader.featureEnable & 0x40) {
4056 tuning_caps_param &= 0x7f;
4057 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
4058 tuning_caps_param);
4059 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
4060 tuning_caps_param);
4064 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
4066 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4067 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4068 int quick_drop;
4069 s32 t[3], f[3] = {5180, 5500, 5785};
4071 if (!(pBase->miscConfiguration & BIT(4)))
4072 return;
4074 if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) {
4075 if (freq < 4000) {
4076 quick_drop = eep->modalHeader2G.quick_drop;
4077 } else {
4078 t[0] = eep->base_ext1.quick_drop_low;
4079 t[1] = eep->modalHeader5G.quick_drop;
4080 t[2] = eep->base_ext1.quick_drop_high;
4081 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
4083 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
4087 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
4089 u32 value;
4091 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
4093 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4094 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
4095 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4096 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
4099 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
4101 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4102 u8 xpa_ctl;
4104 if (!(eep->baseEepHeader.featureEnable & 0x80))
4105 return;
4107 if (!AR_SREV_9300(ah) &&
4108 !AR_SREV_9340(ah) &&
4109 !AR_SREV_9580(ah) &&
4110 !AR_SREV_9531(ah) &&
4111 !AR_SREV_9561(ah))
4112 return;
4114 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
4115 if (is2ghz)
4116 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4117 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
4118 else
4119 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4120 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
4123 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
4125 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4126 u8 bias;
4128 if (!(eep->baseEepHeader.miscConfiguration & 0x40))
4129 return;
4131 if (!AR_SREV_9300(ah))
4132 return;
4134 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
4135 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4136 bias & 0x3);
4137 bias >>= 2;
4138 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4139 bias & 0x3);
4140 bias >>= 2;
4141 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4142 bias & 0x3);
4145 static int ar9003_hw_get_thermometer(struct ath_hw *ah)
4147 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4148 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4149 int thermometer = (pBase->miscConfiguration >> 1) & 0x3;
4151 return --thermometer;
4154 static void ar9003_hw_thermometer_apply(struct ath_hw *ah)
4156 struct ath9k_hw_capabilities *pCap = &ah->caps;
4157 int thermometer = ar9003_hw_get_thermometer(ah);
4158 u8 therm_on = (thermometer < 0) ? 0 : 1;
4160 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4161 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4162 if (pCap->chip_chainmask & BIT(1))
4163 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4164 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4165 if (pCap->chip_chainmask & BIT(2))
4166 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4167 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4169 therm_on = thermometer == 0;
4170 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4171 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4172 if (pCap->chip_chainmask & BIT(1)) {
4173 therm_on = thermometer == 1;
4174 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4175 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4177 if (pCap->chip_chainmask & BIT(2)) {
4178 therm_on = thermometer == 2;
4179 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4180 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4184 static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4186 u32 data = 0, ko, kg;
4188 if (!AR_SREV_9462_20_OR_LATER(ah))
4189 return;
4191 ar9300_otp_read_word(ah, 1, &data);
4192 ko = data & 0xff;
4193 kg = (data >> 8) & 0xff;
4194 if (ko || kg) {
4195 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4196 AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko);
4197 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4198 AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN,
4199 kg + 256);
4203 static void ar9003_hw_apply_minccapwr_thresh(struct ath_hw *ah,
4204 bool is2ghz)
4206 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4207 const u_int32_t cca_ctrl[AR9300_MAX_CHAINS] = {
4208 AR_PHY_CCA_CTRL_0,
4209 AR_PHY_CCA_CTRL_1,
4210 AR_PHY_CCA_CTRL_2,
4212 int chain;
4213 u32 val;
4215 if (is2ghz) {
4216 if (!(eep->base_ext1.misc_enable & BIT(2)))
4217 return;
4218 } else {
4219 if (!(eep->base_ext1.misc_enable & BIT(3)))
4220 return;
4223 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
4224 if (!(ah->caps.tx_chainmask & BIT(chain)))
4225 continue;
4227 val = ar9003_modal_header(ah, is2ghz)->noiseFloorThreshCh[chain];
4228 REG_RMW_FIELD(ah, cca_ctrl[chain],
4229 AR_PHY_EXT_CCA0_THRESH62_1, val);
4234 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4235 struct ath9k_channel *chan)
4237 bool is2ghz = IS_CHAN_2GHZ(chan);
4238 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
4239 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
4240 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
4241 ar9003_hw_drive_strength_apply(ah);
4242 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
4243 ar9003_hw_atten_apply(ah, chan);
4244 ar9003_hw_quick_drop_apply(ah, chan->channel);
4245 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah))
4246 ar9003_hw_internal_regulator_apply(ah);
4247 ar9003_hw_apply_tuning_caps(ah);
4248 ar9003_hw_apply_minccapwr_thresh(ah, is2ghz);
4249 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4250 ar9003_hw_thermometer_apply(ah);
4251 ar9003_hw_thermo_cal_apply(ah);
4254 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
4255 struct ath9k_channel *chan)
4260 * Returns the interpolated y value corresponding to the specified x value
4261 * from the np ordered pairs of data (px,py).
4262 * The pairs do not have to be in any order.
4263 * If the specified x value is less than any of the px,
4264 * the returned y value is equal to the py for the lowest px.
4265 * If the specified x value is greater than any of the px,
4266 * the returned y value is equal to the py for the highest px.
4268 static int ar9003_hw_power_interpolate(int32_t x,
4269 int32_t *px, int32_t *py, u_int16_t np)
4271 int ip = 0;
4272 int lx = 0, ly = 0, lhave = 0;
4273 int hx = 0, hy = 0, hhave = 0;
4274 int dx = 0;
4275 int y = 0;
4277 lhave = 0;
4278 hhave = 0;
4280 /* identify best lower and higher x calibration measurement */
4281 for (ip = 0; ip < np; ip++) {
4282 dx = x - px[ip];
4284 /* this measurement is higher than our desired x */
4285 if (dx <= 0) {
4286 if (!hhave || dx > (x - hx)) {
4287 /* new best higher x measurement */
4288 hx = px[ip];
4289 hy = py[ip];
4290 hhave = 1;
4293 /* this measurement is lower than our desired x */
4294 if (dx >= 0) {
4295 if (!lhave || dx < (x - lx)) {
4296 /* new best lower x measurement */
4297 lx = px[ip];
4298 ly = py[ip];
4299 lhave = 1;
4304 /* the low x is good */
4305 if (lhave) {
4306 /* so is the high x */
4307 if (hhave) {
4308 /* they're the same, so just pick one */
4309 if (hx == lx)
4310 y = ly;
4311 else /* interpolate */
4312 y = interpolate(x, lx, hx, ly, hy);
4313 } else /* only low is good, use it */
4314 y = ly;
4315 } else if (hhave) /* only high is good, use it */
4316 y = hy;
4317 else /* nothing is good,this should never happen unless np=0, ???? */
4318 y = -(1 << 30);
4319 return y;
4322 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4323 u16 rateIndex, u16 freq, bool is2GHz)
4325 u16 numPiers, i;
4326 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4327 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4328 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4329 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4330 u8 *pFreqBin;
4332 if (is2GHz) {
4333 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4334 pEepromTargetPwr = eep->calTargetPower2G;
4335 pFreqBin = eep->calTarget_freqbin_2G;
4336 } else {
4337 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4338 pEepromTargetPwr = eep->calTargetPower5G;
4339 pFreqBin = eep->calTarget_freqbin_5G;
4343 * create array of channels and targetpower from
4344 * targetpower piers stored on eeprom
4346 for (i = 0; i < numPiers; i++) {
4347 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4348 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4351 /* interpolate to get target power for given frequency */
4352 return (u8) ar9003_hw_power_interpolate((s32) freq,
4353 freqArray,
4354 targetPowerArray, numPiers);
4357 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4358 u16 rateIndex,
4359 u16 freq, bool is2GHz)
4361 u16 numPiers, i;
4362 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4363 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4364 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4365 struct cal_tgt_pow_ht *pEepromTargetPwr;
4366 u8 *pFreqBin;
4368 if (is2GHz) {
4369 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4370 pEepromTargetPwr = eep->calTargetPower2GHT20;
4371 pFreqBin = eep->calTarget_freqbin_2GHT20;
4372 } else {
4373 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4374 pEepromTargetPwr = eep->calTargetPower5GHT20;
4375 pFreqBin = eep->calTarget_freqbin_5GHT20;
4379 * create array of channels and targetpower
4380 * from targetpower piers stored on eeprom
4382 for (i = 0; i < numPiers; i++) {
4383 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4384 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4387 /* interpolate to get target power for given frequency */
4388 return (u8) ar9003_hw_power_interpolate((s32) freq,
4389 freqArray,
4390 targetPowerArray, numPiers);
4393 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4394 u16 rateIndex,
4395 u16 freq, bool is2GHz)
4397 u16 numPiers, i;
4398 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4399 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4400 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4401 struct cal_tgt_pow_ht *pEepromTargetPwr;
4402 u8 *pFreqBin;
4404 if (is2GHz) {
4405 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4406 pEepromTargetPwr = eep->calTargetPower2GHT40;
4407 pFreqBin = eep->calTarget_freqbin_2GHT40;
4408 } else {
4409 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4410 pEepromTargetPwr = eep->calTargetPower5GHT40;
4411 pFreqBin = eep->calTarget_freqbin_5GHT40;
4415 * create array of channels and targetpower from
4416 * targetpower piers stored on eeprom
4418 for (i = 0; i < numPiers; i++) {
4419 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4420 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4423 /* interpolate to get target power for given frequency */
4424 return (u8) ar9003_hw_power_interpolate((s32) freq,
4425 freqArray,
4426 targetPowerArray, numPiers);
4429 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4430 u16 rateIndex, u16 freq)
4432 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4433 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4434 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4435 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4436 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4437 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4440 * create array of channels and targetpower from
4441 * targetpower piers stored on eeprom
4443 for (i = 0; i < numPiers; i++) {
4444 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4445 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4448 /* interpolate to get target power for given frequency */
4449 return (u8) ar9003_hw_power_interpolate((s32) freq,
4450 freqArray,
4451 targetPowerArray, numPiers);
4454 static void ar9003_hw_selfgen_tpc_txpower(struct ath_hw *ah,
4455 struct ath9k_channel *chan,
4456 u8 *pwr_array)
4458 u32 val;
4460 /* target power values for self generated frames (ACK,RTS/CTS) */
4461 if (IS_CHAN_2GHZ(chan)) {
4462 val = SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_ACK) |
4463 SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_CTS) |
4464 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4465 } else {
4466 val = SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_ACK) |
4467 SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_CTS) |
4468 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4470 REG_WRITE(ah, AR_TPC, val);
4473 /* Set tx power registers to array of values passed in */
4474 int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4476 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4477 /* make sure forced gain is not set */
4478 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4480 /* Write the OFDM power per rate set */
4482 /* 6 (LSB), 9, 12, 18 (MSB) */
4483 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4484 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4485 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4486 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4487 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4489 /* 24 (LSB), 36, 48, 54 (MSB) */
4490 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4491 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4492 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4493 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4494 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4496 /* Write the CCK power per rate set */
4498 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4499 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4500 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4501 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4502 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4503 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4505 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4506 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4507 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4508 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4509 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4510 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4513 /* Write the power for duplicated frames - HT40 */
4515 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4516 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4517 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4518 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4519 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4520 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4523 /* Write the HT20 power per rate set */
4525 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4526 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4527 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4528 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4529 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4530 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4533 /* 6 (LSB), 7, 12, 13 (MSB) */
4534 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4535 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4536 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4537 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4538 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4541 /* 14 (LSB), 15, 20, 21 */
4542 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4543 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4544 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4545 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4546 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4549 /* Mixed HT20 and HT40 rates */
4551 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4552 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4553 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4554 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4555 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4556 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4560 * Write the HT40 power per rate set
4561 * correct PAR difference between HT40 and HT20/LEGACY
4562 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4564 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4565 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4566 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4567 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4568 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4571 /* 6 (LSB), 7, 12, 13 (MSB) */
4572 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4573 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4574 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4575 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4576 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4579 /* 14 (LSB), 15, 20, 21 */
4580 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4581 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4582 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4583 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4584 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4587 return 0;
4588 #undef POW_SM
4591 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4592 u8 *targetPowerValT2,
4593 bool is2GHz)
4595 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4596 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4597 is2GHz);
4598 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4599 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4600 is2GHz);
4601 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4602 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4603 is2GHz);
4604 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4605 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4606 is2GHz);
4609 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4610 u8 *targetPowerValT2)
4612 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4613 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4614 freq);
4615 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4616 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4617 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4618 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4619 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4620 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4623 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4624 u8 *targetPowerValT2, bool is2GHz)
4626 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4627 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4628 is2GHz);
4629 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4630 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4631 freq, is2GHz);
4632 targetPowerValT2[ALL_TARGET_HT20_4] =
4633 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4634 is2GHz);
4635 targetPowerValT2[ALL_TARGET_HT20_5] =
4636 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4637 is2GHz);
4638 targetPowerValT2[ALL_TARGET_HT20_6] =
4639 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4640 is2GHz);
4641 targetPowerValT2[ALL_TARGET_HT20_7] =
4642 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4643 is2GHz);
4644 targetPowerValT2[ALL_TARGET_HT20_12] =
4645 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4646 is2GHz);
4647 targetPowerValT2[ALL_TARGET_HT20_13] =
4648 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4649 is2GHz);
4650 targetPowerValT2[ALL_TARGET_HT20_14] =
4651 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4652 is2GHz);
4653 targetPowerValT2[ALL_TARGET_HT20_15] =
4654 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4655 is2GHz);
4656 targetPowerValT2[ALL_TARGET_HT20_20] =
4657 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4658 is2GHz);
4659 targetPowerValT2[ALL_TARGET_HT20_21] =
4660 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4661 is2GHz);
4662 targetPowerValT2[ALL_TARGET_HT20_22] =
4663 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4664 is2GHz);
4665 targetPowerValT2[ALL_TARGET_HT20_23] =
4666 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4667 is2GHz);
4670 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4671 u16 freq,
4672 u8 *targetPowerValT2,
4673 bool is2GHz)
4675 /* XXX: hard code for now, need to get from eeprom struct */
4676 u8 ht40PowerIncForPdadc = 0;
4678 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4679 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4680 is2GHz) + ht40PowerIncForPdadc;
4681 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4682 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4683 freq,
4684 is2GHz) + ht40PowerIncForPdadc;
4685 targetPowerValT2[ALL_TARGET_HT40_4] =
4686 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4687 is2GHz) + ht40PowerIncForPdadc;
4688 targetPowerValT2[ALL_TARGET_HT40_5] =
4689 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4690 is2GHz) + ht40PowerIncForPdadc;
4691 targetPowerValT2[ALL_TARGET_HT40_6] =
4692 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4693 is2GHz) + ht40PowerIncForPdadc;
4694 targetPowerValT2[ALL_TARGET_HT40_7] =
4695 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4696 is2GHz) + ht40PowerIncForPdadc;
4697 targetPowerValT2[ALL_TARGET_HT40_12] =
4698 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4699 is2GHz) + ht40PowerIncForPdadc;
4700 targetPowerValT2[ALL_TARGET_HT40_13] =
4701 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4702 is2GHz) + ht40PowerIncForPdadc;
4703 targetPowerValT2[ALL_TARGET_HT40_14] =
4704 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4705 is2GHz) + ht40PowerIncForPdadc;
4706 targetPowerValT2[ALL_TARGET_HT40_15] =
4707 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4708 is2GHz) + ht40PowerIncForPdadc;
4709 targetPowerValT2[ALL_TARGET_HT40_20] =
4710 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4711 is2GHz) + ht40PowerIncForPdadc;
4712 targetPowerValT2[ALL_TARGET_HT40_21] =
4713 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4714 is2GHz) + ht40PowerIncForPdadc;
4715 targetPowerValT2[ALL_TARGET_HT40_22] =
4716 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4717 is2GHz) + ht40PowerIncForPdadc;
4718 targetPowerValT2[ALL_TARGET_HT40_23] =
4719 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4720 is2GHz) + ht40PowerIncForPdadc;
4723 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4724 struct ath9k_channel *chan,
4725 u8 *targetPowerValT2)
4727 bool is2GHz = IS_CHAN_2GHZ(chan);
4728 unsigned int i = 0;
4729 struct ath_common *common = ath9k_hw_common(ah);
4730 u16 freq = chan->channel;
4732 if (is2GHz)
4733 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4735 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4736 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4738 if (IS_CHAN_HT40(chan))
4739 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4740 is2GHz);
4742 for (i = 0; i < ar9300RateSize; i++) {
4743 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
4744 i, targetPowerValT2[i]);
4748 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4749 int mode,
4750 int ipier,
4751 int ichain,
4752 int *pfrequency,
4753 int *pcorrection,
4754 int *ptemperature, int *pvoltage,
4755 int *pnf_cal, int *pnf_power)
4757 u8 *pCalPier;
4758 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4759 int is2GHz;
4760 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4761 struct ath_common *common = ath9k_hw_common(ah);
4763 if (ichain >= AR9300_MAX_CHAINS) {
4764 ath_dbg(common, EEPROM,
4765 "Invalid chain index, must be less than %d\n",
4766 AR9300_MAX_CHAINS);
4767 return -1;
4770 if (mode) { /* 5GHz */
4771 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4772 ath_dbg(common, EEPROM,
4773 "Invalid 5GHz cal pier index, must be less than %d\n",
4774 AR9300_NUM_5G_CAL_PIERS);
4775 return -1;
4777 pCalPier = &(eep->calFreqPier5G[ipier]);
4778 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4779 is2GHz = 0;
4780 } else {
4781 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4782 ath_dbg(common, EEPROM,
4783 "Invalid 2GHz cal pier index, must be less than %d\n",
4784 AR9300_NUM_2G_CAL_PIERS);
4785 return -1;
4788 pCalPier = &(eep->calFreqPier2G[ipier]);
4789 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4790 is2GHz = 1;
4793 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4794 *pcorrection = pCalPierStruct->refPower;
4795 *ptemperature = pCalPierStruct->tempMeas;
4796 *pvoltage = pCalPierStruct->voltMeas;
4797 *pnf_cal = pCalPierStruct->rxTempMeas ?
4798 N2DBM(pCalPierStruct->rxNoisefloorCal) : 0;
4799 *pnf_power = pCalPierStruct->rxTempMeas ?
4800 N2DBM(pCalPierStruct->rxNoisefloorPower) : 0;
4802 return 0;
4805 static void ar9003_hw_power_control_override(struct ath_hw *ah,
4806 int frequency,
4807 int *correction,
4808 int *voltage, int *temperature)
4810 int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
4811 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4812 int f[8], t[8], t1[3], t2[3], i;
4814 REG_RMW(ah, AR_PHY_TPC_11_B0,
4815 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4816 AR_PHY_TPC_OLPC_GAIN_DELTA);
4817 if (ah->caps.tx_chainmask & BIT(1))
4818 REG_RMW(ah, AR_PHY_TPC_11_B1,
4819 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4820 AR_PHY_TPC_OLPC_GAIN_DELTA);
4821 if (ah->caps.tx_chainmask & BIT(2))
4822 REG_RMW(ah, AR_PHY_TPC_11_B2,
4823 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4824 AR_PHY_TPC_OLPC_GAIN_DELTA);
4826 /* enable open loop power control on chip */
4827 REG_RMW(ah, AR_PHY_TPC_6_B0,
4828 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4829 AR_PHY_TPC_6_ERROR_EST_MODE);
4830 if (ah->caps.tx_chainmask & BIT(1))
4831 REG_RMW(ah, AR_PHY_TPC_6_B1,
4832 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4833 AR_PHY_TPC_6_ERROR_EST_MODE);
4834 if (ah->caps.tx_chainmask & BIT(2))
4835 REG_RMW(ah, AR_PHY_TPC_6_B2,
4836 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4837 AR_PHY_TPC_6_ERROR_EST_MODE);
4840 * enable temperature compensation
4841 * Need to use register names
4843 if (frequency < 4000) {
4844 temp_slope = eep->modalHeader2G.tempSlope;
4845 } else {
4846 if (AR_SREV_9550(ah)) {
4847 t[0] = eep->base_ext1.tempslopextension[2];
4848 t1[0] = eep->base_ext1.tempslopextension[3];
4849 t2[0] = eep->base_ext1.tempslopextension[4];
4850 f[0] = 5180;
4852 t[1] = eep->modalHeader5G.tempSlope;
4853 t1[1] = eep->base_ext1.tempslopextension[0];
4854 t2[1] = eep->base_ext1.tempslopextension[1];
4855 f[1] = 5500;
4857 t[2] = eep->base_ext1.tempslopextension[5];
4858 t1[2] = eep->base_ext1.tempslopextension[6];
4859 t2[2] = eep->base_ext1.tempslopextension[7];
4860 f[2] = 5785;
4862 temp_slope = ar9003_hw_power_interpolate(frequency,
4863 f, t, 3);
4864 temp_slope1 = ar9003_hw_power_interpolate(frequency,
4865 f, t1, 3);
4866 temp_slope2 = ar9003_hw_power_interpolate(frequency,
4867 f, t2, 3);
4869 goto tempslope;
4872 if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4873 for (i = 0; i < 8; i++) {
4874 t[i] = eep->base_ext1.tempslopextension[i];
4875 f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4877 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4878 f, t, 8);
4879 } else if (eep->base_ext2.tempSlopeLow != 0) {
4880 t[0] = eep->base_ext2.tempSlopeLow;
4881 f[0] = 5180;
4882 t[1] = eep->modalHeader5G.tempSlope;
4883 f[1] = 5500;
4884 t[2] = eep->base_ext2.tempSlopeHigh;
4885 f[2] = 5785;
4886 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4887 f, t, 3);
4888 } else {
4889 temp_slope = eep->modalHeader5G.tempSlope;
4893 tempslope:
4894 if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
4895 u8 txmask = (eep->baseEepHeader.txrxMask & 0xf0) >> 4;
4898 * AR955x has tempSlope register for each chain.
4899 * Check whether temp_compensation feature is enabled or not.
4901 if (eep->baseEepHeader.featureEnable & 0x1) {
4902 if (frequency < 4000) {
4903 if (txmask & BIT(0))
4904 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4905 AR_PHY_TPC_19_ALPHA_THERM,
4906 eep->base_ext2.tempSlopeLow);
4907 if (txmask & BIT(1))
4908 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4909 AR_PHY_TPC_19_ALPHA_THERM,
4910 temp_slope);
4911 if (txmask & BIT(2))
4912 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4913 AR_PHY_TPC_19_ALPHA_THERM,
4914 eep->base_ext2.tempSlopeHigh);
4915 } else {
4916 if (txmask & BIT(0))
4917 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4918 AR_PHY_TPC_19_ALPHA_THERM,
4919 temp_slope);
4920 if (txmask & BIT(1))
4921 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4922 AR_PHY_TPC_19_ALPHA_THERM,
4923 temp_slope1);
4924 if (txmask & BIT(2))
4925 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4926 AR_PHY_TPC_19_ALPHA_THERM,
4927 temp_slope2);
4929 } else {
4931 * If temp compensation is not enabled,
4932 * set all registers to 0.
4934 if (txmask & BIT(0))
4935 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4936 AR_PHY_TPC_19_ALPHA_THERM, 0);
4937 if (txmask & BIT(1))
4938 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4939 AR_PHY_TPC_19_ALPHA_THERM, 0);
4940 if (txmask & BIT(2))
4941 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4942 AR_PHY_TPC_19_ALPHA_THERM, 0);
4944 } else {
4945 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4946 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4949 if (AR_SREV_9462_20_OR_LATER(ah))
4950 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4951 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4954 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4955 temperature[0]);
4958 /* Apply the recorded correction values. */
4959 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4961 int ichain, ipier, npier;
4962 int mode;
4963 int lfrequency[AR9300_MAX_CHAINS],
4964 lcorrection[AR9300_MAX_CHAINS],
4965 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS],
4966 lnf_cal[AR9300_MAX_CHAINS], lnf_pwr[AR9300_MAX_CHAINS];
4967 int hfrequency[AR9300_MAX_CHAINS],
4968 hcorrection[AR9300_MAX_CHAINS],
4969 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS],
4970 hnf_cal[AR9300_MAX_CHAINS], hnf_pwr[AR9300_MAX_CHAINS];
4971 int fdiff;
4972 int correction[AR9300_MAX_CHAINS],
4973 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS],
4974 nf_cal[AR9300_MAX_CHAINS], nf_pwr[AR9300_MAX_CHAINS];
4975 int pfrequency, pcorrection, ptemperature, pvoltage,
4976 pnf_cal, pnf_pwr;
4977 struct ath_common *common = ath9k_hw_common(ah);
4979 mode = (frequency >= 4000);
4980 if (mode)
4981 npier = AR9300_NUM_5G_CAL_PIERS;
4982 else
4983 npier = AR9300_NUM_2G_CAL_PIERS;
4985 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4986 lfrequency[ichain] = 0;
4987 hfrequency[ichain] = 100000;
4989 /* identify best lower and higher frequency calibration measurement */
4990 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4991 for (ipier = 0; ipier < npier; ipier++) {
4992 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4993 &pfrequency, &pcorrection,
4994 &ptemperature, &pvoltage,
4995 &pnf_cal, &pnf_pwr)) {
4996 fdiff = frequency - pfrequency;
4999 * this measurement is higher than
5000 * our desired frequency
5002 if (fdiff <= 0) {
5003 if (hfrequency[ichain] <= 0 ||
5004 hfrequency[ichain] >= 100000 ||
5005 fdiff >
5006 (frequency - hfrequency[ichain])) {
5008 * new best higher
5009 * frequency measurement
5011 hfrequency[ichain] = pfrequency;
5012 hcorrection[ichain] =
5013 pcorrection;
5014 htemperature[ichain] =
5015 ptemperature;
5016 hvoltage[ichain] = pvoltage;
5017 hnf_cal[ichain] = pnf_cal;
5018 hnf_pwr[ichain] = pnf_pwr;
5021 if (fdiff >= 0) {
5022 if (lfrequency[ichain] <= 0
5023 || fdiff <
5024 (frequency - lfrequency[ichain])) {
5026 * new best lower
5027 * frequency measurement
5029 lfrequency[ichain] = pfrequency;
5030 lcorrection[ichain] =
5031 pcorrection;
5032 ltemperature[ichain] =
5033 ptemperature;
5034 lvoltage[ichain] = pvoltage;
5035 lnf_cal[ichain] = pnf_cal;
5036 lnf_pwr[ichain] = pnf_pwr;
5043 /* interpolate */
5044 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
5045 ath_dbg(common, EEPROM,
5046 "ch=%d f=%d low=%d %d h=%d %d n=%d %d p=%d %d\n",
5047 ichain, frequency, lfrequency[ichain],
5048 lcorrection[ichain], hfrequency[ichain],
5049 hcorrection[ichain], lnf_cal[ichain],
5050 hnf_cal[ichain], lnf_pwr[ichain],
5051 hnf_pwr[ichain]);
5052 /* they're the same, so just pick one */
5053 if (hfrequency[ichain] == lfrequency[ichain]) {
5054 correction[ichain] = lcorrection[ichain];
5055 voltage[ichain] = lvoltage[ichain];
5056 temperature[ichain] = ltemperature[ichain];
5057 nf_cal[ichain] = lnf_cal[ichain];
5058 nf_pwr[ichain] = lnf_pwr[ichain];
5060 /* the low frequency is good */
5061 else if (frequency - lfrequency[ichain] < 1000) {
5062 /* so is the high frequency, interpolate */
5063 if (hfrequency[ichain] - frequency < 1000) {
5065 correction[ichain] = interpolate(frequency,
5066 lfrequency[ichain],
5067 hfrequency[ichain],
5068 lcorrection[ichain],
5069 hcorrection[ichain]);
5071 temperature[ichain] = interpolate(frequency,
5072 lfrequency[ichain],
5073 hfrequency[ichain],
5074 ltemperature[ichain],
5075 htemperature[ichain]);
5077 voltage[ichain] = interpolate(frequency,
5078 lfrequency[ichain],
5079 hfrequency[ichain],
5080 lvoltage[ichain],
5081 hvoltage[ichain]);
5083 nf_cal[ichain] = interpolate(frequency,
5084 lfrequency[ichain],
5085 hfrequency[ichain],
5086 lnf_cal[ichain],
5087 hnf_cal[ichain]);
5089 nf_pwr[ichain] = interpolate(frequency,
5090 lfrequency[ichain],
5091 hfrequency[ichain],
5092 lnf_pwr[ichain],
5093 hnf_pwr[ichain]);
5095 /* only low is good, use it */
5096 else {
5097 correction[ichain] = lcorrection[ichain];
5098 temperature[ichain] = ltemperature[ichain];
5099 voltage[ichain] = lvoltage[ichain];
5100 nf_cal[ichain] = lnf_cal[ichain];
5101 nf_pwr[ichain] = lnf_pwr[ichain];
5104 /* only high is good, use it */
5105 else if (hfrequency[ichain] - frequency < 1000) {
5106 correction[ichain] = hcorrection[ichain];
5107 temperature[ichain] = htemperature[ichain];
5108 voltage[ichain] = hvoltage[ichain];
5109 nf_cal[ichain] = hnf_cal[ichain];
5110 nf_pwr[ichain] = hnf_pwr[ichain];
5111 } else { /* nothing is good, presume 0???? */
5112 correction[ichain] = 0;
5113 temperature[ichain] = 0;
5114 voltage[ichain] = 0;
5115 nf_cal[ichain] = 0;
5116 nf_pwr[ichain] = 0;
5120 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
5121 temperature);
5123 ath_dbg(common, EEPROM,
5124 "for frequency=%d, calibration correction = %d %d %d\n",
5125 frequency, correction[0], correction[1], correction[2]);
5127 /* Store calibrated noise floor values */
5128 for (ichain = 0; ichain < AR5416_MAX_CHAINS; ichain++)
5129 if (mode) {
5130 ah->nf_5g.cal[ichain] = nf_cal[ichain];
5131 ah->nf_5g.pwr[ichain] = nf_pwr[ichain];
5132 } else {
5133 ah->nf_2g.cal[ichain] = nf_cal[ichain];
5134 ah->nf_2g.pwr[ichain] = nf_pwr[ichain];
5137 return 0;
5140 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
5141 int idx,
5142 int edge,
5143 bool is2GHz)
5145 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5146 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5148 if (is2GHz)
5149 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
5150 else
5151 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
5154 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
5155 int idx,
5156 unsigned int edge,
5157 u16 freq,
5158 bool is2GHz)
5160 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5161 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5163 u8 *ctl_freqbin = is2GHz ?
5164 &eep->ctl_freqbin_2G[idx][0] :
5165 &eep->ctl_freqbin_5G[idx][0];
5167 if (is2GHz) {
5168 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
5169 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
5170 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
5171 } else {
5172 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
5173 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
5174 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
5177 return MAX_RATE_POWER;
5181 * Find the maximum conformance test limit for the given channel and CTL info
5183 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
5184 u16 freq, int idx, bool is2GHz)
5186 u16 twiceMaxEdgePower = MAX_RATE_POWER;
5187 u8 *ctl_freqbin = is2GHz ?
5188 &eep->ctl_freqbin_2G[idx][0] :
5189 &eep->ctl_freqbin_5G[idx][0];
5190 u16 num_edges = is2GHz ?
5191 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
5192 unsigned int edge;
5194 /* Get the edge power */
5195 for (edge = 0;
5196 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
5197 edge++) {
5199 * If there's an exact channel match or an inband flag set
5200 * on the lower channel use the given rdEdgePower
5202 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
5203 twiceMaxEdgePower =
5204 ar9003_hw_get_direct_edge_power(eep, idx,
5205 edge, is2GHz);
5206 break;
5207 } else if ((edge > 0) &&
5208 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
5209 is2GHz))) {
5210 twiceMaxEdgePower =
5211 ar9003_hw_get_indirect_edge_power(eep, idx,
5212 edge, freq,
5213 is2GHz);
5215 * Leave loop - no more affecting edges possible in
5216 * this monotonic increasing list
5218 break;
5222 if (is2GHz && !twiceMaxEdgePower)
5223 twiceMaxEdgePower = 60;
5225 return twiceMaxEdgePower;
5228 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
5229 struct ath9k_channel *chan,
5230 u8 *pPwrArray, u16 cfgCtl,
5231 u8 antenna_reduction,
5232 u16 powerLimit)
5234 struct ath_common *common = ath9k_hw_common(ah);
5235 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
5236 u16 twiceMaxEdgePower;
5237 int i;
5238 u16 scaledPower = 0, minCtlPower;
5239 static const u16 ctlModesFor11a[] = {
5240 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
5242 static const u16 ctlModesFor11g[] = {
5243 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
5244 CTL_11G_EXT, CTL_2GHT40
5246 u16 numCtlModes;
5247 const u16 *pCtlMode;
5248 u16 ctlMode, freq;
5249 struct chan_centers centers;
5250 u8 *ctlIndex;
5251 u8 ctlNum;
5252 u16 twiceMinEdgePower;
5253 bool is2ghz = IS_CHAN_2GHZ(chan);
5255 ath9k_hw_get_channel_centers(ah, chan, &centers);
5256 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
5257 antenna_reduction);
5259 if (is2ghz) {
5260 /* Setup for CTL modes */
5261 /* CTL_11B, CTL_11G, CTL_2GHT20 */
5262 numCtlModes =
5263 ARRAY_SIZE(ctlModesFor11g) -
5264 SUB_NUM_CTL_MODES_AT_2G_40;
5265 pCtlMode = ctlModesFor11g;
5266 if (IS_CHAN_HT40(chan))
5267 /* All 2G CTL's */
5268 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
5269 } else {
5270 /* Setup for CTL modes */
5271 /* CTL_11A, CTL_5GHT20 */
5272 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
5273 SUB_NUM_CTL_MODES_AT_5G_40;
5274 pCtlMode = ctlModesFor11a;
5275 if (IS_CHAN_HT40(chan))
5276 /* All 5G CTL's */
5277 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
5281 * For MIMO, need to apply regulatory caps individually across
5282 * dynamically running modes: CCK, OFDM, HT20, HT40
5284 * The outer loop walks through each possible applicable runtime mode.
5285 * The inner loop walks through each ctlIndex entry in EEPROM.
5286 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
5288 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
5289 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
5290 (pCtlMode[ctlMode] == CTL_2GHT40);
5291 if (isHt40CtlMode)
5292 freq = centers.synth_center;
5293 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
5294 freq = centers.ext_center;
5295 else
5296 freq = centers.ctl_center;
5298 ath_dbg(common, REGULATORY,
5299 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
5300 ctlMode, numCtlModes, isHt40CtlMode,
5301 (pCtlMode[ctlMode] & EXT_ADDITIVE));
5303 /* walk through each CTL index stored in EEPROM */
5304 if (is2ghz) {
5305 ctlIndex = pEepData->ctlIndex_2G;
5306 ctlNum = AR9300_NUM_CTLS_2G;
5307 } else {
5308 ctlIndex = pEepData->ctlIndex_5G;
5309 ctlNum = AR9300_NUM_CTLS_5G;
5312 twiceMaxEdgePower = MAX_RATE_POWER;
5313 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
5314 ath_dbg(common, REGULATORY,
5315 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
5316 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
5317 chan->channel);
5320 * compare test group from regulatory
5321 * channel list with test mode from pCtlMode
5322 * list
5324 if ((((cfgCtl & ~CTL_MODE_M) |
5325 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5326 ctlIndex[i]) ||
5327 (((cfgCtl & ~CTL_MODE_M) |
5328 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5329 ((ctlIndex[i] & CTL_MODE_M) |
5330 SD_NO_CTL))) {
5331 twiceMinEdgePower =
5332 ar9003_hw_get_max_edge_power(pEepData,
5333 freq, i,
5334 is2ghz);
5336 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
5338 * Find the minimum of all CTL
5339 * edge powers that apply to
5340 * this channel
5342 twiceMaxEdgePower =
5343 min(twiceMaxEdgePower,
5344 twiceMinEdgePower);
5345 else {
5346 /* specific */
5347 twiceMaxEdgePower = twiceMinEdgePower;
5348 break;
5353 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
5355 ath_dbg(common, REGULATORY,
5356 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
5357 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
5358 scaledPower, minCtlPower);
5360 /* Apply ctl mode to correct target power set */
5361 switch (pCtlMode[ctlMode]) {
5362 case CTL_11B:
5363 for (i = ALL_TARGET_LEGACY_1L_5L;
5364 i <= ALL_TARGET_LEGACY_11S; i++)
5365 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5366 minCtlPower);
5367 break;
5368 case CTL_11A:
5369 case CTL_11G:
5370 for (i = ALL_TARGET_LEGACY_6_24;
5371 i <= ALL_TARGET_LEGACY_54; i++)
5372 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5373 minCtlPower);
5374 break;
5375 case CTL_5GHT20:
5376 case CTL_2GHT20:
5377 for (i = ALL_TARGET_HT20_0_8_16;
5378 i <= ALL_TARGET_HT20_23; i++) {
5379 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5380 minCtlPower);
5381 if (ath9k_hw_mci_is_enabled(ah))
5382 pPwrArray[i] =
5383 (u8)min((u16)pPwrArray[i],
5384 ar9003_mci_get_max_txpower(ah,
5385 pCtlMode[ctlMode]));
5387 break;
5388 case CTL_5GHT40:
5389 case CTL_2GHT40:
5390 for (i = ALL_TARGET_HT40_0_8_16;
5391 i <= ALL_TARGET_HT40_23; i++) {
5392 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5393 minCtlPower);
5394 if (ath9k_hw_mci_is_enabled(ah))
5395 pPwrArray[i] =
5396 (u8)min((u16)pPwrArray[i],
5397 ar9003_mci_get_max_txpower(ah,
5398 pCtlMode[ctlMode]));
5400 break;
5401 default:
5402 break;
5404 } /* end ctl mode checking */
5407 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5409 u8 mod_idx = mcs_idx % 8;
5411 if (mod_idx <= 3)
5412 return mod_idx ? (base_pwridx + 1) : base_pwridx;
5413 else
5414 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5417 static void ar9003_paprd_set_txpower(struct ath_hw *ah,
5418 struct ath9k_channel *chan,
5419 u8 *targetPowerValT2)
5421 int i;
5423 if (!ar9003_is_paprd_enabled(ah))
5424 return;
5426 if (IS_CHAN_HT40(chan))
5427 i = ALL_TARGET_HT40_7;
5428 else
5429 i = ALL_TARGET_HT20_7;
5431 if (IS_CHAN_2GHZ(chan)) {
5432 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) &&
5433 !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) {
5434 if (IS_CHAN_HT40(chan))
5435 i = ALL_TARGET_HT40_0_8_16;
5436 else
5437 i = ALL_TARGET_HT20_0_8_16;
5441 ah->paprd_target_power = targetPowerValT2[i];
5444 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5445 struct ath9k_channel *chan, u16 cfgCtl,
5446 u8 twiceAntennaReduction,
5447 u8 powerLimit, bool test)
5449 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5450 struct ath_common *common = ath9k_hw_common(ah);
5451 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5452 struct ar9300_modal_eep_header *modal_hdr;
5453 u8 targetPowerValT2[ar9300RateSize];
5454 u8 target_power_val_t2_eep[ar9300RateSize];
5455 u8 targetPowerValT2_tpc[ar9300RateSize];
5456 unsigned int i = 0, paprd_scale_factor = 0;
5457 u8 pwr_idx, min_pwridx = 0;
5459 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5462 * Get target powers from EEPROM - our baseline for TX Power
5464 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5466 if (ar9003_is_paprd_enabled(ah)) {
5467 if (IS_CHAN_2GHZ(chan))
5468 modal_hdr = &eep->modalHeader2G;
5469 else
5470 modal_hdr = &eep->modalHeader5G;
5472 ah->paprd_ratemask =
5473 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5474 AR9300_PAPRD_RATE_MASK;
5476 ah->paprd_ratemask_ht40 =
5477 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5478 AR9300_PAPRD_RATE_MASK;
5480 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5481 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5482 ALL_TARGET_HT20_0_8_16;
5484 if (!ah->paprd_table_write_done) {
5485 memcpy(target_power_val_t2_eep, targetPowerValT2,
5486 sizeof(targetPowerValT2));
5487 for (i = 0; i < 24; i++) {
5488 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5489 if (ah->paprd_ratemask & (1 << i)) {
5490 if (targetPowerValT2[pwr_idx] &&
5491 targetPowerValT2[pwr_idx] ==
5492 target_power_val_t2_eep[pwr_idx])
5493 targetPowerValT2[pwr_idx] -=
5494 paprd_scale_factor;
5498 memcpy(target_power_val_t2_eep, targetPowerValT2,
5499 sizeof(targetPowerValT2));
5502 ar9003_hw_set_power_per_rate_table(ah, chan,
5503 targetPowerValT2, cfgCtl,
5504 twiceAntennaReduction,
5505 powerLimit);
5507 memcpy(targetPowerValT2_tpc, targetPowerValT2,
5508 sizeof(targetPowerValT2));
5510 if (ar9003_is_paprd_enabled(ah)) {
5511 for (i = 0; i < ar9300RateSize; i++) {
5512 if ((ah->paprd_ratemask & (1 << i)) &&
5513 (abs(targetPowerValT2[i] -
5514 target_power_val_t2_eep[i]) >
5515 paprd_scale_factor)) {
5516 ah->paprd_ratemask &= ~(1 << i);
5517 ath_dbg(common, EEPROM,
5518 "paprd disabled for mcs %d\n", i);
5523 regulatory->max_power_level = 0;
5524 for (i = 0; i < ar9300RateSize; i++) {
5525 if (targetPowerValT2[i] > regulatory->max_power_level)
5526 regulatory->max_power_level = targetPowerValT2[i];
5529 ath9k_hw_update_regulatory_maxpower(ah);
5531 if (test)
5532 return;
5534 for (i = 0; i < ar9300RateSize; i++) {
5535 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
5536 i, targetPowerValT2[i]);
5539 /* Write target power array to registers */
5540 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5541 ar9003_hw_calibration_apply(ah, chan->channel);
5542 ar9003_paprd_set_txpower(ah, chan, targetPowerValT2);
5544 ar9003_hw_selfgen_tpc_txpower(ah, chan, targetPowerValT2);
5546 /* TPC initializations */
5547 if (ah->tpc_enabled) {
5548 u32 val;
5550 ar9003_hw_init_rate_txpower(ah, targetPowerValT2_tpc, chan);
5552 /* Enable TPC */
5553 REG_WRITE(ah, AR_PHY_PWRTX_MAX,
5554 AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
5555 /* Disable per chain power reduction */
5556 val = REG_READ(ah, AR_PHY_POWER_TX_SUB);
5557 if (AR_SREV_9340(ah))
5558 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5559 val & 0xFFFFFFC0);
5560 else
5561 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5562 val & 0xFFFFF000);
5563 } else {
5564 /* Disable TPC */
5565 REG_WRITE(ah, AR_PHY_PWRTX_MAX, 0);
5569 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5570 u16 i, bool is2GHz)
5572 return AR_NO_SPUR;
5575 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5577 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5579 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5582 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5584 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5586 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5589 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5591 return ar9003_modal_header(ah, is2ghz)->spurChans;
5594 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5595 struct ath9k_channel *chan)
5597 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5599 if (IS_CHAN_2GHZ(chan))
5600 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5601 AR9300_PAPRD_SCALE_1);
5602 else {
5603 if (chan->channel >= 5700)
5604 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5605 AR9300_PAPRD_SCALE_1);
5606 else if (chan->channel >= 5400)
5607 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5608 AR9300_PAPRD_SCALE_2);
5609 else
5610 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5611 AR9300_PAPRD_SCALE_1);
5615 static u8 ar9003_get_eepmisc(struct ath_hw *ah)
5617 return ah->eeprom.map4k.baseEepHeader.eepMisc;
5620 const struct eeprom_ops eep_ar9300_ops = {
5621 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5622 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5623 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5624 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5625 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5626 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5627 .set_board_values = ath9k_hw_ar9300_set_board_values,
5628 .set_addac = ath9k_hw_ar9300_set_addac,
5629 .set_txpower = ath9k_hw_ar9300_set_txpower,
5630 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel,
5631 .get_eepmisc = ar9003_get_eepmisc