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) __constant_cpu_to_le16(x)
27 #define LE32(x) __constant_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),
134 .xlna_bias_strength = 0,
140 .ant_div_control = 0,
142 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
149 /* ar9300_cal_data_per_freq_op_loop 2g */
151 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
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} },
155 .calTarget_freqbin_Cck = {
159 .calTarget_freqbin_2G = {
164 .calTarget_freqbin_2GHT20 = {
169 .calTarget_freqbin_2GHT40 = {
174 .calTargetPowerCck = {
175 /* 1L-5L,5S,11L,11S */
176 { {36, 36, 36, 36} },
177 { {36, 36, 36, 36} },
179 .calTargetPower2G = {
181 { {32, 32, 28, 24} },
182 { {32, 32, 28, 24} },
183 { {32, 32, 28, 24} },
185 .calTargetPower2GHT20 = {
186 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
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} },
190 .calTargetPower2GHT40 = {
191 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
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} },
196 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
197 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
227 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
228 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
229 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
230 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
234 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
235 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
236 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
241 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
242 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
248 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
249 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
250 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
251 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
255 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
256 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
257 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
261 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
262 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
263 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
268 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
269 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
270 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
275 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
276 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
277 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
278 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
282 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
283 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
284 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
286 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
287 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
288 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
290 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
291 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
292 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
294 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
295 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
296 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
299 /* 4 idle,t1,t2,b (4 bits per setting) */
300 .antCtrlCommon = LE32(0x110),
301 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
302 .antCtrlCommon2 = LE32(0x22222),
303 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
305 LE16(0x000), LE16(0x000), LE16(0x000),
307 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
308 .xatten1DB = {0, 0, 0},
311 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
312 * for merlin (0xa20c/b20c 16:12
314 .xatten1Margin = {0, 0, 0},
317 /* spurChans spur channels in usual fbin coding format */
318 .spurChans = {0, 0, 0, 0, 0},
319 /* noiseFloorThreshCh Check if the register is per chain */
320 .noiseFloorThreshCh = {-1, 0, 0},
321 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
324 .txFrameToDataStart = 0x0e,
325 .txFrameToPaOn = 0x0e,
326 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
328 .switchSettling = 0x2d,
329 .adcDesiredSize = -30,
332 .txFrameToXpaOn = 0xe,
334 .papdRateMaskHt20 = LE32(0x0c80c080),
335 .papdRateMaskHt40 = LE32(0x0080c080),
336 .xlna_bias_strength = 0,
344 .xatten1DBLow = {0, 0, 0},
345 .xatten1MarginLow = {0, 0, 0},
346 .xatten1DBHigh = {0, 0, 0},
347 .xatten1MarginHigh = {0, 0, 0}
392 .calTarget_freqbin_5G = {
402 .calTarget_freqbin_5GHT20 = {
412 .calTarget_freqbin_5GHT40 = {
422 .calTargetPower5G = {
424 { {20, 20, 20, 10} },
425 { {20, 20, 20, 10} },
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} },
433 .calTargetPower5GHT20 = {
435 * 0_8_16,1-3_9-11_17-19,
436 * 4,5,6,7,12,13,14,15,20,21,22,23
438 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
439 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
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} },
447 .calTargetPower5GHT40 = {
449 * 0_8_16,1-3_9-11_17-19,
450 * 4,5,6,7,12,13,14,15,20,21,22,23
452 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
453 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
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} },
462 0x10, 0x16, 0x18, 0x40, 0x46,
463 0x48, 0x30, 0x36, 0x38
467 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
468 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
469 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
470 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
471 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
472 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
473 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
474 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
477 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
478 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
479 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
480 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
481 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
482 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
483 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
484 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
488 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
489 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
490 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
491 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
492 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
493 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
494 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
495 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
499 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
500 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
501 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
502 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
503 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
504 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
505 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
506 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
510 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
511 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
512 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
513 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
514 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
515 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
516 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
517 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
521 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
522 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
523 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
524 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
525 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
526 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
527 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
528 /* Data[5].ctlEdges[7].bChannel */ 0xFF
532 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
533 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
534 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
535 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
536 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
537 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
538 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
539 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
543 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
544 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
545 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
546 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
547 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
548 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
549 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
550 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
554 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
555 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
556 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
557 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
558 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
559 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
560 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
561 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
567 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
568 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
573 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
574 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
579 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
580 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
585 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
586 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
591 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
592 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
597 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
598 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
603 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
604 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
609 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
610 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
615 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
616 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
622 static const struct ar9300_eeprom ar9300_x113 = {
624 .templateVersion = 6,
625 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
626 .custData = {"x113-023-f0000"},
628 .regDmn = { LE16(0), LE16(0x1f) },
629 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
631 .opFlags = AR5416_OPFLAGS_11A,
635 .blueToothOptions = 0,
637 .deviceType = 5, /* takes lower byte in eeprom location */
638 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
639 .params_for_tuning_caps = {0, 0},
640 .featureEnable = 0x0d,
642 * bit0 - enable tx temp comp - disabled
643 * bit1 - enable tx volt comp - disabled
644 * bit2 - enable fastClock - enabled
645 * bit3 - enable doubling - enabled
646 * bit4 - enable internal regulator - disabled
647 * bit5 - enable pa predistortion - disabled
649 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
650 .eepromWriteEnableGpio = 6,
651 .wlanDisableGpio = 0,
653 .rxBandSelectGpio = 0xff,
658 /* ar9300_modal_eep_header 2g */
659 /* 4 idle,t1,t2,b(4 bits per setting) */
660 .antCtrlCommon = LE32(0x110),
661 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
662 .antCtrlCommon2 = LE32(0x44444),
665 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
666 * rx1, rx12, b (2 bits each)
668 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
671 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
672 * for ar9280 (0xa20c/b20c 5:0)
674 .xatten1DB = {0, 0, 0},
677 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
678 * for ar9280 (0xa20c/b20c 16:12
680 .xatten1Margin = {0, 0, 0},
685 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
686 * channels in usual fbin coding format
688 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
691 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
692 * if the register is per chain
694 .noiseFloorThreshCh = {-1, 0, 0},
695 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
698 .txFrameToDataStart = 0x0e,
699 .txFrameToPaOn = 0x0e,
700 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
702 .switchSettling = 0x2c,
703 .adcDesiredSize = -30,
706 .txFrameToXpaOn = 0xe,
708 .papdRateMaskHt20 = LE32(0x0c80c080),
709 .papdRateMaskHt40 = LE32(0x0080c080),
710 .xlna_bias_strength = 0,
716 .ant_div_control = 0,
718 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
725 /* ar9300_cal_data_per_freq_op_loop 2g */
727 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
728 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
729 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
731 .calTarget_freqbin_Cck = {
735 .calTarget_freqbin_2G = {
740 .calTarget_freqbin_2GHT20 = {
745 .calTarget_freqbin_2GHT40 = {
750 .calTargetPowerCck = {
751 /* 1L-5L,5S,11L,11S */
752 { {34, 34, 34, 34} },
753 { {34, 34, 34, 34} },
755 .calTargetPower2G = {
757 { {34, 34, 32, 32} },
758 { {34, 34, 32, 32} },
759 { {34, 34, 32, 32} },
761 .calTargetPower2GHT20 = {
762 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
763 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
764 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
766 .calTargetPower2GHT40 = {
767 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
768 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
769 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
772 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
773 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
803 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
804 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
805 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
806 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
810 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
811 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
812 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
817 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
818 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
824 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
825 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
826 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
827 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
831 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
832 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
833 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
837 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
838 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
839 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
844 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
845 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
846 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
851 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
852 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
853 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
854 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
858 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
859 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
860 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
862 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
863 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
864 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
866 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
867 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
868 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), 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, 1), CTL(60, 1) } },
872 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
875 /* 4 idle,t1,t2,b (4 bits per setting) */
876 .antCtrlCommon = LE32(0x220),
877 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
878 .antCtrlCommon2 = LE32(0x11111),
879 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
881 LE16(0x150), LE16(0x150), LE16(0x150),
883 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
884 .xatten1DB = {0, 0, 0},
887 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
888 * for merlin (0xa20c/b20c 16:12
890 .xatten1Margin = {0, 0, 0},
893 /* spurChans spur channels in usual fbin coding format */
894 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
895 /* noiseFloorThreshCh Check if the register is per chain */
896 .noiseFloorThreshCh = {-1, 0, 0},
897 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
900 .txFrameToDataStart = 0x0e,
901 .txFrameToPaOn = 0x0e,
902 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
904 .switchSettling = 0x2d,
905 .adcDesiredSize = -30,
908 .txFrameToXpaOn = 0xe,
910 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
911 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
912 .xlna_bias_strength = 0,
919 .tempSlopeHigh = 105,
920 .xatten1DBLow = {0, 0, 0},
921 .xatten1MarginLow = {0, 0, 0},
922 .xatten1DBHigh = {0, 0, 0},
923 .xatten1MarginHigh = {0, 0, 0}
968 .calTarget_freqbin_5G = {
978 .calTarget_freqbin_5GHT20 = {
988 .calTarget_freqbin_5GHT40 = {
998 .calTargetPower5G = {
1000 { {42, 40, 40, 34} },
1001 { {42, 40, 40, 34} },
1002 { {42, 40, 40, 34} },
1003 { {42, 40, 40, 34} },
1004 { {42, 40, 40, 34} },
1005 { {42, 40, 40, 34} },
1006 { {42, 40, 40, 34} },
1007 { {42, 40, 40, 34} },
1009 .calTargetPower5GHT20 = {
1011 * 0_8_16,1-3_9-11_17-19,
1012 * 4,5,6,7,12,13,14,15,20,21,22,23
1014 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1015 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1016 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1017 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
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 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1021 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1023 .calTargetPower5GHT40 = {
1025 * 0_8_16,1-3_9-11_17-19,
1026 * 4,5,6,7,12,13,14,15,20,21,22,23
1028 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1029 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1030 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1031 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
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 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1035 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1038 0x10, 0x16, 0x18, 0x40, 0x46,
1039 0x48, 0x30, 0x36, 0x38
1043 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1044 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1045 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1046 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1047 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1048 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1049 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1050 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1053 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1054 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1055 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1056 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1057 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1058 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1059 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1060 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1064 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1065 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1066 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1067 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1068 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1069 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1070 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1071 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1075 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1076 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1077 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1078 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1079 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1080 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1081 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1082 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1086 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1087 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1088 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1089 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1090 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1091 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1092 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1093 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1097 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1098 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1099 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1100 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1101 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1102 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1103 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1104 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1108 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1109 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1110 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1111 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1112 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1113 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1114 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1115 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1119 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1120 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1121 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1122 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1123 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1124 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1125 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1126 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1130 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1131 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1132 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1133 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1134 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1135 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1136 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1137 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1140 .ctlPowerData_5G = {
1143 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1144 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1149 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1150 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1155 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1156 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1161 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1162 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1167 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1168 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1173 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1174 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1179 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1180 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1185 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1186 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1191 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1192 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1199 static const struct ar9300_eeprom ar9300_h112 = {
1201 .templateVersion = 3,
1202 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1203 .custData = {"h112-241-f0000"},
1205 .regDmn = { LE16(0), LE16(0x1f) },
1206 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1208 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1212 .blueToothOptions = 0,
1214 .deviceType = 5, /* takes lower byte in eeprom location */
1215 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1216 .params_for_tuning_caps = {0, 0},
1217 .featureEnable = 0x0d,
1219 * bit0 - enable tx temp comp - disabled
1220 * bit1 - enable tx volt comp - disabled
1221 * bit2 - enable fastClock - enabled
1222 * bit3 - enable doubling - enabled
1223 * bit4 - enable internal regulator - disabled
1224 * bit5 - enable pa predistortion - disabled
1226 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1227 .eepromWriteEnableGpio = 6,
1228 .wlanDisableGpio = 0,
1230 .rxBandSelectGpio = 0xff,
1235 /* ar9300_modal_eep_header 2g */
1236 /* 4 idle,t1,t2,b(4 bits per setting) */
1237 .antCtrlCommon = LE32(0x110),
1238 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1239 .antCtrlCommon2 = LE32(0x44444),
1242 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1243 * rx1, rx12, b (2 bits each)
1245 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1248 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1249 * for ar9280 (0xa20c/b20c 5:0)
1251 .xatten1DB = {0, 0, 0},
1254 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1255 * for ar9280 (0xa20c/b20c 16:12
1257 .xatten1Margin = {0, 0, 0},
1262 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1263 * channels in usual fbin coding format
1265 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1268 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1269 * if the register is per chain
1271 .noiseFloorThreshCh = {-1, 0, 0},
1272 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1275 .txFrameToDataStart = 0x0e,
1276 .txFrameToPaOn = 0x0e,
1277 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1279 .switchSettling = 0x2c,
1280 .adcDesiredSize = -30,
1283 .txFrameToXpaOn = 0xe,
1285 .papdRateMaskHt20 = LE32(0x0c80c080),
1286 .papdRateMaskHt40 = LE32(0x0080c080),
1287 .xlna_bias_strength = 0,
1289 0, 0, 0, 0, 0, 0, 0,
1293 .ant_div_control = 0,
1294 .future = {0, 0, 0},
1295 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1302 /* ar9300_cal_data_per_freq_op_loop 2g */
1304 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1305 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1306 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1308 .calTarget_freqbin_Cck = {
1312 .calTarget_freqbin_2G = {
1317 .calTarget_freqbin_2GHT20 = {
1322 .calTarget_freqbin_2GHT40 = {
1327 .calTargetPowerCck = {
1328 /* 1L-5L,5S,11L,11S */
1329 { {34, 34, 34, 34} },
1330 { {34, 34, 34, 34} },
1332 .calTargetPower2G = {
1334 { {34, 34, 32, 32} },
1335 { {34, 34, 32, 32} },
1336 { {34, 34, 32, 32} },
1338 .calTargetPower2GHT20 = {
1339 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1340 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1341 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1343 .calTargetPower2GHT40 = {
1344 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1345 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1346 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1349 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1350 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1380 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1381 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1382 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1383 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1387 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1388 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1389 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1394 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1395 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1401 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1402 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1403 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1404 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1408 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1409 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1410 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1414 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1415 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1416 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1421 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1422 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1423 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1428 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1429 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1430 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1431 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1434 .ctlPowerData_2G = {
1435 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1436 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1437 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1439 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
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) } },
1443 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1444 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1445 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1447 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1448 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1449 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1452 /* 4 idle,t1,t2,b (4 bits per setting) */
1453 .antCtrlCommon = LE32(0x220),
1454 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1455 .antCtrlCommon2 = LE32(0x44444),
1456 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1458 LE16(0x150), LE16(0x150), LE16(0x150),
1460 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1461 .xatten1DB = {0, 0, 0},
1464 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1465 * for merlin (0xa20c/b20c 16:12
1467 .xatten1Margin = {0, 0, 0},
1470 /* spurChans spur channels in usual fbin coding format */
1471 .spurChans = {0, 0, 0, 0, 0},
1472 /* noiseFloorThreshCh Check if the register is per chain */
1473 .noiseFloorThreshCh = {-1, 0, 0},
1474 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1477 .txFrameToDataStart = 0x0e,
1478 .txFrameToPaOn = 0x0e,
1479 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1481 .switchSettling = 0x2d,
1482 .adcDesiredSize = -30,
1485 .txFrameToXpaOn = 0xe,
1487 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1488 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1489 .xlna_bias_strength = 0,
1491 0, 0, 0, 0, 0, 0, 0,
1496 .tempSlopeHigh = 50,
1497 .xatten1DBLow = {0, 0, 0},
1498 .xatten1MarginLow = {0, 0, 0},
1499 .xatten1DBHigh = {0, 0, 0},
1500 .xatten1MarginHigh = {0, 0, 0}
1545 .calTarget_freqbin_5G = {
1555 .calTarget_freqbin_5GHT20 = {
1565 .calTarget_freqbin_5GHT40 = {
1575 .calTargetPower5G = {
1577 { {30, 30, 28, 24} },
1578 { {30, 30, 28, 24} },
1579 { {30, 30, 28, 24} },
1580 { {30, 30, 28, 24} },
1581 { {30, 30, 28, 24} },
1582 { {30, 30, 28, 24} },
1583 { {30, 30, 28, 24} },
1584 { {30, 30, 28, 24} },
1586 .calTargetPower5GHT20 = {
1588 * 0_8_16,1-3_9-11_17-19,
1589 * 4,5,6,7,12,13,14,15,20,21,22,23
1591 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1592 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1593 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1594 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1595 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1596 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1597 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1598 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1600 .calTargetPower5GHT40 = {
1602 * 0_8_16,1-3_9-11_17-19,
1603 * 4,5,6,7,12,13,14,15,20,21,22,23
1605 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1606 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1607 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1608 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1609 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1610 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1611 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1612 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1615 0x10, 0x16, 0x18, 0x40, 0x46,
1616 0x48, 0x30, 0x36, 0x38
1620 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1621 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1622 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1623 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1624 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1625 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1626 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1627 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1630 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1631 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1632 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1633 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1634 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1635 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1636 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1637 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1641 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1642 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1643 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1644 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1645 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1646 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1647 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1648 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1652 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1653 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1654 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1655 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1656 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1657 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1658 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1659 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1663 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1664 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1665 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1666 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1667 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1668 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1669 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1670 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1674 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1675 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1676 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1677 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1678 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1679 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1680 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1681 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1685 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1686 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1687 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1688 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1689 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1690 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1691 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1692 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1696 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1697 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1698 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1699 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1700 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1701 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1702 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1703 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1707 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1708 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1709 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1710 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1711 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1712 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1713 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1714 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1717 .ctlPowerData_5G = {
1720 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1721 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
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, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1733 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1738 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1739 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1744 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1745 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1750 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1751 CTL(60, 1), 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, 1), CTL(60, 1), CTL(60, 1),
1762 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1763 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1768 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1769 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1776 static const struct ar9300_eeprom ar9300_x112 = {
1778 .templateVersion = 5,
1779 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1780 .custData = {"x112-041-f0000"},
1782 .regDmn = { LE16(0), LE16(0x1f) },
1783 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1785 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1789 .blueToothOptions = 0,
1791 .deviceType = 5, /* takes lower byte in eeprom location */
1792 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1793 .params_for_tuning_caps = {0, 0},
1794 .featureEnable = 0x0d,
1796 * bit0 - enable tx temp comp - disabled
1797 * bit1 - enable tx volt comp - disabled
1798 * bit2 - enable fastclock - enabled
1799 * bit3 - enable doubling - enabled
1800 * bit4 - enable internal regulator - disabled
1801 * bit5 - enable pa predistortion - disabled
1803 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1804 .eepromWriteEnableGpio = 6,
1805 .wlanDisableGpio = 0,
1807 .rxBandSelectGpio = 0xff,
1812 /* ar9300_modal_eep_header 2g */
1813 /* 4 idle,t1,t2,b(4 bits per setting) */
1814 .antCtrlCommon = LE32(0x110),
1815 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1816 .antCtrlCommon2 = LE32(0x22222),
1819 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1820 * rx1, rx12, b (2 bits each)
1822 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1825 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1826 * for ar9280 (0xa20c/b20c 5:0)
1828 .xatten1DB = {0x1b, 0x1b, 0x1b},
1831 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1832 * for ar9280 (0xa20c/b20c 16:12
1834 .xatten1Margin = {0x15, 0x15, 0x15},
1839 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1840 * channels in usual fbin coding format
1842 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1845 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1846 * if the register is per chain
1848 .noiseFloorThreshCh = {-1, 0, 0},
1849 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1852 .txFrameToDataStart = 0x0e,
1853 .txFrameToPaOn = 0x0e,
1854 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1856 .switchSettling = 0x2c,
1857 .adcDesiredSize = -30,
1860 .txFrameToXpaOn = 0xe,
1862 .papdRateMaskHt20 = LE32(0x0c80c080),
1863 .papdRateMaskHt40 = LE32(0x0080c080),
1864 .xlna_bias_strength = 0,
1866 0, 0, 0, 0, 0, 0, 0,
1870 .ant_div_control = 0,
1871 .future = {0, 0, 0},
1872 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1879 /* ar9300_cal_data_per_freq_op_loop 2g */
1881 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1882 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1883 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1885 .calTarget_freqbin_Cck = {
1889 .calTarget_freqbin_2G = {
1894 .calTarget_freqbin_2GHT20 = {
1899 .calTarget_freqbin_2GHT40 = {
1904 .calTargetPowerCck = {
1905 /* 1L-5L,5S,11L,11s */
1906 { {38, 38, 38, 38} },
1907 { {38, 38, 38, 38} },
1909 .calTargetPower2G = {
1911 { {38, 38, 36, 34} },
1912 { {38, 38, 36, 34} },
1913 { {38, 38, 34, 32} },
1915 .calTargetPower2GHT20 = {
1916 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1917 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1918 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1920 .calTargetPower2GHT40 = {
1921 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1922 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1923 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1926 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1927 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1957 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1958 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1959 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1960 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1964 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1965 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1966 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1971 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1972 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1978 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
1979 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
1980 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
1981 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
1985 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1986 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1987 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1991 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1992 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1993 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1998 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1999 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2000 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2005 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2006 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2007 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2008 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2011 .ctlPowerData_2G = {
2012 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2013 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2014 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2016 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2017 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2018 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2020 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2021 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2022 { { CTL(60, 0), CTL(60, 1), 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, 1), CTL(60, 1) } },
2026 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2029 /* 4 idle,t1,t2,b (4 bits per setting) */
2030 .antCtrlCommon = LE32(0x110),
2031 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2032 .antCtrlCommon2 = LE32(0x22222),
2033 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2035 LE16(0x0), LE16(0x0), LE16(0x0),
2037 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2038 .xatten1DB = {0x13, 0x19, 0x17},
2041 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2042 * for merlin (0xa20c/b20c 16:12
2044 .xatten1Margin = {0x19, 0x19, 0x19},
2047 /* spurChans spur channels in usual fbin coding format */
2048 .spurChans = {0, 0, 0, 0, 0},
2049 /* noiseFloorThreshch check if the register is per chain */
2050 .noiseFloorThreshCh = {-1, 0, 0},
2051 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2054 .txFrameToDataStart = 0x0e,
2055 .txFrameToPaOn = 0x0e,
2056 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2058 .switchSettling = 0x2d,
2059 .adcDesiredSize = -30,
2062 .txFrameToXpaOn = 0xe,
2064 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2065 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2066 .xlna_bias_strength = 0,
2068 0, 0, 0, 0, 0, 0, 0,
2073 .tempSlopeHigh = 105,
2074 .xatten1DBLow = {0x10, 0x14, 0x10},
2075 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2076 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2077 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2122 .calTarget_freqbin_5G = {
2132 .calTarget_freqbin_5GHT20 = {
2142 .calTarget_freqbin_5GHT40 = {
2152 .calTargetPower5G = {
2154 { {32, 32, 28, 26} },
2155 { {32, 32, 28, 26} },
2156 { {32, 32, 28, 26} },
2157 { {32, 32, 26, 24} },
2158 { {32, 32, 26, 24} },
2159 { {32, 32, 24, 22} },
2160 { {30, 30, 24, 22} },
2161 { {30, 30, 24, 22} },
2163 .calTargetPower5GHT20 = {
2165 * 0_8_16,1-3_9-11_17-19,
2166 * 4,5,6,7,12,13,14,15,20,21,22,23
2168 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2169 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2170 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2171 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2172 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2173 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2174 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2175 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2177 .calTargetPower5GHT40 = {
2179 * 0_8_16,1-3_9-11_17-19,
2180 * 4,5,6,7,12,13,14,15,20,21,22,23
2182 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2183 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2184 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2185 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2186 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2187 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2188 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2189 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2192 0x10, 0x16, 0x18, 0x40, 0x46,
2193 0x48, 0x30, 0x36, 0x38
2197 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2198 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2199 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2200 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2201 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2202 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2203 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2204 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2207 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2208 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2209 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2210 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2211 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2212 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2213 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2214 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2218 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2219 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2220 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2221 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2222 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2223 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2224 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2225 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2229 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2230 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2231 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2232 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2233 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2234 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2235 /* Data[3].ctledges[6].bchannel */ 0xFF,
2236 /* Data[3].ctledges[7].bchannel */ 0xFF,
2240 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2241 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2242 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2243 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2244 /* Data[4].ctledges[4].bchannel */ 0xFF,
2245 /* Data[4].ctledges[5].bchannel */ 0xFF,
2246 /* Data[4].ctledges[6].bchannel */ 0xFF,
2247 /* Data[4].ctledges[7].bchannel */ 0xFF,
2251 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2252 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2253 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2254 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2255 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2256 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2257 /* Data[5].ctledges[6].bchannel */ 0xFF,
2258 /* Data[5].ctledges[7].bchannel */ 0xFF
2262 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2263 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2264 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2265 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2266 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2267 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2268 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2269 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2273 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2274 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2275 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2276 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2277 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2278 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2279 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2280 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2284 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2285 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2286 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2287 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2288 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2289 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2290 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2291 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2294 .ctlPowerData_5G = {
2297 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2298 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2303 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2304 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2309 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2310 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2315 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2316 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2321 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2322 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2327 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2328 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2333 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2334 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2339 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2340 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2345 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2346 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2352 static const struct ar9300_eeprom ar9300_h116 = {
2354 .templateVersion = 4,
2355 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2356 .custData = {"h116-041-f0000"},
2358 .regDmn = { LE16(0), LE16(0x1f) },
2359 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2361 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2365 .blueToothOptions = 0,
2367 .deviceType = 5, /* takes lower byte in eeprom location */
2368 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2369 .params_for_tuning_caps = {0, 0},
2370 .featureEnable = 0x0d,
2372 * bit0 - enable tx temp comp - disabled
2373 * bit1 - enable tx volt comp - disabled
2374 * bit2 - enable fastClock - enabled
2375 * bit3 - enable doubling - enabled
2376 * bit4 - enable internal regulator - disabled
2377 * bit5 - enable pa predistortion - disabled
2379 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2380 .eepromWriteEnableGpio = 6,
2381 .wlanDisableGpio = 0,
2383 .rxBandSelectGpio = 0xff,
2388 /* ar9300_modal_eep_header 2g */
2389 /* 4 idle,t1,t2,b(4 bits per setting) */
2390 .antCtrlCommon = LE32(0x110),
2391 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2392 .antCtrlCommon2 = LE32(0x44444),
2395 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2396 * rx1, rx12, b (2 bits each)
2398 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2401 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2402 * for ar9280 (0xa20c/b20c 5:0)
2404 .xatten1DB = {0x1f, 0x1f, 0x1f},
2407 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2408 * for ar9280 (0xa20c/b20c 16:12
2410 .xatten1Margin = {0x12, 0x12, 0x12},
2415 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2416 * channels in usual fbin coding format
2418 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2421 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2422 * if the register is per chain
2424 .noiseFloorThreshCh = {-1, 0, 0},
2425 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2428 .txFrameToDataStart = 0x0e,
2429 .txFrameToPaOn = 0x0e,
2430 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2432 .switchSettling = 0x2c,
2433 .adcDesiredSize = -30,
2436 .txFrameToXpaOn = 0xe,
2438 .papdRateMaskHt20 = LE32(0x0c80C080),
2439 .papdRateMaskHt40 = LE32(0x0080C080),
2440 .xlna_bias_strength = 0,
2442 0, 0, 0, 0, 0, 0, 0,
2446 .ant_div_control = 0,
2447 .future = {0, 0, 0},
2448 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
2455 /* ar9300_cal_data_per_freq_op_loop 2g */
2457 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2458 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2459 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2461 .calTarget_freqbin_Cck = {
2465 .calTarget_freqbin_2G = {
2470 .calTarget_freqbin_2GHT20 = {
2475 .calTarget_freqbin_2GHT40 = {
2480 .calTargetPowerCck = {
2481 /* 1L-5L,5S,11L,11S */
2482 { {34, 34, 34, 34} },
2483 { {34, 34, 34, 34} },
2485 .calTargetPower2G = {
2487 { {34, 34, 32, 32} },
2488 { {34, 34, 32, 32} },
2489 { {34, 34, 32, 32} },
2491 .calTargetPower2GHT20 = {
2492 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2493 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2494 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2496 .calTargetPower2GHT40 = {
2497 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2498 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2499 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2502 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2503 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2533 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2534 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2535 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2536 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2540 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2541 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2542 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2547 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2548 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2554 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2555 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2556 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2557 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2561 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2562 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2563 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2567 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2568 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2569 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2574 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2575 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2576 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2581 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2582 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2583 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2584 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2587 .ctlPowerData_2G = {
2588 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2589 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2590 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2592 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2593 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2594 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2596 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
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) } },
2600 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2601 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2602 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2605 /* 4 idle,t1,t2,b (4 bits per setting) */
2606 .antCtrlCommon = LE32(0x220),
2607 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2608 .antCtrlCommon2 = LE32(0x44444),
2609 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2611 LE16(0x150), LE16(0x150), LE16(0x150),
2613 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2614 .xatten1DB = {0x19, 0x19, 0x19},
2617 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2618 * for merlin (0xa20c/b20c 16:12
2620 .xatten1Margin = {0x14, 0x14, 0x14},
2623 /* spurChans spur channels in usual fbin coding format */
2624 .spurChans = {0, 0, 0, 0, 0},
2625 /* noiseFloorThreshCh Check if the register is per chain */
2626 .noiseFloorThreshCh = {-1, 0, 0},
2627 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2630 .txFrameToDataStart = 0x0e,
2631 .txFrameToPaOn = 0x0e,
2632 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2634 .switchSettling = 0x2d,
2635 .adcDesiredSize = -30,
2638 .txFrameToXpaOn = 0xe,
2640 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2641 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2642 .xlna_bias_strength = 0,
2644 0, 0, 0, 0, 0, 0, 0,
2649 .tempSlopeHigh = 50,
2650 .xatten1DBLow = {0, 0, 0},
2651 .xatten1MarginLow = {0, 0, 0},
2652 .xatten1DBHigh = {0, 0, 0},
2653 .xatten1MarginHigh = {0, 0, 0}
2698 .calTarget_freqbin_5G = {
2708 .calTarget_freqbin_5GHT20 = {
2718 .calTarget_freqbin_5GHT40 = {
2728 .calTargetPower5G = {
2730 { {30, 30, 28, 24} },
2731 { {30, 30, 28, 24} },
2732 { {30, 30, 28, 24} },
2733 { {30, 30, 28, 24} },
2734 { {30, 30, 28, 24} },
2735 { {30, 30, 28, 24} },
2736 { {30, 30, 28, 24} },
2737 { {30, 30, 28, 24} },
2739 .calTargetPower5GHT20 = {
2741 * 0_8_16,1-3_9-11_17-19,
2742 * 4,5,6,7,12,13,14,15,20,21,22,23
2744 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2745 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2746 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2747 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2748 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2749 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2750 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2751 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2753 .calTargetPower5GHT40 = {
2755 * 0_8_16,1-3_9-11_17-19,
2756 * 4,5,6,7,12,13,14,15,20,21,22,23
2758 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2759 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2760 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2761 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2762 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2763 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2764 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2765 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2768 0x10, 0x16, 0x18, 0x40, 0x46,
2769 0x48, 0x30, 0x36, 0x38
2773 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2774 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2775 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2776 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2777 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2778 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2779 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2780 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2783 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2784 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2785 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2786 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2787 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2788 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2789 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2790 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2794 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2795 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2796 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2797 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2798 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2799 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2800 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2801 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2805 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2806 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2807 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2808 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2809 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2810 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2811 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2812 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2816 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2817 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2818 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2819 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2820 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2821 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2822 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2823 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2827 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2828 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2829 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2830 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2831 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2832 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2833 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2834 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2838 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2839 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2840 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2841 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2842 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2843 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2844 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2845 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2849 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2850 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2851 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2852 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2853 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2854 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2855 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2856 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2860 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2861 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2862 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2863 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2864 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2865 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2866 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2867 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2870 .ctlPowerData_5G = {
2873 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2874 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2879 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2880 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2885 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2886 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2891 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2892 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2897 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2898 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2903 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2904 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2909 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2910 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2915 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2916 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2921 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2922 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2929 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2937 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2939 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2942 for (it = 0; it < N_LOOP; it++)
2943 if (ar9300_eep_templates[it]->templateVersion == id)
2944 return ar9300_eep_templates[it];
2949 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2954 static int interpolate(int x, int xa, int xb, int ya, int yb)
2956 int bf, factor, plus;
2958 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2961 return ya + factor + plus;
2964 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2965 enum eeprom_param param)
2967 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2968 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
2972 return get_unaligned_be16(eep->macAddr);
2974 return get_unaligned_be16(eep->macAddr + 2);
2976 return get_unaligned_be16(eep->macAddr + 4);
2978 return le16_to_cpu(pBase->regDmn[0]);
2980 return pBase->deviceCap;
2982 return pBase->opCapFlags.opFlags;
2984 return pBase->rfSilent;
2986 return (pBase->txrxMask >> 4) & 0xf;
2988 return pBase->txrxMask & 0xf;
2990 return !!(pBase->featureEnable & BIT(5));
2991 case EEP_CHAIN_MASK_REDUCE:
2992 return (pBase->miscConfiguration >> 0x3) & 0x1;
2993 case EEP_ANT_DIV_CTL1:
2994 if (AR_SREV_9565(ah))
2995 return AR9300_EEP_ANTDIV_CONTROL_DEFAULT_VALUE;
2997 return eep->base_ext1.ant_div_control;
2998 case EEP_ANTENNA_GAIN_5G:
2999 return eep->modalHeader5G.antennaGain;
3000 case EEP_ANTENNA_GAIN_2G:
3001 return eep->modalHeader2G.antennaGain;
3007 static bool ar9300_eeprom_read_byte(struct ath_hw *ah, int address,
3012 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3015 *buffer = (val >> (8 * (address % 2))) & 0xff;
3019 static bool ar9300_eeprom_read_word(struct ath_hw *ah, int address,
3024 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3027 buffer[0] = val >> 8;
3028 buffer[1] = val & 0xff;
3033 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3036 struct ath_common *common = ath9k_hw_common(ah);
3039 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3040 ath_dbg(common, EEPROM, "eeprom address not in range\n");
3045 * Since we're reading the bytes in reverse order from a little-endian
3046 * word stream, an even address means we only use the lower half of
3047 * the 16-bit word at that address
3049 if (address % 2 == 0) {
3050 if (!ar9300_eeprom_read_byte(ah, address--, buffer++))
3056 for (i = 0; i < count / 2; i++) {
3057 if (!ar9300_eeprom_read_word(ah, address, buffer))
3065 if (!ar9300_eeprom_read_byte(ah, address, buffer))
3071 ath_dbg(common, EEPROM, "unable to read eeprom region at offset %d\n",
3076 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3078 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3080 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3081 AR9300_OTP_STATUS_VALID, 1000))
3084 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3088 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3094 for (i = 0; i < count; i++) {
3095 int offset = 8 * ((address - i) % 4);
3096 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3099 buffer[i] = (data >> offset) & 0xff;
3106 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3107 int *length, int *major, int *minor)
3109 unsigned long value[4];
3115 *code = ((value[0] >> 5) & 0x0007);
3116 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3117 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3118 *major = (value[2] & 0x000f);
3119 *minor = (value[3] & 0x00ff);
3122 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3124 int it, checksum = 0;
3126 for (it = 0; it < dsize; it++) {
3127 checksum += data[it];
3134 static bool ar9300_uncompress_block(struct ath_hw *ah,
3144 struct ath_common *common = ath9k_hw_common(ah);
3148 for (it = 0; it < size; it += (length+2)) {
3152 length = block[it+1];
3155 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3156 ath_dbg(common, EEPROM,
3157 "Restore at %d: spot=%d offset=%d length=%d\n",
3158 it, spot, offset, length);
3159 memcpy(&mptr[spot], &block[it+2], length);
3161 } else if (length > 0) {
3162 ath_dbg(common, EEPROM,
3163 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3164 it, spot, offset, length);
3171 static int ar9300_compress_decision(struct ath_hw *ah,
3176 u8 *word, int length, int mdata_size)
3178 struct ath_common *common = ath9k_hw_common(ah);
3179 const struct ar9300_eeprom *eep = NULL;
3183 if (length != mdata_size) {
3184 ath_dbg(common, EEPROM,
3185 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3186 mdata_size, length);
3189 memcpy(mptr, word + COMP_HDR_LEN, length);
3190 ath_dbg(common, EEPROM,
3191 "restored eeprom %d: uncompressed, length %d\n",
3194 case _CompressBlock:
3195 if (reference == 0) {
3197 eep = ar9003_eeprom_struct_find_by_id(reference);
3199 ath_dbg(common, EEPROM,
3200 "can't find reference eeprom struct %d\n",
3204 memcpy(mptr, eep, mdata_size);
3206 ath_dbg(common, EEPROM,
3207 "restore eeprom %d: block, reference %d, length %d\n",
3208 it, reference, length);
3209 ar9300_uncompress_block(ah, mptr, mdata_size,
3210 (word + COMP_HDR_LEN), length);
3213 ath_dbg(common, EEPROM, "unknown compression code %d\n", code);
3219 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3222 static bool ar9300_check_header(void *data)
3225 return !(*word == 0 || *word == ~0);
3228 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3233 if (!read(ah, base_addr, header, 4))
3236 return ar9300_check_header(header);
3239 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3242 u16 *data = (u16 *) mptr;
3245 for (i = 0; i < mdata_size / 2; i++, data++)
3246 ath9k_hw_nvram_read(ah, i, data);
3251 * Read the configuration data from the eeprom.
3252 * The data can be put in any specified memory buffer.
3254 * Returns -1 on error.
3255 * Returns address of next memory location on success.
3257 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3258 u8 *mptr, int mdata_size)
3265 int reference, length, major, minor;
3268 u16 checksum, mchecksum;
3269 struct ath_common *common = ath9k_hw_common(ah);
3270 struct ar9300_eeprom *eep;
3271 eeprom_read_op read;
3273 if (ath9k_hw_use_flash(ah)) {
3276 ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3278 /* check if eeprom contains valid data */
3279 eep = (struct ar9300_eeprom *) mptr;
3280 txrx = eep->baseEepHeader.txrxMask;
3281 if (txrx != 0 && txrx != 0xff)
3285 word = kzalloc(2048, GFP_KERNEL);
3289 memcpy(mptr, &ar9300_default, mdata_size);
3291 read = ar9300_read_eeprom;
3292 if (AR_SREV_9485(ah))
3293 cptr = AR9300_BASE_ADDR_4K;
3294 else if (AR_SREV_9330(ah))
3295 cptr = AR9300_BASE_ADDR_512;
3297 cptr = AR9300_BASE_ADDR;
3298 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3300 if (ar9300_check_eeprom_header(ah, read, cptr))
3303 cptr = AR9300_BASE_ADDR_512;
3304 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3306 if (ar9300_check_eeprom_header(ah, read, cptr))
3309 read = ar9300_read_otp;
3310 cptr = AR9300_BASE_ADDR;
3311 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3312 if (ar9300_check_eeprom_header(ah, read, cptr))
3315 cptr = AR9300_BASE_ADDR_512;
3316 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3317 if (ar9300_check_eeprom_header(ah, read, cptr))
3323 ath_dbg(common, EEPROM, "Found valid EEPROM data\n");
3325 for (it = 0; it < MSTATE; it++) {
3326 if (!read(ah, cptr, word, COMP_HDR_LEN))
3329 if (!ar9300_check_header(word))
3332 ar9300_comp_hdr_unpack(word, &code, &reference,
3333 &length, &major, &minor);
3334 ath_dbg(common, EEPROM,
3335 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3336 cptr, code, reference, length, major, minor);
3337 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3338 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3339 ath_dbg(common, EEPROM, "Skipping bad header\n");
3340 cptr -= COMP_HDR_LEN;
3345 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3346 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3347 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3348 ath_dbg(common, EEPROM, "checksum %x %x\n",
3349 checksum, mchecksum);
3350 if (checksum == mchecksum) {
3351 ar9300_compress_decision(ah, it, code, reference, mptr,
3352 word, length, mdata_size);
3354 ath_dbg(common, EEPROM,
3355 "skipping block with bad checksum\n");
3357 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3369 * Restore the configuration structure by reading the eeprom.
3370 * This function destroys any existing in-memory structure
3373 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3375 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3377 if (ar9300_eeprom_restore_internal(ah, mptr,
3378 sizeof(struct ar9300_eeprom)) < 0)
3384 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3385 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3386 struct ar9300_modal_eep_header *modal_hdr)
3388 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3389 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3390 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3391 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3392 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3393 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3394 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3395 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3396 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3397 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3398 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3399 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3400 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3401 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3402 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3403 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3404 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3405 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3406 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3407 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3408 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3409 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3410 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3411 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3412 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3413 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3414 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3415 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3416 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3417 PR_EEP("txClip", modal_hdr->txClip);
3418 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3423 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3424 u8 *buf, u32 len, u32 size)
3426 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3427 struct ar9300_base_eep_hdr *pBase;
3429 if (!dump_base_hdr) {
3430 len += scnprintf(buf + len, size - len,
3431 "%20s :\n", "2GHz modal Header");
3432 len = ar9003_dump_modal_eeprom(buf, len, size,
3433 &eep->modalHeader2G);
3434 len += scnprintf(buf + len, size - len,
3435 "%20s :\n", "5GHz modal Header");
3436 len = ar9003_dump_modal_eeprom(buf, len, size,
3437 &eep->modalHeader5G);
3441 pBase = &eep->baseEepHeader;
3443 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3444 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3445 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3446 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3447 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3448 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3449 AR5416_OPFLAGS_11A));
3450 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3451 AR5416_OPFLAGS_11G));
3452 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3453 AR5416_OPFLAGS_N_2G_HT20));
3454 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3455 AR5416_OPFLAGS_N_2G_HT40));
3456 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3457 AR5416_OPFLAGS_N_5G_HT20));
3458 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3459 AR5416_OPFLAGS_N_5G_HT40));
3460 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3461 PR_EEP("RF Silent", pBase->rfSilent);
3462 PR_EEP("BT option", pBase->blueToothOptions);
3463 PR_EEP("Device Cap", pBase->deviceCap);
3464 PR_EEP("Device Type", pBase->deviceType);
3465 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3466 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3467 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3468 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3469 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3470 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3471 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3472 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3473 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3474 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3475 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3476 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3477 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3478 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3479 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3480 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3481 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3482 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3483 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3485 len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3486 ah->eeprom.ar9300_eep.macAddr);
3494 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3495 u8 *buf, u32 len, u32 size)
3501 /* XXX: review hardware docs */
3502 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3504 return ah->eeprom.ar9300_eep.eepromVersion;
3507 /* XXX: could be read from the eepromVersion, not sure yet */
3508 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3513 static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
3516 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3519 return &eep->modalHeader2G;
3521 return &eep->modalHeader5G;
3524 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3526 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3528 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3529 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3530 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
3531 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3533 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3534 REG_RMW_FIELD(ah, AR_CH0_THERM,
3535 AR_CH0_THERM_XPABIASLVL_MSB,
3537 REG_RMW_FIELD(ah, AR_CH0_THERM,
3538 AR_CH0_THERM_XPASHORT2GND, 1);
3542 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3544 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3547 u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3549 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3552 u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3554 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3557 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3560 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3561 return le16_to_cpu(val);
3564 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3566 struct ath_common *common = ath9k_hw_common(ah);
3567 struct ath9k_hw_capabilities *pCap = &ah->caps;
3569 u32 regval, value, gpio;
3570 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3571 AR_PHY_SWITCH_CHAIN_0,
3572 AR_PHY_SWITCH_CHAIN_1,
3573 AR_PHY_SWITCH_CHAIN_2,
3576 if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0)) {
3577 if (ah->config.xlna_gpio)
3578 gpio = ah->config.xlna_gpio;
3580 gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
3582 ath9k_hw_cfg_output(ah, gpio,
3583 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
3586 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3588 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3589 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3590 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3591 } else if (AR_SREV_9550(ah)) {
3592 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3593 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3595 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3596 AR_SWITCH_TABLE_COM_ALL, value);
3600 * AR9462 defines new switch table for BT/WLAN,
3601 * here's new field name in XXX.ref for both 2G and 5G.
3602 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3603 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3604 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3606 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3607 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3609 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3610 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3612 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
3613 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3614 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3615 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3616 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3619 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3620 if (AR_SREV_9485(ah) && common->bt_ant_diversity) {
3621 value &= ~AR_SWITCH_TABLE_COM2_ALL;
3622 value |= ah->config.ant_ctrl_comm2g_switch_enable;
3625 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3627 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3628 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
3629 REG_RMW_FIELD(ah, switch_chain_reg[0],
3630 AR_SWITCH_TABLE_ALL, value);
3633 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3634 if ((ah->rxchainmask & BIT(chain)) ||
3635 (ah->txchainmask & BIT(chain))) {
3636 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3638 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3639 AR_SWITCH_TABLE_ALL, value);
3643 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
3644 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3646 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3647 * are the fields present
3649 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3650 regval &= (~AR_ANT_DIV_CTRL_ALL);
3651 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3653 regval &= (~AR_PHY_ANT_DIV_LNADIV);
3654 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
3656 if (AR_SREV_9485(ah) && common->bt_ant_diversity)
3657 regval |= AR_ANT_DIV_ENABLE;
3659 if (AR_SREV_9565(ah)) {
3660 if (common->bt_ant_diversity) {
3661 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S);
3663 REG_SET_BIT(ah, AR_PHY_RESTART,
3664 AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
3666 /* Force WLAN LNA diversity ON */
3667 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
3668 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3670 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S);
3671 regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S);
3673 REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL,
3674 (1 << AR_PHY_ANT_SW_RX_PROT_S));
3676 /* Force WLAN LNA diversity OFF */
3677 REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV,
3678 AR_BTCOEX_WL_LNADIV_FORCE_ON);
3682 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3684 /* enable fast_div */
3685 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3686 regval &= (~AR_FAST_DIV_ENABLE);
3687 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
3689 if ((AR_SREV_9485(ah) || AR_SREV_9565(ah))
3690 && common->bt_ant_diversity)
3691 regval |= AR_FAST_DIV_ENABLE;
3693 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3695 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
3696 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3698 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3701 regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
3702 AR_PHY_ANT_DIV_ALT_LNACONF |
3703 AR_PHY_ANT_DIV_ALT_GAINTB |
3704 AR_PHY_ANT_DIV_MAIN_GAINTB));
3705 /* by default use LNA1 for the main antenna */
3706 regval |= (ATH_ANT_DIV_COMB_LNA1 <<
3707 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
3708 regval |= (ATH_ANT_DIV_COMB_LNA2 <<
3709 AR_PHY_ANT_DIV_ALT_LNACONF_S);
3710 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3715 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3717 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3718 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3722 drive_strength = pBase->miscConfiguration & BIT(0);
3723 if (!drive_strength)
3726 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3734 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3736 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3747 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3749 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3754 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3757 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3758 struct ath9k_channel *chan)
3762 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3764 if (chain >= 0 && chain < 3) {
3765 if (IS_CHAN_2GHZ(chan))
3766 return eep->modalHeader2G.xatten1DB[chain];
3767 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3768 t[0] = eep->base_ext2.xatten1DBLow[chain];
3770 t[1] = eep->modalHeader5G.xatten1DB[chain];
3772 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3774 value = ar9003_hw_power_interpolate((s32) chan->channel,
3778 return eep->modalHeader5G.xatten1DB[chain];
3785 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3786 struct ath9k_channel *chan)
3790 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3792 if (chain >= 0 && chain < 3) {
3793 if (IS_CHAN_2GHZ(chan))
3794 return eep->modalHeader2G.xatten1Margin[chain];
3795 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3796 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3798 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3800 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3802 value = ar9003_hw_power_interpolate((s32) chan->channel,
3806 return eep->modalHeader5G.xatten1Margin[chain];
3812 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3816 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3817 AR_PHY_EXT_ATTEN_CTL_1,
3818 AR_PHY_EXT_ATTEN_CTL_2,
3821 if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
3822 value = ar9003_hw_atten_chain_get(ah, 1, chan);
3823 REG_RMW_FIELD(ah, ext_atten_reg[0],
3824 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3826 value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
3827 REG_RMW_FIELD(ah, ext_atten_reg[0],
3828 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3832 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3833 for (i = 0; i < 3; i++) {
3834 if (ah->txchainmask & BIT(i)) {
3835 value = ar9003_hw_atten_chain_get(ah, i, chan);
3836 REG_RMW_FIELD(ah, ext_atten_reg[i],
3837 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3839 if (AR_SREV_9485(ah) &&
3840 (ar9003_hw_get_rx_gain_idx(ah) == 0) &&
3841 ah->config.xatten_margin_cfg)
3844 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3846 if (ah->config.alt_mingainidx)
3847 REG_RMW_FIELD(ah, AR_PHY_EXT_ATTEN_CTL_0,
3848 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3851 REG_RMW_FIELD(ah, ext_atten_reg[i],
3852 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3858 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3862 while (pmu_set != REG_READ(ah, pmu_reg)) {
3865 REG_WRITE(ah, pmu_reg, pmu_set);
3872 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3874 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3875 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3878 if (pBase->featureEnable & BIT(4)) {
3879 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3882 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3883 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3884 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3887 if (AR_SREV_9330(ah)) {
3888 if (ah->is_clk_25mhz) {
3889 reg_pmu_set = (3 << 1) | (8 << 4) |
3890 (3 << 8) | (1 << 14) |
3891 (6 << 17) | (1 << 20) |
3894 reg_pmu_set = (4 << 1) | (7 << 4) |
3895 (3 << 8) | (1 << 14) |
3896 (6 << 17) | (1 << 20) |
3900 reg_pmu_set = (5 << 1) | (7 << 4) |
3901 (2 << 8) | (2 << 14) |
3902 (6 << 17) | (1 << 20) |
3903 (3 << 24) | (1 << 28);
3906 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3907 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3910 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3912 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3913 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3916 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3918 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3919 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3921 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3922 reg_val = le32_to_cpu(pBase->swreg);
3923 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3925 /* Internal regulator is ON. Write swreg register. */
3926 reg_val = le32_to_cpu(pBase->swreg);
3927 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3928 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3929 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3930 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3931 /* Set REG_CONTROL1.SWREG_PROGRAM */
3932 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3934 AR_RTC_REG_CONTROL1) |
3935 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3938 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3939 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3940 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3944 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3945 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3948 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3949 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3952 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
3953 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3955 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3956 AR_RTC_FORCE_SWREG_PRD;
3957 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3963 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3965 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3966 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3968 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3971 if (eep->baseEepHeader.featureEnable & 0x40) {
3972 tuning_caps_param &= 0x7f;
3973 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3975 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3980 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3982 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3983 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3985 s32 t[3], f[3] = {5180, 5500, 5785};
3987 if (!(pBase->miscConfiguration & BIT(4)))
3990 if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) {
3992 quick_drop = eep->modalHeader2G.quick_drop;
3994 t[0] = eep->base_ext1.quick_drop_low;
3995 t[1] = eep->modalHeader5G.quick_drop;
3996 t[2] = eep->base_ext1.quick_drop_high;
3997 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
3999 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
4003 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
4007 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
4009 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4010 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
4011 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4012 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
4015 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
4017 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4020 if (!(eep->baseEepHeader.featureEnable & 0x80))
4023 if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah))
4026 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
4028 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4029 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
4031 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
4032 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
4035 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
4037 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4040 if (!(eep->baseEepHeader.miscConfiguration & 0x40))
4043 if (!AR_SREV_9300(ah))
4046 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
4047 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4050 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4053 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
4057 static int ar9003_hw_get_thermometer(struct ath_hw *ah)
4059 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4060 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
4061 int thermometer = (pBase->miscConfiguration >> 1) & 0x3;
4063 return --thermometer;
4066 static void ar9003_hw_thermometer_apply(struct ath_hw *ah)
4068 int thermometer = ar9003_hw_get_thermometer(ah);
4069 u8 therm_on = (thermometer < 0) ? 0 : 1;
4071 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4072 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4073 if (ah->caps.tx_chainmask & BIT(1))
4074 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4075 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4076 if (ah->caps.tx_chainmask & BIT(2))
4077 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4078 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4080 therm_on = (thermometer < 0) ? 0 : (thermometer == 0);
4081 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4082 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4083 if (ah->caps.tx_chainmask & BIT(1)) {
4084 therm_on = (thermometer < 0) ? 0 : (thermometer == 1);
4085 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4086 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4088 if (ah->caps.tx_chainmask & BIT(2)) {
4089 therm_on = (thermometer < 0) ? 0 : (thermometer == 2);
4090 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4091 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4095 static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4099 if (!AR_SREV_9462_20_OR_LATER(ah))
4102 ar9300_otp_read_word(ah, 1, &data);
4104 kg = (data >> 8) & 0xff;
4106 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4107 AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko);
4108 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4109 AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN,
4114 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4115 struct ath9k_channel *chan)
4117 bool is2ghz = IS_CHAN_2GHZ(chan);
4118 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
4119 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
4120 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
4121 ar9003_hw_drive_strength_apply(ah);
4122 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
4123 ar9003_hw_atten_apply(ah, chan);
4124 ar9003_hw_quick_drop_apply(ah, chan->channel);
4125 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah))
4126 ar9003_hw_internal_regulator_apply(ah);
4127 ar9003_hw_apply_tuning_caps(ah);
4128 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4129 ar9003_hw_thermometer_apply(ah);
4130 ar9003_hw_thermo_cal_apply(ah);
4133 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
4134 struct ath9k_channel *chan)
4139 * Returns the interpolated y value corresponding to the specified x value
4140 * from the np ordered pairs of data (px,py).
4141 * The pairs do not have to be in any order.
4142 * If the specified x value is less than any of the px,
4143 * the returned y value is equal to the py for the lowest px.
4144 * If the specified x value is greater than any of the px,
4145 * the returned y value is equal to the py for the highest px.
4147 static int ar9003_hw_power_interpolate(int32_t x,
4148 int32_t *px, int32_t *py, u_int16_t np)
4151 int lx = 0, ly = 0, lhave = 0;
4152 int hx = 0, hy = 0, hhave = 0;
4159 /* identify best lower and higher x calibration measurement */
4160 for (ip = 0; ip < np; ip++) {
4163 /* this measurement is higher than our desired x */
4165 if (!hhave || dx > (x - hx)) {
4166 /* new best higher x measurement */
4172 /* this measurement is lower than our desired x */
4174 if (!lhave || dx < (x - lx)) {
4175 /* new best lower x measurement */
4183 /* the low x is good */
4185 /* so is the high x */
4187 /* they're the same, so just pick one */
4190 else /* interpolate */
4191 y = interpolate(x, lx, hx, ly, hy);
4192 } else /* only low is good, use it */
4194 } else if (hhave) /* only high is good, use it */
4196 else /* nothing is good,this should never happen unless np=0, ???? */
4201 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4202 u16 rateIndex, u16 freq, bool is2GHz)
4205 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4206 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4207 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4208 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4212 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4213 pEepromTargetPwr = eep->calTargetPower2G;
4214 pFreqBin = eep->calTarget_freqbin_2G;
4216 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4217 pEepromTargetPwr = eep->calTargetPower5G;
4218 pFreqBin = eep->calTarget_freqbin_5G;
4222 * create array of channels and targetpower from
4223 * targetpower piers stored on eeprom
4225 for (i = 0; i < numPiers; i++) {
4226 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4227 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4230 /* interpolate to get target power for given frequency */
4231 return (u8) ar9003_hw_power_interpolate((s32) freq,
4233 targetPowerArray, numPiers);
4236 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4238 u16 freq, bool is2GHz)
4241 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4242 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4243 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4244 struct cal_tgt_pow_ht *pEepromTargetPwr;
4248 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4249 pEepromTargetPwr = eep->calTargetPower2GHT20;
4250 pFreqBin = eep->calTarget_freqbin_2GHT20;
4252 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4253 pEepromTargetPwr = eep->calTargetPower5GHT20;
4254 pFreqBin = eep->calTarget_freqbin_5GHT20;
4258 * create array of channels and targetpower
4259 * from targetpower piers stored on eeprom
4261 for (i = 0; i < numPiers; i++) {
4262 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4263 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4266 /* interpolate to get target power for given frequency */
4267 return (u8) ar9003_hw_power_interpolate((s32) freq,
4269 targetPowerArray, numPiers);
4272 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4274 u16 freq, bool is2GHz)
4277 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4278 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4279 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4280 struct cal_tgt_pow_ht *pEepromTargetPwr;
4284 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4285 pEepromTargetPwr = eep->calTargetPower2GHT40;
4286 pFreqBin = eep->calTarget_freqbin_2GHT40;
4288 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4289 pEepromTargetPwr = eep->calTargetPower5GHT40;
4290 pFreqBin = eep->calTarget_freqbin_5GHT40;
4294 * create array of channels and targetpower from
4295 * targetpower piers stored on eeprom
4297 for (i = 0; i < numPiers; i++) {
4298 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4299 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4302 /* interpolate to get target power for given frequency */
4303 return (u8) ar9003_hw_power_interpolate((s32) freq,
4305 targetPowerArray, numPiers);
4308 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4309 u16 rateIndex, u16 freq)
4311 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4312 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4313 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4314 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4315 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4316 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4319 * create array of channels and targetpower from
4320 * targetpower piers stored on eeprom
4322 for (i = 0; i < numPiers; i++) {
4323 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4324 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4327 /* interpolate to get target power for given frequency */
4328 return (u8) ar9003_hw_power_interpolate((s32) freq,
4330 targetPowerArray, numPiers);
4333 /* Set tx power registers to array of values passed in */
4334 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4336 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4337 /* make sure forced gain is not set */
4338 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4340 /* Write the OFDM power per rate set */
4342 /* 6 (LSB), 9, 12, 18 (MSB) */
4343 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4344 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4345 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4346 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4347 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4349 /* 24 (LSB), 36, 48, 54 (MSB) */
4350 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4351 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4352 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4353 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4354 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4356 /* Write the CCK power per rate set */
4358 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4359 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4360 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4361 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4362 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4363 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4365 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4366 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4367 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4368 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4369 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4370 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4373 /* Write the power for duplicated frames - HT40 */
4375 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4376 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4377 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4378 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4379 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4380 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4383 /* Write the HT20 power per rate set */
4385 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4386 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4387 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4388 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4389 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4390 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4393 /* 6 (LSB), 7, 12, 13 (MSB) */
4394 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4395 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4396 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4397 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4398 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4401 /* 14 (LSB), 15, 20, 21 */
4402 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4403 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4404 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4405 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4406 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4409 /* Mixed HT20 and HT40 rates */
4411 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4412 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4413 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4414 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4415 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4416 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4420 * Write the HT40 power per rate set
4421 * correct PAR difference between HT40 and HT20/LEGACY
4422 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4424 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4425 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4426 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4427 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4428 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4431 /* 6 (LSB), 7, 12, 13 (MSB) */
4432 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4433 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4434 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4435 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4436 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4439 /* 14 (LSB), 15, 20, 21 */
4440 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4441 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4442 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4443 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4444 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4451 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4452 u8 *targetPowerValT2,
4455 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4456 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4458 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4459 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4461 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4462 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4464 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4465 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4469 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4470 u8 *targetPowerValT2)
4472 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4473 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4475 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4476 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4477 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4478 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4479 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4480 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4483 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4484 u8 *targetPowerValT2, bool is2GHz)
4486 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4487 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4489 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4490 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4492 targetPowerValT2[ALL_TARGET_HT20_4] =
4493 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4495 targetPowerValT2[ALL_TARGET_HT20_5] =
4496 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4498 targetPowerValT2[ALL_TARGET_HT20_6] =
4499 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4501 targetPowerValT2[ALL_TARGET_HT20_7] =
4502 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4504 targetPowerValT2[ALL_TARGET_HT20_12] =
4505 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4507 targetPowerValT2[ALL_TARGET_HT20_13] =
4508 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4510 targetPowerValT2[ALL_TARGET_HT20_14] =
4511 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4513 targetPowerValT2[ALL_TARGET_HT20_15] =
4514 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4516 targetPowerValT2[ALL_TARGET_HT20_20] =
4517 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4519 targetPowerValT2[ALL_TARGET_HT20_21] =
4520 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4522 targetPowerValT2[ALL_TARGET_HT20_22] =
4523 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4525 targetPowerValT2[ALL_TARGET_HT20_23] =
4526 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4530 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4532 u8 *targetPowerValT2,
4535 /* XXX: hard code for now, need to get from eeprom struct */
4536 u8 ht40PowerIncForPdadc = 0;
4538 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4539 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4540 is2GHz) + ht40PowerIncForPdadc;
4541 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4542 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4544 is2GHz) + ht40PowerIncForPdadc;
4545 targetPowerValT2[ALL_TARGET_HT40_4] =
4546 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4547 is2GHz) + ht40PowerIncForPdadc;
4548 targetPowerValT2[ALL_TARGET_HT40_5] =
4549 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4550 is2GHz) + ht40PowerIncForPdadc;
4551 targetPowerValT2[ALL_TARGET_HT40_6] =
4552 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4553 is2GHz) + ht40PowerIncForPdadc;
4554 targetPowerValT2[ALL_TARGET_HT40_7] =
4555 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4556 is2GHz) + ht40PowerIncForPdadc;
4557 targetPowerValT2[ALL_TARGET_HT40_12] =
4558 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4559 is2GHz) + ht40PowerIncForPdadc;
4560 targetPowerValT2[ALL_TARGET_HT40_13] =
4561 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4562 is2GHz) + ht40PowerIncForPdadc;
4563 targetPowerValT2[ALL_TARGET_HT40_14] =
4564 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4565 is2GHz) + ht40PowerIncForPdadc;
4566 targetPowerValT2[ALL_TARGET_HT40_15] =
4567 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4568 is2GHz) + ht40PowerIncForPdadc;
4569 targetPowerValT2[ALL_TARGET_HT40_20] =
4570 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4571 is2GHz) + ht40PowerIncForPdadc;
4572 targetPowerValT2[ALL_TARGET_HT40_21] =
4573 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4574 is2GHz) + ht40PowerIncForPdadc;
4575 targetPowerValT2[ALL_TARGET_HT40_22] =
4576 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4577 is2GHz) + ht40PowerIncForPdadc;
4578 targetPowerValT2[ALL_TARGET_HT40_23] =
4579 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4580 is2GHz) + ht40PowerIncForPdadc;
4583 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4584 struct ath9k_channel *chan,
4585 u8 *targetPowerValT2)
4587 bool is2GHz = IS_CHAN_2GHZ(chan);
4589 struct ath_common *common = ath9k_hw_common(ah);
4590 u16 freq = chan->channel;
4593 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4595 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4596 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4598 if (IS_CHAN_HT40(chan))
4599 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4602 for (i = 0; i < ar9300RateSize; i++) {
4603 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
4604 i, targetPowerValT2[i]);
4608 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4614 int *ptemperature, int *pvoltage)
4617 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4619 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4620 struct ath_common *common = ath9k_hw_common(ah);
4622 if (ichain >= AR9300_MAX_CHAINS) {
4623 ath_dbg(common, EEPROM,
4624 "Invalid chain index, must be less than %d\n",
4629 if (mode) { /* 5GHz */
4630 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4631 ath_dbg(common, EEPROM,
4632 "Invalid 5GHz cal pier index, must be less than %d\n",
4633 AR9300_NUM_5G_CAL_PIERS);
4636 pCalPier = &(eep->calFreqPier5G[ipier]);
4637 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4640 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4641 ath_dbg(common, EEPROM,
4642 "Invalid 2GHz cal pier index, must be less than %d\n",
4643 AR9300_NUM_2G_CAL_PIERS);
4647 pCalPier = &(eep->calFreqPier2G[ipier]);
4648 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4652 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4653 *pcorrection = pCalPierStruct->refPower;
4654 *ptemperature = pCalPierStruct->tempMeas;
4655 *pvoltage = pCalPierStruct->voltMeas;
4660 static void ar9003_hw_power_control_override(struct ath_hw *ah,
4663 int *voltage, int *temperature)
4665 int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
4666 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4667 int f[8], t[8], t1[3], t2[3], i;
4669 REG_RMW(ah, AR_PHY_TPC_11_B0,
4670 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4671 AR_PHY_TPC_OLPC_GAIN_DELTA);
4672 if (ah->caps.tx_chainmask & BIT(1))
4673 REG_RMW(ah, AR_PHY_TPC_11_B1,
4674 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4675 AR_PHY_TPC_OLPC_GAIN_DELTA);
4676 if (ah->caps.tx_chainmask & BIT(2))
4677 REG_RMW(ah, AR_PHY_TPC_11_B2,
4678 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4679 AR_PHY_TPC_OLPC_GAIN_DELTA);
4681 /* enable open loop power control on chip */
4682 REG_RMW(ah, AR_PHY_TPC_6_B0,
4683 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4684 AR_PHY_TPC_6_ERROR_EST_MODE);
4685 if (ah->caps.tx_chainmask & BIT(1))
4686 REG_RMW(ah, AR_PHY_TPC_6_B1,
4687 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4688 AR_PHY_TPC_6_ERROR_EST_MODE);
4689 if (ah->caps.tx_chainmask & BIT(2))
4690 REG_RMW(ah, AR_PHY_TPC_6_B2,
4691 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4692 AR_PHY_TPC_6_ERROR_EST_MODE);
4695 * enable temperature compensation
4696 * Need to use register names
4698 if (frequency < 4000) {
4699 temp_slope = eep->modalHeader2G.tempSlope;
4701 if (AR_SREV_9550(ah)) {
4702 t[0] = eep->base_ext1.tempslopextension[2];
4703 t1[0] = eep->base_ext1.tempslopextension[3];
4704 t2[0] = eep->base_ext1.tempslopextension[4];
4707 t[1] = eep->modalHeader5G.tempSlope;
4708 t1[1] = eep->base_ext1.tempslopextension[0];
4709 t2[1] = eep->base_ext1.tempslopextension[1];
4712 t[2] = eep->base_ext1.tempslopextension[5];
4713 t1[2] = eep->base_ext1.tempslopextension[6];
4714 t2[2] = eep->base_ext1.tempslopextension[7];
4717 temp_slope = ar9003_hw_power_interpolate(frequency,
4719 temp_slope1 = ar9003_hw_power_interpolate(frequency,
4721 temp_slope2 = ar9003_hw_power_interpolate(frequency,
4727 if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4728 for (i = 0; i < 8; i++) {
4729 t[i] = eep->base_ext1.tempslopextension[i];
4730 f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4732 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4734 } else if (eep->base_ext2.tempSlopeLow != 0) {
4735 t[0] = eep->base_ext2.tempSlopeLow;
4737 t[1] = eep->modalHeader5G.tempSlope;
4739 t[2] = eep->base_ext2.tempSlopeHigh;
4741 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4744 temp_slope = eep->modalHeader5G.tempSlope;
4749 if (AR_SREV_9550(ah)) {
4751 * AR955x has tempSlope register for each chain.
4752 * Check whether temp_compensation feature is enabled or not.
4754 if (eep->baseEepHeader.featureEnable & 0x1) {
4755 if (frequency < 4000) {
4756 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4757 AR_PHY_TPC_19_ALPHA_THERM,
4758 eep->base_ext2.tempSlopeLow);
4759 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4760 AR_PHY_TPC_19_ALPHA_THERM,
4762 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4763 AR_PHY_TPC_19_ALPHA_THERM,
4764 eep->base_ext2.tempSlopeHigh);
4766 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4767 AR_PHY_TPC_19_ALPHA_THERM,
4769 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4770 AR_PHY_TPC_19_ALPHA_THERM,
4772 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4773 AR_PHY_TPC_19_ALPHA_THERM,
4778 * If temp compensation is not enabled,
4779 * set all registers to 0.
4781 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4782 AR_PHY_TPC_19_ALPHA_THERM, 0);
4783 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4784 AR_PHY_TPC_19_ALPHA_THERM, 0);
4785 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4786 AR_PHY_TPC_19_ALPHA_THERM, 0);
4789 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4790 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4793 if (AR_SREV_9462_20_OR_LATER(ah))
4794 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4795 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4798 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4802 /* Apply the recorded correction values. */
4803 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4805 int ichain, ipier, npier;
4807 int lfrequency[AR9300_MAX_CHAINS],
4808 lcorrection[AR9300_MAX_CHAINS],
4809 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4810 int hfrequency[AR9300_MAX_CHAINS],
4811 hcorrection[AR9300_MAX_CHAINS],
4812 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4814 int correction[AR9300_MAX_CHAINS],
4815 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4816 int pfrequency, pcorrection, ptemperature, pvoltage;
4817 struct ath_common *common = ath9k_hw_common(ah);
4819 mode = (frequency >= 4000);
4821 npier = AR9300_NUM_5G_CAL_PIERS;
4823 npier = AR9300_NUM_2G_CAL_PIERS;
4825 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4826 lfrequency[ichain] = 0;
4827 hfrequency[ichain] = 100000;
4829 /* identify best lower and higher frequency calibration measurement */
4830 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4831 for (ipier = 0; ipier < npier; ipier++) {
4832 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4833 &pfrequency, &pcorrection,
4834 &ptemperature, &pvoltage)) {
4835 fdiff = frequency - pfrequency;
4838 * this measurement is higher than
4839 * our desired frequency
4842 if (hfrequency[ichain] <= 0 ||
4843 hfrequency[ichain] >= 100000 ||
4845 (frequency - hfrequency[ichain])) {
4848 * frequency measurement
4850 hfrequency[ichain] = pfrequency;
4851 hcorrection[ichain] =
4853 htemperature[ichain] =
4855 hvoltage[ichain] = pvoltage;
4859 if (lfrequency[ichain] <= 0
4861 (frequency - lfrequency[ichain])) {
4864 * frequency measurement
4866 lfrequency[ichain] = pfrequency;
4867 lcorrection[ichain] =
4869 ltemperature[ichain] =
4871 lvoltage[ichain] = pvoltage;
4879 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4880 ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
4881 ichain, frequency, lfrequency[ichain],
4882 lcorrection[ichain], hfrequency[ichain],
4883 hcorrection[ichain]);
4884 /* they're the same, so just pick one */
4885 if (hfrequency[ichain] == lfrequency[ichain]) {
4886 correction[ichain] = lcorrection[ichain];
4887 voltage[ichain] = lvoltage[ichain];
4888 temperature[ichain] = ltemperature[ichain];
4890 /* the low frequency is good */
4891 else if (frequency - lfrequency[ichain] < 1000) {
4892 /* so is the high frequency, interpolate */
4893 if (hfrequency[ichain] - frequency < 1000) {
4895 correction[ichain] = interpolate(frequency,
4898 lcorrection[ichain],
4899 hcorrection[ichain]);
4901 temperature[ichain] = interpolate(frequency,
4904 ltemperature[ichain],
4905 htemperature[ichain]);
4907 voltage[ichain] = interpolate(frequency,
4913 /* only low is good, use it */
4915 correction[ichain] = lcorrection[ichain];
4916 temperature[ichain] = ltemperature[ichain];
4917 voltage[ichain] = lvoltage[ichain];
4920 /* only high is good, use it */
4921 else if (hfrequency[ichain] - frequency < 1000) {
4922 correction[ichain] = hcorrection[ichain];
4923 temperature[ichain] = htemperature[ichain];
4924 voltage[ichain] = hvoltage[ichain];
4925 } else { /* nothing is good, presume 0???? */
4926 correction[ichain] = 0;
4927 temperature[ichain] = 0;
4928 voltage[ichain] = 0;
4932 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4935 ath_dbg(common, EEPROM,
4936 "for frequency=%d, calibration correction = %d %d %d\n",
4937 frequency, correction[0], correction[1], correction[2]);
4942 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4947 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4948 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4951 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4953 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4956 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4962 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4963 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4965 u8 *ctl_freqbin = is2GHz ?
4966 &eep->ctl_freqbin_2G[idx][0] :
4967 &eep->ctl_freqbin_5G[idx][0];
4970 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4971 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4972 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4974 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4975 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4976 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4979 return MAX_RATE_POWER;
4983 * Find the maximum conformance test limit for the given channel and CTL info
4985 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4986 u16 freq, int idx, bool is2GHz)
4988 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4989 u8 *ctl_freqbin = is2GHz ?
4990 &eep->ctl_freqbin_2G[idx][0] :
4991 &eep->ctl_freqbin_5G[idx][0];
4992 u16 num_edges = is2GHz ?
4993 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4996 /* Get the edge power */
4998 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
5001 * If there's an exact channel match or an inband flag set
5002 * on the lower channel use the given rdEdgePower
5004 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
5006 ar9003_hw_get_direct_edge_power(eep, idx,
5009 } else if ((edge > 0) &&
5010 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
5013 ar9003_hw_get_indirect_edge_power(eep, idx,
5017 * Leave loop - no more affecting edges possible in
5018 * this monotonic increasing list
5023 return twiceMaxEdgePower;
5026 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
5027 struct ath9k_channel *chan,
5028 u8 *pPwrArray, u16 cfgCtl,
5029 u8 antenna_reduction,
5032 struct ath_common *common = ath9k_hw_common(ah);
5033 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
5034 u16 twiceMaxEdgePower;
5036 u16 scaledPower = 0, minCtlPower;
5037 static const u16 ctlModesFor11a[] = {
5038 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
5040 static const u16 ctlModesFor11g[] = {
5041 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
5042 CTL_11G_EXT, CTL_2GHT40
5045 const u16 *pCtlMode;
5047 struct chan_centers centers;
5050 u16 twiceMinEdgePower;
5051 bool is2ghz = IS_CHAN_2GHZ(chan);
5053 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
5054 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
5058 /* Setup for CTL modes */
5059 /* CTL_11B, CTL_11G, CTL_2GHT20 */
5061 ARRAY_SIZE(ctlModesFor11g) -
5062 SUB_NUM_CTL_MODES_AT_2G_40;
5063 pCtlMode = ctlModesFor11g;
5064 if (IS_CHAN_HT40(chan))
5066 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
5068 /* Setup for CTL modes */
5069 /* CTL_11A, CTL_5GHT20 */
5070 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
5071 SUB_NUM_CTL_MODES_AT_5G_40;
5072 pCtlMode = ctlModesFor11a;
5073 if (IS_CHAN_HT40(chan))
5075 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
5079 * For MIMO, need to apply regulatory caps individually across
5080 * dynamically running modes: CCK, OFDM, HT20, HT40
5082 * The outer loop walks through each possible applicable runtime mode.
5083 * The inner loop walks through each ctlIndex entry in EEPROM.
5084 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
5086 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
5087 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
5088 (pCtlMode[ctlMode] == CTL_2GHT40);
5090 freq = centers.synth_center;
5091 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
5092 freq = centers.ext_center;
5094 freq = centers.ctl_center;
5096 ath_dbg(common, REGULATORY,
5097 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
5098 ctlMode, numCtlModes, isHt40CtlMode,
5099 (pCtlMode[ctlMode] & EXT_ADDITIVE));
5101 /* walk through each CTL index stored in EEPROM */
5103 ctlIndex = pEepData->ctlIndex_2G;
5104 ctlNum = AR9300_NUM_CTLS_2G;
5106 ctlIndex = pEepData->ctlIndex_5G;
5107 ctlNum = AR9300_NUM_CTLS_5G;
5110 twiceMaxEdgePower = MAX_RATE_POWER;
5111 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
5112 ath_dbg(common, REGULATORY,
5113 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
5114 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
5118 * compare test group from regulatory
5119 * channel list with test mode from pCtlMode
5122 if ((((cfgCtl & ~CTL_MODE_M) |
5123 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5125 (((cfgCtl & ~CTL_MODE_M) |
5126 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5127 ((ctlIndex[i] & CTL_MODE_M) |
5130 ar9003_hw_get_max_edge_power(pEepData,
5134 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
5136 * Find the minimum of all CTL
5137 * edge powers that apply to
5141 min(twiceMaxEdgePower,
5145 twiceMaxEdgePower = twiceMinEdgePower;
5151 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
5153 ath_dbg(common, REGULATORY,
5154 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
5155 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
5156 scaledPower, minCtlPower);
5158 /* Apply ctl mode to correct target power set */
5159 switch (pCtlMode[ctlMode]) {
5161 for (i = ALL_TARGET_LEGACY_1L_5L;
5162 i <= ALL_TARGET_LEGACY_11S; i++)
5163 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5168 for (i = ALL_TARGET_LEGACY_6_24;
5169 i <= ALL_TARGET_LEGACY_54; i++)
5170 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5175 for (i = ALL_TARGET_HT20_0_8_16;
5176 i <= ALL_TARGET_HT20_23; i++) {
5177 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5179 if (ath9k_hw_mci_is_enabled(ah))
5181 (u8)min((u16)pPwrArray[i],
5182 ar9003_mci_get_max_txpower(ah,
5183 pCtlMode[ctlMode]));
5188 for (i = ALL_TARGET_HT40_0_8_16;
5189 i <= ALL_TARGET_HT40_23; i++) {
5190 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5192 if (ath9k_hw_mci_is_enabled(ah))
5194 (u8)min((u16)pPwrArray[i],
5195 ar9003_mci_get_max_txpower(ah,
5196 pCtlMode[ctlMode]));
5202 } /* end ctl mode checking */
5205 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5207 u8 mod_idx = mcs_idx % 8;
5210 return mod_idx ? (base_pwridx + 1) : base_pwridx;
5212 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5215 static void ar9003_paprd_set_txpower(struct ath_hw *ah,
5216 struct ath9k_channel *chan,
5217 u8 *targetPowerValT2)
5221 if (!ar9003_is_paprd_enabled(ah))
5224 if (IS_CHAN_HT40(chan))
5225 i = ALL_TARGET_HT40_7;
5227 i = ALL_TARGET_HT20_7;
5229 if (IS_CHAN_2GHZ(chan)) {
5230 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) &&
5231 !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) {
5232 if (IS_CHAN_HT40(chan))
5233 i = ALL_TARGET_HT40_0_8_16;
5235 i = ALL_TARGET_HT20_0_8_16;
5239 ah->paprd_target_power = targetPowerValT2[i];
5242 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5243 struct ath9k_channel *chan, u16 cfgCtl,
5244 u8 twiceAntennaReduction,
5245 u8 powerLimit, bool test)
5247 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5248 struct ath_common *common = ath9k_hw_common(ah);
5249 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5250 struct ar9300_modal_eep_header *modal_hdr;
5251 u8 targetPowerValT2[ar9300RateSize];
5252 u8 target_power_val_t2_eep[ar9300RateSize];
5253 unsigned int i = 0, paprd_scale_factor = 0;
5254 u8 pwr_idx, min_pwridx = 0;
5256 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5259 * Get target powers from EEPROM - our baseline for TX Power
5261 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5263 if (ar9003_is_paprd_enabled(ah)) {
5264 if (IS_CHAN_2GHZ(chan))
5265 modal_hdr = &eep->modalHeader2G;
5267 modal_hdr = &eep->modalHeader5G;
5269 ah->paprd_ratemask =
5270 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5271 AR9300_PAPRD_RATE_MASK;
5273 ah->paprd_ratemask_ht40 =
5274 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5275 AR9300_PAPRD_RATE_MASK;
5277 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5278 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5279 ALL_TARGET_HT20_0_8_16;
5281 if (!ah->paprd_table_write_done) {
5282 memcpy(target_power_val_t2_eep, targetPowerValT2,
5283 sizeof(targetPowerValT2));
5284 for (i = 0; i < 24; i++) {
5285 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5286 if (ah->paprd_ratemask & (1 << i)) {
5287 if (targetPowerValT2[pwr_idx] &&
5288 targetPowerValT2[pwr_idx] ==
5289 target_power_val_t2_eep[pwr_idx])
5290 targetPowerValT2[pwr_idx] -=
5295 memcpy(target_power_val_t2_eep, targetPowerValT2,
5296 sizeof(targetPowerValT2));
5299 ar9003_hw_set_power_per_rate_table(ah, chan,
5300 targetPowerValT2, cfgCtl,
5301 twiceAntennaReduction,
5304 if (ar9003_is_paprd_enabled(ah)) {
5305 for (i = 0; i < ar9300RateSize; i++) {
5306 if ((ah->paprd_ratemask & (1 << i)) &&
5307 (abs(targetPowerValT2[i] -
5308 target_power_val_t2_eep[i]) >
5309 paprd_scale_factor)) {
5310 ah->paprd_ratemask &= ~(1 << i);
5311 ath_dbg(common, EEPROM,
5312 "paprd disabled for mcs %d\n", i);
5317 regulatory->max_power_level = 0;
5318 for (i = 0; i < ar9300RateSize; i++) {
5319 if (targetPowerValT2[i] > regulatory->max_power_level)
5320 regulatory->max_power_level = targetPowerValT2[i];
5323 ath9k_hw_update_regulatory_maxpower(ah);
5328 for (i = 0; i < ar9300RateSize; i++) {
5329 ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
5330 i, targetPowerValT2[i]);
5333 /* Write target power array to registers */
5334 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5335 ar9003_hw_calibration_apply(ah, chan->channel);
5336 ar9003_paprd_set_txpower(ah, chan, targetPowerValT2);
5339 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5345 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5347 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5349 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5352 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5354 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5356 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5359 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5361 return ar9003_modal_header(ah, is2ghz)->spurChans;
5364 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5365 struct ath9k_channel *chan)
5367 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5369 if (IS_CHAN_2GHZ(chan))
5370 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5371 AR9300_PAPRD_SCALE_1);
5373 if (chan->channel >= 5700)
5374 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5375 AR9300_PAPRD_SCALE_1);
5376 else if (chan->channel >= 5400)
5377 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5378 AR9300_PAPRD_SCALE_2);
5380 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5381 AR9300_PAPRD_SCALE_1);
5385 const struct eeprom_ops eep_ar9300_ops = {
5386 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5387 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5388 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5389 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5390 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5391 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5392 .set_board_values = ath9k_hw_ar9300_set_board_values,
5393 .set_addac = ath9k_hw_ar9300_set_addac,
5394 .set_txpower = ath9k_hw_ar9300_set_txpower,
5395 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel