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_dbg(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_dbg(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_dbg(common, ATH_DBG_EEPROM,
3193 "Restore at %d: spot=%d offset=%d length=%d\n",
3194 it, spot, offset, length);
3195 memcpy(&mptr[spot], &block[it+2], length);
3197 } else if (length > 0) {
3198 ath_dbg(common, ATH_DBG_EEPROM,
3199 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3200 it, spot, offset, length);
3207 static int ar9300_compress_decision(struct ath_hw *ah,
3212 u8 *word, int length, int mdata_size)
3214 struct ath_common *common = ath9k_hw_common(ah);
3216 const struct ar9300_eeprom *eep = NULL;
3220 if (length != mdata_size) {
3221 ath_dbg(common, ATH_DBG_EEPROM,
3222 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3223 mdata_size, length);
3226 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
3227 ath_dbg(common, ATH_DBG_EEPROM,
3228 "restored eeprom %d: uncompressed, length %d\n",
3231 case _CompressBlock:
3232 if (reference == 0) {
3235 eep = ar9003_eeprom_struct_find_by_id(reference);
3237 ath_dbg(common, ATH_DBG_EEPROM,
3238 "cant find reference eeprom struct %d\n",
3242 memcpy(mptr, eep, mdata_size);
3244 ath_dbg(common, ATH_DBG_EEPROM,
3245 "restore eeprom %d: block, reference %d, length %d\n",
3246 it, reference, length);
3247 ar9300_uncompress_block(ah, mptr, mdata_size,
3248 (u8 *) (word + COMP_HDR_LEN), length);
3251 ath_dbg(common, ATH_DBG_EEPROM,
3252 "unknown compression code %d\n", code);
3258 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3261 static bool ar9300_check_header(void *data)
3264 return !(*word == 0 || *word == ~0);
3267 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3272 if (!read(ah, base_addr, header, 4))
3275 return ar9300_check_header(header);
3278 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3281 struct ath_common *common = ath9k_hw_common(ah);
3282 u16 *data = (u16 *) mptr;
3285 for (i = 0; i < mdata_size / 2; i++, data++)
3286 ath9k_hw_nvram_read(common, i, data);
3291 * Read the configuration data from the eeprom.
3292 * The data can be put in any specified memory buffer.
3294 * Returns -1 on error.
3295 * Returns address of next memory location on success.
3297 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3298 u8 *mptr, int mdata_size)
3305 int reference, length, major, minor;
3308 u16 checksum, mchecksum;
3309 struct ath_common *common = ath9k_hw_common(ah);
3310 eeprom_read_op read;
3312 if (ath9k_hw_use_flash(ah))
3313 return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3315 word = kzalloc(2048, GFP_KERNEL);
3319 memcpy(mptr, &ar9300_default, mdata_size);
3321 read = ar9300_read_eeprom;
3322 cptr = AR9300_BASE_ADDR;
3323 ath_dbg(common, ATH_DBG_EEPROM,
3324 "Trying EEPROM accesss at Address 0x%04x\n", cptr);
3325 if (ar9300_check_eeprom_header(ah, read, cptr))
3328 cptr = AR9300_BASE_ADDR_512;
3329 ath_dbg(common, ATH_DBG_EEPROM,
3330 "Trying EEPROM accesss at Address 0x%04x\n", cptr);
3331 if (ar9300_check_eeprom_header(ah, read, cptr))
3334 read = ar9300_read_otp;
3335 cptr = AR9300_BASE_ADDR;
3336 ath_dbg(common, ATH_DBG_EEPROM,
3337 "Trying OTP accesss at Address 0x%04x\n", cptr);
3338 if (ar9300_check_eeprom_header(ah, read, cptr))
3341 cptr = AR9300_BASE_ADDR_512;
3342 ath_dbg(common, ATH_DBG_EEPROM,
3343 "Trying OTP accesss at Address 0x%04x\n", cptr);
3344 if (ar9300_check_eeprom_header(ah, read, cptr))
3350 ath_dbg(common, ATH_DBG_EEPROM, "Found valid EEPROM data\n");
3352 for (it = 0; it < MSTATE; it++) {
3353 if (!read(ah, cptr, word, COMP_HDR_LEN))
3356 if (!ar9300_check_header(word))
3359 ar9300_comp_hdr_unpack(word, &code, &reference,
3360 &length, &major, &minor);
3361 ath_dbg(common, ATH_DBG_EEPROM,
3362 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3363 cptr, code, reference, length, major, minor);
3364 if (length >= 1024) {
3365 ath_dbg(common, ATH_DBG_EEPROM,
3366 "Skipping bad header\n");
3367 cptr -= COMP_HDR_LEN;
3372 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3373 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3374 mchecksum = word[COMP_HDR_LEN + osize] |
3375 (word[COMP_HDR_LEN + osize + 1] << 8);
3376 ath_dbg(common, ATH_DBG_EEPROM,
3377 "checksum %x %x\n", checksum, mchecksum);
3378 if (checksum == mchecksum) {
3379 ar9300_compress_decision(ah, it, code, reference, mptr,
3380 word, length, mdata_size);
3382 ath_dbg(common, ATH_DBG_EEPROM,
3383 "skipping block with bad checksum\n");
3385 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3397 * Restore the configuration structure by reading the eeprom.
3398 * This function destroys any existing in-memory structure
3401 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3403 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3405 if (ar9300_eeprom_restore_internal(ah, mptr,
3406 sizeof(struct ar9300_eeprom)) < 0)
3412 /* XXX: review hardware docs */
3413 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3415 return ah->eeprom.ar9300_eep.eepromVersion;
3418 /* XXX: could be read from the eepromVersion, not sure yet */
3419 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3424 static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
3425 enum ath9k_hal_freq_band freq_band)
3430 static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
3431 struct ath9k_channel *chan)
3436 static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
3438 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3441 return eep->modalHeader2G.xpaBiasLvl;
3443 return eep->modalHeader5G.xpaBiasLvl;
3446 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3448 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
3449 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3450 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, bias >> 2);
3451 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
3454 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3456 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3460 val = eep->modalHeader2G.antCtrlCommon;
3462 val = eep->modalHeader5G.antCtrlCommon;
3463 return le32_to_cpu(val);
3466 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3468 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3472 val = eep->modalHeader2G.antCtrlCommon2;
3474 val = eep->modalHeader5G.antCtrlCommon2;
3475 return le32_to_cpu(val);
3478 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
3482 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3485 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
3487 val = eep->modalHeader2G.antCtrlChain[chain];
3489 val = eep->modalHeader5G.antCtrlChain[chain];
3492 return le16_to_cpu(val);
3495 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3497 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3498 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
3500 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3501 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3503 value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
3504 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
3506 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3507 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
3509 value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
3510 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
3513 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3518 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
3520 if (!drive_strength)
3523 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3531 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3533 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3544 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3546 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3551 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3554 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3555 struct ath9k_channel *chan)
3559 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3561 if (chain >= 0 && chain < 3) {
3562 if (IS_CHAN_2GHZ(chan))
3563 return eep->modalHeader2G.xatten1DB[chain];
3564 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3565 t[0] = eep->base_ext2.xatten1DBLow[chain];
3567 t[1] = eep->modalHeader5G.xatten1DB[chain];
3569 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3571 value = ar9003_hw_power_interpolate((s32) chan->channel,
3575 return eep->modalHeader5G.xatten1DB[chain];
3582 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3583 struct ath9k_channel *chan)
3587 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3589 if (chain >= 0 && chain < 3) {
3590 if (IS_CHAN_2GHZ(chan))
3591 return eep->modalHeader2G.xatten1Margin[chain];
3592 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3593 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3595 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3597 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3599 value = ar9003_hw_power_interpolate((s32) chan->channel,
3603 return eep->modalHeader5G.xatten1Margin[chain];
3609 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3613 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3614 AR_PHY_EXT_ATTEN_CTL_1,
3615 AR_PHY_EXT_ATTEN_CTL_2,
3618 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3619 for (i = 0; i < 3; i++) {
3620 value = ar9003_hw_atten_chain_get(ah, i, chan);
3621 REG_RMW_FIELD(ah, ext_atten_reg[i],
3622 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3624 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3625 REG_RMW_FIELD(ah, ext_atten_reg[i],
3626 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
3630 static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3632 int internal_regulator =
3633 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
3635 if (internal_regulator) {
3636 /* Internal regulator is ON. Write swreg register. */
3637 int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
3638 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3639 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3640 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3641 REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
3642 /* Set REG_CONTROL1.SWREG_PROGRAM */
3643 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3645 AR_RTC_REG_CONTROL1) |
3646 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3648 REG_WRITE(ah, AR_RTC_SLEEP_CLK,
3651 AR_RTC_FORCE_SWREG_PRD));
3655 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3656 struct ath9k_channel *chan)
3658 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
3659 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
3660 ar9003_hw_drive_strength_apply(ah);
3661 ar9003_hw_atten_apply(ah, chan);
3662 ar9003_hw_internal_regulator_apply(ah);
3665 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
3666 struct ath9k_channel *chan)
3671 * Returns the interpolated y value corresponding to the specified x value
3672 * from the np ordered pairs of data (px,py).
3673 * The pairs do not have to be in any order.
3674 * If the specified x value is less than any of the px,
3675 * the returned y value is equal to the py for the lowest px.
3676 * If the specified x value is greater than any of the px,
3677 * the returned y value is equal to the py for the highest px.
3679 static int ar9003_hw_power_interpolate(int32_t x,
3680 int32_t *px, int32_t *py, u_int16_t np)
3683 int lx = 0, ly = 0, lhave = 0;
3684 int hx = 0, hy = 0, hhave = 0;
3691 /* identify best lower and higher x calibration measurement */
3692 for (ip = 0; ip < np; ip++) {
3695 /* this measurement is higher than our desired x */
3697 if (!hhave || dx > (x - hx)) {
3698 /* new best higher x measurement */
3704 /* this measurement is lower than our desired x */
3706 if (!lhave || dx < (x - lx)) {
3707 /* new best lower x measurement */
3715 /* the low x is good */
3717 /* so is the high x */
3719 /* they're the same, so just pick one */
3722 else /* interpolate */
3723 y = interpolate(x, lx, hx, ly, hy);
3724 } else /* only low is good, use it */
3726 } else if (hhave) /* only high is good, use it */
3728 else /* nothing is good,this should never happen unless np=0, ???? */
3733 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
3734 u16 rateIndex, u16 freq, bool is2GHz)
3737 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
3738 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
3739 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3740 struct cal_tgt_pow_legacy *pEepromTargetPwr;
3744 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
3745 pEepromTargetPwr = eep->calTargetPower2G;
3746 pFreqBin = eep->calTarget_freqbin_2G;
3748 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
3749 pEepromTargetPwr = eep->calTargetPower5G;
3750 pFreqBin = eep->calTarget_freqbin_5G;
3754 * create array of channels and targetpower from
3755 * targetpower piers stored on eeprom
3757 for (i = 0; i < numPiers; i++) {
3758 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
3759 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3762 /* interpolate to get target power for given frequency */
3763 return (u8) ar9003_hw_power_interpolate((s32) freq,
3765 targetPowerArray, numPiers);
3768 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
3770 u16 freq, bool is2GHz)
3773 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
3774 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
3775 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3776 struct cal_tgt_pow_ht *pEepromTargetPwr;
3780 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
3781 pEepromTargetPwr = eep->calTargetPower2GHT20;
3782 pFreqBin = eep->calTarget_freqbin_2GHT20;
3784 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
3785 pEepromTargetPwr = eep->calTargetPower5GHT20;
3786 pFreqBin = eep->calTarget_freqbin_5GHT20;
3790 * create array of channels and targetpower
3791 * from targetpower piers stored on eeprom
3793 for (i = 0; i < numPiers; i++) {
3794 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
3795 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3798 /* interpolate to get target power for given frequency */
3799 return (u8) ar9003_hw_power_interpolate((s32) freq,
3801 targetPowerArray, numPiers);
3804 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
3806 u16 freq, bool is2GHz)
3809 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
3810 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
3811 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3812 struct cal_tgt_pow_ht *pEepromTargetPwr;
3816 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
3817 pEepromTargetPwr = eep->calTargetPower2GHT40;
3818 pFreqBin = eep->calTarget_freqbin_2GHT40;
3820 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
3821 pEepromTargetPwr = eep->calTargetPower5GHT40;
3822 pFreqBin = eep->calTarget_freqbin_5GHT40;
3826 * create array of channels and targetpower from
3827 * targetpower piers stored on eeprom
3829 for (i = 0; i < numPiers; i++) {
3830 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
3831 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3834 /* interpolate to get target power for given frequency */
3835 return (u8) ar9003_hw_power_interpolate((s32) freq,
3837 targetPowerArray, numPiers);
3840 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
3841 u16 rateIndex, u16 freq)
3843 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
3844 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
3845 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
3846 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3847 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
3848 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
3851 * create array of channels and targetpower from
3852 * targetpower piers stored on eeprom
3854 for (i = 0; i < numPiers; i++) {
3855 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
3856 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3859 /* interpolate to get target power for given frequency */
3860 return (u8) ar9003_hw_power_interpolate((s32) freq,
3862 targetPowerArray, numPiers);
3865 /* Set tx power registers to array of values passed in */
3866 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
3868 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
3869 /* make sure forced gain is not set */
3870 REG_WRITE(ah, 0xa458, 0);
3872 /* Write the OFDM power per rate set */
3874 /* 6 (LSB), 9, 12, 18 (MSB) */
3875 REG_WRITE(ah, 0xa3c0,
3876 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
3877 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
3878 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
3879 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
3881 /* 24 (LSB), 36, 48, 54 (MSB) */
3882 REG_WRITE(ah, 0xa3c4,
3883 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
3884 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
3885 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
3886 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
3888 /* Write the CCK power per rate set */
3890 /* 1L (LSB), reserved, 2L, 2S (MSB) */
3891 REG_WRITE(ah, 0xa3c8,
3892 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
3893 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
3894 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
3895 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
3897 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
3898 REG_WRITE(ah, 0xa3cc,
3899 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
3900 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
3901 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
3902 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
3905 /* Write the HT20 power per rate set */
3907 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
3908 REG_WRITE(ah, 0xa3d0,
3909 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
3910 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
3911 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
3912 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
3915 /* 6 (LSB), 7, 12, 13 (MSB) */
3916 REG_WRITE(ah, 0xa3d4,
3917 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
3918 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
3919 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
3920 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
3923 /* 14 (LSB), 15, 20, 21 */
3924 REG_WRITE(ah, 0xa3e4,
3925 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
3926 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
3927 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
3928 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
3931 /* Mixed HT20 and HT40 rates */
3933 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
3934 REG_WRITE(ah, 0xa3e8,
3935 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
3936 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
3937 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
3938 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
3942 * Write the HT40 power per rate set
3943 * correct PAR difference between HT40 and HT20/LEGACY
3944 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
3946 REG_WRITE(ah, 0xa3d8,
3947 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
3948 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
3949 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
3950 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
3953 /* 6 (LSB), 7, 12, 13 (MSB) */
3954 REG_WRITE(ah, 0xa3dc,
3955 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
3956 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
3957 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
3958 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
3961 /* 14 (LSB), 15, 20, 21 */
3962 REG_WRITE(ah, 0xa3ec,
3963 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
3964 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
3965 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
3966 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
3973 static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
3974 u8 *targetPowerValT2)
3976 /* XXX: hard code for now, need to get from eeprom struct */
3977 u8 ht40PowerIncForPdadc = 0;
3978 bool is2GHz = false;
3980 struct ath_common *common = ath9k_hw_common(ah);
3985 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
3986 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
3988 targetPowerValT2[ALL_TARGET_LEGACY_36] =
3989 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
3991 targetPowerValT2[ALL_TARGET_LEGACY_48] =
3992 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
3994 targetPowerValT2[ALL_TARGET_LEGACY_54] =
3995 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
3997 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
3998 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4000 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4001 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4002 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4003 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4004 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4005 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4006 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4007 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4009 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4010 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4012 targetPowerValT2[ALL_TARGET_HT20_4] =
4013 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4015 targetPowerValT2[ALL_TARGET_HT20_5] =
4016 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4018 targetPowerValT2[ALL_TARGET_HT20_6] =
4019 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4021 targetPowerValT2[ALL_TARGET_HT20_7] =
4022 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4024 targetPowerValT2[ALL_TARGET_HT20_12] =
4025 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4027 targetPowerValT2[ALL_TARGET_HT20_13] =
4028 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4030 targetPowerValT2[ALL_TARGET_HT20_14] =
4031 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4033 targetPowerValT2[ALL_TARGET_HT20_15] =
4034 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4036 targetPowerValT2[ALL_TARGET_HT20_20] =
4037 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4039 targetPowerValT2[ALL_TARGET_HT20_21] =
4040 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4042 targetPowerValT2[ALL_TARGET_HT20_22] =
4043 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4045 targetPowerValT2[ALL_TARGET_HT20_23] =
4046 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4048 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4049 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4050 is2GHz) + ht40PowerIncForPdadc;
4051 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4052 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4054 is2GHz) + ht40PowerIncForPdadc;
4055 targetPowerValT2[ALL_TARGET_HT40_4] =
4056 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4057 is2GHz) + ht40PowerIncForPdadc;
4058 targetPowerValT2[ALL_TARGET_HT40_5] =
4059 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4060 is2GHz) + ht40PowerIncForPdadc;
4061 targetPowerValT2[ALL_TARGET_HT40_6] =
4062 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4063 is2GHz) + ht40PowerIncForPdadc;
4064 targetPowerValT2[ALL_TARGET_HT40_7] =
4065 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4066 is2GHz) + ht40PowerIncForPdadc;
4067 targetPowerValT2[ALL_TARGET_HT40_12] =
4068 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4069 is2GHz) + ht40PowerIncForPdadc;
4070 targetPowerValT2[ALL_TARGET_HT40_13] =
4071 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4072 is2GHz) + ht40PowerIncForPdadc;
4073 targetPowerValT2[ALL_TARGET_HT40_14] =
4074 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4075 is2GHz) + ht40PowerIncForPdadc;
4076 targetPowerValT2[ALL_TARGET_HT40_15] =
4077 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4078 is2GHz) + ht40PowerIncForPdadc;
4079 targetPowerValT2[ALL_TARGET_HT40_20] =
4080 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4081 is2GHz) + ht40PowerIncForPdadc;
4082 targetPowerValT2[ALL_TARGET_HT40_21] =
4083 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4084 is2GHz) + ht40PowerIncForPdadc;
4085 targetPowerValT2[ALL_TARGET_HT40_22] =
4086 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4087 is2GHz) + ht40PowerIncForPdadc;
4088 targetPowerValT2[ALL_TARGET_HT40_23] =
4089 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4090 is2GHz) + ht40PowerIncForPdadc;
4092 for (i = 0; i < ar9300RateSize; i++) {
4093 ath_dbg(common, ATH_DBG_EEPROM,
4094 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
4098 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4104 int *ptemperature, int *pvoltage)
4107 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4109 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4110 struct ath_common *common = ath9k_hw_common(ah);
4112 if (ichain >= AR9300_MAX_CHAINS) {
4113 ath_dbg(common, ATH_DBG_EEPROM,
4114 "Invalid chain index, must be less than %d\n",
4119 if (mode) { /* 5GHz */
4120 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4121 ath_dbg(common, ATH_DBG_EEPROM,
4122 "Invalid 5GHz cal pier index, must be less than %d\n",
4123 AR9300_NUM_5G_CAL_PIERS);
4126 pCalPier = &(eep->calFreqPier5G[ipier]);
4127 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4130 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4131 ath_dbg(common, ATH_DBG_EEPROM,
4132 "Invalid 2GHz cal pier index, must be less than %d\n",
4133 AR9300_NUM_2G_CAL_PIERS);
4137 pCalPier = &(eep->calFreqPier2G[ipier]);
4138 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4142 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
4143 *pcorrection = pCalPierStruct->refPower;
4144 *ptemperature = pCalPierStruct->tempMeas;
4145 *pvoltage = pCalPierStruct->voltMeas;
4150 static int ar9003_hw_power_control_override(struct ath_hw *ah,
4153 int *voltage, int *temperature)
4156 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4159 REG_RMW(ah, AR_PHY_TPC_11_B0,
4160 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4161 AR_PHY_TPC_OLPC_GAIN_DELTA);
4162 REG_RMW(ah, AR_PHY_TPC_11_B1,
4163 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4164 AR_PHY_TPC_OLPC_GAIN_DELTA);
4165 REG_RMW(ah, AR_PHY_TPC_11_B2,
4166 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4167 AR_PHY_TPC_OLPC_GAIN_DELTA);
4169 /* enable open loop power control on chip */
4170 REG_RMW(ah, AR_PHY_TPC_6_B0,
4171 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4172 AR_PHY_TPC_6_ERROR_EST_MODE);
4173 REG_RMW(ah, AR_PHY_TPC_6_B1,
4174 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4175 AR_PHY_TPC_6_ERROR_EST_MODE);
4176 REG_RMW(ah, AR_PHY_TPC_6_B2,
4177 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4178 AR_PHY_TPC_6_ERROR_EST_MODE);
4181 * enable temperature compensation
4182 * Need to use register names
4184 if (frequency < 4000)
4185 tempSlope = eep->modalHeader2G.tempSlope;
4186 else if (eep->base_ext2.tempSlopeLow != 0) {
4187 t[0] = eep->base_ext2.tempSlopeLow;
4189 t[1] = eep->modalHeader5G.tempSlope;
4191 t[2] = eep->base_ext2.tempSlopeHigh;
4193 tempSlope = ar9003_hw_power_interpolate((s32) frequency,
4196 tempSlope = eep->modalHeader5G.tempSlope;
4198 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
4199 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4205 /* Apply the recorded correction values. */
4206 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4208 int ichain, ipier, npier;
4210 int lfrequency[AR9300_MAX_CHAINS],
4211 lcorrection[AR9300_MAX_CHAINS],
4212 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4213 int hfrequency[AR9300_MAX_CHAINS],
4214 hcorrection[AR9300_MAX_CHAINS],
4215 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4217 int correction[AR9300_MAX_CHAINS],
4218 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4219 int pfrequency, pcorrection, ptemperature, pvoltage;
4220 struct ath_common *common = ath9k_hw_common(ah);
4222 mode = (frequency >= 4000);
4224 npier = AR9300_NUM_5G_CAL_PIERS;
4226 npier = AR9300_NUM_2G_CAL_PIERS;
4228 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4229 lfrequency[ichain] = 0;
4230 hfrequency[ichain] = 100000;
4232 /* identify best lower and higher frequency calibration measurement */
4233 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4234 for (ipier = 0; ipier < npier; ipier++) {
4235 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4236 &pfrequency, &pcorrection,
4237 &ptemperature, &pvoltage)) {
4238 fdiff = frequency - pfrequency;
4241 * this measurement is higher than
4242 * our desired frequency
4245 if (hfrequency[ichain] <= 0 ||
4246 hfrequency[ichain] >= 100000 ||
4248 (frequency - hfrequency[ichain])) {
4251 * frequency measurement
4253 hfrequency[ichain] = pfrequency;
4254 hcorrection[ichain] =
4256 htemperature[ichain] =
4258 hvoltage[ichain] = pvoltage;
4262 if (lfrequency[ichain] <= 0
4264 (frequency - lfrequency[ichain])) {
4267 * frequency measurement
4269 lfrequency[ichain] = pfrequency;
4270 lcorrection[ichain] =
4272 ltemperature[ichain] =
4274 lvoltage[ichain] = pvoltage;
4282 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4283 ath_dbg(common, ATH_DBG_EEPROM,
4284 "ch=%d f=%d low=%d %d h=%d %d\n",
4285 ichain, frequency, lfrequency[ichain],
4286 lcorrection[ichain], hfrequency[ichain],
4287 hcorrection[ichain]);
4288 /* they're the same, so just pick one */
4289 if (hfrequency[ichain] == lfrequency[ichain]) {
4290 correction[ichain] = lcorrection[ichain];
4291 voltage[ichain] = lvoltage[ichain];
4292 temperature[ichain] = ltemperature[ichain];
4294 /* the low frequency is good */
4295 else if (frequency - lfrequency[ichain] < 1000) {
4296 /* so is the high frequency, interpolate */
4297 if (hfrequency[ichain] - frequency < 1000) {
4299 correction[ichain] = interpolate(frequency,
4302 lcorrection[ichain],
4303 hcorrection[ichain]);
4305 temperature[ichain] = interpolate(frequency,
4308 ltemperature[ichain],
4309 htemperature[ichain]);
4311 voltage[ichain] = interpolate(frequency,
4317 /* only low is good, use it */
4319 correction[ichain] = lcorrection[ichain];
4320 temperature[ichain] = ltemperature[ichain];
4321 voltage[ichain] = lvoltage[ichain];
4324 /* only high is good, use it */
4325 else if (hfrequency[ichain] - frequency < 1000) {
4326 correction[ichain] = hcorrection[ichain];
4327 temperature[ichain] = htemperature[ichain];
4328 voltage[ichain] = hvoltage[ichain];
4329 } else { /* nothing is good, presume 0???? */
4330 correction[ichain] = 0;
4331 temperature[ichain] = 0;
4332 voltage[ichain] = 0;
4336 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4339 ath_dbg(common, ATH_DBG_EEPROM,
4340 "for frequency=%d, calibration correction = %d %d %d\n",
4341 frequency, correction[0], correction[1], correction[2]);
4346 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4351 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4352 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4355 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4357 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4360 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4366 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4367 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4369 u8 *ctl_freqbin = is2GHz ?
4370 &eep->ctl_freqbin_2G[idx][0] :
4371 &eep->ctl_freqbin_5G[idx][0];
4374 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4375 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4376 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4378 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4379 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4380 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4383 return AR9300_MAX_RATE_POWER;
4387 * Find the maximum conformance test limit for the given channel and CTL info
4389 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4390 u16 freq, int idx, bool is2GHz)
4392 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
4393 u8 *ctl_freqbin = is2GHz ?
4394 &eep->ctl_freqbin_2G[idx][0] :
4395 &eep->ctl_freqbin_5G[idx][0];
4396 u16 num_edges = is2GHz ?
4397 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4400 /* Get the edge power */
4402 (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED);
4405 * If there's an exact channel match or an inband flag set
4406 * on the lower channel use the given rdEdgePower
4408 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
4410 ar9003_hw_get_direct_edge_power(eep, idx,
4413 } else if ((edge > 0) &&
4414 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
4417 ar9003_hw_get_indirect_edge_power(eep, idx,
4421 * Leave loop - no more affecting edges possible in
4422 * this monotonic increasing list
4427 return twiceMaxEdgePower;
4430 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4431 struct ath9k_channel *chan,
4432 u8 *pPwrArray, u16 cfgCtl,
4433 u8 twiceAntennaReduction,
4434 u8 twiceMaxRegulatoryPower,
4437 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4438 struct ath_common *common = ath9k_hw_common(ah);
4439 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4440 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
4441 static const u16 tpScaleReductionTable[5] = {
4442 0, 3, 6, 9, AR9300_MAX_RATE_POWER
4445 int16_t twiceLargestAntenna;
4446 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4447 static const u16 ctlModesFor11a[] = {
4448 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4450 static const u16 ctlModesFor11g[] = {
4451 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
4452 CTL_11G_EXT, CTL_2GHT40
4455 const u16 *pCtlMode;
4457 struct chan_centers centers;
4460 u16 twiceMinEdgePower;
4461 bool is2ghz = IS_CHAN_2GHZ(chan);
4463 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4465 /* Compute TxPower reduction due to Antenna Gain */
4467 twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
4469 twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
4471 twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
4472 twiceLargestAntenna, 0);
4475 * scaledPower is the minimum of the user input power level
4476 * and the regulatory allowed power level
4478 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4480 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
4481 maxRegAllowedPower -=
4482 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
4485 scaledPower = min(powerLimit, maxRegAllowedPower);
4488 * Reduce scaled Power by number of chains active to get
4489 * to per chain tx power level
4491 switch (ar5416_get_ntxchains(ah->txchainmask)) {
4495 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
4498 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
4502 scaledPower = max((u16)0, scaledPower);
4505 * Get target powers from EEPROM - our baseline for TX Power
4508 /* Setup for CTL modes */
4509 /* CTL_11B, CTL_11G, CTL_2GHT20 */
4511 ARRAY_SIZE(ctlModesFor11g) -
4512 SUB_NUM_CTL_MODES_AT_2G_40;
4513 pCtlMode = ctlModesFor11g;
4514 if (IS_CHAN_HT40(chan))
4516 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4518 /* Setup for CTL modes */
4519 /* CTL_11A, CTL_5GHT20 */
4520 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
4521 SUB_NUM_CTL_MODES_AT_5G_40;
4522 pCtlMode = ctlModesFor11a;
4523 if (IS_CHAN_HT40(chan))
4525 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4529 * For MIMO, need to apply regulatory caps individually across
4530 * dynamically running modes: CCK, OFDM, HT20, HT40
4532 * The outer loop walks through each possible applicable runtime mode.
4533 * The inner loop walks through each ctlIndex entry in EEPROM.
4534 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
4536 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4537 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
4538 (pCtlMode[ctlMode] == CTL_2GHT40);
4540 freq = centers.synth_center;
4541 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4542 freq = centers.ext_center;
4544 freq = centers.ctl_center;
4546 ath_dbg(common, ATH_DBG_REGULATORY,
4547 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
4548 ctlMode, numCtlModes, isHt40CtlMode,
4549 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4551 /* walk through each CTL index stored in EEPROM */
4553 ctlIndex = pEepData->ctlIndex_2G;
4554 ctlNum = AR9300_NUM_CTLS_2G;
4556 ctlIndex = pEepData->ctlIndex_5G;
4557 ctlNum = AR9300_NUM_CTLS_5G;
4560 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
4561 ath_dbg(common, ATH_DBG_REGULATORY,
4562 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
4563 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
4567 * compare test group from regulatory
4568 * channel list with test mode from pCtlMode
4571 if ((((cfgCtl & ~CTL_MODE_M) |
4572 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4574 (((cfgCtl & ~CTL_MODE_M) |
4575 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4576 ((ctlIndex[i] & CTL_MODE_M) |
4579 ar9003_hw_get_max_edge_power(pEepData,
4583 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
4585 * Find the minimum of all CTL
4586 * edge powers that apply to
4590 min(twiceMaxEdgePower,
4601 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
4603 ath_dbg(common, ATH_DBG_REGULATORY,
4604 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
4605 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4606 scaledPower, minCtlPower);
4608 /* Apply ctl mode to correct target power set */
4609 switch (pCtlMode[ctlMode]) {
4611 for (i = ALL_TARGET_LEGACY_1L_5L;
4612 i <= ALL_TARGET_LEGACY_11S; i++)
4614 (u8)min((u16)pPwrArray[i],
4619 for (i = ALL_TARGET_LEGACY_6_24;
4620 i <= ALL_TARGET_LEGACY_54; i++)
4622 (u8)min((u16)pPwrArray[i],
4627 for (i = ALL_TARGET_HT20_0_8_16;
4628 i <= ALL_TARGET_HT20_21; i++)
4630 (u8)min((u16)pPwrArray[i],
4632 pPwrArray[ALL_TARGET_HT20_22] =
4633 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
4635 pPwrArray[ALL_TARGET_HT20_23] =
4636 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
4641 for (i = ALL_TARGET_HT40_0_8_16;
4642 i <= ALL_TARGET_HT40_23; i++)
4644 (u8)min((u16)pPwrArray[i],
4650 } /* end ctl mode checking */
4653 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4654 struct ath9k_channel *chan, u16 cfgCtl,
4655 u8 twiceAntennaReduction,
4656 u8 twiceMaxRegulatoryPower,
4657 u8 powerLimit, bool test)
4659 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4660 struct ath_common *common = ath9k_hw_common(ah);
4661 u8 targetPowerValT2[ar9300RateSize];
4664 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
4665 ar9003_hw_set_power_per_rate_table(ah, chan,
4666 targetPowerValT2, cfgCtl,
4667 twiceAntennaReduction,
4668 twiceMaxRegulatoryPower,
4671 regulatory->max_power_level = 0;
4672 for (i = 0; i < ar9300RateSize; i++) {
4673 if (targetPowerValT2[i] > regulatory->max_power_level)
4674 regulatory->max_power_level = targetPowerValT2[i];
4680 for (i = 0; i < ar9300RateSize; i++) {
4681 ath_dbg(common, ATH_DBG_EEPROM,
4682 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
4686 * This is the TX power we send back to driver core,
4687 * and it can use to pass to userspace to display our
4688 * currently configured TX power setting.
4690 * Since power is rate dependent, use one of the indices
4691 * from the AR9300_Rates enum to select an entry from
4692 * targetPowerValT2[] to report. Currently returns the
4693 * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
4694 * as CCK power is less interesting (?).
4696 i = ALL_TARGET_LEGACY_6_24; /* legacy */
4697 if (IS_CHAN_HT40(chan))
4698 i = ALL_TARGET_HT40_0_8_16; /* ht40 */
4699 else if (IS_CHAN_HT20(chan))
4700 i = ALL_TARGET_HT20_0_8_16; /* ht20 */
4702 ah->txpower_limit = targetPowerValT2[i];
4703 regulatory->max_power_level = targetPowerValT2[i];
4705 /* Write target power array to registers */
4706 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
4707 ar9003_hw_calibration_apply(ah, chan->channel);
4710 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
4716 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
4718 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4720 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
4723 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
4725 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4727 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
4730 const struct eeprom_ops eep_ar9300_ops = {
4731 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
4732 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
4733 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
4734 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
4735 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
4736 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
4737 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
4738 .set_board_values = ath9k_hw_ar9300_set_board_values,
4739 .set_addac = ath9k_hw_ar9300_set_addac,
4740 .set_txpower = ath9k_hw_ar9300_set_txpower,
4741 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel