2 * Copyright (c) 2010 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.
18 #include "ar9003_phy.h"
19 #include "ar9003_eeprom.h"
21 #define COMP_HDR_LEN 4
22 #define COMP_CKSUM_LEN 2
24 #define AR_CH0_TOP (0x00016288)
25 #define AR_CH0_TOP_XPABIASLVL (0x300)
26 #define AR_CH0_TOP_XPABIASLVL_S (8)
28 #define AR_CH0_THERM (0x00016290)
29 #define AR_CH0_THERM_XPABIASLVL_MSB 0x3
30 #define AR_CH0_THERM_XPABIASLVL_MSB_S 0
31 #define AR_CH0_THERM_XPASHORT2GND 0x4
32 #define AR_CH0_THERM_XPASHORT2GND_S 2
34 #define AR_SWITCH_TABLE_COM_ALL (0xffff)
35 #define AR_SWITCH_TABLE_COM_ALL_S (0)
37 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
38 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
40 #define AR_SWITCH_TABLE_ALL (0xfff)
41 #define AR_SWITCH_TABLE_ALL_S (0)
43 #define LE16(x) __constant_cpu_to_le16(x)
44 #define LE32(x) __constant_cpu_to_le32(x)
46 /* Local defines to distinguish between extension and control CTL's */
47 #define EXT_ADDITIVE (0x8000)
48 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
49 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
50 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
51 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
52 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
53 #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */
54 #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */
55 #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */
57 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
58 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
60 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
62 static int ar9003_hw_power_interpolate(int32_t x,
63 int32_t *px, int32_t *py, u_int16_t np);
65 static const struct ar9300_eeprom ar9300_default = {
68 .macAddr = {1, 2, 3, 4, 5, 6},
69 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
72 .regDmn = { LE16(0), LE16(0x1f) },
73 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
75 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
79 .blueToothOptions = 0,
81 .deviceType = 5, /* takes lower byte in eeprom location */
82 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
83 .params_for_tuning_caps = {0, 0},
84 .featureEnable = 0x0c,
86 * bit0 - enable tx temp comp - disabled
87 * bit1 - enable tx volt comp - disabled
88 * bit2 - enable fastClock - enabled
89 * bit3 - enable doubling - enabled
90 * bit4 - enable internal regulator - disabled
91 * bit5 - enable pa predistortion - disabled
93 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
94 .eepromWriteEnableGpio = 3,
97 .rxBandSelectGpio = 0xff,
102 /* ar9300_modal_eep_header 2g */
103 /* 4 idle,t1,t2,b(4 bits per setting) */
104 .antCtrlCommon = LE32(0x110),
105 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
106 .antCtrlCommon2 = LE32(0x22222),
109 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
110 * rx1, rx12, b (2 bits each)
112 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
115 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
116 * for ar9280 (0xa20c/b20c 5:0)
118 .xatten1DB = {0, 0, 0},
121 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
122 * for ar9280 (0xa20c/b20c 16:12
124 .xatten1Margin = {0, 0, 0},
129 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
130 * channels in usual fbin coding format
132 .spurChans = {0, 0, 0, 0, 0},
135 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
136 * if the register is per chain
138 .noiseFloorThreshCh = {-1, 0, 0},
139 .ob = {1, 1, 1},/* 3 chain */
140 .db_stage2 = {1, 1, 1}, /* 3 chain */
141 .db_stage3 = {0, 0, 0},
142 .db_stage4 = {0, 0, 0},
144 .txFrameToDataStart = 0x0e,
145 .txFrameToPaOn = 0x0e,
146 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
148 .switchSettling = 0x2c,
149 .adcDesiredSize = -30,
152 .txFrameToXpaOn = 0xe,
154 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
155 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
157 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
161 .ant_div_control = 0,
162 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
169 /* ar9300_cal_data_per_freq_op_loop 2g */
171 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
172 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
173 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
175 .calTarget_freqbin_Cck = {
179 .calTarget_freqbin_2G = {
184 .calTarget_freqbin_2GHT20 = {
189 .calTarget_freqbin_2GHT40 = {
194 .calTargetPowerCck = {
195 /* 1L-5L,5S,11L,11S */
196 { {36, 36, 36, 36} },
197 { {36, 36, 36, 36} },
199 .calTargetPower2G = {
201 { {32, 32, 28, 24} },
202 { {32, 32, 28, 24} },
203 { {32, 32, 28, 24} },
205 .calTargetPower2GHT20 = {
206 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
207 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
208 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
210 .calTargetPower2GHT40 = {
211 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
212 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
213 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
216 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
217 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
247 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
248 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
249 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
250 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
254 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
255 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
256 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
261 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
262 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
268 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
269 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
270 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
271 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
275 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
276 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
277 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
281 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
282 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
283 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
288 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
289 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
290 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
295 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
296 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
297 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
298 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
302 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
303 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
304 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
306 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
307 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
308 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
310 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
311 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
312 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
314 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
315 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
316 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
319 /* 4 idle,t1,t2,b (4 bits per setting) */
320 .antCtrlCommon = LE32(0x110),
321 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
322 .antCtrlCommon2 = LE32(0x22222),
323 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
325 LE16(0x000), LE16(0x000), LE16(0x000),
327 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
328 .xatten1DB = {0, 0, 0},
331 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
332 * for merlin (0xa20c/b20c 16:12
334 .xatten1Margin = {0, 0, 0},
337 /* spurChans spur channels in usual fbin coding format */
338 .spurChans = {0, 0, 0, 0, 0},
339 /* noiseFloorThreshCh Check if the register is per chain */
340 .noiseFloorThreshCh = {-1, 0, 0},
341 .ob = {3, 3, 3}, /* 3 chain */
342 .db_stage2 = {3, 3, 3}, /* 3 chain */
343 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
344 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
346 .txFrameToDataStart = 0x0e,
347 .txFrameToPaOn = 0x0e,
348 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
350 .switchSettling = 0x2d,
351 .adcDesiredSize = -30,
354 .txFrameToXpaOn = 0xe,
356 .papdRateMaskHt20 = LE32(0x0c80c080),
357 .papdRateMaskHt40 = LE32(0x0080c080),
359 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
365 .xatten1DBLow = {0, 0, 0},
366 .xatten1MarginLow = {0, 0, 0},
367 .xatten1DBHigh = {0, 0, 0},
368 .xatten1MarginHigh = {0, 0, 0}
413 .calTarget_freqbin_5G = {
423 .calTarget_freqbin_5GHT20 = {
433 .calTarget_freqbin_5GHT40 = {
443 .calTargetPower5G = {
445 { {20, 20, 20, 10} },
446 { {20, 20, 20, 10} },
447 { {20, 20, 20, 10} },
448 { {20, 20, 20, 10} },
449 { {20, 20, 20, 10} },
450 { {20, 20, 20, 10} },
451 { {20, 20, 20, 10} },
452 { {20, 20, 20, 10} },
454 .calTargetPower5GHT20 = {
456 * 0_8_16,1-3_9-11_17-19,
457 * 4,5,6,7,12,13,14,15,20,21,22,23
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} },
466 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
468 .calTargetPower5GHT40 = {
470 * 0_8_16,1-3_9-11_17-19,
471 * 4,5,6,7,12,13,14,15,20,21,22,23
473 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
474 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
475 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
476 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
477 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
478 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
479 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
480 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
483 0x10, 0x16, 0x18, 0x40, 0x46,
484 0x48, 0x30, 0x36, 0x38
488 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
489 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
490 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
491 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
492 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
493 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
494 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
495 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
498 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
499 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
500 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
501 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
502 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
503 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
504 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
505 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
509 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
510 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
511 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
512 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
513 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
514 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
515 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
516 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
520 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
521 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
522 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
523 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
524 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
525 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
526 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
527 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
531 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
532 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
533 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
534 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
535 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
536 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
537 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
538 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
542 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
543 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
544 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
545 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
546 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
547 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
548 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
549 /* Data[5].ctlEdges[7].bChannel */ 0xFF
553 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
554 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
555 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
556 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
557 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
558 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
559 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
560 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
564 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
565 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
566 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
567 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
568 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
569 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
570 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
571 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
575 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
576 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
577 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
578 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
579 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
580 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
581 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
582 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
588 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
589 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
594 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
595 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
600 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
601 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
606 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
607 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
612 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
613 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
618 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
619 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
624 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
625 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
630 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
631 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
636 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
637 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
643 static const struct ar9300_eeprom ar9300_x113 = {
645 .templateVersion = 6,
646 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
647 .custData = {"x113-023-f0000"},
649 .regDmn = { LE16(0), LE16(0x1f) },
650 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
652 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
656 .blueToothOptions = 0,
658 .deviceType = 5, /* takes lower byte in eeprom location */
659 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
660 .params_for_tuning_caps = {0, 0},
661 .featureEnable = 0x0d,
663 * bit0 - enable tx temp comp - disabled
664 * bit1 - enable tx volt comp - disabled
665 * bit2 - enable fastClock - enabled
666 * bit3 - enable doubling - enabled
667 * bit4 - enable internal regulator - disabled
668 * bit5 - enable pa predistortion - disabled
670 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
671 .eepromWriteEnableGpio = 6,
672 .wlanDisableGpio = 0,
674 .rxBandSelectGpio = 0xff,
679 /* ar9300_modal_eep_header 2g */
680 /* 4 idle,t1,t2,b(4 bits per setting) */
681 .antCtrlCommon = LE32(0x110),
682 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
683 .antCtrlCommon2 = LE32(0x44444),
686 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
687 * rx1, rx12, b (2 bits each)
689 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
692 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
693 * for ar9280 (0xa20c/b20c 5:0)
695 .xatten1DB = {0, 0, 0},
698 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
699 * for ar9280 (0xa20c/b20c 16:12
701 .xatten1Margin = {0, 0, 0},
706 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
707 * channels in usual fbin coding format
709 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
712 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
713 * if the register is per chain
715 .noiseFloorThreshCh = {-1, 0, 0},
716 .ob = {1, 1, 1},/* 3 chain */
717 .db_stage2 = {1, 1, 1}, /* 3 chain */
718 .db_stage3 = {0, 0, 0},
719 .db_stage4 = {0, 0, 0},
721 .txFrameToDataStart = 0x0e,
722 .txFrameToPaOn = 0x0e,
723 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
725 .switchSettling = 0x2c,
726 .adcDesiredSize = -30,
729 .txFrameToXpaOn = 0xe,
731 .papdRateMaskHt20 = LE32(0x0c80c080),
732 .papdRateMaskHt40 = LE32(0x0080c080),
734 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
738 .ant_div_control = 0,
739 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
746 /* ar9300_cal_data_per_freq_op_loop 2g */
748 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
749 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
750 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
752 .calTarget_freqbin_Cck = {
756 .calTarget_freqbin_2G = {
761 .calTarget_freqbin_2GHT20 = {
766 .calTarget_freqbin_2GHT40 = {
771 .calTargetPowerCck = {
772 /* 1L-5L,5S,11L,11S */
773 { {34, 34, 34, 34} },
774 { {34, 34, 34, 34} },
776 .calTargetPower2G = {
778 { {34, 34, 32, 32} },
779 { {34, 34, 32, 32} },
780 { {34, 34, 32, 32} },
782 .calTargetPower2GHT20 = {
783 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
784 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
785 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
787 .calTargetPower2GHT40 = {
788 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
789 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
790 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
793 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
794 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
824 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
825 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
826 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
827 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
831 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
832 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
833 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
838 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
839 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
845 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
846 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
847 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
848 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
852 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
853 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
854 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
858 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
859 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
860 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
865 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
866 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
867 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
872 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
873 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
874 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
875 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
879 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
880 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
881 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
883 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
884 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
885 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
887 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
888 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
889 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
891 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
892 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
893 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
896 /* 4 idle,t1,t2,b (4 bits per setting) */
897 .antCtrlCommon = LE32(0x220),
898 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
899 .antCtrlCommon2 = LE32(0x11111),
900 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
902 LE16(0x150), LE16(0x150), LE16(0x150),
904 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
905 .xatten1DB = {0, 0, 0},
908 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
909 * for merlin (0xa20c/b20c 16:12
911 .xatten1Margin = {0, 0, 0},
914 /* spurChans spur channels in usual fbin coding format */
915 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
916 /* noiseFloorThreshCh Check if the register is per chain */
917 .noiseFloorThreshCh = {-1, 0, 0},
918 .ob = {3, 3, 3}, /* 3 chain */
919 .db_stage2 = {3, 3, 3}, /* 3 chain */
920 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
921 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
923 .txFrameToDataStart = 0x0e,
924 .txFrameToPaOn = 0x0e,
925 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
927 .switchSettling = 0x2d,
928 .adcDesiredSize = -30,
931 .txFrameToXpaOn = 0xe,
933 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
934 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
936 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
941 .tempSlopeHigh = 105,
942 .xatten1DBLow = {0, 0, 0},
943 .xatten1MarginLow = {0, 0, 0},
944 .xatten1DBHigh = {0, 0, 0},
945 .xatten1MarginHigh = {0, 0, 0}
990 .calTarget_freqbin_5G = {
1000 .calTarget_freqbin_5GHT20 = {
1010 .calTarget_freqbin_5GHT40 = {
1020 .calTargetPower5G = {
1022 { {42, 40, 40, 34} },
1023 { {42, 40, 40, 34} },
1024 { {42, 40, 40, 34} },
1025 { {42, 40, 40, 34} },
1026 { {42, 40, 40, 34} },
1027 { {42, 40, 40, 34} },
1028 { {42, 40, 40, 34} },
1029 { {42, 40, 40, 34} },
1031 .calTargetPower5GHT20 = {
1033 * 0_8_16,1-3_9-11_17-19,
1034 * 4,5,6,7,12,13,14,15,20,21,22,23
1036 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1037 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1038 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1039 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1040 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1041 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1042 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1043 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1045 .calTargetPower5GHT40 = {
1047 * 0_8_16,1-3_9-11_17-19,
1048 * 4,5,6,7,12,13,14,15,20,21,22,23
1050 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1051 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1052 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1053 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1054 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1055 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1056 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1057 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1060 0x10, 0x16, 0x18, 0x40, 0x46,
1061 0x48, 0x30, 0x36, 0x38
1065 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1066 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1067 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1068 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1069 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1070 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1071 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1072 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1075 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1076 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1077 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1078 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1079 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1080 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1081 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1082 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1086 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1087 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1088 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1089 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1090 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1091 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1092 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1093 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1097 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1098 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1099 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1100 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1101 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1102 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1103 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1104 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1108 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1109 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1110 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1111 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1112 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1113 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1114 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1115 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1119 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1120 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1121 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1122 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1123 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1124 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1125 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1126 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1130 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1131 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1132 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1133 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1134 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1135 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1136 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1137 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1141 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1142 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1143 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1144 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1145 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1146 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1147 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1148 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1152 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1153 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1154 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1155 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1156 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1157 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1158 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1159 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1162 .ctlPowerData_5G = {
1165 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1166 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1171 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1172 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1177 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1178 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1183 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1184 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1189 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1190 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1195 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1196 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1201 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1202 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1207 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1208 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1213 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1214 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1221 static const struct ar9300_eeprom ar9300_h112 = {
1223 .templateVersion = 3,
1224 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1225 .custData = {"h112-241-f0000"},
1227 .regDmn = { LE16(0), LE16(0x1f) },
1228 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1230 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
1234 .blueToothOptions = 0,
1236 .deviceType = 5, /* takes lower byte in eeprom location */
1237 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1238 .params_for_tuning_caps = {0, 0},
1239 .featureEnable = 0x0d,
1241 * bit0 - enable tx temp comp - disabled
1242 * bit1 - enable tx volt comp - disabled
1243 * bit2 - enable fastClock - enabled
1244 * bit3 - enable doubling - enabled
1245 * bit4 - enable internal regulator - disabled
1246 * bit5 - enable pa predistortion - disabled
1248 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1249 .eepromWriteEnableGpio = 6,
1250 .wlanDisableGpio = 0,
1252 .rxBandSelectGpio = 0xff,
1257 /* ar9300_modal_eep_header 2g */
1258 /* 4 idle,t1,t2,b(4 bits per setting) */
1259 .antCtrlCommon = LE32(0x110),
1260 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1261 .antCtrlCommon2 = LE32(0x44444),
1264 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1265 * rx1, rx12, b (2 bits each)
1267 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1270 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1271 * for ar9280 (0xa20c/b20c 5:0)
1273 .xatten1DB = {0, 0, 0},
1276 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1277 * for ar9280 (0xa20c/b20c 16:12
1279 .xatten1Margin = {0, 0, 0},
1284 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1285 * channels in usual fbin coding format
1287 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1290 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1291 * if the register is per chain
1293 .noiseFloorThreshCh = {-1, 0, 0},
1294 .ob = {1, 1, 1},/* 3 chain */
1295 .db_stage2 = {1, 1, 1}, /* 3 chain */
1296 .db_stage3 = {0, 0, 0},
1297 .db_stage4 = {0, 0, 0},
1299 .txFrameToDataStart = 0x0e,
1300 .txFrameToPaOn = 0x0e,
1301 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1303 .switchSettling = 0x2c,
1304 .adcDesiredSize = -30,
1307 .txFrameToXpaOn = 0xe,
1309 .papdRateMaskHt20 = LE32(0x80c080),
1310 .papdRateMaskHt40 = LE32(0x80c080),
1312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1316 .ant_div_control = 0,
1317 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1324 /* ar9300_cal_data_per_freq_op_loop 2g */
1326 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1327 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1328 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1330 .calTarget_freqbin_Cck = {
1334 .calTarget_freqbin_2G = {
1339 .calTarget_freqbin_2GHT20 = {
1344 .calTarget_freqbin_2GHT40 = {
1349 .calTargetPowerCck = {
1350 /* 1L-5L,5S,11L,11S */
1351 { {34, 34, 34, 34} },
1352 { {34, 34, 34, 34} },
1354 .calTargetPower2G = {
1356 { {34, 34, 32, 32} },
1357 { {34, 34, 32, 32} },
1358 { {34, 34, 32, 32} },
1360 .calTargetPower2GHT20 = {
1361 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1362 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1363 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1365 .calTargetPower2GHT40 = {
1366 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1367 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1368 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1371 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1372 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1402 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1403 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1404 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1405 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1409 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1410 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1411 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1416 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1417 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1423 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1424 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1425 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1426 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1430 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1431 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1432 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1436 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1437 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1438 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1443 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1444 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1445 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1450 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1451 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1452 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1453 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1456 .ctlPowerData_2G = {
1457 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1458 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1459 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1461 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
1462 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1463 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1465 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1466 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1467 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1469 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1470 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1471 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1474 /* 4 idle,t1,t2,b (4 bits per setting) */
1475 .antCtrlCommon = LE32(0x220),
1476 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1477 .antCtrlCommon2 = LE32(0x44444),
1478 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1480 LE16(0x150), LE16(0x150), LE16(0x150),
1482 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1483 .xatten1DB = {0, 0, 0},
1486 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1487 * for merlin (0xa20c/b20c 16:12
1489 .xatten1Margin = {0, 0, 0},
1492 /* spurChans spur channels in usual fbin coding format */
1493 .spurChans = {0, 0, 0, 0, 0},
1494 /* noiseFloorThreshCh Check if the register is per chain */
1495 .noiseFloorThreshCh = {-1, 0, 0},
1496 .ob = {3, 3, 3}, /* 3 chain */
1497 .db_stage2 = {3, 3, 3}, /* 3 chain */
1498 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
1499 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
1501 .txFrameToDataStart = 0x0e,
1502 .txFrameToPaOn = 0x0e,
1503 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1505 .switchSettling = 0x2d,
1506 .adcDesiredSize = -30,
1509 .txFrameToXpaOn = 0xe,
1511 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1512 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1514 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1519 .tempSlopeHigh = 50,
1520 .xatten1DBLow = {0, 0, 0},
1521 .xatten1MarginLow = {0, 0, 0},
1522 .xatten1DBHigh = {0, 0, 0},
1523 .xatten1MarginHigh = {0, 0, 0}
1568 .calTarget_freqbin_5G = {
1578 .calTarget_freqbin_5GHT20 = {
1588 .calTarget_freqbin_5GHT40 = {
1598 .calTargetPower5G = {
1600 { {30, 30, 28, 24} },
1601 { {30, 30, 28, 24} },
1602 { {30, 30, 28, 24} },
1603 { {30, 30, 28, 24} },
1604 { {30, 30, 28, 24} },
1605 { {30, 30, 28, 24} },
1606 { {30, 30, 28, 24} },
1607 { {30, 30, 28, 24} },
1609 .calTargetPower5GHT20 = {
1611 * 0_8_16,1-3_9-11_17-19,
1612 * 4,5,6,7,12,13,14,15,20,21,22,23
1614 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1615 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1616 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1617 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1618 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1619 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1620 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1621 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1623 .calTargetPower5GHT40 = {
1625 * 0_8_16,1-3_9-11_17-19,
1626 * 4,5,6,7,12,13,14,15,20,21,22,23
1628 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1629 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1630 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1631 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1632 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1633 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1634 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1635 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1638 0x10, 0x16, 0x18, 0x40, 0x46,
1639 0x48, 0x30, 0x36, 0x38
1643 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1644 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1645 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1646 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1647 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1648 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1649 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1650 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1653 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1654 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1655 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1656 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1657 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1658 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1659 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1660 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1664 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1665 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1666 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1667 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1668 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1669 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1670 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1671 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1675 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1676 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1677 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1678 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1679 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1680 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1681 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1682 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1686 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1687 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1688 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1689 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1690 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1691 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1692 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1693 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1697 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1698 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1699 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1700 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1701 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1702 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1703 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1704 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1708 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1709 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1710 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1711 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1712 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1713 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1714 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1715 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1719 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1720 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1721 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1722 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1723 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1724 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1725 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1726 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1730 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1731 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1732 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1733 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1734 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1735 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1736 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1737 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1740 .ctlPowerData_5G = {
1743 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1744 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1749 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1750 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1755 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1756 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1761 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1762 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1767 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1768 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1773 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1774 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1779 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1780 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1785 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1786 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1791 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1792 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1799 static const struct ar9300_eeprom ar9300_x112 = {
1801 .templateVersion = 5,
1802 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1803 .custData = {"x112-041-f0000"},
1805 .regDmn = { LE16(0), LE16(0x1f) },
1806 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1808 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
1812 .blueToothOptions = 0,
1814 .deviceType = 5, /* takes lower byte in eeprom location */
1815 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1816 .params_for_tuning_caps = {0, 0},
1817 .featureEnable = 0x0d,
1819 * bit0 - enable tx temp comp - disabled
1820 * bit1 - enable tx volt comp - disabled
1821 * bit2 - enable fastclock - enabled
1822 * bit3 - enable doubling - enabled
1823 * bit4 - enable internal regulator - disabled
1824 * bit5 - enable pa predistortion - disabled
1826 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1827 .eepromWriteEnableGpio = 6,
1828 .wlanDisableGpio = 0,
1830 .rxBandSelectGpio = 0xff,
1835 /* ar9300_modal_eep_header 2g */
1836 /* 4 idle,t1,t2,b(4 bits per setting) */
1837 .antCtrlCommon = LE32(0x110),
1838 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1839 .antCtrlCommon2 = LE32(0x22222),
1842 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1843 * rx1, rx12, b (2 bits each)
1845 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1848 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1849 * for ar9280 (0xa20c/b20c 5:0)
1851 .xatten1DB = {0x1b, 0x1b, 0x1b},
1854 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1855 * for ar9280 (0xa20c/b20c 16:12
1857 .xatten1Margin = {0x15, 0x15, 0x15},
1862 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1863 * channels in usual fbin coding format
1865 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1868 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1869 * if the register is per chain
1871 .noiseFloorThreshCh = {-1, 0, 0},
1872 .ob = {1, 1, 1},/* 3 chain */
1873 .db_stage2 = {1, 1, 1}, /* 3 chain */
1874 .db_stage3 = {0, 0, 0},
1875 .db_stage4 = {0, 0, 0},
1877 .txFrameToDataStart = 0x0e,
1878 .txFrameToPaOn = 0x0e,
1879 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1881 .switchSettling = 0x2c,
1882 .adcDesiredSize = -30,
1885 .txFrameToXpaOn = 0xe,
1887 .papdRateMaskHt20 = LE32(0x0c80c080),
1888 .papdRateMaskHt40 = LE32(0x0080c080),
1890 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1894 .ant_div_control = 0,
1895 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1902 /* ar9300_cal_data_per_freq_op_loop 2g */
1904 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1905 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1906 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1908 .calTarget_freqbin_Cck = {
1912 .calTarget_freqbin_2G = {
1917 .calTarget_freqbin_2GHT20 = {
1922 .calTarget_freqbin_2GHT40 = {
1927 .calTargetPowerCck = {
1928 /* 1L-5L,5S,11L,11s */
1929 { {38, 38, 38, 38} },
1930 { {38, 38, 38, 38} },
1932 .calTargetPower2G = {
1934 { {38, 38, 36, 34} },
1935 { {38, 38, 36, 34} },
1936 { {38, 38, 34, 32} },
1938 .calTargetPower2GHT20 = {
1939 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1940 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1941 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1943 .calTargetPower2GHT40 = {
1944 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1945 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1946 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1949 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1950 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1980 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1981 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1982 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1983 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1987 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1988 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1989 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1994 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1995 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2001 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2002 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2003 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2004 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2008 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2009 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2010 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2014 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2015 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2016 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2021 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2022 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2023 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2028 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2029 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2030 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2031 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2034 .ctlPowerData_2G = {
2035 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2036 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2037 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2039 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
2040 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2041 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2043 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2044 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2045 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2047 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2048 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2049 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2052 /* 4 idle,t1,t2,b (4 bits per setting) */
2053 .antCtrlCommon = LE32(0x110),
2054 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2055 .antCtrlCommon2 = LE32(0x22222),
2056 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2058 LE16(0x0), LE16(0x0), LE16(0x0),
2060 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2061 .xatten1DB = {0x13, 0x19, 0x17},
2064 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2065 * for merlin (0xa20c/b20c 16:12
2067 .xatten1Margin = {0x19, 0x19, 0x19},
2070 /* spurChans spur channels in usual fbin coding format */
2071 .spurChans = {0, 0, 0, 0, 0},
2072 /* noiseFloorThreshch check if the register is per chain */
2073 .noiseFloorThreshCh = {-1, 0, 0},
2074 .ob = {3, 3, 3}, /* 3 chain */
2075 .db_stage2 = {3, 3, 3}, /* 3 chain */
2076 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
2077 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
2079 .txFrameToDataStart = 0x0e,
2080 .txFrameToPaOn = 0x0e,
2081 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2083 .switchSettling = 0x2d,
2084 .adcDesiredSize = -30,
2087 .txFrameToXpaOn = 0xe,
2089 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2090 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2092 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2097 .tempSlopeHigh = 105,
2098 .xatten1DBLow = {0x10, 0x14, 0x10},
2099 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2100 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2101 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2146 .calTarget_freqbin_5G = {
2156 .calTarget_freqbin_5GHT20 = {
2166 .calTarget_freqbin_5GHT40 = {
2176 .calTargetPower5G = {
2178 { {32, 32, 28, 26} },
2179 { {32, 32, 28, 26} },
2180 { {32, 32, 28, 26} },
2181 { {32, 32, 26, 24} },
2182 { {32, 32, 26, 24} },
2183 { {32, 32, 24, 22} },
2184 { {30, 30, 24, 22} },
2185 { {30, 30, 24, 22} },
2187 .calTargetPower5GHT20 = {
2189 * 0_8_16,1-3_9-11_17-19,
2190 * 4,5,6,7,12,13,14,15,20,21,22,23
2192 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2193 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2194 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2195 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2196 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2197 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2198 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2199 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2201 .calTargetPower5GHT40 = {
2203 * 0_8_16,1-3_9-11_17-19,
2204 * 4,5,6,7,12,13,14,15,20,21,22,23
2206 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2207 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2208 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2209 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2210 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2211 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2212 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2213 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2216 0x10, 0x16, 0x18, 0x40, 0x46,
2217 0x48, 0x30, 0x36, 0x38
2221 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2222 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2223 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2224 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2225 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2226 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2227 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2228 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2231 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2232 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2233 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2234 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2235 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2236 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2237 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2238 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2242 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2243 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2244 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2245 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2246 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2247 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2248 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2249 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2253 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2254 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2255 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2256 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2257 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2258 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2259 /* Data[3].ctledges[6].bchannel */ 0xFF,
2260 /* Data[3].ctledges[7].bchannel */ 0xFF,
2264 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2265 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2266 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2267 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2268 /* Data[4].ctledges[4].bchannel */ 0xFF,
2269 /* Data[4].ctledges[5].bchannel */ 0xFF,
2270 /* Data[4].ctledges[6].bchannel */ 0xFF,
2271 /* Data[4].ctledges[7].bchannel */ 0xFF,
2275 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2276 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2277 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2278 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2279 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2280 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2281 /* Data[5].ctledges[6].bchannel */ 0xFF,
2282 /* Data[5].ctledges[7].bchannel */ 0xFF
2286 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2287 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2288 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2289 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2290 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2291 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2292 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2293 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2297 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2298 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2299 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2300 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2301 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2302 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2303 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2304 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2308 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2309 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2310 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2311 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2312 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2313 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2314 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2315 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2318 .ctlPowerData_5G = {
2321 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2322 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2327 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2328 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2333 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2334 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2339 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2340 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2345 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2346 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2351 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2352 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2357 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2358 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2363 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2364 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2369 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2370 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2376 static const struct ar9300_eeprom ar9300_h116 = {
2378 .templateVersion = 4,
2379 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2380 .custData = {"h116-041-f0000"},
2382 .regDmn = { LE16(0), LE16(0x1f) },
2383 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2385 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
2389 .blueToothOptions = 0,
2391 .deviceType = 5, /* takes lower byte in eeprom location */
2392 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2393 .params_for_tuning_caps = {0, 0},
2394 .featureEnable = 0x0d,
2396 * bit0 - enable tx temp comp - disabled
2397 * bit1 - enable tx volt comp - disabled
2398 * bit2 - enable fastClock - enabled
2399 * bit3 - enable doubling - enabled
2400 * bit4 - enable internal regulator - disabled
2401 * bit5 - enable pa predistortion - disabled
2403 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2404 .eepromWriteEnableGpio = 6,
2405 .wlanDisableGpio = 0,
2407 .rxBandSelectGpio = 0xff,
2412 /* ar9300_modal_eep_header 2g */
2413 /* 4 idle,t1,t2,b(4 bits per setting) */
2414 .antCtrlCommon = LE32(0x110),
2415 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2416 .antCtrlCommon2 = LE32(0x44444),
2419 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2420 * rx1, rx12, b (2 bits each)
2422 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2425 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2426 * for ar9280 (0xa20c/b20c 5:0)
2428 .xatten1DB = {0x1f, 0x1f, 0x1f},
2431 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2432 * for ar9280 (0xa20c/b20c 16:12
2434 .xatten1Margin = {0x12, 0x12, 0x12},
2439 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2440 * channels in usual fbin coding format
2442 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2445 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2446 * if the register is per chain
2448 .noiseFloorThreshCh = {-1, 0, 0},
2449 .ob = {1, 1, 1},/* 3 chain */
2450 .db_stage2 = {1, 1, 1}, /* 3 chain */
2451 .db_stage3 = {0, 0, 0},
2452 .db_stage4 = {0, 0, 0},
2454 .txFrameToDataStart = 0x0e,
2455 .txFrameToPaOn = 0x0e,
2456 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2458 .switchSettling = 0x2c,
2459 .adcDesiredSize = -30,
2462 .txFrameToXpaOn = 0xe,
2464 .papdRateMaskHt20 = LE32(0x0c80C080),
2465 .papdRateMaskHt40 = LE32(0x0080C080),
2467 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2471 .ant_div_control = 0,
2472 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2479 /* ar9300_cal_data_per_freq_op_loop 2g */
2481 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2482 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2483 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2485 .calTarget_freqbin_Cck = {
2489 .calTarget_freqbin_2G = {
2494 .calTarget_freqbin_2GHT20 = {
2499 .calTarget_freqbin_2GHT40 = {
2504 .calTargetPowerCck = {
2505 /* 1L-5L,5S,11L,11S */
2506 { {34, 34, 34, 34} },
2507 { {34, 34, 34, 34} },
2509 .calTargetPower2G = {
2511 { {34, 34, 32, 32} },
2512 { {34, 34, 32, 32} },
2513 { {34, 34, 32, 32} },
2515 .calTargetPower2GHT20 = {
2516 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2517 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2518 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2520 .calTargetPower2GHT40 = {
2521 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2522 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2523 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2526 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2527 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2557 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2558 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2559 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2560 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2564 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2565 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2566 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2571 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2572 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2578 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2579 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2580 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2581 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2585 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2586 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2587 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2591 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2592 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2593 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2598 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2599 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2600 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2605 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2606 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2607 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2608 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2611 .ctlPowerData_2G = {
2612 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2613 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2614 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2616 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
2617 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2618 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2620 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2621 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2622 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2624 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2625 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2626 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2629 /* 4 idle,t1,t2,b (4 bits per setting) */
2630 .antCtrlCommon = LE32(0x220),
2631 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2632 .antCtrlCommon2 = LE32(0x44444),
2633 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2635 LE16(0x150), LE16(0x150), LE16(0x150),
2637 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2638 .xatten1DB = {0x19, 0x19, 0x19},
2641 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2642 * for merlin (0xa20c/b20c 16:12
2644 .xatten1Margin = {0x14, 0x14, 0x14},
2647 /* spurChans spur channels in usual fbin coding format */
2648 .spurChans = {0, 0, 0, 0, 0},
2649 /* noiseFloorThreshCh Check if the register is per chain */
2650 .noiseFloorThreshCh = {-1, 0, 0},
2651 .ob = {3, 3, 3}, /* 3 chain */
2652 .db_stage2 = {3, 3, 3}, /* 3 chain */
2653 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
2654 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
2656 .txFrameToDataStart = 0x0e,
2657 .txFrameToPaOn = 0x0e,
2658 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2660 .switchSettling = 0x2d,
2661 .adcDesiredSize = -30,
2664 .txFrameToXpaOn = 0xe,
2666 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2667 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2669 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2674 .tempSlopeHigh = 50,
2675 .xatten1DBLow = {0, 0, 0},
2676 .xatten1MarginLow = {0, 0, 0},
2677 .xatten1DBHigh = {0, 0, 0},
2678 .xatten1MarginHigh = {0, 0, 0}
2723 .calTarget_freqbin_5G = {
2733 .calTarget_freqbin_5GHT20 = {
2743 .calTarget_freqbin_5GHT40 = {
2753 .calTargetPower5G = {
2755 { {30, 30, 28, 24} },
2756 { {30, 30, 28, 24} },
2757 { {30, 30, 28, 24} },
2758 { {30, 30, 28, 24} },
2759 { {30, 30, 28, 24} },
2760 { {30, 30, 28, 24} },
2761 { {30, 30, 28, 24} },
2762 { {30, 30, 28, 24} },
2764 .calTargetPower5GHT20 = {
2766 * 0_8_16,1-3_9-11_17-19,
2767 * 4,5,6,7,12,13,14,15,20,21,22,23
2769 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2770 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2771 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2772 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2773 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2774 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2775 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2776 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2778 .calTargetPower5GHT40 = {
2780 * 0_8_16,1-3_9-11_17-19,
2781 * 4,5,6,7,12,13,14,15,20,21,22,23
2783 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2784 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2785 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2786 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2787 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2788 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2789 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2790 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2793 0x10, 0x16, 0x18, 0x40, 0x46,
2794 0x48, 0x30, 0x36, 0x38
2798 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2799 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2800 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2801 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2802 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2803 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2804 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2805 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2808 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2809 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2810 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2811 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2812 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2813 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2814 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2815 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2819 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2820 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2821 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2822 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2823 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2824 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2825 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2826 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2830 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2831 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2832 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2833 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2834 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2835 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2836 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2837 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2841 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2842 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2843 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2844 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2845 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2846 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2847 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2848 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2852 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2853 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2854 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2855 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2856 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2857 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2858 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2859 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2863 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2864 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2865 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2866 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2867 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2868 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2869 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2870 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2874 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2875 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2876 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2877 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2878 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2879 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2880 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2881 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2885 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2886 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2887 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2888 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2889 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2890 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2891 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2892 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2895 .ctlPowerData_5G = {
2898 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2899 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2904 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2905 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2910 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2911 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2916 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2917 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2922 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2923 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2928 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2929 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2934 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2935 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2940 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2941 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2946 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2947 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2954 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2962 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2964 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2967 for (it = 0; it < N_LOOP; it++)
2968 if (ar9300_eep_templates[it]->templateVersion == id)
2969 return ar9300_eep_templates[it];
2975 static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
2977 if (fbin == AR9300_BCHAN_UNUSED)
2980 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
2983 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2988 static int interpolate(int x, int xa, int xb, int ya, int yb)
2990 int bf, factor, plus;
2992 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2995 return ya + factor + plus;
2998 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2999 enum eeprom_param param)
3001 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3002 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3006 return eep->macAddr[0] << 8 | eep->macAddr[1];
3008 return eep->macAddr[2] << 8 | eep->macAddr[3];
3010 return eep->macAddr[4] << 8 | eep->macAddr[5];
3012 return le16_to_cpu(pBase->regDmn[0]);
3014 return le16_to_cpu(pBase->regDmn[1]);
3016 return pBase->deviceCap;
3018 return pBase->opCapFlags.opFlags;
3020 return pBase->rfSilent;
3022 return (pBase->txrxMask >> 4) & 0xf;
3024 return pBase->txrxMask & 0xf;
3025 case EEP_DRIVE_STRENGTH:
3026 #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1
3027 return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
3028 case EEP_INTERNAL_REGULATOR:
3029 /* Bit 4 is internal regulator flag */
3030 return (pBase->featureEnable & 0x10) >> 4;
3032 return le32_to_cpu(pBase->swreg);
3034 return !!(pBase->featureEnable & BIT(5));
3035 case EEP_CHAIN_MASK_REDUCE:
3036 return (pBase->miscConfiguration >> 0x3) & 0x1;
3042 static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
3047 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3050 *buffer = (val >> (8 * (address % 2))) & 0xff;
3054 static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
3059 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3062 buffer[0] = val >> 8;
3063 buffer[1] = val & 0xff;
3068 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3071 struct ath_common *common = ath9k_hw_common(ah);
3074 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3075 ath_print(common, ATH_DBG_EEPROM,
3076 "eeprom address not in range\n");
3081 * Since we're reading the bytes in reverse order from a little-endian
3082 * word stream, an even address means we only use the lower half of
3083 * the 16-bit word at that address
3085 if (address % 2 == 0) {
3086 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
3092 for (i = 0; i < count / 2; i++) {
3093 if (!ar9300_eeprom_read_word(common, address, buffer))
3101 if (!ar9300_eeprom_read_byte(common, address, buffer))
3107 ath_print(common, ATH_DBG_EEPROM,
3108 "unable to read eeprom region at offset %d\n", address);
3112 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3114 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3116 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3117 AR9300_OTP_STATUS_VALID, 1000))
3120 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3124 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3130 for (i = 0; i < count; i++) {
3131 int offset = 8 * ((address - i) % 4);
3132 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3135 buffer[i] = (data >> offset) & 0xff;
3142 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3143 int *length, int *major, int *minor)
3145 unsigned long value[4];
3151 *code = ((value[0] >> 5) & 0x0007);
3152 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3153 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3154 *major = (value[2] & 0x000f);
3155 *minor = (value[3] & 0x00ff);
3158 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3160 int it, checksum = 0;
3162 for (it = 0; it < dsize; it++) {
3163 checksum += data[it];
3170 static bool ar9300_uncompress_block(struct ath_hw *ah,
3180 struct ath_common *common = ath9k_hw_common(ah);
3184 for (it = 0; it < size; it += (length+2)) {
3188 length = block[it+1];
3191 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3192 ath_print(common, ATH_DBG_EEPROM,
3193 "Restore at %d: spot=%d "
3194 "offset=%d length=%d\n",
3195 it, spot, offset, length);
3196 memcpy(&mptr[spot], &block[it+2], length);
3198 } else if (length > 0) {
3199 ath_print(common, ATH_DBG_EEPROM,
3200 "Bad restore at %d: spot=%d "
3201 "offset=%d length=%d\n",
3202 it, spot, offset, length);
3209 static int ar9300_compress_decision(struct ath_hw *ah,
3214 u8 *word, int length, int mdata_size)
3216 struct ath_common *common = ath9k_hw_common(ah);
3218 const struct ar9300_eeprom *eep = NULL;
3222 if (length != mdata_size) {
3223 ath_print(common, ATH_DBG_EEPROM,
3224 "EEPROM structure size mismatch"
3225 "memory=%d eeprom=%d\n", mdata_size, length);
3228 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
3229 ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
3230 " uncompressed, length %d\n", it, length);
3232 case _CompressBlock:
3233 if (reference == 0) {
3236 eep = ar9003_eeprom_struct_find_by_id(reference);
3238 ath_print(common, ATH_DBG_EEPROM,
3239 "cant find reference eeprom"
3240 "struct %d\n", reference);
3243 memcpy(mptr, eep, mdata_size);
3245 ath_print(common, ATH_DBG_EEPROM,
3246 "restore eeprom %d: block, reference %d,"
3247 " length %d\n", it, reference, length);
3248 ar9300_uncompress_block(ah, mptr, mdata_size,
3249 (u8 *) (word + COMP_HDR_LEN), length);
3252 ath_print(common, ATH_DBG_EEPROM, "unknown compression"
3253 " code %d\n", code);
3259 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3262 static bool ar9300_check_header(void *data)
3265 return !(*word == 0 || *word == ~0);
3268 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3273 if (!read(ah, base_addr, header, 4))
3276 return ar9300_check_header(header);
3279 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3282 struct ath_common *common = ath9k_hw_common(ah);
3283 u16 *data = (u16 *) mptr;
3286 for (i = 0; i < mdata_size / 2; i++, data++)
3287 ath9k_hw_nvram_read(common, i, data);
3292 * Read the configuration data from the eeprom.
3293 * The data can be put in any specified memory buffer.
3295 * Returns -1 on error.
3296 * Returns address of next memory location on success.
3298 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3299 u8 *mptr, int mdata_size)
3306 int reference, length, major, minor;
3309 u16 checksum, mchecksum;
3310 struct ath_common *common = ath9k_hw_common(ah);
3311 eeprom_read_op read;
3313 if (ath9k_hw_use_flash(ah))
3314 return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3316 word = kzalloc(2048, GFP_KERNEL);
3320 memcpy(mptr, &ar9300_default, mdata_size);
3322 read = ar9300_read_eeprom;
3323 cptr = AR9300_BASE_ADDR;
3324 ath_print(common, ATH_DBG_EEPROM,
3325 "Trying EEPROM accesss at Address 0x%04x\n", cptr);
3326 if (ar9300_check_eeprom_header(ah, read, cptr))
3329 cptr = AR9300_BASE_ADDR_512;
3330 ath_print(common, ATH_DBG_EEPROM,
3331 "Trying EEPROM accesss at Address 0x%04x\n", cptr);
3332 if (ar9300_check_eeprom_header(ah, read, cptr))
3335 read = ar9300_read_otp;
3336 cptr = AR9300_BASE_ADDR;
3337 ath_print(common, ATH_DBG_EEPROM,
3338 "Trying OTP accesss at Address 0x%04x\n", cptr);
3339 if (ar9300_check_eeprom_header(ah, read, cptr))
3342 cptr = AR9300_BASE_ADDR_512;
3343 ath_print(common, ATH_DBG_EEPROM,
3344 "Trying OTP accesss at Address 0x%04x\n", cptr);
3345 if (ar9300_check_eeprom_header(ah, read, cptr))
3351 ath_print(common, ATH_DBG_EEPROM, "Found valid EEPROM data");
3353 for (it = 0; it < MSTATE; it++) {
3354 if (!read(ah, cptr, word, COMP_HDR_LEN))
3357 if (!ar9300_check_header(word))
3360 ar9300_comp_hdr_unpack(word, &code, &reference,
3361 &length, &major, &minor);
3362 ath_print(common, ATH_DBG_EEPROM,
3363 "Found block at %x: code=%d ref=%d"
3364 "length=%d major=%d minor=%d\n", cptr, code,
3365 reference, length, major, minor);
3366 if (length >= 1024) {
3367 ath_print(common, ATH_DBG_EEPROM,
3368 "Skipping bad header\n");
3369 cptr -= COMP_HDR_LEN;
3374 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3375 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3376 mchecksum = word[COMP_HDR_LEN + osize] |
3377 (word[COMP_HDR_LEN + osize + 1] << 8);
3378 ath_print(common, ATH_DBG_EEPROM,
3379 "checksum %x %x\n", checksum, mchecksum);
3380 if (checksum == mchecksum) {
3381 ar9300_compress_decision(ah, it, code, reference, mptr,
3382 word, length, mdata_size);
3384 ath_print(common, ATH_DBG_EEPROM,
3385 "skipping block with bad checksum\n");
3387 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3399 * Restore the configuration structure by reading the eeprom.
3400 * This function destroys any existing in-memory structure
3403 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3405 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3407 if (ar9300_eeprom_restore_internal(ah, mptr,
3408 sizeof(struct ar9300_eeprom)) < 0)
3414 /* XXX: review hardware docs */
3415 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3417 return ah->eeprom.ar9300_eep.eepromVersion;
3420 /* XXX: could be read from the eepromVersion, not sure yet */
3421 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3426 static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
3427 enum ath9k_hal_freq_band freq_band)
3432 static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
3433 struct ath9k_channel *chan)
3438 static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
3440 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3443 return eep->modalHeader2G.xpaBiasLvl;
3445 return eep->modalHeader5G.xpaBiasLvl;
3448 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3450 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
3451 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3452 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, bias >> 2);
3453 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
3456 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3458 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3462 val = eep->modalHeader2G.antCtrlCommon;
3464 val = eep->modalHeader5G.antCtrlCommon;
3465 return le32_to_cpu(val);
3468 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3470 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3474 val = eep->modalHeader2G.antCtrlCommon2;
3476 val = eep->modalHeader5G.antCtrlCommon2;
3477 return le32_to_cpu(val);
3480 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
3484 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3487 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
3489 val = eep->modalHeader2G.antCtrlChain[chain];
3491 val = eep->modalHeader5G.antCtrlChain[chain];
3494 return le16_to_cpu(val);
3497 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3499 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3500 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
3502 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3503 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3505 value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
3506 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
3508 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3509 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
3511 value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
3512 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
3515 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3520 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
3522 if (!drive_strength)
3525 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3533 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3535 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3546 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3548 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3553 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3556 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3557 struct ath9k_channel *chan)
3561 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3563 if (chain >= 0 && chain < 3) {
3564 if (IS_CHAN_2GHZ(chan))
3565 return eep->modalHeader2G.xatten1DB[chain];
3566 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3567 t[0] = eep->base_ext2.xatten1DBLow[chain];
3569 t[1] = eep->modalHeader5G.xatten1DB[chain];
3571 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3573 value = ar9003_hw_power_interpolate((s32) chan->channel,
3577 return eep->modalHeader5G.xatten1DB[chain];
3584 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3585 struct ath9k_channel *chan)
3589 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3591 if (chain >= 0 && chain < 3) {
3592 if (IS_CHAN_2GHZ(chan))
3593 return eep->modalHeader2G.xatten1Margin[chain];
3594 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3595 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3597 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3599 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3601 value = ar9003_hw_power_interpolate((s32) chan->channel,
3605 return eep->modalHeader5G.xatten1Margin[chain];
3611 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3615 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3616 AR_PHY_EXT_ATTEN_CTL_1,
3617 AR_PHY_EXT_ATTEN_CTL_2,
3620 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3621 for (i = 0; i < 3; i++) {
3622 value = ar9003_hw_atten_chain_get(ah, i, chan);
3623 REG_RMW_FIELD(ah, ext_atten_reg[i],
3624 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3626 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3627 REG_RMW_FIELD(ah, ext_atten_reg[i],
3628 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
3632 static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3634 int internal_regulator =
3635 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
3637 if (internal_regulator) {
3638 /* Internal regulator is ON. Write swreg register. */
3639 int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
3640 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3641 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3642 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3643 REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
3644 /* Set REG_CONTROL1.SWREG_PROGRAM */
3645 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3647 AR_RTC_REG_CONTROL1) |
3648 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3650 REG_WRITE(ah, AR_RTC_SLEEP_CLK,
3653 AR_RTC_FORCE_SWREG_PRD));
3657 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3658 struct ath9k_channel *chan)
3660 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
3661 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
3662 ar9003_hw_drive_strength_apply(ah);
3663 ar9003_hw_atten_apply(ah, chan);
3664 ar9003_hw_internal_regulator_apply(ah);
3667 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
3668 struct ath9k_channel *chan)
3673 * Returns the interpolated y value corresponding to the specified x value
3674 * from the np ordered pairs of data (px,py).
3675 * The pairs do not have to be in any order.
3676 * If the specified x value is less than any of the px,
3677 * the returned y value is equal to the py for the lowest px.
3678 * If the specified x value is greater than any of the px,
3679 * the returned y value is equal to the py for the highest px.
3681 static int ar9003_hw_power_interpolate(int32_t x,
3682 int32_t *px, int32_t *py, u_int16_t np)
3685 int lx = 0, ly = 0, lhave = 0;
3686 int hx = 0, hy = 0, hhave = 0;
3693 /* identify best lower and higher x calibration measurement */
3694 for (ip = 0; ip < np; ip++) {
3697 /* this measurement is higher than our desired x */
3699 if (!hhave || dx > (x - hx)) {
3700 /* new best higher x measurement */
3706 /* this measurement is lower than our desired x */
3708 if (!lhave || dx < (x - lx)) {
3709 /* new best lower x measurement */
3717 /* the low x is good */
3719 /* so is the high x */
3721 /* they're the same, so just pick one */
3724 else /* interpolate */
3725 y = interpolate(x, lx, hx, ly, hy);
3726 } else /* only low is good, use it */
3728 } else if (hhave) /* only high is good, use it */
3730 else /* nothing is good,this should never happen unless np=0, ???? */
3735 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
3736 u16 rateIndex, u16 freq, bool is2GHz)
3739 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
3740 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
3741 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3742 struct cal_tgt_pow_legacy *pEepromTargetPwr;
3746 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
3747 pEepromTargetPwr = eep->calTargetPower2G;
3748 pFreqBin = eep->calTarget_freqbin_2G;
3750 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
3751 pEepromTargetPwr = eep->calTargetPower5G;
3752 pFreqBin = eep->calTarget_freqbin_5G;
3756 * create array of channels and targetpower from
3757 * targetpower piers stored on eeprom
3759 for (i = 0; i < numPiers; i++) {
3760 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
3761 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3764 /* interpolate to get target power for given frequency */
3765 return (u8) ar9003_hw_power_interpolate((s32) freq,
3767 targetPowerArray, numPiers);
3770 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
3772 u16 freq, bool is2GHz)
3775 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
3776 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
3777 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3778 struct cal_tgt_pow_ht *pEepromTargetPwr;
3782 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
3783 pEepromTargetPwr = eep->calTargetPower2GHT20;
3784 pFreqBin = eep->calTarget_freqbin_2GHT20;
3786 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
3787 pEepromTargetPwr = eep->calTargetPower5GHT20;
3788 pFreqBin = eep->calTarget_freqbin_5GHT20;
3792 * create array of channels and targetpower
3793 * from targetpower piers stored on eeprom
3795 for (i = 0; i < numPiers; i++) {
3796 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
3797 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3800 /* interpolate to get target power for given frequency */
3801 return (u8) ar9003_hw_power_interpolate((s32) freq,
3803 targetPowerArray, numPiers);
3806 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
3808 u16 freq, bool is2GHz)
3811 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
3812 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
3813 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3814 struct cal_tgt_pow_ht *pEepromTargetPwr;
3818 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
3819 pEepromTargetPwr = eep->calTargetPower2GHT40;
3820 pFreqBin = eep->calTarget_freqbin_2GHT40;
3822 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
3823 pEepromTargetPwr = eep->calTargetPower5GHT40;
3824 pFreqBin = eep->calTarget_freqbin_5GHT40;
3828 * create array of channels and targetpower from
3829 * targetpower piers stored on eeprom
3831 for (i = 0; i < numPiers; i++) {
3832 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
3833 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3836 /* interpolate to get target power for given frequency */
3837 return (u8) ar9003_hw_power_interpolate((s32) freq,
3839 targetPowerArray, numPiers);
3842 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
3843 u16 rateIndex, u16 freq)
3845 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
3846 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
3847 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
3848 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3849 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
3850 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
3853 * create array of channels and targetpower from
3854 * targetpower piers stored on eeprom
3856 for (i = 0; i < numPiers; i++) {
3857 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
3858 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3861 /* interpolate to get target power for given frequency */
3862 return (u8) ar9003_hw_power_interpolate((s32) freq,
3864 targetPowerArray, numPiers);
3867 /* Set tx power registers to array of values passed in */
3868 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
3870 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
3871 /* make sure forced gain is not set */
3872 REG_WRITE(ah, 0xa458, 0);
3874 /* Write the OFDM power per rate set */
3876 /* 6 (LSB), 9, 12, 18 (MSB) */
3877 REG_WRITE(ah, 0xa3c0,
3878 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
3879 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
3880 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
3881 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
3883 /* 24 (LSB), 36, 48, 54 (MSB) */
3884 REG_WRITE(ah, 0xa3c4,
3885 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
3886 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
3887 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
3888 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
3890 /* Write the CCK power per rate set */
3892 /* 1L (LSB), reserved, 2L, 2S (MSB) */
3893 REG_WRITE(ah, 0xa3c8,
3894 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
3895 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
3896 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
3897 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
3899 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
3900 REG_WRITE(ah, 0xa3cc,
3901 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
3902 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
3903 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
3904 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
3907 /* Write the HT20 power per rate set */
3909 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
3910 REG_WRITE(ah, 0xa3d0,
3911 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
3912 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
3913 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
3914 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
3917 /* 6 (LSB), 7, 12, 13 (MSB) */
3918 REG_WRITE(ah, 0xa3d4,
3919 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
3920 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
3921 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
3922 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
3925 /* 14 (LSB), 15, 20, 21 */
3926 REG_WRITE(ah, 0xa3e4,
3927 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
3928 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
3929 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
3930 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
3933 /* Mixed HT20 and HT40 rates */
3935 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
3936 REG_WRITE(ah, 0xa3e8,
3937 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
3938 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
3939 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
3940 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
3944 * Write the HT40 power per rate set
3945 * correct PAR difference between HT40 and HT20/LEGACY
3946 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
3948 REG_WRITE(ah, 0xa3d8,
3949 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
3950 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
3951 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
3952 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
3955 /* 6 (LSB), 7, 12, 13 (MSB) */
3956 REG_WRITE(ah, 0xa3dc,
3957 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
3958 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
3959 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
3960 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
3963 /* 14 (LSB), 15, 20, 21 */
3964 REG_WRITE(ah, 0xa3ec,
3965 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
3966 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
3967 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
3968 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
3975 static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
3976 u8 *targetPowerValT2)
3978 /* XXX: hard code for now, need to get from eeprom struct */
3979 u8 ht40PowerIncForPdadc = 0;
3980 bool is2GHz = false;
3982 struct ath_common *common = ath9k_hw_common(ah);
3987 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
3988 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
3990 targetPowerValT2[ALL_TARGET_LEGACY_36] =
3991 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
3993 targetPowerValT2[ALL_TARGET_LEGACY_48] =
3994 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
3996 targetPowerValT2[ALL_TARGET_LEGACY_54] =
3997 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
3999 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4000 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4002 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4003 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4004 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4005 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4006 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4007 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4008 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4009 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4011 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4012 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4014 targetPowerValT2[ALL_TARGET_HT20_4] =
4015 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4017 targetPowerValT2[ALL_TARGET_HT20_5] =
4018 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4020 targetPowerValT2[ALL_TARGET_HT20_6] =
4021 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4023 targetPowerValT2[ALL_TARGET_HT20_7] =
4024 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4026 targetPowerValT2[ALL_TARGET_HT20_12] =
4027 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4029 targetPowerValT2[ALL_TARGET_HT20_13] =
4030 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4032 targetPowerValT2[ALL_TARGET_HT20_14] =
4033 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4035 targetPowerValT2[ALL_TARGET_HT20_15] =
4036 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4038 targetPowerValT2[ALL_TARGET_HT20_20] =
4039 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4041 targetPowerValT2[ALL_TARGET_HT20_21] =
4042 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4044 targetPowerValT2[ALL_TARGET_HT20_22] =
4045 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4047 targetPowerValT2[ALL_TARGET_HT20_23] =
4048 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4050 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4051 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4052 is2GHz) + ht40PowerIncForPdadc;
4053 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4054 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4056 is2GHz) + ht40PowerIncForPdadc;
4057 targetPowerValT2[ALL_TARGET_HT40_4] =
4058 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4059 is2GHz) + ht40PowerIncForPdadc;
4060 targetPowerValT2[ALL_TARGET_HT40_5] =
4061 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4062 is2GHz) + ht40PowerIncForPdadc;
4063 targetPowerValT2[ALL_TARGET_HT40_6] =
4064 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4065 is2GHz) + ht40PowerIncForPdadc;
4066 targetPowerValT2[ALL_TARGET_HT40_7] =
4067 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4068 is2GHz) + ht40PowerIncForPdadc;
4069 targetPowerValT2[ALL_TARGET_HT40_12] =
4070 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4071 is2GHz) + ht40PowerIncForPdadc;
4072 targetPowerValT2[ALL_TARGET_HT40_13] =
4073 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4074 is2GHz) + ht40PowerIncForPdadc;
4075 targetPowerValT2[ALL_TARGET_HT40_14] =
4076 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4077 is2GHz) + ht40PowerIncForPdadc;
4078 targetPowerValT2[ALL_TARGET_HT40_15] =
4079 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4080 is2GHz) + ht40PowerIncForPdadc;
4081 targetPowerValT2[ALL_TARGET_HT40_20] =
4082 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4083 is2GHz) + ht40PowerIncForPdadc;
4084 targetPowerValT2[ALL_TARGET_HT40_21] =
4085 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4086 is2GHz) + ht40PowerIncForPdadc;
4087 targetPowerValT2[ALL_TARGET_HT40_22] =
4088 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4089 is2GHz) + ht40PowerIncForPdadc;
4090 targetPowerValT2[ALL_TARGET_HT40_23] =
4091 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4092 is2GHz) + ht40PowerIncForPdadc;
4094 while (i < ar9300RateSize) {
4095 ath_print(common, ATH_DBG_EEPROM,
4096 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
4099 ath_print(common, ATH_DBG_EEPROM,
4100 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
4103 ath_print(common, ATH_DBG_EEPROM,
4104 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
4107 ath_print(common, ATH_DBG_EEPROM,
4108 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
4113 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4119 int *ptemperature, int *pvoltage)
4122 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4124 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4125 struct ath_common *common = ath9k_hw_common(ah);
4127 if (ichain >= AR9300_MAX_CHAINS) {
4128 ath_print(common, ATH_DBG_EEPROM,
4129 "Invalid chain index, must be less than %d\n",
4134 if (mode) { /* 5GHz */
4135 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4136 ath_print(common, ATH_DBG_EEPROM,
4137 "Invalid 5GHz cal pier index, must "
4138 "be less than %d\n",
4139 AR9300_NUM_5G_CAL_PIERS);
4142 pCalPier = &(eep->calFreqPier5G[ipier]);
4143 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4146 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4147 ath_print(common, ATH_DBG_EEPROM,
4148 "Invalid 2GHz cal pier index, must "
4149 "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
4153 pCalPier = &(eep->calFreqPier2G[ipier]);
4154 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4158 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
4159 *pcorrection = pCalPierStruct->refPower;
4160 *ptemperature = pCalPierStruct->tempMeas;
4161 *pvoltage = pCalPierStruct->voltMeas;
4166 static int ar9003_hw_power_control_override(struct ath_hw *ah,
4169 int *voltage, int *temperature)
4172 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4175 REG_RMW(ah, AR_PHY_TPC_11_B0,
4176 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4177 AR_PHY_TPC_OLPC_GAIN_DELTA);
4178 REG_RMW(ah, AR_PHY_TPC_11_B1,
4179 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4180 AR_PHY_TPC_OLPC_GAIN_DELTA);
4181 REG_RMW(ah, AR_PHY_TPC_11_B2,
4182 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4183 AR_PHY_TPC_OLPC_GAIN_DELTA);
4185 /* enable open loop power control on chip */
4186 REG_RMW(ah, AR_PHY_TPC_6_B0,
4187 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4188 AR_PHY_TPC_6_ERROR_EST_MODE);
4189 REG_RMW(ah, AR_PHY_TPC_6_B1,
4190 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4191 AR_PHY_TPC_6_ERROR_EST_MODE);
4192 REG_RMW(ah, AR_PHY_TPC_6_B2,
4193 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4194 AR_PHY_TPC_6_ERROR_EST_MODE);
4197 * enable temperature compensation
4198 * Need to use register names
4200 if (frequency < 4000)
4201 tempSlope = eep->modalHeader2G.tempSlope;
4202 else if (eep->base_ext2.tempSlopeLow != 0) {
4203 t[0] = eep->base_ext2.tempSlopeLow;
4205 t[1] = eep->modalHeader5G.tempSlope;
4207 t[2] = eep->base_ext2.tempSlopeHigh;
4209 tempSlope = ar9003_hw_power_interpolate((s32) frequency,
4212 tempSlope = eep->modalHeader5G.tempSlope;
4214 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
4215 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4221 /* Apply the recorded correction values. */
4222 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4224 int ichain, ipier, npier;
4226 int lfrequency[AR9300_MAX_CHAINS],
4227 lcorrection[AR9300_MAX_CHAINS],
4228 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4229 int hfrequency[AR9300_MAX_CHAINS],
4230 hcorrection[AR9300_MAX_CHAINS],
4231 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4233 int correction[AR9300_MAX_CHAINS],
4234 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4235 int pfrequency, pcorrection, ptemperature, pvoltage;
4236 struct ath_common *common = ath9k_hw_common(ah);
4238 mode = (frequency >= 4000);
4240 npier = AR9300_NUM_5G_CAL_PIERS;
4242 npier = AR9300_NUM_2G_CAL_PIERS;
4244 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4245 lfrequency[ichain] = 0;
4246 hfrequency[ichain] = 100000;
4248 /* identify best lower and higher frequency calibration measurement */
4249 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4250 for (ipier = 0; ipier < npier; ipier++) {
4251 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4252 &pfrequency, &pcorrection,
4253 &ptemperature, &pvoltage)) {
4254 fdiff = frequency - pfrequency;
4257 * this measurement is higher than
4258 * our desired frequency
4261 if (hfrequency[ichain] <= 0 ||
4262 hfrequency[ichain] >= 100000 ||
4264 (frequency - hfrequency[ichain])) {
4267 * frequency measurement
4269 hfrequency[ichain] = pfrequency;
4270 hcorrection[ichain] =
4272 htemperature[ichain] =
4274 hvoltage[ichain] = pvoltage;
4278 if (lfrequency[ichain] <= 0
4280 (frequency - lfrequency[ichain])) {
4283 * frequency measurement
4285 lfrequency[ichain] = pfrequency;
4286 lcorrection[ichain] =
4288 ltemperature[ichain] =
4290 lvoltage[ichain] = pvoltage;
4298 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4299 ath_print(common, ATH_DBG_EEPROM,
4300 "ch=%d f=%d low=%d %d h=%d %d\n",
4301 ichain, frequency, lfrequency[ichain],
4302 lcorrection[ichain], hfrequency[ichain],
4303 hcorrection[ichain]);
4304 /* they're the same, so just pick one */
4305 if (hfrequency[ichain] == lfrequency[ichain]) {
4306 correction[ichain] = lcorrection[ichain];
4307 voltage[ichain] = lvoltage[ichain];
4308 temperature[ichain] = ltemperature[ichain];
4310 /* the low frequency is good */
4311 else if (frequency - lfrequency[ichain] < 1000) {
4312 /* so is the high frequency, interpolate */
4313 if (hfrequency[ichain] - frequency < 1000) {
4315 correction[ichain] = interpolate(frequency,
4318 lcorrection[ichain],
4319 hcorrection[ichain]);
4321 temperature[ichain] = interpolate(frequency,
4324 ltemperature[ichain],
4325 htemperature[ichain]);
4327 voltage[ichain] = interpolate(frequency,
4333 /* only low is good, use it */
4335 correction[ichain] = lcorrection[ichain];
4336 temperature[ichain] = ltemperature[ichain];
4337 voltage[ichain] = lvoltage[ichain];
4340 /* only high is good, use it */
4341 else if (hfrequency[ichain] - frequency < 1000) {
4342 correction[ichain] = hcorrection[ichain];
4343 temperature[ichain] = htemperature[ichain];
4344 voltage[ichain] = hvoltage[ichain];
4345 } else { /* nothing is good, presume 0???? */
4346 correction[ichain] = 0;
4347 temperature[ichain] = 0;
4348 voltage[ichain] = 0;
4352 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4355 ath_print(common, ATH_DBG_EEPROM,
4356 "for frequency=%d, calibration correction = %d %d %d\n",
4357 frequency, correction[0], correction[1], correction[2]);
4362 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4367 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4368 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4371 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4373 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4376 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4382 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4383 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4385 u8 *ctl_freqbin = is2GHz ?
4386 &eep->ctl_freqbin_2G[idx][0] :
4387 &eep->ctl_freqbin_5G[idx][0];
4390 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4391 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4392 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4394 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4395 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4396 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4399 return AR9300_MAX_RATE_POWER;
4403 * Find the maximum conformance test limit for the given channel and CTL info
4405 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4406 u16 freq, int idx, bool is2GHz)
4408 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
4409 u8 *ctl_freqbin = is2GHz ?
4410 &eep->ctl_freqbin_2G[idx][0] :
4411 &eep->ctl_freqbin_5G[idx][0];
4412 u16 num_edges = is2GHz ?
4413 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4416 /* Get the edge power */
4418 (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED);
4421 * If there's an exact channel match or an inband flag set
4422 * on the lower channel use the given rdEdgePower
4424 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
4426 ar9003_hw_get_direct_edge_power(eep, idx,
4429 } else if ((edge > 0) &&
4430 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
4433 ar9003_hw_get_indirect_edge_power(eep, idx,
4437 * Leave loop - no more affecting edges possible in
4438 * this monotonic increasing list
4443 return twiceMaxEdgePower;
4446 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4447 struct ath9k_channel *chan,
4448 u8 *pPwrArray, u16 cfgCtl,
4449 u8 twiceAntennaReduction,
4450 u8 twiceMaxRegulatoryPower,
4453 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4454 struct ath_common *common = ath9k_hw_common(ah);
4455 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4456 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
4457 static const u16 tpScaleReductionTable[5] = {
4458 0, 3, 6, 9, AR9300_MAX_RATE_POWER
4461 int16_t twiceLargestAntenna;
4462 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4463 static const u16 ctlModesFor11a[] = {
4464 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4466 static const u16 ctlModesFor11g[] = {
4467 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
4468 CTL_11G_EXT, CTL_2GHT40
4471 const u16 *pCtlMode;
4473 struct chan_centers centers;
4476 u16 twiceMinEdgePower;
4477 bool is2ghz = IS_CHAN_2GHZ(chan);
4479 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4481 /* Compute TxPower reduction due to Antenna Gain */
4483 twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
4485 twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
4487 twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
4488 twiceLargestAntenna, 0);
4491 * scaledPower is the minimum of the user input power level
4492 * and the regulatory allowed power level
4494 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4496 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
4497 maxRegAllowedPower -=
4498 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
4501 scaledPower = min(powerLimit, maxRegAllowedPower);
4504 * Reduce scaled Power by number of chains active to get
4505 * to per chain tx power level
4507 switch (ar5416_get_ntxchains(ah->txchainmask)) {
4511 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
4514 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
4518 scaledPower = max((u16)0, scaledPower);
4521 * Get target powers from EEPROM - our baseline for TX Power
4524 /* Setup for CTL modes */
4525 /* CTL_11B, CTL_11G, CTL_2GHT20 */
4527 ARRAY_SIZE(ctlModesFor11g) -
4528 SUB_NUM_CTL_MODES_AT_2G_40;
4529 pCtlMode = ctlModesFor11g;
4530 if (IS_CHAN_HT40(chan))
4532 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4534 /* Setup for CTL modes */
4535 /* CTL_11A, CTL_5GHT20 */
4536 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
4537 SUB_NUM_CTL_MODES_AT_5G_40;
4538 pCtlMode = ctlModesFor11a;
4539 if (IS_CHAN_HT40(chan))
4541 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4545 * For MIMO, need to apply regulatory caps individually across
4546 * dynamically running modes: CCK, OFDM, HT20, HT40
4548 * The outer loop walks through each possible applicable runtime mode.
4549 * The inner loop walks through each ctlIndex entry in EEPROM.
4550 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
4552 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4553 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
4554 (pCtlMode[ctlMode] == CTL_2GHT40);
4556 freq = centers.synth_center;
4557 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4558 freq = centers.ext_center;
4560 freq = centers.ctl_center;
4562 ath_print(common, ATH_DBG_REGULATORY,
4563 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4564 "EXT_ADDITIVE %d\n",
4565 ctlMode, numCtlModes, isHt40CtlMode,
4566 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4568 /* walk through each CTL index stored in EEPROM */
4570 ctlIndex = pEepData->ctlIndex_2G;
4571 ctlNum = AR9300_NUM_CTLS_2G;
4573 ctlIndex = pEepData->ctlIndex_5G;
4574 ctlNum = AR9300_NUM_CTLS_5G;
4577 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
4578 ath_print(common, ATH_DBG_REGULATORY,
4579 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4580 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4582 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
4586 * compare test group from regulatory
4587 * channel list with test mode from pCtlMode
4590 if ((((cfgCtl & ~CTL_MODE_M) |
4591 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4593 (((cfgCtl & ~CTL_MODE_M) |
4594 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4595 ((ctlIndex[i] & CTL_MODE_M) |
4598 ar9003_hw_get_max_edge_power(pEepData,
4602 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
4604 * Find the minimum of all CTL
4605 * edge powers that apply to
4609 min(twiceMaxEdgePower,
4620 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
4622 ath_print(common, ATH_DBG_REGULATORY,
4623 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d "
4624 "sP %d minCtlPwr %d\n",
4625 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4626 scaledPower, minCtlPower);
4628 /* Apply ctl mode to correct target power set */
4629 switch (pCtlMode[ctlMode]) {
4631 for (i = ALL_TARGET_LEGACY_1L_5L;
4632 i <= ALL_TARGET_LEGACY_11S; i++)
4634 (u8)min((u16)pPwrArray[i],
4639 for (i = ALL_TARGET_LEGACY_6_24;
4640 i <= ALL_TARGET_LEGACY_54; i++)
4642 (u8)min((u16)pPwrArray[i],
4647 for (i = ALL_TARGET_HT20_0_8_16;
4648 i <= ALL_TARGET_HT20_21; i++)
4650 (u8)min((u16)pPwrArray[i],
4652 pPwrArray[ALL_TARGET_HT20_22] =
4653 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
4655 pPwrArray[ALL_TARGET_HT20_23] =
4656 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
4661 for (i = ALL_TARGET_HT40_0_8_16;
4662 i <= ALL_TARGET_HT40_23; i++)
4664 (u8)min((u16)pPwrArray[i],
4670 } /* end ctl mode checking */
4673 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4674 struct ath9k_channel *chan, u16 cfgCtl,
4675 u8 twiceAntennaReduction,
4676 u8 twiceMaxRegulatoryPower,
4677 u8 powerLimit, bool test)
4679 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4680 struct ath_common *common = ath9k_hw_common(ah);
4681 u8 targetPowerValT2[ar9300RateSize];
4684 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
4685 ar9003_hw_set_power_per_rate_table(ah, chan,
4686 targetPowerValT2, cfgCtl,
4687 twiceAntennaReduction,
4688 twiceMaxRegulatoryPower,
4691 regulatory->max_power_level = 0;
4692 for (i = 0; i < ar9300RateSize; i++) {
4693 if (targetPowerValT2[i] > regulatory->max_power_level)
4694 regulatory->max_power_level = targetPowerValT2[i];
4700 for (i = 0; i < ar9300RateSize; i++) {
4701 ath_print(common, ATH_DBG_EEPROM,
4702 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
4704 ath_print(common, ATH_DBG_EEPROM,
4705 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
4707 ath_print(common, ATH_DBG_EEPROM,
4708 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
4710 ath_print(common, ATH_DBG_EEPROM,
4711 "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]);
4716 * This is the TX power we send back to driver core,
4717 * and it can use to pass to userspace to display our
4718 * currently configured TX power setting.
4720 * Since power is rate dependent, use one of the indices
4721 * from the AR9300_Rates enum to select an entry from
4722 * targetPowerValT2[] to report. Currently returns the
4723 * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
4724 * as CCK power is less interesting (?).
4726 i = ALL_TARGET_LEGACY_6_24; /* legacy */
4727 if (IS_CHAN_HT40(chan))
4728 i = ALL_TARGET_HT40_0_8_16; /* ht40 */
4729 else if (IS_CHAN_HT20(chan))
4730 i = ALL_TARGET_HT20_0_8_16; /* ht20 */
4732 ah->txpower_limit = targetPowerValT2[i];
4733 regulatory->max_power_level = targetPowerValT2[i];
4735 /* Write target power array to registers */
4736 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
4737 ar9003_hw_calibration_apply(ah, chan->channel);
4740 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
4746 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
4748 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4750 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
4753 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
4755 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4757 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
4760 const struct eeprom_ops eep_ar9300_ops = {
4761 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
4762 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
4763 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
4764 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
4765 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
4766 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
4767 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
4768 .set_board_values = ath9k_hw_ar9300_set_board_values,
4769 .set_addac = ath9k_hw_ar9300_set_addac,
4770 .set_txpower = ath9k_hw_ar9300_set_txpower,
4771 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel