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"
22 #define COMP_HDR_LEN 4
23 #define COMP_CKSUM_LEN 2
25 #define LE16(x) __constant_cpu_to_le16(x)
26 #define LE32(x) __constant_cpu_to_le32(x)
28 /* Local defines to distinguish between extension and control CTL's */
29 #define EXT_ADDITIVE (0x8000)
30 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
31 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
32 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
34 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
35 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
37 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
39 #define EEPROM_DATA_LEN_9485 1088
41 static int ar9003_hw_power_interpolate(int32_t x,
42 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,
141 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
148 /* ar9300_cal_data_per_freq_op_loop 2g */
150 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
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} },
154 .calTarget_freqbin_Cck = {
158 .calTarget_freqbin_2G = {
163 .calTarget_freqbin_2GHT20 = {
168 .calTarget_freqbin_2GHT40 = {
173 .calTargetPowerCck = {
174 /* 1L-5L,5S,11L,11S */
175 { {36, 36, 36, 36} },
176 { {36, 36, 36, 36} },
178 .calTargetPower2G = {
180 { {32, 32, 28, 24} },
181 { {32, 32, 28, 24} },
182 { {32, 32, 28, 24} },
184 .calTargetPower2GHT20 = {
185 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
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} },
189 .calTargetPower2GHT40 = {
190 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
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} },
195 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
196 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
226 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
227 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
228 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
229 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
233 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
234 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
235 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
240 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
241 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
247 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
248 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
249 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
250 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
254 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
255 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
256 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
260 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
261 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
262 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
267 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
268 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
269 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
274 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
275 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
276 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
277 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
281 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
282 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
283 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
285 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
286 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
287 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
289 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
290 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
291 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
293 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
294 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
295 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
298 /* 4 idle,t1,t2,b (4 bits per setting) */
299 .antCtrlCommon = LE32(0x110),
300 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
301 .antCtrlCommon2 = LE32(0x22222),
302 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
304 LE16(0x000), LE16(0x000), LE16(0x000),
306 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
307 .xatten1DB = {0, 0, 0},
310 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
311 * for merlin (0xa20c/b20c 16:12
313 .xatten1Margin = {0, 0, 0},
316 /* spurChans spur channels in usual fbin coding format */
317 .spurChans = {0, 0, 0, 0, 0},
318 /* noiseFloorThreshCh Check if the register is per chain */
319 .noiseFloorThreshCh = {-1, 0, 0},
320 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
323 .txFrameToDataStart = 0x0e,
324 .txFrameToPaOn = 0x0e,
325 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
327 .switchSettling = 0x2d,
328 .adcDesiredSize = -30,
331 .txFrameToXpaOn = 0xe,
333 .papdRateMaskHt20 = LE32(0x0c80c080),
334 .papdRateMaskHt40 = LE32(0x0080c080),
335 .xlna_bias_strength = 0,
343 .xatten1DBLow = {0, 0, 0},
344 .xatten1MarginLow = {0, 0, 0},
345 .xatten1DBHigh = {0, 0, 0},
346 .xatten1MarginHigh = {0, 0, 0}
391 .calTarget_freqbin_5G = {
401 .calTarget_freqbin_5GHT20 = {
411 .calTarget_freqbin_5GHT40 = {
421 .calTargetPower5G = {
423 { {20, 20, 20, 10} },
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} },
432 .calTargetPower5GHT20 = {
434 * 0_8_16,1-3_9-11_17-19,
435 * 4,5,6,7,12,13,14,15,20,21,22,23
437 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
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} },
446 .calTargetPower5GHT40 = {
448 * 0_8_16,1-3_9-11_17-19,
449 * 4,5,6,7,12,13,14,15,20,21,22,23
451 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
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} },
461 0x10, 0x16, 0x18, 0x40, 0x46,
462 0x48, 0x30, 0x36, 0x38
466 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
467 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
468 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
469 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
470 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
471 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
472 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
473 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
476 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
477 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
478 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
479 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
480 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
481 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
482 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
483 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
487 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
488 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
489 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
490 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
491 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
492 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
493 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
494 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
498 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
499 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
500 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
501 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
502 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
503 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
504 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
505 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
509 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
510 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
511 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
512 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
513 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
514 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
515 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
516 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
520 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
521 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
522 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
523 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
524 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
525 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
526 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
527 /* Data[5].ctlEdges[7].bChannel */ 0xFF
531 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
532 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
533 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
534 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
535 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
536 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
537 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
538 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
542 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
543 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
544 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
545 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
546 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
547 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
548 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
549 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
553 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
554 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
555 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
556 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
557 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
558 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
559 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
560 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
566 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
567 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
572 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
573 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
578 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
579 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
584 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
585 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
590 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
591 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
596 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
597 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
602 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
603 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
608 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
609 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
614 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
615 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
621 static const struct ar9300_eeprom ar9300_x113 = {
623 .templateVersion = 6,
624 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
625 .custData = {"x113-023-f0000"},
627 .regDmn = { LE16(0), LE16(0x1f) },
628 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
630 .opFlags = AR5416_OPFLAGS_11A,
634 .blueToothOptions = 0,
636 .deviceType = 5, /* takes lower byte in eeprom location */
637 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
638 .params_for_tuning_caps = {0, 0},
639 .featureEnable = 0x0d,
641 * bit0 - enable tx temp comp - disabled
642 * bit1 - enable tx volt comp - disabled
643 * bit2 - enable fastClock - enabled
644 * bit3 - enable doubling - enabled
645 * bit4 - enable internal regulator - disabled
646 * bit5 - enable pa predistortion - disabled
648 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
649 .eepromWriteEnableGpio = 6,
650 .wlanDisableGpio = 0,
652 .rxBandSelectGpio = 0xff,
657 /* ar9300_modal_eep_header 2g */
658 /* 4 idle,t1,t2,b(4 bits per setting) */
659 .antCtrlCommon = LE32(0x110),
660 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
661 .antCtrlCommon2 = LE32(0x44444),
664 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
665 * rx1, rx12, b (2 bits each)
667 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
670 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
671 * for ar9280 (0xa20c/b20c 5:0)
673 .xatten1DB = {0, 0, 0},
676 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
677 * for ar9280 (0xa20c/b20c 16:12
679 .xatten1Margin = {0, 0, 0},
684 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
685 * channels in usual fbin coding format
687 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
690 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
691 * if the register is per chain
693 .noiseFloorThreshCh = {-1, 0, 0},
694 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
697 .txFrameToDataStart = 0x0e,
698 .txFrameToPaOn = 0x0e,
699 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
701 .switchSettling = 0x2c,
702 .adcDesiredSize = -30,
705 .txFrameToXpaOn = 0xe,
707 .papdRateMaskHt20 = LE32(0x0c80c080),
708 .papdRateMaskHt40 = LE32(0x0080c080),
709 .xlna_bias_strength = 0,
715 .ant_div_control = 0,
716 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
723 /* ar9300_cal_data_per_freq_op_loop 2g */
725 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
726 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
727 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
729 .calTarget_freqbin_Cck = {
733 .calTarget_freqbin_2G = {
738 .calTarget_freqbin_2GHT20 = {
743 .calTarget_freqbin_2GHT40 = {
748 .calTargetPowerCck = {
749 /* 1L-5L,5S,11L,11S */
750 { {34, 34, 34, 34} },
751 { {34, 34, 34, 34} },
753 .calTargetPower2G = {
755 { {34, 34, 32, 32} },
756 { {34, 34, 32, 32} },
757 { {34, 34, 32, 32} },
759 .calTargetPower2GHT20 = {
760 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
761 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
762 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
764 .calTargetPower2GHT40 = {
765 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
766 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
767 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
770 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
771 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
801 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
802 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
803 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
804 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
808 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
809 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
810 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
815 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
816 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
822 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
823 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
824 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
825 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
829 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
830 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
831 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
835 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
836 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
837 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
842 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
843 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
844 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
849 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
850 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
851 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
852 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
856 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
857 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
858 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
860 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
861 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
862 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
864 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
865 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
866 { { 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) } },
869 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
870 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
873 /* 4 idle,t1,t2,b (4 bits per setting) */
874 .antCtrlCommon = LE32(0x220),
875 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
876 .antCtrlCommon2 = LE32(0x11111),
877 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
879 LE16(0x150), LE16(0x150), LE16(0x150),
881 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
882 .xatten1DB = {0, 0, 0},
885 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
886 * for merlin (0xa20c/b20c 16:12
888 .xatten1Margin = {0, 0, 0},
891 /* spurChans spur channels in usual fbin coding format */
892 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
893 /* noiseFloorThreshCh Check if the register is per chain */
894 .noiseFloorThreshCh = {-1, 0, 0},
895 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
898 .txFrameToDataStart = 0x0e,
899 .txFrameToPaOn = 0x0e,
900 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
902 .switchSettling = 0x2d,
903 .adcDesiredSize = -30,
906 .txFrameToXpaOn = 0xe,
908 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
909 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
910 .xlna_bias_strength = 0,
917 .tempSlopeHigh = 105,
918 .xatten1DBLow = {0, 0, 0},
919 .xatten1MarginLow = {0, 0, 0},
920 .xatten1DBHigh = {0, 0, 0},
921 .xatten1MarginHigh = {0, 0, 0}
966 .calTarget_freqbin_5G = {
976 .calTarget_freqbin_5GHT20 = {
986 .calTarget_freqbin_5GHT40 = {
996 .calTargetPower5G = {
998 { {42, 40, 40, 34} },
999 { {42, 40, 40, 34} },
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} },
1007 .calTargetPower5GHT20 = {
1009 * 0_8_16,1-3_9-11_17-19,
1010 * 4,5,6,7,12,13,14,15,20,21,22,23
1012 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1013 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
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 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1019 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1021 .calTargetPower5GHT40 = {
1023 * 0_8_16,1-3_9-11_17-19,
1024 * 4,5,6,7,12,13,14,15,20,21,22,23
1026 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1027 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
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 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1033 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1036 0x10, 0x16, 0x18, 0x40, 0x46,
1037 0x48, 0x30, 0x36, 0x38
1041 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1042 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1043 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1044 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1045 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1046 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1047 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1048 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1051 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1052 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1053 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1054 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1055 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1056 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1057 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1058 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1062 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1063 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1064 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1065 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1066 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1067 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1068 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1069 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1073 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1074 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1075 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1076 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1077 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1078 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1079 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1080 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1084 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1085 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1086 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1087 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1088 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1089 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1090 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1091 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1095 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1096 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1097 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1098 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1099 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1100 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1101 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1102 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1106 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1107 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1108 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1109 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1110 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1111 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1112 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1113 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1117 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1118 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1119 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1120 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1121 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1122 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1123 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1124 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1128 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1129 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1130 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1131 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1132 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1133 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1134 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1135 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1138 .ctlPowerData_5G = {
1141 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1142 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1147 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1148 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1153 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1154 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1159 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1160 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1165 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1166 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1171 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1172 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1177 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1178 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1183 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1184 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1189 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1190 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1197 static const struct ar9300_eeprom ar9300_h112 = {
1199 .templateVersion = 3,
1200 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1201 .custData = {"h112-241-f0000"},
1203 .regDmn = { LE16(0), LE16(0x1f) },
1204 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1206 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1210 .blueToothOptions = 0,
1212 .deviceType = 5, /* takes lower byte in eeprom location */
1213 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1214 .params_for_tuning_caps = {0, 0},
1215 .featureEnable = 0x0d,
1217 * bit0 - enable tx temp comp - disabled
1218 * bit1 - enable tx volt comp - disabled
1219 * bit2 - enable fastClock - enabled
1220 * bit3 - enable doubling - enabled
1221 * bit4 - enable internal regulator - disabled
1222 * bit5 - enable pa predistortion - disabled
1224 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1225 .eepromWriteEnableGpio = 6,
1226 .wlanDisableGpio = 0,
1228 .rxBandSelectGpio = 0xff,
1233 /* ar9300_modal_eep_header 2g */
1234 /* 4 idle,t1,t2,b(4 bits per setting) */
1235 .antCtrlCommon = LE32(0x110),
1236 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1237 .antCtrlCommon2 = LE32(0x44444),
1240 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1241 * rx1, rx12, b (2 bits each)
1243 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1246 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1247 * for ar9280 (0xa20c/b20c 5:0)
1249 .xatten1DB = {0, 0, 0},
1252 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1253 * for ar9280 (0xa20c/b20c 16:12
1255 .xatten1Margin = {0, 0, 0},
1260 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1261 * channels in usual fbin coding format
1263 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1266 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1267 * if the register is per chain
1269 .noiseFloorThreshCh = {-1, 0, 0},
1270 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1273 .txFrameToDataStart = 0x0e,
1274 .txFrameToPaOn = 0x0e,
1275 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1277 .switchSettling = 0x2c,
1278 .adcDesiredSize = -30,
1281 .txFrameToXpaOn = 0xe,
1283 .papdRateMaskHt20 = LE32(0x0c80c080),
1284 .papdRateMaskHt40 = LE32(0x0080c080),
1285 .xlna_bias_strength = 0,
1287 0, 0, 0, 0, 0, 0, 0,
1291 .ant_div_control = 0,
1292 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1299 /* ar9300_cal_data_per_freq_op_loop 2g */
1301 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1302 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1303 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1305 .calTarget_freqbin_Cck = {
1309 .calTarget_freqbin_2G = {
1314 .calTarget_freqbin_2GHT20 = {
1319 .calTarget_freqbin_2GHT40 = {
1324 .calTargetPowerCck = {
1325 /* 1L-5L,5S,11L,11S */
1326 { {34, 34, 34, 34} },
1327 { {34, 34, 34, 34} },
1329 .calTargetPower2G = {
1331 { {34, 34, 32, 32} },
1332 { {34, 34, 32, 32} },
1333 { {34, 34, 32, 32} },
1335 .calTargetPower2GHT20 = {
1336 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1337 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1338 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1340 .calTargetPower2GHT40 = {
1341 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1342 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1343 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1346 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1347 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1377 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1378 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1379 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1380 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1384 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1385 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1386 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1391 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1392 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1398 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1399 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1400 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1401 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1405 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1406 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1407 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1411 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1412 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1413 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1418 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1419 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1420 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1425 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1426 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1427 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1428 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1431 .ctlPowerData_2G = {
1432 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1433 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1434 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1436 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
1437 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1438 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1440 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1441 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1442 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), 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, 1), CTL(60, 1) } },
1446 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1449 /* 4 idle,t1,t2,b (4 bits per setting) */
1450 .antCtrlCommon = LE32(0x220),
1451 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1452 .antCtrlCommon2 = LE32(0x44444),
1453 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1455 LE16(0x150), LE16(0x150), LE16(0x150),
1457 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1458 .xatten1DB = {0, 0, 0},
1461 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1462 * for merlin (0xa20c/b20c 16:12
1464 .xatten1Margin = {0, 0, 0},
1467 /* spurChans spur channels in usual fbin coding format */
1468 .spurChans = {0, 0, 0, 0, 0},
1469 /* noiseFloorThreshCh Check if the register is per chain */
1470 .noiseFloorThreshCh = {-1, 0, 0},
1471 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1474 .txFrameToDataStart = 0x0e,
1475 .txFrameToPaOn = 0x0e,
1476 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1478 .switchSettling = 0x2d,
1479 .adcDesiredSize = -30,
1482 .txFrameToXpaOn = 0xe,
1484 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1485 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1486 .xlna_bias_strength = 0,
1488 0, 0, 0, 0, 0, 0, 0,
1493 .tempSlopeHigh = 50,
1494 .xatten1DBLow = {0, 0, 0},
1495 .xatten1MarginLow = {0, 0, 0},
1496 .xatten1DBHigh = {0, 0, 0},
1497 .xatten1MarginHigh = {0, 0, 0}
1542 .calTarget_freqbin_5G = {
1552 .calTarget_freqbin_5GHT20 = {
1562 .calTarget_freqbin_5GHT40 = {
1572 .calTargetPower5G = {
1574 { {30, 30, 28, 24} },
1575 { {30, 30, 28, 24} },
1576 { {30, 30, 28, 24} },
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} },
1583 .calTargetPower5GHT20 = {
1585 * 0_8_16,1-3_9-11_17-19,
1586 * 4,5,6,7,12,13,14,15,20,21,22,23
1588 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1589 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1590 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1591 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1592 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1593 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1594 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1595 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1597 .calTargetPower5GHT40 = {
1599 * 0_8_16,1-3_9-11_17-19,
1600 * 4,5,6,7,12,13,14,15,20,21,22,23
1602 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1603 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1604 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1605 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1606 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1607 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1608 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1609 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1612 0x10, 0x16, 0x18, 0x40, 0x46,
1613 0x48, 0x30, 0x36, 0x38
1617 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1618 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1619 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1620 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1621 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1622 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1623 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1624 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1627 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1628 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1629 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1630 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1631 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1632 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1633 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1634 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1638 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1639 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1640 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1641 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1642 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1643 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1644 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1645 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1649 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1650 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1651 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1652 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1653 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1654 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1655 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1656 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1660 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1661 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1662 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1663 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1664 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1665 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1666 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1667 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1671 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1672 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1673 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1674 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1675 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1676 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1677 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1678 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1682 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1683 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1684 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1685 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1686 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1687 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1688 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1689 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1693 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1694 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1695 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1696 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1697 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1698 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1699 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1700 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1704 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1705 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1706 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1707 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1708 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1709 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1710 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1711 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1714 .ctlPowerData_5G = {
1717 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1718 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1723 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1724 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1729 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1730 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1735 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1736 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1741 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1742 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1747 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1748 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1753 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1754 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1759 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1760 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1765 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1766 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1773 static const struct ar9300_eeprom ar9300_x112 = {
1775 .templateVersion = 5,
1776 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1777 .custData = {"x112-041-f0000"},
1779 .regDmn = { LE16(0), LE16(0x1f) },
1780 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1782 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1786 .blueToothOptions = 0,
1788 .deviceType = 5, /* takes lower byte in eeprom location */
1789 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1790 .params_for_tuning_caps = {0, 0},
1791 .featureEnable = 0x0d,
1793 * bit0 - enable tx temp comp - disabled
1794 * bit1 - enable tx volt comp - disabled
1795 * bit2 - enable fastclock - enabled
1796 * bit3 - enable doubling - enabled
1797 * bit4 - enable internal regulator - disabled
1798 * bit5 - enable pa predistortion - disabled
1800 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1801 .eepromWriteEnableGpio = 6,
1802 .wlanDisableGpio = 0,
1804 .rxBandSelectGpio = 0xff,
1809 /* ar9300_modal_eep_header 2g */
1810 /* 4 idle,t1,t2,b(4 bits per setting) */
1811 .antCtrlCommon = LE32(0x110),
1812 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1813 .antCtrlCommon2 = LE32(0x22222),
1816 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1817 * rx1, rx12, b (2 bits each)
1819 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1822 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1823 * for ar9280 (0xa20c/b20c 5:0)
1825 .xatten1DB = {0x1b, 0x1b, 0x1b},
1828 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1829 * for ar9280 (0xa20c/b20c 16:12
1831 .xatten1Margin = {0x15, 0x15, 0x15},
1836 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1837 * channels in usual fbin coding format
1839 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1842 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1843 * if the register is per chain
1845 .noiseFloorThreshCh = {-1, 0, 0},
1846 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1849 .txFrameToDataStart = 0x0e,
1850 .txFrameToPaOn = 0x0e,
1851 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1853 .switchSettling = 0x2c,
1854 .adcDesiredSize = -30,
1857 .txFrameToXpaOn = 0xe,
1859 .papdRateMaskHt20 = LE32(0x0c80c080),
1860 .papdRateMaskHt40 = LE32(0x0080c080),
1861 .xlna_bias_strength = 0,
1863 0, 0, 0, 0, 0, 0, 0,
1867 .ant_div_control = 0,
1868 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1875 /* ar9300_cal_data_per_freq_op_loop 2g */
1877 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1878 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1879 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1881 .calTarget_freqbin_Cck = {
1885 .calTarget_freqbin_2G = {
1890 .calTarget_freqbin_2GHT20 = {
1895 .calTarget_freqbin_2GHT40 = {
1900 .calTargetPowerCck = {
1901 /* 1L-5L,5S,11L,11s */
1902 { {38, 38, 38, 38} },
1903 { {38, 38, 38, 38} },
1905 .calTargetPower2G = {
1907 { {38, 38, 36, 34} },
1908 { {38, 38, 36, 34} },
1909 { {38, 38, 34, 32} },
1911 .calTargetPower2GHT20 = {
1912 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1913 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1914 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1916 .calTargetPower2GHT40 = {
1917 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1918 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1919 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1922 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1923 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1953 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1954 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1955 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1956 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1960 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1961 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1962 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1967 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1968 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1974 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
1975 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
1976 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
1977 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
1981 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1982 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1983 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1987 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1988 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1989 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1994 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1995 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1996 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2001 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2002 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2003 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2004 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2007 .ctlPowerData_2G = {
2008 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2009 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2010 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2012 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2013 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2014 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2016 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), 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, 0), CTL(60, 0) } },
2021 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2022 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2025 /* 4 idle,t1,t2,b (4 bits per setting) */
2026 .antCtrlCommon = LE32(0x110),
2027 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2028 .antCtrlCommon2 = LE32(0x22222),
2029 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2031 LE16(0x0), LE16(0x0), LE16(0x0),
2033 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2034 .xatten1DB = {0x13, 0x19, 0x17},
2037 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2038 * for merlin (0xa20c/b20c 16:12
2040 .xatten1Margin = {0x19, 0x19, 0x19},
2043 /* spurChans spur channels in usual fbin coding format */
2044 .spurChans = {0, 0, 0, 0, 0},
2045 /* noiseFloorThreshch check if the register is per chain */
2046 .noiseFloorThreshCh = {-1, 0, 0},
2047 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2050 .txFrameToDataStart = 0x0e,
2051 .txFrameToPaOn = 0x0e,
2052 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2054 .switchSettling = 0x2d,
2055 .adcDesiredSize = -30,
2058 .txFrameToXpaOn = 0xe,
2060 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2061 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2062 .xlna_bias_strength = 0,
2064 0, 0, 0, 0, 0, 0, 0,
2069 .tempSlopeHigh = 105,
2070 .xatten1DBLow = {0x10, 0x14, 0x10},
2071 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2072 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2073 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2118 .calTarget_freqbin_5G = {
2128 .calTarget_freqbin_5GHT20 = {
2138 .calTarget_freqbin_5GHT40 = {
2148 .calTargetPower5G = {
2150 { {32, 32, 28, 26} },
2151 { {32, 32, 28, 26} },
2152 { {32, 32, 28, 26} },
2153 { {32, 32, 26, 24} },
2154 { {32, 32, 26, 24} },
2155 { {32, 32, 24, 22} },
2156 { {30, 30, 24, 22} },
2157 { {30, 30, 24, 22} },
2159 .calTargetPower5GHT20 = {
2161 * 0_8_16,1-3_9-11_17-19,
2162 * 4,5,6,7,12,13,14,15,20,21,22,23
2164 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2165 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2166 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2167 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2168 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2169 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2170 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2171 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2173 .calTargetPower5GHT40 = {
2175 * 0_8_16,1-3_9-11_17-19,
2176 * 4,5,6,7,12,13,14,15,20,21,22,23
2178 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2179 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2180 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2181 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2182 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2183 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2184 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2185 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2188 0x10, 0x16, 0x18, 0x40, 0x46,
2189 0x48, 0x30, 0x36, 0x38
2193 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2194 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2195 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2196 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2197 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2198 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2199 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2200 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2203 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2204 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2205 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2206 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2207 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2208 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2209 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2210 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2214 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2215 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2216 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2217 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2218 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2219 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2220 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2221 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2225 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2226 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2227 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2228 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2229 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2230 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2231 /* Data[3].ctledges[6].bchannel */ 0xFF,
2232 /* Data[3].ctledges[7].bchannel */ 0xFF,
2236 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2237 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2238 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2239 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2240 /* Data[4].ctledges[4].bchannel */ 0xFF,
2241 /* Data[4].ctledges[5].bchannel */ 0xFF,
2242 /* Data[4].ctledges[6].bchannel */ 0xFF,
2243 /* Data[4].ctledges[7].bchannel */ 0xFF,
2247 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2248 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2249 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2250 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2251 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2252 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2253 /* Data[5].ctledges[6].bchannel */ 0xFF,
2254 /* Data[5].ctledges[7].bchannel */ 0xFF
2258 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2259 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2260 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2261 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2262 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2263 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2264 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2265 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2269 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2270 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2271 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2272 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2273 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2274 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2275 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2276 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2280 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2281 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2282 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2283 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2284 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2285 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2286 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2287 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2290 .ctlPowerData_5G = {
2293 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2294 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2299 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2300 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2305 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2306 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2311 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2312 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2317 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2318 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2323 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2324 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2329 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2330 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2335 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2336 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2341 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2342 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2348 static const struct ar9300_eeprom ar9300_h116 = {
2350 .templateVersion = 4,
2351 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2352 .custData = {"h116-041-f0000"},
2354 .regDmn = { LE16(0), LE16(0x1f) },
2355 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2357 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2361 .blueToothOptions = 0,
2363 .deviceType = 5, /* takes lower byte in eeprom location */
2364 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2365 .params_for_tuning_caps = {0, 0},
2366 .featureEnable = 0x0d,
2368 * bit0 - enable tx temp comp - disabled
2369 * bit1 - enable tx volt comp - disabled
2370 * bit2 - enable fastClock - enabled
2371 * bit3 - enable doubling - enabled
2372 * bit4 - enable internal regulator - disabled
2373 * bit5 - enable pa predistortion - disabled
2375 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2376 .eepromWriteEnableGpio = 6,
2377 .wlanDisableGpio = 0,
2379 .rxBandSelectGpio = 0xff,
2384 /* ar9300_modal_eep_header 2g */
2385 /* 4 idle,t1,t2,b(4 bits per setting) */
2386 .antCtrlCommon = LE32(0x110),
2387 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2388 .antCtrlCommon2 = LE32(0x44444),
2391 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2392 * rx1, rx12, b (2 bits each)
2394 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2397 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2398 * for ar9280 (0xa20c/b20c 5:0)
2400 .xatten1DB = {0x1f, 0x1f, 0x1f},
2403 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2404 * for ar9280 (0xa20c/b20c 16:12
2406 .xatten1Margin = {0x12, 0x12, 0x12},
2411 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2412 * channels in usual fbin coding format
2414 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2417 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2418 * if the register is per chain
2420 .noiseFloorThreshCh = {-1, 0, 0},
2421 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2424 .txFrameToDataStart = 0x0e,
2425 .txFrameToPaOn = 0x0e,
2426 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2428 .switchSettling = 0x2c,
2429 .adcDesiredSize = -30,
2432 .txFrameToXpaOn = 0xe,
2434 .papdRateMaskHt20 = LE32(0x0c80C080),
2435 .papdRateMaskHt40 = LE32(0x0080C080),
2436 .xlna_bias_strength = 0,
2438 0, 0, 0, 0, 0, 0, 0,
2442 .ant_div_control = 0,
2443 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2450 /* ar9300_cal_data_per_freq_op_loop 2g */
2452 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2453 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2454 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2456 .calTarget_freqbin_Cck = {
2460 .calTarget_freqbin_2G = {
2465 .calTarget_freqbin_2GHT20 = {
2470 .calTarget_freqbin_2GHT40 = {
2475 .calTargetPowerCck = {
2476 /* 1L-5L,5S,11L,11S */
2477 { {34, 34, 34, 34} },
2478 { {34, 34, 34, 34} },
2480 .calTargetPower2G = {
2482 { {34, 34, 32, 32} },
2483 { {34, 34, 32, 32} },
2484 { {34, 34, 32, 32} },
2486 .calTargetPower2GHT20 = {
2487 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2488 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2489 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2491 .calTargetPower2GHT40 = {
2492 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2493 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2494 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2497 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2498 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2528 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2529 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2530 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2531 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2535 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2536 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2537 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2542 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2543 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2549 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2550 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2551 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2552 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2556 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2557 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2558 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2562 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2563 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2564 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2569 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2570 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2571 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2576 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2577 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2578 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2579 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2582 .ctlPowerData_2G = {
2583 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2584 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2585 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2587 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
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) } },
2591 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2592 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2593 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2595 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2596 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2597 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2600 /* 4 idle,t1,t2,b (4 bits per setting) */
2601 .antCtrlCommon = LE32(0x220),
2602 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2603 .antCtrlCommon2 = LE32(0x44444),
2604 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2606 LE16(0x150), LE16(0x150), LE16(0x150),
2608 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2609 .xatten1DB = {0x19, 0x19, 0x19},
2612 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2613 * for merlin (0xa20c/b20c 16:12
2615 .xatten1Margin = {0x14, 0x14, 0x14},
2618 /* spurChans spur channels in usual fbin coding format */
2619 .spurChans = {0, 0, 0, 0, 0},
2620 /* noiseFloorThreshCh Check if the register is per chain */
2621 .noiseFloorThreshCh = {-1, 0, 0},
2622 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2625 .txFrameToDataStart = 0x0e,
2626 .txFrameToPaOn = 0x0e,
2627 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2629 .switchSettling = 0x2d,
2630 .adcDesiredSize = -30,
2633 .txFrameToXpaOn = 0xe,
2635 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2636 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2637 .xlna_bias_strength = 0,
2639 0, 0, 0, 0, 0, 0, 0,
2644 .tempSlopeHigh = 50,
2645 .xatten1DBLow = {0, 0, 0},
2646 .xatten1MarginLow = {0, 0, 0},
2647 .xatten1DBHigh = {0, 0, 0},
2648 .xatten1MarginHigh = {0, 0, 0}
2693 .calTarget_freqbin_5G = {
2703 .calTarget_freqbin_5GHT20 = {
2713 .calTarget_freqbin_5GHT40 = {
2723 .calTargetPower5G = {
2725 { {30, 30, 28, 24} },
2726 { {30, 30, 28, 24} },
2727 { {30, 30, 28, 24} },
2728 { {30, 30, 28, 24} },
2729 { {30, 30, 28, 24} },
2730 { {30, 30, 28, 24} },
2731 { {30, 30, 28, 24} },
2732 { {30, 30, 28, 24} },
2734 .calTargetPower5GHT20 = {
2736 * 0_8_16,1-3_9-11_17-19,
2737 * 4,5,6,7,12,13,14,15,20,21,22,23
2739 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2740 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2741 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2742 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2743 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2744 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2745 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2746 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2748 .calTargetPower5GHT40 = {
2750 * 0_8_16,1-3_9-11_17-19,
2751 * 4,5,6,7,12,13,14,15,20,21,22,23
2753 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2754 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2755 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2756 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2757 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2758 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2759 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2760 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2763 0x10, 0x16, 0x18, 0x40, 0x46,
2764 0x48, 0x30, 0x36, 0x38
2768 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2769 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2770 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2771 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2772 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2773 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2774 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2775 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2778 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2779 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2780 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2781 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2782 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2783 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2784 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2785 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2789 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2790 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2791 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2792 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2793 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2794 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2795 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2796 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2800 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2801 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2802 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2803 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2804 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2805 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2806 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2807 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2811 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2812 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2813 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2814 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2815 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2816 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2817 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2818 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2822 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2823 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2824 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2825 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2826 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2827 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2828 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2829 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2833 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2834 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2835 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2836 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2837 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2838 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2839 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2840 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2844 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2845 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2846 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2847 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2848 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2849 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2850 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2851 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2855 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2856 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2857 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2858 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2859 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2860 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2861 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2862 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2865 .ctlPowerData_5G = {
2868 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2869 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2874 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2875 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2880 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2881 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2886 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2887 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2892 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2893 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2898 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2899 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2904 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2905 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2910 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2911 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2916 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2917 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2924 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2932 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2934 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2937 for (it = 0; it < N_LOOP; it++)
2938 if (ar9300_eep_templates[it]->templateVersion == id)
2939 return ar9300_eep_templates[it];
2944 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2949 static int interpolate(int x, int xa, int xb, int ya, int yb)
2951 int bf, factor, plus;
2953 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2956 return ya + factor + plus;
2959 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2960 enum eeprom_param param)
2962 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2963 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
2967 return get_unaligned_be16(eep->macAddr);
2969 return get_unaligned_be16(eep->macAddr + 2);
2971 return get_unaligned_be16(eep->macAddr + 4);
2973 return le16_to_cpu(pBase->regDmn[0]);
2975 return pBase->deviceCap;
2977 return pBase->opCapFlags.opFlags;
2979 return pBase->rfSilent;
2981 return (pBase->txrxMask >> 4) & 0xf;
2983 return pBase->txrxMask & 0xf;
2985 return !!(pBase->featureEnable & BIT(5));
2986 case EEP_CHAIN_MASK_REDUCE:
2987 return (pBase->miscConfiguration >> 0x3) & 0x1;
2988 case EEP_ANT_DIV_CTL1:
2989 return eep->base_ext1.ant_div_control;
2990 case EEP_ANTENNA_GAIN_5G:
2991 return eep->modalHeader5G.antennaGain;
2992 case EEP_ANTENNA_GAIN_2G:
2993 return eep->modalHeader2G.antennaGain;
2999 static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
3004 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3007 *buffer = (val >> (8 * (address % 2))) & 0xff;
3011 static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
3016 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3019 buffer[0] = val >> 8;
3020 buffer[1] = val & 0xff;
3025 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3028 struct ath_common *common = ath9k_hw_common(ah);
3031 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3032 ath_dbg(common, EEPROM, "eeprom address not in range\n");
3037 * Since we're reading the bytes in reverse order from a little-endian
3038 * word stream, an even address means we only use the lower half of
3039 * the 16-bit word at that address
3041 if (address % 2 == 0) {
3042 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
3048 for (i = 0; i < count / 2; i++) {
3049 if (!ar9300_eeprom_read_word(common, address, buffer))
3057 if (!ar9300_eeprom_read_byte(common, address, buffer))
3063 ath_dbg(common, EEPROM, "unable to read eeprom region at offset %d\n",
3068 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3070 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3072 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3073 AR9300_OTP_STATUS_VALID, 1000))
3076 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3080 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3086 for (i = 0; i < count; i++) {
3087 int offset = 8 * ((address - i) % 4);
3088 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3091 buffer[i] = (data >> offset) & 0xff;
3098 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3099 int *length, int *major, int *minor)
3101 unsigned long value[4];
3107 *code = ((value[0] >> 5) & 0x0007);
3108 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3109 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3110 *major = (value[2] & 0x000f);
3111 *minor = (value[3] & 0x00ff);
3114 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3116 int it, checksum = 0;
3118 for (it = 0; it < dsize; it++) {
3119 checksum += data[it];
3126 static bool ar9300_uncompress_block(struct ath_hw *ah,
3136 struct ath_common *common = ath9k_hw_common(ah);
3140 for (it = 0; it < size; it += (length+2)) {
3144 length = block[it+1];
3147 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3148 ath_dbg(common, EEPROM,
3149 "Restore at %d: spot=%d offset=%d length=%d\n",
3150 it, spot, offset, length);
3151 memcpy(&mptr[spot], &block[it+2], length);
3153 } else if (length > 0) {
3154 ath_dbg(common, EEPROM,
3155 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3156 it, spot, offset, length);
3163 static int ar9300_compress_decision(struct ath_hw *ah,
3168 u8 *word, int length, int mdata_size)
3170 struct ath_common *common = ath9k_hw_common(ah);
3171 const struct ar9300_eeprom *eep = NULL;
3175 if (length != mdata_size) {
3176 ath_dbg(common, EEPROM,
3177 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3178 mdata_size, length);
3181 memcpy(mptr, word + COMP_HDR_LEN, length);
3182 ath_dbg(common, EEPROM,
3183 "restored eeprom %d: uncompressed, length %d\n",
3186 case _CompressBlock:
3187 if (reference == 0) {
3189 eep = ar9003_eeprom_struct_find_by_id(reference);
3191 ath_dbg(common, EEPROM,
3192 "can't find reference eeprom struct %d\n",
3196 memcpy(mptr, eep, mdata_size);
3198 ath_dbg(common, EEPROM,
3199 "restore eeprom %d: block, reference %d, length %d\n",
3200 it, reference, length);
3201 ar9300_uncompress_block(ah, mptr, mdata_size,
3202 (word + COMP_HDR_LEN), length);
3205 ath_dbg(common, EEPROM, "unknown compression code %d\n", code);
3211 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3214 static bool ar9300_check_header(void *data)
3217 return !(*word == 0 || *word == ~0);
3220 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3225 if (!read(ah, base_addr, header, 4))
3228 return ar9300_check_header(header);
3231 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3234 struct ath_common *common = ath9k_hw_common(ah);
3235 u16 *data = (u16 *) mptr;
3238 for (i = 0; i < mdata_size / 2; i++, data++)
3239 ath9k_hw_nvram_read(common, i, data);
3244 * Read the configuration data from the eeprom.
3245 * The data can be put in any specified memory buffer.
3247 * Returns -1 on error.
3248 * Returns address of next memory location on success.
3250 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3251 u8 *mptr, int mdata_size)
3258 int reference, length, major, minor;
3261 u16 checksum, mchecksum;
3262 struct ath_common *common = ath9k_hw_common(ah);
3263 struct ar9300_eeprom *eep;
3264 eeprom_read_op read;
3266 if (ath9k_hw_use_flash(ah)) {
3269 ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3271 /* check if eeprom contains valid data */
3272 eep = (struct ar9300_eeprom *) mptr;
3273 txrx = eep->baseEepHeader.txrxMask;
3274 if (txrx != 0 && txrx != 0xff)
3278 word = kzalloc(2048, GFP_KERNEL);
3282 memcpy(mptr, &ar9300_default, mdata_size);
3284 read = ar9300_read_eeprom;
3285 if (AR_SREV_9485(ah))
3286 cptr = AR9300_BASE_ADDR_4K;
3287 else if (AR_SREV_9330(ah))
3288 cptr = AR9300_BASE_ADDR_512;
3290 cptr = AR9300_BASE_ADDR;
3291 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3293 if (ar9300_check_eeprom_header(ah, read, cptr))
3296 cptr = AR9300_BASE_ADDR_512;
3297 ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n",
3299 if (ar9300_check_eeprom_header(ah, read, cptr))
3302 read = ar9300_read_otp;
3303 cptr = AR9300_BASE_ADDR;
3304 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3305 if (ar9300_check_eeprom_header(ah, read, cptr))
3308 cptr = AR9300_BASE_ADDR_512;
3309 ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr);
3310 if (ar9300_check_eeprom_header(ah, read, cptr))
3316 ath_dbg(common, EEPROM, "Found valid EEPROM data\n");
3318 for (it = 0; it < MSTATE; it++) {
3319 if (!read(ah, cptr, word, COMP_HDR_LEN))
3322 if (!ar9300_check_header(word))
3325 ar9300_comp_hdr_unpack(word, &code, &reference,
3326 &length, &major, &minor);
3327 ath_dbg(common, EEPROM,
3328 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3329 cptr, code, reference, length, major, minor);
3330 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3331 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3332 ath_dbg(common, EEPROM, "Skipping bad header\n");
3333 cptr -= COMP_HDR_LEN;
3338 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3339 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3340 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3341 ath_dbg(common, EEPROM, "checksum %x %x\n",
3342 checksum, mchecksum);
3343 if (checksum == mchecksum) {
3344 ar9300_compress_decision(ah, it, code, reference, mptr,
3345 word, length, mdata_size);
3347 ath_dbg(common, EEPROM,
3348 "skipping block with bad checksum\n");
3350 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3362 * Restore the configuration structure by reading the eeprom.
3363 * This function destroys any existing in-memory structure
3366 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3368 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3370 if (ar9300_eeprom_restore_internal(ah, mptr,
3371 sizeof(struct ar9300_eeprom)) < 0)
3377 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3378 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3379 struct ar9300_modal_eep_header *modal_hdr)
3381 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3382 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3383 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3384 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3385 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3386 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3387 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3388 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3389 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3390 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3391 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3392 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3393 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3394 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3395 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3396 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3397 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3398 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3399 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3400 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3401 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3402 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3403 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3404 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3405 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3406 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3407 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3408 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3409 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3410 PR_EEP("txClip", modal_hdr->txClip);
3411 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3416 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3417 u8 *buf, u32 len, u32 size)
3419 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3420 struct ar9300_base_eep_hdr *pBase;
3422 if (!dump_base_hdr) {
3423 len += snprintf(buf + len, size - len,
3424 "%20s :\n", "2GHz modal Header");
3425 len = ar9003_dump_modal_eeprom(buf, len, size,
3426 &eep->modalHeader2G);
3427 len += snprintf(buf + len, size - len,
3428 "%20s :\n", "5GHz modal Header");
3429 len = ar9003_dump_modal_eeprom(buf, len, size,
3430 &eep->modalHeader5G);
3434 pBase = &eep->baseEepHeader;
3436 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3437 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3438 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3439 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3440 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3441 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3442 AR5416_OPFLAGS_11A));
3443 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3444 AR5416_OPFLAGS_11G));
3445 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3446 AR5416_OPFLAGS_N_2G_HT20));
3447 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3448 AR5416_OPFLAGS_N_2G_HT40));
3449 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3450 AR5416_OPFLAGS_N_5G_HT20));
3451 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3452 AR5416_OPFLAGS_N_5G_HT40));
3453 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3454 PR_EEP("RF Silent", pBase->rfSilent);
3455 PR_EEP("BT option", pBase->blueToothOptions);
3456 PR_EEP("Device Cap", pBase->deviceCap);
3457 PR_EEP("Device Type", pBase->deviceType);
3458 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3459 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3460 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3461 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3462 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3463 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3464 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3465 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3466 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3467 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3468 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3469 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3470 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3471 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3472 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3473 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3474 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3475 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3476 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3478 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3479 ah->eeprom.ar9300_eep.macAddr);
3487 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3488 u8 *buf, u32 len, u32 size)
3494 /* XXX: review hardware docs */
3495 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3497 return ah->eeprom.ar9300_eep.eepromVersion;
3500 /* XXX: could be read from the eepromVersion, not sure yet */
3501 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3506 static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
3509 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3512 return &eep->modalHeader2G;
3514 return &eep->modalHeader5G;
3517 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3519 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3521 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3522 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3523 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah))
3524 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3526 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3527 REG_RMW_FIELD(ah, AR_CH0_THERM,
3528 AR_CH0_THERM_XPABIASLVL_MSB,
3530 REG_RMW_FIELD(ah, AR_CH0_THERM,
3531 AR_CH0_THERM_XPASHORT2GND, 1);
3535 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
3537 return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
3541 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3543 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
3546 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3548 return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
3551 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
3554 __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
3555 return le16_to_cpu(val);
3558 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3563 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3564 AR_PHY_SWITCH_CHAIN_0,
3565 AR_PHY_SWITCH_CHAIN_1,
3566 AR_PHY_SWITCH_CHAIN_2,
3569 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3571 if (AR_SREV_9462(ah)) {
3572 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3573 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3574 } else if (AR_SREV_9550(ah)) {
3575 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3576 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3578 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3579 AR_SWITCH_TABLE_COM_ALL, value);
3583 * AR9462 defines new switch table for BT/WLAN,
3584 * here's new field name in XXX.ref for both 2G and 5G.
3585 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3586 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3587 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3589 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3590 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3592 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3593 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3595 if (AR_SREV_9462_20_OR_LATER(ah)) {
3596 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3597 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3598 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3599 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE);
3602 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3603 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3605 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3606 if ((ah->rxchainmask & BIT(chain)) ||
3607 (ah->txchainmask & BIT(chain))) {
3608 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3610 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3611 AR_SWITCH_TABLE_ALL, value);
3615 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3616 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3618 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3619 * are the fields present
3621 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3622 regval &= (~AR_ANT_DIV_CTRL_ALL);
3623 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3625 regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
3626 regval |= ((value >> 6) & 0x1) <<
3627 AR_PHY_9485_ANT_DIV_LNADIV_S;
3628 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3630 /*enable fast_div */
3631 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3632 regval &= (~AR_FAST_DIV_ENABLE);
3633 regval |= ((value >> 7) & 0x1) <<
3634 AR_FAST_DIV_ENABLE_S;
3635 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3637 ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
3638 /* check whether antenna diversity is enabled */
3639 if ((ant_div_ctl1 >> 0x6) == 0x3) {
3640 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3642 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3645 regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
3646 AR_PHY_9485_ANT_DIV_ALT_LNACONF |
3647 AR_PHY_9485_ANT_DIV_ALT_GAINTB |
3648 AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
3649 /* by default use LNA1 for the main antenna */
3650 regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
3651 AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
3652 regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
3653 AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
3654 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3662 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3664 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3665 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3669 drive_strength = pBase->miscConfiguration & BIT(0);
3670 if (!drive_strength)
3673 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3681 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3683 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3694 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3696 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3701 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3704 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3705 struct ath9k_channel *chan)
3709 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3711 if (chain >= 0 && chain < 3) {
3712 if (IS_CHAN_2GHZ(chan))
3713 return eep->modalHeader2G.xatten1DB[chain];
3714 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3715 t[0] = eep->base_ext2.xatten1DBLow[chain];
3717 t[1] = eep->modalHeader5G.xatten1DB[chain];
3719 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3721 value = ar9003_hw_power_interpolate((s32) chan->channel,
3725 return eep->modalHeader5G.xatten1DB[chain];
3732 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3733 struct ath9k_channel *chan)
3737 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3739 if (chain >= 0 && chain < 3) {
3740 if (IS_CHAN_2GHZ(chan))
3741 return eep->modalHeader2G.xatten1Margin[chain];
3742 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3743 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3745 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3747 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3749 value = ar9003_hw_power_interpolate((s32) chan->channel,
3753 return eep->modalHeader5G.xatten1Margin[chain];
3759 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3763 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3764 AR_PHY_EXT_ATTEN_CTL_1,
3765 AR_PHY_EXT_ATTEN_CTL_2,
3768 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3769 for (i = 0; i < 3; i++) {
3770 if (ah->txchainmask & BIT(i)) {
3771 value = ar9003_hw_atten_chain_get(ah, i, chan);
3772 REG_RMW_FIELD(ah, ext_atten_reg[i],
3773 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3775 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3776 REG_RMW_FIELD(ah, ext_atten_reg[i],
3777 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3783 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3787 while (pmu_set != REG_READ(ah, pmu_reg)) {
3790 REG_WRITE(ah, pmu_reg, pmu_set);
3797 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3799 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3800 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3803 if (pBase->featureEnable & BIT(4)) {
3804 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3807 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3808 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3809 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3812 if (AR_SREV_9330(ah)) {
3813 if (ah->is_clk_25mhz) {
3814 reg_pmu_set = (3 << 1) | (8 << 4) |
3815 (3 << 8) | (1 << 14) |
3816 (6 << 17) | (1 << 20) |
3819 reg_pmu_set = (4 << 1) | (7 << 4) |
3820 (3 << 8) | (1 << 14) |
3821 (6 << 17) | (1 << 20) |
3825 reg_pmu_set = (5 << 1) | (7 << 4) |
3826 (2 << 8) | (2 << 14) |
3827 (6 << 17) | (1 << 20) |
3828 (3 << 24) | (1 << 28);
3831 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3832 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3835 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3837 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3838 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3841 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3843 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3844 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3846 } else if (AR_SREV_9462(ah)) {
3847 reg_val = le32_to_cpu(pBase->swreg);
3848 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3850 /* Internal regulator is ON. Write swreg register. */
3851 reg_val = le32_to_cpu(pBase->swreg);
3852 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3853 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3854 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3855 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3856 /* Set REG_CONTROL1.SWREG_PROGRAM */
3857 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3859 AR_RTC_REG_CONTROL1) |
3860 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3863 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3864 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3865 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3869 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3870 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3873 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3874 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3877 } else if (AR_SREV_9462(ah))
3878 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3880 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3881 AR_RTC_FORCE_SWREG_PRD;
3882 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3888 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3890 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3891 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3893 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3896 if (eep->baseEepHeader.featureEnable & 0x40) {
3897 tuning_caps_param &= 0x7f;
3898 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3900 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3905 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3907 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3908 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
3910 s32 t[3], f[3] = {5180, 5500, 5785};
3912 if (!(pBase->miscConfiguration & BIT(1)))
3916 quick_drop = eep->modalHeader2G.quick_drop;
3918 t[0] = eep->base_ext1.quick_drop_low;
3919 t[1] = eep->modalHeader5G.quick_drop;
3920 t[2] = eep->base_ext1.quick_drop_high;
3921 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
3923 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
3926 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
3930 value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
3932 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3933 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
3934 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3935 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
3938 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
3940 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3943 if (!(eep->baseEepHeader.featureEnable & 0x80))
3946 if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah))
3949 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
3951 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3952 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
3954 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3955 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
3958 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
3960 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3963 if (!(eep->baseEepHeader.featureEnable & 0x40))
3966 if (!AR_SREV_9300(ah))
3969 bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
3970 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
3973 REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
3976 REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
3980 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3981 struct ath9k_channel *chan)
3983 bool is2ghz = IS_CHAN_2GHZ(chan);
3984 ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
3985 ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
3986 ar9003_hw_ant_ctrl_apply(ah, is2ghz);
3987 ar9003_hw_drive_strength_apply(ah);
3988 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
3989 ar9003_hw_atten_apply(ah, chan);
3990 ar9003_hw_quick_drop_apply(ah, chan->channel);
3991 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah))
3992 ar9003_hw_internal_regulator_apply(ah);
3993 ar9003_hw_apply_tuning_caps(ah);
3994 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
3997 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
3998 struct ath9k_channel *chan)
4003 * Returns the interpolated y value corresponding to the specified x value
4004 * from the np ordered pairs of data (px,py).
4005 * The pairs do not have to be in any order.
4006 * If the specified x value is less than any of the px,
4007 * the returned y value is equal to the py for the lowest px.
4008 * If the specified x value is greater than any of the px,
4009 * the returned y value is equal to the py for the highest px.
4011 static int ar9003_hw_power_interpolate(int32_t x,
4012 int32_t *px, int32_t *py, u_int16_t np)
4015 int lx = 0, ly = 0, lhave = 0;
4016 int hx = 0, hy = 0, hhave = 0;
4023 /* identify best lower and higher x calibration measurement */
4024 for (ip = 0; ip < np; ip++) {
4027 /* this measurement is higher than our desired x */
4029 if (!hhave || dx > (x - hx)) {
4030 /* new best higher x measurement */
4036 /* this measurement is lower than our desired x */
4038 if (!lhave || dx < (x - lx)) {
4039 /* new best lower x measurement */
4047 /* the low x is good */
4049 /* so is the high x */
4051 /* they're the same, so just pick one */
4054 else /* interpolate */
4055 y = interpolate(x, lx, hx, ly, hy);
4056 } else /* only low is good, use it */
4058 } else if (hhave) /* only high is good, use it */
4060 else /* nothing is good,this should never happen unless np=0, ???? */
4065 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4066 u16 rateIndex, u16 freq, bool is2GHz)
4069 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4070 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4071 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4072 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4076 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4077 pEepromTargetPwr = eep->calTargetPower2G;
4078 pFreqBin = eep->calTarget_freqbin_2G;
4080 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4081 pEepromTargetPwr = eep->calTargetPower5G;
4082 pFreqBin = eep->calTarget_freqbin_5G;
4086 * create array of channels and targetpower from
4087 * targetpower piers stored on eeprom
4089 for (i = 0; i < numPiers; i++) {
4090 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4091 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4094 /* interpolate to get target power for given frequency */
4095 return (u8) ar9003_hw_power_interpolate((s32) freq,
4097 targetPowerArray, numPiers);
4100 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4102 u16 freq, bool is2GHz)
4105 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4106 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4107 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4108 struct cal_tgt_pow_ht *pEepromTargetPwr;
4112 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4113 pEepromTargetPwr = eep->calTargetPower2GHT20;
4114 pFreqBin = eep->calTarget_freqbin_2GHT20;
4116 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4117 pEepromTargetPwr = eep->calTargetPower5GHT20;
4118 pFreqBin = eep->calTarget_freqbin_5GHT20;
4122 * create array of channels and targetpower
4123 * from targetpower piers stored on eeprom
4125 for (i = 0; i < numPiers; i++) {
4126 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4127 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4130 /* interpolate to get target power for given frequency */
4131 return (u8) ar9003_hw_power_interpolate((s32) freq,
4133 targetPowerArray, numPiers);
4136 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4138 u16 freq, bool is2GHz)
4141 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4142 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4143 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4144 struct cal_tgt_pow_ht *pEepromTargetPwr;
4148 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4149 pEepromTargetPwr = eep->calTargetPower2GHT40;
4150 pFreqBin = eep->calTarget_freqbin_2GHT40;
4152 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4153 pEepromTargetPwr = eep->calTargetPower5GHT40;
4154 pFreqBin = eep->calTarget_freqbin_5GHT40;
4158 * create array of channels and targetpower from
4159 * targetpower piers stored on eeprom
4161 for (i = 0; i < numPiers; i++) {
4162 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], is2GHz);
4163 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4166 /* interpolate to get target power for given frequency */
4167 return (u8) ar9003_hw_power_interpolate((s32) freq,
4169 targetPowerArray, numPiers);
4172 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4173 u16 rateIndex, u16 freq)
4175 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4176 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4177 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4178 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4179 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4180 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4183 * create array of channels and targetpower from
4184 * targetpower piers stored on eeprom
4186 for (i = 0; i < numPiers; i++) {
4187 freqArray[i] = ath9k_hw_fbin2freq(pFreqBin[i], 1);
4188 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4191 /* interpolate to get target power for given frequency */
4192 return (u8) ar9003_hw_power_interpolate((s32) freq,
4194 targetPowerArray, numPiers);
4197 /* Set tx power registers to array of values passed in */
4198 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4200 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4201 /* make sure forced gain is not set */
4202 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4204 /* Write the OFDM power per rate set */
4206 /* 6 (LSB), 9, 12, 18 (MSB) */
4207 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4208 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4209 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4210 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4211 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4213 /* 24 (LSB), 36, 48, 54 (MSB) */
4214 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4215 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4216 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4217 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4218 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4220 /* Write the CCK power per rate set */
4222 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4223 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4224 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4225 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4226 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4227 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4229 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4230 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4231 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4232 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4233 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4234 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4237 /* Write the power for duplicated frames - HT40 */
4239 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4240 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4241 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4242 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4243 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4244 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4247 /* Write the HT20 power per rate set */
4249 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4250 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4251 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4252 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4253 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4254 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4257 /* 6 (LSB), 7, 12, 13 (MSB) */
4258 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4259 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4260 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4261 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4262 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4265 /* 14 (LSB), 15, 20, 21 */
4266 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4267 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4268 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4269 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4270 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4273 /* Mixed HT20 and HT40 rates */
4275 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4276 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4277 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4278 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4279 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4280 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4284 * Write the HT40 power per rate set
4285 * correct PAR difference between HT40 and HT20/LEGACY
4286 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4288 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4289 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4290 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4291 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4292 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4295 /* 6 (LSB), 7, 12, 13 (MSB) */
4296 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4297 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4298 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4299 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4300 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4303 /* 14 (LSB), 15, 20, 21 */
4304 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4305 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4306 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4307 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4308 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4315 static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
4316 u8 *targetPowerValT2,
4319 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
4320 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
4322 targetPowerValT2[ALL_TARGET_LEGACY_36] =
4323 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
4325 targetPowerValT2[ALL_TARGET_LEGACY_48] =
4326 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
4328 targetPowerValT2[ALL_TARGET_LEGACY_54] =
4329 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
4333 static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
4334 u8 *targetPowerValT2)
4336 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4337 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4339 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4340 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4341 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4342 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4343 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4344 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4347 static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
4348 u8 *targetPowerValT2, bool is2GHz)
4350 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4351 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4353 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4354 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4356 targetPowerValT2[ALL_TARGET_HT20_4] =
4357 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4359 targetPowerValT2[ALL_TARGET_HT20_5] =
4360 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4362 targetPowerValT2[ALL_TARGET_HT20_6] =
4363 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4365 targetPowerValT2[ALL_TARGET_HT20_7] =
4366 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4368 targetPowerValT2[ALL_TARGET_HT20_12] =
4369 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4371 targetPowerValT2[ALL_TARGET_HT20_13] =
4372 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4374 targetPowerValT2[ALL_TARGET_HT20_14] =
4375 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4377 targetPowerValT2[ALL_TARGET_HT20_15] =
4378 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4380 targetPowerValT2[ALL_TARGET_HT20_20] =
4381 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4383 targetPowerValT2[ALL_TARGET_HT20_21] =
4384 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4386 targetPowerValT2[ALL_TARGET_HT20_22] =
4387 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4389 targetPowerValT2[ALL_TARGET_HT20_23] =
4390 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4394 static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
4396 u8 *targetPowerValT2,
4399 /* XXX: hard code for now, need to get from eeprom struct */
4400 u8 ht40PowerIncForPdadc = 0;
4402 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4403 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4404 is2GHz) + ht40PowerIncForPdadc;
4405 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4406 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4408 is2GHz) + ht40PowerIncForPdadc;
4409 targetPowerValT2[ALL_TARGET_HT40_4] =
4410 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4411 is2GHz) + ht40PowerIncForPdadc;
4412 targetPowerValT2[ALL_TARGET_HT40_5] =
4413 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4414 is2GHz) + ht40PowerIncForPdadc;
4415 targetPowerValT2[ALL_TARGET_HT40_6] =
4416 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4417 is2GHz) + ht40PowerIncForPdadc;
4418 targetPowerValT2[ALL_TARGET_HT40_7] =
4419 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4420 is2GHz) + ht40PowerIncForPdadc;
4421 targetPowerValT2[ALL_TARGET_HT40_12] =
4422 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4423 is2GHz) + ht40PowerIncForPdadc;
4424 targetPowerValT2[ALL_TARGET_HT40_13] =
4425 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4426 is2GHz) + ht40PowerIncForPdadc;
4427 targetPowerValT2[ALL_TARGET_HT40_14] =
4428 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4429 is2GHz) + ht40PowerIncForPdadc;
4430 targetPowerValT2[ALL_TARGET_HT40_15] =
4431 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4432 is2GHz) + ht40PowerIncForPdadc;
4433 targetPowerValT2[ALL_TARGET_HT40_20] =
4434 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4435 is2GHz) + ht40PowerIncForPdadc;
4436 targetPowerValT2[ALL_TARGET_HT40_21] =
4437 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4438 is2GHz) + ht40PowerIncForPdadc;
4439 targetPowerValT2[ALL_TARGET_HT40_22] =
4440 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4441 is2GHz) + ht40PowerIncForPdadc;
4442 targetPowerValT2[ALL_TARGET_HT40_23] =
4443 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4444 is2GHz) + ht40PowerIncForPdadc;
4447 static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
4448 struct ath9k_channel *chan,
4449 u8 *targetPowerValT2)
4451 bool is2GHz = IS_CHAN_2GHZ(chan);
4453 struct ath_common *common = ath9k_hw_common(ah);
4454 u16 freq = chan->channel;
4457 ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
4459 ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
4460 ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
4462 if (IS_CHAN_HT40(chan))
4463 ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
4466 for (i = 0; i < ar9300RateSize; i++) {
4467 ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n",
4468 i, targetPowerValT2[i]);
4472 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4478 int *ptemperature, int *pvoltage)
4481 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4483 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4484 struct ath_common *common = ath9k_hw_common(ah);
4486 if (ichain >= AR9300_MAX_CHAINS) {
4487 ath_dbg(common, EEPROM,
4488 "Invalid chain index, must be less than %d\n",
4493 if (mode) { /* 5GHz */
4494 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4495 ath_dbg(common, EEPROM,
4496 "Invalid 5GHz cal pier index, must be less than %d\n",
4497 AR9300_NUM_5G_CAL_PIERS);
4500 pCalPier = &(eep->calFreqPier5G[ipier]);
4501 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4504 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4505 ath_dbg(common, EEPROM,
4506 "Invalid 2GHz cal pier index, must be less than %d\n",
4507 AR9300_NUM_2G_CAL_PIERS);
4511 pCalPier = &(eep->calFreqPier2G[ipier]);
4512 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4516 *pfrequency = ath9k_hw_fbin2freq(*pCalPier, is2GHz);
4517 *pcorrection = pCalPierStruct->refPower;
4518 *ptemperature = pCalPierStruct->tempMeas;
4519 *pvoltage = pCalPierStruct->voltMeas;
4524 static int ar9003_hw_power_control_override(struct ath_hw *ah,
4527 int *voltage, int *temperature)
4530 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4533 REG_RMW(ah, AR_PHY_TPC_11_B0,
4534 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4535 AR_PHY_TPC_OLPC_GAIN_DELTA);
4536 if (ah->caps.tx_chainmask & BIT(1))
4537 REG_RMW(ah, AR_PHY_TPC_11_B1,
4538 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4539 AR_PHY_TPC_OLPC_GAIN_DELTA);
4540 if (ah->caps.tx_chainmask & BIT(2))
4541 REG_RMW(ah, AR_PHY_TPC_11_B2,
4542 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4543 AR_PHY_TPC_OLPC_GAIN_DELTA);
4545 /* enable open loop power control on chip */
4546 REG_RMW(ah, AR_PHY_TPC_6_B0,
4547 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4548 AR_PHY_TPC_6_ERROR_EST_MODE);
4549 if (ah->caps.tx_chainmask & BIT(1))
4550 REG_RMW(ah, AR_PHY_TPC_6_B1,
4551 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4552 AR_PHY_TPC_6_ERROR_EST_MODE);
4553 if (ah->caps.tx_chainmask & BIT(2))
4554 REG_RMW(ah, AR_PHY_TPC_6_B2,
4555 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4556 AR_PHY_TPC_6_ERROR_EST_MODE);
4559 * enable temperature compensation
4560 * Need to use register names
4562 if (frequency < 4000)
4563 tempSlope = eep->modalHeader2G.tempSlope;
4564 else if (eep->base_ext2.tempSlopeLow != 0) {
4565 t[0] = eep->base_ext2.tempSlopeLow;
4567 t[1] = eep->modalHeader5G.tempSlope;
4569 t[2] = eep->base_ext2.tempSlopeHigh;
4571 tempSlope = ar9003_hw_power_interpolate((s32) frequency,
4574 tempSlope = eep->modalHeader5G.tempSlope;
4576 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
4578 if (AR_SREV_9462_20(ah))
4579 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4580 AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope);
4583 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4589 /* Apply the recorded correction values. */
4590 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4592 int ichain, ipier, npier;
4594 int lfrequency[AR9300_MAX_CHAINS],
4595 lcorrection[AR9300_MAX_CHAINS],
4596 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4597 int hfrequency[AR9300_MAX_CHAINS],
4598 hcorrection[AR9300_MAX_CHAINS],
4599 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4601 int correction[AR9300_MAX_CHAINS],
4602 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4603 int pfrequency, pcorrection, ptemperature, pvoltage;
4604 struct ath_common *common = ath9k_hw_common(ah);
4606 mode = (frequency >= 4000);
4608 npier = AR9300_NUM_5G_CAL_PIERS;
4610 npier = AR9300_NUM_2G_CAL_PIERS;
4612 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4613 lfrequency[ichain] = 0;
4614 hfrequency[ichain] = 100000;
4616 /* identify best lower and higher frequency calibration measurement */
4617 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4618 for (ipier = 0; ipier < npier; ipier++) {
4619 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4620 &pfrequency, &pcorrection,
4621 &ptemperature, &pvoltage)) {
4622 fdiff = frequency - pfrequency;
4625 * this measurement is higher than
4626 * our desired frequency
4629 if (hfrequency[ichain] <= 0 ||
4630 hfrequency[ichain] >= 100000 ||
4632 (frequency - hfrequency[ichain])) {
4635 * frequency measurement
4637 hfrequency[ichain] = pfrequency;
4638 hcorrection[ichain] =
4640 htemperature[ichain] =
4642 hvoltage[ichain] = pvoltage;
4646 if (lfrequency[ichain] <= 0
4648 (frequency - lfrequency[ichain])) {
4651 * frequency measurement
4653 lfrequency[ichain] = pfrequency;
4654 lcorrection[ichain] =
4656 ltemperature[ichain] =
4658 lvoltage[ichain] = pvoltage;
4666 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4667 ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n",
4668 ichain, frequency, lfrequency[ichain],
4669 lcorrection[ichain], hfrequency[ichain],
4670 hcorrection[ichain]);
4671 /* they're the same, so just pick one */
4672 if (hfrequency[ichain] == lfrequency[ichain]) {
4673 correction[ichain] = lcorrection[ichain];
4674 voltage[ichain] = lvoltage[ichain];
4675 temperature[ichain] = ltemperature[ichain];
4677 /* the low frequency is good */
4678 else if (frequency - lfrequency[ichain] < 1000) {
4679 /* so is the high frequency, interpolate */
4680 if (hfrequency[ichain] - frequency < 1000) {
4682 correction[ichain] = interpolate(frequency,
4685 lcorrection[ichain],
4686 hcorrection[ichain]);
4688 temperature[ichain] = interpolate(frequency,
4691 ltemperature[ichain],
4692 htemperature[ichain]);
4694 voltage[ichain] = interpolate(frequency,
4700 /* only low is good, use it */
4702 correction[ichain] = lcorrection[ichain];
4703 temperature[ichain] = ltemperature[ichain];
4704 voltage[ichain] = lvoltage[ichain];
4707 /* only high is good, use it */
4708 else if (hfrequency[ichain] - frequency < 1000) {
4709 correction[ichain] = hcorrection[ichain];
4710 temperature[ichain] = htemperature[ichain];
4711 voltage[ichain] = hvoltage[ichain];
4712 } else { /* nothing is good, presume 0???? */
4713 correction[ichain] = 0;
4714 temperature[ichain] = 0;
4715 voltage[ichain] = 0;
4719 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4722 ath_dbg(common, EEPROM,
4723 "for frequency=%d, calibration correction = %d %d %d\n",
4724 frequency, correction[0], correction[1], correction[2]);
4729 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4734 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4735 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4738 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4740 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4743 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4749 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4750 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4752 u8 *ctl_freqbin = is2GHz ?
4753 &eep->ctl_freqbin_2G[idx][0] :
4754 &eep->ctl_freqbin_5G[idx][0];
4757 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4758 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4759 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4761 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4762 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4763 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4766 return MAX_RATE_POWER;
4770 * Find the maximum conformance test limit for the given channel and CTL info
4772 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4773 u16 freq, int idx, bool is2GHz)
4775 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4776 u8 *ctl_freqbin = is2GHz ?
4777 &eep->ctl_freqbin_2G[idx][0] :
4778 &eep->ctl_freqbin_5G[idx][0];
4779 u16 num_edges = is2GHz ?
4780 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4783 /* Get the edge power */
4785 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
4788 * If there's an exact channel match or an inband flag set
4789 * on the lower channel use the given rdEdgePower
4791 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
4793 ar9003_hw_get_direct_edge_power(eep, idx,
4796 } else if ((edge > 0) &&
4797 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
4800 ar9003_hw_get_indirect_edge_power(eep, idx,
4804 * Leave loop - no more affecting edges possible in
4805 * this monotonic increasing list
4810 return twiceMaxEdgePower;
4813 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4814 struct ath9k_channel *chan,
4815 u8 *pPwrArray, u16 cfgCtl,
4816 u8 antenna_reduction,
4819 struct ath_common *common = ath9k_hw_common(ah);
4820 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4821 u16 twiceMaxEdgePower;
4823 u16 scaledPower = 0, minCtlPower;
4824 static const u16 ctlModesFor11a[] = {
4825 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4827 static const u16 ctlModesFor11g[] = {
4828 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
4829 CTL_11G_EXT, CTL_2GHT40
4832 const u16 *pCtlMode;
4834 struct chan_centers centers;
4837 u16 twiceMinEdgePower;
4838 bool is2ghz = IS_CHAN_2GHZ(chan);
4840 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4841 scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
4845 /* Setup for CTL modes */
4846 /* CTL_11B, CTL_11G, CTL_2GHT20 */
4848 ARRAY_SIZE(ctlModesFor11g) -
4849 SUB_NUM_CTL_MODES_AT_2G_40;
4850 pCtlMode = ctlModesFor11g;
4851 if (IS_CHAN_HT40(chan))
4853 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4855 /* Setup for CTL modes */
4856 /* CTL_11A, CTL_5GHT20 */
4857 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
4858 SUB_NUM_CTL_MODES_AT_5G_40;
4859 pCtlMode = ctlModesFor11a;
4860 if (IS_CHAN_HT40(chan))
4862 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4866 * For MIMO, need to apply regulatory caps individually across
4867 * dynamically running modes: CCK, OFDM, HT20, HT40
4869 * The outer loop walks through each possible applicable runtime mode.
4870 * The inner loop walks through each ctlIndex entry in EEPROM.
4871 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
4873 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4874 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
4875 (pCtlMode[ctlMode] == CTL_2GHT40);
4877 freq = centers.synth_center;
4878 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4879 freq = centers.ext_center;
4881 freq = centers.ctl_center;
4883 ath_dbg(common, REGULATORY,
4884 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
4885 ctlMode, numCtlModes, isHt40CtlMode,
4886 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4888 /* walk through each CTL index stored in EEPROM */
4890 ctlIndex = pEepData->ctlIndex_2G;
4891 ctlNum = AR9300_NUM_CTLS_2G;
4893 ctlIndex = pEepData->ctlIndex_5G;
4894 ctlNum = AR9300_NUM_CTLS_5G;
4897 twiceMaxEdgePower = MAX_RATE_POWER;
4898 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
4899 ath_dbg(common, REGULATORY,
4900 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
4901 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
4905 * compare test group from regulatory
4906 * channel list with test mode from pCtlMode
4909 if ((((cfgCtl & ~CTL_MODE_M) |
4910 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4912 (((cfgCtl & ~CTL_MODE_M) |
4913 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4914 ((ctlIndex[i] & CTL_MODE_M) |
4917 ar9003_hw_get_max_edge_power(pEepData,
4921 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
4923 * Find the minimum of all CTL
4924 * edge powers that apply to
4928 min(twiceMaxEdgePower,
4939 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
4941 ath_dbg(common, REGULATORY,
4942 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
4943 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4944 scaledPower, minCtlPower);
4946 /* Apply ctl mode to correct target power set */
4947 switch (pCtlMode[ctlMode]) {
4949 for (i = ALL_TARGET_LEGACY_1L_5L;
4950 i <= ALL_TARGET_LEGACY_11S; i++)
4952 (u8)min((u16)pPwrArray[i],
4957 for (i = ALL_TARGET_LEGACY_6_24;
4958 i <= ALL_TARGET_LEGACY_54; i++)
4960 (u8)min((u16)pPwrArray[i],
4965 for (i = ALL_TARGET_HT20_0_8_16;
4966 i <= ALL_TARGET_HT20_21; i++)
4968 (u8)min((u16)pPwrArray[i],
4970 pPwrArray[ALL_TARGET_HT20_22] =
4971 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
4973 pPwrArray[ALL_TARGET_HT20_23] =
4974 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
4979 for (i = ALL_TARGET_HT40_0_8_16;
4980 i <= ALL_TARGET_HT40_23; i++)
4982 (u8)min((u16)pPwrArray[i],
4988 } /* end ctl mode checking */
4991 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
4993 u8 mod_idx = mcs_idx % 8;
4996 return mod_idx ? (base_pwridx + 1) : base_pwridx;
4998 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
5001 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5002 struct ath9k_channel *chan, u16 cfgCtl,
5003 u8 twiceAntennaReduction,
5004 u8 powerLimit, bool test)
5006 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
5007 struct ath_common *common = ath9k_hw_common(ah);
5008 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5009 struct ar9300_modal_eep_header *modal_hdr;
5010 u8 targetPowerValT2[ar9300RateSize];
5011 u8 target_power_val_t2_eep[ar9300RateSize];
5012 unsigned int i = 0, paprd_scale_factor = 0;
5013 u8 pwr_idx, min_pwridx = 0;
5015 memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
5018 * Get target powers from EEPROM - our baseline for TX Power
5020 ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
5022 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
5023 if (IS_CHAN_2GHZ(chan))
5024 modal_hdr = &eep->modalHeader2G;
5026 modal_hdr = &eep->modalHeader5G;
5028 ah->paprd_ratemask =
5029 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5030 AR9300_PAPRD_RATE_MASK;
5032 ah->paprd_ratemask_ht40 =
5033 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5034 AR9300_PAPRD_RATE_MASK;
5036 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5037 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5038 ALL_TARGET_HT20_0_8_16;
5040 if (!ah->paprd_table_write_done) {
5041 memcpy(target_power_val_t2_eep, targetPowerValT2,
5042 sizeof(targetPowerValT2));
5043 for (i = 0; i < 24; i++) {
5044 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5045 if (ah->paprd_ratemask & (1 << i)) {
5046 if (targetPowerValT2[pwr_idx] &&
5047 targetPowerValT2[pwr_idx] ==
5048 target_power_val_t2_eep[pwr_idx])
5049 targetPowerValT2[pwr_idx] -=
5054 memcpy(target_power_val_t2_eep, targetPowerValT2,
5055 sizeof(targetPowerValT2));
5058 ar9003_hw_set_power_per_rate_table(ah, chan,
5059 targetPowerValT2, cfgCtl,
5060 twiceAntennaReduction,
5063 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
5064 for (i = 0; i < ar9300RateSize; i++) {
5065 if ((ah->paprd_ratemask & (1 << i)) &&
5066 (abs(targetPowerValT2[i] -
5067 target_power_val_t2_eep[i]) >
5068 paprd_scale_factor)) {
5069 ah->paprd_ratemask &= ~(1 << i);
5070 ath_dbg(common, EEPROM,
5071 "paprd disabled for mcs %d\n", i);
5076 regulatory->max_power_level = 0;
5077 for (i = 0; i < ar9300RateSize; i++) {
5078 if (targetPowerValT2[i] > regulatory->max_power_level)
5079 regulatory->max_power_level = targetPowerValT2[i];
5082 ath9k_hw_update_regulatory_maxpower(ah);
5087 for (i = 0; i < ar9300RateSize; i++) {
5088 ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n",
5089 i, targetPowerValT2[i]);
5092 /* Write target power array to registers */
5093 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5094 ar9003_hw_calibration_apply(ah, chan->channel);
5096 if (IS_CHAN_2GHZ(chan)) {
5097 if (IS_CHAN_HT40(chan))
5098 i = ALL_TARGET_HT40_0_8_16;
5100 i = ALL_TARGET_HT20_0_8_16;
5102 if (IS_CHAN_HT40(chan))
5103 i = ALL_TARGET_HT40_7;
5105 i = ALL_TARGET_HT20_7;
5107 ah->paprd_target_power = targetPowerValT2[i];
5110 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5116 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5118 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5120 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5123 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5125 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5127 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5130 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
5132 return ar9003_modal_header(ah, is2ghz)->spurChans;
5135 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5136 struct ath9k_channel *chan)
5138 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5140 if (IS_CHAN_2GHZ(chan))
5141 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5142 AR9300_PAPRD_SCALE_1);
5144 if (chan->channel >= 5700)
5145 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5146 AR9300_PAPRD_SCALE_1);
5147 else if (chan->channel >= 5400)
5148 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5149 AR9300_PAPRD_SCALE_2);
5151 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5152 AR9300_PAPRD_SCALE_1);
5156 const struct eeprom_ops eep_ar9300_ops = {
5157 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5158 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5159 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5160 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5161 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5162 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5163 .set_board_values = ath9k_hw_ar9300_set_board_values,
5164 .set_addac = ath9k_hw_ar9300_set_addac,
5165 .set_txpower = ath9k_hw_ar9300_set_txpower,
5166 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel