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) {
3206 eep = ar9003_eeprom_struct_find_by_id(reference);
3208 ath_dbg(common, EEPROM,
3209 "can't find reference eeprom struct %d\n",
3213 memcpy(mptr, eep, mdata_size);
3215 ath_dbg(common, EEPROM,
3216 "restore eeprom %d: block, reference %d, length %d\n",
3217 it, reference, length);
3218 ar9300_uncompress_block(ah, mptr, mdata_size,
3219 (word + COMP_HDR_LEN), length);
3222 ath_dbg(common, EEPROM, "unknown compression code %d\n", code);
3228 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3231 static bool ar9300_check_header(void *data)
3234 return !(*word == 0 || *word == ~0);
3237 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3242 if (!read(ah, base_addr, header, 4))
3245 return ar9300_check_header(header);
3248 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3251 u16 *data = (u16 *) mptr;
3254 for (i = 0; i < mdata_size / 2; i++, data++)
3255 if (!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 if (ar9300_eeprom_restore_flash(ah, mptr, mdata_size))
3289 /* check if eeprom contains valid data */
3290 eep = (struct ar9300_eeprom *) mptr;
3291 txrx = eep->baseEepHeader.txrxMask;
3292 if (txrx != 0 && txrx != 0xff)
3296 word = kzalloc(2048, GFP_KERNEL);
3300 memcpy(mptr, &ar9300_default, mdata_size);
3302 read = ar9300_read_eeprom;
3303 if (AR_SREV_9485(ah))
3304 cptr = AR9300_BASE_ADDR_4K;
3305 else if (AR_SREV_9330(ah))
3306 cptr = AR9300_BASE_ADDR_512;
3308 cptr = AR9300_BASE_ADDR;
3309 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3311 if (ar9300_check_eeprom_header(ah, read, cptr))
3314 cptr = AR9300_BASE_ADDR_512;
3315 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3317 if (ar9300_check_eeprom_header(ah, read, cptr))
3320 read = ar9300_read_otp;
3321 cptr = AR9300_BASE_ADDR;
3322 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3323 if (ar9300_check_eeprom_header(ah, read, cptr))
3326 cptr = AR9300_BASE_ADDR_512;
3327 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3328 if (ar9300_check_eeprom_header(ah, read, cptr))
3334 ath_dbg(common, EEPROM, "Found valid EEPROM data\n");
3336 for (it = 0; it < MSTATE; it++) {
3337 if (!read(ah, cptr, word, COMP_HDR_LEN))
3340 if (!ar9300_check_header(word))
3343 ar9300_comp_hdr_unpack(word, &code, &reference,
3344 &length, &major, &minor);
3345 ath_dbg(common, EEPROM,
3346 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3347 cptr, code, reference, length, major, minor);
3348 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3349 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485) ||
3351 ath_dbg(common, EEPROM, "Skipping bad header\n");
3352 cptr -= COMP_HDR_LEN;
3357 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3358 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3359 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3360 ath_dbg(common, EEPROM, "checksum %x %x\n",
3361 checksum, mchecksum);
3362 if (checksum == mchecksum) {
3363 ar9300_compress_decision(ah, it, code, reference, mptr,
3364 word, length, mdata_size);
3366 ath_dbg(common, EEPROM,
3367 "skipping block with bad checksum\n");
3369 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3381 * Restore the configuration structure by reading the eeprom.
3382 * This function destroys any existing in-memory structure
3385 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3387 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3389 if (ar9300_eeprom_restore_internal(ah, mptr,
3390 sizeof(struct ar9300_eeprom)) < 0)
3396 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3397 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3398 struct ar9300_modal_eep_header *modal_hdr)
3400 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3401 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3402 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3403 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3404 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3405 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3406 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3407 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3408 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3409 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3410 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3411 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3412 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3413 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3414 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3415 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3416 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3417 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3418 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3419 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3420 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3421 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3422 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3423 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3424 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3425 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3426 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3427 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3428 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3429 PR_EEP("txClip", modal_hdr->txClip);
3430 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3435 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3436 u8 *buf, u32 len, u32 size)
3438 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3439 struct ar9300_base_eep_hdr *pBase;
3441 if (!dump_base_hdr) {
3442 len += scnprintf(buf + len, size - len,
3443 "%20s :\n", "2GHz modal Header");
3444 len = ar9003_dump_modal_eeprom(buf, len, size,
3445 &eep->modalHeader2G);
3446 len += scnprintf(buf + len, size - len,
3447 "%20s :\n", "5GHz modal Header");
3448 len = ar9003_dump_modal_eeprom(buf, len, size,
3449 &eep->modalHeader5G);
3453 pBase = &eep->baseEepHeader;
3455 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3456 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3457 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3458 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3459 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3460 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3461 AR5416_OPFLAGS_11A));
3462 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3463 AR5416_OPFLAGS_11G));
3464 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3465 AR5416_OPFLAGS_N_2G_HT20));
3466 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3467 AR5416_OPFLAGS_N_2G_HT40));
3468 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3469 AR5416_OPFLAGS_N_5G_HT20));
3470 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3471 AR5416_OPFLAGS_N_5G_HT40));
3472 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3473 PR_EEP("RF Silent", pBase->rfSilent);
3474 PR_EEP("BT option", pBase->blueToothOptions);
3475 PR_EEP("Device Cap", pBase->deviceCap);
3476 PR_EEP("Device Type", pBase->deviceType);
3477 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3478 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3479 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3480 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3481 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3482 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3483 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3484 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3485 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3486 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3487 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3488 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3489 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3490 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3491 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3492 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3493 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3494 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3495 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3497 len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3498 ah->eeprom.ar9300_eep.macAddr);
3506 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3507 u8 *buf, u32 len, u32 size)
3513 /* XXX: review hardware docs */
3514 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3516 return ah->eeprom.ar9300_eep.eepromVersion;
3519 /* XXX: could be read from the eepromVersion, not sure yet */
3520 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3525 static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
3528 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3531 return &eep->modalHeader2G;
3533 return &eep->modalHeader5G;
3536 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3538 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3540 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
3541 AR_SREV_9531(ah) || AR_SREV_9561(ah))
3542 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3543 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
3544 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3546 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3547 REG_RMW_FIELD(ah, AR_CH0_THERM,
3548 AR_CH0_THERM_XPABIASLVL_MSB,
3550 REG_RMW_FIELD(ah, AR_CH0_THERM,
3551 AR_CH0_THERM_XPASHORT2GND, 1);
3555 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3557 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3560 u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3562 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3565 u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3567 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3570 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3573 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3574 return le16_to_cpu(val);
3577 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3579 struct ath_common *common = ath9k_hw_common(ah);
3580 struct ath9k_hw_capabilities *pCap = &ah->caps;
3582 u32 regval, value, gpio;
3583 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3584 AR_PHY_SWITCH_CHAIN_0,
3585 AR_PHY_SWITCH_CHAIN_1,
3586 AR_PHY_SWITCH_CHAIN_2,
3589 if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0)) {
3590 if (ah->config.xlna_gpio)
3591 gpio = ah->config.xlna_gpio;
3593 gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
3595 ath9k_hw_gpio_request_out(ah, gpio, NULL,
3596 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
3599 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3601 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3602 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3603 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3604 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
3605 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3606 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3608 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3609 AR_SWITCH_TABLE_COM_ALL, value);
3613 * AR9462 defines new switch table for BT/WLAN,
3614 * here's new field name in XXX.ref for both 2G and 5G.
3615 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3616 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3617 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3619 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3620 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3622 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3623 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3625 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
3626 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3627 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3628 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3629 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3632 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3633 if (AR_SREV_9485(ah) && common->bt_ant_diversity) {
3634 value &= ~AR_SWITCH_TABLE_COM2_ALL;
3635 value |= ah->config.ant_ctrl_comm2g_switch_enable;
3638 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3640 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3641 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3642 REG_RMW_FIELD(ah, switch_chain_reg[0],
3643 AR_SWITCH_TABLE_ALL, value);
3646 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3647 if ((ah->rxchainmask & BIT(chain)) ||
3648 (ah->txchainmask & BIT(chain))) {
3649 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3651 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3652 AR_SWITCH_TABLE_ALL, value);
3656 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
3657 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3659 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3660 * are the fields present
3662 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3663 regval &= (~AR_ANT_DIV_CTRL_ALL);
3664 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3666 regval &= (~AR_PHY_ANT_DIV_LNADIV);
3667 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
3669 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3670 regval |= AR_ANT_DIV_ENABLE;
3672 if (AR_SREV_9565(ah)) {
3673 if (common->bt_ant_diversity) {
3674 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S);
3676 REG_SET_BIT(ah, AR_PHY_RESTART,
3677 AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
3679 /* Force WLAN LNA diversity ON */
3680 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
3681 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3683 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S);
3684 regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S);
3686 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL,
3687 (1 << AR_PHY_ANT_SW_RX_PROT_S));
3689 /* Force WLAN LNA diversity OFF */
3690 REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV,
3691 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3695 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3697 /* enable fast_div */
3698 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3699 regval &= (~AR_FAST_DIV_ENABLE);
3700 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
3702 if ((AR_SREV_9485(ah) || AR_SREV_9565(ah))
3703 && common->bt_ant_diversity)
3704 regval |= AR_FAST_DIV_ENABLE;
3706 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3708 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
3709 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3711 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3714 regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
3715 AR_PHY_ANT_DIV_ALT_LNACONF |
3716 AR_PHY_ANT_DIV_ALT_GAINTB |
3717 AR_PHY_ANT_DIV_MAIN_GAINTB));
3718 /* by default use LNA1 for the main antenna */
3719 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
3720 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
3721 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
3722 AR_PHY_ANT_DIV_ALT_LNACONF_S);
3723 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3728 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3730 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3731 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3735 drive_strength = pBase->miscConfiguration & BIT(0);
3736 if (!drive_strength)
3739 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3747 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3749 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3760 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3762 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3767 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3770 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3771 struct ath9k_channel *chan)
3775 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3777 if (chain >= 0 && chain < 3) {
3778 if (IS_CHAN_2GHZ(chan))
3779 return eep->modalHeader2G.xatten1DB[chain];
3780 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3781 t[0] = eep->base_ext2.xatten1DBLow[chain];
3783 t[1] = eep->modalHeader5G.xatten1DB[chain];
3785 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3787 value = ar9003_hw_power_interpolate((s32) chan->channel,
3791 return eep->modalHeader5G.xatten1DB[chain];
3798 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3799 struct ath9k_channel *chan)
3803 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3805 if (chain >= 0 && chain < 3) {
3806 if (IS_CHAN_2GHZ(chan))
3807 return eep->modalHeader2G.xatten1Margin[chain];
3808 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3809 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3811 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3813 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3815 value = ar9003_hw_power_interpolate((s32) chan->channel,
3819 return eep->modalHeader5G.xatten1Margin[chain];
3825 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3829 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3830 AR_PHY_EXT_ATTEN_CTL_1,
3831 AR_PHY_EXT_ATTEN_CTL_2,
3834 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3835 value = ar9003_hw_atten_chain_get(ah, 1, chan);
3836 REG_RMW_FIELD(ah, ext_atten_reg[0],
3837 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3839 value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
3840 REG_RMW_FIELD(ah, ext_atten_reg[0],
3841 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3845 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3846 for (i = 0; i < 3; i++) {
3847 if (ah->txchainmask & BIT(i)) {
3848 value = ar9003_hw_atten_chain_get(ah, i, chan);
3849 REG_RMW_FIELD(ah, ext_atten_reg[i],
3850 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3852 if (AR_SREV_9485(ah) &&
3853 (ar9003_hw_get_rx_gain_idx(ah) == 0) &&
3854 ah->config.xatten_margin_cfg)
3857 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3859 if (ah->config.alt_mingainidx)
3860 REG_RMW_FIELD(ah, AR_PHY_EXT_ATTEN_CTL_0,
3861 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3864 REG_RMW_FIELD(ah, ext_atten_reg[i],
3865 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3871 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3875 while (pmu_set != REG_READ(ah, pmu_reg)) {
3878 REG_WRITE(ah, pmu_reg, pmu_set);
3885 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3887 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3888 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3891 if (pBase->featureEnable & BIT(4)) {
3892 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3895 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3896 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3897 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3900 if (AR_SREV_9330(ah)) {
3901 if (ah->is_clk_25mhz) {
3902 reg_pmu_set = (3 << 1) | (8 << 4) |
3903 (3 << 8) | (1 << 14) |
3904 (6 << 17) | (1 << 20) |
3907 reg_pmu_set = (4 << 1) | (7 << 4) |
3908 (3 << 8) | (1 << 14) |
3909 (6 << 17) | (1 << 20) |
3913 reg_pmu_set = (5 << 1) | (7 << 4) |
3914 (2 << 8) | (2 << 14) |
3915 (6 << 17) | (1 << 20) |
3916 (3 << 24) | (1 << 28);
3919 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3920 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3923 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3925 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3926 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3929 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3931 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3932 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3934 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah) ||
3936 reg_val = le32_to_cpu(pBase->swreg);
3937 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3939 if (AR_SREV_9561(ah))
3940 REG_WRITE(ah, AR_PHY_PMU2, 0x10200000);
3942 /* Internal regulator is ON. Write swreg register. */
3943 reg_val = le32_to_cpu(pBase->swreg);
3944 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3945 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3946 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3947 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3948 /* Set REG_CONTROL1.SWREG_PROGRAM */
3949 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3951 AR_RTC_REG_CONTROL1) |
3952 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3955 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3956 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3957 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3961 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3962 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3965 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3966 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3969 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
3970 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3972 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3973 AR_RTC_FORCE_SWREG_PRD;
3974 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3980 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3982 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3983 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3985 if (AR_SREV_9340(ah) || AR_SREV_9531(ah))
3988 if (eep->baseEepHeader.featureEnable & 0x40) {
3989 tuning_caps_param &= 0x7f;
3990 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3992 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3997 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3999 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4000 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4002 s32 t[3], f[3] = {5180, 5500, 5785};
4004 if (!(pBase->miscConfiguration & BIT(4)))
4007 if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) {
4009 quick_drop = eep->modalHeader2G.quick_drop;
4011 t[0] = eep->base_ext1.quick_drop_low;
4012 t[1] = eep->modalHeader5G.quick_drop;
4013 t[2] = eep->base_ext1.quick_drop_high;
4014 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
4016 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
4020 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
4024 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
4026 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4027 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
4028 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4029 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
4032 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
4034 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4037 if (!(eep->baseEepHeader.featureEnable & 0x80))
4040 if (!AR_SREV_9300(ah) &&
4041 !AR_SREV_9340(ah) &&
4042 !AR_SREV_9580(ah) &&
4043 !AR_SREV_9531(ah) &&
4047 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
4049 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4050 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
4052 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4053 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
4056 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
4058 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4061 if (!(eep->baseEepHeader.miscConfiguration & 0x40))
4064 if (!AR_SREV_9300(ah))
4067 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
4068 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4071 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4074 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4078 static int ar9003_hw_get_thermometer(struct ath_hw *ah)
4080 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4081 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4082 int thermometer = (pBase->miscConfiguration >> 1) & 0x3;
4084 return --thermometer;
4087 static void ar9003_hw_thermometer_apply(struct ath_hw *ah)
4089 struct ath9k_hw_capabilities *pCap = &ah->caps;
4090 int thermometer = ar9003_hw_get_thermometer(ah);
4091 u8 therm_on = (thermometer < 0) ? 0 : 1;
4093 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4094 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4095 if (pCap->chip_chainmask & BIT(1))
4096 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4097 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4098 if (pCap->chip_chainmask & BIT(2))
4099 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4100 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4102 therm_on = thermometer == 0;
4103 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4104 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4105 if (pCap->chip_chainmask & BIT(1)) {
4106 therm_on = thermometer == 1;
4107 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4108 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4110 if (pCap->chip_chainmask & BIT(2)) {
4111 therm_on = thermometer == 2;
4112 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4113 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4117 static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4119 u32 data = 0, ko, kg;
4121 if (!AR_SREV_9462_20_OR_LATER(ah))
4124 ar9300_otp_read_word(ah, 1, &data);
4126 kg = (data >> 8) & 0xff;
4128 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4129 AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko);
4130 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4131 AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN,
4136 static void ar9003_hw_apply_minccapwr_thresh(struct ath_hw *ah,
4139 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4140 const u_int32_t cca_ctrl[AR9300_MAX_CHAINS] = {
4149 if (!(eep->base_ext1.misc_enable & BIT(2)))
4152 if (!(eep->base_ext1.misc_enable & BIT(3)))
4156 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
4157 if (!(ah->caps.tx_chainmask & BIT(chain)))
4160 val = ar9003_modal_header(ah, is2ghz)->noiseFloorThreshCh[chain];
4161 REG_RMW_FIELD(ah, cca_ctrl[chain],
4162 AR_PHY_EXT_CCA0_THRESH62_1, val);
4167 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4168 struct ath9k_channel *chan)
4170 bool is2ghz = IS_CHAN_2GHZ(chan);
4171 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
4172 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
4173 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
4174 ar9003_hw_drive_strength_apply(ah);
4175 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
4176 ar9003_hw_atten_apply(ah, chan);
4177 ar9003_hw_quick_drop_apply(ah, chan->channel);
4178 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah))
4179 ar9003_hw_internal_regulator_apply(ah);
4180 ar9003_hw_apply_tuning_caps(ah);
4181 ar9003_hw_apply_minccapwr_thresh(ah, is2ghz);
4182 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4183 ar9003_hw_thermometer_apply(ah);
4184 ar9003_hw_thermo_cal_apply(ah);
4187 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
4188 struct ath9k_channel *chan)
4193 * Returns the interpolated y value corresponding to the specified x value
4194 * from the np ordered pairs of data (px,py).
4195 * The pairs do not have to be in any order.
4196 * If the specified x value is less than any of the px,
4197 * the returned y value is equal to the py for the lowest px.
4198 * If the specified x value is greater than any of the px,
4199 * the returned y value is equal to the py for the highest px.
4201 static int ar9003_hw_power_interpolate(int32_t x,
4202 int32_t *px, int32_t *py, u_int16_t np)
4205 int lx = 0, ly = 0, lhave = 0;
4206 int hx = 0, hy = 0, hhave = 0;
4213 /* identify best lower and higher x calibration measurement */
4214 for (ip = 0; ip < np; ip++) {
4217 /* this measurement is higher than our desired x */
4219 if (!hhave || dx > (x - hx)) {
4220 /* new best higher x measurement */
4226 /* this measurement is lower than our desired x */
4228 if (!lhave || dx < (x - lx)) {
4229 /* new best lower x measurement */
4237 /* the low x is good */
4239 /* so is the high x */
4241 /* they're the same, so just pick one */
4244 else /* interpolate */
4245 y = interpolate(x, lx, hx, ly, hy);
4246 } else /* only low is good, use it */
4248 } else if (hhave) /* only high is good, use it */
4250 else /* nothing is good,this should never happen unless np=0, ???? */
4255 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4256 u16 rateIndex, u16 freq, bool is2GHz)
4259 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4260 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4261 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4262 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4266 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4267 pEepromTargetPwr = eep->calTargetPower2G;
4268 pFreqBin = eep->calTarget_freqbin_2G;
4270 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4271 pEepromTargetPwr = eep->calTargetPower5G;
4272 pFreqBin = eep->calTarget_freqbin_5G;
4276 * create array of channels and targetpower from
4277 * targetpower piers stored on eeprom
4279 for (i = 0; i < numPiers; i++) {
4280 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4281 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4284 /* interpolate to get target power for given frequency */
4285 return (u8) ar9003_hw_power_interpolate((s32) freq,
4287 targetPowerArray, numPiers);
4290 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4292 u16 freq, bool is2GHz)
4295 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4296 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4297 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4298 struct cal_tgt_pow_ht *pEepromTargetPwr;
4302 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4303 pEepromTargetPwr = eep->calTargetPower2GHT20;
4304 pFreqBin = eep->calTarget_freqbin_2GHT20;
4306 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4307 pEepromTargetPwr = eep->calTargetPower5GHT20;
4308 pFreqBin = eep->calTarget_freqbin_5GHT20;
4312 * create array of channels and targetpower
4313 * from targetpower piers stored on eeprom
4315 for (i = 0; i < numPiers; i++) {
4316 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4317 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4320 /* interpolate to get target power for given frequency */
4321 return (u8) ar9003_hw_power_interpolate((s32) freq,
4323 targetPowerArray, numPiers);
4326 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4328 u16 freq, bool is2GHz)
4331 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4332 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4333 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4334 struct cal_tgt_pow_ht *pEepromTargetPwr;
4338 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4339 pEepromTargetPwr = eep->calTargetPower2GHT40;
4340 pFreqBin = eep->calTarget_freqbin_2GHT40;
4342 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4343 pEepromTargetPwr = eep->calTargetPower5GHT40;
4344 pFreqBin = eep->calTarget_freqbin_5GHT40;
4348 * create array of channels and targetpower from
4349 * targetpower piers stored on eeprom
4351 for (i = 0; i < numPiers; i++) {
4352 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4353 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4356 /* interpolate to get target power for given frequency */
4357 return (u8) ar9003_hw_power_interpolate((s32) freq,
4359 targetPowerArray, numPiers);
4362 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4363 u16 rateIndex, u16 freq)
4365 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4366 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4367 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4368 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4369 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4370 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4373 * create array of channels and targetpower from
4374 * targetpower piers stored on eeprom
4376 for (i = 0; i < numPiers; i++) {
4377 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4378 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4381 /* interpolate to get target power for given frequency */
4382 return (u8) ar9003_hw_power_interpolate((s32) freq,
4384 targetPowerArray, numPiers);
4387 static void ar9003_hw_selfgen_tpc_txpower(struct ath_hw *ah,
4388 struct ath9k_channel *chan,
4393 /* target power values for self generated frames (ACK,RTS/CTS) */
4394 if (IS_CHAN_2GHZ(chan)) {
4395 val = SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_ACK) |
4396 SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_CTS) |
4397 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4399 val = SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_ACK) |
4400 SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_CTS) |
4401 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4403 REG_WRITE(ah, AR_TPC, val);
4406 /* Set tx power registers to array of values passed in */
4407 int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4409 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4410 /* make sure forced gain is not set */
4411 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4413 /* Write the OFDM power per rate set */
4415 /* 6 (LSB), 9, 12, 18 (MSB) */
4416 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4417 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4418 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4419 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4420 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4422 /* 24 (LSB), 36, 48, 54 (MSB) */
4423 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4424 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4425 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4426 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4427 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4429 /* Write the CCK power per rate set */
4431 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4432 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4433 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4434 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4435 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4436 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4438 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4439 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4440 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4441 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4442 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4443 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4446 /* Write the power for duplicated frames - HT40 */
4448 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4449 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4450 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4451 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4452 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4453 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4456 /* Write the HT20 power per rate set */
4458 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4459 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4460 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4461 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4462 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4463 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4466 /* 6 (LSB), 7, 12, 13 (MSB) */
4467 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4468 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4469 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4470 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4471 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4474 /* 14 (LSB), 15, 20, 21 */
4475 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4476 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4477 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4478 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4479 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4482 /* Mixed HT20 and HT40 rates */
4484 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4485 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4486 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4487 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4488 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4489 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4493 * Write the HT40 power per rate set
4494 * correct PAR difference between HT40 and HT20/LEGACY
4495 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4497 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4498 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4499 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4500 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4501 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4504 /* 6 (LSB), 7, 12, 13 (MSB) */
4505 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4506 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4507 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4508 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4509 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4512 /* 14 (LSB), 15, 20, 21 */
4513 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4514 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4515 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4516 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4517 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4524 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4525 u8 *targetPowerValT2,
4528 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4529 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4531 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4532 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4534 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4535 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4537 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4538 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4542 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4543 u8 *targetPowerValT2)
4545 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4546 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4548 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4549 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4550 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4551 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4552 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4553 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4556 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4557 u8 *targetPowerValT2, bool is2GHz)
4559 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4560 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4562 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4563 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4565 targetPowerValT2[ALL_TARGET_HT20_4] =
4566 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4568 targetPowerValT2[ALL_TARGET_HT20_5] =
4569 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4571 targetPowerValT2[ALL_TARGET_HT20_6] =
4572 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4574 targetPowerValT2[ALL_TARGET_HT20_7] =
4575 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4577 targetPowerValT2[ALL_TARGET_HT20_12] =
4578 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4580 targetPowerValT2[ALL_TARGET_HT20_13] =
4581 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4583 targetPowerValT2[ALL_TARGET_HT20_14] =
4584 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4586 targetPowerValT2[ALL_TARGET_HT20_15] =
4587 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4589 targetPowerValT2[ALL_TARGET_HT20_20] =
4590 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4592 targetPowerValT2[ALL_TARGET_HT20_21] =
4593 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4595 targetPowerValT2[ALL_TARGET_HT20_22] =
4596 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4598 targetPowerValT2[ALL_TARGET_HT20_23] =
4599 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4603 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4605 u8 *targetPowerValT2,
4608 /* XXX: hard code for now, need to get from eeprom struct */
4609 u8 ht40PowerIncForPdadc = 0;
4611 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4612 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4613 is2GHz) + ht40PowerIncForPdadc;
4614 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4615 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4617 is2GHz) + ht40PowerIncForPdadc;
4618 targetPowerValT2[ALL_TARGET_HT40_4] =
4619 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4620 is2GHz) + ht40PowerIncForPdadc;
4621 targetPowerValT2[ALL_TARGET_HT40_5] =
4622 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4623 is2GHz) + ht40PowerIncForPdadc;
4624 targetPowerValT2[ALL_TARGET_HT40_6] =
4625 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4626 is2GHz) + ht40PowerIncForPdadc;
4627 targetPowerValT2[ALL_TARGET_HT40_7] =
4628 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4629 is2GHz) + ht40PowerIncForPdadc;
4630 targetPowerValT2[ALL_TARGET_HT40_12] =
4631 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4632 is2GHz) + ht40PowerIncForPdadc;
4633 targetPowerValT2[ALL_TARGET_HT40_13] =
4634 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4635 is2GHz) + ht40PowerIncForPdadc;
4636 targetPowerValT2[ALL_TARGET_HT40_14] =
4637 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4638 is2GHz) + ht40PowerIncForPdadc;
4639 targetPowerValT2[ALL_TARGET_HT40_15] =
4640 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4641 is2GHz) + ht40PowerIncForPdadc;
4642 targetPowerValT2[ALL_TARGET_HT40_20] =
4643 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4644 is2GHz) + ht40PowerIncForPdadc;
4645 targetPowerValT2[ALL_TARGET_HT40_21] =
4646 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4647 is2GHz) + ht40PowerIncForPdadc;
4648 targetPowerValT2[ALL_TARGET_HT40_22] =
4649 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4650 is2GHz) + ht40PowerIncForPdadc;
4651 targetPowerValT2[ALL_TARGET_HT40_23] =
4652 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4653 is2GHz) + ht40PowerIncForPdadc;
4656 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4657 struct ath9k_channel *chan,
4658 u8 *targetPowerValT2)
4660 bool is2GHz = IS_CHAN_2GHZ(chan);
4662 struct ath_common *common = ath9k_hw_common(ah);
4663 u16 freq = chan->channel;
4666 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4668 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4669 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4671 if (IS_CHAN_HT40(chan))
4672 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4675 for (i = 0; i < ar9300RateSize; i++) {
4676 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
4677 i, targetPowerValT2[i]);
4681 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4687 int *ptemperature, int *pvoltage)
4690 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4692 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4693 struct ath_common *common = ath9k_hw_common(ah);
4695 if (ichain >= AR9300_MAX_CHAINS) {
4696 ath_dbg(common, EEPROM,
4697 "Invalid chain index, must be less than %d\n",
4702 if (mode) { /* 5GHz */
4703 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4704 ath_dbg(common, EEPROM,
4705 "Invalid 5GHz cal pier index, must be less than %d\n",
4706 AR9300_NUM_5G_CAL_PIERS);
4709 pCalPier = &(eep->calFreqPier5G[ipier]);
4710 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4713 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4714 ath_dbg(common, EEPROM,
4715 "Invalid 2GHz cal pier index, must be less than %d\n",
4716 AR9300_NUM_2G_CAL_PIERS);
4720 pCalPier = &(eep->calFreqPier2G[ipier]);
4721 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4725 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4726 *pcorrection = pCalPierStruct->refPower;
4727 *ptemperature = pCalPierStruct->tempMeas;
4728 *pvoltage = pCalPierStruct->voltMeas;
4733 static void ar9003_hw_power_control_override(struct ath_hw *ah,
4736 int *voltage, int *temperature)
4738 int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
4739 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4740 int f[8], t[8], t1[3], t2[3], i;
4742 REG_RMW(ah, AR_PHY_TPC_11_B0,
4743 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4744 AR_PHY_TPC_OLPC_GAIN_DELTA);
4745 if (ah->caps.tx_chainmask & BIT(1))
4746 REG_RMW(ah, AR_PHY_TPC_11_B1,
4747 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4748 AR_PHY_TPC_OLPC_GAIN_DELTA);
4749 if (ah->caps.tx_chainmask & BIT(2))
4750 REG_RMW(ah, AR_PHY_TPC_11_B2,
4751 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4752 AR_PHY_TPC_OLPC_GAIN_DELTA);
4754 /* enable open loop power control on chip */
4755 REG_RMW(ah, AR_PHY_TPC_6_B0,
4756 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4757 AR_PHY_TPC_6_ERROR_EST_MODE);
4758 if (ah->caps.tx_chainmask & BIT(1))
4759 REG_RMW(ah, AR_PHY_TPC_6_B1,
4760 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4761 AR_PHY_TPC_6_ERROR_EST_MODE);
4762 if (ah->caps.tx_chainmask & BIT(2))
4763 REG_RMW(ah, AR_PHY_TPC_6_B2,
4764 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4765 AR_PHY_TPC_6_ERROR_EST_MODE);
4768 * enable temperature compensation
4769 * Need to use register names
4771 if (frequency < 4000) {
4772 temp_slope = eep->modalHeader2G.tempSlope;
4774 if (AR_SREV_9550(ah)) {
4775 t[0] = eep->base_ext1.tempslopextension[2];
4776 t1[0] = eep->base_ext1.tempslopextension[3];
4777 t2[0] = eep->base_ext1.tempslopextension[4];
4780 t[1] = eep->modalHeader5G.tempSlope;
4781 t1[1] = eep->base_ext1.tempslopextension[0];
4782 t2[1] = eep->base_ext1.tempslopextension[1];
4785 t[2] = eep->base_ext1.tempslopextension[5];
4786 t1[2] = eep->base_ext1.tempslopextension[6];
4787 t2[2] = eep->base_ext1.tempslopextension[7];
4790 temp_slope = ar9003_hw_power_interpolate(frequency,
4792 temp_slope1 = ar9003_hw_power_interpolate(frequency,
4794 temp_slope2 = ar9003_hw_power_interpolate(frequency,
4800 if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4801 for (i = 0; i < 8; i++) {
4802 t[i] = eep->base_ext1.tempslopextension[i];
4803 f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4805 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4807 } else if (eep->base_ext2.tempSlopeLow != 0) {
4808 t[0] = eep->base_ext2.tempSlopeLow;
4810 t[1] = eep->modalHeader5G.tempSlope;
4812 t[2] = eep->base_ext2.tempSlopeHigh;
4814 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4817 temp_slope = eep->modalHeader5G.tempSlope;
4822 if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
4823 u8 txmask = (eep->baseEepHeader.txrxMask & 0xf0) >> 4;
4826 * AR955x has tempSlope register for each chain.
4827 * Check whether temp_compensation feature is enabled or not.
4829 if (eep->baseEepHeader.featureEnable & 0x1) {
4830 if (frequency < 4000) {
4831 if (txmask & BIT(0))
4832 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4833 AR_PHY_TPC_19_ALPHA_THERM,
4834 eep->base_ext2.tempSlopeLow);
4835 if (txmask & BIT(1))
4836 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4837 AR_PHY_TPC_19_ALPHA_THERM,
4839 if (txmask & BIT(2))
4840 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4841 AR_PHY_TPC_19_ALPHA_THERM,
4842 eep->base_ext2.tempSlopeHigh);
4844 if (txmask & BIT(0))
4845 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4846 AR_PHY_TPC_19_ALPHA_THERM,
4848 if (txmask & BIT(1))
4849 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4850 AR_PHY_TPC_19_ALPHA_THERM,
4852 if (txmask & BIT(2))
4853 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4854 AR_PHY_TPC_19_ALPHA_THERM,
4859 * If temp compensation is not enabled,
4860 * set all registers to 0.
4862 if (txmask & BIT(0))
4863 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4864 AR_PHY_TPC_19_ALPHA_THERM, 0);
4865 if (txmask & BIT(1))
4866 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4867 AR_PHY_TPC_19_ALPHA_THERM, 0);
4868 if (txmask & BIT(2))
4869 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4870 AR_PHY_TPC_19_ALPHA_THERM, 0);
4873 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4874 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4877 if (AR_SREV_9462_20_OR_LATER(ah))
4878 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4879 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4882 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4886 /* Apply the recorded correction values. */
4887 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4889 int ichain, ipier, npier;
4891 int lfrequency[AR9300_MAX_CHAINS],
4892 lcorrection[AR9300_MAX_CHAINS],
4893 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4894 int hfrequency[AR9300_MAX_CHAINS],
4895 hcorrection[AR9300_MAX_CHAINS],
4896 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4898 int correction[AR9300_MAX_CHAINS],
4899 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4900 int pfrequency, pcorrection, ptemperature, pvoltage;
4901 struct ath_common *common = ath9k_hw_common(ah);
4903 mode = (frequency >= 4000);
4905 npier = AR9300_NUM_5G_CAL_PIERS;
4907 npier = AR9300_NUM_2G_CAL_PIERS;
4909 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4910 lfrequency[ichain] = 0;
4911 hfrequency[ichain] = 100000;
4913 /* identify best lower and higher frequency calibration measurement */
4914 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4915 for (ipier = 0; ipier < npier; ipier++) {
4916 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4917 &pfrequency, &pcorrection,
4918 &ptemperature, &pvoltage)) {
4919 fdiff = frequency - pfrequency;
4922 * this measurement is higher than
4923 * our desired frequency
4926 if (hfrequency[ichain] <= 0 ||
4927 hfrequency[ichain] >= 100000 ||
4929 (frequency - hfrequency[ichain])) {
4932 * frequency measurement
4934 hfrequency[ichain] = pfrequency;
4935 hcorrection[ichain] =
4937 htemperature[ichain] =
4939 hvoltage[ichain] = pvoltage;
4943 if (lfrequency[ichain] <= 0
4945 (frequency - lfrequency[ichain])) {
4948 * frequency measurement
4950 lfrequency[ichain] = pfrequency;
4951 lcorrection[ichain] =
4953 ltemperature[ichain] =
4955 lvoltage[ichain] = pvoltage;
4963 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4964 ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
4965 ichain, frequency, lfrequency[ichain],
4966 lcorrection[ichain], hfrequency[ichain],
4967 hcorrection[ichain]);
4968 /* they're the same, so just pick one */
4969 if (hfrequency[ichain] == lfrequency[ichain]) {
4970 correction[ichain] = lcorrection[ichain];
4971 voltage[ichain] = lvoltage[ichain];
4972 temperature[ichain] = ltemperature[ichain];
4974 /* the low frequency is good */
4975 else if (frequency - lfrequency[ichain] < 1000) {
4976 /* so is the high frequency, interpolate */
4977 if (hfrequency[ichain] - frequency < 1000) {
4979 correction[ichain] = interpolate(frequency,
4982 lcorrection[ichain],
4983 hcorrection[ichain]);
4985 temperature[ichain] = interpolate(frequency,
4988 ltemperature[ichain],
4989 htemperature[ichain]);
4991 voltage[ichain] = interpolate(frequency,
4997 /* only low is good, use it */
4999 correction[ichain] = lcorrection[ichain];
5000 temperature[ichain] = ltemperature[ichain];
5001 voltage[ichain] = lvoltage[ichain];
5004 /* only high is good, use it */
5005 else if (hfrequency[ichain] - frequency < 1000) {
5006 correction[ichain] = hcorrection[ichain];
5007 temperature[ichain] = htemperature[ichain];
5008 voltage[ichain] = hvoltage[ichain];
5009 } else { /* nothing is good, presume 0???? */
5010 correction[ichain] = 0;
5011 temperature[ichain] = 0;
5012 voltage[ichain] = 0;
5016 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
5019 ath_dbg(common, EEPROM,
5020 "for frequency=%d, calibration correction = %d %d %d\n",
5021 frequency, correction[0], correction[1], correction[2]);
5026 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
5031 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5032 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5035 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
5037 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
5040 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
5046 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5047 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5049 u8 *ctl_freqbin = is2GHz ?
5050 &eep->ctl_freqbin_2G[idx][0] :
5051 &eep->ctl_freqbin_5G[idx][0];
5054 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
5055 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
5056 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
5058 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
5059 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
5060 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
5063 return MAX_RATE_POWER;
5067 * Find the maximum conformance test limit for the given channel and CTL info
5069 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
5070 u16 freq, int idx, bool is2GHz)
5072 u16 twiceMaxEdgePower = MAX_RATE_POWER;
5073 u8 *ctl_freqbin = is2GHz ?
5074 &eep->ctl_freqbin_2G[idx][0] :
5075 &eep->ctl_freqbin_5G[idx][0];
5076 u16 num_edges = is2GHz ?
5077 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
5080 /* Get the edge power */
5082 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
5085 * If there's an exact channel match or an inband flag set
5086 * on the lower channel use the given rdEdgePower
5088 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
5090 ar9003_hw_get_direct_edge_power(eep, idx,
5093 } else if ((edge > 0) &&
5094 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
5097 ar9003_hw_get_indirect_edge_power(eep, idx,
5101 * Leave loop - no more affecting edges possible in
5102 * this monotonic increasing list
5108 if (is2GHz && !twiceMaxEdgePower)
5109 twiceMaxEdgePower = 60;
5111 return twiceMaxEdgePower;
5114 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
5115 struct ath9k_channel *chan,
5116 u8 *pPwrArray, u16 cfgCtl,
5117 u8 antenna_reduction,
5120 struct ath_common *common = ath9k_hw_common(ah);
5121 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
5122 u16 twiceMaxEdgePower;
5124 u16 scaledPower = 0, minCtlPower;
5125 static const u16 ctlModesFor11a[] = {
5126 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
5128 static const u16 ctlModesFor11g[] = {
5129 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
5130 CTL_11G_EXT, CTL_2GHT40
5133 const u16 *pCtlMode;
5135 struct chan_centers centers;
5138 u16 twiceMinEdgePower;
5139 bool is2ghz = IS_CHAN_2GHZ(chan);
5141 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5142 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
5146 /* Setup for CTL modes */
5147 /* CTL_11B, CTL_11G, CTL_2GHT20 */
5149 ARRAY_SIZE(ctlModesFor11g) -
5150 SUB_NUM_CTL_MODES_AT_2G_40;
5151 pCtlMode = ctlModesFor11g;
5152 if (IS_CHAN_HT40(chan))
5154 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
5156 /* Setup for CTL modes */
5157 /* CTL_11A, CTL_5GHT20 */
5158 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
5159 SUB_NUM_CTL_MODES_AT_5G_40;
5160 pCtlMode = ctlModesFor11a;
5161 if (IS_CHAN_HT40(chan))
5163 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
5167 * For MIMO, need to apply regulatory caps individually across
5168 * dynamically running modes: CCK, OFDM, HT20, HT40
5170 * The outer loop walks through each possible applicable runtime mode.
5171 * The inner loop walks through each ctlIndex entry in EEPROM.
5172 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
5174 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
5175 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
5176 (pCtlMode[ctlMode] == CTL_2GHT40);
5178 freq = centers.synth_center;
5179 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
5180 freq = centers.ext_center;
5182 freq = centers.ctl_center;
5184 ath_dbg(common, REGULATORY,
5185 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
5186 ctlMode, numCtlModes, isHt40CtlMode,
5187 (pCtlMode[ctlMode] & EXT_ADDITIVE));
5189 /* walk through each CTL index stored in EEPROM */
5191 ctlIndex = pEepData->ctlIndex_2G;
5192 ctlNum = AR9300_NUM_CTLS_2G;
5194 ctlIndex = pEepData->ctlIndex_5G;
5195 ctlNum = AR9300_NUM_CTLS_5G;
5198 twiceMaxEdgePower = MAX_RATE_POWER;
5199 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
5200 ath_dbg(common, REGULATORY,
5201 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
5202 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
5206 * compare test group from regulatory
5207 * channel list with test mode from pCtlMode
5210 if ((((cfgCtl & ~CTL_MODE_M) |
5211 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5213 (((cfgCtl & ~CTL_MODE_M) |
5214 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5215 ((ctlIndex[i] & CTL_MODE_M) |
5218 ar9003_hw_get_max_edge_power(pEepData,
5222 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
5224 * Find the minimum of all CTL
5225 * edge powers that apply to
5229 min(twiceMaxEdgePower,
5233 twiceMaxEdgePower = twiceMinEdgePower;
5239 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
5241 ath_dbg(common, REGULATORY,
5242 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
5243 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
5244 scaledPower, minCtlPower);
5246 /* Apply ctl mode to correct target power set */
5247 switch (pCtlMode[ctlMode]) {
5249 for (i = ALL_TARGET_LEGACY_1L_5L;
5250 i <= ALL_TARGET_LEGACY_11S; i++)
5251 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5256 for (i = ALL_TARGET_LEGACY_6_24;
5257 i <= ALL_TARGET_LEGACY_54; i++)
5258 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5263 for (i = ALL_TARGET_HT20_0_8_16;
5264 i <= ALL_TARGET_HT20_23; i++) {
5265 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5267 if (ath9k_hw_mci_is_enabled(ah))
5269 (u8)min((u16)pPwrArray[i],
5270 ar9003_mci_get_max_txpower(ah,
5271 pCtlMode[ctlMode]));
5276 for (i = ALL_TARGET_HT40_0_8_16;
5277 i <= ALL_TARGET_HT40_23; i++) {
5278 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5280 if (ath9k_hw_mci_is_enabled(ah))
5282 (u8)min((u16)pPwrArray[i],
5283 ar9003_mci_get_max_txpower(ah,
5284 pCtlMode[ctlMode]));
5290 } /* end ctl mode checking */
5293 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5295 u8 mod_idx = mcs_idx % 8;
5298 return mod_idx ? (base_pwridx + 1) : base_pwridx;
5300 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5303 static void ar9003_paprd_set_txpower(struct ath_hw *ah,
5304 struct ath9k_channel *chan,
5305 u8 *targetPowerValT2)
5309 if (!ar9003_is_paprd_enabled(ah))
5312 if (IS_CHAN_HT40(chan))
5313 i = ALL_TARGET_HT40_7;
5315 i = ALL_TARGET_HT20_7;
5317 if (IS_CHAN_2GHZ(chan)) {
5318 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) &&
5319 !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) {
5320 if (IS_CHAN_HT40(chan))
5321 i = ALL_TARGET_HT40_0_8_16;
5323 i = ALL_TARGET_HT20_0_8_16;
5327 ah->paprd_target_power = targetPowerValT2[i];
5330 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5331 struct ath9k_channel *chan, u16 cfgCtl,
5332 u8 twiceAntennaReduction,
5333 u8 powerLimit, bool test)
5335 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5336 struct ath_common *common = ath9k_hw_common(ah);
5337 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5338 struct ar9300_modal_eep_header *modal_hdr;
5339 u8 targetPowerValT2[ar9300RateSize];
5340 u8 target_power_val_t2_eep[ar9300RateSize];
5341 u8 targetPowerValT2_tpc[ar9300RateSize];
5342 unsigned int i = 0, paprd_scale_factor = 0;
5343 u8 pwr_idx, min_pwridx = 0;
5345 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5348 * Get target powers from EEPROM - our baseline for TX Power
5350 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5352 if (ar9003_is_paprd_enabled(ah)) {
5353 if (IS_CHAN_2GHZ(chan))
5354 modal_hdr = &eep->modalHeader2G;
5356 modal_hdr = &eep->modalHeader5G;
5358 ah->paprd_ratemask =
5359 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5360 AR9300_PAPRD_RATE_MASK;
5362 ah->paprd_ratemask_ht40 =
5363 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5364 AR9300_PAPRD_RATE_MASK;
5366 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5367 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5368 ALL_TARGET_HT20_0_8_16;
5370 if (!ah->paprd_table_write_done) {
5371 memcpy(target_power_val_t2_eep, targetPowerValT2,
5372 sizeof(targetPowerValT2));
5373 for (i = 0; i < 24; i++) {
5374 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5375 if (ah->paprd_ratemask & (1 << i)) {
5376 if (targetPowerValT2[pwr_idx] &&
5377 targetPowerValT2[pwr_idx] ==
5378 target_power_val_t2_eep[pwr_idx])
5379 targetPowerValT2[pwr_idx] -=
5384 memcpy(target_power_val_t2_eep, targetPowerValT2,
5385 sizeof(targetPowerValT2));
5388 ar9003_hw_set_power_per_rate_table(ah, chan,
5389 targetPowerValT2, cfgCtl,
5390 twiceAntennaReduction,
5393 memcpy(targetPowerValT2_tpc, targetPowerValT2,
5394 sizeof(targetPowerValT2));
5396 if (ar9003_is_paprd_enabled(ah)) {
5397 for (i = 0; i < ar9300RateSize; i++) {
5398 if ((ah->paprd_ratemask & (1 << i)) &&
5399 (abs(targetPowerValT2[i] -
5400 target_power_val_t2_eep[i]) >
5401 paprd_scale_factor)) {
5402 ah->paprd_ratemask &= ~(1 << i);
5403 ath_dbg(common, EEPROM,
5404 "paprd disabled for mcs %d\n", i);
5409 regulatory->max_power_level = 0;
5410 for (i = 0; i < ar9300RateSize; i++) {
5411 if (targetPowerValT2[i] > regulatory->max_power_level)
5412 regulatory->max_power_level = targetPowerValT2[i];
5415 ath9k_hw_update_regulatory_maxpower(ah);
5420 for (i = 0; i < ar9300RateSize; i++) {
5421 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
5422 i, targetPowerValT2[i]);
5425 /* Write target power array to registers */
5426 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5427 ar9003_hw_calibration_apply(ah, chan->channel);
5428 ar9003_paprd_set_txpower(ah, chan, targetPowerValT2);
5430 ar9003_hw_selfgen_tpc_txpower(ah, chan, targetPowerValT2);
5432 /* TPC initializations */
5433 if (ah->tpc_enabled) {
5436 ar9003_hw_init_rate_txpower(ah, targetPowerValT2_tpc, chan);
5439 REG_WRITE(ah, AR_PHY_PWRTX_MAX,
5440 AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
5441 /* Disable per chain power reduction */
5442 val = REG_READ(ah, AR_PHY_POWER_TX_SUB);
5443 if (AR_SREV_9340(ah))
5444 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5447 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5451 REG_WRITE(ah, AR_PHY_PWRTX_MAX, 0);
5455 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5461 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5463 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5465 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5468 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5470 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5472 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5475 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5477 return ar9003_modal_header(ah, is2ghz)->spurChans;
5480 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5481 struct ath9k_channel *chan)
5483 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5485 if (IS_CHAN_2GHZ(chan))
5486 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5487 AR9300_PAPRD_SCALE_1);
5489 if (chan->channel >= 5700)
5490 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5491 AR9300_PAPRD_SCALE_1);
5492 else if (chan->channel >= 5400)
5493 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5494 AR9300_PAPRD_SCALE_2);
5496 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5497 AR9300_PAPRD_SCALE_1);
5501 const struct eeprom_ops eep_ar9300_ops = {
5502 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5503 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5504 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5505 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5506 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5507 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5508 .set_board_values = ath9k_hw_ar9300_set_board_values,
5509 .set_addac = ath9k_hw_ar9300_set_addac,
5510 .set_txpower = ath9k_hw_ar9300_set_txpower,
5511 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel