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>
19 #include "ar9003_phy.h"
20 #include "ar9003_eeprom.h"
22 #define COMP_HDR_LEN 4
23 #define COMP_CKSUM_LEN 2
25 #define LE16(x) __constant_cpu_to_le16(x)
26 #define LE32(x) __constant_cpu_to_le32(x)
28 /* Local defines to distinguish between extension and control CTL's */
29 #define EXT_ADDITIVE (0x8000)
30 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
31 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
32 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
33 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
34 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
35 #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */
36 #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */
37 #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */
39 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
40 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
42 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
44 #define EEPROM_DATA_LEN_9485 1088
46 static int ar9003_hw_power_interpolate(int32_t x,
47 int32_t *px, int32_t *py, u_int16_t np);
50 static const struct ar9300_eeprom ar9300_default = {
53 .macAddr = {0, 2, 3, 4, 5, 6},
54 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
57 .regDmn = { LE16(0), LE16(0x1f) },
58 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
60 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
64 .blueToothOptions = 0,
66 .deviceType = 5, /* takes lower byte in eeprom location */
67 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
68 .params_for_tuning_caps = {0, 0},
69 .featureEnable = 0x0c,
71 * bit0 - enable tx temp comp - disabled
72 * bit1 - enable tx volt comp - disabled
73 * bit2 - enable fastClock - enabled
74 * bit3 - enable doubling - enabled
75 * bit4 - enable internal regulator - disabled
76 * bit5 - enable pa predistortion - disabled
78 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
79 .eepromWriteEnableGpio = 3,
82 .rxBandSelectGpio = 0xff,
87 /* ar9300_modal_eep_header 2g */
88 /* 4 idle,t1,t2,b(4 bits per setting) */
89 .antCtrlCommon = LE32(0x110),
90 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
91 .antCtrlCommon2 = LE32(0x22222),
94 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
95 * rx1, rx12, b (2 bits each)
97 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
100 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
101 * for ar9280 (0xa20c/b20c 5:0)
103 .xatten1DB = {0, 0, 0},
106 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
107 * for ar9280 (0xa20c/b20c 16:12
109 .xatten1Margin = {0, 0, 0},
114 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
115 * channels in usual fbin coding format
117 .spurChans = {0, 0, 0, 0, 0},
120 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
121 * if the register is per chain
123 .noiseFloorThreshCh = {-1, 0, 0},
124 .ob = {1, 1, 1},/* 3 chain */
125 .db_stage2 = {1, 1, 1}, /* 3 chain */
126 .db_stage3 = {0, 0, 0},
127 .db_stage4 = {0, 0, 0},
129 .txFrameToDataStart = 0x0e,
130 .txFrameToPaOn = 0x0e,
131 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
133 .switchSettling = 0x2c,
134 .adcDesiredSize = -30,
137 .txFrameToXpaOn = 0xe,
139 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
140 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
142 0, 0, 0, 0, 0, 0, 0, 0,
146 .ant_div_control = 0,
147 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
154 /* ar9300_cal_data_per_freq_op_loop 2g */
156 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
157 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
158 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
160 .calTarget_freqbin_Cck = {
164 .calTarget_freqbin_2G = {
169 .calTarget_freqbin_2GHT20 = {
174 .calTarget_freqbin_2GHT40 = {
179 .calTargetPowerCck = {
180 /* 1L-5L,5S,11L,11S */
181 { {36, 36, 36, 36} },
182 { {36, 36, 36, 36} },
184 .calTargetPower2G = {
186 { {32, 32, 28, 24} },
187 { {32, 32, 28, 24} },
188 { {32, 32, 28, 24} },
190 .calTargetPower2GHT20 = {
191 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
192 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
193 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
195 .calTargetPower2GHT40 = {
196 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
197 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
198 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
201 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
202 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
232 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
233 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
234 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
235 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
239 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
240 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
241 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
246 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
247 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
253 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
254 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
255 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
256 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
260 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
261 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
262 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
266 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
267 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
268 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
273 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
274 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
275 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
280 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
281 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
282 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
283 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
287 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
288 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
289 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
291 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
292 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
293 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
295 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), 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, 0), CTL(60, 0) } },
299 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
300 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
301 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
304 /* 4 idle,t1,t2,b (4 bits per setting) */
305 .antCtrlCommon = LE32(0x110),
306 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
307 .antCtrlCommon2 = LE32(0x22222),
308 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
310 LE16(0x000), LE16(0x000), LE16(0x000),
312 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
313 .xatten1DB = {0, 0, 0},
316 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
317 * for merlin (0xa20c/b20c 16:12
319 .xatten1Margin = {0, 0, 0},
322 /* spurChans spur channels in usual fbin coding format */
323 .spurChans = {0, 0, 0, 0, 0},
324 /* noiseFloorThreshCh Check if the register is per chain */
325 .noiseFloorThreshCh = {-1, 0, 0},
326 .ob = {3, 3, 3}, /* 3 chain */
327 .db_stage2 = {3, 3, 3}, /* 3 chain */
328 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
329 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
331 .txFrameToDataStart = 0x0e,
332 .txFrameToPaOn = 0x0e,
333 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
335 .switchSettling = 0x2d,
336 .adcDesiredSize = -30,
339 .txFrameToXpaOn = 0xe,
341 .papdRateMaskHt20 = LE32(0x0c80c080),
342 .papdRateMaskHt40 = LE32(0x0080c080),
344 0, 0, 0, 0, 0, 0, 0, 0,
350 .xatten1DBLow = {0, 0, 0},
351 .xatten1MarginLow = {0, 0, 0},
352 .xatten1DBHigh = {0, 0, 0},
353 .xatten1MarginHigh = {0, 0, 0}
398 .calTarget_freqbin_5G = {
408 .calTarget_freqbin_5GHT20 = {
418 .calTarget_freqbin_5GHT40 = {
428 .calTargetPower5G = {
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} },
435 { {20, 20, 20, 10} },
436 { {20, 20, 20, 10} },
437 { {20, 20, 20, 10} },
439 .calTargetPower5GHT20 = {
441 * 0_8_16,1-3_9-11_17-19,
442 * 4,5,6,7,12,13,14,15,20,21,22,23
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} },
449 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
450 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
451 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
453 .calTargetPower5GHT40 = {
455 * 0_8_16,1-3_9-11_17-19,
456 * 4,5,6,7,12,13,14,15,20,21,22,23
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} },
463 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
464 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
465 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
468 0x10, 0x16, 0x18, 0x40, 0x46,
469 0x48, 0x30, 0x36, 0x38
473 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
474 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
475 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
476 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
477 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
478 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
479 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
480 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
483 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
484 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
485 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
486 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
487 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
488 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
489 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
490 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
494 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
495 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
496 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
497 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
498 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
499 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
500 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
501 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
505 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
506 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
507 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
508 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
509 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
510 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
511 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
512 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
516 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
517 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
518 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
519 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
520 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
521 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
522 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
523 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
527 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
528 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
529 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
530 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
531 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
532 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
533 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
534 /* Data[5].ctlEdges[7].bChannel */ 0xFF
538 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
539 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
540 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
541 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
542 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
543 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
544 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
545 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
549 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
550 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
551 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
552 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
553 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
554 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
555 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
556 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
560 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
561 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
562 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
563 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
564 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
565 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
566 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
567 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
573 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
574 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
579 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
580 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
585 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
586 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
591 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
592 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
597 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
598 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
603 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
604 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
609 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
610 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
615 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
616 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
621 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
622 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
628 static const struct ar9300_eeprom ar9300_x113 = {
630 .templateVersion = 6,
631 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
632 .custData = {"x113-023-f0000"},
634 .regDmn = { LE16(0), LE16(0x1f) },
635 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
637 .opFlags = AR5416_OPFLAGS_11A,
641 .blueToothOptions = 0,
643 .deviceType = 5, /* takes lower byte in eeprom location */
644 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
645 .params_for_tuning_caps = {0, 0},
646 .featureEnable = 0x0d,
648 * bit0 - enable tx temp comp - disabled
649 * bit1 - enable tx volt comp - disabled
650 * bit2 - enable fastClock - enabled
651 * bit3 - enable doubling - enabled
652 * bit4 - enable internal regulator - disabled
653 * bit5 - enable pa predistortion - disabled
655 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
656 .eepromWriteEnableGpio = 6,
657 .wlanDisableGpio = 0,
659 .rxBandSelectGpio = 0xff,
664 /* ar9300_modal_eep_header 2g */
665 /* 4 idle,t1,t2,b(4 bits per setting) */
666 .antCtrlCommon = LE32(0x110),
667 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
668 .antCtrlCommon2 = LE32(0x44444),
671 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
672 * rx1, rx12, b (2 bits each)
674 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
677 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
678 * for ar9280 (0xa20c/b20c 5:0)
680 .xatten1DB = {0, 0, 0},
683 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
684 * for ar9280 (0xa20c/b20c 16:12
686 .xatten1Margin = {0, 0, 0},
691 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
692 * channels in usual fbin coding format
694 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
697 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
698 * if the register is per chain
700 .noiseFloorThreshCh = {-1, 0, 0},
701 .ob = {1, 1, 1},/* 3 chain */
702 .db_stage2 = {1, 1, 1}, /* 3 chain */
703 .db_stage3 = {0, 0, 0},
704 .db_stage4 = {0, 0, 0},
706 .txFrameToDataStart = 0x0e,
707 .txFrameToPaOn = 0x0e,
708 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
710 .switchSettling = 0x2c,
711 .adcDesiredSize = -30,
714 .txFrameToXpaOn = 0xe,
716 .papdRateMaskHt20 = LE32(0x0c80c080),
717 .papdRateMaskHt40 = LE32(0x0080c080),
719 0, 0, 0, 0, 0, 0, 0, 0,
723 .ant_div_control = 0,
724 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
731 /* ar9300_cal_data_per_freq_op_loop 2g */
733 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
734 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
735 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
737 .calTarget_freqbin_Cck = {
741 .calTarget_freqbin_2G = {
746 .calTarget_freqbin_2GHT20 = {
751 .calTarget_freqbin_2GHT40 = {
756 .calTargetPowerCck = {
757 /* 1L-5L,5S,11L,11S */
758 { {34, 34, 34, 34} },
759 { {34, 34, 34, 34} },
761 .calTargetPower2G = {
763 { {34, 34, 32, 32} },
764 { {34, 34, 32, 32} },
765 { {34, 34, 32, 32} },
767 .calTargetPower2GHT20 = {
768 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
769 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
770 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
772 .calTargetPower2GHT40 = {
773 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
774 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
775 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
778 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
779 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
809 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
810 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
811 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
812 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
816 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
817 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
818 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
823 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
824 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
830 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
831 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
832 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
833 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
837 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
838 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
839 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
843 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
844 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
845 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
850 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
851 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
852 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
857 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
858 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
859 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
860 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
864 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
865 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
866 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
868 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
869 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
870 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
872 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
873 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
874 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
876 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
877 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
878 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
881 /* 4 idle,t1,t2,b (4 bits per setting) */
882 .antCtrlCommon = LE32(0x220),
883 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
884 .antCtrlCommon2 = LE32(0x11111),
885 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
887 LE16(0x150), LE16(0x150), LE16(0x150),
889 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
890 .xatten1DB = {0, 0, 0},
893 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
894 * for merlin (0xa20c/b20c 16:12
896 .xatten1Margin = {0, 0, 0},
899 /* spurChans spur channels in usual fbin coding format */
900 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
901 /* noiseFloorThreshCh Check if the register is per chain */
902 .noiseFloorThreshCh = {-1, 0, 0},
903 .ob = {3, 3, 3}, /* 3 chain */
904 .db_stage2 = {3, 3, 3}, /* 3 chain */
905 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
906 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
908 .txFrameToDataStart = 0x0e,
909 .txFrameToPaOn = 0x0e,
910 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
912 .switchSettling = 0x2d,
913 .adcDesiredSize = -30,
916 .txFrameToXpaOn = 0xe,
918 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
919 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
921 0, 0, 0, 0, 0, 0, 0, 0,
926 .tempSlopeHigh = 105,
927 .xatten1DBLow = {0, 0, 0},
928 .xatten1MarginLow = {0, 0, 0},
929 .xatten1DBHigh = {0, 0, 0},
930 .xatten1MarginHigh = {0, 0, 0}
975 .calTarget_freqbin_5G = {
985 .calTarget_freqbin_5GHT20 = {
995 .calTarget_freqbin_5GHT40 = {
1005 .calTargetPower5G = {
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} },
1013 { {42, 40, 40, 34} },
1014 { {42, 40, 40, 34} },
1016 .calTargetPower5GHT20 = {
1018 * 0_8_16,1-3_9-11_17-19,
1019 * 4,5,6,7,12,13,14,15,20,21,22,23
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 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1026 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1027 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1028 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1030 .calTargetPower5GHT40 = {
1032 * 0_8_16,1-3_9-11_17-19,
1033 * 4,5,6,7,12,13,14,15,20,21,22,23
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 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1040 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1041 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1042 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1045 0x10, 0x16, 0x18, 0x40, 0x46,
1046 0x48, 0x30, 0x36, 0x38
1050 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1051 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1052 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1053 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1054 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1055 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1056 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1057 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1060 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1061 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1062 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1063 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1064 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1065 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1066 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1067 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1071 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1072 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1073 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1074 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1075 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1076 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1077 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1078 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1082 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1083 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1084 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1085 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1086 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1087 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1088 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1089 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1093 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1094 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1095 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1096 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1097 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1098 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1099 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1100 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1104 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1105 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1106 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1107 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1108 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1109 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1110 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1111 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1115 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1116 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1117 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1118 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1119 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1120 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1121 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1122 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1126 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1127 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1128 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1129 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1130 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1131 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1132 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1133 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1137 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1138 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1139 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1140 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1141 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1142 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1143 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1144 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1147 .ctlPowerData_5G = {
1150 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1151 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1156 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1157 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1162 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1163 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1168 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1169 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1174 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1175 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1180 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1181 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1186 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1187 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1192 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1193 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1198 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1199 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1206 static const struct ar9300_eeprom ar9300_h112 = {
1208 .templateVersion = 3,
1209 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1210 .custData = {"h112-241-f0000"},
1212 .regDmn = { LE16(0), LE16(0x1f) },
1213 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1215 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1219 .blueToothOptions = 0,
1221 .deviceType = 5, /* takes lower byte in eeprom location */
1222 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1223 .params_for_tuning_caps = {0, 0},
1224 .featureEnable = 0x0d,
1226 * bit0 - enable tx temp comp - disabled
1227 * bit1 - enable tx volt comp - disabled
1228 * bit2 - enable fastClock - enabled
1229 * bit3 - enable doubling - enabled
1230 * bit4 - enable internal regulator - disabled
1231 * bit5 - enable pa predistortion - disabled
1233 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1234 .eepromWriteEnableGpio = 6,
1235 .wlanDisableGpio = 0,
1237 .rxBandSelectGpio = 0xff,
1242 /* ar9300_modal_eep_header 2g */
1243 /* 4 idle,t1,t2,b(4 bits per setting) */
1244 .antCtrlCommon = LE32(0x110),
1245 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1246 .antCtrlCommon2 = LE32(0x44444),
1249 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1250 * rx1, rx12, b (2 bits each)
1252 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1255 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1256 * for ar9280 (0xa20c/b20c 5:0)
1258 .xatten1DB = {0, 0, 0},
1261 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1262 * for ar9280 (0xa20c/b20c 16:12
1264 .xatten1Margin = {0, 0, 0},
1269 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1270 * channels in usual fbin coding format
1272 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1275 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1276 * if the register is per chain
1278 .noiseFloorThreshCh = {-1, 0, 0},
1279 .ob = {1, 1, 1},/* 3 chain */
1280 .db_stage2 = {1, 1, 1}, /* 3 chain */
1281 .db_stage3 = {0, 0, 0},
1282 .db_stage4 = {0, 0, 0},
1284 .txFrameToDataStart = 0x0e,
1285 .txFrameToPaOn = 0x0e,
1286 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1288 .switchSettling = 0x2c,
1289 .adcDesiredSize = -30,
1292 .txFrameToXpaOn = 0xe,
1294 .papdRateMaskHt20 = LE32(0x80c080),
1295 .papdRateMaskHt40 = LE32(0x80c080),
1297 0, 0, 0, 0, 0, 0, 0, 0,
1301 .ant_div_control = 0,
1302 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1309 /* ar9300_cal_data_per_freq_op_loop 2g */
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} },
1313 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1315 .calTarget_freqbin_Cck = {
1319 .calTarget_freqbin_2G = {
1324 .calTarget_freqbin_2GHT20 = {
1329 .calTarget_freqbin_2GHT40 = {
1334 .calTargetPowerCck = {
1335 /* 1L-5L,5S,11L,11S */
1336 { {34, 34, 34, 34} },
1337 { {34, 34, 34, 34} },
1339 .calTargetPower2G = {
1341 { {34, 34, 32, 32} },
1342 { {34, 34, 32, 32} },
1343 { {34, 34, 32, 32} },
1345 .calTargetPower2GHT20 = {
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} },
1348 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1350 .calTargetPower2GHT40 = {
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} },
1353 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1356 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1357 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1387 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1388 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1389 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1390 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1394 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1395 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1396 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1401 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1402 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1408 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1409 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1410 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1411 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1415 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1416 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1417 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1421 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1422 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1423 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1428 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1429 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1430 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1435 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1436 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1437 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1438 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1441 .ctlPowerData_2G = {
1442 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1443 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1444 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1446 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
1447 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1448 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1450 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1451 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1452 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1454 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1455 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1456 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1459 /* 4 idle,t1,t2,b (4 bits per setting) */
1460 .antCtrlCommon = LE32(0x220),
1461 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1462 .antCtrlCommon2 = LE32(0x44444),
1463 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1465 LE16(0x150), LE16(0x150), LE16(0x150),
1467 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1468 .xatten1DB = {0, 0, 0},
1471 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1472 * for merlin (0xa20c/b20c 16:12
1474 .xatten1Margin = {0, 0, 0},
1477 /* spurChans spur channels in usual fbin coding format */
1478 .spurChans = {0, 0, 0, 0, 0},
1479 /* noiseFloorThreshCh Check if the register is per chain */
1480 .noiseFloorThreshCh = {-1, 0, 0},
1481 .ob = {3, 3, 3}, /* 3 chain */
1482 .db_stage2 = {3, 3, 3}, /* 3 chain */
1483 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
1484 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
1486 .txFrameToDataStart = 0x0e,
1487 .txFrameToPaOn = 0x0e,
1488 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1490 .switchSettling = 0x2d,
1491 .adcDesiredSize = -30,
1494 .txFrameToXpaOn = 0xe,
1496 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1497 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1499 0, 0, 0, 0, 0, 0, 0, 0,
1504 .tempSlopeHigh = 50,
1505 .xatten1DBLow = {0, 0, 0},
1506 .xatten1MarginLow = {0, 0, 0},
1507 .xatten1DBHigh = {0, 0, 0},
1508 .xatten1MarginHigh = {0, 0, 0}
1553 .calTarget_freqbin_5G = {
1563 .calTarget_freqbin_5GHT20 = {
1573 .calTarget_freqbin_5GHT40 = {
1583 .calTargetPower5G = {
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} },
1592 { {30, 30, 28, 24} },
1594 .calTargetPower5GHT20 = {
1596 * 0_8_16,1-3_9-11_17-19,
1597 * 4,5,6,7,12,13,14,15,20,21,22,23
1599 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1600 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1601 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1602 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1603 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1604 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1605 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1606 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1608 .calTargetPower5GHT40 = {
1610 * 0_8_16,1-3_9-11_17-19,
1611 * 4,5,6,7,12,13,14,15,20,21,22,23
1613 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1614 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1615 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1616 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1617 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1618 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1619 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1620 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1623 0x10, 0x16, 0x18, 0x40, 0x46,
1624 0x48, 0x30, 0x36, 0x38
1628 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1629 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1630 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1631 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1632 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1633 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1634 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1635 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1638 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1639 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1640 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1641 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1642 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1643 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1644 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1645 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1649 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1650 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1651 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1652 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1653 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1654 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1655 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1656 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1660 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1661 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1662 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1663 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1664 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1665 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1666 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1667 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1671 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1672 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1673 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1674 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1675 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1676 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1677 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1678 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1682 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1683 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1684 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1685 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1686 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1687 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1688 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1689 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1693 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1694 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1695 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1696 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1697 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1698 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1699 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1700 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1704 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1705 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1706 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1707 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1708 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1709 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1710 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1711 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1715 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1716 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1717 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1718 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1719 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1720 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1721 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1722 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1725 .ctlPowerData_5G = {
1728 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1729 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1734 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1735 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1740 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1741 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1746 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1747 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1752 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1753 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1758 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1759 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1764 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1765 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1770 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1771 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1776 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1777 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1784 static const struct ar9300_eeprom ar9300_x112 = {
1786 .templateVersion = 5,
1787 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1788 .custData = {"x112-041-f0000"},
1790 .regDmn = { LE16(0), LE16(0x1f) },
1791 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1793 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1797 .blueToothOptions = 0,
1799 .deviceType = 5, /* takes lower byte in eeprom location */
1800 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1801 .params_for_tuning_caps = {0, 0},
1802 .featureEnable = 0x0d,
1804 * bit0 - enable tx temp comp - disabled
1805 * bit1 - enable tx volt comp - disabled
1806 * bit2 - enable fastclock - enabled
1807 * bit3 - enable doubling - enabled
1808 * bit4 - enable internal regulator - disabled
1809 * bit5 - enable pa predistortion - disabled
1811 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1812 .eepromWriteEnableGpio = 6,
1813 .wlanDisableGpio = 0,
1815 .rxBandSelectGpio = 0xff,
1820 /* ar9300_modal_eep_header 2g */
1821 /* 4 idle,t1,t2,b(4 bits per setting) */
1822 .antCtrlCommon = LE32(0x110),
1823 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1824 .antCtrlCommon2 = LE32(0x22222),
1827 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1828 * rx1, rx12, b (2 bits each)
1830 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1833 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1834 * for ar9280 (0xa20c/b20c 5:0)
1836 .xatten1DB = {0x1b, 0x1b, 0x1b},
1839 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1840 * for ar9280 (0xa20c/b20c 16:12
1842 .xatten1Margin = {0x15, 0x15, 0x15},
1847 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1848 * channels in usual fbin coding format
1850 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1853 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1854 * if the register is per chain
1856 .noiseFloorThreshCh = {-1, 0, 0},
1857 .ob = {1, 1, 1},/* 3 chain */
1858 .db_stage2 = {1, 1, 1}, /* 3 chain */
1859 .db_stage3 = {0, 0, 0},
1860 .db_stage4 = {0, 0, 0},
1862 .txFrameToDataStart = 0x0e,
1863 .txFrameToPaOn = 0x0e,
1864 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1866 .switchSettling = 0x2c,
1867 .adcDesiredSize = -30,
1870 .txFrameToXpaOn = 0xe,
1872 .papdRateMaskHt20 = LE32(0x0c80c080),
1873 .papdRateMaskHt40 = LE32(0x0080c080),
1875 0, 0, 0, 0, 0, 0, 0, 0,
1879 .ant_div_control = 0,
1880 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1887 /* ar9300_cal_data_per_freq_op_loop 2g */
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 = {
1897 .calTarget_freqbin_2G = {
1902 .calTarget_freqbin_2GHT20 = {
1907 .calTarget_freqbin_2GHT40 = {
1912 .calTargetPowerCck = {
1913 /* 1L-5L,5S,11L,11s */
1914 { {38, 38, 38, 38} },
1915 { {38, 38, 38, 38} },
1917 .calTargetPower2G = {
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} },
1934 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1935 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
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),
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) } },
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) */
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},
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 .ob = {3, 3, 3}, /* 3 chain */
2060 .db_stage2 = {3, 3, 3}, /* 3 chain */
2061 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
2062 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
2064 .txFrameToDataStart = 0x0e,
2065 .txFrameToPaOn = 0x0e,
2066 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2068 .switchSettling = 0x2d,
2069 .adcDesiredSize = -30,
2072 .txFrameToXpaOn = 0xe,
2074 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2075 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2077 0, 0, 0, 0, 0, 0, 0, 0,
2082 .tempSlopeHigh = 105,
2083 .xatten1DBLow = {0x10, 0x14, 0x10},
2084 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2085 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2086 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2131 .calTarget_freqbin_5G = {
2141 .calTarget_freqbin_5GHT20 = {
2151 .calTarget_freqbin_5GHT40 = {
2161 .calTargetPower5G = {
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} },
2201 0x10, 0x16, 0x18, 0x40, 0x46,
2202 0x48, 0x30, 0x36, 0x38
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 = {
2363 .templateVersion = 4,
2364 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2365 .custData = {"h116-041-f0000"},
2367 .regDmn = { LE16(0), LE16(0x1f) },
2368 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2370 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2374 .blueToothOptions = 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,
2392 .rxBandSelectGpio = 0xff,
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},
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 .ob = {1, 1, 1},/* 3 chain */
2435 .db_stage2 = {1, 1, 1}, /* 3 chain */
2436 .db_stage3 = {0, 0, 0},
2437 .db_stage4 = {0, 0, 0},
2439 .txFrameToDataStart = 0x0e,
2440 .txFrameToPaOn = 0x0e,
2441 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2443 .switchSettling = 0x2c,
2444 .adcDesiredSize = -30,
2447 .txFrameToXpaOn = 0xe,
2449 .papdRateMaskHt20 = LE32(0x0c80C080),
2450 .papdRateMaskHt40 = LE32(0x0080C080),
2452 0, 0, 0, 0, 0, 0, 0, 0,
2456 .ant_div_control = 0,
2457 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2464 /* ar9300_cal_data_per_freq_op_loop 2g */
2466 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2467 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2468 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2470 .calTarget_freqbin_Cck = {
2474 .calTarget_freqbin_2G = {
2479 .calTarget_freqbin_2GHT20 = {
2484 .calTarget_freqbin_2GHT40 = {
2489 .calTargetPowerCck = {
2490 /* 1L-5L,5S,11L,11S */
2491 { {34, 34, 34, 34} },
2492 { {34, 34, 34, 34} },
2494 .calTargetPower2G = {
2496 { {34, 34, 32, 32} },
2497 { {34, 34, 32, 32} },
2498 { {34, 34, 32, 32} },
2500 .calTargetPower2GHT20 = {
2501 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2502 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2503 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2505 .calTargetPower2GHT40 = {
2506 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2507 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2508 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2511 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2512 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2542 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2543 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2544 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2545 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2549 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2550 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2551 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2556 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2557 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2563 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2564 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2565 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2566 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2570 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2571 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2572 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2576 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2577 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2578 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2583 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2584 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2585 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2590 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2591 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2592 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2593 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2596 .ctlPowerData_2G = {
2597 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2598 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2599 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2601 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2602 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2603 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2605 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2606 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2607 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2609 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2610 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2611 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2614 /* 4 idle,t1,t2,b (4 bits per setting) */
2615 .antCtrlCommon = LE32(0x220),
2616 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2617 .antCtrlCommon2 = LE32(0x44444),
2618 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2620 LE16(0x150), LE16(0x150), LE16(0x150),
2622 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2623 .xatten1DB = {0x19, 0x19, 0x19},
2626 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2627 * for merlin (0xa20c/b20c 16:12
2629 .xatten1Margin = {0x14, 0x14, 0x14},
2632 /* spurChans spur channels in usual fbin coding format */
2633 .spurChans = {0, 0, 0, 0, 0},
2634 /* noiseFloorThreshCh Check if the register is per chain */
2635 .noiseFloorThreshCh = {-1, 0, 0},
2636 .ob = {3, 3, 3}, /* 3 chain */
2637 .db_stage2 = {3, 3, 3}, /* 3 chain */
2638 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
2639 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
2641 .txFrameToDataStart = 0x0e,
2642 .txFrameToPaOn = 0x0e,
2643 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2645 .switchSettling = 0x2d,
2646 .adcDesiredSize = -30,
2649 .txFrameToXpaOn = 0xe,
2651 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2652 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2654 0, 0, 0, 0, 0, 0, 0, 0,
2659 .tempSlopeHigh = 50,
2660 .xatten1DBLow = {0, 0, 0},
2661 .xatten1MarginLow = {0, 0, 0},
2662 .xatten1DBHigh = {0, 0, 0},
2663 .xatten1MarginHigh = {0, 0, 0}
2708 .calTarget_freqbin_5G = {
2718 .calTarget_freqbin_5GHT20 = {
2728 .calTarget_freqbin_5GHT40 = {
2738 .calTargetPower5G = {
2740 { {30, 30, 28, 24} },
2741 { {30, 30, 28, 24} },
2742 { {30, 30, 28, 24} },
2743 { {30, 30, 28, 24} },
2744 { {30, 30, 28, 24} },
2745 { {30, 30, 28, 24} },
2746 { {30, 30, 28, 24} },
2747 { {30, 30, 28, 24} },
2749 .calTargetPower5GHT20 = {
2751 * 0_8_16,1-3_9-11_17-19,
2752 * 4,5,6,7,12,13,14,15,20,21,22,23
2754 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2755 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2756 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2757 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2758 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2759 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2760 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2761 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2763 .calTargetPower5GHT40 = {
2765 * 0_8_16,1-3_9-11_17-19,
2766 * 4,5,6,7,12,13,14,15,20,21,22,23
2768 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2769 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2770 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2771 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2772 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2773 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2774 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2775 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2778 0x10, 0x16, 0x18, 0x40, 0x46,
2779 0x48, 0x30, 0x36, 0x38
2783 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2784 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2785 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2786 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2787 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2788 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2789 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2790 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2793 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2794 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2795 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2796 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2797 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2798 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2799 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2800 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2804 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2805 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2806 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2807 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2808 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2809 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2810 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2811 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2815 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2816 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2817 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2818 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2819 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2820 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2821 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2822 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2826 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2827 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2828 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2829 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2830 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2831 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2832 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2833 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2837 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2838 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2839 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2840 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2841 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2842 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2843 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2844 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2848 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2849 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2850 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2851 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2852 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2853 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2854 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2855 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2859 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2860 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2861 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2862 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2863 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2864 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2865 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2866 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2870 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2871 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2872 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2873 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2874 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2875 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2876 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2877 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2880 .ctlPowerData_5G = {
2883 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2884 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2889 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2890 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2895 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2896 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2901 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2902 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2907 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2908 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2913 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2914 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2919 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2920 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2925 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2926 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2931 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2932 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2939 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2947 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2949 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2952 for (it = 0; it < N_LOOP; it++)
2953 if (ar9300_eep_templates[it]->templateVersion == id)
2954 return ar9300_eep_templates[it];
2960 static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
2962 if (fbin == AR5416_BCHAN_UNUSED)
2965 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
2968 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2973 static int interpolate(int x, int xa, int xb, int ya, int yb)
2975 int bf, factor, plus;
2977 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2980 return ya + factor + plus;
2983 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2984 enum eeprom_param param)
2986 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2987 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
2991 return get_unaligned_be16(eep->macAddr);
2993 return get_unaligned_be16(eep->macAddr + 2);
2995 return get_unaligned_be16(eep->macAddr + 4);
2997 return le16_to_cpu(pBase->regDmn[0]);
2999 return pBase->deviceCap;
3001 return pBase->opCapFlags.opFlags;
3003 return pBase->rfSilent;
3005 return (pBase->txrxMask >> 4) & 0xf;
3007 return pBase->txrxMask & 0xf;
3008 case EEP_DRIVE_STRENGTH:
3009 #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1
3010 return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
3011 case EEP_INTERNAL_REGULATOR:
3012 /* Bit 4 is internal regulator flag */
3013 return (pBase->featureEnable & 0x10) >> 4;
3015 return le32_to_cpu(pBase->swreg);
3017 return !!(pBase->featureEnable & BIT(5));
3018 case EEP_CHAIN_MASK_REDUCE:
3019 return (pBase->miscConfiguration >> 0x3) & 0x1;
3020 case EEP_ANT_DIV_CTL1:
3021 return eep->base_ext1.ant_div_control;
3022 case EEP_ANTENNA_GAIN_5G:
3023 return eep->modalHeader5G.antennaGain;
3024 case EEP_ANTENNA_GAIN_2G:
3025 return eep->modalHeader2G.antennaGain;
3031 static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
3036 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3039 *buffer = (val >> (8 * (address % 2))) & 0xff;
3043 static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
3048 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3051 buffer[0] = val >> 8;
3052 buffer[1] = val & 0xff;
3057 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3060 struct ath_common *common = ath9k_hw_common(ah);
3063 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3064 ath_dbg(common, ATH_DBG_EEPROM,
3065 "eeprom address not in range\n");
3070 * Since we're reading the bytes in reverse order from a little-endian
3071 * word stream, an even address means we only use the lower half of
3072 * the 16-bit word at that address
3074 if (address % 2 == 0) {
3075 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
3081 for (i = 0; i < count / 2; i++) {
3082 if (!ar9300_eeprom_read_word(common, address, buffer))
3090 if (!ar9300_eeprom_read_byte(common, address, buffer))
3096 ath_dbg(common, ATH_DBG_EEPROM,
3097 "unable to read eeprom region at offset %d\n", address);
3101 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3103 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3105 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3106 AR9300_OTP_STATUS_VALID, 1000))
3109 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3113 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3119 for (i = 0; i < count; i++) {
3120 int offset = 8 * ((address - i) % 4);
3121 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3124 buffer[i] = (data >> offset) & 0xff;
3131 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3132 int *length, int *major, int *minor)
3134 unsigned long value[4];
3140 *code = ((value[0] >> 5) & 0x0007);
3141 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3142 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3143 *major = (value[2] & 0x000f);
3144 *minor = (value[3] & 0x00ff);
3147 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3149 int it, checksum = 0;
3151 for (it = 0; it < dsize; it++) {
3152 checksum += data[it];
3159 static bool ar9300_uncompress_block(struct ath_hw *ah,
3169 struct ath_common *common = ath9k_hw_common(ah);
3173 for (it = 0; it < size; it += (length+2)) {
3177 length = block[it+1];
3180 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3181 ath_dbg(common, ATH_DBG_EEPROM,
3182 "Restore at %d: spot=%d offset=%d length=%d\n",
3183 it, spot, offset, length);
3184 memcpy(&mptr[spot], &block[it+2], length);
3186 } else if (length > 0) {
3187 ath_dbg(common, ATH_DBG_EEPROM,
3188 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3189 it, spot, offset, length);
3196 static int ar9300_compress_decision(struct ath_hw *ah,
3201 u8 *word, int length, int mdata_size)
3203 struct ath_common *common = ath9k_hw_common(ah);
3204 const struct ar9300_eeprom *eep = NULL;
3208 if (length != mdata_size) {
3209 ath_dbg(common, ATH_DBG_EEPROM,
3210 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3211 mdata_size, length);
3214 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
3215 ath_dbg(common, ATH_DBG_EEPROM,
3216 "restored eeprom %d: uncompressed, length %d\n",
3219 case _CompressBlock:
3220 if (reference == 0) {
3222 eep = ar9003_eeprom_struct_find_by_id(reference);
3224 ath_dbg(common, ATH_DBG_EEPROM,
3225 "can't find reference eeprom struct %d\n",
3229 memcpy(mptr, eep, mdata_size);
3231 ath_dbg(common, ATH_DBG_EEPROM,
3232 "restore eeprom %d: block, reference %d, length %d\n",
3233 it, reference, length);
3234 ar9300_uncompress_block(ah, mptr, mdata_size,
3235 (u8 *) (word + COMP_HDR_LEN), length);
3238 ath_dbg(common, ATH_DBG_EEPROM,
3239 "unknown compression code %d\n", code);
3245 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3248 static bool ar9300_check_header(void *data)
3251 return !(*word == 0 || *word == ~0);
3254 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3259 if (!read(ah, base_addr, header, 4))
3262 return ar9300_check_header(header);
3265 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3268 struct ath_common *common = ath9k_hw_common(ah);
3269 u16 *data = (u16 *) mptr;
3272 for (i = 0; i < mdata_size / 2; i++, data++)
3273 ath9k_hw_nvram_read(common, i, data);
3278 * Read the configuration data from the eeprom.
3279 * The data can be put in any specified memory buffer.
3281 * Returns -1 on error.
3282 * Returns address of next memory location on success.
3284 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3285 u8 *mptr, int mdata_size)
3292 int reference, length, major, minor;
3295 u16 checksum, mchecksum;
3296 struct ath_common *common = ath9k_hw_common(ah);
3297 eeprom_read_op read;
3299 if (ath9k_hw_use_flash(ah))
3300 return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3302 word = kzalloc(2048, GFP_KERNEL);
3306 memcpy(mptr, &ar9300_default, mdata_size);
3308 read = ar9300_read_eeprom;
3309 if (AR_SREV_9485(ah))
3310 cptr = AR9300_BASE_ADDR_4K;
3311 else if (AR_SREV_9330(ah))
3312 cptr = AR9300_BASE_ADDR_512;
3314 cptr = AR9300_BASE_ADDR;
3315 ath_dbg(common, ATH_DBG_EEPROM,
3316 "Trying EEPROM access at Address 0x%04x\n", cptr);
3317 if (ar9300_check_eeprom_header(ah, read, cptr))
3320 cptr = AR9300_BASE_ADDR_512;
3321 ath_dbg(common, ATH_DBG_EEPROM,
3322 "Trying EEPROM access at Address 0x%04x\n", cptr);
3323 if (ar9300_check_eeprom_header(ah, read, cptr))
3326 read = ar9300_read_otp;
3327 cptr = AR9300_BASE_ADDR;
3328 ath_dbg(common, ATH_DBG_EEPROM,
3329 "Trying OTP access at Address 0x%04x\n", cptr);
3330 if (ar9300_check_eeprom_header(ah, read, cptr))
3333 cptr = AR9300_BASE_ADDR_512;
3334 ath_dbg(common, ATH_DBG_EEPROM,
3335 "Trying OTP access at Address 0x%04x\n", cptr);
3336 if (ar9300_check_eeprom_header(ah, read, cptr))
3342 ath_dbg(common, ATH_DBG_EEPROM, "Found valid EEPROM data\n");
3344 for (it = 0; it < MSTATE; it++) {
3345 if (!read(ah, cptr, word, COMP_HDR_LEN))
3348 if (!ar9300_check_header(word))
3351 ar9300_comp_hdr_unpack(word, &code, &reference,
3352 &length, &major, &minor);
3353 ath_dbg(common, ATH_DBG_EEPROM,
3354 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3355 cptr, code, reference, length, major, minor);
3356 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3357 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3358 ath_dbg(common, ATH_DBG_EEPROM,
3359 "Skipping bad header\n");
3360 cptr -= COMP_HDR_LEN;
3365 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3366 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3367 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3368 ath_dbg(common, ATH_DBG_EEPROM,
3369 "checksum %x %x\n", checksum, mchecksum);
3370 if (checksum == mchecksum) {
3371 ar9300_compress_decision(ah, it, code, reference, mptr,
3372 word, length, mdata_size);
3374 ath_dbg(common, ATH_DBG_EEPROM,
3375 "skipping block with bad checksum\n");
3377 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3389 * Restore the configuration structure by reading the eeprom.
3390 * This function destroys any existing in-memory structure
3393 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3395 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3397 if (ar9300_eeprom_restore_internal(ah, mptr,
3398 sizeof(struct ar9300_eeprom)) < 0)
3404 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3405 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3406 struct ar9300_modal_eep_header *modal_hdr)
3408 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3409 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3410 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3411 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3412 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3413 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3414 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3415 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3416 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3417 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3418 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3419 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3420 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3421 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3422 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3423 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3424 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3425 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3426 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3427 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3428 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3429 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3430 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3431 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3432 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3433 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3434 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3435 PR_EEP("txClip", modal_hdr->txClip);
3436 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3437 PR_EEP("Chain0 ob", modal_hdr->ob[0]);
3438 PR_EEP("Chain1 ob", modal_hdr->ob[1]);
3439 PR_EEP("Chain2 ob", modal_hdr->ob[2]);
3441 PR_EEP("Chain0 db_stage2", modal_hdr->db_stage2[0]);
3442 PR_EEP("Chain1 db_stage2", modal_hdr->db_stage2[1]);
3443 PR_EEP("Chain2 db_stage2", modal_hdr->db_stage2[2]);
3444 PR_EEP("Chain0 db_stage3", modal_hdr->db_stage3[0]);
3445 PR_EEP("Chain1 db_stage3", modal_hdr->db_stage3[1]);
3446 PR_EEP("Chain2 db_stage3", modal_hdr->db_stage3[2]);
3447 PR_EEP("Chain0 db_stage4", modal_hdr->db_stage4[0]);
3448 PR_EEP("Chain1 db_stage4", modal_hdr->db_stage4[1]);
3449 PR_EEP("Chain2 db_stage4", modal_hdr->db_stage4[2]);
3454 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3455 u8 *buf, u32 len, u32 size)
3457 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3458 struct ar9300_base_eep_hdr *pBase;
3460 if (!dump_base_hdr) {
3461 len += snprintf(buf + len, size - len,
3462 "%20s :\n", "2GHz modal Header");
3463 len += ar9003_dump_modal_eeprom(buf, len, size,
3464 &eep->modalHeader2G);
3465 len += snprintf(buf + len, size - len,
3466 "%20s :\n", "5GHz modal Header");
3467 len += ar9003_dump_modal_eeprom(buf, len, size,
3468 &eep->modalHeader5G);
3472 pBase = &eep->baseEepHeader;
3474 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3475 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3476 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3477 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3478 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3479 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3480 AR5416_OPFLAGS_11A));
3481 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3482 AR5416_OPFLAGS_11G));
3483 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3484 AR5416_OPFLAGS_N_2G_HT20));
3485 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3486 AR5416_OPFLAGS_N_2G_HT40));
3487 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3488 AR5416_OPFLAGS_N_5G_HT20));
3489 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3490 AR5416_OPFLAGS_N_5G_HT40));
3491 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3492 PR_EEP("RF Silent", pBase->rfSilent);
3493 PR_EEP("BT option", pBase->blueToothOptions);
3494 PR_EEP("Device Cap", pBase->deviceCap);
3495 PR_EEP("Device Type", pBase->deviceType);
3496 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3497 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3498 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3499 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3500 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3501 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3502 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3503 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3504 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3505 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3506 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3507 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3508 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3509 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3510 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3511 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3512 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3513 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3515 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3516 ah->eeprom.ar9300_eep.macAddr);
3524 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3525 u8 *buf, u32 len, u32 size)
3531 /* XXX: review hardware docs */
3532 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3534 return ah->eeprom.ar9300_eep.eepromVersion;
3537 /* XXX: could be read from the eepromVersion, not sure yet */
3538 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3543 static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
3545 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3548 return eep->modalHeader2G.xpaBiasLvl;
3550 return eep->modalHeader5G.xpaBiasLvl;
3553 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3555 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
3557 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3558 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3559 else if (AR_SREV_9462(ah))
3560 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3562 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3563 REG_RMW_FIELD(ah, AR_CH0_THERM,
3564 AR_CH0_THERM_XPABIASLVL_MSB,
3566 REG_RMW_FIELD(ah, AR_CH0_THERM,
3567 AR_CH0_THERM_XPASHORT2GND, 1);
3571 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz)
3573 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3577 val = eep->modalHeader2G.switchcomspdt;
3579 val = eep->modalHeader5G.switchcomspdt;
3580 return le32_to_cpu(val);
3584 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3586 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3590 val = eep->modalHeader2G.antCtrlCommon;
3592 val = eep->modalHeader5G.antCtrlCommon;
3593 return le32_to_cpu(val);
3596 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3598 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3602 val = eep->modalHeader2G.antCtrlCommon2;
3604 val = eep->modalHeader5G.antCtrlCommon2;
3605 return le32_to_cpu(val);
3608 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
3612 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3615 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
3617 val = eep->modalHeader2G.antCtrlChain[chain];
3619 val = eep->modalHeader5G.antCtrlChain[chain];
3622 return le16_to_cpu(val);
3625 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3630 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3631 AR_PHY_SWITCH_CHAIN_0,
3632 AR_PHY_SWITCH_CHAIN_1,
3633 AR_PHY_SWITCH_CHAIN_2,
3636 if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0))
3637 ath9k_hw_cfg_output(ah, AR9300_EXT_LNA_CTL_GPIO_AR9485,
3638 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
3640 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3642 if (AR_SREV_9462(ah)) {
3643 if (AR_SREV_9462_10(ah)) {
3644 value &= ~AR_SWITCH_TABLE_COM_SPDT;
3645 value |= 0x00100000;
3647 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3648 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3650 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3651 AR_SWITCH_TABLE_COM_ALL, value);
3655 * AR9462 defines new switch table for BT/WLAN,
3656 * here's new field name in XXX.ref for both 2G and 5G.
3657 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3658 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3659 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3661 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3662 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3664 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3665 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3667 if (AR_SREV_9462_20_OR_LATER(ah)) {
3668 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3669 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3670 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3673 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3674 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3676 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3677 if ((ah->rxchainmask & BIT(chain)) ||
3678 (ah->txchainmask & BIT(chain))) {
3679 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3681 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3682 AR_SWITCH_TABLE_ALL, value);
3686 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3687 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3689 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3690 * are the fields present
3692 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3693 regval &= (~AR_ANT_DIV_CTRL_ALL);
3694 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3696 regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
3697 regval |= ((value >> 6) & 0x1) <<
3698 AR_PHY_9485_ANT_DIV_LNADIV_S;
3699 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3701 /*enable fast_div */
3702 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3703 regval &= (~AR_FAST_DIV_ENABLE);
3704 regval |= ((value >> 7) & 0x1) <<
3705 AR_FAST_DIV_ENABLE_S;
3706 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3708 ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
3709 /* check whether antenna diversity is enabled */
3710 if ((ant_div_ctl1 >> 0x6) == 0x3) {
3711 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3713 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3716 regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
3717 AR_PHY_9485_ANT_DIV_ALT_LNACONF |
3718 AR_PHY_9485_ANT_DIV_ALT_GAINTB |
3719 AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
3720 /* by default use LNA1 for the main antenna */
3721 regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
3722 AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
3723 regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
3724 AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
3725 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3733 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3738 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
3740 if (!drive_strength)
3743 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3751 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3753 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3764 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3766 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3771 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3774 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3775 struct ath9k_channel *chan)
3779 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3781 if (chain >= 0 && chain < 3) {
3782 if (IS_CHAN_2GHZ(chan))
3783 return eep->modalHeader2G.xatten1DB[chain];
3784 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3785 t[0] = eep->base_ext2.xatten1DBLow[chain];
3787 t[1] = eep->modalHeader5G.xatten1DB[chain];
3789 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3791 value = ar9003_hw_power_interpolate((s32) chan->channel,
3795 return eep->modalHeader5G.xatten1DB[chain];
3802 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3803 struct ath9k_channel *chan)
3807 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3809 if (chain >= 0 && chain < 3) {
3810 if (IS_CHAN_2GHZ(chan))
3811 return eep->modalHeader2G.xatten1Margin[chain];
3812 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3813 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3815 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3817 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3819 value = ar9003_hw_power_interpolate((s32) chan->channel,
3823 return eep->modalHeader5G.xatten1Margin[chain];
3829 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3833 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3834 AR_PHY_EXT_ATTEN_CTL_1,
3835 AR_PHY_EXT_ATTEN_CTL_2,
3838 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3839 for (i = 0; i < 3; i++) {
3840 if (ah->txchainmask & BIT(i)) {
3841 value = ar9003_hw_atten_chain_get(ah, i, chan);
3842 REG_RMW_FIELD(ah, ext_atten_reg[i],
3843 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3845 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3846 REG_RMW_FIELD(ah, ext_atten_reg[i],
3847 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3853 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3857 while (pmu_set != REG_READ(ah, pmu_reg)) {
3860 REG_WRITE(ah, pmu_reg, pmu_set);
3867 static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3869 int internal_regulator =
3870 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
3873 if (internal_regulator) {
3874 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3877 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3878 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3879 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3882 if (AR_SREV_9330(ah)) {
3883 if (ah->is_clk_25mhz) {
3884 reg_pmu_set = (3 << 1) | (8 << 4) |
3885 (3 << 8) | (1 << 14) |
3886 (6 << 17) | (1 << 20) |
3889 reg_pmu_set = (4 << 1) | (7 << 4) |
3890 (3 << 8) | (1 << 14) |
3891 (6 << 17) | (1 << 20) |
3895 reg_pmu_set = (5 << 1) | (7 << 4) |
3896 (2 << 8) | (2 << 14) |
3897 (6 << 17) | (1 << 20) |
3898 (3 << 24) | (1 << 28);
3901 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3902 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3905 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3907 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3908 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3911 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3913 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3914 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3916 } else if (AR_SREV_9462(ah)) {
3917 reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
3918 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3920 /* Internal regulator is ON. Write swreg register. */
3921 reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
3922 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3923 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3924 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3925 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3926 /* Set REG_CONTROL1.SWREG_PROGRAM */
3927 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3929 AR_RTC_REG_CONTROL1) |
3930 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3933 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3934 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3935 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3939 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3940 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3943 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3944 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3947 } else if (AR_SREV_9462(ah))
3948 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3950 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3951 AR_RTC_FORCE_SWREG_PRD;
3952 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3958 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3960 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3961 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3963 if (eep->baseEepHeader.featureEnable & 0x40) {
3964 tuning_caps_param &= 0x7f;
3965 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3967 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3972 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3973 struct ath9k_channel *chan)
3975 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
3976 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
3977 ar9003_hw_drive_strength_apply(ah);
3978 ar9003_hw_atten_apply(ah, chan);
3979 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah))
3980 ar9003_hw_internal_regulator_apply(ah);
3981 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3982 ar9003_hw_apply_tuning_caps(ah);
3985 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
3986 struct ath9k_channel *chan)
3991 * Returns the interpolated y value corresponding to the specified x value
3992 * from the np ordered pairs of data (px,py).
3993 * The pairs do not have to be in any order.
3994 * If the specified x value is less than any of the px,
3995 * the returned y value is equal to the py for the lowest px.
3996 * If the specified x value is greater than any of the px,
3997 * the returned y value is equal to the py for the highest px.
3999 static int ar9003_hw_power_interpolate(int32_t x,
4000 int32_t *px, int32_t *py, u_int16_t np)
4003 int lx = 0, ly = 0, lhave = 0;
4004 int hx = 0, hy = 0, hhave = 0;
4011 /* identify best lower and higher x calibration measurement */
4012 for (ip = 0; ip < np; ip++) {
4015 /* this measurement is higher than our desired x */
4017 if (!hhave || dx > (x - hx)) {
4018 /* new best higher x measurement */
4024 /* this measurement is lower than our desired x */
4026 if (!lhave || dx < (x - lx)) {
4027 /* new best lower x measurement */
4035 /* the low x is good */
4037 /* so is the high x */
4039 /* they're the same, so just pick one */
4042 else /* interpolate */
4043 y = interpolate(x, lx, hx, ly, hy);
4044 } else /* only low is good, use it */
4046 } else if (hhave) /* only high is good, use it */
4048 else /* nothing is good,this should never happen unless np=0, ???? */
4053 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4054 u16 rateIndex, u16 freq, bool is2GHz)
4057 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4058 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4059 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4060 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4064 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4065 pEepromTargetPwr = eep->calTargetPower2G;
4066 pFreqBin = eep->calTarget_freqbin_2G;
4068 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4069 pEepromTargetPwr = eep->calTargetPower5G;
4070 pFreqBin = eep->calTarget_freqbin_5G;
4074 * create array of channels and targetpower from
4075 * targetpower piers stored on eeprom
4077 for (i = 0; i < numPiers; i++) {
4078 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
4079 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4082 /* interpolate to get target power for given frequency */
4083 return (u8) ar9003_hw_power_interpolate((s32) freq,
4085 targetPowerArray, numPiers);
4088 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4090 u16 freq, bool is2GHz)
4093 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4094 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4095 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4096 struct cal_tgt_pow_ht *pEepromTargetPwr;
4100 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4101 pEepromTargetPwr = eep->calTargetPower2GHT20;
4102 pFreqBin = eep->calTarget_freqbin_2GHT20;
4104 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4105 pEepromTargetPwr = eep->calTargetPower5GHT20;
4106 pFreqBin = eep->calTarget_freqbin_5GHT20;
4110 * create array of channels and targetpower
4111 * from targetpower piers stored on eeprom
4113 for (i = 0; i < numPiers; i++) {
4114 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
4115 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4118 /* interpolate to get target power for given frequency */
4119 return (u8) ar9003_hw_power_interpolate((s32) freq,
4121 targetPowerArray, numPiers);
4124 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4126 u16 freq, bool is2GHz)
4129 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4130 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4131 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4132 struct cal_tgt_pow_ht *pEepromTargetPwr;
4136 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4137 pEepromTargetPwr = eep->calTargetPower2GHT40;
4138 pFreqBin = eep->calTarget_freqbin_2GHT40;
4140 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4141 pEepromTargetPwr = eep->calTargetPower5GHT40;
4142 pFreqBin = eep->calTarget_freqbin_5GHT40;
4146 * create array of channels and targetpower from
4147 * targetpower piers stored on eeprom
4149 for (i = 0; i < numPiers; i++) {
4150 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
4151 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4154 /* interpolate to get target power for given frequency */
4155 return (u8) ar9003_hw_power_interpolate((s32) freq,
4157 targetPowerArray, numPiers);
4160 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4161 u16 rateIndex, u16 freq)
4163 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4164 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4165 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4166 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4167 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4168 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4171 * create array of channels and targetpower from
4172 * targetpower piers stored on eeprom
4174 for (i = 0; i < numPiers; i++) {
4175 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
4176 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4179 /* interpolate to get target power for given frequency */
4180 return (u8) ar9003_hw_power_interpolate((s32) freq,
4182 targetPowerArray, numPiers);
4185 /* Set tx power registers to array of values passed in */
4186 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4188 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4189 /* make sure forced gain is not set */
4190 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4192 /* Write the OFDM power per rate set */
4194 /* 6 (LSB), 9, 12, 18 (MSB) */
4195 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4196 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4197 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4198 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4199 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4201 /* 24 (LSB), 36, 48, 54 (MSB) */
4202 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4203 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4204 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4205 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4206 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4208 /* Write the CCK power per rate set */
4210 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4211 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4212 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4213 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4214 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4215 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4217 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4218 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4219 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4220 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4221 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4222 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4225 /* Write the power for duplicated frames - HT40 */
4227 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4228 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4229 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4230 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4231 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4232 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4235 /* Write the HT20 power per rate set */
4237 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4238 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4239 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4240 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4241 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4242 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4245 /* 6 (LSB), 7, 12, 13 (MSB) */
4246 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4247 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4248 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4249 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4250 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4253 /* 14 (LSB), 15, 20, 21 */
4254 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4255 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4256 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4257 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4258 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4261 /* Mixed HT20 and HT40 rates */
4263 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4264 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4265 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4266 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4267 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4268 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4272 * Write the HT40 power per rate set
4273 * correct PAR difference between HT40 and HT20/LEGACY
4274 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4276 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4277 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4278 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4279 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4280 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4283 /* 6 (LSB), 7, 12, 13 (MSB) */
4284 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4285 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4286 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4287 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4288 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4291 /* 14 (LSB), 15, 20, 21 */
4292 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4293 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4294 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4295 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4296 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4303 static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
4304 u8 *targetPowerValT2)
4306 /* XXX: hard code for now, need to get from eeprom struct */
4307 u8 ht40PowerIncForPdadc = 0;
4308 bool is2GHz = false;
4310 struct ath_common *common = ath9k_hw_common(ah);
4315 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4316 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4318 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4319 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4321 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4322 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4324 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4325 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4327 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4328 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4330 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4331 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4332 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4333 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4334 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4335 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4336 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4337 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4339 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4340 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4342 targetPowerValT2[ALL_TARGET_HT20_4] =
4343 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4345 targetPowerValT2[ALL_TARGET_HT20_5] =
4346 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4348 targetPowerValT2[ALL_TARGET_HT20_6] =
4349 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4351 targetPowerValT2[ALL_TARGET_HT20_7] =
4352 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4354 targetPowerValT2[ALL_TARGET_HT20_12] =
4355 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4357 targetPowerValT2[ALL_TARGET_HT20_13] =
4358 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4360 targetPowerValT2[ALL_TARGET_HT20_14] =
4361 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4363 targetPowerValT2[ALL_TARGET_HT20_15] =
4364 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4366 targetPowerValT2[ALL_TARGET_HT20_20] =
4367 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4369 targetPowerValT2[ALL_TARGET_HT20_21] =
4370 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4372 targetPowerValT2[ALL_TARGET_HT20_22] =
4373 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4375 targetPowerValT2[ALL_TARGET_HT20_23] =
4376 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4378 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4379 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4380 is2GHz) + ht40PowerIncForPdadc;
4381 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4382 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4384 is2GHz) + ht40PowerIncForPdadc;
4385 targetPowerValT2[ALL_TARGET_HT40_4] =
4386 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4387 is2GHz) + ht40PowerIncForPdadc;
4388 targetPowerValT2[ALL_TARGET_HT40_5] =
4389 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4390 is2GHz) + ht40PowerIncForPdadc;
4391 targetPowerValT2[ALL_TARGET_HT40_6] =
4392 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4393 is2GHz) + ht40PowerIncForPdadc;
4394 targetPowerValT2[ALL_TARGET_HT40_7] =
4395 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4396 is2GHz) + ht40PowerIncForPdadc;
4397 targetPowerValT2[ALL_TARGET_HT40_12] =
4398 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4399 is2GHz) + ht40PowerIncForPdadc;
4400 targetPowerValT2[ALL_TARGET_HT40_13] =
4401 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4402 is2GHz) + ht40PowerIncForPdadc;
4403 targetPowerValT2[ALL_TARGET_HT40_14] =
4404 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4405 is2GHz) + ht40PowerIncForPdadc;
4406 targetPowerValT2[ALL_TARGET_HT40_15] =
4407 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4408 is2GHz) + ht40PowerIncForPdadc;
4409 targetPowerValT2[ALL_TARGET_HT40_20] =
4410 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4411 is2GHz) + ht40PowerIncForPdadc;
4412 targetPowerValT2[ALL_TARGET_HT40_21] =
4413 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4414 is2GHz) + ht40PowerIncForPdadc;
4415 targetPowerValT2[ALL_TARGET_HT40_22] =
4416 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4417 is2GHz) + ht40PowerIncForPdadc;
4418 targetPowerValT2[ALL_TARGET_HT40_23] =
4419 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4420 is2GHz) + ht40PowerIncForPdadc;
4422 for (i = 0; i < ar9300RateSize; i++) {
4423 ath_dbg(common, ATH_DBG_EEPROM,
4424 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
4428 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4434 int *ptemperature, int *pvoltage)
4437 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4439 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4440 struct ath_common *common = ath9k_hw_common(ah);
4442 if (ichain >= AR9300_MAX_CHAINS) {
4443 ath_dbg(common, ATH_DBG_EEPROM,
4444 "Invalid chain index, must be less than %d\n",
4449 if (mode) { /* 5GHz */
4450 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4451 ath_dbg(common, ATH_DBG_EEPROM,
4452 "Invalid 5GHz cal pier index, must be less than %d\n",
4453 AR9300_NUM_5G_CAL_PIERS);
4456 pCalPier = &(eep->calFreqPier5G[ipier]);
4457 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4460 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4461 ath_dbg(common, ATH_DBG_EEPROM,
4462 "Invalid 2GHz cal pier index, must be less than %d\n",
4463 AR9300_NUM_2G_CAL_PIERS);
4467 pCalPier = &(eep->calFreqPier2G[ipier]);
4468 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4472 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
4473 *pcorrection = pCalPierStruct->refPower;
4474 *ptemperature = pCalPierStruct->tempMeas;
4475 *pvoltage = pCalPierStruct->voltMeas;
4480 static int ar9003_hw_power_control_override(struct ath_hw *ah,
4483 int *voltage, int *temperature)
4486 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4489 REG_RMW(ah, AR_PHY_TPC_11_B0,
4490 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4491 AR_PHY_TPC_OLPC_GAIN_DELTA);
4492 if (ah->caps.tx_chainmask & BIT(1))
4493 REG_RMW(ah, AR_PHY_TPC_11_B1,
4494 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4495 AR_PHY_TPC_OLPC_GAIN_DELTA);
4496 if (ah->caps.tx_chainmask & BIT(2))
4497 REG_RMW(ah, AR_PHY_TPC_11_B2,
4498 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4499 AR_PHY_TPC_OLPC_GAIN_DELTA);
4501 /* enable open loop power control on chip */
4502 REG_RMW(ah, AR_PHY_TPC_6_B0,
4503 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4504 AR_PHY_TPC_6_ERROR_EST_MODE);
4505 if (ah->caps.tx_chainmask & BIT(1))
4506 REG_RMW(ah, AR_PHY_TPC_6_B1,
4507 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4508 AR_PHY_TPC_6_ERROR_EST_MODE);
4509 if (ah->caps.tx_chainmask & BIT(2))
4510 REG_RMW(ah, AR_PHY_TPC_6_B2,
4511 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4512 AR_PHY_TPC_6_ERROR_EST_MODE);
4515 * enable temperature compensation
4516 * Need to use register names
4518 if (frequency < 4000)
4519 tempSlope = eep->modalHeader2G.tempSlope;
4520 else if (eep->base_ext2.tempSlopeLow != 0) {
4521 t[0] = eep->base_ext2.tempSlopeLow;
4523 t[1] = eep->modalHeader5G.tempSlope;
4525 t[2] = eep->base_ext2.tempSlopeHigh;
4527 tempSlope = ar9003_hw_power_interpolate((s32) frequency,
4530 tempSlope = eep->modalHeader5G.tempSlope;
4532 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
4534 if (AR_SREV_9462_20(ah))
4535 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4536 AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope);
4539 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4545 /* Apply the recorded correction values. */
4546 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4548 int ichain, ipier, npier;
4550 int lfrequency[AR9300_MAX_CHAINS],
4551 lcorrection[AR9300_MAX_CHAINS],
4552 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4553 int hfrequency[AR9300_MAX_CHAINS],
4554 hcorrection[AR9300_MAX_CHAINS],
4555 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4557 int correction[AR9300_MAX_CHAINS],
4558 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4559 int pfrequency, pcorrection, ptemperature, pvoltage;
4560 struct ath_common *common = ath9k_hw_common(ah);
4562 mode = (frequency >= 4000);
4564 npier = AR9300_NUM_5G_CAL_PIERS;
4566 npier = AR9300_NUM_2G_CAL_PIERS;
4568 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4569 lfrequency[ichain] = 0;
4570 hfrequency[ichain] = 100000;
4572 /* identify best lower and higher frequency calibration measurement */
4573 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4574 for (ipier = 0; ipier < npier; ipier++) {
4575 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4576 &pfrequency, &pcorrection,
4577 &ptemperature, &pvoltage)) {
4578 fdiff = frequency - pfrequency;
4581 * this measurement is higher than
4582 * our desired frequency
4585 if (hfrequency[ichain] <= 0 ||
4586 hfrequency[ichain] >= 100000 ||
4588 (frequency - hfrequency[ichain])) {
4591 * frequency measurement
4593 hfrequency[ichain] = pfrequency;
4594 hcorrection[ichain] =
4596 htemperature[ichain] =
4598 hvoltage[ichain] = pvoltage;
4602 if (lfrequency[ichain] <= 0
4604 (frequency - lfrequency[ichain])) {
4607 * frequency measurement
4609 lfrequency[ichain] = pfrequency;
4610 lcorrection[ichain] =
4612 ltemperature[ichain] =
4614 lvoltage[ichain] = pvoltage;
4622 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4623 ath_dbg(common, ATH_DBG_EEPROM,
4624 "ch=%d f=%d low=%d %d h=%d %d\n",
4625 ichain, frequency, lfrequency[ichain],
4626 lcorrection[ichain], hfrequency[ichain],
4627 hcorrection[ichain]);
4628 /* they're the same, so just pick one */
4629 if (hfrequency[ichain] == lfrequency[ichain]) {
4630 correction[ichain] = lcorrection[ichain];
4631 voltage[ichain] = lvoltage[ichain];
4632 temperature[ichain] = ltemperature[ichain];
4634 /* the low frequency is good */
4635 else if (frequency - lfrequency[ichain] < 1000) {
4636 /* so is the high frequency, interpolate */
4637 if (hfrequency[ichain] - frequency < 1000) {
4639 correction[ichain] = interpolate(frequency,
4642 lcorrection[ichain],
4643 hcorrection[ichain]);
4645 temperature[ichain] = interpolate(frequency,
4648 ltemperature[ichain],
4649 htemperature[ichain]);
4651 voltage[ichain] = interpolate(frequency,
4657 /* only low is good, use it */
4659 correction[ichain] = lcorrection[ichain];
4660 temperature[ichain] = ltemperature[ichain];
4661 voltage[ichain] = lvoltage[ichain];
4664 /* only high is good, use it */
4665 else if (hfrequency[ichain] - frequency < 1000) {
4666 correction[ichain] = hcorrection[ichain];
4667 temperature[ichain] = htemperature[ichain];
4668 voltage[ichain] = hvoltage[ichain];
4669 } else { /* nothing is good, presume 0???? */
4670 correction[ichain] = 0;
4671 temperature[ichain] = 0;
4672 voltage[ichain] = 0;
4676 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4679 ath_dbg(common, ATH_DBG_EEPROM,
4680 "for frequency=%d, calibration correction = %d %d %d\n",
4681 frequency, correction[0], correction[1], correction[2]);
4686 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4691 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4692 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4695 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4697 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4700 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4706 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4707 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4709 u8 *ctl_freqbin = is2GHz ?
4710 &eep->ctl_freqbin_2G[idx][0] :
4711 &eep->ctl_freqbin_5G[idx][0];
4714 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4715 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4716 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4718 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4719 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4720 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4723 return MAX_RATE_POWER;
4727 * Find the maximum conformance test limit for the given channel and CTL info
4729 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4730 u16 freq, int idx, bool is2GHz)
4732 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4733 u8 *ctl_freqbin = is2GHz ?
4734 &eep->ctl_freqbin_2G[idx][0] :
4735 &eep->ctl_freqbin_5G[idx][0];
4736 u16 num_edges = is2GHz ?
4737 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4740 /* Get the edge power */
4742 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
4745 * If there's an exact channel match or an inband flag set
4746 * on the lower channel use the given rdEdgePower
4748 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
4750 ar9003_hw_get_direct_edge_power(eep, idx,
4753 } else if ((edge > 0) &&
4754 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
4757 ar9003_hw_get_indirect_edge_power(eep, idx,
4761 * Leave loop - no more affecting edges possible in
4762 * this monotonic increasing list
4767 return twiceMaxEdgePower;
4770 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4771 struct ath9k_channel *chan,
4772 u8 *pPwrArray, u16 cfgCtl,
4773 u8 antenna_reduction,
4776 struct ath_common *common = ath9k_hw_common(ah);
4777 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4778 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4780 u16 scaledPower = 0, minCtlPower;
4781 static const u16 ctlModesFor11a[] = {
4782 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4784 static const u16 ctlModesFor11g[] = {
4785 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
4786 CTL_11G_EXT, CTL_2GHT40
4789 const u16 *pCtlMode;
4791 struct chan_centers centers;
4794 u16 twiceMinEdgePower;
4795 bool is2ghz = IS_CHAN_2GHZ(chan);
4797 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4798 scaledPower = powerLimit - antenna_reduction;
4801 * Reduce scaled Power by number of chains active to get
4802 * to per chain tx power level
4804 switch (ar5416_get_ntxchains(ah->txchainmask)) {
4808 if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
4809 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
4814 if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
4815 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
4821 scaledPower = max((u16)0, scaledPower);
4824 * Get target powers from EEPROM - our baseline for TX Power
4827 /* Setup for CTL modes */
4828 /* CTL_11B, CTL_11G, CTL_2GHT20 */
4830 ARRAY_SIZE(ctlModesFor11g) -
4831 SUB_NUM_CTL_MODES_AT_2G_40;
4832 pCtlMode = ctlModesFor11g;
4833 if (IS_CHAN_HT40(chan))
4835 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4837 /* Setup for CTL modes */
4838 /* CTL_11A, CTL_5GHT20 */
4839 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
4840 SUB_NUM_CTL_MODES_AT_5G_40;
4841 pCtlMode = ctlModesFor11a;
4842 if (IS_CHAN_HT40(chan))
4844 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4848 * For MIMO, need to apply regulatory caps individually across
4849 * dynamically running modes: CCK, OFDM, HT20, HT40
4851 * The outer loop walks through each possible applicable runtime mode.
4852 * The inner loop walks through each ctlIndex entry in EEPROM.
4853 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
4855 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4856 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
4857 (pCtlMode[ctlMode] == CTL_2GHT40);
4859 freq = centers.synth_center;
4860 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4861 freq = centers.ext_center;
4863 freq = centers.ctl_center;
4865 ath_dbg(common, ATH_DBG_REGULATORY,
4866 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
4867 ctlMode, numCtlModes, isHt40CtlMode,
4868 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4870 /* walk through each CTL index stored in EEPROM */
4872 ctlIndex = pEepData->ctlIndex_2G;
4873 ctlNum = AR9300_NUM_CTLS_2G;
4875 ctlIndex = pEepData->ctlIndex_5G;
4876 ctlNum = AR9300_NUM_CTLS_5G;
4879 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
4880 ath_dbg(common, ATH_DBG_REGULATORY,
4881 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
4882 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
4886 * compare test group from regulatory
4887 * channel list with test mode from pCtlMode
4890 if ((((cfgCtl & ~CTL_MODE_M) |
4891 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4893 (((cfgCtl & ~CTL_MODE_M) |
4894 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4895 ((ctlIndex[i] & CTL_MODE_M) |
4898 ar9003_hw_get_max_edge_power(pEepData,
4902 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
4904 * Find the minimum of all CTL
4905 * edge powers that apply to
4909 min(twiceMaxEdgePower,
4920 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
4922 ath_dbg(common, ATH_DBG_REGULATORY,
4923 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
4924 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4925 scaledPower, minCtlPower);
4927 /* Apply ctl mode to correct target power set */
4928 switch (pCtlMode[ctlMode]) {
4930 for (i = ALL_TARGET_LEGACY_1L_5L;
4931 i <= ALL_TARGET_LEGACY_11S; i++)
4933 (u8)min((u16)pPwrArray[i],
4938 for (i = ALL_TARGET_LEGACY_6_24;
4939 i <= ALL_TARGET_LEGACY_54; i++)
4941 (u8)min((u16)pPwrArray[i],
4946 for (i = ALL_TARGET_HT20_0_8_16;
4947 i <= ALL_TARGET_HT20_21; i++)
4949 (u8)min((u16)pPwrArray[i],
4951 pPwrArray[ALL_TARGET_HT20_22] =
4952 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
4954 pPwrArray[ALL_TARGET_HT20_23] =
4955 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
4960 for (i = ALL_TARGET_HT40_0_8_16;
4961 i <= ALL_TARGET_HT40_23; i++)
4963 (u8)min((u16)pPwrArray[i],
4969 } /* end ctl mode checking */
4972 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
4974 u8 mod_idx = mcs_idx % 8;
4977 return mod_idx ? (base_pwridx + 1) : base_pwridx;
4979 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
4982 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4983 struct ath9k_channel *chan, u16 cfgCtl,
4984 u8 twiceAntennaReduction,
4985 u8 powerLimit, bool test)
4987 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4988 struct ath_common *common = ath9k_hw_common(ah);
4989 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4990 struct ar9300_modal_eep_header *modal_hdr;
4991 u8 targetPowerValT2[ar9300RateSize];
4992 u8 target_power_val_t2_eep[ar9300RateSize];
4993 unsigned int i = 0, paprd_scale_factor = 0;
4994 u8 pwr_idx, min_pwridx = 0;
4996 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
4998 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
4999 if (IS_CHAN_2GHZ(chan))
5000 modal_hdr = &eep->modalHeader2G;
5002 modal_hdr = &eep->modalHeader5G;
5004 ah->paprd_ratemask =
5005 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5006 AR9300_PAPRD_RATE_MASK;
5008 ah->paprd_ratemask_ht40 =
5009 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5010 AR9300_PAPRD_RATE_MASK;
5012 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5013 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5014 ALL_TARGET_HT20_0_8_16;
5016 if (!ah->paprd_table_write_done) {
5017 memcpy(target_power_val_t2_eep, targetPowerValT2,
5018 sizeof(targetPowerValT2));
5019 for (i = 0; i < 24; i++) {
5020 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5021 if (ah->paprd_ratemask & (1 << i)) {
5022 if (targetPowerValT2[pwr_idx] &&
5023 targetPowerValT2[pwr_idx] ==
5024 target_power_val_t2_eep[pwr_idx])
5025 targetPowerValT2[pwr_idx] -=
5030 memcpy(target_power_val_t2_eep, targetPowerValT2,
5031 sizeof(targetPowerValT2));
5034 ar9003_hw_set_power_per_rate_table(ah, chan,
5035 targetPowerValT2, cfgCtl,
5036 twiceAntennaReduction,
5039 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
5040 for (i = 0; i < ar9300RateSize; i++) {
5041 if ((ah->paprd_ratemask & (1 << i)) &&
5042 (abs(targetPowerValT2[i] -
5043 target_power_val_t2_eep[i]) >
5044 paprd_scale_factor)) {
5045 ah->paprd_ratemask &= ~(1 << i);
5046 ath_dbg(common, ATH_DBG_EEPROM,
5047 "paprd disabled for mcs %d\n", i);
5052 regulatory->max_power_level = 0;
5053 for (i = 0; i < ar9300RateSize; i++) {
5054 if (targetPowerValT2[i] > regulatory->max_power_level)
5055 regulatory->max_power_level = targetPowerValT2[i];
5061 for (i = 0; i < ar9300RateSize; i++) {
5062 ath_dbg(common, ATH_DBG_EEPROM,
5063 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
5066 ah->txpower_limit = regulatory->max_power_level;
5068 /* Write target power array to registers */
5069 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5070 ar9003_hw_calibration_apply(ah, chan->channel);
5072 if (IS_CHAN_2GHZ(chan)) {
5073 if (IS_CHAN_HT40(chan))
5074 i = ALL_TARGET_HT40_0_8_16;
5076 i = ALL_TARGET_HT20_0_8_16;
5078 if (IS_CHAN_HT40(chan))
5079 i = ALL_TARGET_HT40_7;
5081 i = ALL_TARGET_HT20_7;
5083 ah->paprd_target_power = targetPowerValT2[i];
5086 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5092 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5094 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5096 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5099 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5101 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5103 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5106 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz)
5108 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5111 return eep->modalHeader2G.spurChans;
5113 return eep->modalHeader5G.spurChans;
5116 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5117 struct ath9k_channel *chan)
5119 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5121 if (IS_CHAN_2GHZ(chan))
5122 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5123 AR9300_PAPRD_SCALE_1);
5125 if (chan->channel >= 5700)
5126 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5127 AR9300_PAPRD_SCALE_1);
5128 else if (chan->channel >= 5400)
5129 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5130 AR9300_PAPRD_SCALE_2);
5132 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5133 AR9300_PAPRD_SCALE_1);
5137 const struct eeprom_ops eep_ar9300_ops = {
5138 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5139 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5140 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5141 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5142 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5143 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5144 .set_board_values = ath9k_hw_ar9300_set_board_values,
5145 .set_addac = ath9k_hw_ar9300_set_addac,
5146 .set_txpower = ath9k_hw_ar9300_set_txpower,
5147 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel