2 * Copyright (c) 2010-2011 Atheros Communications Inc.
4 * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5 * Original from Linux kernel 3.0.1
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <ipxe/malloc.h>
24 #include "ar9003_phy.h"
25 #include "ar9003_eeprom.h"
27 #define COMP_HDR_LEN 4
28 #define COMP_CKSUM_LEN 2
30 #define AR_CH0_TOP (0x00016288)
31 #define AR_CH0_TOP_XPABIASLVL (0x300)
32 #define AR_CH0_TOP_XPABIASLVL_S (8)
34 #define AR_CH0_THERM (0x00016290)
35 #define AR_CH0_THERM_XPABIASLVL_MSB 0x3
36 #define AR_CH0_THERM_XPABIASLVL_MSB_S 0
37 #define AR_CH0_THERM_XPASHORT2GND 0x4
38 #define AR_CH0_THERM_XPASHORT2GND_S 2
40 #define AR_SWITCH_TABLE_COM_ALL (0xffff)
41 #define AR_SWITCH_TABLE_COM_ALL_S (0)
43 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
44 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
46 #define AR_SWITCH_TABLE_ALL (0xfff)
47 #define AR_SWITCH_TABLE_ALL_S (0)
49 #define LE16(x) (uint16_t)(x)
50 #define LE32(x) (uint32_t)(x)
52 /* Local defines to distinguish between extension and control CTL's */
53 #define EXT_ADDITIVE (0x8000)
54 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
55 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
56 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
57 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
58 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
59 #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */
60 #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */
61 #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */
63 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
64 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
66 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
68 #define EEPROM_DATA_LEN_9485 1088
70 static int ar9003_hw_power_interpolate(int32_t x,
71 int32_t *px, int32_t *py, uint16_t np);
74 static const struct ar9300_eeprom ar9300_default = {
77 .macAddr = {1, 2, 3, 4, 5, 6},
78 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
81 .regDmn = { LE16(0), LE16(0x1f) },
82 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
84 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
88 .blueToothOptions = 0,
90 .deviceType = 5, /* takes lower byte in eeprom location */
91 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
92 .params_for_tuning_caps = {0, 0},
93 .featureEnable = 0x0c,
95 * bit0 - enable tx temp comp - disabled
96 * bit1 - enable tx volt comp - disabled
97 * bit2 - enable fastClock - enabled
98 * bit3 - enable doubling - enabled
99 * bit4 - enable internal regulator - disabled
100 * bit5 - enable pa predistortion - disabled
102 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
103 .eepromWriteEnableGpio = 3,
104 .wlanDisableGpio = 0,
106 .rxBandSelectGpio = 0xff,
111 /* ar9300_modal_eep_header 2g */
112 /* 4 idle,t1,t2,b(4 bits per setting) */
113 .antCtrlCommon = LE32(0x110),
114 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
115 .antCtrlCommon2 = LE32(0x22222),
118 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
119 * rx1, rx12, b (2 bits each)
121 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
124 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
125 * for ar9280 (0xa20c/b20c 5:0)
127 .xatten1DB = {0, 0, 0},
130 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
131 * for ar9280 (0xa20c/b20c 16:12
133 .xatten1Margin = {0, 0, 0},
138 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
139 * channels in usual fbin coding format
141 .spurChans = {0, 0, 0, 0, 0},
144 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
145 * if the register is per chain
147 .noiseFloorThreshCh = {-1, 0, 0},
148 .ob = {1, 1, 1},/* 3 chain */
149 .db_stage2 = {1, 1, 1}, /* 3 chain */
150 .db_stage3 = {0, 0, 0},
151 .db_stage4 = {0, 0, 0},
153 .txFrameToDataStart = 0x0e,
154 .txFrameToPaOn = 0x0e,
155 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
157 .switchSettling = 0x2c,
158 .adcDesiredSize = -30,
161 .txFrameToXpaOn = 0xe,
163 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
164 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
166 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
170 .ant_div_control = 0,
171 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
178 /* ar9300_cal_data_per_freq_op_loop 2g */
180 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
181 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
182 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
184 .calTarget_freqbin_Cck = {
188 .calTarget_freqbin_2G = {
193 .calTarget_freqbin_2GHT20 = {
198 .calTarget_freqbin_2GHT40 = {
203 .calTargetPowerCck = {
204 /* 1L-5L,5S,11L,11S */
205 { {36, 36, 36, 36} },
206 { {36, 36, 36, 36} },
208 .calTargetPower2G = {
210 { {32, 32, 28, 24} },
211 { {32, 32, 28, 24} },
212 { {32, 32, 28, 24} },
214 .calTargetPower2GHT20 = {
215 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
216 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
217 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
219 .calTargetPower2GHT40 = {
220 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
221 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
222 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
225 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
226 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
256 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
257 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
258 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
259 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
263 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
264 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
265 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
270 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
271 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
277 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
278 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
279 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
280 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
284 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
285 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
286 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
290 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
291 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
292 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
297 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
298 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
299 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
304 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
305 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
306 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
307 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
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) } },
313 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
315 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
316 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
317 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
319 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
320 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
321 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
323 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
324 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
325 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
328 /* 4 idle,t1,t2,b (4 bits per setting) */
329 .antCtrlCommon = LE32(0x110),
330 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
331 .antCtrlCommon2 = LE32(0x22222),
332 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
334 LE16(0x000), LE16(0x000), LE16(0x000),
336 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
337 .xatten1DB = {0, 0, 0},
340 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
341 * for merlin (0xa20c/b20c 16:12
343 .xatten1Margin = {0, 0, 0},
346 /* spurChans spur channels in usual fbin coding format */
347 .spurChans = {0, 0, 0, 0, 0},
348 /* noiseFloorThreshCh Check if the register is per chain */
349 .noiseFloorThreshCh = {-1, 0, 0},
350 .ob = {3, 3, 3}, /* 3 chain */
351 .db_stage2 = {3, 3, 3}, /* 3 chain */
352 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
353 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
355 .txFrameToDataStart = 0x0e,
356 .txFrameToPaOn = 0x0e,
357 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
359 .switchSettling = 0x2d,
360 .adcDesiredSize = -30,
363 .txFrameToXpaOn = 0xe,
365 .papdRateMaskHt20 = LE32(0x0c80c080),
366 .papdRateMaskHt40 = LE32(0x0080c080),
368 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
374 .xatten1DBLow = {0, 0, 0},
375 .xatten1MarginLow = {0, 0, 0},
376 .xatten1DBHigh = {0, 0, 0},
377 .xatten1MarginHigh = {0, 0, 0}
422 .calTarget_freqbin_5G = {
432 .calTarget_freqbin_5GHT20 = {
442 .calTarget_freqbin_5GHT40 = {
452 .calTargetPower5G = {
454 { {20, 20, 20, 10} },
455 { {20, 20, 20, 10} },
456 { {20, 20, 20, 10} },
457 { {20, 20, 20, 10} },
458 { {20, 20, 20, 10} },
459 { {20, 20, 20, 10} },
460 { {20, 20, 20, 10} },
461 { {20, 20, 20, 10} },
463 .calTargetPower5GHT20 = {
465 * 0_8_16,1-3_9-11_17-19,
466 * 4,5,6,7,12,13,14,15,20,21,22,23
468 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
469 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
470 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
471 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
472 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
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} },
477 .calTargetPower5GHT40 = {
479 * 0_8_16,1-3_9-11_17-19,
480 * 4,5,6,7,12,13,14,15,20,21,22,23
482 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
483 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
484 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
485 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
486 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
487 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
488 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
489 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
492 0x10, 0x16, 0x18, 0x40, 0x46,
493 0x48, 0x30, 0x36, 0x38
497 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
498 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
499 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
500 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
501 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
502 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
503 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
504 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
507 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
508 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
509 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
510 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
511 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
512 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
513 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
514 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
518 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
519 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
520 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
521 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
522 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
523 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
524 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
525 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
529 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
530 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
531 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
532 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
533 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
534 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
535 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
536 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
540 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
541 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
542 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
543 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
544 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
545 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
546 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
547 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
551 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
552 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
553 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
554 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
555 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
556 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
557 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
558 /* Data[5].ctlEdges[7].bChannel */ 0xFF
562 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
563 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
564 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
565 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
566 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
567 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
568 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
569 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
573 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
574 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
575 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
576 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
577 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
578 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
579 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
580 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
584 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
585 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
586 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
587 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
588 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
589 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
590 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
591 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
597 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
598 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
603 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
604 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
609 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
610 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
615 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
616 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
621 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
622 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
627 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
628 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
633 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
634 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
639 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
640 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
645 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
646 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
652 static const struct ar9300_eeprom ar9300_x113 = {
654 .templateVersion = 6,
655 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
656 .custData = {"x113-023-f0000"},
658 .regDmn = { LE16(0), LE16(0x1f) },
659 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
661 .opFlags = AR5416_OPFLAGS_11A,
665 .blueToothOptions = 0,
667 .deviceType = 5, /* takes lower byte in eeprom location */
668 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
669 .params_for_tuning_caps = {0, 0},
670 .featureEnable = 0x0d,
672 * bit0 - enable tx temp comp - disabled
673 * bit1 - enable tx volt comp - disabled
674 * bit2 - enable fastClock - enabled
675 * bit3 - enable doubling - enabled
676 * bit4 - enable internal regulator - disabled
677 * bit5 - enable pa predistortion - disabled
679 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
680 .eepromWriteEnableGpio = 6,
681 .wlanDisableGpio = 0,
683 .rxBandSelectGpio = 0xff,
688 /* ar9300_modal_eep_header 2g */
689 /* 4 idle,t1,t2,b(4 bits per setting) */
690 .antCtrlCommon = LE32(0x110),
691 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
692 .antCtrlCommon2 = LE32(0x44444),
695 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
696 * rx1, rx12, b (2 bits each)
698 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
701 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
702 * for ar9280 (0xa20c/b20c 5:0)
704 .xatten1DB = {0, 0, 0},
707 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
708 * for ar9280 (0xa20c/b20c 16:12
710 .xatten1Margin = {0, 0, 0},
715 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
716 * channels in usual fbin coding format
718 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
721 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
722 * if the register is per chain
724 .noiseFloorThreshCh = {-1, 0, 0},
725 .ob = {1, 1, 1},/* 3 chain */
726 .db_stage2 = {1, 1, 1}, /* 3 chain */
727 .db_stage3 = {0, 0, 0},
728 .db_stage4 = {0, 0, 0},
730 .txFrameToDataStart = 0x0e,
731 .txFrameToPaOn = 0x0e,
732 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
734 .switchSettling = 0x2c,
735 .adcDesiredSize = -30,
738 .txFrameToXpaOn = 0xe,
740 .papdRateMaskHt20 = LE32(0x0c80c080),
741 .papdRateMaskHt40 = LE32(0x0080c080),
743 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
747 .ant_div_control = 0,
748 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
755 /* ar9300_cal_data_per_freq_op_loop 2g */
757 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
758 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
759 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
761 .calTarget_freqbin_Cck = {
765 .calTarget_freqbin_2G = {
770 .calTarget_freqbin_2GHT20 = {
775 .calTarget_freqbin_2GHT40 = {
780 .calTargetPowerCck = {
781 /* 1L-5L,5S,11L,11S */
782 { {34, 34, 34, 34} },
783 { {34, 34, 34, 34} },
785 .calTargetPower2G = {
787 { {34, 34, 32, 32} },
788 { {34, 34, 32, 32} },
789 { {34, 34, 32, 32} },
791 .calTargetPower2GHT20 = {
792 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
793 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
794 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
796 .calTargetPower2GHT40 = {
797 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
798 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
799 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
802 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
803 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
833 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
834 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
835 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
836 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
840 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
841 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
842 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
847 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
848 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
854 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
855 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
856 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
857 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
861 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
862 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
863 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
867 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
868 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
869 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
874 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
875 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
876 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
881 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
882 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
883 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
884 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
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) } },
890 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
892 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
893 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
894 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
896 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
897 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
898 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
900 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
901 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
902 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
905 /* 4 idle,t1,t2,b (4 bits per setting) */
906 .antCtrlCommon = LE32(0x220),
907 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
908 .antCtrlCommon2 = LE32(0x11111),
909 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
911 LE16(0x150), LE16(0x150), LE16(0x150),
913 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
914 .xatten1DB = {0, 0, 0},
917 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
918 * for merlin (0xa20c/b20c 16:12
920 .xatten1Margin = {0, 0, 0},
923 /* spurChans spur channels in usual fbin coding format */
924 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
925 /* noiseFloorThreshCh Check if the register is per chain */
926 .noiseFloorThreshCh = {-1, 0, 0},
927 .ob = {3, 3, 3}, /* 3 chain */
928 .db_stage2 = {3, 3, 3}, /* 3 chain */
929 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
930 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
932 .txFrameToDataStart = 0x0e,
933 .txFrameToPaOn = 0x0e,
934 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
936 .switchSettling = 0x2d,
937 .adcDesiredSize = -30,
940 .txFrameToXpaOn = 0xe,
942 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
943 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
945 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
950 .tempSlopeHigh = 105,
951 .xatten1DBLow = {0, 0, 0},
952 .xatten1MarginLow = {0, 0, 0},
953 .xatten1DBHigh = {0, 0, 0},
954 .xatten1MarginHigh = {0, 0, 0}
999 .calTarget_freqbin_5G = {
1009 .calTarget_freqbin_5GHT20 = {
1019 .calTarget_freqbin_5GHT40 = {
1029 .calTargetPower5G = {
1031 { {42, 40, 40, 34} },
1032 { {42, 40, 40, 34} },
1033 { {42, 40, 40, 34} },
1034 { {42, 40, 40, 34} },
1035 { {42, 40, 40, 34} },
1036 { {42, 40, 40, 34} },
1037 { {42, 40, 40, 34} },
1038 { {42, 40, 40, 34} },
1040 .calTargetPower5GHT20 = {
1042 * 0_8_16,1-3_9-11_17-19,
1043 * 4,5,6,7,12,13,14,15,20,21,22,23
1045 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1046 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1047 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1048 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1049 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1050 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1051 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1052 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1054 .calTargetPower5GHT40 = {
1056 * 0_8_16,1-3_9-11_17-19,
1057 * 4,5,6,7,12,13,14,15,20,21,22,23
1059 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1060 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1061 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1062 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1063 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1064 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1065 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1066 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1069 0x10, 0x16, 0x18, 0x40, 0x46,
1070 0x48, 0x30, 0x36, 0x38
1074 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1075 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1076 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1077 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1078 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1079 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1080 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1081 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1084 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1085 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1086 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1087 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1088 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1089 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1090 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1091 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1095 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1096 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1097 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1098 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1099 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1100 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1101 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1102 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1106 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1107 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1108 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1109 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1110 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1111 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1112 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1113 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1117 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1118 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1119 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1120 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1121 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1122 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1123 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1124 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1128 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1129 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1130 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1131 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1132 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1133 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1134 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1135 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1139 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1140 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1141 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1142 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1143 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1144 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1145 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1146 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1150 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1151 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1152 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1153 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1154 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1155 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1156 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1157 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1161 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1162 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1163 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1164 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1165 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1166 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1167 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1168 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1171 .ctlPowerData_5G = {
1174 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1175 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1180 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1181 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1186 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1187 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1192 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1193 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1198 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1199 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1204 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1205 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1210 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1211 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1216 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1217 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1222 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1223 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1230 static const struct ar9300_eeprom ar9300_h112 = {
1232 .templateVersion = 3,
1233 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1234 .custData = {"h112-241-f0000"},
1236 .regDmn = { LE16(0), LE16(0x1f) },
1237 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1239 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1243 .blueToothOptions = 0,
1245 .deviceType = 5, /* takes lower byte in eeprom location */
1246 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1247 .params_for_tuning_caps = {0, 0},
1248 .featureEnable = 0x0d,
1250 * bit0 - enable tx temp comp - disabled
1251 * bit1 - enable tx volt comp - disabled
1252 * bit2 - enable fastClock - enabled
1253 * bit3 - enable doubling - enabled
1254 * bit4 - enable internal regulator - disabled
1255 * bit5 - enable pa predistortion - disabled
1257 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1258 .eepromWriteEnableGpio = 6,
1259 .wlanDisableGpio = 0,
1261 .rxBandSelectGpio = 0xff,
1266 /* ar9300_modal_eep_header 2g */
1267 /* 4 idle,t1,t2,b(4 bits per setting) */
1268 .antCtrlCommon = LE32(0x110),
1269 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1270 .antCtrlCommon2 = LE32(0x44444),
1273 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1274 * rx1, rx12, b (2 bits each)
1276 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1279 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1280 * for ar9280 (0xa20c/b20c 5:0)
1282 .xatten1DB = {0, 0, 0},
1285 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1286 * for ar9280 (0xa20c/b20c 16:12
1288 .xatten1Margin = {0, 0, 0},
1293 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1294 * channels in usual fbin coding format
1296 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1299 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1300 * if the register is per chain
1302 .noiseFloorThreshCh = {-1, 0, 0},
1303 .ob = {1, 1, 1},/* 3 chain */
1304 .db_stage2 = {1, 1, 1}, /* 3 chain */
1305 .db_stage3 = {0, 0, 0},
1306 .db_stage4 = {0, 0, 0},
1308 .txFrameToDataStart = 0x0e,
1309 .txFrameToPaOn = 0x0e,
1310 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1312 .switchSettling = 0x2c,
1313 .adcDesiredSize = -30,
1316 .txFrameToXpaOn = 0xe,
1318 .papdRateMaskHt20 = LE32(0x80c080),
1319 .papdRateMaskHt40 = LE32(0x80c080),
1321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1325 .ant_div_control = 0,
1326 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1333 /* ar9300_cal_data_per_freq_op_loop 2g */
1335 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1336 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1337 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1339 .calTarget_freqbin_Cck = {
1343 .calTarget_freqbin_2G = {
1348 .calTarget_freqbin_2GHT20 = {
1353 .calTarget_freqbin_2GHT40 = {
1358 .calTargetPowerCck = {
1359 /* 1L-5L,5S,11L,11S */
1360 { {34, 34, 34, 34} },
1361 { {34, 34, 34, 34} },
1363 .calTargetPower2G = {
1365 { {34, 34, 32, 32} },
1366 { {34, 34, 32, 32} },
1367 { {34, 34, 32, 32} },
1369 .calTargetPower2GHT20 = {
1370 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1371 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1372 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1374 .calTargetPower2GHT40 = {
1375 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1376 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1377 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1380 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1381 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1411 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1412 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1413 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1414 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1418 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1419 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1420 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1425 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1426 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1432 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1433 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1434 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1435 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1439 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1440 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1441 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1445 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1446 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1447 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1452 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1453 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1454 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1459 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1460 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1461 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1462 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1465 .ctlPowerData_2G = {
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) } },
1468 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1470 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
1471 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1472 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1474 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1475 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1476 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1478 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1479 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1480 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1483 /* 4 idle,t1,t2,b (4 bits per setting) */
1484 .antCtrlCommon = LE32(0x220),
1485 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1486 .antCtrlCommon2 = LE32(0x44444),
1487 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1489 LE16(0x150), LE16(0x150), LE16(0x150),
1491 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1492 .xatten1DB = {0, 0, 0},
1495 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1496 * for merlin (0xa20c/b20c 16:12
1498 .xatten1Margin = {0, 0, 0},
1501 /* spurChans spur channels in usual fbin coding format */
1502 .spurChans = {0, 0, 0, 0, 0},
1503 /* noiseFloorThreshCh Check if the register is per chain */
1504 .noiseFloorThreshCh = {-1, 0, 0},
1505 .ob = {3, 3, 3}, /* 3 chain */
1506 .db_stage2 = {3, 3, 3}, /* 3 chain */
1507 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
1508 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
1510 .txFrameToDataStart = 0x0e,
1511 .txFrameToPaOn = 0x0e,
1512 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1514 .switchSettling = 0x2d,
1515 .adcDesiredSize = -30,
1518 .txFrameToXpaOn = 0xe,
1520 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1521 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1523 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1528 .tempSlopeHigh = 50,
1529 .xatten1DBLow = {0, 0, 0},
1530 .xatten1MarginLow = {0, 0, 0},
1531 .xatten1DBHigh = {0, 0, 0},
1532 .xatten1MarginHigh = {0, 0, 0}
1577 .calTarget_freqbin_5G = {
1587 .calTarget_freqbin_5GHT20 = {
1597 .calTarget_freqbin_5GHT40 = {
1607 .calTargetPower5G = {
1609 { {30, 30, 28, 24} },
1610 { {30, 30, 28, 24} },
1611 { {30, 30, 28, 24} },
1612 { {30, 30, 28, 24} },
1613 { {30, 30, 28, 24} },
1614 { {30, 30, 28, 24} },
1615 { {30, 30, 28, 24} },
1616 { {30, 30, 28, 24} },
1618 .calTargetPower5GHT20 = {
1620 * 0_8_16,1-3_9-11_17-19,
1621 * 4,5,6,7,12,13,14,15,20,21,22,23
1623 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1624 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1625 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1626 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1627 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1628 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1629 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1630 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1632 .calTargetPower5GHT40 = {
1634 * 0_8_16,1-3_9-11_17-19,
1635 * 4,5,6,7,12,13,14,15,20,21,22,23
1637 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1638 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1639 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1640 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1641 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1642 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1643 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1644 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1647 0x10, 0x16, 0x18, 0x40, 0x46,
1648 0x48, 0x30, 0x36, 0x38
1652 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1653 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1654 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1655 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1656 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1657 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1658 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1659 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1662 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1663 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1664 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1665 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1666 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1667 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1668 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1669 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1673 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1674 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1675 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1676 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1677 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1678 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1679 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1680 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1684 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1685 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1686 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1687 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1688 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1689 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1690 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1691 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1695 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1696 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1697 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1698 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1699 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1700 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1701 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1702 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1706 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1707 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1708 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1709 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1710 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1711 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1712 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1713 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1717 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1718 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1719 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1720 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1721 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1722 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1723 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1724 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1728 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1729 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1730 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1731 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1732 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1733 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1734 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1735 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1739 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1740 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1741 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1742 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1743 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1744 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1745 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1746 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1749 .ctlPowerData_5G = {
1752 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1753 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1758 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1759 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1764 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1765 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1770 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1771 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1776 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1777 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1782 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1783 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1788 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1789 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1794 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1795 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1800 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1801 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1808 static const struct ar9300_eeprom ar9300_x112 = {
1810 .templateVersion = 5,
1811 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1812 .custData = {"x112-041-f0000"},
1814 .regDmn = { LE16(0), LE16(0x1f) },
1815 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1817 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1821 .blueToothOptions = 0,
1823 .deviceType = 5, /* takes lower byte in eeprom location */
1824 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1825 .params_for_tuning_caps = {0, 0},
1826 .featureEnable = 0x0d,
1828 * bit0 - enable tx temp comp - disabled
1829 * bit1 - enable tx volt comp - disabled
1830 * bit2 - enable fastclock - enabled
1831 * bit3 - enable doubling - enabled
1832 * bit4 - enable internal regulator - disabled
1833 * bit5 - enable pa predistortion - disabled
1835 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1836 .eepromWriteEnableGpio = 6,
1837 .wlanDisableGpio = 0,
1839 .rxBandSelectGpio = 0xff,
1844 /* ar9300_modal_eep_header 2g */
1845 /* 4 idle,t1,t2,b(4 bits per setting) */
1846 .antCtrlCommon = LE32(0x110),
1847 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1848 .antCtrlCommon2 = LE32(0x22222),
1851 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1852 * rx1, rx12, b (2 bits each)
1854 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1857 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1858 * for ar9280 (0xa20c/b20c 5:0)
1860 .xatten1DB = {0x1b, 0x1b, 0x1b},
1863 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1864 * for ar9280 (0xa20c/b20c 16:12
1866 .xatten1Margin = {0x15, 0x15, 0x15},
1871 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1872 * channels in usual fbin coding format
1874 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1877 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1878 * if the register is per chain
1880 .noiseFloorThreshCh = {-1, 0, 0},
1881 .ob = {1, 1, 1},/* 3 chain */
1882 .db_stage2 = {1, 1, 1}, /* 3 chain */
1883 .db_stage3 = {0, 0, 0},
1884 .db_stage4 = {0, 0, 0},
1886 .txFrameToDataStart = 0x0e,
1887 .txFrameToPaOn = 0x0e,
1888 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1890 .switchSettling = 0x2c,
1891 .adcDesiredSize = -30,
1894 .txFrameToXpaOn = 0xe,
1896 .papdRateMaskHt20 = LE32(0x0c80c080),
1897 .papdRateMaskHt40 = LE32(0x0080c080),
1899 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1903 .ant_div_control = 0,
1904 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1911 /* ar9300_cal_data_per_freq_op_loop 2g */
1913 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1914 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1915 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1917 .calTarget_freqbin_Cck = {
1921 .calTarget_freqbin_2G = {
1926 .calTarget_freqbin_2GHT20 = {
1931 .calTarget_freqbin_2GHT40 = {
1936 .calTargetPowerCck = {
1937 /* 1L-5L,5S,11L,11s */
1938 { {38, 38, 38, 38} },
1939 { {38, 38, 38, 38} },
1941 .calTargetPower2G = {
1943 { {38, 38, 36, 34} },
1944 { {38, 38, 36, 34} },
1945 { {38, 38, 34, 32} },
1947 .calTargetPower2GHT20 = {
1948 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1949 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1950 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1952 .calTargetPower2GHT40 = {
1953 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1954 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1955 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1958 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1959 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1989 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1990 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1991 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1992 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1996 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1997 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1998 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2003 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2004 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2010 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2011 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2012 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2013 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2017 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2018 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2019 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2023 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2024 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2025 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2030 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2031 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2032 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2037 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2038 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2039 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2040 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2043 .ctlPowerData_2G = {
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) } },
2046 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2048 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
2049 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2050 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2052 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2053 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2054 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2056 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2057 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2058 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2061 /* 4 idle,t1,t2,b (4 bits per setting) */
2062 .antCtrlCommon = LE32(0x110),
2063 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2064 .antCtrlCommon2 = LE32(0x22222),
2065 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2067 LE16(0x0), LE16(0x0), LE16(0x0),
2069 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2070 .xatten1DB = {0x13, 0x19, 0x17},
2073 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2074 * for merlin (0xa20c/b20c 16:12
2076 .xatten1Margin = {0x19, 0x19, 0x19},
2079 /* spurChans spur channels in usual fbin coding format */
2080 .spurChans = {0, 0, 0, 0, 0},
2081 /* noiseFloorThreshch check if the register is per chain */
2082 .noiseFloorThreshCh = {-1, 0, 0},
2083 .ob = {3, 3, 3}, /* 3 chain */
2084 .db_stage2 = {3, 3, 3}, /* 3 chain */
2085 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
2086 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
2088 .txFrameToDataStart = 0x0e,
2089 .txFrameToPaOn = 0x0e,
2090 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2092 .switchSettling = 0x2d,
2093 .adcDesiredSize = -30,
2096 .txFrameToXpaOn = 0xe,
2098 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2099 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2106 .tempSlopeHigh = 105,
2107 .xatten1DBLow = {0x10, 0x14, 0x10},
2108 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2109 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2110 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2155 .calTarget_freqbin_5G = {
2165 .calTarget_freqbin_5GHT20 = {
2175 .calTarget_freqbin_5GHT40 = {
2185 .calTargetPower5G = {
2187 { {32, 32, 28, 26} },
2188 { {32, 32, 28, 26} },
2189 { {32, 32, 28, 26} },
2190 { {32, 32, 26, 24} },
2191 { {32, 32, 26, 24} },
2192 { {32, 32, 24, 22} },
2193 { {30, 30, 24, 22} },
2194 { {30, 30, 24, 22} },
2196 .calTargetPower5GHT20 = {
2198 * 0_8_16,1-3_9-11_17-19,
2199 * 4,5,6,7,12,13,14,15,20,21,22,23
2201 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2202 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2203 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2204 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2205 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2206 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2207 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2208 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2210 .calTargetPower5GHT40 = {
2212 * 0_8_16,1-3_9-11_17-19,
2213 * 4,5,6,7,12,13,14,15,20,21,22,23
2215 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2216 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2217 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2218 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2219 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2220 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2221 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2222 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2225 0x10, 0x16, 0x18, 0x40, 0x46,
2226 0x48, 0x30, 0x36, 0x38
2230 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2231 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2232 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2233 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2234 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2235 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2236 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2237 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2240 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2241 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2242 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2243 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2244 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2245 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2246 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2247 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2251 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2252 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2253 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2254 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2255 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2256 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2257 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2258 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2262 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2263 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2264 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2265 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2266 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2267 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2268 /* Data[3].ctledges[6].bchannel */ 0xFF,
2269 /* Data[3].ctledges[7].bchannel */ 0xFF,
2273 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2274 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2275 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2276 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2277 /* Data[4].ctledges[4].bchannel */ 0xFF,
2278 /* Data[4].ctledges[5].bchannel */ 0xFF,
2279 /* Data[4].ctledges[6].bchannel */ 0xFF,
2280 /* Data[4].ctledges[7].bchannel */ 0xFF,
2284 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2285 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2286 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2287 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2288 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2289 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2290 /* Data[5].ctledges[6].bchannel */ 0xFF,
2291 /* Data[5].ctledges[7].bchannel */ 0xFF
2295 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2296 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2297 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2298 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2299 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2300 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2301 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2302 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2306 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2307 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2308 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2309 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2310 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2311 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2312 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2313 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2317 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2318 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2319 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2320 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2321 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2322 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2323 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2324 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2327 .ctlPowerData_5G = {
2330 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2331 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2336 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2337 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2342 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2343 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2348 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2349 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2354 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2355 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2360 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2361 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2366 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2367 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2372 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2373 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2378 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2379 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2385 static const struct ar9300_eeprom ar9300_h116 = {
2387 .templateVersion = 4,
2388 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2389 .custData = {"h116-041-f0000"},
2391 .regDmn = { LE16(0), LE16(0x1f) },
2392 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2394 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2398 .blueToothOptions = 0,
2400 .deviceType = 5, /* takes lower byte in eeprom location */
2401 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2402 .params_for_tuning_caps = {0, 0},
2403 .featureEnable = 0x0d,
2405 * bit0 - enable tx temp comp - disabled
2406 * bit1 - enable tx volt comp - disabled
2407 * bit2 - enable fastClock - enabled
2408 * bit3 - enable doubling - enabled
2409 * bit4 - enable internal regulator - disabled
2410 * bit5 - enable pa predistortion - disabled
2412 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2413 .eepromWriteEnableGpio = 6,
2414 .wlanDisableGpio = 0,
2416 .rxBandSelectGpio = 0xff,
2421 /* ar9300_modal_eep_header 2g */
2422 /* 4 idle,t1,t2,b(4 bits per setting) */
2423 .antCtrlCommon = LE32(0x110),
2424 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2425 .antCtrlCommon2 = LE32(0x44444),
2428 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2429 * rx1, rx12, b (2 bits each)
2431 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2434 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2435 * for ar9280 (0xa20c/b20c 5:0)
2437 .xatten1DB = {0x1f, 0x1f, 0x1f},
2440 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2441 * for ar9280 (0xa20c/b20c 16:12
2443 .xatten1Margin = {0x12, 0x12, 0x12},
2448 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2449 * channels in usual fbin coding format
2451 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2454 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2455 * if the register is per chain
2457 .noiseFloorThreshCh = {-1, 0, 0},
2458 .ob = {1, 1, 1},/* 3 chain */
2459 .db_stage2 = {1, 1, 1}, /* 3 chain */
2460 .db_stage3 = {0, 0, 0},
2461 .db_stage4 = {0, 0, 0},
2463 .txFrameToDataStart = 0x0e,
2464 .txFrameToPaOn = 0x0e,
2465 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2467 .switchSettling = 0x2c,
2468 .adcDesiredSize = -30,
2471 .txFrameToXpaOn = 0xe,
2473 .papdRateMaskHt20 = LE32(0x0c80C080),
2474 .papdRateMaskHt40 = LE32(0x0080C080),
2476 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2480 .ant_div_control = 0,
2481 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2488 /* ar9300_cal_data_per_freq_op_loop 2g */
2490 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2491 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2492 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2494 .calTarget_freqbin_Cck = {
2498 .calTarget_freqbin_2G = {
2503 .calTarget_freqbin_2GHT20 = {
2508 .calTarget_freqbin_2GHT40 = {
2513 .calTargetPowerCck = {
2514 /* 1L-5L,5S,11L,11S */
2515 { {34, 34, 34, 34} },
2516 { {34, 34, 34, 34} },
2518 .calTargetPower2G = {
2520 { {34, 34, 32, 32} },
2521 { {34, 34, 32, 32} },
2522 { {34, 34, 32, 32} },
2524 .calTargetPower2GHT20 = {
2525 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2526 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2527 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2529 .calTargetPower2GHT40 = {
2530 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2531 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2532 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2535 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2536 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2566 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2567 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2568 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2569 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2573 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2574 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2575 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2580 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2581 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2587 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2588 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2589 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2590 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2594 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2595 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2596 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2600 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2601 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2602 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2607 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2608 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2609 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2614 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2615 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2616 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2617 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2620 .ctlPowerData_2G = {
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) } },
2623 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2625 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
2626 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2627 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2629 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2630 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2631 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2633 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2634 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2635 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2638 /* 4 idle,t1,t2,b (4 bits per setting) */
2639 .antCtrlCommon = LE32(0x220),
2640 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2641 .antCtrlCommon2 = LE32(0x44444),
2642 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2644 LE16(0x150), LE16(0x150), LE16(0x150),
2646 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2647 .xatten1DB = {0x19, 0x19, 0x19},
2650 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2651 * for merlin (0xa20c/b20c 16:12
2653 .xatten1Margin = {0x14, 0x14, 0x14},
2656 /* spurChans spur channels in usual fbin coding format */
2657 .spurChans = {0, 0, 0, 0, 0},
2658 /* noiseFloorThreshCh Check if the register is per chain */
2659 .noiseFloorThreshCh = {-1, 0, 0},
2660 .ob = {3, 3, 3}, /* 3 chain */
2661 .db_stage2 = {3, 3, 3}, /* 3 chain */
2662 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
2663 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
2665 .txFrameToDataStart = 0x0e,
2666 .txFrameToPaOn = 0x0e,
2667 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2669 .switchSettling = 0x2d,
2670 .adcDesiredSize = -30,
2673 .txFrameToXpaOn = 0xe,
2675 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2676 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2678 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2683 .tempSlopeHigh = 50,
2684 .xatten1DBLow = {0, 0, 0},
2685 .xatten1MarginLow = {0, 0, 0},
2686 .xatten1DBHigh = {0, 0, 0},
2687 .xatten1MarginHigh = {0, 0, 0}
2732 .calTarget_freqbin_5G = {
2742 .calTarget_freqbin_5GHT20 = {
2752 .calTarget_freqbin_5GHT40 = {
2762 .calTargetPower5G = {
2764 { {30, 30, 28, 24} },
2765 { {30, 30, 28, 24} },
2766 { {30, 30, 28, 24} },
2767 { {30, 30, 28, 24} },
2768 { {30, 30, 28, 24} },
2769 { {30, 30, 28, 24} },
2770 { {30, 30, 28, 24} },
2771 { {30, 30, 28, 24} },
2773 .calTargetPower5GHT20 = {
2775 * 0_8_16,1-3_9-11_17-19,
2776 * 4,5,6,7,12,13,14,15,20,21,22,23
2778 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2779 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2780 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2781 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2782 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2783 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2784 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2785 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2787 .calTargetPower5GHT40 = {
2789 * 0_8_16,1-3_9-11_17-19,
2790 * 4,5,6,7,12,13,14,15,20,21,22,23
2792 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2793 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2794 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2795 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2796 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2797 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2798 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2799 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2802 0x10, 0x16, 0x18, 0x40, 0x46,
2803 0x48, 0x30, 0x36, 0x38
2807 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2808 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2809 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2810 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2811 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2812 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2813 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2814 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2817 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2818 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2819 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2820 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2821 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2822 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2823 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2824 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2828 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2829 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2830 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2831 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2832 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2833 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2834 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2835 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2839 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2840 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2841 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2842 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2843 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2844 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2845 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2846 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2850 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2851 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2852 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2853 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2854 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2855 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2856 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2857 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2861 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2862 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2863 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2864 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2865 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2866 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2867 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2868 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2872 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2873 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2874 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2875 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2876 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2877 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2878 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2879 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2883 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2884 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2885 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2886 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2887 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2888 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2889 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2890 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2894 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2895 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2896 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2897 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2898 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2899 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2900 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2901 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2904 .ctlPowerData_5G = {
2907 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2908 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2913 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2914 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2919 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2920 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2925 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2926 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2931 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2932 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2937 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2938 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2943 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2944 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2949 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2950 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2955 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2956 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2963 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2971 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2973 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2976 for (it = 0; it < N_LOOP; it++)
2977 if (ar9300_eep_templates[it]->templateVersion == id)
2978 return ar9300_eep_templates[it];
2984 static u16 ath9k_hw_fbin2freq(u8 fbin, int is2GHz)
2986 if (fbin == AR5416_BCHAN_UNUSED)
2989 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
2992 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah __unused)
2997 static int interpolate(int x, int xa, int xb, int ya, int yb)
2999 int bf, factor, plus;
3001 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
3004 return ya + factor + plus;
3007 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
3008 enum eeprom_param param)
3010 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3011 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3015 return eep->macAddr[0] << 8 | eep->macAddr[1];
3017 return eep->macAddr[2] << 8 | eep->macAddr[3];
3019 return eep->macAddr[4] << 8 | eep->macAddr[5];
3021 return (uint16_t)(pBase->regDmn[0]);
3023 return (uint16_t)(pBase->regDmn[1]);
3025 return pBase->deviceCap;
3027 return pBase->opCapFlags.opFlags;
3029 return pBase->rfSilent;
3031 return (pBase->txrxMask >> 4) & 0xf;
3033 return pBase->txrxMask & 0xf;
3034 case EEP_DRIVE_STRENGTH:
3035 #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1
3036 return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
3037 case EEP_INTERNAL_REGULATOR:
3038 /* Bit 4 is internal regulator flag */
3039 return (pBase->featureEnable & 0x10) >> 4;
3041 return (uint32_t)(pBase->swreg);
3043 return !!(pBase->featureEnable & BIT(5));
3044 case EEP_CHAIN_MASK_REDUCE:
3045 return (pBase->miscConfiguration >> 0x3) & 0x1;
3046 case EEP_ANT_DIV_CTL1:
3047 return (uint32_t)(eep->base_ext1.ant_div_control);
3053 static int ar9300_eeprom_read_byte(struct ath_common *common, int address,
3058 if (!ath9k_hw_nvram_read(common, address / 2, &val))
3061 *buffer = (val >> (8 * (address % 2))) & 0xff;
3065 static int ar9300_eeprom_read_word(struct ath_common *common, int address,
3070 if (!ath9k_hw_nvram_read(common, address / 2, &val))
3073 buffer[0] = val >> 8;
3074 buffer[1] = val & 0xff;
3079 static int ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3082 struct ath_common *common = ath9k_hw_common(ah);
3085 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3087 "eeprom address not in range\n");
3092 * Since we're reading the bytes in reverse order from a little-endian
3093 * word stream, an even address means we only use the lower half of
3094 * the 16-bit word at that address
3096 if (address % 2 == 0) {
3097 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
3103 for (i = 0; i < count / 2; i++) {
3104 if (!ar9300_eeprom_read_word(common, address, buffer))
3112 if (!ar9300_eeprom_read_byte(common, address, buffer))
3119 "unable to read eeprom region at offset %d\n", address);
3123 static int ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3125 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3127 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3128 AR9300_OTP_STATUS_VALID, 1000))
3131 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3135 static int ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3141 for (i = 0; i < count; i++) {
3142 int offset = 8 * ((address - i) % 4);
3143 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3146 buffer[i] = (data >> offset) & 0xff;
3153 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3154 int *length, int *major, int *minor)
3156 unsigned long value[4];
3162 *code = ((value[0] >> 5) & 0x0007);
3163 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3164 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3165 *major = (value[2] & 0x000f);
3166 *minor = (value[3] & 0x00ff);
3169 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3171 int it, checksum = 0;
3173 for (it = 0; it < dsize; it++) {
3174 checksum += data[it];
3181 static int ar9300_uncompress_block(struct ath_hw *ah __unused,
3194 for (it = 0; it < size; it += (length+2)) {
3198 length = block[it+1];
3201 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3203 "Restore at %d: spot=%d offset=%d length=%d\n",
3204 it, spot, offset, length);
3205 memcpy(&mptr[spot], &block[it+2], length);
3207 } else if (length > 0) {
3209 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3210 it, spot, offset, length);
3217 static int ar9300_compress_decision(struct ath_hw *ah,
3222 u8 *word, int length, int mdata_size)
3224 const struct ar9300_eeprom *eep = NULL;
3228 if (length != mdata_size) {
3230 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3231 mdata_size, length);
3234 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
3236 "restored eeprom %d: uncompressed, length %d\n",
3239 case _CompressBlock:
3240 if (reference == 0) {
3242 eep = ar9003_eeprom_struct_find_by_id(reference);
3245 "can't find reference eeprom struct %d\n",
3249 memcpy(mptr, eep, mdata_size);
3252 "restore eeprom %d: block, reference %d, length %d\n",
3253 it, reference, length);
3254 ar9300_uncompress_block(ah, mptr, mdata_size,
3255 (u8 *) (word + COMP_HDR_LEN), length);
3259 "unknown compression code %d\n", code);
3265 typedef int (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3268 static int ar9300_check_header(void *data)
3271 return !(*word == 0 || *word == (unsigned int)~0);
3274 static int ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3279 if (!read(ah, base_addr, header, 4))
3282 return ar9300_check_header(header);
3285 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3288 struct ath_common *common = ath9k_hw_common(ah);
3289 u16 *data = (u16 *) mptr;
3292 for (i = 0; i < mdata_size / 2; i++, data++)
3293 ath9k_hw_nvram_read(common, i, data);
3298 * Read the configuration data from the eeprom.
3299 * The data can be put in any specified memory buffer.
3301 * Returns -1 on error.
3302 * Returns address of next memory location on success.
3304 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3305 u8 *mptr, int mdata_size)
3312 int reference, length, major, minor;
3315 u16 checksum, mchecksum;
3316 eeprom_read_op read;
3318 if (ath9k_hw_use_flash(ah))
3319 return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3321 word = zalloc(2048);
3325 memcpy(mptr, &ar9300_default, mdata_size);
3327 read = ar9300_read_eeprom;
3328 if (AR_SREV_9485(ah))
3329 cptr = AR9300_BASE_ADDR_4K;
3331 cptr = AR9300_BASE_ADDR;
3333 "Trying EEPROM access at Address 0x%04x\n", cptr);
3334 if (ar9300_check_eeprom_header(ah, read, cptr))
3337 cptr = AR9300_BASE_ADDR_512;
3339 "Trying EEPROM access at Address 0x%04x\n", cptr);
3340 if (ar9300_check_eeprom_header(ah, read, cptr))
3343 read = ar9300_read_otp;
3344 cptr = AR9300_BASE_ADDR;
3346 "Trying OTP access at Address 0x%04x\n", cptr);
3347 if (ar9300_check_eeprom_header(ah, read, cptr))
3350 cptr = AR9300_BASE_ADDR_512;
3352 "Trying OTP access at Address 0x%04x\n", cptr);
3353 if (ar9300_check_eeprom_header(ah, read, cptr))
3359 DBG2("ath9k: Found valid EEPROM data\n");
3361 for (it = 0; it < MSTATE; it++) {
3362 if (!read(ah, cptr, word, COMP_HDR_LEN))
3365 if (!ar9300_check_header(word))
3368 ar9300_comp_hdr_unpack(word, &code, &reference,
3369 &length, &major, &minor);
3371 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3372 cptr, code, reference, length, major, minor);
3373 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3374 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3376 "Skipping bad header\n");
3377 cptr -= COMP_HDR_LEN;
3382 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3383 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3384 mchecksum = word[COMP_HDR_LEN + osize] |
3385 (word[COMP_HDR_LEN + osize + 1] << 8);
3387 "checksum %x %x\n", checksum, mchecksum);
3388 if (checksum == mchecksum) {
3389 ar9300_compress_decision(ah, it, code, reference, mptr,
3390 word, length, mdata_size);
3393 "skipping block with bad checksum\n");
3395 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3407 * Restore the configuration structure by reading the eeprom.
3408 * This function destroys any existing in-memory structure
3411 static int ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3413 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3415 if (ar9300_eeprom_restore_internal(ah, mptr,
3416 sizeof(struct ar9300_eeprom)) < 0)
3422 /* XXX: review hardware docs */
3423 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3425 return ah->eeprom.ar9300_eep.eepromVersion;
3428 /* XXX: could be read from the eepromVersion, not sure yet */
3429 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah __unused)
3434 static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, int is2ghz)
3436 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3439 return eep->modalHeader2G.xpaBiasLvl;
3441 return eep->modalHeader5G.xpaBiasLvl;
3444 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, int is2ghz)
3446 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
3448 if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
3449 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3451 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3452 REG_RMW_FIELD(ah, AR_CH0_THERM,
3453 AR_CH0_THERM_XPABIASLVL_MSB,
3455 REG_RMW_FIELD(ah, AR_CH0_THERM,
3456 AR_CH0_THERM_XPASHORT2GND, 1);
3460 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, int is2ghz)
3462 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3466 val = eep->modalHeader2G.antCtrlCommon;
3468 val = eep->modalHeader5G.antCtrlCommon;
3469 return (uint32_t)(val);
3472 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, int is2ghz)
3474 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3478 val = eep->modalHeader2G.antCtrlCommon2;
3480 val = eep->modalHeader5G.antCtrlCommon2;
3481 return (uint32_t)(val);
3484 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
3488 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3491 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
3493 val = eep->modalHeader2G.antCtrlChain[chain];
3495 val = eep->modalHeader5G.antCtrlChain[chain];
3498 return (uint16_t)(val);
3501 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, int is2ghz)
3506 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3507 AR_PHY_SWITCH_CHAIN_0,
3508 AR_PHY_SWITCH_CHAIN_1,
3509 AR_PHY_SWITCH_CHAIN_2,
3512 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3514 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
3516 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3517 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3519 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3520 if ((ah->rxchainmask & BIT(chain)) ||
3521 (ah->txchainmask & BIT(chain))) {
3522 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3524 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3525 AR_SWITCH_TABLE_ALL, value);
3529 if (AR_SREV_9485(ah)) {
3530 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3532 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3533 * are the fields present
3535 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3536 regval &= (~AR_ANT_DIV_CTRL_ALL);
3537 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3539 regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
3540 regval |= ((value >> 6) & 0x1) <<
3541 AR_PHY_9485_ANT_DIV_LNADIV_S;
3542 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3544 /*enable fast_div */
3545 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3546 regval &= (~AR_FAST_DIV_ENABLE);
3547 regval |= ((value >> 7) & 0x1) <<
3548 AR_FAST_DIV_ENABLE_S;
3549 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3551 ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
3552 /* check whether antenna diversity is enabled */
3553 if ((ant_div_ctl1 >> 0x6) == 0x3) {
3554 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3556 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3559 regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
3560 AR_PHY_9485_ANT_DIV_ALT_LNACONF |
3561 AR_PHY_9485_ANT_DIV_ALT_GAINTB |
3562 AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
3563 /* by default use LNA1 for the main antenna */
3564 regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
3565 AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
3566 regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
3567 AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
3568 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3576 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3581 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
3583 if (!drive_strength)
3586 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3594 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3596 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3607 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3609 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3614 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3617 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3618 struct ath9k_channel *chan)
3622 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3624 if (chain >= 0 && chain < 3) {
3625 if (IS_CHAN_2GHZ(chan))
3626 return eep->modalHeader2G.xatten1DB[chain];
3627 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3628 t[0] = eep->base_ext2.xatten1DBLow[chain];
3630 t[1] = eep->modalHeader5G.xatten1DB[chain];
3632 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3634 value = ar9003_hw_power_interpolate((s32) chan->channel,
3638 return eep->modalHeader5G.xatten1DB[chain];
3645 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3646 struct ath9k_channel *chan)
3650 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3652 if (chain >= 0 && chain < 3) {
3653 if (IS_CHAN_2GHZ(chan))
3654 return eep->modalHeader2G.xatten1Margin[chain];
3655 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3656 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3658 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3660 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3662 value = ar9003_hw_power_interpolate((s32) chan->channel,
3666 return eep->modalHeader5G.xatten1Margin[chain];
3672 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3676 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3677 AR_PHY_EXT_ATTEN_CTL_1,
3678 AR_PHY_EXT_ATTEN_CTL_2,
3681 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3682 for (i = 0; i < 3; i++) {
3683 if (ah->txchainmask & BIT(i)) {
3684 value = ar9003_hw_atten_chain_get(ah, i, chan);
3685 REG_RMW_FIELD(ah, ext_atten_reg[i],
3686 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3688 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3689 REG_RMW_FIELD(ah, ext_atten_reg[i],
3690 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3696 static int is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3700 while ((unsigned int)pmu_set != REG_READ(ah, pmu_reg)) {
3703 REG_WRITE(ah, pmu_reg, pmu_set);
3710 static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3712 int internal_regulator =
3713 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
3715 if (internal_regulator) {
3716 if (AR_SREV_9485(ah)) {
3719 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3720 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3721 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3724 reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) |
3725 (2 << 14) | (6 << 17) | (1 << 20) |
3726 (3 << 24) | (1 << 28);
3728 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3729 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3732 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3734 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3735 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3738 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3740 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3741 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3744 /* Internal regulator is ON. Write swreg register. */
3745 int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
3746 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3747 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3748 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3749 REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
3750 /* Set REG_CONTROL1.SWREG_PROGRAM */
3751 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3753 AR_RTC_REG_CONTROL1) |
3754 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3757 if (AR_SREV_9485(ah)) {
3758 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3759 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3763 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3764 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3767 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3768 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3772 REG_WRITE(ah, AR_RTC_SLEEP_CLK,
3775 AR_RTC_FORCE_SWREG_PRD));
3780 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3782 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3783 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3785 if (eep->baseEepHeader.featureEnable & 0x40) {
3786 tuning_caps_param &= 0x7f;
3787 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3789 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3794 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3795 struct ath9k_channel *chan)
3797 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
3798 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
3799 ar9003_hw_drive_strength_apply(ah);
3800 ar9003_hw_atten_apply(ah, chan);
3801 if (!AR_SREV_9340(ah))
3802 ar9003_hw_internal_regulator_apply(ah);
3803 if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
3804 ar9003_hw_apply_tuning_caps(ah);
3807 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah __unused,
3808 struct ath9k_channel *chan __unused)
3813 * Returns the interpolated y value corresponding to the specified x value
3814 * from the np ordered pairs of data (px,py).
3815 * The pairs do not have to be in any order.
3816 * If the specified x value is less than any of the px,
3817 * the returned y value is equal to the py for the lowest px.
3818 * If the specified x value is greater than any of the px,
3819 * the returned y value is equal to the py for the highest px.
3821 static int ar9003_hw_power_interpolate(int32_t x,
3822 int32_t *px, int32_t *py, uint16_t np)
3825 int lx = 0, ly = 0, lhave = 0;
3826 int hx = 0, hy = 0, hhave = 0;
3833 /* identify best lower and higher x calibration measurement */
3834 for (ip = 0; ip < np; ip++) {
3837 /* this measurement is higher than our desired x */
3839 if (!hhave || dx > (x - hx)) {
3840 /* new best higher x measurement */
3846 /* this measurement is lower than our desired x */
3848 if (!lhave || dx < (x - lx)) {
3849 /* new best lower x measurement */
3857 /* the low x is good */
3859 /* so is the high x */
3861 /* they're the same, so just pick one */
3864 else /* interpolate */
3865 y = interpolate(x, lx, hx, ly, hy);
3866 } else /* only low is good, use it */
3868 } else if (hhave) /* only high is good, use it */
3870 else /* nothing is good,this should never happen unless np=0, ???? */
3875 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
3876 u16 rateIndex, u16 freq, int is2GHz)
3879 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
3880 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
3881 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3882 struct cal_tgt_pow_legacy *pEepromTargetPwr;
3886 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
3887 pEepromTargetPwr = eep->calTargetPower2G;
3888 pFreqBin = eep->calTarget_freqbin_2G;
3890 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
3891 pEepromTargetPwr = eep->calTargetPower5G;
3892 pFreqBin = eep->calTarget_freqbin_5G;
3896 * create array of channels and targetpower from
3897 * targetpower piers stored on eeprom
3899 for (i = 0; i < numPiers; i++) {
3900 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
3901 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3904 /* interpolate to get target power for given frequency */
3905 return (u8) ar9003_hw_power_interpolate((s32) freq,
3907 targetPowerArray, numPiers);
3910 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
3912 u16 freq, int is2GHz)
3915 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
3916 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
3917 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3918 struct cal_tgt_pow_ht *pEepromTargetPwr;
3922 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
3923 pEepromTargetPwr = eep->calTargetPower2GHT20;
3924 pFreqBin = eep->calTarget_freqbin_2GHT20;
3926 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
3927 pEepromTargetPwr = eep->calTargetPower5GHT20;
3928 pFreqBin = eep->calTarget_freqbin_5GHT20;
3932 * create array of channels and targetpower
3933 * from targetpower piers stored on eeprom
3935 for (i = 0; i < numPiers; i++) {
3936 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
3937 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3940 /* interpolate to get target power for given frequency */
3941 return (u8) ar9003_hw_power_interpolate((s32) freq,
3943 targetPowerArray, numPiers);
3946 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
3948 u16 freq, int is2GHz)
3951 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
3952 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
3953 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3954 struct cal_tgt_pow_ht *pEepromTargetPwr;
3958 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
3959 pEepromTargetPwr = eep->calTargetPower2GHT40;
3960 pFreqBin = eep->calTarget_freqbin_2GHT40;
3962 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
3963 pEepromTargetPwr = eep->calTargetPower5GHT40;
3964 pFreqBin = eep->calTarget_freqbin_5GHT40;
3968 * create array of channels and targetpower from
3969 * targetpower piers stored on eeprom
3971 for (i = 0; i < numPiers; i++) {
3972 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
3973 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
3976 /* interpolate to get target power for given frequency */
3977 return (u8) ar9003_hw_power_interpolate((s32) freq,
3979 targetPowerArray, numPiers);
3982 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
3983 u16 rateIndex, u16 freq)
3985 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
3986 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
3987 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
3988 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3989 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
3990 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
3993 * create array of channels and targetpower from
3994 * targetpower piers stored on eeprom
3996 for (i = 0; i < numPiers; i++) {
3997 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
3998 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4001 /* interpolate to get target power for given frequency */
4002 return (u8) ar9003_hw_power_interpolate((s32) freq,
4004 targetPowerArray, numPiers);
4007 /* Set tx power registers to array of values passed in */
4008 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4010 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4011 /* make sure forced gain is not set */
4012 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4014 /* Write the OFDM power per rate set */
4016 /* 6 (LSB), 9, 12, 18 (MSB) */
4017 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4018 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4019 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4020 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4021 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4023 /* 24 (LSB), 36, 48, 54 (MSB) */
4024 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4025 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4026 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4027 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4028 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4030 /* Write the CCK power per rate set */
4032 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4033 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4034 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4035 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4036 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4037 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4039 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4040 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4041 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4042 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4043 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4044 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4047 /* Write the power for duplicated frames - HT40 */
4049 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4050 REG_WRITE(ah, 0xa3e0,
4051 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4052 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4053 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4054 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4057 /* Write the HT20 power per rate set */
4059 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4060 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4061 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4062 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4063 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4064 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4067 /* 6 (LSB), 7, 12, 13 (MSB) */
4068 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4069 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4070 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4071 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4072 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4075 /* 14 (LSB), 15, 20, 21 */
4076 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4077 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4078 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4079 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4080 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4083 /* Mixed HT20 and HT40 rates */
4085 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4086 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4087 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4088 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4089 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4090 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4094 * Write the HT40 power per rate set
4095 * correct PAR difference between HT40 and HT20/LEGACY
4096 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4098 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4099 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4100 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4101 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4102 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4105 /* 6 (LSB), 7, 12, 13 (MSB) */
4106 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4107 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4108 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4109 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4110 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4113 /* 14 (LSB), 15, 20, 21 */
4114 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4115 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4116 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4117 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4118 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4125 static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
4126 u8 *targetPowerValT2)
4128 /* XXX: hard code for now, need to get from eeprom struct */
4129 u8 ht40PowerIncForPdadc = 0;
4136 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4137 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4139 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4140 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4142 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4143 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4145 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4146 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4148 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4149 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4151 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4152 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4153 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4154 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4155 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4156 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4157 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4158 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4160 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4161 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4163 targetPowerValT2[ALL_TARGET_HT20_4] =
4164 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4166 targetPowerValT2[ALL_TARGET_HT20_5] =
4167 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4169 targetPowerValT2[ALL_TARGET_HT20_6] =
4170 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4172 targetPowerValT2[ALL_TARGET_HT20_7] =
4173 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4175 targetPowerValT2[ALL_TARGET_HT20_12] =
4176 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4178 targetPowerValT2[ALL_TARGET_HT20_13] =
4179 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4181 targetPowerValT2[ALL_TARGET_HT20_14] =
4182 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4184 targetPowerValT2[ALL_TARGET_HT20_15] =
4185 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4187 targetPowerValT2[ALL_TARGET_HT20_20] =
4188 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4190 targetPowerValT2[ALL_TARGET_HT20_21] =
4191 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4193 targetPowerValT2[ALL_TARGET_HT20_22] =
4194 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4196 targetPowerValT2[ALL_TARGET_HT20_23] =
4197 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4199 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4200 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4201 is2GHz) + ht40PowerIncForPdadc;
4202 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4203 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4205 is2GHz) + ht40PowerIncForPdadc;
4206 targetPowerValT2[ALL_TARGET_HT40_4] =
4207 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4208 is2GHz) + ht40PowerIncForPdadc;
4209 targetPowerValT2[ALL_TARGET_HT40_5] =
4210 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4211 is2GHz) + ht40PowerIncForPdadc;
4212 targetPowerValT2[ALL_TARGET_HT40_6] =
4213 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4214 is2GHz) + ht40PowerIncForPdadc;
4215 targetPowerValT2[ALL_TARGET_HT40_7] =
4216 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4217 is2GHz) + ht40PowerIncForPdadc;
4218 targetPowerValT2[ALL_TARGET_HT40_12] =
4219 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4220 is2GHz) + ht40PowerIncForPdadc;
4221 targetPowerValT2[ALL_TARGET_HT40_13] =
4222 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4223 is2GHz) + ht40PowerIncForPdadc;
4224 targetPowerValT2[ALL_TARGET_HT40_14] =
4225 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4226 is2GHz) + ht40PowerIncForPdadc;
4227 targetPowerValT2[ALL_TARGET_HT40_15] =
4228 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4229 is2GHz) + ht40PowerIncForPdadc;
4230 targetPowerValT2[ALL_TARGET_HT40_20] =
4231 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4232 is2GHz) + ht40PowerIncForPdadc;
4233 targetPowerValT2[ALL_TARGET_HT40_21] =
4234 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4235 is2GHz) + ht40PowerIncForPdadc;
4236 targetPowerValT2[ALL_TARGET_HT40_22] =
4237 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4238 is2GHz) + ht40PowerIncForPdadc;
4239 targetPowerValT2[ALL_TARGET_HT40_23] =
4240 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4241 is2GHz) + ht40PowerIncForPdadc;
4243 for (i = 0; i < ar9300RateSize; i++) {
4245 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
4249 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4255 int *ptemperature, int *pvoltage)
4258 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4260 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4262 if (ichain >= AR9300_MAX_CHAINS) {
4264 "Invalid chain index, must be less than %d\n",
4269 if (mode) { /* 5GHz */
4270 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4272 "Invalid 5GHz cal pier index, must be less than %d\n",
4273 AR9300_NUM_5G_CAL_PIERS);
4276 pCalPier = &(eep->calFreqPier5G[ipier]);
4277 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4280 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4282 "Invalid 2GHz cal pier index, must be less than %d\n",
4283 AR9300_NUM_2G_CAL_PIERS);
4287 pCalPier = &(eep->calFreqPier2G[ipier]);
4288 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4292 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
4293 *pcorrection = pCalPierStruct->refPower;
4294 *ptemperature = pCalPierStruct->tempMeas;
4295 *pvoltage = pCalPierStruct->voltMeas;
4300 static int ar9003_hw_power_control_override(struct ath_hw *ah,
4303 int *voltage __unused, int *temperature)
4306 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4309 REG_RMW(ah, AR_PHY_TPC_11_B0,
4310 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4311 AR_PHY_TPC_OLPC_GAIN_DELTA);
4312 if (ah->caps.tx_chainmask & BIT(1))
4313 REG_RMW(ah, AR_PHY_TPC_11_B1,
4314 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4315 AR_PHY_TPC_OLPC_GAIN_DELTA);
4316 if (ah->caps.tx_chainmask & BIT(2))
4317 REG_RMW(ah, AR_PHY_TPC_11_B2,
4318 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4319 AR_PHY_TPC_OLPC_GAIN_DELTA);
4321 /* enable open loop power control on chip */
4322 REG_RMW(ah, AR_PHY_TPC_6_B0,
4323 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4324 AR_PHY_TPC_6_ERROR_EST_MODE);
4325 if (ah->caps.tx_chainmask & BIT(1))
4326 REG_RMW(ah, AR_PHY_TPC_6_B1,
4327 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4328 AR_PHY_TPC_6_ERROR_EST_MODE);
4329 if (ah->caps.tx_chainmask & BIT(2))
4330 REG_RMW(ah, AR_PHY_TPC_6_B2,
4331 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4332 AR_PHY_TPC_6_ERROR_EST_MODE);
4335 * enable temperature compensation
4336 * Need to use register names
4338 if (frequency < 4000)
4339 tempSlope = eep->modalHeader2G.tempSlope;
4340 else if (eep->base_ext2.tempSlopeLow != 0) {
4341 t[0] = eep->base_ext2.tempSlopeLow;
4343 t[1] = eep->modalHeader5G.tempSlope;
4345 t[2] = eep->base_ext2.tempSlopeHigh;
4347 tempSlope = ar9003_hw_power_interpolate((s32) frequency,
4350 tempSlope = eep->modalHeader5G.tempSlope;
4352 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
4353 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4359 /* Apply the recorded correction values. */
4360 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4362 int ichain, ipier, npier;
4364 int lfrequency[AR9300_MAX_CHAINS],
4365 lcorrection[AR9300_MAX_CHAINS],
4366 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4367 int hfrequency[AR9300_MAX_CHAINS],
4368 hcorrection[AR9300_MAX_CHAINS],
4369 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4371 int correction[AR9300_MAX_CHAINS],
4372 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4373 int pfrequency, pcorrection, ptemperature, pvoltage;
4375 mode = (frequency >= 4000);
4377 npier = AR9300_NUM_5G_CAL_PIERS;
4379 npier = AR9300_NUM_2G_CAL_PIERS;
4381 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4382 lfrequency[ichain] = 0;
4383 hfrequency[ichain] = 100000;
4385 /* identify best lower and higher frequency calibration measurement */
4386 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4387 for (ipier = 0; ipier < npier; ipier++) {
4388 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4389 &pfrequency, &pcorrection,
4390 &ptemperature, &pvoltage)) {
4391 fdiff = frequency - pfrequency;
4394 * this measurement is higher than
4395 * our desired frequency
4398 if (hfrequency[ichain] <= 0 ||
4399 hfrequency[ichain] >= 100000 ||
4401 (frequency - hfrequency[ichain])) {
4404 * frequency measurement
4406 hfrequency[ichain] = pfrequency;
4407 hcorrection[ichain] =
4409 htemperature[ichain] =
4411 hvoltage[ichain] = pvoltage;
4415 if (lfrequency[ichain] <= 0
4417 (frequency - lfrequency[ichain])) {
4420 * frequency measurement
4422 lfrequency[ichain] = pfrequency;
4423 lcorrection[ichain] =
4425 ltemperature[ichain] =
4427 lvoltage[ichain] = pvoltage;
4435 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4437 "ch=%d f=%d low=%d %d h=%d %d\n",
4438 ichain, frequency, lfrequency[ichain],
4439 lcorrection[ichain], hfrequency[ichain],
4440 hcorrection[ichain]);
4441 /* they're the same, so just pick one */
4442 if (hfrequency[ichain] == lfrequency[ichain]) {
4443 correction[ichain] = lcorrection[ichain];
4444 voltage[ichain] = lvoltage[ichain];
4445 temperature[ichain] = ltemperature[ichain];
4447 /* the low frequency is good */
4448 else if (frequency - lfrequency[ichain] < 1000) {
4449 /* so is the high frequency, interpolate */
4450 if (hfrequency[ichain] - frequency < 1000) {
4452 correction[ichain] = interpolate(frequency,
4455 lcorrection[ichain],
4456 hcorrection[ichain]);
4458 temperature[ichain] = interpolate(frequency,
4461 ltemperature[ichain],
4462 htemperature[ichain]);
4464 voltage[ichain] = interpolate(frequency,
4470 /* only low is good, use it */
4472 correction[ichain] = lcorrection[ichain];
4473 temperature[ichain] = ltemperature[ichain];
4474 voltage[ichain] = lvoltage[ichain];
4477 /* only high is good, use it */
4478 else if (hfrequency[ichain] - frequency < 1000) {
4479 correction[ichain] = hcorrection[ichain];
4480 temperature[ichain] = htemperature[ichain];
4481 voltage[ichain] = hvoltage[ichain];
4482 } else { /* nothing is good, presume 0???? */
4483 correction[ichain] = 0;
4484 temperature[ichain] = 0;
4485 voltage[ichain] = 0;
4489 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4493 "for frequency=%d, calibration correction = %d %d %d\n",
4494 frequency, correction[0], correction[1], correction[2]);
4499 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4504 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4505 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4508 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4510 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4513 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4519 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4520 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4522 u8 *ctl_freqbin = is2GHz ?
4523 &eep->ctl_freqbin_2G[idx][0] :
4524 &eep->ctl_freqbin_5G[idx][0];
4527 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4528 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4529 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4531 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4532 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4533 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4536 return MAX_RATE_POWER;
4540 * Find the maximum conformance test limit for the given channel and CTL info
4542 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4543 u16 freq, int idx, int is2GHz)
4545 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4546 u8 *ctl_freqbin = is2GHz ?
4547 &eep->ctl_freqbin_2G[idx][0] :
4548 &eep->ctl_freqbin_5G[idx][0];
4549 u16 num_edges = is2GHz ?
4550 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4553 /* Get the edge power */
4555 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
4558 * If there's an exact channel match or an inband flag set
4559 * on the lower channel use the given rdEdgePower
4561 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
4563 ar9003_hw_get_direct_edge_power(eep, idx,
4566 } else if ((edge > 0) &&
4567 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
4570 ar9003_hw_get_indirect_edge_power(eep, idx,
4574 * Leave loop - no more affecting edges possible in
4575 * this monotonic increasing list
4580 return twiceMaxEdgePower;
4583 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4584 struct ath9k_channel *chan,
4585 u8 *pPwrArray, u16 cfgCtl,
4586 u8 twiceAntennaReduction,
4587 u8 twiceMaxRegulatoryPower,
4590 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4591 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4592 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4593 static const u16 tpScaleReductionTable[5] = {
4594 0, 3, 6, 9, MAX_RATE_POWER
4597 int16_t twiceLargestAntenna;
4598 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4599 static const u16 ctlModesFor11a[] = {
4600 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4602 static const u16 ctlModesFor11g[] = {
4603 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
4604 CTL_11G_EXT, CTL_2GHT40
4607 const u16 *pCtlMode;
4609 struct chan_centers centers;
4612 u16 twiceMinEdgePower;
4613 int is2ghz = IS_CHAN_2GHZ(chan);
4615 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4617 /* Compute TxPower reduction due to Antenna Gain */
4619 twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
4621 twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
4623 twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
4624 twiceLargestAntenna, 0);
4627 * scaledPower is the minimum of the user input power level
4628 * and the regulatory allowed power level
4630 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4632 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
4633 maxRegAllowedPower -=
4634 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
4637 scaledPower = min(powerLimit, maxRegAllowedPower);
4640 * Reduce scaled Power by number of chains active to get
4641 * to per chain tx power level
4643 switch (ar5416_get_ntxchains(ah->txchainmask)) {
4647 if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
4648 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
4653 if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
4654 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
4660 scaledPower = max((u16)0, scaledPower);
4663 * Get target powers from EEPROM - our baseline for TX Power
4666 /* Setup for CTL modes */
4667 /* CTL_11B, CTL_11G, CTL_2GHT20 */
4669 ARRAY_SIZE(ctlModesFor11g) -
4670 SUB_NUM_CTL_MODES_AT_2G_40;
4671 pCtlMode = ctlModesFor11g;
4672 if (IS_CHAN_HT40(chan))
4674 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4676 /* Setup for CTL modes */
4677 /* CTL_11A, CTL_5GHT20 */
4678 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
4679 SUB_NUM_CTL_MODES_AT_5G_40;
4680 pCtlMode = ctlModesFor11a;
4681 if (IS_CHAN_HT40(chan))
4683 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4687 * For MIMO, need to apply regulatory caps individually across
4688 * dynamically running modes: CCK, OFDM, HT20, HT40
4690 * The outer loop walks through each possible applicable runtime mode.
4691 * The inner loop walks through each ctlIndex entry in EEPROM.
4692 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
4694 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4695 int isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
4696 (pCtlMode[ctlMode] == CTL_2GHT40);
4698 freq = centers.synth_center;
4699 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4700 freq = centers.ext_center;
4702 freq = centers.ctl_center;
4705 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
4706 ctlMode, numCtlModes, isHt40CtlMode,
4707 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4709 /* walk through each CTL index stored in EEPROM */
4711 ctlIndex = pEepData->ctlIndex_2G;
4712 ctlNum = AR9300_NUM_CTLS_2G;
4714 ctlIndex = pEepData->ctlIndex_5G;
4715 ctlNum = AR9300_NUM_CTLS_5G;
4718 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
4720 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
4721 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
4725 * compare test group from regulatory
4726 * channel list with test mode from pCtlMode
4729 if ((((cfgCtl & ~CTL_MODE_M) |
4730 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4732 (((cfgCtl & ~CTL_MODE_M) |
4733 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4734 ((ctlIndex[i] & CTL_MODE_M) |
4737 ar9003_hw_get_max_edge_power(pEepData,
4741 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
4743 * Find the minimum of all CTL
4744 * edge powers that apply to
4748 min(twiceMaxEdgePower,
4759 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
4762 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
4763 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4764 scaledPower, minCtlPower);
4766 /* Apply ctl mode to correct target power set */
4767 switch (pCtlMode[ctlMode]) {
4769 for (i = ALL_TARGET_LEGACY_1L_5L;
4770 i <= ALL_TARGET_LEGACY_11S; i++)
4772 (u8)min((u16)pPwrArray[i],
4777 for (i = ALL_TARGET_LEGACY_6_24;
4778 i <= ALL_TARGET_LEGACY_54; i++)
4780 (u8)min((u16)pPwrArray[i],
4785 for (i = ALL_TARGET_HT20_0_8_16;
4786 i <= ALL_TARGET_HT20_21; i++)
4788 (u8)min((u16)pPwrArray[i],
4790 pPwrArray[ALL_TARGET_HT20_22] =
4791 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
4793 pPwrArray[ALL_TARGET_HT20_23] =
4794 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
4799 for (i = ALL_TARGET_HT40_0_8_16;
4800 i <= ALL_TARGET_HT40_23; i++)
4802 (u8)min((u16)pPwrArray[i],
4808 } /* end ctl mode checking */
4811 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
4813 u8 mod_idx = mcs_idx % 8;
4816 return mod_idx ? (base_pwridx + 1) : base_pwridx;
4818 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
4821 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4822 struct ath9k_channel *chan, u16 cfgCtl,
4823 u8 twiceAntennaReduction,
4824 u8 twiceMaxRegulatoryPower,
4825 u8 powerLimit, int test)
4827 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4828 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4829 struct ar9300_modal_eep_header *modal_hdr;
4830 u8 targetPowerValT2[ar9300RateSize];
4831 u8 target_power_val_t2_eep[ar9300RateSize];
4832 unsigned int i = 0, paprd_scale_factor = 0;
4833 u8 pwr_idx, min_pwridx = 0;
4835 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
4837 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
4838 if (IS_CHAN_2GHZ(chan))
4839 modal_hdr = &eep->modalHeader2G;
4841 modal_hdr = &eep->modalHeader5G;
4843 ah->paprd_ratemask =
4844 (uint32_t)(modal_hdr->papdRateMaskHt20) &
4845 AR9300_PAPRD_RATE_MASK;
4847 ah->paprd_ratemask_ht40 =
4848 (uint32_t)(modal_hdr->papdRateMaskHt40) &
4849 AR9300_PAPRD_RATE_MASK;
4851 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
4852 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
4853 ALL_TARGET_HT20_0_8_16;
4855 if (!ah->paprd_table_write_done) {
4856 memcpy(target_power_val_t2_eep, targetPowerValT2,
4857 sizeof(targetPowerValT2));
4858 for (i = 0; i < 24; i++) {
4859 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
4860 if (ah->paprd_ratemask & (1 << i)) {
4861 if (targetPowerValT2[pwr_idx] &&
4862 targetPowerValT2[pwr_idx] ==
4863 target_power_val_t2_eep[pwr_idx])
4864 targetPowerValT2[pwr_idx] -=
4869 memcpy(target_power_val_t2_eep, targetPowerValT2,
4870 sizeof(targetPowerValT2));
4873 ar9003_hw_set_power_per_rate_table(ah, chan,
4874 targetPowerValT2, cfgCtl,
4875 twiceAntennaReduction,
4876 twiceMaxRegulatoryPower,
4879 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
4880 for (i = 0; i < ar9300RateSize; i++) {
4881 if ((ah->paprd_ratemask & (1 << i)) &&
4882 ((unsigned int)abs(targetPowerValT2[i] -
4883 target_power_val_t2_eep[i]) >
4884 paprd_scale_factor)) {
4885 ah->paprd_ratemask &= ~(1 << i);
4887 "paprd disabled for mcs %d\n", i);
4892 regulatory->max_power_level = 0;
4893 for (i = 0; i < ar9300RateSize; i++) {
4894 if (targetPowerValT2[i] > regulatory->max_power_level)
4895 regulatory->max_power_level = targetPowerValT2[i];
4901 for (i = 0; i < ar9300RateSize; i++) {
4903 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
4907 * This is the TX power we send back to driver core,
4908 * and it can use to pass to userspace to display our
4909 * currently configured TX power setting.
4911 * Since power is rate dependent, use one of the indices
4912 * from the AR9300_Rates enum to select an entry from
4913 * targetPowerValT2[] to report. Currently returns the
4914 * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
4915 * as CCK power is less interesting (?).
4917 i = ALL_TARGET_LEGACY_6_24; /* legacy */
4918 if (IS_CHAN_HT40(chan))
4919 i = ALL_TARGET_HT40_0_8_16; /* ht40 */
4920 else if (IS_CHAN_HT20(chan))
4921 i = ALL_TARGET_HT20_0_8_16; /* ht20 */
4923 ah->txpower_limit = targetPowerValT2[i];
4924 regulatory->max_power_level = targetPowerValT2[i];
4926 /* Write target power array to registers */
4927 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
4928 ar9003_hw_calibration_apply(ah, chan->channel);
4930 if (IS_CHAN_2GHZ(chan)) {
4931 if (IS_CHAN_HT40(chan))
4932 i = ALL_TARGET_HT40_0_8_16;
4934 i = ALL_TARGET_HT20_0_8_16;
4936 if (IS_CHAN_HT40(chan))
4937 i = ALL_TARGET_HT40_7;
4939 i = ALL_TARGET_HT20_7;
4941 ah->paprd_target_power = targetPowerValT2[i];
4944 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah __unused,
4945 u16 i __unused, int is2GHz __unused)
4950 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
4952 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4954 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
4957 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
4959 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4961 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
4964 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, int is_2ghz)
4966 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4969 return eep->modalHeader2G.spurChans;
4971 return eep->modalHeader5G.spurChans;
4974 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
4975 struct ath9k_channel *chan)
4977 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4979 if (IS_CHAN_2GHZ(chan))
4980 return MS((uint32_t)(eep->modalHeader2G.papdRateMaskHt20),
4981 AR9300_PAPRD_SCALE_1);
4983 if (chan->channel >= 5700)
4984 return MS((uint32_t)(eep->modalHeader5G.papdRateMaskHt20),
4985 AR9300_PAPRD_SCALE_1);
4986 else if (chan->channel >= 5400)
4987 return MS((uint32_t)(eep->modalHeader5G.papdRateMaskHt40),
4988 AR9300_PAPRD_SCALE_2);
4990 return MS((uint32_t)(eep->modalHeader5G.papdRateMaskHt40),
4991 AR9300_PAPRD_SCALE_1);
4995 const struct eeprom_ops eep_ar9300_ops = {
4996 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
4997 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
4998 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
4999 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5000 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5001 .set_board_values = ath9k_hw_ar9300_set_board_values,
5002 .set_addac = ath9k_hw_ar9300_set_addac,
5003 .set_txpower = ath9k_hw_ar9300_set_txpower,
5004 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel