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 return eep->base_ext1.ant_div_control;
2995 case EEP_ANTENNA_GAIN_5G:
2996 return eep->modalHeader5G.antennaGain;
2997 case EEP_ANTENNA_GAIN_2G:
2998 return eep->modalHeader2G.antennaGain;
3004 static bool ar9300_eeprom_read_byte(struct ath_hw *ah, int address,
3009 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3012 *buffer = (val >> (8 * (address % 2))) & 0xff;
3016 static bool ar9300_eeprom_read_word(struct ath_hw *ah, int address,
3021 if (unlikely(!ath9k_hw_nvram_read(ah, address / 2, &val)))
3024 buffer[0] = val >> 8;
3025 buffer[1] = val & 0xff;
3030 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3033 struct ath_common *common = ath9k_hw_common(ah);
3036 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3037 ath_dbg(common, EEPROM, "eeprom address not in range\n");
3042 * Since we're reading the bytes in reverse order from a little-endian
3043 * word stream, an even address means we only use the lower half of
3044 * the 16-bit word at that address
3046 if (address % 2 == 0) {
3047 if (!ar9300_eeprom_read_byte(ah, address--, buffer++))
3053 for (i = 0; i < count / 2; i++) {
3054 if (!ar9300_eeprom_read_word(ah, address, buffer))
3062 if (!ar9300_eeprom_read_byte(ah, address, buffer))
3068 ath_dbg(common, EEPROM, "unable to read eeprom region at offset %d\n",
3073 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3075 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3077 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3078 AR9300_OTP_STATUS_VALID, 1000))
3081 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3085 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3091 for (i = 0; i < count; i++) {
3092 int offset = 8 * ((address - i) % 4);
3093 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3096 buffer[i] = (data >> offset) & 0xff;
3103 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3104 int *length, int *major, int *minor)
3106 unsigned long value[4];
3112 *code = ((value[0] >> 5) & 0x0007);
3113 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3114 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3115 *major = (value[2] & 0x000f);
3116 *minor = (value[3] & 0x00ff);
3119 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3121 int it, checksum = 0;
3123 for (it = 0; it < dsize; it++) {
3124 checksum += data[it];
3131 static bool ar9300_uncompress_block(struct ath_hw *ah,
3141 struct ath_common *common = ath9k_hw_common(ah);
3145 for (it = 0; it < size; it += (length+2)) {
3149 length = block[it+1];
3152 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3153 ath_dbg(common, EEPROM,
3154 "Restore at %d: spot=%d offset=%d length=%d\n",
3155 it, spot, offset, length);
3156 memcpy(&mptr[spot], &block[it+2], length);
3158 } else if (length > 0) {
3159 ath_dbg(common, EEPROM,
3160 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3161 it, spot, offset, length);
3168 static int ar9300_compress_decision(struct ath_hw *ah,
3173 u8 *word, int length, int mdata_size)
3175 struct ath_common *common = ath9k_hw_common(ah);
3176 const struct ar9300_eeprom *eep = NULL;
3180 if (length != mdata_size) {
3181 ath_dbg(common, EEPROM,
3182 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3183 mdata_size, length);
3186 memcpy(mptr, word + COMP_HDR_LEN, length);
3187 ath_dbg(common, EEPROM,
3188 "restored eeprom %d: uncompressed, length %d\n",
3191 case _CompressBlock:
3192 if (reference == 0) {
3194 eep = ar9003_eeprom_struct_find_by_id(reference);
3196 ath_dbg(common, EEPROM,
3197 "can't find reference eeprom struct %d\n",
3201 memcpy(mptr, eep, mdata_size);
3203 ath_dbg(common, EEPROM,
3204 "restore eeprom %d: block, reference %d, length %d\n",
3205 it, reference, length);
3206 ar9300_uncompress_block(ah, mptr, mdata_size,
3207 (word + COMP_HDR_LEN), length);
3210 ath_dbg(common, EEPROM, "unknown compression code %d\n", code);
3216 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3219 static bool ar9300_check_header(void *data)
3222 return !(*word == 0 || *word == ~0);
3225 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3230 if (!read(ah, base_addr, header, 4))
3233 return ar9300_check_header(header);
3236 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3239 u16 *data = (u16 *) mptr;
3242 for (i = 0; i < mdata_size / 2; i++, data++)
3243 ath9k_hw_nvram_read(ah, i, data);
3248 * Read the configuration data from the eeprom.
3249 * The data can be put in any specified memory buffer.
3251 * Returns -1 on error.
3252 * Returns address of next memory location on success.
3254 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3255 u8 *mptr, int mdata_size)
3262 int reference, length, major, minor;
3265 u16 checksum, mchecksum;
3266 struct ath_common *common = ath9k_hw_common(ah);
3267 struct ar9300_eeprom *eep;
3268 eeprom_read_op read;
3270 if (ath9k_hw_use_flash(ah)) {
3273 ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3275 /* check if eeprom contains valid data */
3276 eep = (struct ar9300_eeprom *) mptr;
3277 txrx = eep->baseEepHeader.txrxMask;
3278 if (txrx != 0 && txrx != 0xff)
3282 word = kzalloc(2048, GFP_KERNEL);
3286 memcpy(mptr, &ar9300_default, mdata_size);
3288 read = ar9300_read_eeprom;
3289 if (AR_SREV_9485(ah))
3290 cptr = AR9300_BASE_ADDR_4K;
3291 else if (AR_SREV_9330(ah))
3292 cptr = AR9300_BASE_ADDR_512;
3294 cptr = AR9300_BASE_ADDR;
3295 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3297 if (ar9300_check_eeprom_header(ah, read, cptr))
3300 cptr = AR9300_BASE_ADDR_512;
3301 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3303 if (ar9300_check_eeprom_header(ah, read, cptr))
3306 read = ar9300_read_otp;
3307 cptr = AR9300_BASE_ADDR;
3308 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3309 if (ar9300_check_eeprom_header(ah, read, cptr))
3312 cptr = AR9300_BASE_ADDR_512;
3313 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3314 if (ar9300_check_eeprom_header(ah, read, cptr))
3320 ath_dbg(common, EEPROM, "Found valid EEPROM data\n");
3322 for (it = 0; it < MSTATE; it++) {
3323 if (!read(ah, cptr, word, COMP_HDR_LEN))
3326 if (!ar9300_check_header(word))
3329 ar9300_comp_hdr_unpack(word, &code, &reference,
3330 &length, &major, &minor);
3331 ath_dbg(common, EEPROM,
3332 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3333 cptr, code, reference, length, major, minor);
3334 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3335 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3336 ath_dbg(common, EEPROM, "Skipping bad header\n");
3337 cptr -= COMP_HDR_LEN;
3342 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3343 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3344 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3345 ath_dbg(common, EEPROM, "checksum %x %x\n",
3346 checksum, mchecksum);
3347 if (checksum == mchecksum) {
3348 ar9300_compress_decision(ah, it, code, reference, mptr,
3349 word, length, mdata_size);
3351 ath_dbg(common, EEPROM,
3352 "skipping block with bad checksum\n");
3354 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3366 * Restore the configuration structure by reading the eeprom.
3367 * This function destroys any existing in-memory structure
3370 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3372 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3374 if (ar9300_eeprom_restore_internal(ah, mptr,
3375 sizeof(struct ar9300_eeprom)) < 0)
3381 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3382 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3383 struct ar9300_modal_eep_header *modal_hdr)
3385 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3386 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3387 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3388 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3389 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3390 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3391 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3392 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3393 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3394 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3395 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3396 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3397 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3398 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3399 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3400 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3401 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3402 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3403 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3404 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3405 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3406 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3407 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3408 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3409 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3410 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3411 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3412 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3413 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3414 PR_EEP("txClip", modal_hdr->txClip);
3415 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3420 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3421 u8 *buf, u32 len, u32 size)
3423 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3424 struct ar9300_base_eep_hdr *pBase;
3426 if (!dump_base_hdr) {
3427 len += snprintf(buf + len, size - len,
3428 "%20s :\n", "2GHz modal Header");
3429 len = ar9003_dump_modal_eeprom(buf, len, size,
3430 &eep->modalHeader2G);
3431 len += snprintf(buf + len, size - len,
3432 "%20s :\n", "5GHz modal Header");
3433 len = ar9003_dump_modal_eeprom(buf, len, size,
3434 &eep->modalHeader5G);
3438 pBase = &eep->baseEepHeader;
3440 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3441 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3442 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3443 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3444 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3445 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3446 AR5416_OPFLAGS_11A));
3447 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3448 AR5416_OPFLAGS_11G));
3449 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3450 AR5416_OPFLAGS_N_2G_HT20));
3451 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3452 AR5416_OPFLAGS_N_2G_HT40));
3453 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3454 AR5416_OPFLAGS_N_5G_HT20));
3455 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3456 AR5416_OPFLAGS_N_5G_HT40));
3457 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3458 PR_EEP("RF Silent", pBase->rfSilent);
3459 PR_EEP("BT option", pBase->blueToothOptions);
3460 PR_EEP("Device Cap", pBase->deviceCap);
3461 PR_EEP("Device Type", pBase->deviceType);
3462 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3463 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3464 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3465 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3466 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3467 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3468 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3469 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3470 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3471 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3472 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3473 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3474 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3475 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3476 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3477 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3478 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3479 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3480 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3482 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3483 ah->eeprom.ar9300_eep.macAddr);
3491 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3492 u8 *buf, u32 len, u32 size)
3498 /* XXX: review hardware docs */
3499 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3501 return ah->eeprom.ar9300_eep.eepromVersion;
3504 /* XXX: could be read from the eepromVersion, not sure yet */
3505 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3510 static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
3513 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3516 return &eep->modalHeader2G;
3518 return &eep->modalHeader5G;
3521 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3523 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3525 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3526 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3527 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
3528 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3530 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3531 REG_RMW_FIELD(ah, AR_CH0_THERM,
3532 AR_CH0_THERM_XPABIASLVL_MSB,
3534 REG_RMW_FIELD(ah, AR_CH0_THERM,
3535 AR_CH0_THERM_XPASHORT2GND, 1);
3539 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3541 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3545 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3547 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3550 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3552 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3555 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3558 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3559 return le16_to_cpu(val);
3562 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3564 struct ath9k_hw_capabilities *pCap = &ah->caps;
3567 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3568 AR_PHY_SWITCH_CHAIN_0,
3569 AR_PHY_SWITCH_CHAIN_1,
3570 AR_PHY_SWITCH_CHAIN_2,
3573 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3575 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3576 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3577 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3578 } else if (AR_SREV_9550(ah)) {
3579 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3580 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3582 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3583 AR_SWITCH_TABLE_COM_ALL, value);
3587 * AR9462 defines new switch table for BT/WLAN,
3588 * here's new field name in XXX.ref for both 2G and 5G.
3589 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3590 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3591 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3593 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3594 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3596 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3597 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3599 if (AR_SREV_9462_20(ah) || AR_SREV_9565(ah)) {
3600 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3601 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3602 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3603 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3606 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3607 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3609 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3610 if ((ah->rxchainmask & BIT(chain)) ||
3611 (ah->txchainmask & BIT(chain))) {
3612 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3614 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3615 AR_SWITCH_TABLE_ALL, value);
3619 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
3620 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3622 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3623 * are the fields present
3625 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3626 regval &= (~AR_ANT_DIV_CTRL_ALL);
3627 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3629 regval &= (~AR_PHY_ANT_DIV_LNADIV);
3630 regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
3632 if (AR_SREV_9565(ah)) {
3633 if (ah->shared_chain_lnadiv) {
3634 regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S);
3636 regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S);
3637 regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S);
3641 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3643 /*enable fast_div */
3644 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3645 regval &= (~AR_FAST_DIV_ENABLE);
3646 regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
3647 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3649 if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) {
3650 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3652 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3655 regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
3656 AR_PHY_ANT_DIV_ALT_LNACONF |
3657 AR_PHY_ANT_DIV_ALT_GAINTB |
3658 AR_PHY_ANT_DIV_MAIN_GAINTB));
3659 /* by default use LNA1 for the main antenna */
3660 regval |= (AR_PHY_ANT_DIV_LNA1 <<
3661 AR_PHY_ANT_DIV_MAIN_LNACONF_S);
3662 regval |= (AR_PHY_ANT_DIV_LNA2 <<
3663 AR_PHY_ANT_DIV_ALT_LNACONF_S);
3664 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3669 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3671 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3672 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3676 drive_strength = pBase->miscConfiguration & BIT(0);
3677 if (!drive_strength)
3680 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3688 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3690 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3701 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3703 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3708 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3711 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3712 struct ath9k_channel *chan)
3716 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3718 if (chain >= 0 && chain < 3) {
3719 if (IS_CHAN_2GHZ(chan))
3720 return eep->modalHeader2G.xatten1DB[chain];
3721 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3722 t[0] = eep->base_ext2.xatten1DBLow[chain];
3724 t[1] = eep->modalHeader5G.xatten1DB[chain];
3726 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3728 value = ar9003_hw_power_interpolate((s32) chan->channel,
3732 return eep->modalHeader5G.xatten1DB[chain];
3739 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3740 struct ath9k_channel *chan)
3744 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3746 if (chain >= 0 && chain < 3) {
3747 if (IS_CHAN_2GHZ(chan))
3748 return eep->modalHeader2G.xatten1Margin[chain];
3749 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3750 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3752 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3754 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3756 value = ar9003_hw_power_interpolate((s32) chan->channel,
3760 return eep->modalHeader5G.xatten1Margin[chain];
3766 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3770 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3771 AR_PHY_EXT_ATTEN_CTL_1,
3772 AR_PHY_EXT_ATTEN_CTL_2,
3775 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3776 for (i = 0; i < 3; i++) {
3777 if (ah->txchainmask & BIT(i)) {
3778 value = ar9003_hw_atten_chain_get(ah, i, chan);
3779 REG_RMW_FIELD(ah, ext_atten_reg[i],
3780 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3782 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3783 REG_RMW_FIELD(ah, ext_atten_reg[i],
3784 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3790 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3794 while (pmu_set != REG_READ(ah, pmu_reg)) {
3797 REG_WRITE(ah, pmu_reg, pmu_set);
3804 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3806 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3807 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3810 if (pBase->featureEnable & BIT(4)) {
3811 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3814 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3815 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3816 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3819 if (AR_SREV_9330(ah)) {
3820 if (ah->is_clk_25mhz) {
3821 reg_pmu_set = (3 << 1) | (8 << 4) |
3822 (3 << 8) | (1 << 14) |
3823 (6 << 17) | (1 << 20) |
3826 reg_pmu_set = (4 << 1) | (7 << 4) |
3827 (3 << 8) | (1 << 14) |
3828 (6 << 17) | (1 << 20) |
3832 reg_pmu_set = (5 << 1) | (7 << 4) |
3833 (2 << 8) | (2 << 14) |
3834 (6 << 17) | (1 << 20) |
3835 (3 << 24) | (1 << 28);
3838 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3839 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3842 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3844 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3845 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3848 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3850 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3851 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3853 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3854 reg_val = le32_to_cpu(pBase->swreg);
3855 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3857 /* Internal regulator is ON. Write swreg register. */
3858 reg_val = le32_to_cpu(pBase->swreg);
3859 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3860 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3861 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3862 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3863 /* Set REG_CONTROL1.SWREG_PROGRAM */
3864 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3866 AR_RTC_REG_CONTROL1) |
3867 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3870 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3871 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3872 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3876 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3877 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3880 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3881 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3884 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
3885 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3887 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3888 AR_RTC_FORCE_SWREG_PRD;
3889 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3895 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3897 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3898 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3900 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3903 if (eep->baseEepHeader.featureEnable & 0x40) {
3904 tuning_caps_param &= 0x7f;
3905 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3907 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3912 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3914 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3915 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3917 s32 t[3], f[3] = {5180, 5500, 5785};
3919 if (!(pBase->miscConfiguration & BIT(1)))
3923 quick_drop = eep->modalHeader2G.quick_drop;
3925 t[0] = eep->base_ext1.quick_drop_low;
3926 t[1] = eep->modalHeader5G.quick_drop;
3927 t[2] = eep->base_ext1.quick_drop_high;
3928 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
3930 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
3933 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
3937 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
3939 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3940 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
3941 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3942 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
3945 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
3947 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3950 if (!(eep->baseEepHeader.featureEnable & 0x80))
3953 if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah))
3956 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
3958 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3959 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
3961 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3962 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
3965 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
3967 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3970 if (!(eep->baseEepHeader.featureEnable & 0x40))
3973 if (!AR_SREV_9300(ah))
3976 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
3977 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
3980 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
3983 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
3987 static int ar9003_hw_get_thermometer(struct ath_hw *ah)
3989 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3990 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3991 int thermometer = (pBase->miscConfiguration >> 1) & 0x3;
3993 return --thermometer;
3996 static void ar9003_hw_thermometer_apply(struct ath_hw *ah)
3998 int thermometer = ar9003_hw_get_thermometer(ah);
3999 u8 therm_on = (thermometer < 0) ? 0 : 1;
4001 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4002 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4003 if (ah->caps.tx_chainmask & BIT(1))
4004 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4005 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4006 if (ah->caps.tx_chainmask & BIT(2))
4007 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4008 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
4010 therm_on = (thermometer < 0) ? 0 : (thermometer == 0);
4011 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
4012 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4013 if (ah->caps.tx_chainmask & BIT(1)) {
4014 therm_on = (thermometer < 0) ? 0 : (thermometer == 1);
4015 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
4016 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4018 if (ah->caps.tx_chainmask & BIT(2)) {
4019 therm_on = (thermometer < 0) ? 0 : (thermometer == 2);
4020 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4021 AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
4025 static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4029 if (!AR_SREV_9462_20(ah))
4031 ar9300_otp_read_word(ah, 1, &data);
4033 kg = (data >> 8) & 0xff;
4035 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4036 AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko);
4037 REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
4038 AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN,
4043 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4044 struct ath9k_channel *chan)
4046 bool is2ghz = IS_CHAN_2GHZ(chan);
4047 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
4048 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
4049 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
4050 ar9003_hw_drive_strength_apply(ah);
4051 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
4052 ar9003_hw_atten_apply(ah, chan);
4053 ar9003_hw_quick_drop_apply(ah, chan->channel);
4054 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah))
4055 ar9003_hw_internal_regulator_apply(ah);
4056 ar9003_hw_apply_tuning_caps(ah);
4057 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4058 ar9003_hw_thermometer_apply(ah);
4059 ar9003_hw_thermo_cal_apply(ah);
4062 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
4063 struct ath9k_channel *chan)
4068 * Returns the interpolated y value corresponding to the specified x value
4069 * from the np ordered pairs of data (px,py).
4070 * The pairs do not have to be in any order.
4071 * If the specified x value is less than any of the px,
4072 * the returned y value is equal to the py for the lowest px.
4073 * If the specified x value is greater than any of the px,
4074 * the returned y value is equal to the py for the highest px.
4076 static int ar9003_hw_power_interpolate(int32_t x,
4077 int32_t *px, int32_t *py, u_int16_t np)
4080 int lx = 0, ly = 0, lhave = 0;
4081 int hx = 0, hy = 0, hhave = 0;
4088 /* identify best lower and higher x calibration measurement */
4089 for (ip = 0; ip < np; ip++) {
4092 /* this measurement is higher than our desired x */
4094 if (!hhave || dx > (x - hx)) {
4095 /* new best higher x measurement */
4101 /* this measurement is lower than our desired x */
4103 if (!lhave || dx < (x - lx)) {
4104 /* new best lower x measurement */
4112 /* the low x is good */
4114 /* so is the high x */
4116 /* they're the same, so just pick one */
4119 else /* interpolate */
4120 y = interpolate(x, lx, hx, ly, hy);
4121 } else /* only low is good, use it */
4123 } else if (hhave) /* only high is good, use it */
4125 else /* nothing is good,this should never happen unless np=0, ???? */
4130 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4131 u16 rateIndex, u16 freq, bool is2GHz)
4134 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4135 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4136 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4137 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4141 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4142 pEepromTargetPwr = eep->calTargetPower2G;
4143 pFreqBin = eep->calTarget_freqbin_2G;
4145 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4146 pEepromTargetPwr = eep->calTargetPower5G;
4147 pFreqBin = eep->calTarget_freqbin_5G;
4151 * create array of channels and targetpower from
4152 * targetpower piers stored on eeprom
4154 for (i = 0; i < numPiers; i++) {
4155 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4156 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4159 /* interpolate to get target power for given frequency */
4160 return (u8) ar9003_hw_power_interpolate((s32) freq,
4162 targetPowerArray, numPiers);
4165 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4167 u16 freq, bool is2GHz)
4170 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4171 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4172 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4173 struct cal_tgt_pow_ht *pEepromTargetPwr;
4177 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4178 pEepromTargetPwr = eep->calTargetPower2GHT20;
4179 pFreqBin = eep->calTarget_freqbin_2GHT20;
4181 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4182 pEepromTargetPwr = eep->calTargetPower5GHT20;
4183 pFreqBin = eep->calTarget_freqbin_5GHT20;
4187 * create array of channels and targetpower
4188 * from targetpower piers stored on eeprom
4190 for (i = 0; i < numPiers; i++) {
4191 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4192 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4195 /* interpolate to get target power for given frequency */
4196 return (u8) ar9003_hw_power_interpolate((s32) freq,
4198 targetPowerArray, numPiers);
4201 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4203 u16 freq, bool is2GHz)
4206 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4207 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4208 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4209 struct cal_tgt_pow_ht *pEepromTargetPwr;
4213 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4214 pEepromTargetPwr = eep->calTargetPower2GHT40;
4215 pFreqBin = eep->calTarget_freqbin_2GHT40;
4217 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4218 pEepromTargetPwr = eep->calTargetPower5GHT40;
4219 pFreqBin = eep->calTarget_freqbin_5GHT40;
4223 * create array of channels and targetpower from
4224 * targetpower piers stored on eeprom
4226 for (i = 0; i < numPiers; i++) {
4227 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4228 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4231 /* interpolate to get target power for given frequency */
4232 return (u8) ar9003_hw_power_interpolate((s32) freq,
4234 targetPowerArray, numPiers);
4237 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4238 u16 rateIndex, u16 freq)
4240 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4241 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4242 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4243 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4244 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4245 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4248 * create array of channels and targetpower from
4249 * targetpower piers stored on eeprom
4251 for (i = 0; i < numPiers; i++) {
4252 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4253 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4256 /* interpolate to get target power for given frequency */
4257 return (u8) ar9003_hw_power_interpolate((s32) freq,
4259 targetPowerArray, numPiers);
4262 /* Set tx power registers to array of values passed in */
4263 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4265 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4266 /* make sure forced gain is not set */
4267 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4269 /* Write the OFDM power per rate set */
4271 /* 6 (LSB), 9, 12, 18 (MSB) */
4272 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4273 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4274 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4275 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4276 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4278 /* 24 (LSB), 36, 48, 54 (MSB) */
4279 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4280 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4281 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4282 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4283 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4285 /* Write the CCK power per rate set */
4287 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4288 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4289 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4290 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4291 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4292 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4294 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4295 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4296 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4297 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4298 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4299 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4302 /* Write the power for duplicated frames - HT40 */
4304 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4305 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4306 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4307 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4308 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4309 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4312 /* Write the HT20 power per rate set */
4314 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4315 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4316 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4317 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4318 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4319 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4322 /* 6 (LSB), 7, 12, 13 (MSB) */
4323 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4324 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4325 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4326 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4327 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4330 /* 14 (LSB), 15, 20, 21 */
4331 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4332 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4333 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4334 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4335 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4338 /* Mixed HT20 and HT40 rates */
4340 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4341 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4342 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4343 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4344 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4345 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4349 * Write the HT40 power per rate set
4350 * correct PAR difference between HT40 and HT20/LEGACY
4351 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4353 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4354 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4355 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4356 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4357 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4360 /* 6 (LSB), 7, 12, 13 (MSB) */
4361 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4362 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4363 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4364 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4365 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4368 /* 14 (LSB), 15, 20, 21 */
4369 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4370 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4371 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4372 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4373 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4380 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4381 u8 *targetPowerValT2,
4384 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4385 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4387 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4388 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4390 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4391 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4393 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4394 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4398 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4399 u8 *targetPowerValT2)
4401 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4402 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4404 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4405 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4406 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4407 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4408 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4409 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4412 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4413 u8 *targetPowerValT2, bool is2GHz)
4415 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4416 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4418 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4419 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4421 targetPowerValT2[ALL_TARGET_HT20_4] =
4422 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4424 targetPowerValT2[ALL_TARGET_HT20_5] =
4425 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4427 targetPowerValT2[ALL_TARGET_HT20_6] =
4428 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4430 targetPowerValT2[ALL_TARGET_HT20_7] =
4431 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4433 targetPowerValT2[ALL_TARGET_HT20_12] =
4434 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4436 targetPowerValT2[ALL_TARGET_HT20_13] =
4437 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4439 targetPowerValT2[ALL_TARGET_HT20_14] =
4440 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4442 targetPowerValT2[ALL_TARGET_HT20_15] =
4443 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4445 targetPowerValT2[ALL_TARGET_HT20_20] =
4446 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4448 targetPowerValT2[ALL_TARGET_HT20_21] =
4449 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4451 targetPowerValT2[ALL_TARGET_HT20_22] =
4452 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4454 targetPowerValT2[ALL_TARGET_HT20_23] =
4455 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4459 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4461 u8 *targetPowerValT2,
4464 /* XXX: hard code for now, need to get from eeprom struct */
4465 u8 ht40PowerIncForPdadc = 0;
4467 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4468 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4469 is2GHz) + ht40PowerIncForPdadc;
4470 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4471 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4473 is2GHz) + ht40PowerIncForPdadc;
4474 targetPowerValT2[ALL_TARGET_HT40_4] =
4475 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4476 is2GHz) + ht40PowerIncForPdadc;
4477 targetPowerValT2[ALL_TARGET_HT40_5] =
4478 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4479 is2GHz) + ht40PowerIncForPdadc;
4480 targetPowerValT2[ALL_TARGET_HT40_6] =
4481 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4482 is2GHz) + ht40PowerIncForPdadc;
4483 targetPowerValT2[ALL_TARGET_HT40_7] =
4484 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4485 is2GHz) + ht40PowerIncForPdadc;
4486 targetPowerValT2[ALL_TARGET_HT40_12] =
4487 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4488 is2GHz) + ht40PowerIncForPdadc;
4489 targetPowerValT2[ALL_TARGET_HT40_13] =
4490 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4491 is2GHz) + ht40PowerIncForPdadc;
4492 targetPowerValT2[ALL_TARGET_HT40_14] =
4493 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4494 is2GHz) + ht40PowerIncForPdadc;
4495 targetPowerValT2[ALL_TARGET_HT40_15] =
4496 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4497 is2GHz) + ht40PowerIncForPdadc;
4498 targetPowerValT2[ALL_TARGET_HT40_20] =
4499 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4500 is2GHz) + ht40PowerIncForPdadc;
4501 targetPowerValT2[ALL_TARGET_HT40_21] =
4502 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4503 is2GHz) + ht40PowerIncForPdadc;
4504 targetPowerValT2[ALL_TARGET_HT40_22] =
4505 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4506 is2GHz) + ht40PowerIncForPdadc;
4507 targetPowerValT2[ALL_TARGET_HT40_23] =
4508 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4509 is2GHz) + ht40PowerIncForPdadc;
4512 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4513 struct ath9k_channel *chan,
4514 u8 *targetPowerValT2)
4516 bool is2GHz = IS_CHAN_2GHZ(chan);
4518 struct ath_common *common = ath9k_hw_common(ah);
4519 u16 freq = chan->channel;
4522 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4524 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4525 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4527 if (IS_CHAN_HT40(chan))
4528 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4531 for (i = 0; i < ar9300RateSize; i++) {
4532 ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n",
4533 i, targetPowerValT2[i]);
4537 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4543 int *ptemperature, int *pvoltage)
4546 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4548 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4549 struct ath_common *common = ath9k_hw_common(ah);
4551 if (ichain >= AR9300_MAX_CHAINS) {
4552 ath_dbg(common, EEPROM,
4553 "Invalid chain index, must be less than %d\n",
4558 if (mode) { /* 5GHz */
4559 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4560 ath_dbg(common, EEPROM,
4561 "Invalid 5GHz cal pier index, must be less than %d\n",
4562 AR9300_NUM_5G_CAL_PIERS);
4565 pCalPier = &(eep->calFreqPier5G[ipier]);
4566 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4569 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4570 ath_dbg(common, EEPROM,
4571 "Invalid 2GHz cal pier index, must be less than %d\n",
4572 AR9300_NUM_2G_CAL_PIERS);
4576 pCalPier = &(eep->calFreqPier2G[ipier]);
4577 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4581 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4582 *pcorrection = pCalPierStruct->refPower;
4583 *ptemperature = pCalPierStruct->tempMeas;
4584 *pvoltage = pCalPierStruct->voltMeas;
4589 static void ar9003_hw_power_control_override(struct ath_hw *ah,
4592 int *voltage, int *temperature)
4594 int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
4595 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4596 int f[8], t[8], t1[3], t2[3], i;
4598 REG_RMW(ah, AR_PHY_TPC_11_B0,
4599 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4600 AR_PHY_TPC_OLPC_GAIN_DELTA);
4601 if (ah->caps.tx_chainmask & BIT(1))
4602 REG_RMW(ah, AR_PHY_TPC_11_B1,
4603 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4604 AR_PHY_TPC_OLPC_GAIN_DELTA);
4605 if (ah->caps.tx_chainmask & BIT(2))
4606 REG_RMW(ah, AR_PHY_TPC_11_B2,
4607 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4608 AR_PHY_TPC_OLPC_GAIN_DELTA);
4610 /* enable open loop power control on chip */
4611 REG_RMW(ah, AR_PHY_TPC_6_B0,
4612 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4613 AR_PHY_TPC_6_ERROR_EST_MODE);
4614 if (ah->caps.tx_chainmask & BIT(1))
4615 REG_RMW(ah, AR_PHY_TPC_6_B1,
4616 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4617 AR_PHY_TPC_6_ERROR_EST_MODE);
4618 if (ah->caps.tx_chainmask & BIT(2))
4619 REG_RMW(ah, AR_PHY_TPC_6_B2,
4620 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4621 AR_PHY_TPC_6_ERROR_EST_MODE);
4624 * enable temperature compensation
4625 * Need to use register names
4627 if (frequency < 4000) {
4628 temp_slope = eep->modalHeader2G.tempSlope;
4630 if (AR_SREV_9550(ah)) {
4631 t[0] = eep->base_ext1.tempslopextension[2];
4632 t1[0] = eep->base_ext1.tempslopextension[3];
4633 t2[0] = eep->base_ext1.tempslopextension[4];
4636 t[1] = eep->modalHeader5G.tempSlope;
4637 t1[1] = eep->base_ext1.tempslopextension[0];
4638 t2[1] = eep->base_ext1.tempslopextension[1];
4641 t[2] = eep->base_ext1.tempslopextension[5];
4642 t1[2] = eep->base_ext1.tempslopextension[6];
4643 t2[2] = eep->base_ext1.tempslopextension[7];
4646 temp_slope = ar9003_hw_power_interpolate(frequency,
4648 temp_slope1 = ar9003_hw_power_interpolate(frequency,
4650 temp_slope2 = ar9003_hw_power_interpolate(frequency,
4656 if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
4657 for (i = 0; i < 8; i++) {
4658 t[i] = eep->base_ext1.tempslopextension[i];
4659 f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
4661 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4663 } else if (eep->base_ext2.tempSlopeLow != 0) {
4664 t[0] = eep->base_ext2.tempSlopeLow;
4666 t[1] = eep->modalHeader5G.tempSlope;
4668 t[2] = eep->base_ext2.tempSlopeHigh;
4670 temp_slope = ar9003_hw_power_interpolate((s32) frequency,
4673 temp_slope = eep->modalHeader5G.tempSlope;
4678 if (AR_SREV_9550(ah)) {
4680 * AR955x has tempSlope register for each chain.
4681 * Check whether temp_compensation feature is enabled or not.
4683 if (eep->baseEepHeader.featureEnable & 0x1) {
4684 if (frequency < 4000) {
4685 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4686 AR_PHY_TPC_19_ALPHA_THERM,
4687 eep->base_ext2.tempSlopeLow);
4688 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4689 AR_PHY_TPC_19_ALPHA_THERM,
4691 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4692 AR_PHY_TPC_19_ALPHA_THERM,
4693 eep->base_ext2.tempSlopeHigh);
4695 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4696 AR_PHY_TPC_19_ALPHA_THERM,
4698 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4699 AR_PHY_TPC_19_ALPHA_THERM,
4701 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4702 AR_PHY_TPC_19_ALPHA_THERM,
4707 * If temp compensation is not enabled,
4708 * set all registers to 0.
4710 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4711 AR_PHY_TPC_19_ALPHA_THERM, 0);
4712 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4713 AR_PHY_TPC_19_ALPHA_THERM, 0);
4714 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
4715 AR_PHY_TPC_19_ALPHA_THERM, 0);
4718 REG_RMW_FIELD(ah, AR_PHY_TPC_19,
4719 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4722 if (AR_SREV_9462_20(ah))
4723 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4724 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4727 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4731 /* Apply the recorded correction values. */
4732 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4734 int ichain, ipier, npier;
4736 int lfrequency[AR9300_MAX_CHAINS],
4737 lcorrection[AR9300_MAX_CHAINS],
4738 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4739 int hfrequency[AR9300_MAX_CHAINS],
4740 hcorrection[AR9300_MAX_CHAINS],
4741 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4743 int correction[AR9300_MAX_CHAINS],
4744 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4745 int pfrequency, pcorrection, ptemperature, pvoltage;
4746 struct ath_common *common = ath9k_hw_common(ah);
4748 mode = (frequency >= 4000);
4750 npier = AR9300_NUM_5G_CAL_PIERS;
4752 npier = AR9300_NUM_2G_CAL_PIERS;
4754 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4755 lfrequency[ichain] = 0;
4756 hfrequency[ichain] = 100000;
4758 /* identify best lower and higher frequency calibration measurement */
4759 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4760 for (ipier = 0; ipier < npier; ipier++) {
4761 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4762 &pfrequency, &pcorrection,
4763 &ptemperature, &pvoltage)) {
4764 fdiff = frequency - pfrequency;
4767 * this measurement is higher than
4768 * our desired frequency
4771 if (hfrequency[ichain] <= 0 ||
4772 hfrequency[ichain] >= 100000 ||
4774 (frequency - hfrequency[ichain])) {
4777 * frequency measurement
4779 hfrequency[ichain] = pfrequency;
4780 hcorrection[ichain] =
4782 htemperature[ichain] =
4784 hvoltage[ichain] = pvoltage;
4788 if (lfrequency[ichain] <= 0
4790 (frequency - lfrequency[ichain])) {
4793 * frequency measurement
4795 lfrequency[ichain] = pfrequency;
4796 lcorrection[ichain] =
4798 ltemperature[ichain] =
4800 lvoltage[ichain] = pvoltage;
4808 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4809 ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
4810 ichain, frequency, lfrequency[ichain],
4811 lcorrection[ichain], hfrequency[ichain],
4812 hcorrection[ichain]);
4813 /* they're the same, so just pick one */
4814 if (hfrequency[ichain] == lfrequency[ichain]) {
4815 correction[ichain] = lcorrection[ichain];
4816 voltage[ichain] = lvoltage[ichain];
4817 temperature[ichain] = ltemperature[ichain];
4819 /* the low frequency is good */
4820 else if (frequency - lfrequency[ichain] < 1000) {
4821 /* so is the high frequency, interpolate */
4822 if (hfrequency[ichain] - frequency < 1000) {
4824 correction[ichain] = interpolate(frequency,
4827 lcorrection[ichain],
4828 hcorrection[ichain]);
4830 temperature[ichain] = interpolate(frequency,
4833 ltemperature[ichain],
4834 htemperature[ichain]);
4836 voltage[ichain] = interpolate(frequency,
4842 /* only low is good, use it */
4844 correction[ichain] = lcorrection[ichain];
4845 temperature[ichain] = ltemperature[ichain];
4846 voltage[ichain] = lvoltage[ichain];
4849 /* only high is good, use it */
4850 else if (hfrequency[ichain] - frequency < 1000) {
4851 correction[ichain] = hcorrection[ichain];
4852 temperature[ichain] = htemperature[ichain];
4853 voltage[ichain] = hvoltage[ichain];
4854 } else { /* nothing is good, presume 0???? */
4855 correction[ichain] = 0;
4856 temperature[ichain] = 0;
4857 voltage[ichain] = 0;
4861 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4864 ath_dbg(common, EEPROM,
4865 "for frequency=%d, calibration correction = %d %d %d\n",
4866 frequency, correction[0], correction[1], correction[2]);
4871 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4876 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4877 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4880 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4882 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4885 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4891 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4892 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4894 u8 *ctl_freqbin = is2GHz ?
4895 &eep->ctl_freqbin_2G[idx][0] :
4896 &eep->ctl_freqbin_5G[idx][0];
4899 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4900 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4901 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4903 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4904 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4905 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4908 return MAX_RATE_POWER;
4912 * Find the maximum conformance test limit for the given channel and CTL info
4914 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4915 u16 freq, int idx, bool is2GHz)
4917 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4918 u8 *ctl_freqbin = is2GHz ?
4919 &eep->ctl_freqbin_2G[idx][0] :
4920 &eep->ctl_freqbin_5G[idx][0];
4921 u16 num_edges = is2GHz ?
4922 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4925 /* Get the edge power */
4927 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
4930 * If there's an exact channel match or an inband flag set
4931 * on the lower channel use the given rdEdgePower
4933 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
4935 ar9003_hw_get_direct_edge_power(eep, idx,
4938 } else if ((edge > 0) &&
4939 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
4942 ar9003_hw_get_indirect_edge_power(eep, idx,
4946 * Leave loop - no more affecting edges possible in
4947 * this monotonic increasing list
4952 return twiceMaxEdgePower;
4955 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4956 struct ath9k_channel *chan,
4957 u8 *pPwrArray, u16 cfgCtl,
4958 u8 antenna_reduction,
4961 struct ath_common *common = ath9k_hw_common(ah);
4962 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4963 u16 twiceMaxEdgePower;
4965 u16 scaledPower = 0, minCtlPower;
4966 static const u16 ctlModesFor11a[] = {
4967 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4969 static const u16 ctlModesFor11g[] = {
4970 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
4971 CTL_11G_EXT, CTL_2GHT40
4974 const u16 *pCtlMode;
4976 struct chan_centers centers;
4979 u16 twiceMinEdgePower;
4980 bool is2ghz = IS_CHAN_2GHZ(chan);
4982 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4983 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
4987 /* Setup for CTL modes */
4988 /* CTL_11B, CTL_11G, CTL_2GHT20 */
4990 ARRAY_SIZE(ctlModesFor11g) -
4991 SUB_NUM_CTL_MODES_AT_2G_40;
4992 pCtlMode = ctlModesFor11g;
4993 if (IS_CHAN_HT40(chan))
4995 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4997 /* Setup for CTL modes */
4998 /* CTL_11A, CTL_5GHT20 */
4999 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
5000 SUB_NUM_CTL_MODES_AT_5G_40;
5001 pCtlMode = ctlModesFor11a;
5002 if (IS_CHAN_HT40(chan))
5004 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
5008 * For MIMO, need to apply regulatory caps individually across
5009 * dynamically running modes: CCK, OFDM, HT20, HT40
5011 * The outer loop walks through each possible applicable runtime mode.
5012 * The inner loop walks through each ctlIndex entry in EEPROM.
5013 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
5015 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
5016 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
5017 (pCtlMode[ctlMode] == CTL_2GHT40);
5019 freq = centers.synth_center;
5020 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
5021 freq = centers.ext_center;
5023 freq = centers.ctl_center;
5025 ath_dbg(common, REGULATORY,
5026 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
5027 ctlMode, numCtlModes, isHt40CtlMode,
5028 (pCtlMode[ctlMode] & EXT_ADDITIVE));
5030 /* walk through each CTL index stored in EEPROM */
5032 ctlIndex = pEepData->ctlIndex_2G;
5033 ctlNum = AR9300_NUM_CTLS_2G;
5035 ctlIndex = pEepData->ctlIndex_5G;
5036 ctlNum = AR9300_NUM_CTLS_5G;
5039 twiceMaxEdgePower = MAX_RATE_POWER;
5040 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
5041 ath_dbg(common, REGULATORY,
5042 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
5043 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
5047 * compare test group from regulatory
5048 * channel list with test mode from pCtlMode
5051 if ((((cfgCtl & ~CTL_MODE_M) |
5052 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5054 (((cfgCtl & ~CTL_MODE_M) |
5055 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
5056 ((ctlIndex[i] & CTL_MODE_M) |
5059 ar9003_hw_get_max_edge_power(pEepData,
5063 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
5065 * Find the minimum of all CTL
5066 * edge powers that apply to
5070 min(twiceMaxEdgePower,
5074 twiceMaxEdgePower = twiceMinEdgePower;
5080 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
5082 ath_dbg(common, REGULATORY,
5083 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
5084 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
5085 scaledPower, minCtlPower);
5087 /* Apply ctl mode to correct target power set */
5088 switch (pCtlMode[ctlMode]) {
5090 for (i = ALL_TARGET_LEGACY_1L_5L;
5091 i <= ALL_TARGET_LEGACY_11S; i++)
5092 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5097 for (i = ALL_TARGET_LEGACY_6_24;
5098 i <= ALL_TARGET_LEGACY_54; i++)
5099 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5104 for (i = ALL_TARGET_HT20_0_8_16;
5105 i <= ALL_TARGET_HT20_23; i++) {
5106 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5108 if (ath9k_hw_mci_is_enabled(ah))
5110 (u8)min((u16)pPwrArray[i],
5111 ar9003_mci_get_max_txpower(ah,
5112 pCtlMode[ctlMode]));
5117 for (i = ALL_TARGET_HT40_0_8_16;
5118 i <= ALL_TARGET_HT40_23; i++) {
5119 pPwrArray[i] = (u8)min((u16)pPwrArray[i],
5121 if (ath9k_hw_mci_is_enabled(ah))
5123 (u8)min((u16)pPwrArray[i],
5124 ar9003_mci_get_max_txpower(ah,
5125 pCtlMode[ctlMode]));
5131 } /* end ctl mode checking */
5134 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5136 u8 mod_idx = mcs_idx % 8;
5139 return mod_idx ? (base_pwridx + 1) : base_pwridx;
5141 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5144 static void ar9003_paprd_set_txpower(struct ath_hw *ah,
5145 struct ath9k_channel *chan,
5146 u8 *targetPowerValT2)
5150 if (!ar9003_is_paprd_enabled(ah))
5153 if (IS_CHAN_HT40(chan))
5154 i = ALL_TARGET_HT40_7;
5156 i = ALL_TARGET_HT20_7;
5158 if (IS_CHAN_2GHZ(chan)) {
5159 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) &&
5160 !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) {
5161 if (IS_CHAN_HT40(chan))
5162 i = ALL_TARGET_HT40_0_8_16;
5164 i = ALL_TARGET_HT20_0_8_16;
5168 ah->paprd_target_power = targetPowerValT2[i];
5171 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5172 struct ath9k_channel *chan, u16 cfgCtl,
5173 u8 twiceAntennaReduction,
5174 u8 powerLimit, bool test)
5176 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5177 struct ath_common *common = ath9k_hw_common(ah);
5178 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5179 struct ar9300_modal_eep_header *modal_hdr;
5180 u8 targetPowerValT2[ar9300RateSize];
5181 u8 target_power_val_t2_eep[ar9300RateSize];
5182 unsigned int i = 0, paprd_scale_factor = 0;
5183 u8 pwr_idx, min_pwridx = 0;
5185 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5188 * Get target powers from EEPROM - our baseline for TX Power
5190 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5192 if (ar9003_is_paprd_enabled(ah)) {
5193 if (IS_CHAN_2GHZ(chan))
5194 modal_hdr = &eep->modalHeader2G;
5196 modal_hdr = &eep->modalHeader5G;
5198 ah->paprd_ratemask =
5199 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5200 AR9300_PAPRD_RATE_MASK;
5202 ah->paprd_ratemask_ht40 =
5203 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5204 AR9300_PAPRD_RATE_MASK;
5206 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5207 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5208 ALL_TARGET_HT20_0_8_16;
5210 if (!ah->paprd_table_write_done) {
5211 memcpy(target_power_val_t2_eep, targetPowerValT2,
5212 sizeof(targetPowerValT2));
5213 for (i = 0; i < 24; i++) {
5214 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5215 if (ah->paprd_ratemask & (1 << i)) {
5216 if (targetPowerValT2[pwr_idx] &&
5217 targetPowerValT2[pwr_idx] ==
5218 target_power_val_t2_eep[pwr_idx])
5219 targetPowerValT2[pwr_idx] -=
5224 memcpy(target_power_val_t2_eep, targetPowerValT2,
5225 sizeof(targetPowerValT2));
5228 ar9003_hw_set_power_per_rate_table(ah, chan,
5229 targetPowerValT2, cfgCtl,
5230 twiceAntennaReduction,
5233 if (ar9003_is_paprd_enabled(ah)) {
5234 for (i = 0; i < ar9300RateSize; i++) {
5235 if ((ah->paprd_ratemask & (1 << i)) &&
5236 (abs(targetPowerValT2[i] -
5237 target_power_val_t2_eep[i]) >
5238 paprd_scale_factor)) {
5239 ah->paprd_ratemask &= ~(1 << i);
5240 ath_dbg(common, EEPROM,
5241 "paprd disabled for mcs %d\n", i);
5246 regulatory->max_power_level = 0;
5247 for (i = 0; i < ar9300RateSize; i++) {
5248 if (targetPowerValT2[i] > regulatory->max_power_level)
5249 regulatory->max_power_level = targetPowerValT2[i];
5252 ath9k_hw_update_regulatory_maxpower(ah);
5257 for (i = 0; i < ar9300RateSize; i++) {
5258 ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n",
5259 i, targetPowerValT2[i]);
5262 /* Write target power array to registers */
5263 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5264 ar9003_hw_calibration_apply(ah, chan->channel);
5265 ar9003_paprd_set_txpower(ah, chan, targetPowerValT2);
5268 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5274 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5276 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5278 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5281 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5283 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5285 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5288 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5290 return ar9003_modal_header(ah, is2ghz)->spurChans;
5293 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5294 struct ath9k_channel *chan)
5296 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5298 if (IS_CHAN_2GHZ(chan))
5299 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5300 AR9300_PAPRD_SCALE_1);
5302 if (chan->channel >= 5700)
5303 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5304 AR9300_PAPRD_SCALE_1);
5305 else if (chan->channel >= 5400)
5306 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5307 AR9300_PAPRD_SCALE_2);
5309 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5310 AR9300_PAPRD_SCALE_1);
5314 const struct eeprom_ops eep_ar9300_ops = {
5315 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5316 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5317 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5318 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5319 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5320 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5321 .set_board_values = ath9k_hw_ar9300_set_board_values,
5322 .set_addac = ath9k_hw_ar9300_set_addac,
5323 .set_txpower = ath9k_hw_ar9300_set_txpower,
5324 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel