2 * Copyright (c) 2010-2011 Atheros Communications Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <asm/unaligned.h>
19 #include "ar9003_phy.h"
20 #include "ar9003_eeprom.h"
21 #include "ar9003_mci.h"
23 #define COMP_HDR_LEN 4
24 #define COMP_CKSUM_LEN 2
26 #define LE16(x) cpu_to_le16(x)
27 #define LE32(x) cpu_to_le32(x)
29 /* Local defines to distinguish between extension and control CTL's */
30 #define EXT_ADDITIVE (0x8000)
31 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
32 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
33 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
35 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
36 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
38 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
40 #define EEPROM_DATA_LEN_9485 1088
42 static int ar9003_hw_power_interpolate(int32_t x,
43 int32_t *px, int32_t *py, u_int16_t np);
45 static const struct ar9300_eeprom ar9300_default = {
48 .macAddr = {0, 2, 3, 4, 5, 6},
49 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
52 .regDmn = { LE16(0), LE16(0x1f) },
53 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
55 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
59 .blueToothOptions = 0,
61 .deviceType = 5, /* takes lower byte in eeprom location */
62 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
63 .params_for_tuning_caps = {0, 0},
64 .featureEnable = 0x0c,
66 * bit0 - enable tx temp comp - disabled
67 * bit1 - enable tx volt comp - disabled
68 * bit2 - enable fastClock - enabled
69 * bit3 - enable doubling - enabled
70 * bit4 - enable internal regulator - disabled
71 * bit5 - enable pa predistortion - disabled
73 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
74 .eepromWriteEnableGpio = 3,
77 .rxBandSelectGpio = 0xff,
82 /* ar9300_modal_eep_header 2g */
83 /* 4 idle,t1,t2,b(4 bits per setting) */
84 .antCtrlCommon = LE32(0x110),
85 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
86 .antCtrlCommon2 = LE32(0x22222),
89 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
90 * rx1, rx12, b (2 bits each)
92 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
95 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
96 * for ar9280 (0xa20c/b20c 5:0)
98 .xatten1DB = {0, 0, 0},
101 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
102 * for ar9280 (0xa20c/b20c 16:12
104 .xatten1Margin = {0, 0, 0},
109 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
110 * channels in usual fbin coding format
112 .spurChans = {0, 0, 0, 0, 0},
115 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
116 * if the register is per chain
118 .noiseFloorThreshCh = {-1, 0, 0},
119 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
122 .txFrameToDataStart = 0x0e,
123 .txFrameToPaOn = 0x0e,
124 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
126 .switchSettling = 0x2c,
127 .adcDesiredSize = -30,
130 .txFrameToXpaOn = 0xe,
132 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
133 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
135 .xlna_bias_strength = 0,
141 .ant_div_control = 0,
143 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
150 /* ar9300_cal_data_per_freq_op_loop 2g */
152 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
153 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
154 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
156 .calTarget_freqbin_Cck = {
160 .calTarget_freqbin_2G = {
165 .calTarget_freqbin_2GHT20 = {
170 .calTarget_freqbin_2GHT40 = {
175 .calTargetPowerCck = {
176 /* 1L-5L,5S,11L,11S */
177 { {36, 36, 36, 36} },
178 { {36, 36, 36, 36} },
180 .calTargetPower2G = {
182 { {32, 32, 28, 24} },
183 { {32, 32, 28, 24} },
184 { {32, 32, 28, 24} },
186 .calTargetPower2GHT20 = {
187 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
188 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
189 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
191 .calTargetPower2GHT40 = {
192 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
193 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
194 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
197 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
198 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
228 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
229 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
230 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
231 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
235 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
236 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
237 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
242 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
243 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
249 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
250 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
251 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
252 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
256 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
257 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
258 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
262 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
263 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
264 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
269 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
270 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
271 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
276 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
277 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
278 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
279 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
283 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
284 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
285 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
287 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
288 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
289 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
291 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
292 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
293 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
295 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
296 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
297 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
300 /* 4 idle,t1,t2,b (4 bits per setting) */
301 .antCtrlCommon = LE32(0x110),
302 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
303 .antCtrlCommon2 = LE32(0x22222),
304 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
306 LE16(0x000), LE16(0x000), LE16(0x000),
308 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
309 .xatten1DB = {0, 0, 0},
312 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
313 * for merlin (0xa20c/b20c 16:12
315 .xatten1Margin = {0, 0, 0},
318 /* spurChans spur channels in usual fbin coding format */
319 .spurChans = {0, 0, 0, 0, 0},
320 /* noiseFloorThreshCh Check if the register is per chain */
321 .noiseFloorThreshCh = {-1, 0, 0},
322 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
325 .txFrameToDataStart = 0x0e,
326 .txFrameToPaOn = 0x0e,
327 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
329 .switchSettling = 0x2d,
330 .adcDesiredSize = -30,
333 .txFrameToXpaOn = 0xe,
335 .papdRateMaskHt20 = LE32(0x0c80c080),
336 .papdRateMaskHt40 = LE32(0x0080c080),
338 .xlna_bias_strength = 0,
346 .xatten1DBLow = {0, 0, 0},
347 .xatten1MarginLow = {0, 0, 0},
348 .xatten1DBHigh = {0, 0, 0},
349 .xatten1MarginHigh = {0, 0, 0}
394 .calTarget_freqbin_5G = {
404 .calTarget_freqbin_5GHT20 = {
414 .calTarget_freqbin_5GHT40 = {
424 .calTargetPower5G = {
426 { {20, 20, 20, 10} },
427 { {20, 20, 20, 10} },
428 { {20, 20, 20, 10} },
429 { {20, 20, 20, 10} },
430 { {20, 20, 20, 10} },
431 { {20, 20, 20, 10} },
432 { {20, 20, 20, 10} },
433 { {20, 20, 20, 10} },
435 .calTargetPower5GHT20 = {
437 * 0_8_16,1-3_9-11_17-19,
438 * 4,5,6,7,12,13,14,15,20,21,22,23
440 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
441 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
442 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
443 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
444 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
445 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
446 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
447 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
449 .calTargetPower5GHT40 = {
451 * 0_8_16,1-3_9-11_17-19,
452 * 4,5,6,7,12,13,14,15,20,21,22,23
454 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
455 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
456 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
457 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
458 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
459 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
460 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
461 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
464 0x10, 0x16, 0x18, 0x40, 0x46,
465 0x48, 0x30, 0x36, 0x38
469 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
470 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
471 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
472 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
473 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
474 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
475 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
476 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
479 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
480 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
481 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
482 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
483 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
484 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
485 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
486 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
490 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
491 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
492 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
493 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
494 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
495 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
496 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
497 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
501 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
502 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
503 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
504 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
505 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
506 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
507 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
508 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
512 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
513 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
514 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
515 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
516 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
517 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
518 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
519 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
523 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
524 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
525 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
526 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
527 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
528 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
529 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
530 /* Data[5].ctlEdges[7].bChannel */ 0xFF
534 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
535 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
536 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
537 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
538 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
539 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
540 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
541 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
545 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
546 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
547 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
548 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
549 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
550 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
551 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
552 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
556 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
557 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
558 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
559 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
560 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
561 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
562 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
563 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
569 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
570 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
575 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
576 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
581 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
582 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
587 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
588 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
593 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
594 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
599 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
600 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
605 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
606 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
611 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
612 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
617 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
618 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
624 static const struct ar9300_eeprom ar9300_x113 = {
626 .templateVersion = 6,
627 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
628 .custData = {"x113-023-f0000"},
630 .regDmn = { LE16(0), LE16(0x1f) },
631 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
633 .opFlags = AR5416_OPFLAGS_11A,
637 .blueToothOptions = 0,
639 .deviceType = 5, /* takes lower byte in eeprom location */
640 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
641 .params_for_tuning_caps = {0, 0},
642 .featureEnable = 0x0d,
644 * bit0 - enable tx temp comp - disabled
645 * bit1 - enable tx volt comp - disabled
646 * bit2 - enable fastClock - enabled
647 * bit3 - enable doubling - enabled
648 * bit4 - enable internal regulator - disabled
649 * bit5 - enable pa predistortion - disabled
651 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
652 .eepromWriteEnableGpio = 6,
653 .wlanDisableGpio = 0,
655 .rxBandSelectGpio = 0xff,
660 /* ar9300_modal_eep_header 2g */
661 /* 4 idle,t1,t2,b(4 bits per setting) */
662 .antCtrlCommon = LE32(0x110),
663 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
664 .antCtrlCommon2 = LE32(0x44444),
667 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
668 * rx1, rx12, b (2 bits each)
670 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
673 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
674 * for ar9280 (0xa20c/b20c 5:0)
676 .xatten1DB = {0, 0, 0},
679 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
680 * for ar9280 (0xa20c/b20c 16:12
682 .xatten1Margin = {0, 0, 0},
687 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
688 * channels in usual fbin coding format
690 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
693 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
694 * if the register is per chain
696 .noiseFloorThreshCh = {-1, 0, 0},
697 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
700 .txFrameToDataStart = 0x0e,
701 .txFrameToPaOn = 0x0e,
702 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
704 .switchSettling = 0x2c,
705 .adcDesiredSize = -30,
708 .txFrameToXpaOn = 0xe,
710 .papdRateMaskHt20 = LE32(0x0c80c080),
711 .papdRateMaskHt40 = LE32(0x0080c080),
713 .xlna_bias_strength = 0,
719 .ant_div_control = 0,
721 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
728 /* ar9300_cal_data_per_freq_op_loop 2g */
730 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
731 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
732 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
734 .calTarget_freqbin_Cck = {
738 .calTarget_freqbin_2G = {
743 .calTarget_freqbin_2GHT20 = {
748 .calTarget_freqbin_2GHT40 = {
753 .calTargetPowerCck = {
754 /* 1L-5L,5S,11L,11S */
755 { {34, 34, 34, 34} },
756 { {34, 34, 34, 34} },
758 .calTargetPower2G = {
760 { {34, 34, 32, 32} },
761 { {34, 34, 32, 32} },
762 { {34, 34, 32, 32} },
764 .calTargetPower2GHT20 = {
765 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
766 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
767 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
769 .calTargetPower2GHT40 = {
770 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
771 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
772 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
775 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
776 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
806 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
807 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
808 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
809 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
813 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
814 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
815 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
820 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
821 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
827 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
828 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
829 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
830 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
834 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
835 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
836 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
840 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
841 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
842 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
847 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
848 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
849 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
854 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
855 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
856 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
857 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
861 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
862 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
863 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
865 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
866 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
867 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
869 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
870 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
871 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
873 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
874 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
875 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
878 /* 4 idle,t1,t2,b (4 bits per setting) */
879 .antCtrlCommon = LE32(0x220),
880 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
881 .antCtrlCommon2 = LE32(0x11111),
882 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
884 LE16(0x150), LE16(0x150), LE16(0x150),
886 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
887 .xatten1DB = {0, 0, 0},
890 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
891 * for merlin (0xa20c/b20c 16:12
893 .xatten1Margin = {0, 0, 0},
896 /* spurChans spur channels in usual fbin coding format */
897 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
898 /* noiseFloorThreshCh Check if the register is per chain */
899 .noiseFloorThreshCh = {-1, 0, 0},
900 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
903 .txFrameToDataStart = 0x0e,
904 .txFrameToPaOn = 0x0e,
905 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
907 .switchSettling = 0x2d,
908 .adcDesiredSize = -30,
911 .txFrameToXpaOn = 0xe,
913 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
914 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
916 .xlna_bias_strength = 0,
923 .tempSlopeHigh = 105,
924 .xatten1DBLow = {0, 0, 0},
925 .xatten1MarginLow = {0, 0, 0},
926 .xatten1DBHigh = {0, 0, 0},
927 .xatten1MarginHigh = {0, 0, 0}
972 .calTarget_freqbin_5G = {
982 .calTarget_freqbin_5GHT20 = {
992 .calTarget_freqbin_5GHT40 = {
1002 .calTargetPower5G = {
1004 { {42, 40, 40, 34} },
1005 { {42, 40, 40, 34} },
1006 { {42, 40, 40, 34} },
1007 { {42, 40, 40, 34} },
1008 { {42, 40, 40, 34} },
1009 { {42, 40, 40, 34} },
1010 { {42, 40, 40, 34} },
1011 { {42, 40, 40, 34} },
1013 .calTargetPower5GHT20 = {
1015 * 0_8_16,1-3_9-11_17-19,
1016 * 4,5,6,7,12,13,14,15,20,21,22,23
1018 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1019 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1020 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1021 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1022 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1023 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1024 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1025 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1027 .calTargetPower5GHT40 = {
1029 * 0_8_16,1-3_9-11_17-19,
1030 * 4,5,6,7,12,13,14,15,20,21,22,23
1032 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1033 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1034 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1035 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1036 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1037 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1038 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1039 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1042 0x10, 0x16, 0x18, 0x40, 0x46,
1043 0x48, 0x30, 0x36, 0x38
1047 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1048 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1049 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1050 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1051 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1052 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1053 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1054 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1057 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1058 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1059 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1060 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1061 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1062 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1063 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1064 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1068 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1069 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1070 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1071 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1072 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1073 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1074 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1075 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1079 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1080 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1081 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1082 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1083 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1084 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1085 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1086 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1090 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1091 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1092 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1093 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1094 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1095 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1096 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1097 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1101 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1102 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1103 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1104 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1105 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1106 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1107 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1108 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1112 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1113 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1114 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1115 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1116 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1117 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1118 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1119 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1123 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1124 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1125 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1126 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1127 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1128 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1129 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1130 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1134 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1135 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1136 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1137 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1138 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1139 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1140 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1141 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1144 .ctlPowerData_5G = {
1147 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1148 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1153 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1154 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1159 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1160 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1165 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1166 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1171 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1172 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1177 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1178 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1183 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1184 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1189 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1190 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1195 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1196 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1203 static const struct ar9300_eeprom ar9300_h112 = {
1205 .templateVersion = 3,
1206 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1207 .custData = {"h112-241-f0000"},
1209 .regDmn = { LE16(0), LE16(0x1f) },
1210 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1212 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1216 .blueToothOptions = 0,
1218 .deviceType = 5, /* takes lower byte in eeprom location */
1219 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1220 .params_for_tuning_caps = {0, 0},
1221 .featureEnable = 0x0d,
1223 * bit0 - enable tx temp comp - disabled
1224 * bit1 - enable tx volt comp - disabled
1225 * bit2 - enable fastClock - enabled
1226 * bit3 - enable doubling - enabled
1227 * bit4 - enable internal regulator - disabled
1228 * bit5 - enable pa predistortion - disabled
1230 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1231 .eepromWriteEnableGpio = 6,
1232 .wlanDisableGpio = 0,
1234 .rxBandSelectGpio = 0xff,
1239 /* ar9300_modal_eep_header 2g */
1240 /* 4 idle,t1,t2,b(4 bits per setting) */
1241 .antCtrlCommon = LE32(0x110),
1242 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1243 .antCtrlCommon2 = LE32(0x44444),
1246 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1247 * rx1, rx12, b (2 bits each)
1249 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1252 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1253 * for ar9280 (0xa20c/b20c 5:0)
1255 .xatten1DB = {0, 0, 0},
1258 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1259 * for ar9280 (0xa20c/b20c 16:12
1261 .xatten1Margin = {0, 0, 0},
1266 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1267 * channels in usual fbin coding format
1269 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1272 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1273 * if the register is per chain
1275 .noiseFloorThreshCh = {-1, 0, 0},
1276 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1279 .txFrameToDataStart = 0x0e,
1280 .txFrameToPaOn = 0x0e,
1281 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1283 .switchSettling = 0x2c,
1284 .adcDesiredSize = -30,
1287 .txFrameToXpaOn = 0xe,
1289 .papdRateMaskHt20 = LE32(0x0c80c080),
1290 .papdRateMaskHt40 = LE32(0x0080c080),
1292 .xlna_bias_strength = 0,
1294 0, 0, 0, 0, 0, 0, 0,
1298 .ant_div_control = 0,
1300 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1307 /* ar9300_cal_data_per_freq_op_loop 2g */
1309 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1310 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1311 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1313 .calTarget_freqbin_Cck = {
1317 .calTarget_freqbin_2G = {
1322 .calTarget_freqbin_2GHT20 = {
1327 .calTarget_freqbin_2GHT40 = {
1332 .calTargetPowerCck = {
1333 /* 1L-5L,5S,11L,11S */
1334 { {34, 34, 34, 34} },
1335 { {34, 34, 34, 34} },
1337 .calTargetPower2G = {
1339 { {34, 34, 32, 32} },
1340 { {34, 34, 32, 32} },
1341 { {34, 34, 32, 32} },
1343 .calTargetPower2GHT20 = {
1344 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1345 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1346 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1348 .calTargetPower2GHT40 = {
1349 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1350 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1351 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1354 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1355 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1385 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1386 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1387 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1388 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1392 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1393 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1394 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1399 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1400 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1406 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1407 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1408 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1409 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1413 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1414 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1415 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1419 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1420 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1421 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1426 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1427 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1428 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1433 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1434 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1435 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1436 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1439 .ctlPowerData_2G = {
1440 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1441 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1442 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1444 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
1445 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1446 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1448 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1449 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1450 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1452 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1453 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1454 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1457 /* 4 idle,t1,t2,b (4 bits per setting) */
1458 .antCtrlCommon = LE32(0x220),
1459 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1460 .antCtrlCommon2 = LE32(0x44444),
1461 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1463 LE16(0x150), LE16(0x150), LE16(0x150),
1465 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1466 .xatten1DB = {0, 0, 0},
1469 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1470 * for merlin (0xa20c/b20c 16:12
1472 .xatten1Margin = {0, 0, 0},
1475 /* spurChans spur channels in usual fbin coding format */
1476 .spurChans = {0, 0, 0, 0, 0},
1477 /* noiseFloorThreshCh Check if the register is per chain */
1478 .noiseFloorThreshCh = {-1, 0, 0},
1479 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1482 .txFrameToDataStart = 0x0e,
1483 .txFrameToPaOn = 0x0e,
1484 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1486 .switchSettling = 0x2d,
1487 .adcDesiredSize = -30,
1490 .txFrameToXpaOn = 0xe,
1492 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1493 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1495 .xlna_bias_strength = 0,
1497 0, 0, 0, 0, 0, 0, 0,
1502 .tempSlopeHigh = 50,
1503 .xatten1DBLow = {0, 0, 0},
1504 .xatten1MarginLow = {0, 0, 0},
1505 .xatten1DBHigh = {0, 0, 0},
1506 .xatten1MarginHigh = {0, 0, 0}
1551 .calTarget_freqbin_5G = {
1561 .calTarget_freqbin_5GHT20 = {
1571 .calTarget_freqbin_5GHT40 = {
1581 .calTargetPower5G = {
1583 { {30, 30, 28, 24} },
1584 { {30, 30, 28, 24} },
1585 { {30, 30, 28, 24} },
1586 { {30, 30, 28, 24} },
1587 { {30, 30, 28, 24} },
1588 { {30, 30, 28, 24} },
1589 { {30, 30, 28, 24} },
1590 { {30, 30, 28, 24} },
1592 .calTargetPower5GHT20 = {
1594 * 0_8_16,1-3_9-11_17-19,
1595 * 4,5,6,7,12,13,14,15,20,21,22,23
1597 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1598 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1599 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1600 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1601 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1602 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1603 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1604 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1606 .calTargetPower5GHT40 = {
1608 * 0_8_16,1-3_9-11_17-19,
1609 * 4,5,6,7,12,13,14,15,20,21,22,23
1611 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1612 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1613 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1614 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1615 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1616 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1617 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1618 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1621 0x10, 0x16, 0x18, 0x40, 0x46,
1622 0x48, 0x30, 0x36, 0x38
1626 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1627 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1628 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1629 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1630 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1631 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1632 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1633 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1636 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1637 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1638 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1639 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1640 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1641 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1642 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1643 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1647 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1648 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1649 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1650 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1651 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1652 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1653 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1654 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1658 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1659 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1660 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1661 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1662 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1663 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1664 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1665 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1669 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1670 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1671 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1672 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1673 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1674 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1675 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1676 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1680 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1681 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1682 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1683 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1684 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1685 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1686 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1687 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1691 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1692 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1693 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1694 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1695 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1696 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1697 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1698 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1702 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1703 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1704 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1705 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1706 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1707 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1708 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1709 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1713 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1714 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1715 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1716 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1717 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1718 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1719 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1720 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1723 .ctlPowerData_5G = {
1726 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1727 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1732 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1733 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1738 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1739 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1744 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1745 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1750 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1751 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1756 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1757 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1762 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1763 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1768 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1769 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1774 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1775 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1782 static const struct ar9300_eeprom ar9300_x112 = {
1784 .templateVersion = 5,
1785 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1786 .custData = {"x112-041-f0000"},
1788 .regDmn = { LE16(0), LE16(0x1f) },
1789 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1791 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1795 .blueToothOptions = 0,
1797 .deviceType = 5, /* takes lower byte in eeprom location */
1798 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1799 .params_for_tuning_caps = {0, 0},
1800 .featureEnable = 0x0d,
1802 * bit0 - enable tx temp comp - disabled
1803 * bit1 - enable tx volt comp - disabled
1804 * bit2 - enable fastclock - enabled
1805 * bit3 - enable doubling - enabled
1806 * bit4 - enable internal regulator - disabled
1807 * bit5 - enable pa predistortion - disabled
1809 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1810 .eepromWriteEnableGpio = 6,
1811 .wlanDisableGpio = 0,
1813 .rxBandSelectGpio = 0xff,
1818 /* ar9300_modal_eep_header 2g */
1819 /* 4 idle,t1,t2,b(4 bits per setting) */
1820 .antCtrlCommon = LE32(0x110),
1821 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1822 .antCtrlCommon2 = LE32(0x22222),
1825 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1826 * rx1, rx12, b (2 bits each)
1828 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1831 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1832 * for ar9280 (0xa20c/b20c 5:0)
1834 .xatten1DB = {0x1b, 0x1b, 0x1b},
1837 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1838 * for ar9280 (0xa20c/b20c 16:12
1840 .xatten1Margin = {0x15, 0x15, 0x15},
1845 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1846 * channels in usual fbin coding format
1848 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1851 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1852 * if the register is per chain
1854 .noiseFloorThreshCh = {-1, 0, 0},
1855 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1858 .txFrameToDataStart = 0x0e,
1859 .txFrameToPaOn = 0x0e,
1860 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1862 .switchSettling = 0x2c,
1863 .adcDesiredSize = -30,
1866 .txFrameToXpaOn = 0xe,
1868 .papdRateMaskHt20 = LE32(0x0c80c080),
1869 .papdRateMaskHt40 = LE32(0x0080c080),
1871 .xlna_bias_strength = 0,
1873 0, 0, 0, 0, 0, 0, 0,
1877 .ant_div_control = 0,
1879 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1886 /* ar9300_cal_data_per_freq_op_loop 2g */
1888 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1889 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1890 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1892 .calTarget_freqbin_Cck = {
1896 .calTarget_freqbin_2G = {
1901 .calTarget_freqbin_2GHT20 = {
1906 .calTarget_freqbin_2GHT40 = {
1911 .calTargetPowerCck = {
1912 /* 1L-5L,5S,11L,11s */
1913 { {38, 38, 38, 38} },
1914 { {38, 38, 38, 38} },
1916 .calTargetPower2G = {
1918 { {38, 38, 36, 34} },
1919 { {38, 38, 36, 34} },
1920 { {38, 38, 34, 32} },
1922 .calTargetPower2GHT20 = {
1923 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1924 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1925 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1927 .calTargetPower2GHT40 = {
1928 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1929 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1930 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1933 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1934 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1964 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1965 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1966 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1967 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1971 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1972 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1973 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1978 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1979 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1985 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
1986 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
1987 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
1988 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
1992 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1993 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1994 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1998 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1999 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2000 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2005 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2006 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2007 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2012 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2013 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2014 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2015 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2018 .ctlPowerData_2G = {
2019 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2020 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2021 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2023 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2024 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2025 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2027 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2028 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2029 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2031 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2032 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2033 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2036 /* 4 idle,t1,t2,b (4 bits per setting) */
2037 .antCtrlCommon = LE32(0x110),
2038 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2039 .antCtrlCommon2 = LE32(0x22222),
2040 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2042 LE16(0x0), LE16(0x0), LE16(0x0),
2044 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2045 .xatten1DB = {0x13, 0x19, 0x17},
2048 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2049 * for merlin (0xa20c/b20c 16:12
2051 .xatten1Margin = {0x19, 0x19, 0x19},
2054 /* spurChans spur channels in usual fbin coding format */
2055 .spurChans = {0, 0, 0, 0, 0},
2056 /* noiseFloorThreshch check if the register is per chain */
2057 .noiseFloorThreshCh = {-1, 0, 0},
2058 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2061 .txFrameToDataStart = 0x0e,
2062 .txFrameToPaOn = 0x0e,
2063 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2065 .switchSettling = 0x2d,
2066 .adcDesiredSize = -30,
2069 .txFrameToXpaOn = 0xe,
2071 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2072 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2074 .xlna_bias_strength = 0,
2076 0, 0, 0, 0, 0, 0, 0,
2081 .tempSlopeHigh = 105,
2082 .xatten1DBLow = {0x10, 0x14, 0x10},
2083 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2084 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2085 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2130 .calTarget_freqbin_5G = {
2140 .calTarget_freqbin_5GHT20 = {
2150 .calTarget_freqbin_5GHT40 = {
2160 .calTargetPower5G = {
2162 { {32, 32, 28, 26} },
2163 { {32, 32, 28, 26} },
2164 { {32, 32, 28, 26} },
2165 { {32, 32, 26, 24} },
2166 { {32, 32, 26, 24} },
2167 { {32, 32, 24, 22} },
2168 { {30, 30, 24, 22} },
2169 { {30, 30, 24, 22} },
2171 .calTargetPower5GHT20 = {
2173 * 0_8_16,1-3_9-11_17-19,
2174 * 4,5,6,7,12,13,14,15,20,21,22,23
2176 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2177 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2178 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2179 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2180 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2181 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2182 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2183 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2185 .calTargetPower5GHT40 = {
2187 * 0_8_16,1-3_9-11_17-19,
2188 * 4,5,6,7,12,13,14,15,20,21,22,23
2190 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2191 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2192 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2193 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2194 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2195 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2196 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2197 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2200 0x10, 0x16, 0x18, 0x40, 0x46,
2201 0x48, 0x30, 0x36, 0x38
2205 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2206 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2207 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2208 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2209 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2210 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2211 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2212 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2215 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2216 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2217 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2218 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2219 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2220 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2221 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2222 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2226 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2227 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2228 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2229 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2230 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2231 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2232 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2233 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2237 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2238 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2239 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2240 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2241 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2242 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2243 /* Data[3].ctledges[6].bchannel */ 0xFF,
2244 /* Data[3].ctledges[7].bchannel */ 0xFF,
2248 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2249 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2250 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2251 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2252 /* Data[4].ctledges[4].bchannel */ 0xFF,
2253 /* Data[4].ctledges[5].bchannel */ 0xFF,
2254 /* Data[4].ctledges[6].bchannel */ 0xFF,
2255 /* Data[4].ctledges[7].bchannel */ 0xFF,
2259 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2260 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2261 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2262 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2263 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2264 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2265 /* Data[5].ctledges[6].bchannel */ 0xFF,
2266 /* Data[5].ctledges[7].bchannel */ 0xFF
2270 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2271 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2272 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2273 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2274 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2275 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2276 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2277 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2281 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2282 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2283 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2284 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2285 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2286 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2287 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2288 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2292 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2293 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2294 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2295 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2296 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2297 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2298 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2299 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2302 .ctlPowerData_5G = {
2305 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2306 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2311 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2312 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2317 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2318 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2323 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2324 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2329 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2330 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2335 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2336 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2341 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2342 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2347 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2348 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2353 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2354 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2360 static const struct ar9300_eeprom ar9300_h116 = {
2362 .templateVersion = 4,
2363 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2364 .custData = {"h116-041-f0000"},
2366 .regDmn = { LE16(0), LE16(0x1f) },
2367 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2369 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2373 .blueToothOptions = 0,
2375 .deviceType = 5, /* takes lower byte in eeprom location */
2376 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2377 .params_for_tuning_caps = {0, 0},
2378 .featureEnable = 0x0d,
2380 * bit0 - enable tx temp comp - disabled
2381 * bit1 - enable tx volt comp - disabled
2382 * bit2 - enable fastClock - enabled
2383 * bit3 - enable doubling - enabled
2384 * bit4 - enable internal regulator - disabled
2385 * bit5 - enable pa predistortion - disabled
2387 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2388 .eepromWriteEnableGpio = 6,
2389 .wlanDisableGpio = 0,
2391 .rxBandSelectGpio = 0xff,
2396 /* ar9300_modal_eep_header 2g */
2397 /* 4 idle,t1,t2,b(4 bits per setting) */
2398 .antCtrlCommon = LE32(0x110),
2399 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2400 .antCtrlCommon2 = LE32(0x44444),
2403 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2404 * rx1, rx12, b (2 bits each)
2406 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2409 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2410 * for ar9280 (0xa20c/b20c 5:0)
2412 .xatten1DB = {0x1f, 0x1f, 0x1f},
2415 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2416 * for ar9280 (0xa20c/b20c 16:12
2418 .xatten1Margin = {0x12, 0x12, 0x12},
2423 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2424 * channels in usual fbin coding format
2426 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2429 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2430 * if the register is per chain
2432 .noiseFloorThreshCh = {-1, 0, 0},
2433 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2436 .txFrameToDataStart = 0x0e,
2437 .txFrameToPaOn = 0x0e,
2438 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2440 .switchSettling = 0x2c,
2441 .adcDesiredSize = -30,
2444 .txFrameToXpaOn = 0xe,
2446 .papdRateMaskHt20 = LE32(0x0c80C080),
2447 .papdRateMaskHt40 = LE32(0x0080C080),
2449 .xlna_bias_strength = 0,
2451 0, 0, 0, 0, 0, 0, 0,
2455 .ant_div_control = 0,
2457 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
2464 /* ar9300_cal_data_per_freq_op_loop 2g */
2466 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2467 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2468 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2470 .calTarget_freqbin_Cck = {
2474 .calTarget_freqbin_2G = {
2479 .calTarget_freqbin_2GHT20 = {
2484 .calTarget_freqbin_2GHT40 = {
2489 .calTargetPowerCck = {
2490 /* 1L-5L,5S,11L,11S */
2491 { {34, 34, 34, 34} },
2492 { {34, 34, 34, 34} },
2494 .calTargetPower2G = {
2496 { {34, 34, 32, 32} },
2497 { {34, 34, 32, 32} },
2498 { {34, 34, 32, 32} },
2500 .calTargetPower2GHT20 = {
2501 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2502 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2503 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2505 .calTargetPower2GHT40 = {
2506 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2507 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2508 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2511 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2512 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2542 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2543 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2544 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2545 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2549 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2550 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2551 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2556 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2557 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2563 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2564 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2565 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2566 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2570 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2571 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2572 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2576 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2577 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2578 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2583 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2584 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2585 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2590 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2591 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2592 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2593 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2596 .ctlPowerData_2G = {
2597 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2598 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2599 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2601 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2602 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2603 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2605 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2606 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2607 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2609 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2610 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2611 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2614 /* 4 idle,t1,t2,b (4 bits per setting) */
2615 .antCtrlCommon = LE32(0x220),
2616 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2617 .antCtrlCommon2 = LE32(0x44444),
2618 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2620 LE16(0x150), LE16(0x150), LE16(0x150),
2622 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2623 .xatten1DB = {0x19, 0x19, 0x19},
2626 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2627 * for merlin (0xa20c/b20c 16:12
2629 .xatten1Margin = {0x14, 0x14, 0x14},
2632 /* spurChans spur channels in usual fbin coding format */
2633 .spurChans = {0, 0, 0, 0, 0},
2634 /* noiseFloorThreshCh Check if the register is per chain */
2635 .noiseFloorThreshCh = {-1, 0, 0},
2636 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2639 .txFrameToDataStart = 0x0e,
2640 .txFrameToPaOn = 0x0e,
2641 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2643 .switchSettling = 0x2d,
2644 .adcDesiredSize = -30,
2647 .txFrameToXpaOn = 0xe,
2649 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2650 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2652 .xlna_bias_strength = 0,
2654 0, 0, 0, 0, 0, 0, 0,
2659 .tempSlopeHigh = 50,
2660 .xatten1DBLow = {0, 0, 0},
2661 .xatten1MarginLow = {0, 0, 0},
2662 .xatten1DBHigh = {0, 0, 0},
2663 .xatten1MarginHigh = {0, 0, 0}
2708 .calTarget_freqbin_5G = {
2718 .calTarget_freqbin_5GHT20 = {
2728 .calTarget_freqbin_5GHT40 = {
2738 .calTargetPower5G = {
2740 { {30, 30, 28, 24} },
2741 { {30, 30, 28, 24} },
2742 { {30, 30, 28, 24} },
2743 { {30, 30, 28, 24} },
2744 { {30, 30, 28, 24} },
2745 { {30, 30, 28, 24} },
2746 { {30, 30, 28, 24} },
2747 { {30, 30, 28, 24} },
2749 .calTargetPower5GHT20 = {
2751 * 0_8_16,1-3_9-11_17-19,
2752 * 4,5,6,7,12,13,14,15,20,21,22,23
2754 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2755 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2756 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2757 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2758 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2759 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2760 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2761 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2763 .calTargetPower5GHT40 = {
2765 * 0_8_16,1-3_9-11_17-19,
2766 * 4,5,6,7,12,13,14,15,20,21,22,23
2768 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2769 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2770 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2771 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2772 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2773 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2774 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2775 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2778 0x10, 0x16, 0x18, 0x40, 0x46,
2779 0x48, 0x30, 0x36, 0x38
2783 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2784 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2785 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2786 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2787 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2788 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2789 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2790 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2793 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2794 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2795 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2796 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2797 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2798 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2799 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2800 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2804 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2805 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2806 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2807 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2808 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2809 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2810 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2811 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2815 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2816 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2817 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2818 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2819 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2820 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2821 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2822 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2826 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2827 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2828 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2829 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2830 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2831 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2832 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2833 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2837 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2838 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2839 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2840 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2841 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2842 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2843 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2844 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2848 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2849 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2850 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2851 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2852 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2853 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2854 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2855 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2859 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2860 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2861 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2862 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2863 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2864 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2865 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2866 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2870 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2871 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2872 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2873 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2874 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2875 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2876 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2877 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2880 .ctlPowerData_5G = {
2883 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2884 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2889 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2890 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2895 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2896 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2901 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2902 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2907 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2908 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2913 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2914 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2919 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2920 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2925 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2926 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2931 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2932 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2939 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2947 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2949 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2952 for (it = 0; it < N_LOOP; it++)
2953 if (ar9300_eep_templates[it]->templateVersion == id)
2954 return ar9300_eep_templates[it];
2959 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2964 static int interpolate(int x, int xa, int xb, int ya, int yb)
2966 int bf, factor, plus;
2968 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2971 return ya + factor + plus;
2974 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2975 enum eeprom_param param)
2977 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2978 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
2982 return get_unaligned_be16(eep->macAddr);
2984 return get_unaligned_be16(eep->macAddr + 2);
2986 return get_unaligned_be16(eep->macAddr + 4);
2988 return le16_to_cpu(pBase->regDmn[0]);
2990 return pBase->deviceCap;
2992 return pBase->opCapFlags.opFlags;
2994 return pBase->rfSilent;
2996 return (pBase->txrxMask >> 4) & 0xf;
2998 return pBase->txrxMask & 0xf;
3000 return !!(pBase->featureEnable & BIT(5));
3001 case EEP_CHAIN_MASK_REDUCE:
3002 return (pBase->miscConfiguration >> 0x3) & 0x1;
3003 case EEP_ANT_DIV_CTL1:
3004 if (AR_SREV_9565(ah))
3005 return AR9300_EEP_ANTDIV_CONTROL_DEFAULT_VALUE;
3007 return eep->base_ext1.ant_div_control;
3008 case EEP_ANTENNA_GAIN_5G:
3009 return eep->modalHeader5G.antennaGain;
3010 case EEP_ANTENNA_GAIN_2G:
3011 return eep->modalHeader2G.antennaGain;
3017 static bool ar9300_eeprom_read_byte(struct ath_hw *ah, int address,
3022 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3025 *buffer = (val >> (8 * (address % 2))) & 0xff;
3029 static bool ar9300_eeprom_read_word(struct ath_hw *ah, int address,
3034 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3037 buffer[0] = val >> 8;
3038 buffer[1] = val & 0xff;
3043 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3046 struct ath_common *common = ath9k_hw_common(ah);
3049 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3050 ath_dbg(common, EEPROM, "eeprom address not in range\n");
3055 * Since we're reading the bytes in reverse order from a little-endian
3056 * word stream, an even address means we only use the lower half of
3057 * the 16-bit word at that address
3059 if (address % 2 == 0) {
3060 if (!ar9300_eeprom_read_byte(ah, address--, buffer++))
3066 for (i = 0; i < count / 2; i++) {
3067 if (!ar9300_eeprom_read_word(ah, address, buffer))
3075 if (!ar9300_eeprom_read_byte(ah, address, buffer))
3081 ath_dbg(common, EEPROM, "unable to read eeprom region at offset %d\n",
3086 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3088 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3090 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3091 AR9300_OTP_STATUS_VALID, 1000))
3094 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3098 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3104 for (i = 0; i < count; i++) {
3105 int offset = 8 * ((address - i) % 4);
3106 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3109 buffer[i] = (data >> offset) & 0xff;
3116 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3117 int *length, int *major, int *minor)
3119 unsigned long value[4];
3125 *code = ((value[0] >> 5) & 0x0007);
3126 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3127 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3128 *major = (value[2] & 0x000f);
3129 *minor = (value[3] & 0x00ff);
3132 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3134 int it, checksum = 0;
3136 for (it = 0; it < dsize; it++) {
3137 checksum += data[it];
3144 static bool ar9300_uncompress_block(struct ath_hw *ah,
3154 struct ath_common *common = ath9k_hw_common(ah);
3158 for (it = 0; it < size; it += (length+2)) {
3162 length = block[it+1];
3165 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3166 ath_dbg(common, EEPROM,
3167 "Restore at %d: spot=%d offset=%d length=%d\n",
3168 it, spot, offset, length);
3169 memcpy(&mptr[spot], &block[it+2], length);
3171 } else if (length > 0) {
3172 ath_dbg(common, EEPROM,
3173 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3174 it, spot, offset, length);
3181 static int ar9300_compress_decision(struct ath_hw *ah,
3186 u8 *word, int length, int mdata_size)
3188 struct ath_common *common = ath9k_hw_common(ah);
3189 const struct ar9300_eeprom *eep = NULL;
3193 if (length != mdata_size) {
3194 ath_dbg(common, EEPROM,
3195 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3196 mdata_size, length);
3199 memcpy(mptr, word + COMP_HDR_LEN, length);
3200 ath_dbg(common, EEPROM,
3201 "restored eeprom %d: uncompressed, length %d\n",
3204 case _CompressBlock:
3205 if (reference == 0) {
3207 eep = ar9003_eeprom_struct_find_by_id(reference);
3209 ath_dbg(common, EEPROM,
3210 "can't find reference eeprom struct %d\n",
3214 memcpy(mptr, eep, mdata_size);
3216 ath_dbg(common, EEPROM,
3217 "restore eeprom %d: block, reference %d, length %d\n",
3218 it, reference, length);
3219 ar9300_uncompress_block(ah, mptr, mdata_size,
3220 (word + COMP_HDR_LEN), length);
3223 ath_dbg(common, EEPROM, "unknown compression code %d\n", code);
3229 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3232 static bool ar9300_check_header(void *data)
3235 return !(*word == 0 || *word == ~0);
3238 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3243 if (!read(ah, base_addr, header, 4))
3246 return ar9300_check_header(header);
3249 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3252 u16 *data = (u16 *) mptr;
3255 for (i = 0; i < mdata_size / 2; i++, data++)
3256 ath9k_hw_nvram_read(ah, i, data);
3261 * Read the configuration data from the eeprom.
3262 * The data can be put in any specified memory buffer.
3264 * Returns -1 on error.
3265 * Returns address of next memory location on success.
3267 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3268 u8 *mptr, int mdata_size)
3275 int reference, length, major, minor;
3278 u16 checksum, mchecksum;
3279 struct ath_common *common = ath9k_hw_common(ah);
3280 struct ar9300_eeprom *eep;
3281 eeprom_read_op read;
3283 if (ath9k_hw_use_flash(ah)) {
3286 ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3288 /* check if eeprom contains valid data */
3289 eep = (struct ar9300_eeprom *) mptr;
3290 txrx = eep->baseEepHeader.txrxMask;
3291 if (txrx != 0 && txrx != 0xff)
3295 word = kzalloc(2048, GFP_KERNEL);
3299 memcpy(mptr, &ar9300_default, mdata_size);
3301 read = ar9300_read_eeprom;
3302 if (AR_SREV_9485(ah))
3303 cptr = AR9300_BASE_ADDR_4K;
3304 else if (AR_SREV_9330(ah))
3305 cptr = AR9300_BASE_ADDR_512;
3307 cptr = AR9300_BASE_ADDR;
3308 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3310 if (ar9300_check_eeprom_header(ah, read, cptr))
3313 cptr = AR9300_BASE_ADDR_512;
3314 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3316 if (ar9300_check_eeprom_header(ah, read, cptr))
3319 read = ar9300_read_otp;
3320 cptr = AR9300_BASE_ADDR;
3321 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3322 if (ar9300_check_eeprom_header(ah, read, cptr))
3325 cptr = AR9300_BASE_ADDR_512;
3326 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3327 if (ar9300_check_eeprom_header(ah, read, cptr))
3333 ath_dbg(common, EEPROM, "Found valid EEPROM data\n");
3335 for (it = 0; it < MSTATE; it++) {
3336 if (!read(ah, cptr, word, COMP_HDR_LEN))
3339 if (!ar9300_check_header(word))
3342 ar9300_comp_hdr_unpack(word, &code, &reference,
3343 &length, &major, &minor);
3344 ath_dbg(common, EEPROM,
3345 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3346 cptr, code, reference, length, major, minor);
3347 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3348 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485) ||
3350 ath_dbg(common, EEPROM, "Skipping bad header\n");
3351 cptr -= COMP_HDR_LEN;
3356 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3357 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3358 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3359 ath_dbg(common, EEPROM, "checksum %x %x\n",
3360 checksum, mchecksum);
3361 if (checksum == mchecksum) {
3362 ar9300_compress_decision(ah, it, code, reference, mptr,
3363 word, length, mdata_size);
3365 ath_dbg(common, EEPROM,
3366 "skipping block with bad checksum\n");
3368 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3380 * Restore the configuration structure by reading the eeprom.
3381 * This function destroys any existing in-memory structure
3384 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3386 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3388 if (ar9300_eeprom_restore_internal(ah, mptr,
3389 sizeof(struct ar9300_eeprom)) < 0)
3395 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3396 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3397 struct ar9300_modal_eep_header *modal_hdr)
3399 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3400 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3401 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3402 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3403 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3404 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3405 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3406 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3407 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3408 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3409 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3410 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3411 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3412 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3413 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3414 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3415 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3416 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3417 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3418 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3419 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3420 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3421 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3422 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3423 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3424 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3425 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3426 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3427 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3428 PR_EEP("txClip", modal_hdr->txClip);
3429 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3434 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3435 u8 *buf, u32 len, u32 size)
3437 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3438 struct ar9300_base_eep_hdr *pBase;
3440 if (!dump_base_hdr) {
3441 len += scnprintf(buf + len, size - len,
3442 "%20s :\n", "2GHz modal Header");
3443 len = ar9003_dump_modal_eeprom(buf, len, size,
3444 &eep->modalHeader2G);
3445 len += scnprintf(buf + len, size - len,
3446 "%20s :\n", "5GHz modal Header");
3447 len = ar9003_dump_modal_eeprom(buf, len, size,
3448 &eep->modalHeader5G);
3452 pBase = &eep->baseEepHeader;
3454 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3455 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3456 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3457 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3458 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3459 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3460 AR5416_OPFLAGS_11A));
3461 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3462 AR5416_OPFLAGS_11G));
3463 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3464 AR5416_OPFLAGS_N_2G_HT20));
3465 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3466 AR5416_OPFLAGS_N_2G_HT40));
3467 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3468 AR5416_OPFLAGS_N_5G_HT20));
3469 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3470 AR5416_OPFLAGS_N_5G_HT40));
3471 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3472 PR_EEP("RF Silent", pBase->rfSilent);
3473 PR_EEP("BT option", pBase->blueToothOptions);
3474 PR_EEP("Device Cap", pBase->deviceCap);
3475 PR_EEP("Device Type", pBase->deviceType);
3476 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3477 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3478 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3479 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3480 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3481 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3482 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3483 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3484 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3485 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3486 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3487 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3488 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3489 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3490 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3491 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3492 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3493 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3494 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3496 len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3497 ah->eeprom.ar9300_eep.macAddr);
3505 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3506 u8 *buf, u32 len, u32 size)
3512 /* XXX: review hardware docs */
3513 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3515 return ah->eeprom.ar9300_eep.eepromVersion;
3518 /* XXX: could be read from the eepromVersion, not sure yet */
3519 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3524 static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
3527 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3530 return &eep->modalHeader2G;
3532 return &eep->modalHeader5G;
3535 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3537 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3539 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
3540 AR_SREV_9531(ah) || AR_SREV_9561(ah))
3541 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3542 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
3543 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3545 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3546 REG_RMW_FIELD(ah, AR_CH0_THERM,
3547 AR_CH0_THERM_XPABIASLVL_MSB,
3549 REG_RMW_FIELD(ah, AR_CH0_THERM,
3550 AR_CH0_THERM_XPASHORT2GND, 1);
3554 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3556 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3559 u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3561 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3564 u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3566 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3569 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3572 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3573 return le16_to_cpu(val);
3576 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3578 struct ath_common *common = ath9k_hw_common(ah);
3579 struct ath9k_hw_capabilities *pCap = &ah->caps;
3581 u32 regval, value, gpio;
3582 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3583 AR_PHY_SWITCH_CHAIN_0,
3584 AR_PHY_SWITCH_CHAIN_1,
3585 AR_PHY_SWITCH_CHAIN_2,
3588 if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0)) {
3589 if (ah->config.xlna_gpio)
3590 gpio = ah->config.xlna_gpio;
3592 gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
3594 ath9k_hw_cfg_output(ah, gpio,
3595 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
3598 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3600 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3601 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3602 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3603 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
3604 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3605 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3607 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3608 AR_SWITCH_TABLE_COM_ALL, value);
3612 * AR9462 defines new switch table for BT/WLAN,
3613 * here's new field name in XXX.ref for both 2G and 5G.
3614 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3615 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3616 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3618 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3619 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3621 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3622 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3624 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
3625 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3626 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3627 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3628 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3631 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3632 if (AR_SREV_9485(ah) && common->bt_ant_diversity) {
3633 value &= ~AR_SWITCH_TABLE_COM2_ALL;
3634 value |= ah->config.ant_ctrl_comm2g_switch_enable;
3637 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3639 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3640 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3641 REG_RMW_FIELD(ah, switch_chain_reg[0],
3642 AR_SWITCH_TABLE_ALL, value);
3645 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3646 if ((ah->rxchainmask & BIT(chain)) ||
3647 (ah->txchainmask & BIT(chain))) {
3648 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3650 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3651 AR_SWITCH_TABLE_ALL, value);
3655 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
3656 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3658 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3659 * are the fields present
3661 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3662 regval &= (~AR_ANT_DIV_CTRL_ALL);
3663 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3665 regval &= (~AR_PHY_ANT_DIV_LNADIV);
3666 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
3668 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3669 regval |= AR_ANT_DIV_ENABLE;
3671 if (AR_SREV_9565(ah)) {
3672 if (common->bt_ant_diversity) {
3673 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S);
3675 REG_SET_BIT(ah, AR_PHY_RESTART,
3676 AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
3678 /* Force WLAN LNA diversity ON */
3679 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
3680 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3682 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S);
3683 regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S);
3685 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL,
3686 (1 << AR_PHY_ANT_SW_RX_PROT_S));
3688 /* Force WLAN LNA diversity OFF */
3689 REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV,
3690 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3694 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3696 /* enable fast_div */
3697 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3698 regval &= (~AR_FAST_DIV_ENABLE);
3699 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
3701 if ((AR_SREV_9485(ah) || AR_SREV_9565(ah))
3702 && common->bt_ant_diversity)
3703 regval |= AR_FAST_DIV_ENABLE;
3705 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3707 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
3708 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3710 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3713 regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
3714 AR_PHY_ANT_DIV_ALT_LNACONF |
3715 AR_PHY_ANT_DIV_ALT_GAINTB |
3716 AR_PHY_ANT_DIV_MAIN_GAINTB));
3717 /* by default use LNA1 for the main antenna */
3718 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
3719 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
3720 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
3721 AR_PHY_ANT_DIV_ALT_LNACONF_S);
3722 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3727 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3729 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3730 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3734 drive_strength = pBase->miscConfiguration & BIT(0);
3735 if (!drive_strength)
3738 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3746 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3748 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3759 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3761 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3766 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3769 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3770 struct ath9k_channel *chan)
3774 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3776 if (chain >= 0 && chain < 3) {
3777 if (IS_CHAN_2GHZ(chan))
3778 return eep->modalHeader2G.xatten1DB[chain];
3779 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3780 t[0] = eep->base_ext2.xatten1DBLow[chain];
3782 t[1] = eep->modalHeader5G.xatten1DB[chain];
3784 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3786 value = ar9003_hw_power_interpolate((s32) chan->channel,
3790 return eep->modalHeader5G.xatten1DB[chain];
3797 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3798 struct ath9k_channel *chan)
3802 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3804 if (chain >= 0 && chain < 3) {
3805 if (IS_CHAN_2GHZ(chan))
3806 return eep->modalHeader2G.xatten1Margin[chain];
3807 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3808 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3810 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3812 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3814 value = ar9003_hw_power_interpolate((s32) chan->channel,
3818 return eep->modalHeader5G.xatten1Margin[chain];
3824 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3828 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3829 AR_PHY_EXT_ATTEN_CTL_1,
3830 AR_PHY_EXT_ATTEN_CTL_2,
3833 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3834 value = ar9003_hw_atten_chain_get(ah, 1, chan);
3835 REG_RMW_FIELD(ah, ext_atten_reg[0],
3836 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3838 value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
3839 REG_RMW_FIELD(ah, ext_atten_reg[0],
3840 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3844 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3845 for (i = 0; i < 3; i++) {
3846 if (ah->txchainmask & BIT(i)) {
3847 value = ar9003_hw_atten_chain_get(ah, i, chan);
3848 REG_RMW_FIELD(ah, ext_atten_reg[i],
3849 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3851 if (AR_SREV_9485(ah) &&
3852 (ar9003_hw_get_rx_gain_idx(ah) == 0) &&
3853 ah->config.xatten_margin_cfg)
3856 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3858 if (ah->config.alt_mingainidx)
3859 REG_RMW_FIELD(ah, AR_PHY_EXT_ATTEN_CTL_0,
3860 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3863 REG_RMW_FIELD(ah, ext_atten_reg[i],
3864 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3870 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3874 while (pmu_set != REG_READ(ah, pmu_reg)) {
3877 REG_WRITE(ah, pmu_reg, pmu_set);
3884 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3886 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3887 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3890 if (pBase->featureEnable & BIT(4)) {
3891 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3894 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3895 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3896 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3899 if (AR_SREV_9330(ah)) {
3900 if (ah->is_clk_25mhz) {
3901 reg_pmu_set = (3 << 1) | (8 << 4) |
3902 (3 << 8) | (1 << 14) |
3903 (6 << 17) | (1 << 20) |
3906 reg_pmu_set = (4 << 1) | (7 << 4) |
3907 (3 << 8) | (1 << 14) |
3908 (6 << 17) | (1 << 20) |
3912 reg_pmu_set = (5 << 1) | (7 << 4) |
3913 (2 << 8) | (2 << 14) |
3914 (6 << 17) | (1 << 20) |
3915 (3 << 24) | (1 << 28);
3918 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3919 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3922 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3924 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3925 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3928 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3930 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3931 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3933 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah) ||
3935 reg_val = le32_to_cpu(pBase->swreg);
3936 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3938 if (AR_SREV_9561(ah))
3939 REG_WRITE(ah, AR_PHY_PMU2, 0x10200000);
3941 /* Internal regulator is ON. Write swreg register. */
3942 reg_val = le32_to_cpu(pBase->swreg);
3943 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3944 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3945 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3946 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3947 /* Set REG_CONTROL1.SWREG_PROGRAM */
3948 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3950 AR_RTC_REG_CONTROL1) |
3951 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3954 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3955 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3956 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3960 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3961 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3964 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3965 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3968 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
3969 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3971 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3972 AR_RTC_FORCE_SWREG_PRD;
3973 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3979 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3981 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3982 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3984 if (AR_SREV_9340(ah) || AR_SREV_9531(ah))
3987 if (eep->baseEepHeader.featureEnable & 0x40) {
3988 tuning_caps_param &= 0x7f;
3989 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3991 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3996 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3998 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3999 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4001 s32 t[3], f[3] = {5180, 5500, 5785};
4003 if (!(pBase->miscConfiguration & BIT(4)))
4006 if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) {
4008 quick_drop = eep->modalHeader2G.quick_drop;
4010 t[0] = eep->base_ext1.quick_drop_low;
4011 t[1] = eep->modalHeader5G.quick_drop;
4012 t[2] = eep->base_ext1.quick_drop_high;
4013 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
4015 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
4019 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
4023 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
4025 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4026 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
4027 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4028 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
4031 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
4033 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4036 if (!(eep->baseEepHeader.featureEnable & 0x80))
4039 if (!AR_SREV_9300(ah) &&
4040 !AR_SREV_9340(ah) &&
4041 !AR_SREV_9580(ah) &&
4042 !AR_SREV_9531(ah) &&
4046 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
4048 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4049 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
4051 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4052 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
4055 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
4057 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4060 if (!(eep->baseEepHeader.miscConfiguration & 0x40))
4063 if (!AR_SREV_9300(ah))
4066 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
4067 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4070 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4073 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4077 static int ar9003_hw_get_thermometer(struct ath_hw *ah)
4079 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4080 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4081 int thermometer = (pBase->miscConfiguration >> 1) & 0x3;
4083 return --thermometer;
4086 static void ar9003_hw_thermometer_apply(struct ath_hw *ah)
4088 struct ath9k_hw_capabilities *pCap = &ah->caps;
4089 int thermometer = ar9003_hw_get_thermometer(ah);
4090 u8 therm_on = (thermometer < 0) ? 0 : 1;
4092 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4093 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4094 if (pCap->chip_chainmask & BIT(1))
4095 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4096 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4097 if (pCap->chip_chainmask & BIT(2))
4098 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4099 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4101 therm_on = (thermometer < 0) ? 0 : (thermometer == 0);
4102 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4103 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4104 if (pCap->chip_chainmask & BIT(1)) {
4105 therm_on = (thermometer < 0) ? 0 : (thermometer == 1);
4106 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4107 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4109 if (pCap->chip_chainmask & BIT(2)) {
4110 therm_on = (thermometer < 0) ? 0 : (thermometer == 2);
4111 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4112 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4116 static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4118 u32 data = 0, ko, kg;
4120 if (!AR_SREV_9462_20_OR_LATER(ah))
4123 ar9300_otp_read_word(ah, 1, &data);
4125 kg = (data >> 8) & 0xff;
4127 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4128 AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko);
4129 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4130 AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN,
4135 static void ar9003_hw_apply_minccapwr_thresh(struct ath_hw *ah,
4138 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4139 const u_int32_t cca_ctrl[AR9300_MAX_CHAINS] = {
4148 if (!(eep->base_ext1.misc_enable & BIT(2)))
4151 if (!(eep->base_ext1.misc_enable & BIT(3)))
4155 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
4156 if (!(ah->caps.tx_chainmask & BIT(chain)))
4159 val = ar9003_modal_header(ah, is2ghz)->noiseFloorThreshCh[chain];
4160 REG_RMW_FIELD(ah, cca_ctrl[chain],
4161 AR_PHY_EXT_CCA0_THRESH62_1, val);
4166 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4167 struct ath9k_channel *chan)
4169 bool is2ghz = IS_CHAN_2GHZ(chan);
4170 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
4171 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
4172 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
4173 ar9003_hw_drive_strength_apply(ah);
4174 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
4175 ar9003_hw_atten_apply(ah, chan);
4176 ar9003_hw_quick_drop_apply(ah, chan->channel);
4177 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah))
4178 ar9003_hw_internal_regulator_apply(ah);
4179 ar9003_hw_apply_tuning_caps(ah);
4180 ar9003_hw_apply_minccapwr_thresh(ah, is2ghz);
4181 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4182 ar9003_hw_thermometer_apply(ah);
4183 ar9003_hw_thermo_cal_apply(ah);
4186 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
4187 struct ath9k_channel *chan)
4192 * Returns the interpolated y value corresponding to the specified x value
4193 * from the np ordered pairs of data (px,py).
4194 * The pairs do not have to be in any order.
4195 * If the specified x value is less than any of the px,
4196 * the returned y value is equal to the py for the lowest px.
4197 * If the specified x value is greater than any of the px,
4198 * the returned y value is equal to the py for the highest px.
4200 static int ar9003_hw_power_interpolate(int32_t x,
4201 int32_t *px, int32_t *py, u_int16_t np)
4204 int lx = 0, ly = 0, lhave = 0;
4205 int hx = 0, hy = 0, hhave = 0;
4212 /* identify best lower and higher x calibration measurement */
4213 for (ip = 0; ip < np; ip++) {
4216 /* this measurement is higher than our desired x */
4218 if (!hhave || dx > (x - hx)) {
4219 /* new best higher x measurement */
4225 /* this measurement is lower than our desired x */
4227 if (!lhave || dx < (x - lx)) {
4228 /* new best lower x measurement */
4236 /* the low x is good */
4238 /* so is the high x */
4240 /* they're the same, so just pick one */
4243 else /* interpolate */
4244 y = interpolate(x, lx, hx, ly, hy);
4245 } else /* only low is good, use it */
4247 } else if (hhave) /* only high is good, use it */
4249 else /* nothing is good,this should never happen unless np=0, ???? */
4254 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4255 u16 rateIndex, u16 freq, bool is2GHz)
4258 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4259 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4260 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4261 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4265 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4266 pEepromTargetPwr = eep->calTargetPower2G;
4267 pFreqBin = eep->calTarget_freqbin_2G;
4269 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4270 pEepromTargetPwr = eep->calTargetPower5G;
4271 pFreqBin = eep->calTarget_freqbin_5G;
4275 * create array of channels and targetpower from
4276 * targetpower piers stored on eeprom
4278 for (i = 0; i < numPiers; i++) {
4279 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4280 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4283 /* interpolate to get target power for given frequency */
4284 return (u8) ar9003_hw_power_interpolate((s32) freq,
4286 targetPowerArray, numPiers);
4289 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4291 u16 freq, bool is2GHz)
4294 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4295 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4296 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4297 struct cal_tgt_pow_ht *pEepromTargetPwr;
4301 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4302 pEepromTargetPwr = eep->calTargetPower2GHT20;
4303 pFreqBin = eep->calTarget_freqbin_2GHT20;
4305 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4306 pEepromTargetPwr = eep->calTargetPower5GHT20;
4307 pFreqBin = eep->calTarget_freqbin_5GHT20;
4311 * create array of channels and targetpower
4312 * from targetpower piers stored on eeprom
4314 for (i = 0; i < numPiers; i++) {
4315 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4316 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4319 /* interpolate to get target power for given frequency */
4320 return (u8) ar9003_hw_power_interpolate((s32) freq,
4322 targetPowerArray, numPiers);
4325 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4327 u16 freq, bool is2GHz)
4330 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4331 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4332 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4333 struct cal_tgt_pow_ht *pEepromTargetPwr;
4337 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4338 pEepromTargetPwr = eep->calTargetPower2GHT40;
4339 pFreqBin = eep->calTarget_freqbin_2GHT40;
4341 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4342 pEepromTargetPwr = eep->calTargetPower5GHT40;
4343 pFreqBin = eep->calTarget_freqbin_5GHT40;
4347 * create array of channels and targetpower from
4348 * targetpower piers stored on eeprom
4350 for (i = 0; i < numPiers; i++) {
4351 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4352 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4355 /* interpolate to get target power for given frequency */
4356 return (u8) ar9003_hw_power_interpolate((s32) freq,
4358 targetPowerArray, numPiers);
4361 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4362 u16 rateIndex, u16 freq)
4364 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4365 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4366 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4367 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4368 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4369 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4372 * create array of channels and targetpower from
4373 * targetpower piers stored on eeprom
4375 for (i = 0; i < numPiers; i++) {
4376 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4377 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4380 /* interpolate to get target power for given frequency */
4381 return (u8) ar9003_hw_power_interpolate((s32) freq,
4383 targetPowerArray, numPiers);
4386 static void ar9003_hw_selfgen_tpc_txpower(struct ath_hw *ah,
4387 struct ath9k_channel *chan,
4392 /* target power values for self generated frames (ACK,RTS/CTS) */
4393 if (IS_CHAN_2GHZ(chan)) {
4394 val = SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_ACK) |
4395 SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_CTS) |
4396 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4398 val = SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_ACK) |
4399 SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_CTS) |
4400 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4402 REG_WRITE(ah, AR_TPC, val);
4405 /* Set tx power registers to array of values passed in */
4406 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4408 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4409 /* make sure forced gain is not set */
4410 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4412 /* Write the OFDM power per rate set */
4414 /* 6 (LSB), 9, 12, 18 (MSB) */
4415 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4416 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4417 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4418 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4419 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4421 /* 24 (LSB), 36, 48, 54 (MSB) */
4422 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4423 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4424 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4425 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4426 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4428 /* Write the CCK power per rate set */
4430 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4431 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4432 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4433 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4434 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4435 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4437 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4438 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4439 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4440 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4441 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4442 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4445 /* Write the power for duplicated frames - HT40 */
4447 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4448 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4449 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4450 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4451 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4452 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4455 /* Write the HT20 power per rate set */
4457 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4458 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4459 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4460 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4461 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4462 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4465 /* 6 (LSB), 7, 12, 13 (MSB) */
4466 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4467 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4468 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4469 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4470 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4473 /* 14 (LSB), 15, 20, 21 */
4474 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4475 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4476 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4477 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4478 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4481 /* Mixed HT20 and HT40 rates */
4483 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4484 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4485 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4486 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4487 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4488 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4492 * Write the HT40 power per rate set
4493 * correct PAR difference between HT40 and HT20/LEGACY
4494 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4496 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4497 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4498 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4499 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4500 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4503 /* 6 (LSB), 7, 12, 13 (MSB) */
4504 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4505 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4506 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4507 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4508 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4511 /* 14 (LSB), 15, 20, 21 */
4512 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4513 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4514 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4515 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4516 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4523 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4524 u8 *targetPowerValT2,
4527 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4528 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4530 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4531 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4533 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4534 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4536 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4537 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4541 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4542 u8 *targetPowerValT2)
4544 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4545 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4547 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4548 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4549 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4550 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4551 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4552 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4555 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4556 u8 *targetPowerValT2, bool is2GHz)
4558 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4559 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4561 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4562 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4564 targetPowerValT2[ALL_TARGET_HT20_4] =
4565 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4567 targetPowerValT2[ALL_TARGET_HT20_5] =
4568 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4570 targetPowerValT2[ALL_TARGET_HT20_6] =
4571 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4573 targetPowerValT2[ALL_TARGET_HT20_7] =
4574 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4576 targetPowerValT2[ALL_TARGET_HT20_12] =
4577 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4579 targetPowerValT2[ALL_TARGET_HT20_13] =
4580 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4582 targetPowerValT2[ALL_TARGET_HT20_14] =
4583 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4585 targetPowerValT2[ALL_TARGET_HT20_15] =
4586 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4588 targetPowerValT2[ALL_TARGET_HT20_20] =
4589 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4591 targetPowerValT2[ALL_TARGET_HT20_21] =
4592 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4594 targetPowerValT2[ALL_TARGET_HT20_22] =
4595 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4597 targetPowerValT2[ALL_TARGET_HT20_23] =
4598 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4602 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4604 u8 *targetPowerValT2,
4607 /* XXX: hard code for now, need to get from eeprom struct */
4608 u8 ht40PowerIncForPdadc = 0;
4610 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4611 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4612 is2GHz) + ht40PowerIncForPdadc;
4613 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4614 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4616 is2GHz) + ht40PowerIncForPdadc;
4617 targetPowerValT2[ALL_TARGET_HT40_4] =
4618 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4619 is2GHz) + ht40PowerIncForPdadc;
4620 targetPowerValT2[ALL_TARGET_HT40_5] =
4621 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4622 is2GHz) + ht40PowerIncForPdadc;
4623 targetPowerValT2[ALL_TARGET_HT40_6] =
4624 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4625 is2GHz) + ht40PowerIncForPdadc;
4626 targetPowerValT2[ALL_TARGET_HT40_7] =
4627 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4628 is2GHz) + ht40PowerIncForPdadc;
4629 targetPowerValT2[ALL_TARGET_HT40_12] =
4630 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4631 is2GHz) + ht40PowerIncForPdadc;
4632 targetPowerValT2[ALL_TARGET_HT40_13] =
4633 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4634 is2GHz) + ht40PowerIncForPdadc;
4635 targetPowerValT2[ALL_TARGET_HT40_14] =
4636 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4637 is2GHz) + ht40PowerIncForPdadc;
4638 targetPowerValT2[ALL_TARGET_HT40_15] =
4639 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4640 is2GHz) + ht40PowerIncForPdadc;
4641 targetPowerValT2[ALL_TARGET_HT40_20] =
4642 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4643 is2GHz) + ht40PowerIncForPdadc;
4644 targetPowerValT2[ALL_TARGET_HT40_21] =
4645 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4646 is2GHz) + ht40PowerIncForPdadc;
4647 targetPowerValT2[ALL_TARGET_HT40_22] =
4648 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4649 is2GHz) + ht40PowerIncForPdadc;
4650 targetPowerValT2[ALL_TARGET_HT40_23] =
4651 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4652 is2GHz) + ht40PowerIncForPdadc;
4655 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4656 struct ath9k_channel *chan,
4657 u8 *targetPowerValT2)
4659 bool is2GHz = IS_CHAN_2GHZ(chan);
4661 struct ath_common *common = ath9k_hw_common(ah);
4662 u16 freq = chan->channel;
4665 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4667 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4668 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4670 if (IS_CHAN_HT40(chan))
4671 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4674 for (i = 0; i < ar9300RateSize; i++) {
4675 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
4676 i, targetPowerValT2[i]);
4680 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4686 int *ptemperature, int *pvoltage)
4689 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4691 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4692 struct ath_common *common = ath9k_hw_common(ah);
4694 if (ichain >= AR9300_MAX_CHAINS) {
4695 ath_dbg(common, EEPROM,
4696 "Invalid chain index, must be less than %d\n",
4701 if (mode) { /* 5GHz */
4702 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4703 ath_dbg(common, EEPROM,
4704 "Invalid 5GHz cal pier index, must be less than %d\n",
4705 AR9300_NUM_5G_CAL_PIERS);
4708 pCalPier = &(eep->calFreqPier5G[ipier]);
4709 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4712 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4713 ath_dbg(common, EEPROM,
4714 "Invalid 2GHz cal pier index, must be less than %d\n",
4715 AR9300_NUM_2G_CAL_PIERS);
4719 pCalPier = &(eep->calFreqPier2G[ipier]);
4720 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4724 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4725 *pcorrection = pCalPierStruct->refPower;
4726 *ptemperature = pCalPierStruct->tempMeas;
4727 *pvoltage = pCalPierStruct->voltMeas;
4732 static void ar9003_hw_power_control_override(struct ath_hw *ah,
4735 int *voltage, int *temperature)
4737 int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
4738 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4739 int f[8], t[8], t1[3], t2[3], i;
4741 REG_RMW(ah, AR_PHY_TPC_11_B0,
4742 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4743 AR_PHY_TPC_OLPC_GAIN_DELTA);
4744 if (ah->caps.tx_chainmask & BIT(1))
4745 REG_RMW(ah, AR_PHY_TPC_11_B1,
4746 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4747 AR_PHY_TPC_OLPC_GAIN_DELTA);
4748 if (ah->caps.tx_chainmask & BIT(2))
4749 REG_RMW(ah, AR_PHY_TPC_11_B2,
4750 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4751 AR_PHY_TPC_OLPC_GAIN_DELTA);
4753 /* enable open loop power control on chip */
4754 REG_RMW(ah, AR_PHY_TPC_6_B0,
4755 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4756 AR_PHY_TPC_6_ERROR_EST_MODE);
4757 if (ah->caps.tx_chainmask & BIT(1))
4758 REG_RMW(ah, AR_PHY_TPC_6_B1,
4759 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4760 AR_PHY_TPC_6_ERROR_EST_MODE);
4761 if (ah->caps.tx_chainmask & BIT(2))
4762 REG_RMW(ah, AR_PHY_TPC_6_B2,
4763 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4764 AR_PHY_TPC_6_ERROR_EST_MODE);
4767 * enable temperature compensation
4768 * Need to use register names
4770 if (frequency < 4000) {
4771 temp_slope = eep->modalHeader2G.tempSlope;
4773 if (AR_SREV_9550(ah)) {
4774 t[0] = eep->base_ext1.tempslopextension[2];
4775 t1[0] = eep->base_ext1.tempslopextension[3];
4776 t2[0] = eep->base_ext1.tempslopextension[4];
4779 t[1] = eep->modalHeader5G.tempSlope;
4780 t1[1] = eep->base_ext1.tempslopextension[0];
4781 t2[1] = eep->base_ext1.tempslopextension[1];
4784 t[2] = eep->base_ext1.tempslopextension[5];
4785 t1[2] = eep->base_ext1.tempslopextension[6];
4786 t2[2] = eep->base_ext1.tempslopextension[7];
4789 temp_slope = ar9003_hw_power_interpolate(frequency,
4791 temp_slope1 = ar9003_hw_power_interpolate(frequency,
4793 temp_slope2 = ar9003_hw_power_interpolate(frequency,
4799 if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4800 for (i = 0; i < 8; i++) {
4801 t[i] = eep->base_ext1.tempslopextension[i];
4802 f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4804 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4806 } else if (eep->base_ext2.tempSlopeLow != 0) {
4807 t[0] = eep->base_ext2.tempSlopeLow;
4809 t[1] = eep->modalHeader5G.tempSlope;
4811 t[2] = eep->base_ext2.tempSlopeHigh;
4813 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4816 temp_slope = eep->modalHeader5G.tempSlope;
4821 if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
4822 u8 txmask = (eep->baseEepHeader.txrxMask & 0xf0) >> 4;
4825 * AR955x has tempSlope register for each chain.
4826 * Check whether temp_compensation feature is enabled or not.
4828 if (eep->baseEepHeader.featureEnable & 0x1) {
4829 if (frequency < 4000) {
4830 if (txmask & BIT(0))
4831 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4832 AR_PHY_TPC_19_ALPHA_THERM,
4833 eep->base_ext2.tempSlopeLow);
4834 if (txmask & BIT(1))
4835 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4836 AR_PHY_TPC_19_ALPHA_THERM,
4838 if (txmask & BIT(2))
4839 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4840 AR_PHY_TPC_19_ALPHA_THERM,
4841 eep->base_ext2.tempSlopeHigh);
4843 if (txmask & BIT(0))
4844 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4845 AR_PHY_TPC_19_ALPHA_THERM,
4847 if (txmask & BIT(1))
4848 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4849 AR_PHY_TPC_19_ALPHA_THERM,
4851 if (txmask & BIT(2))
4852 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4853 AR_PHY_TPC_19_ALPHA_THERM,
4858 * If temp compensation is not enabled,
4859 * set all registers to 0.
4861 if (txmask & BIT(0))
4862 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4863 AR_PHY_TPC_19_ALPHA_THERM, 0);
4864 if (txmask & BIT(1))
4865 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4866 AR_PHY_TPC_19_ALPHA_THERM, 0);
4867 if (txmask & BIT(2))
4868 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4869 AR_PHY_TPC_19_ALPHA_THERM, 0);
4872 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4873 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4876 if (AR_SREV_9462_20_OR_LATER(ah))
4877 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4878 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4881 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4885 /* Apply the recorded correction values. */
4886 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4888 int ichain, ipier, npier;
4890 int lfrequency[AR9300_MAX_CHAINS],
4891 lcorrection[AR9300_MAX_CHAINS],
4892 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4893 int hfrequency[AR9300_MAX_CHAINS],
4894 hcorrection[AR9300_MAX_CHAINS],
4895 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4897 int correction[AR9300_MAX_CHAINS],
4898 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4899 int pfrequency, pcorrection, ptemperature, pvoltage;
4900 struct ath_common *common = ath9k_hw_common(ah);
4902 mode = (frequency >= 4000);
4904 npier = AR9300_NUM_5G_CAL_PIERS;
4906 npier = AR9300_NUM_2G_CAL_PIERS;
4908 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4909 lfrequency[ichain] = 0;
4910 hfrequency[ichain] = 100000;
4912 /* identify best lower and higher frequency calibration measurement */
4913 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4914 for (ipier = 0; ipier < npier; ipier++) {
4915 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4916 &pfrequency, &pcorrection,
4917 &ptemperature, &pvoltage)) {
4918 fdiff = frequency - pfrequency;
4921 * this measurement is higher than
4922 * our desired frequency
4925 if (hfrequency[ichain] <= 0 ||
4926 hfrequency[ichain] >= 100000 ||
4928 (frequency - hfrequency[ichain])) {
4931 * frequency measurement
4933 hfrequency[ichain] = pfrequency;
4934 hcorrection[ichain] =
4936 htemperature[ichain] =
4938 hvoltage[ichain] = pvoltage;
4942 if (lfrequency[ichain] <= 0
4944 (frequency - lfrequency[ichain])) {
4947 * frequency measurement
4949 lfrequency[ichain] = pfrequency;
4950 lcorrection[ichain] =
4952 ltemperature[ichain] =
4954 lvoltage[ichain] = pvoltage;
4962 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4963 ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
4964 ichain, frequency, lfrequency[ichain],
4965 lcorrection[ichain], hfrequency[ichain],
4966 hcorrection[ichain]);
4967 /* they're the same, so just pick one */
4968 if (hfrequency[ichain] == lfrequency[ichain]) {
4969 correction[ichain] = lcorrection[ichain];
4970 voltage[ichain] = lvoltage[ichain];
4971 temperature[ichain] = ltemperature[ichain];
4973 /* the low frequency is good */
4974 else if (frequency - lfrequency[ichain] < 1000) {
4975 /* so is the high frequency, interpolate */
4976 if (hfrequency[ichain] - frequency < 1000) {
4978 correction[ichain] = interpolate(frequency,
4981 lcorrection[ichain],
4982 hcorrection[ichain]);
4984 temperature[ichain] = interpolate(frequency,
4987 ltemperature[ichain],
4988 htemperature[ichain]);
4990 voltage[ichain] = interpolate(frequency,
4996 /* only low is good, use it */
4998 correction[ichain] = lcorrection[ichain];
4999 temperature[ichain] = ltemperature[ichain];
5000 voltage[ichain] = lvoltage[ichain];
5003 /* only high is good, use it */
5004 else if (hfrequency[ichain] - frequency < 1000) {
5005 correction[ichain] = hcorrection[ichain];
5006 temperature[ichain] = htemperature[ichain];
5007 voltage[ichain] = hvoltage[ichain];
5008 } else { /* nothing is good, presume 0???? */
5009 correction[ichain] = 0;
5010 temperature[ichain] = 0;
5011 voltage[ichain] = 0;
5015 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
5018 ath_dbg(common, EEPROM,
5019 "for frequency=%d, calibration correction = %d %d %d\n",
5020 frequency, correction[0], correction[1], correction[2]);
5025 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
5030 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5031 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5034 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
5036 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
5039 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
5045 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5046 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5048 u8 *ctl_freqbin = is2GHz ?
5049 &eep->ctl_freqbin_2G[idx][0] :
5050 &eep->ctl_freqbin_5G[idx][0];
5053 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
5054 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
5055 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
5057 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
5058 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
5059 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
5062 return MAX_RATE_POWER;
5066 * Find the maximum conformance test limit for the given channel and CTL info
5068 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
5069 u16 freq, int idx, bool is2GHz)
5071 u16 twiceMaxEdgePower = MAX_RATE_POWER;
5072 u8 *ctl_freqbin = is2GHz ?
5073 &eep->ctl_freqbin_2G[idx][0] :
5074 &eep->ctl_freqbin_5G[idx][0];
5075 u16 num_edges = is2GHz ?
5076 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
5079 /* Get the edge power */
5081 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
5084 * If there's an exact channel match or an inband flag set
5085 * on the lower channel use the given rdEdgePower
5087 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
5089 ar9003_hw_get_direct_edge_power(eep, idx,
5092 } else if ((edge > 0) &&
5093 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
5096 ar9003_hw_get_indirect_edge_power(eep, idx,
5100 * Leave loop - no more affecting edges possible in
5101 * this monotonic increasing list
5107 if (is2GHz && !twiceMaxEdgePower)
5108 twiceMaxEdgePower = 60;
5110 return twiceMaxEdgePower;
5113 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
5114 struct ath9k_channel *chan,
5115 u8 *pPwrArray, u16 cfgCtl,
5116 u8 antenna_reduction,
5119 struct ath_common *common = ath9k_hw_common(ah);
5120 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
5121 u16 twiceMaxEdgePower;
5123 u16 scaledPower = 0, minCtlPower;
5124 static const u16 ctlModesFor11a[] = {
5125 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
5127 static const u16 ctlModesFor11g[] = {
5128 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
5129 CTL_11G_EXT, CTL_2GHT40
5132 const u16 *pCtlMode;
5134 struct chan_centers centers;
5137 u16 twiceMinEdgePower;
5138 bool is2ghz = IS_CHAN_2GHZ(chan);
5140 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5141 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
5145 /* Setup for CTL modes */
5146 /* CTL_11B, CTL_11G, CTL_2GHT20 */
5148 ARRAY_SIZE(ctlModesFor11g) -
5149 SUB_NUM_CTL_MODES_AT_2G_40;
5150 pCtlMode = ctlModesFor11g;
5151 if (IS_CHAN_HT40(chan))
5153 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
5155 /* Setup for CTL modes */
5156 /* CTL_11A, CTL_5GHT20 */
5157 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
5158 SUB_NUM_CTL_MODES_AT_5G_40;
5159 pCtlMode = ctlModesFor11a;
5160 if (IS_CHAN_HT40(chan))
5162 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
5166 * For MIMO, need to apply regulatory caps individually across
5167 * dynamically running modes: CCK, OFDM, HT20, HT40
5169 * The outer loop walks through each possible applicable runtime mode.
5170 * The inner loop walks through each ctlIndex entry in EEPROM.
5171 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
5173 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
5174 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
5175 (pCtlMode[ctlMode] == CTL_2GHT40);
5177 freq = centers.synth_center;
5178 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
5179 freq = centers.ext_center;
5181 freq = centers.ctl_center;
5183 ath_dbg(common, REGULATORY,
5184 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
5185 ctlMode, numCtlModes, isHt40CtlMode,
5186 (pCtlMode[ctlMode] & EXT_ADDITIVE));
5188 /* walk through each CTL index stored in EEPROM */
5190 ctlIndex = pEepData->ctlIndex_2G;
5191 ctlNum = AR9300_NUM_CTLS_2G;
5193 ctlIndex = pEepData->ctlIndex_5G;
5194 ctlNum = AR9300_NUM_CTLS_5G;
5197 twiceMaxEdgePower = MAX_RATE_POWER;
5198 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
5199 ath_dbg(common, REGULATORY,
5200 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
5201 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
5205 * compare test group from regulatory
5206 * channel list with test mode from pCtlMode
5209 if ((((cfgCtl & ~CTL_MODE_M) |
5210 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5212 (((cfgCtl & ~CTL_MODE_M) |
5213 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5214 ((ctlIndex[i] & CTL_MODE_M) |
5217 ar9003_hw_get_max_edge_power(pEepData,
5221 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
5223 * Find the minimum of all CTL
5224 * edge powers that apply to
5228 min(twiceMaxEdgePower,
5232 twiceMaxEdgePower = twiceMinEdgePower;
5238 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
5240 ath_dbg(common, REGULATORY,
5241 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
5242 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
5243 scaledPower, minCtlPower);
5245 /* Apply ctl mode to correct target power set */
5246 switch (pCtlMode[ctlMode]) {
5248 for (i = ALL_TARGET_LEGACY_1L_5L;
5249 i <= ALL_TARGET_LEGACY_11S; i++)
5250 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5255 for (i = ALL_TARGET_LEGACY_6_24;
5256 i <= ALL_TARGET_LEGACY_54; i++)
5257 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5262 for (i = ALL_TARGET_HT20_0_8_16;
5263 i <= ALL_TARGET_HT20_23; i++) {
5264 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5266 if (ath9k_hw_mci_is_enabled(ah))
5268 (u8)min((u16)pPwrArray[i],
5269 ar9003_mci_get_max_txpower(ah,
5270 pCtlMode[ctlMode]));
5275 for (i = ALL_TARGET_HT40_0_8_16;
5276 i <= ALL_TARGET_HT40_23; i++) {
5277 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5279 if (ath9k_hw_mci_is_enabled(ah))
5281 (u8)min((u16)pPwrArray[i],
5282 ar9003_mci_get_max_txpower(ah,
5283 pCtlMode[ctlMode]));
5289 } /* end ctl mode checking */
5292 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5294 u8 mod_idx = mcs_idx % 8;
5297 return mod_idx ? (base_pwridx + 1) : base_pwridx;
5299 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5302 static void ar9003_paprd_set_txpower(struct ath_hw *ah,
5303 struct ath9k_channel *chan,
5304 u8 *targetPowerValT2)
5308 if (!ar9003_is_paprd_enabled(ah))
5311 if (IS_CHAN_HT40(chan))
5312 i = ALL_TARGET_HT40_7;
5314 i = ALL_TARGET_HT20_7;
5316 if (IS_CHAN_2GHZ(chan)) {
5317 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) &&
5318 !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) {
5319 if (IS_CHAN_HT40(chan))
5320 i = ALL_TARGET_HT40_0_8_16;
5322 i = ALL_TARGET_HT20_0_8_16;
5326 ah->paprd_target_power = targetPowerValT2[i];
5329 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5330 struct ath9k_channel *chan, u16 cfgCtl,
5331 u8 twiceAntennaReduction,
5332 u8 powerLimit, bool test)
5334 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5335 struct ath_common *common = ath9k_hw_common(ah);
5336 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5337 struct ar9300_modal_eep_header *modal_hdr;
5338 u8 targetPowerValT2[ar9300RateSize];
5339 u8 target_power_val_t2_eep[ar9300RateSize];
5340 u8 targetPowerValT2_tpc[ar9300RateSize];
5341 unsigned int i = 0, paprd_scale_factor = 0;
5342 u8 pwr_idx, min_pwridx = 0;
5344 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5347 * Get target powers from EEPROM - our baseline for TX Power
5349 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5351 if (ar9003_is_paprd_enabled(ah)) {
5352 if (IS_CHAN_2GHZ(chan))
5353 modal_hdr = &eep->modalHeader2G;
5355 modal_hdr = &eep->modalHeader5G;
5357 ah->paprd_ratemask =
5358 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5359 AR9300_PAPRD_RATE_MASK;
5361 ah->paprd_ratemask_ht40 =
5362 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5363 AR9300_PAPRD_RATE_MASK;
5365 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5366 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5367 ALL_TARGET_HT20_0_8_16;
5369 if (!ah->paprd_table_write_done) {
5370 memcpy(target_power_val_t2_eep, targetPowerValT2,
5371 sizeof(targetPowerValT2));
5372 for (i = 0; i < 24; i++) {
5373 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5374 if (ah->paprd_ratemask & (1 << i)) {
5375 if (targetPowerValT2[pwr_idx] &&
5376 targetPowerValT2[pwr_idx] ==
5377 target_power_val_t2_eep[pwr_idx])
5378 targetPowerValT2[pwr_idx] -=
5383 memcpy(target_power_val_t2_eep, targetPowerValT2,
5384 sizeof(targetPowerValT2));
5387 ar9003_hw_set_power_per_rate_table(ah, chan,
5388 targetPowerValT2, cfgCtl,
5389 twiceAntennaReduction,
5392 memcpy(targetPowerValT2_tpc, targetPowerValT2,
5393 sizeof(targetPowerValT2));
5395 if (ar9003_is_paprd_enabled(ah)) {
5396 for (i = 0; i < ar9300RateSize; i++) {
5397 if ((ah->paprd_ratemask & (1 << i)) &&
5398 (abs(targetPowerValT2[i] -
5399 target_power_val_t2_eep[i]) >
5400 paprd_scale_factor)) {
5401 ah->paprd_ratemask &= ~(1 << i);
5402 ath_dbg(common, EEPROM,
5403 "paprd disabled for mcs %d\n", i);
5408 regulatory->max_power_level = 0;
5409 for (i = 0; i < ar9300RateSize; i++) {
5410 if (targetPowerValT2[i] > regulatory->max_power_level)
5411 regulatory->max_power_level = targetPowerValT2[i];
5414 ath9k_hw_update_regulatory_maxpower(ah);
5419 for (i = 0; i < ar9300RateSize; i++) {
5420 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
5421 i, targetPowerValT2[i]);
5424 /* Write target power array to registers */
5425 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5426 ar9003_hw_calibration_apply(ah, chan->channel);
5427 ar9003_paprd_set_txpower(ah, chan, targetPowerValT2);
5429 ar9003_hw_selfgen_tpc_txpower(ah, chan, targetPowerValT2);
5431 /* TPC initializations */
5432 if (ah->tpc_enabled) {
5435 ar9003_hw_init_rate_txpower(ah, targetPowerValT2_tpc, chan);
5438 REG_WRITE(ah, AR_PHY_PWRTX_MAX,
5439 AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
5440 /* Disable per chain power reduction */
5441 val = REG_READ(ah, AR_PHY_POWER_TX_SUB);
5442 if (AR_SREV_9340(ah))
5443 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5446 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5450 REG_WRITE(ah, AR_PHY_PWRTX_MAX, 0);
5454 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5460 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5462 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5464 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5467 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5469 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5471 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5474 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5476 return ar9003_modal_header(ah, is2ghz)->spurChans;
5479 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5480 struct ath9k_channel *chan)
5482 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5484 if (IS_CHAN_2GHZ(chan))
5485 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5486 AR9300_PAPRD_SCALE_1);
5488 if (chan->channel >= 5700)
5489 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5490 AR9300_PAPRD_SCALE_1);
5491 else if (chan->channel >= 5400)
5492 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5493 AR9300_PAPRD_SCALE_2);
5495 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5496 AR9300_PAPRD_SCALE_1);
5500 const struct eeprom_ops eep_ar9300_ops = {
5501 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5502 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5503 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5504 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5505 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5506 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5507 .set_board_values = ath9k_hw_ar9300_set_board_values,
5508 .set_addac = ath9k_hw_ar9300_set_addac,
5509 .set_txpower = ath9k_hw_ar9300_set_txpower,
5510 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel