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 ath9k_hw_nvram_read(ah, i, data);
3260 * Read the configuration data from the eeprom.
3261 * The data can be put in any specified memory buffer.
3263 * Returns -1 on error.
3264 * Returns address of next memory location on success.
3266 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3267 u8 *mptr, int mdata_size)
3274 int reference, length, major, minor;
3277 u16 checksum, mchecksum;
3278 struct ath_common *common = ath9k_hw_common(ah);
3279 struct ar9300_eeprom *eep;
3280 eeprom_read_op read;
3282 if (ath9k_hw_use_flash(ah)) {
3285 ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3287 /* check if eeprom contains valid data */
3288 eep = (struct ar9300_eeprom *) mptr;
3289 txrx = eep->baseEepHeader.txrxMask;
3290 if (txrx != 0 && txrx != 0xff)
3294 word = kzalloc(2048, GFP_KERNEL);
3298 memcpy(mptr, &ar9300_default, mdata_size);
3300 read = ar9300_read_eeprom;
3301 if (AR_SREV_9485(ah))
3302 cptr = AR9300_BASE_ADDR_4K;
3303 else if (AR_SREV_9330(ah))
3304 cptr = AR9300_BASE_ADDR_512;
3306 cptr = AR9300_BASE_ADDR;
3307 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3309 if (ar9300_check_eeprom_header(ah, read, cptr))
3312 cptr = AR9300_BASE_ADDR_512;
3313 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3315 if (ar9300_check_eeprom_header(ah, read, cptr))
3318 read = ar9300_read_otp;
3319 cptr = AR9300_BASE_ADDR;
3320 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3321 if (ar9300_check_eeprom_header(ah, read, cptr))
3324 cptr = AR9300_BASE_ADDR_512;
3325 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3326 if (ar9300_check_eeprom_header(ah, read, cptr))
3332 ath_dbg(common, EEPROM, "Found valid EEPROM data\n");
3334 for (it = 0; it < MSTATE; it++) {
3335 if (!read(ah, cptr, word, COMP_HDR_LEN))
3338 if (!ar9300_check_header(word))
3341 ar9300_comp_hdr_unpack(word, &code, &reference,
3342 &length, &major, &minor);
3343 ath_dbg(common, EEPROM,
3344 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3345 cptr, code, reference, length, major, minor);
3346 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3347 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3348 ath_dbg(common, EEPROM, "Skipping bad header\n");
3349 cptr -= COMP_HDR_LEN;
3354 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3355 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3356 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3357 ath_dbg(common, EEPROM, "checksum %x %x\n",
3358 checksum, mchecksum);
3359 if (checksum == mchecksum) {
3360 ar9300_compress_decision(ah, it, code, reference, mptr,
3361 word, length, mdata_size);
3363 ath_dbg(common, EEPROM,
3364 "skipping block with bad checksum\n");
3366 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3378 * Restore the configuration structure by reading the eeprom.
3379 * This function destroys any existing in-memory structure
3382 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3384 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3386 if (ar9300_eeprom_restore_internal(ah, mptr,
3387 sizeof(struct ar9300_eeprom)) < 0)
3393 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3394 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3395 struct ar9300_modal_eep_header *modal_hdr)
3397 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3398 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3399 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3400 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3401 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3402 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3403 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3404 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3405 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3406 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3407 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3408 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3409 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3410 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3411 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3412 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3413 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3414 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3415 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3416 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3417 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3418 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3419 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3420 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3421 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3422 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3423 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3424 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3425 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3426 PR_EEP("txClip", modal_hdr->txClip);
3427 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3432 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3433 u8 *buf, u32 len, u32 size)
3435 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3436 struct ar9300_base_eep_hdr *pBase;
3438 if (!dump_base_hdr) {
3439 len += scnprintf(buf + len, size - len,
3440 "%20s :\n", "2GHz modal Header");
3441 len = ar9003_dump_modal_eeprom(buf, len, size,
3442 &eep->modalHeader2G);
3443 len += scnprintf(buf + len, size - len,
3444 "%20s :\n", "5GHz modal Header");
3445 len = ar9003_dump_modal_eeprom(buf, len, size,
3446 &eep->modalHeader5G);
3450 pBase = &eep->baseEepHeader;
3452 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3453 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3454 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3455 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3456 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3457 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3458 AR5416_OPFLAGS_11A));
3459 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3460 AR5416_OPFLAGS_11G));
3461 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3462 AR5416_OPFLAGS_N_2G_HT20));
3463 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3464 AR5416_OPFLAGS_N_2G_HT40));
3465 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3466 AR5416_OPFLAGS_N_5G_HT20));
3467 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3468 AR5416_OPFLAGS_N_5G_HT40));
3469 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3470 PR_EEP("RF Silent", pBase->rfSilent);
3471 PR_EEP("BT option", pBase->blueToothOptions);
3472 PR_EEP("Device Cap", pBase->deviceCap);
3473 PR_EEP("Device Type", pBase->deviceType);
3474 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3475 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3476 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3477 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3478 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3479 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3480 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3481 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3482 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3483 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3484 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3485 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3486 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3487 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3488 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3489 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3490 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3491 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3492 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3494 len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3495 ah->eeprom.ar9300_eep.macAddr);
3503 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3504 u8 *buf, u32 len, u32 size)
3510 /* XXX: review hardware docs */
3511 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3513 return ah->eeprom.ar9300_eep.eepromVersion;
3516 /* XXX: could be read from the eepromVersion, not sure yet */
3517 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3522 static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
3525 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3528 return &eep->modalHeader2G;
3530 return &eep->modalHeader5G;
3533 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3535 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3537 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
3538 AR_SREV_9531(ah) || AR_SREV_9561(ah))
3539 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3540 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
3541 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3543 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3544 REG_RMW_FIELD(ah, AR_CH0_THERM,
3545 AR_CH0_THERM_XPABIASLVL_MSB,
3547 REG_RMW_FIELD(ah, AR_CH0_THERM,
3548 AR_CH0_THERM_XPASHORT2GND, 1);
3552 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3554 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3557 u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3559 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3562 u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3564 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3567 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3570 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3571 return le16_to_cpu(val);
3574 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3576 struct ath_common *common = ath9k_hw_common(ah);
3577 struct ath9k_hw_capabilities *pCap = &ah->caps;
3579 u32 regval, value, gpio;
3580 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3581 AR_PHY_SWITCH_CHAIN_0,
3582 AR_PHY_SWITCH_CHAIN_1,
3583 AR_PHY_SWITCH_CHAIN_2,
3586 if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0)) {
3587 if (ah->config.xlna_gpio)
3588 gpio = ah->config.xlna_gpio;
3590 gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
3592 ath9k_hw_gpio_request_out(ah, gpio, NULL,
3593 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
3596 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3598 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3599 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3600 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3601 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
3602 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3603 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3605 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3606 AR_SWITCH_TABLE_COM_ALL, value);
3610 * AR9462 defines new switch table for BT/WLAN,
3611 * here's new field name in XXX.ref for both 2G and 5G.
3612 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3613 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3614 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3616 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3617 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3619 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3620 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3622 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
3623 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3624 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3625 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3626 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3629 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3630 if (AR_SREV_9485(ah) && common->bt_ant_diversity) {
3631 value &= ~AR_SWITCH_TABLE_COM2_ALL;
3632 value |= ah->config.ant_ctrl_comm2g_switch_enable;
3635 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3637 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3638 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3639 REG_RMW_FIELD(ah, switch_chain_reg[0],
3640 AR_SWITCH_TABLE_ALL, value);
3643 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3644 if ((ah->rxchainmask & BIT(chain)) ||
3645 (ah->txchainmask & BIT(chain))) {
3646 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3648 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3649 AR_SWITCH_TABLE_ALL, value);
3653 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
3654 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3656 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3657 * are the fields present
3659 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3660 regval &= (~AR_ANT_DIV_CTRL_ALL);
3661 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3663 regval &= (~AR_PHY_ANT_DIV_LNADIV);
3664 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
3666 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3667 regval |= AR_ANT_DIV_ENABLE;
3669 if (AR_SREV_9565(ah)) {
3670 if (common->bt_ant_diversity) {
3671 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S);
3673 REG_SET_BIT(ah, AR_PHY_RESTART,
3674 AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
3676 /* Force WLAN LNA diversity ON */
3677 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
3678 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3680 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S);
3681 regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S);
3683 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL,
3684 (1 << AR_PHY_ANT_SW_RX_PROT_S));
3686 /* Force WLAN LNA diversity OFF */
3687 REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV,
3688 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3692 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3694 /* enable fast_div */
3695 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3696 regval &= (~AR_FAST_DIV_ENABLE);
3697 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
3699 if ((AR_SREV_9485(ah) || AR_SREV_9565(ah))
3700 && common->bt_ant_diversity)
3701 regval |= AR_FAST_DIV_ENABLE;
3703 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3705 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
3706 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3708 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3711 regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
3712 AR_PHY_ANT_DIV_ALT_LNACONF |
3713 AR_PHY_ANT_DIV_ALT_GAINTB |
3714 AR_PHY_ANT_DIV_MAIN_GAINTB));
3715 /* by default use LNA1 for the main antenna */
3716 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
3717 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
3718 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
3719 AR_PHY_ANT_DIV_ALT_LNACONF_S);
3720 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3725 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3727 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3728 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3732 drive_strength = pBase->miscConfiguration & BIT(0);
3733 if (!drive_strength)
3736 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3744 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3746 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3757 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3759 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3764 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3767 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3768 struct ath9k_channel *chan)
3772 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3774 if (chain >= 0 && chain < 3) {
3775 if (IS_CHAN_2GHZ(chan))
3776 return eep->modalHeader2G.xatten1DB[chain];
3777 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3778 t[0] = eep->base_ext2.xatten1DBLow[chain];
3780 t[1] = eep->modalHeader5G.xatten1DB[chain];
3782 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3784 value = ar9003_hw_power_interpolate((s32) chan->channel,
3788 return eep->modalHeader5G.xatten1DB[chain];
3795 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3796 struct ath9k_channel *chan)
3800 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3802 if (chain >= 0 && chain < 3) {
3803 if (IS_CHAN_2GHZ(chan))
3804 return eep->modalHeader2G.xatten1Margin[chain];
3805 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3806 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3808 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3810 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3812 value = ar9003_hw_power_interpolate((s32) chan->channel,
3816 return eep->modalHeader5G.xatten1Margin[chain];
3822 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3826 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3827 AR_PHY_EXT_ATTEN_CTL_1,
3828 AR_PHY_EXT_ATTEN_CTL_2,
3831 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3832 value = ar9003_hw_atten_chain_get(ah, 1, chan);
3833 REG_RMW_FIELD(ah, ext_atten_reg[0],
3834 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3836 value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
3837 REG_RMW_FIELD(ah, ext_atten_reg[0],
3838 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3842 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3843 for (i = 0; i < 3; i++) {
3844 if (ah->txchainmask & BIT(i)) {
3845 value = ar9003_hw_atten_chain_get(ah, i, chan);
3846 REG_RMW_FIELD(ah, ext_atten_reg[i],
3847 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3849 if (AR_SREV_9485(ah) &&
3850 (ar9003_hw_get_rx_gain_idx(ah) == 0) &&
3851 ah->config.xatten_margin_cfg)
3854 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3856 if (ah->config.alt_mingainidx)
3857 REG_RMW_FIELD(ah, AR_PHY_EXT_ATTEN_CTL_0,
3858 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3861 REG_RMW_FIELD(ah, ext_atten_reg[i],
3862 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3868 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3872 while (pmu_set != REG_READ(ah, pmu_reg)) {
3875 REG_WRITE(ah, pmu_reg, pmu_set);
3882 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3884 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3885 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3888 if (pBase->featureEnable & BIT(4)) {
3889 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3892 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3893 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3894 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3897 if (AR_SREV_9330(ah)) {
3898 if (ah->is_clk_25mhz) {
3899 reg_pmu_set = (3 << 1) | (8 << 4) |
3900 (3 << 8) | (1 << 14) |
3901 (6 << 17) | (1 << 20) |
3904 reg_pmu_set = (4 << 1) | (7 << 4) |
3905 (3 << 8) | (1 << 14) |
3906 (6 << 17) | (1 << 20) |
3910 reg_pmu_set = (5 << 1) | (7 << 4) |
3911 (2 << 8) | (2 << 14) |
3912 (6 << 17) | (1 << 20) |
3913 (3 << 24) | (1 << 28);
3916 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3917 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3920 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3922 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3923 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3926 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3928 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3929 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3931 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah) ||
3933 reg_val = le32_to_cpu(pBase->swreg);
3934 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3936 if (AR_SREV_9561(ah))
3937 REG_WRITE(ah, AR_PHY_PMU2, 0x10200000);
3939 /* Internal regulator is ON. Write swreg register. */
3940 reg_val = le32_to_cpu(pBase->swreg);
3941 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3942 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3943 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3944 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3945 /* Set REG_CONTROL1.SWREG_PROGRAM */
3946 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3948 AR_RTC_REG_CONTROL1) |
3949 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3952 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3953 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3954 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3958 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3959 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3962 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3963 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3966 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
3967 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3969 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3970 AR_RTC_FORCE_SWREG_PRD;
3971 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3977 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3979 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3980 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3982 if (AR_SREV_9340(ah) || AR_SREV_9531(ah))
3985 if (eep->baseEepHeader.featureEnable & 0x40) {
3986 tuning_caps_param &= 0x7f;
3987 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3989 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3994 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3996 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3997 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3999 s32 t[3], f[3] = {5180, 5500, 5785};
4001 if (!(pBase->miscConfiguration & BIT(4)))
4004 if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) {
4006 quick_drop = eep->modalHeader2G.quick_drop;
4008 t[0] = eep->base_ext1.quick_drop_low;
4009 t[1] = eep->modalHeader5G.quick_drop;
4010 t[2] = eep->base_ext1.quick_drop_high;
4011 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
4013 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
4017 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
4021 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
4023 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4024 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
4025 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4026 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
4029 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
4031 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4034 if (!(eep->baseEepHeader.featureEnable & 0x80))
4037 if (!AR_SREV_9300(ah) &&
4038 !AR_SREV_9340(ah) &&
4039 !AR_SREV_9580(ah) &&
4040 !AR_SREV_9531(ah) &&
4044 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
4046 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4047 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
4049 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4050 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
4053 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
4055 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4058 if (!(eep->baseEepHeader.miscConfiguration & 0x40))
4061 if (!AR_SREV_9300(ah))
4064 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
4065 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4068 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4071 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4075 static int ar9003_hw_get_thermometer(struct ath_hw *ah)
4077 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4078 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4079 int thermometer = (pBase->miscConfiguration >> 1) & 0x3;
4081 return --thermometer;
4084 static void ar9003_hw_thermometer_apply(struct ath_hw *ah)
4086 struct ath9k_hw_capabilities *pCap = &ah->caps;
4087 int thermometer = ar9003_hw_get_thermometer(ah);
4088 u8 therm_on = (thermometer < 0) ? 0 : 1;
4090 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4091 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4092 if (pCap->chip_chainmask & BIT(1))
4093 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4094 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4095 if (pCap->chip_chainmask & BIT(2))
4096 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4097 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4099 therm_on = thermometer == 0;
4100 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4101 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4102 if (pCap->chip_chainmask & BIT(1)) {
4103 therm_on = thermometer == 1;
4104 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4105 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4107 if (pCap->chip_chainmask & BIT(2)) {
4108 therm_on = thermometer == 2;
4109 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4110 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4114 static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4118 if (!AR_SREV_9462_20_OR_LATER(ah))
4121 ar9300_otp_read_word(ah, 1, &data);
4123 kg = (data >> 8) & 0xff;
4125 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4126 AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko);
4127 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4128 AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN,
4133 static void ar9003_hw_apply_minccapwr_thresh(struct ath_hw *ah,
4136 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4137 const u_int32_t cca_ctrl[AR9300_MAX_CHAINS] = {
4146 if (!(eep->base_ext1.misc_enable & BIT(2)))
4149 if (!(eep->base_ext1.misc_enable & BIT(3)))
4153 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
4154 if (!(ah->caps.tx_chainmask & BIT(chain)))
4157 val = ar9003_modal_header(ah, is2ghz)->noiseFloorThreshCh[chain];
4158 REG_RMW_FIELD(ah, cca_ctrl[chain],
4159 AR_PHY_EXT_CCA0_THRESH62_1, val);
4164 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4165 struct ath9k_channel *chan)
4167 bool is2ghz = IS_CHAN_2GHZ(chan);
4168 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
4169 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
4170 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
4171 ar9003_hw_drive_strength_apply(ah);
4172 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
4173 ar9003_hw_atten_apply(ah, chan);
4174 ar9003_hw_quick_drop_apply(ah, chan->channel);
4175 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah))
4176 ar9003_hw_internal_regulator_apply(ah);
4177 ar9003_hw_apply_tuning_caps(ah);
4178 ar9003_hw_apply_minccapwr_thresh(ah, is2ghz);
4179 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4180 ar9003_hw_thermometer_apply(ah);
4181 ar9003_hw_thermo_cal_apply(ah);
4184 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
4185 struct ath9k_channel *chan)
4190 * Returns the interpolated y value corresponding to the specified x value
4191 * from the np ordered pairs of data (px,py).
4192 * The pairs do not have to be in any order.
4193 * If the specified x value is less than any of the px,
4194 * the returned y value is equal to the py for the lowest px.
4195 * If the specified x value is greater than any of the px,
4196 * the returned y value is equal to the py for the highest px.
4198 static int ar9003_hw_power_interpolate(int32_t x,
4199 int32_t *px, int32_t *py, u_int16_t np)
4202 int lx = 0, ly = 0, lhave = 0;
4203 int hx = 0, hy = 0, hhave = 0;
4210 /* identify best lower and higher x calibration measurement */
4211 for (ip = 0; ip < np; ip++) {
4214 /* this measurement is higher than our desired x */
4216 if (!hhave || dx > (x - hx)) {
4217 /* new best higher x measurement */
4223 /* this measurement is lower than our desired x */
4225 if (!lhave || dx < (x - lx)) {
4226 /* new best lower x measurement */
4234 /* the low x is good */
4236 /* so is the high x */
4238 /* they're the same, so just pick one */
4241 else /* interpolate */
4242 y = interpolate(x, lx, hx, ly, hy);
4243 } else /* only low is good, use it */
4245 } else if (hhave) /* only high is good, use it */
4247 else /* nothing is good,this should never happen unless np=0, ???? */
4252 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4253 u16 rateIndex, u16 freq, bool is2GHz)
4256 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4257 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4258 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4259 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4263 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4264 pEepromTargetPwr = eep->calTargetPower2G;
4265 pFreqBin = eep->calTarget_freqbin_2G;
4267 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4268 pEepromTargetPwr = eep->calTargetPower5G;
4269 pFreqBin = eep->calTarget_freqbin_5G;
4273 * create array of channels and targetpower from
4274 * targetpower piers stored on eeprom
4276 for (i = 0; i < numPiers; i++) {
4277 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4278 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4281 /* interpolate to get target power for given frequency */
4282 return (u8) ar9003_hw_power_interpolate((s32) freq,
4284 targetPowerArray, numPiers);
4287 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4289 u16 freq, bool is2GHz)
4292 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4293 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4294 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4295 struct cal_tgt_pow_ht *pEepromTargetPwr;
4299 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4300 pEepromTargetPwr = eep->calTargetPower2GHT20;
4301 pFreqBin = eep->calTarget_freqbin_2GHT20;
4303 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4304 pEepromTargetPwr = eep->calTargetPower5GHT20;
4305 pFreqBin = eep->calTarget_freqbin_5GHT20;
4309 * create array of channels and targetpower
4310 * from targetpower piers stored on eeprom
4312 for (i = 0; i < numPiers; i++) {
4313 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4314 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4317 /* interpolate to get target power for given frequency */
4318 return (u8) ar9003_hw_power_interpolate((s32) freq,
4320 targetPowerArray, numPiers);
4323 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4325 u16 freq, bool is2GHz)
4328 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4329 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4330 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4331 struct cal_tgt_pow_ht *pEepromTargetPwr;
4335 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4336 pEepromTargetPwr = eep->calTargetPower2GHT40;
4337 pFreqBin = eep->calTarget_freqbin_2GHT40;
4339 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4340 pEepromTargetPwr = eep->calTargetPower5GHT40;
4341 pFreqBin = eep->calTarget_freqbin_5GHT40;
4345 * create array of channels and targetpower from
4346 * targetpower piers stored on eeprom
4348 for (i = 0; i < numPiers; i++) {
4349 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4350 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4353 /* interpolate to get target power for given frequency */
4354 return (u8) ar9003_hw_power_interpolate((s32) freq,
4356 targetPowerArray, numPiers);
4359 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4360 u16 rateIndex, u16 freq)
4362 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4363 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4364 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4365 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4366 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4367 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4370 * create array of channels and targetpower from
4371 * targetpower piers stored on eeprom
4373 for (i = 0; i < numPiers; i++) {
4374 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4375 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4378 /* interpolate to get target power for given frequency */
4379 return (u8) ar9003_hw_power_interpolate((s32) freq,
4381 targetPowerArray, numPiers);
4384 static void ar9003_hw_selfgen_tpc_txpower(struct ath_hw *ah,
4385 struct ath9k_channel *chan,
4390 /* target power values for self generated frames (ACK,RTS/CTS) */
4391 if (IS_CHAN_2GHZ(chan)) {
4392 val = SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_ACK) |
4393 SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_CTS) |
4394 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4396 val = SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_ACK) |
4397 SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_CTS) |
4398 SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT);
4400 REG_WRITE(ah, AR_TPC, val);
4403 /* Set tx power registers to array of values passed in */
4404 int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4406 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4407 /* make sure forced gain is not set */
4408 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4410 /* Write the OFDM power per rate set */
4412 /* 6 (LSB), 9, 12, 18 (MSB) */
4413 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4414 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4415 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4416 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4417 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4419 /* 24 (LSB), 36, 48, 54 (MSB) */
4420 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4421 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4422 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4423 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4424 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4426 /* Write the CCK power per rate set */
4428 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4429 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4430 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4431 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4432 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4433 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4435 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4436 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4437 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4438 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4439 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4440 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4443 /* Write the power for duplicated frames - HT40 */
4445 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4446 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4447 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4448 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4449 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4450 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4453 /* Write the HT20 power per rate set */
4455 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4456 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4457 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4458 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4459 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4460 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4463 /* 6 (LSB), 7, 12, 13 (MSB) */
4464 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4465 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4466 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4467 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4468 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4471 /* 14 (LSB), 15, 20, 21 */
4472 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4473 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4474 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4475 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4476 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4479 /* Mixed HT20 and HT40 rates */
4481 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4482 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4483 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4484 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4485 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4486 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4490 * Write the HT40 power per rate set
4491 * correct PAR difference between HT40 and HT20/LEGACY
4492 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4494 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4495 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4496 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4497 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4498 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4501 /* 6 (LSB), 7, 12, 13 (MSB) */
4502 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4503 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4504 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4505 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4506 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4509 /* 14 (LSB), 15, 20, 21 */
4510 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4511 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4512 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4513 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4514 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4521 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4522 u8 *targetPowerValT2,
4525 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4526 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4528 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4529 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4531 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4532 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4534 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4535 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4539 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4540 u8 *targetPowerValT2)
4542 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4543 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4545 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4546 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4547 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4548 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4549 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4550 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4553 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4554 u8 *targetPowerValT2, bool is2GHz)
4556 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4557 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4559 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4560 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4562 targetPowerValT2[ALL_TARGET_HT20_4] =
4563 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4565 targetPowerValT2[ALL_TARGET_HT20_5] =
4566 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4568 targetPowerValT2[ALL_TARGET_HT20_6] =
4569 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4571 targetPowerValT2[ALL_TARGET_HT20_7] =
4572 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4574 targetPowerValT2[ALL_TARGET_HT20_12] =
4575 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4577 targetPowerValT2[ALL_TARGET_HT20_13] =
4578 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4580 targetPowerValT2[ALL_TARGET_HT20_14] =
4581 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4583 targetPowerValT2[ALL_TARGET_HT20_15] =
4584 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4586 targetPowerValT2[ALL_TARGET_HT20_20] =
4587 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4589 targetPowerValT2[ALL_TARGET_HT20_21] =
4590 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4592 targetPowerValT2[ALL_TARGET_HT20_22] =
4593 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4595 targetPowerValT2[ALL_TARGET_HT20_23] =
4596 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4600 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4602 u8 *targetPowerValT2,
4605 /* XXX: hard code for now, need to get from eeprom struct */
4606 u8 ht40PowerIncForPdadc = 0;
4608 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4609 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4610 is2GHz) + ht40PowerIncForPdadc;
4611 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4612 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4614 is2GHz) + ht40PowerIncForPdadc;
4615 targetPowerValT2[ALL_TARGET_HT40_4] =
4616 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4617 is2GHz) + ht40PowerIncForPdadc;
4618 targetPowerValT2[ALL_TARGET_HT40_5] =
4619 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4620 is2GHz) + ht40PowerIncForPdadc;
4621 targetPowerValT2[ALL_TARGET_HT40_6] =
4622 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4623 is2GHz) + ht40PowerIncForPdadc;
4624 targetPowerValT2[ALL_TARGET_HT40_7] =
4625 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4626 is2GHz) + ht40PowerIncForPdadc;
4627 targetPowerValT2[ALL_TARGET_HT40_12] =
4628 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4629 is2GHz) + ht40PowerIncForPdadc;
4630 targetPowerValT2[ALL_TARGET_HT40_13] =
4631 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4632 is2GHz) + ht40PowerIncForPdadc;
4633 targetPowerValT2[ALL_TARGET_HT40_14] =
4634 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4635 is2GHz) + ht40PowerIncForPdadc;
4636 targetPowerValT2[ALL_TARGET_HT40_15] =
4637 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4638 is2GHz) + ht40PowerIncForPdadc;
4639 targetPowerValT2[ALL_TARGET_HT40_20] =
4640 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4641 is2GHz) + ht40PowerIncForPdadc;
4642 targetPowerValT2[ALL_TARGET_HT40_21] =
4643 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4644 is2GHz) + ht40PowerIncForPdadc;
4645 targetPowerValT2[ALL_TARGET_HT40_22] =
4646 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4647 is2GHz) + ht40PowerIncForPdadc;
4648 targetPowerValT2[ALL_TARGET_HT40_23] =
4649 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4650 is2GHz) + ht40PowerIncForPdadc;
4653 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4654 struct ath9k_channel *chan,
4655 u8 *targetPowerValT2)
4657 bool is2GHz = IS_CHAN_2GHZ(chan);
4659 struct ath_common *common = ath9k_hw_common(ah);
4660 u16 freq = chan->channel;
4663 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4665 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4666 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4668 if (IS_CHAN_HT40(chan))
4669 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4672 for (i = 0; i < ar9300RateSize; i++) {
4673 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
4674 i, targetPowerValT2[i]);
4678 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4684 int *ptemperature, int *pvoltage)
4687 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4689 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4690 struct ath_common *common = ath9k_hw_common(ah);
4692 if (ichain >= AR9300_MAX_CHAINS) {
4693 ath_dbg(common, EEPROM,
4694 "Invalid chain index, must be less than %d\n",
4699 if (mode) { /* 5GHz */
4700 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4701 ath_dbg(common, EEPROM,
4702 "Invalid 5GHz cal pier index, must be less than %d\n",
4703 AR9300_NUM_5G_CAL_PIERS);
4706 pCalPier = &(eep->calFreqPier5G[ipier]);
4707 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4710 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4711 ath_dbg(common, EEPROM,
4712 "Invalid 2GHz cal pier index, must be less than %d\n",
4713 AR9300_NUM_2G_CAL_PIERS);
4717 pCalPier = &(eep->calFreqPier2G[ipier]);
4718 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4722 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4723 *pcorrection = pCalPierStruct->refPower;
4724 *ptemperature = pCalPierStruct->tempMeas;
4725 *pvoltage = pCalPierStruct->voltMeas;
4730 static void ar9003_hw_power_control_override(struct ath_hw *ah,
4733 int *voltage, int *temperature)
4735 int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
4736 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4737 int f[8], t[8], t1[3], t2[3], i;
4739 REG_RMW(ah, AR_PHY_TPC_11_B0,
4740 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4741 AR_PHY_TPC_OLPC_GAIN_DELTA);
4742 if (ah->caps.tx_chainmask & BIT(1))
4743 REG_RMW(ah, AR_PHY_TPC_11_B1,
4744 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4745 AR_PHY_TPC_OLPC_GAIN_DELTA);
4746 if (ah->caps.tx_chainmask & BIT(2))
4747 REG_RMW(ah, AR_PHY_TPC_11_B2,
4748 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4749 AR_PHY_TPC_OLPC_GAIN_DELTA);
4751 /* enable open loop power control on chip */
4752 REG_RMW(ah, AR_PHY_TPC_6_B0,
4753 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4754 AR_PHY_TPC_6_ERROR_EST_MODE);
4755 if (ah->caps.tx_chainmask & BIT(1))
4756 REG_RMW(ah, AR_PHY_TPC_6_B1,
4757 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4758 AR_PHY_TPC_6_ERROR_EST_MODE);
4759 if (ah->caps.tx_chainmask & BIT(2))
4760 REG_RMW(ah, AR_PHY_TPC_6_B2,
4761 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4762 AR_PHY_TPC_6_ERROR_EST_MODE);
4765 * enable temperature compensation
4766 * Need to use register names
4768 if (frequency < 4000) {
4769 temp_slope = eep->modalHeader2G.tempSlope;
4771 if (AR_SREV_9550(ah)) {
4772 t[0] = eep->base_ext1.tempslopextension[2];
4773 t1[0] = eep->base_ext1.tempslopextension[3];
4774 t2[0] = eep->base_ext1.tempslopextension[4];
4777 t[1] = eep->modalHeader5G.tempSlope;
4778 t1[1] = eep->base_ext1.tempslopextension[0];
4779 t2[1] = eep->base_ext1.tempslopextension[1];
4782 t[2] = eep->base_ext1.tempslopextension[5];
4783 t1[2] = eep->base_ext1.tempslopextension[6];
4784 t2[2] = eep->base_ext1.tempslopextension[7];
4787 temp_slope = ar9003_hw_power_interpolate(frequency,
4789 temp_slope1 = ar9003_hw_power_interpolate(frequency,
4791 temp_slope2 = ar9003_hw_power_interpolate(frequency,
4797 if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4798 for (i = 0; i < 8; i++) {
4799 t[i] = eep->base_ext1.tempslopextension[i];
4800 f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4802 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4804 } else if (eep->base_ext2.tempSlopeLow != 0) {
4805 t[0] = eep->base_ext2.tempSlopeLow;
4807 t[1] = eep->modalHeader5G.tempSlope;
4809 t[2] = eep->base_ext2.tempSlopeHigh;
4811 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4814 temp_slope = eep->modalHeader5G.tempSlope;
4819 if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
4820 u8 txmask = (eep->baseEepHeader.txrxMask & 0xf0) >> 4;
4823 * AR955x has tempSlope register for each chain.
4824 * Check whether temp_compensation feature is enabled or not.
4826 if (eep->baseEepHeader.featureEnable & 0x1) {
4827 if (frequency < 4000) {
4828 if (txmask & BIT(0))
4829 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4830 AR_PHY_TPC_19_ALPHA_THERM,
4831 eep->base_ext2.tempSlopeLow);
4832 if (txmask & BIT(1))
4833 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4834 AR_PHY_TPC_19_ALPHA_THERM,
4836 if (txmask & BIT(2))
4837 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4838 AR_PHY_TPC_19_ALPHA_THERM,
4839 eep->base_ext2.tempSlopeHigh);
4841 if (txmask & BIT(0))
4842 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4843 AR_PHY_TPC_19_ALPHA_THERM,
4845 if (txmask & BIT(1))
4846 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4847 AR_PHY_TPC_19_ALPHA_THERM,
4849 if (txmask & BIT(2))
4850 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4851 AR_PHY_TPC_19_ALPHA_THERM,
4856 * If temp compensation is not enabled,
4857 * set all registers to 0.
4859 if (txmask & BIT(0))
4860 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4861 AR_PHY_TPC_19_ALPHA_THERM, 0);
4862 if (txmask & BIT(1))
4863 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4864 AR_PHY_TPC_19_ALPHA_THERM, 0);
4865 if (txmask & BIT(2))
4866 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4867 AR_PHY_TPC_19_ALPHA_THERM, 0);
4870 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4871 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4874 if (AR_SREV_9462_20_OR_LATER(ah))
4875 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4876 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4879 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4883 /* Apply the recorded correction values. */
4884 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4886 int ichain, ipier, npier;
4888 int lfrequency[AR9300_MAX_CHAINS],
4889 lcorrection[AR9300_MAX_CHAINS],
4890 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4891 int hfrequency[AR9300_MAX_CHAINS],
4892 hcorrection[AR9300_MAX_CHAINS],
4893 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4895 int correction[AR9300_MAX_CHAINS],
4896 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4897 int pfrequency, pcorrection, ptemperature, pvoltage;
4898 struct ath_common *common = ath9k_hw_common(ah);
4900 mode = (frequency >= 4000);
4902 npier = AR9300_NUM_5G_CAL_PIERS;
4904 npier = AR9300_NUM_2G_CAL_PIERS;
4906 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4907 lfrequency[ichain] = 0;
4908 hfrequency[ichain] = 100000;
4910 /* identify best lower and higher frequency calibration measurement */
4911 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4912 for (ipier = 0; ipier < npier; ipier++) {
4913 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4914 &pfrequency, &pcorrection,
4915 &ptemperature, &pvoltage)) {
4916 fdiff = frequency - pfrequency;
4919 * this measurement is higher than
4920 * our desired frequency
4923 if (hfrequency[ichain] <= 0 ||
4924 hfrequency[ichain] >= 100000 ||
4926 (frequency - hfrequency[ichain])) {
4929 * frequency measurement
4931 hfrequency[ichain] = pfrequency;
4932 hcorrection[ichain] =
4934 htemperature[ichain] =
4936 hvoltage[ichain] = pvoltage;
4940 if (lfrequency[ichain] <= 0
4942 (frequency - lfrequency[ichain])) {
4945 * frequency measurement
4947 lfrequency[ichain] = pfrequency;
4948 lcorrection[ichain] =
4950 ltemperature[ichain] =
4952 lvoltage[ichain] = pvoltage;
4960 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4961 ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
4962 ichain, frequency, lfrequency[ichain],
4963 lcorrection[ichain], hfrequency[ichain],
4964 hcorrection[ichain]);
4965 /* they're the same, so just pick one */
4966 if (hfrequency[ichain] == lfrequency[ichain]) {
4967 correction[ichain] = lcorrection[ichain];
4968 voltage[ichain] = lvoltage[ichain];
4969 temperature[ichain] = ltemperature[ichain];
4971 /* the low frequency is good */
4972 else if (frequency - lfrequency[ichain] < 1000) {
4973 /* so is the high frequency, interpolate */
4974 if (hfrequency[ichain] - frequency < 1000) {
4976 correction[ichain] = interpolate(frequency,
4979 lcorrection[ichain],
4980 hcorrection[ichain]);
4982 temperature[ichain] = interpolate(frequency,
4985 ltemperature[ichain],
4986 htemperature[ichain]);
4988 voltage[ichain] = interpolate(frequency,
4994 /* only low is good, use it */
4996 correction[ichain] = lcorrection[ichain];
4997 temperature[ichain] = ltemperature[ichain];
4998 voltage[ichain] = lvoltage[ichain];
5001 /* only high is good, use it */
5002 else if (hfrequency[ichain] - frequency < 1000) {
5003 correction[ichain] = hcorrection[ichain];
5004 temperature[ichain] = htemperature[ichain];
5005 voltage[ichain] = hvoltage[ichain];
5006 } else { /* nothing is good, presume 0???? */
5007 correction[ichain] = 0;
5008 temperature[ichain] = 0;
5009 voltage[ichain] = 0;
5013 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
5016 ath_dbg(common, EEPROM,
5017 "for frequency=%d, calibration correction = %d %d %d\n",
5018 frequency, correction[0], correction[1], correction[2]);
5023 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
5028 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5029 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5032 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
5034 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
5037 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
5043 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
5044 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
5046 u8 *ctl_freqbin = is2GHz ?
5047 &eep->ctl_freqbin_2G[idx][0] :
5048 &eep->ctl_freqbin_5G[idx][0];
5051 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
5052 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
5053 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
5055 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
5056 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
5057 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
5060 return MAX_RATE_POWER;
5064 * Find the maximum conformance test limit for the given channel and CTL info
5066 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
5067 u16 freq, int idx, bool is2GHz)
5069 u16 twiceMaxEdgePower = MAX_RATE_POWER;
5070 u8 *ctl_freqbin = is2GHz ?
5071 &eep->ctl_freqbin_2G[idx][0] :
5072 &eep->ctl_freqbin_5G[idx][0];
5073 u16 num_edges = is2GHz ?
5074 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
5077 /* Get the edge power */
5079 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
5082 * If there's an exact channel match or an inband flag set
5083 * on the lower channel use the given rdEdgePower
5085 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
5087 ar9003_hw_get_direct_edge_power(eep, idx,
5090 } else if ((edge > 0) &&
5091 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
5094 ar9003_hw_get_indirect_edge_power(eep, idx,
5098 * Leave loop - no more affecting edges possible in
5099 * this monotonic increasing list
5105 if (is2GHz && !twiceMaxEdgePower)
5106 twiceMaxEdgePower = 60;
5108 return twiceMaxEdgePower;
5111 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
5112 struct ath9k_channel *chan,
5113 u8 *pPwrArray, u16 cfgCtl,
5114 u8 antenna_reduction,
5117 struct ath_common *common = ath9k_hw_common(ah);
5118 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
5119 u16 twiceMaxEdgePower;
5121 u16 scaledPower = 0, minCtlPower;
5122 static const u16 ctlModesFor11a[] = {
5123 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
5125 static const u16 ctlModesFor11g[] = {
5126 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
5127 CTL_11G_EXT, CTL_2GHT40
5130 const u16 *pCtlMode;
5132 struct chan_centers centers;
5135 u16 twiceMinEdgePower;
5136 bool is2ghz = IS_CHAN_2GHZ(chan);
5138 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5139 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
5143 /* Setup for CTL modes */
5144 /* CTL_11B, CTL_11G, CTL_2GHT20 */
5146 ARRAY_SIZE(ctlModesFor11g) -
5147 SUB_NUM_CTL_MODES_AT_2G_40;
5148 pCtlMode = ctlModesFor11g;
5149 if (IS_CHAN_HT40(chan))
5151 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
5153 /* Setup for CTL modes */
5154 /* CTL_11A, CTL_5GHT20 */
5155 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
5156 SUB_NUM_CTL_MODES_AT_5G_40;
5157 pCtlMode = ctlModesFor11a;
5158 if (IS_CHAN_HT40(chan))
5160 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
5164 * For MIMO, need to apply regulatory caps individually across
5165 * dynamically running modes: CCK, OFDM, HT20, HT40
5167 * The outer loop walks through each possible applicable runtime mode.
5168 * The inner loop walks through each ctlIndex entry in EEPROM.
5169 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
5171 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
5172 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
5173 (pCtlMode[ctlMode] == CTL_2GHT40);
5175 freq = centers.synth_center;
5176 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
5177 freq = centers.ext_center;
5179 freq = centers.ctl_center;
5181 ath_dbg(common, REGULATORY,
5182 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
5183 ctlMode, numCtlModes, isHt40CtlMode,
5184 (pCtlMode[ctlMode] & EXT_ADDITIVE));
5186 /* walk through each CTL index stored in EEPROM */
5188 ctlIndex = pEepData->ctlIndex_2G;
5189 ctlNum = AR9300_NUM_CTLS_2G;
5191 ctlIndex = pEepData->ctlIndex_5G;
5192 ctlNum = AR9300_NUM_CTLS_5G;
5195 twiceMaxEdgePower = MAX_RATE_POWER;
5196 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
5197 ath_dbg(common, REGULATORY,
5198 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
5199 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
5203 * compare test group from regulatory
5204 * channel list with test mode from pCtlMode
5207 if ((((cfgCtl & ~CTL_MODE_M) |
5208 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5210 (((cfgCtl & ~CTL_MODE_M) |
5211 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5212 ((ctlIndex[i] & CTL_MODE_M) |
5215 ar9003_hw_get_max_edge_power(pEepData,
5219 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
5221 * Find the minimum of all CTL
5222 * edge powers that apply to
5226 min(twiceMaxEdgePower,
5230 twiceMaxEdgePower = twiceMinEdgePower;
5236 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
5238 ath_dbg(common, REGULATORY,
5239 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
5240 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
5241 scaledPower, minCtlPower);
5243 /* Apply ctl mode to correct target power set */
5244 switch (pCtlMode[ctlMode]) {
5246 for (i = ALL_TARGET_LEGACY_1L_5L;
5247 i <= ALL_TARGET_LEGACY_11S; i++)
5248 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5253 for (i = ALL_TARGET_LEGACY_6_24;
5254 i <= ALL_TARGET_LEGACY_54; i++)
5255 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5260 for (i = ALL_TARGET_HT20_0_8_16;
5261 i <= ALL_TARGET_HT20_23; i++) {
5262 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5264 if (ath9k_hw_mci_is_enabled(ah))
5266 (u8)min((u16)pPwrArray[i],
5267 ar9003_mci_get_max_txpower(ah,
5268 pCtlMode[ctlMode]));
5273 for (i = ALL_TARGET_HT40_0_8_16;
5274 i <= ALL_TARGET_HT40_23; i++) {
5275 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5277 if (ath9k_hw_mci_is_enabled(ah))
5279 (u8)min((u16)pPwrArray[i],
5280 ar9003_mci_get_max_txpower(ah,
5281 pCtlMode[ctlMode]));
5287 } /* end ctl mode checking */
5290 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5292 u8 mod_idx = mcs_idx % 8;
5295 return mod_idx ? (base_pwridx + 1) : base_pwridx;
5297 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5300 static void ar9003_paprd_set_txpower(struct ath_hw *ah,
5301 struct ath9k_channel *chan,
5302 u8 *targetPowerValT2)
5306 if (!ar9003_is_paprd_enabled(ah))
5309 if (IS_CHAN_HT40(chan))
5310 i = ALL_TARGET_HT40_7;
5312 i = ALL_TARGET_HT20_7;
5314 if (IS_CHAN_2GHZ(chan)) {
5315 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) &&
5316 !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) {
5317 if (IS_CHAN_HT40(chan))
5318 i = ALL_TARGET_HT40_0_8_16;
5320 i = ALL_TARGET_HT20_0_8_16;
5324 ah->paprd_target_power = targetPowerValT2[i];
5327 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5328 struct ath9k_channel *chan, u16 cfgCtl,
5329 u8 twiceAntennaReduction,
5330 u8 powerLimit, bool test)
5332 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5333 struct ath_common *common = ath9k_hw_common(ah);
5334 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5335 struct ar9300_modal_eep_header *modal_hdr;
5336 u8 targetPowerValT2[ar9300RateSize];
5337 u8 target_power_val_t2_eep[ar9300RateSize];
5338 u8 targetPowerValT2_tpc[ar9300RateSize];
5339 unsigned int i = 0, paprd_scale_factor = 0;
5340 u8 pwr_idx, min_pwridx = 0;
5342 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5345 * Get target powers from EEPROM - our baseline for TX Power
5347 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5349 if (ar9003_is_paprd_enabled(ah)) {
5350 if (IS_CHAN_2GHZ(chan))
5351 modal_hdr = &eep->modalHeader2G;
5353 modal_hdr = &eep->modalHeader5G;
5355 ah->paprd_ratemask =
5356 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5357 AR9300_PAPRD_RATE_MASK;
5359 ah->paprd_ratemask_ht40 =
5360 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5361 AR9300_PAPRD_RATE_MASK;
5363 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5364 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5365 ALL_TARGET_HT20_0_8_16;
5367 if (!ah->paprd_table_write_done) {
5368 memcpy(target_power_val_t2_eep, targetPowerValT2,
5369 sizeof(targetPowerValT2));
5370 for (i = 0; i < 24; i++) {
5371 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5372 if (ah->paprd_ratemask & (1 << i)) {
5373 if (targetPowerValT2[pwr_idx] &&
5374 targetPowerValT2[pwr_idx] ==
5375 target_power_val_t2_eep[pwr_idx])
5376 targetPowerValT2[pwr_idx] -=
5381 memcpy(target_power_val_t2_eep, targetPowerValT2,
5382 sizeof(targetPowerValT2));
5385 ar9003_hw_set_power_per_rate_table(ah, chan,
5386 targetPowerValT2, cfgCtl,
5387 twiceAntennaReduction,
5390 memcpy(targetPowerValT2_tpc, targetPowerValT2,
5391 sizeof(targetPowerValT2));
5393 if (ar9003_is_paprd_enabled(ah)) {
5394 for (i = 0; i < ar9300RateSize; i++) {
5395 if ((ah->paprd_ratemask & (1 << i)) &&
5396 (abs(targetPowerValT2[i] -
5397 target_power_val_t2_eep[i]) >
5398 paprd_scale_factor)) {
5399 ah->paprd_ratemask &= ~(1 << i);
5400 ath_dbg(common, EEPROM,
5401 "paprd disabled for mcs %d\n", i);
5406 regulatory->max_power_level = 0;
5407 for (i = 0; i < ar9300RateSize; i++) {
5408 if (targetPowerValT2[i] > regulatory->max_power_level)
5409 regulatory->max_power_level = targetPowerValT2[i];
5412 ath9k_hw_update_regulatory_maxpower(ah);
5417 for (i = 0; i < ar9300RateSize; i++) {
5418 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
5419 i, targetPowerValT2[i]);
5422 /* Write target power array to registers */
5423 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5424 ar9003_hw_calibration_apply(ah, chan->channel);
5425 ar9003_paprd_set_txpower(ah, chan, targetPowerValT2);
5427 ar9003_hw_selfgen_tpc_txpower(ah, chan, targetPowerValT2);
5429 /* TPC initializations */
5430 if (ah->tpc_enabled) {
5433 ar9003_hw_init_rate_txpower(ah, targetPowerValT2_tpc, chan);
5436 REG_WRITE(ah, AR_PHY_PWRTX_MAX,
5437 AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
5438 /* Disable per chain power reduction */
5439 val = REG_READ(ah, AR_PHY_POWER_TX_SUB);
5440 if (AR_SREV_9340(ah))
5441 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5444 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
5448 REG_WRITE(ah, AR_PHY_PWRTX_MAX, 0);
5452 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5458 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5460 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5462 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5465 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5467 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5469 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5472 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5474 return ar9003_modal_header(ah, is2ghz)->spurChans;
5477 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5478 struct ath9k_channel *chan)
5480 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5482 if (IS_CHAN_2GHZ(chan))
5483 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5484 AR9300_PAPRD_SCALE_1);
5486 if (chan->channel >= 5700)
5487 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5488 AR9300_PAPRD_SCALE_1);
5489 else if (chan->channel >= 5400)
5490 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5491 AR9300_PAPRD_SCALE_2);
5493 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5494 AR9300_PAPRD_SCALE_1);
5498 const struct eeprom_ops eep_ar9300_ops = {
5499 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5500 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5501 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5502 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5503 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5504 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5505 .set_board_values = ath9k_hw_ar9300_set_board_values,
5506 .set_addac = ath9k_hw_ar9300_set_addac,
5507 .set_txpower = ath9k_hw_ar9300_set_txpower,
5508 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel