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)
33 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
34 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
35 #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */
36 #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */
37 #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */
39 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
40 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
42 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
44 #define EEPROM_DATA_LEN_9485 1088
46 static int ar9003_hw_power_interpolate(int32_t x,
47 int32_t *px, int32_t *py, u_int16_t np);
50 static const struct ar9300_eeprom ar9300_default = {
53 .macAddr = {0, 2, 3, 4, 5, 6},
54 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
57 .regDmn = { LE16(0), LE16(0x1f) },
58 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
60 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
64 .blueToothOptions = 0,
66 .deviceType = 5, /* takes lower byte in eeprom location */
67 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
68 .params_for_tuning_caps = {0, 0},
69 .featureEnable = 0x0c,
71 * bit0 - enable tx temp comp - disabled
72 * bit1 - enable tx volt comp - disabled
73 * bit2 - enable fastClock - enabled
74 * bit3 - enable doubling - enabled
75 * bit4 - enable internal regulator - disabled
76 * bit5 - enable pa predistortion - disabled
78 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
79 .eepromWriteEnableGpio = 3,
82 .rxBandSelectGpio = 0xff,
87 /* ar9300_modal_eep_header 2g */
88 /* 4 idle,t1,t2,b(4 bits per setting) */
89 .antCtrlCommon = LE32(0x110),
90 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
91 .antCtrlCommon2 = LE32(0x22222),
94 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
95 * rx1, rx12, b (2 bits each)
97 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
100 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
101 * for ar9280 (0xa20c/b20c 5:0)
103 .xatten1DB = {0, 0, 0},
106 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
107 * for ar9280 (0xa20c/b20c 16:12
109 .xatten1Margin = {0, 0, 0},
114 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
115 * channels in usual fbin coding format
117 .spurChans = {0, 0, 0, 0, 0},
120 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
121 * if the register is per chain
123 .noiseFloorThreshCh = {-1, 0, 0},
124 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
127 .txFrameToDataStart = 0x0e,
128 .txFrameToPaOn = 0x0e,
129 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
131 .switchSettling = 0x2c,
132 .adcDesiredSize = -30,
135 .txFrameToXpaOn = 0xe,
137 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
138 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
140 0, 0, 0, 0, 0, 0, 0, 0,
144 .ant_div_control = 0,
145 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
152 /* ar9300_cal_data_per_freq_op_loop 2g */
154 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
155 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
156 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
158 .calTarget_freqbin_Cck = {
162 .calTarget_freqbin_2G = {
167 .calTarget_freqbin_2GHT20 = {
172 .calTarget_freqbin_2GHT40 = {
177 .calTargetPowerCck = {
178 /* 1L-5L,5S,11L,11S */
179 { {36, 36, 36, 36} },
180 { {36, 36, 36, 36} },
182 .calTargetPower2G = {
184 { {32, 32, 28, 24} },
185 { {32, 32, 28, 24} },
186 { {32, 32, 28, 24} },
188 .calTargetPower2GHT20 = {
189 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
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} },
193 .calTargetPower2GHT40 = {
194 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
195 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
196 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
199 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
200 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
230 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
231 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
232 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
233 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
237 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
238 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
239 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
244 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
245 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
251 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
252 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
253 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
254 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
258 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
259 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
260 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
264 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
265 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
266 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
271 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
272 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
273 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
278 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
279 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
280 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
281 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
285 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
286 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
287 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
289 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), 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, 1), CTL(60, 0) } },
294 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
295 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
297 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
298 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
299 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
302 /* 4 idle,t1,t2,b (4 bits per setting) */
303 .antCtrlCommon = LE32(0x110),
304 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
305 .antCtrlCommon2 = LE32(0x22222),
306 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
308 LE16(0x000), LE16(0x000), LE16(0x000),
310 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
311 .xatten1DB = {0, 0, 0},
314 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
315 * for merlin (0xa20c/b20c 16:12
317 .xatten1Margin = {0, 0, 0},
320 /* spurChans spur channels in usual fbin coding format */
321 .spurChans = {0, 0, 0, 0, 0},
322 /* noiseFloorThreshCh Check if the register is per chain */
323 .noiseFloorThreshCh = {-1, 0, 0},
324 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
327 .txFrameToDataStart = 0x0e,
328 .txFrameToPaOn = 0x0e,
329 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
331 .switchSettling = 0x2d,
332 .adcDesiredSize = -30,
335 .txFrameToXpaOn = 0xe,
337 .papdRateMaskHt20 = LE32(0x0c80c080),
338 .papdRateMaskHt40 = LE32(0x0080c080),
340 0, 0, 0, 0, 0, 0, 0, 0,
346 .xatten1DBLow = {0, 0, 0},
347 .xatten1MarginLow = {0, 0, 0},
348 .xatten1DBHigh = {0, 0, 0},
349 .xatten1MarginHigh = {0, 0, 0}
394 .calTarget_freqbin_5G = {
404 .calTarget_freqbin_5GHT20 = {
414 .calTarget_freqbin_5GHT40 = {
424 .calTargetPower5G = {
426 { {20, 20, 20, 10} },
427 { {20, 20, 20, 10} },
428 { {20, 20, 20, 10} },
429 { {20, 20, 20, 10} },
430 { {20, 20, 20, 10} },
431 { {20, 20, 20, 10} },
432 { {20, 20, 20, 10} },
433 { {20, 20, 20, 10} },
435 .calTargetPower5GHT20 = {
437 * 0_8_16,1-3_9-11_17-19,
438 * 4,5,6,7,12,13,14,15,20,21,22,23
440 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
441 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
442 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
443 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
444 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
445 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
446 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
447 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
449 .calTargetPower5GHT40 = {
451 * 0_8_16,1-3_9-11_17-19,
452 * 4,5,6,7,12,13,14,15,20,21,22,23
454 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
455 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
456 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
457 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
458 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
459 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
460 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
461 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
464 0x10, 0x16, 0x18, 0x40, 0x46,
465 0x48, 0x30, 0x36, 0x38
469 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
470 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
471 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
472 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
473 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
474 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
475 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
476 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
479 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
480 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
481 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
482 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
483 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
484 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
485 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
486 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
490 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
491 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
492 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
493 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
494 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
495 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
496 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
497 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
501 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
502 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
503 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
504 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
505 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
506 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
507 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
508 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
512 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
513 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
514 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
515 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
516 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
517 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
518 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
519 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
523 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
524 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
525 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
526 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
527 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
528 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
529 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
530 /* Data[5].ctlEdges[7].bChannel */ 0xFF
534 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
535 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
536 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
537 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
538 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
539 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
540 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
541 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
545 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
546 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
547 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
548 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
549 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
550 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
551 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
552 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
556 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
557 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
558 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
559 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
560 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
561 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
562 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
563 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
569 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
570 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
575 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
576 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
581 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
582 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
587 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
588 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
593 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
594 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
599 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
600 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
605 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
606 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
611 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
612 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
617 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
618 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
624 static const struct ar9300_eeprom ar9300_x113 = {
626 .templateVersion = 6,
627 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
628 .custData = {"x113-023-f0000"},
630 .regDmn = { LE16(0), LE16(0x1f) },
631 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
633 .opFlags = AR5416_OPFLAGS_11A,
637 .blueToothOptions = 0,
639 .deviceType = 5, /* takes lower byte in eeprom location */
640 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
641 .params_for_tuning_caps = {0, 0},
642 .featureEnable = 0x0d,
644 * bit0 - enable tx temp comp - disabled
645 * bit1 - enable tx volt comp - disabled
646 * bit2 - enable fastClock - enabled
647 * bit3 - enable doubling - enabled
648 * bit4 - enable internal regulator - disabled
649 * bit5 - enable pa predistortion - disabled
651 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
652 .eepromWriteEnableGpio = 6,
653 .wlanDisableGpio = 0,
655 .rxBandSelectGpio = 0xff,
660 /* ar9300_modal_eep_header 2g */
661 /* 4 idle,t1,t2,b(4 bits per setting) */
662 .antCtrlCommon = LE32(0x110),
663 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
664 .antCtrlCommon2 = LE32(0x44444),
667 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
668 * rx1, rx12, b (2 bits each)
670 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
673 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
674 * for ar9280 (0xa20c/b20c 5:0)
676 .xatten1DB = {0, 0, 0},
679 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
680 * for ar9280 (0xa20c/b20c 16:12
682 .xatten1Margin = {0, 0, 0},
687 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
688 * channels in usual fbin coding format
690 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
693 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
694 * if the register is per chain
696 .noiseFloorThreshCh = {-1, 0, 0},
697 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
700 .txFrameToDataStart = 0x0e,
701 .txFrameToPaOn = 0x0e,
702 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
704 .switchSettling = 0x2c,
705 .adcDesiredSize = -30,
708 .txFrameToXpaOn = 0xe,
710 .papdRateMaskHt20 = LE32(0x0c80c080),
711 .papdRateMaskHt40 = LE32(0x0080c080),
713 0, 0, 0, 0, 0, 0, 0, 0,
717 .ant_div_control = 0,
718 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
725 /* ar9300_cal_data_per_freq_op_loop 2g */
727 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
728 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
729 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
731 .calTarget_freqbin_Cck = {
735 .calTarget_freqbin_2G = {
740 .calTarget_freqbin_2GHT20 = {
745 .calTarget_freqbin_2GHT40 = {
750 .calTargetPowerCck = {
751 /* 1L-5L,5S,11L,11S */
752 { {34, 34, 34, 34} },
753 { {34, 34, 34, 34} },
755 .calTargetPower2G = {
757 { {34, 34, 32, 32} },
758 { {34, 34, 32, 32} },
759 { {34, 34, 32, 32} },
761 .calTargetPower2GHT20 = {
762 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
763 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
764 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
766 .calTargetPower2GHT40 = {
767 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
768 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
769 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
772 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
773 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
803 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
804 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
805 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
806 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
810 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
811 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
812 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
817 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
818 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
824 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
825 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
826 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
827 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
831 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
832 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
833 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
837 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
838 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
839 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
844 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
845 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
846 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
851 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
852 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
853 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
854 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
858 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
859 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
860 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
862 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
863 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
864 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
866 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
867 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
868 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
870 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
871 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
872 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
875 /* 4 idle,t1,t2,b (4 bits per setting) */
876 .antCtrlCommon = LE32(0x220),
877 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
878 .antCtrlCommon2 = LE32(0x11111),
879 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
881 LE16(0x150), LE16(0x150), LE16(0x150),
883 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
884 .xatten1DB = {0, 0, 0},
887 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
888 * for merlin (0xa20c/b20c 16:12
890 .xatten1Margin = {0, 0, 0},
893 /* spurChans spur channels in usual fbin coding format */
894 .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
895 /* noiseFloorThreshCh Check if the register is per chain */
896 .noiseFloorThreshCh = {-1, 0, 0},
897 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
900 .txFrameToDataStart = 0x0e,
901 .txFrameToPaOn = 0x0e,
902 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
904 .switchSettling = 0x2d,
905 .adcDesiredSize = -30,
908 .txFrameToXpaOn = 0xe,
910 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
911 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
913 0, 0, 0, 0, 0, 0, 0, 0,
918 .tempSlopeHigh = 105,
919 .xatten1DBLow = {0, 0, 0},
920 .xatten1MarginLow = {0, 0, 0},
921 .xatten1DBHigh = {0, 0, 0},
922 .xatten1MarginHigh = {0, 0, 0}
967 .calTarget_freqbin_5G = {
977 .calTarget_freqbin_5GHT20 = {
987 .calTarget_freqbin_5GHT40 = {
997 .calTargetPower5G = {
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} },
1006 { {42, 40, 40, 34} },
1008 .calTargetPower5GHT20 = {
1010 * 0_8_16,1-3_9-11_17-19,
1011 * 4,5,6,7,12,13,14,15,20,21,22,23
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 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1019 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1020 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1022 .calTargetPower5GHT40 = {
1024 * 0_8_16,1-3_9-11_17-19,
1025 * 4,5,6,7,12,13,14,15,20,21,22,23
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 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1033 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1034 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1037 0x10, 0x16, 0x18, 0x40, 0x46,
1038 0x48, 0x30, 0x36, 0x38
1042 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1043 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1044 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1045 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1046 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1047 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1048 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1049 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1052 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1053 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1054 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1055 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1056 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1057 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1058 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1059 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1063 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1064 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1065 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1066 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1067 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1068 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1069 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1070 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1074 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1075 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1076 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1077 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1078 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1079 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1080 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1081 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1085 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1086 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1087 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1088 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1089 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1090 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1091 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1092 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1096 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1097 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1098 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1099 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1100 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1101 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1102 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1103 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1107 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1108 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1109 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1110 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1111 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1112 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1113 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1114 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1118 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1119 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1120 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1121 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1122 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1123 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1124 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1125 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1129 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1130 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1131 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1132 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1133 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1134 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1135 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1136 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1139 .ctlPowerData_5G = {
1142 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1143 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1148 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1149 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1154 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1155 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1160 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1161 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1166 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1167 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1172 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1173 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1178 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1179 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1184 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1185 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1190 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1191 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1198 static const struct ar9300_eeprom ar9300_h112 = {
1200 .templateVersion = 3,
1201 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1202 .custData = {"h112-241-f0000"},
1204 .regDmn = { LE16(0), LE16(0x1f) },
1205 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1207 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1211 .blueToothOptions = 0,
1213 .deviceType = 5, /* takes lower byte in eeprom location */
1214 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1215 .params_for_tuning_caps = {0, 0},
1216 .featureEnable = 0x0d,
1218 * bit0 - enable tx temp comp - disabled
1219 * bit1 - enable tx volt comp - disabled
1220 * bit2 - enable fastClock - enabled
1221 * bit3 - enable doubling - enabled
1222 * bit4 - enable internal regulator - disabled
1223 * bit5 - enable pa predistortion - disabled
1225 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1226 .eepromWriteEnableGpio = 6,
1227 .wlanDisableGpio = 0,
1229 .rxBandSelectGpio = 0xff,
1234 /* ar9300_modal_eep_header 2g */
1235 /* 4 idle,t1,t2,b(4 bits per setting) */
1236 .antCtrlCommon = LE32(0x110),
1237 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1238 .antCtrlCommon2 = LE32(0x44444),
1241 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1242 * rx1, rx12, b (2 bits each)
1244 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
1247 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1248 * for ar9280 (0xa20c/b20c 5:0)
1250 .xatten1DB = {0, 0, 0},
1253 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1254 * for ar9280 (0xa20c/b20c 16:12
1256 .xatten1Margin = {0, 0, 0},
1261 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1262 * channels in usual fbin coding format
1264 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1267 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1268 * if the register is per chain
1270 .noiseFloorThreshCh = {-1, 0, 0},
1271 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1274 .txFrameToDataStart = 0x0e,
1275 .txFrameToPaOn = 0x0e,
1276 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1278 .switchSettling = 0x2c,
1279 .adcDesiredSize = -30,
1282 .txFrameToXpaOn = 0xe,
1284 .papdRateMaskHt20 = LE32(0x0c80c080),
1285 .papdRateMaskHt40 = LE32(0x0080c080),
1287 0, 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),
1487 0, 0, 0, 0, 0, 0, 0, 0,
1492 .tempSlopeHigh = 50,
1493 .xatten1DBLow = {0, 0, 0},
1494 .xatten1MarginLow = {0, 0, 0},
1495 .xatten1DBHigh = {0, 0, 0},
1496 .xatten1MarginHigh = {0, 0, 0}
1541 .calTarget_freqbin_5G = {
1551 .calTarget_freqbin_5GHT20 = {
1561 .calTarget_freqbin_5GHT40 = {
1571 .calTargetPower5G = {
1573 { {30, 30, 28, 24} },
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} },
1582 .calTargetPower5GHT20 = {
1584 * 0_8_16,1-3_9-11_17-19,
1585 * 4,5,6,7,12,13,14,15,20,21,22,23
1587 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1588 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1589 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1590 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1591 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1592 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1593 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1594 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1596 .calTargetPower5GHT40 = {
1598 * 0_8_16,1-3_9-11_17-19,
1599 * 4,5,6,7,12,13,14,15,20,21,22,23
1601 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1602 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1603 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1604 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1605 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1606 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1607 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1608 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1611 0x10, 0x16, 0x18, 0x40, 0x46,
1612 0x48, 0x30, 0x36, 0x38
1616 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1617 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1618 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1619 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1620 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1621 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1622 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1623 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1626 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1627 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1628 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1629 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1630 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1631 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1632 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1633 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1637 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1638 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1639 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1640 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1641 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1642 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1643 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1644 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1648 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1649 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1650 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1651 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1652 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1653 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1654 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1655 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1659 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1660 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1661 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1662 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1663 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1664 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1665 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1666 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1670 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1671 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1672 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1673 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1674 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1675 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1676 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1677 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1681 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1682 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1683 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1684 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1685 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1686 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1687 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1688 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1692 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1693 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1694 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1695 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1696 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1697 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1698 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1699 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1703 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1704 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1705 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1706 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1707 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1708 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1709 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1710 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1713 .ctlPowerData_5G = {
1716 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1717 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1722 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1723 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1728 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1729 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1734 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1735 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1740 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1741 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1746 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1747 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1752 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1753 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1758 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1759 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1764 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1765 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1772 static const struct ar9300_eeprom ar9300_x112 = {
1774 .templateVersion = 5,
1775 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1776 .custData = {"x112-041-f0000"},
1778 .regDmn = { LE16(0), LE16(0x1f) },
1779 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1781 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1785 .blueToothOptions = 0,
1787 .deviceType = 5, /* takes lower byte in eeprom location */
1788 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
1789 .params_for_tuning_caps = {0, 0},
1790 .featureEnable = 0x0d,
1792 * bit0 - enable tx temp comp - disabled
1793 * bit1 - enable tx volt comp - disabled
1794 * bit2 - enable fastclock - enabled
1795 * bit3 - enable doubling - enabled
1796 * bit4 - enable internal regulator - disabled
1797 * bit5 - enable pa predistortion - disabled
1799 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
1800 .eepromWriteEnableGpio = 6,
1801 .wlanDisableGpio = 0,
1803 .rxBandSelectGpio = 0xff,
1808 /* ar9300_modal_eep_header 2g */
1809 /* 4 idle,t1,t2,b(4 bits per setting) */
1810 .antCtrlCommon = LE32(0x110),
1811 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1812 .antCtrlCommon2 = LE32(0x22222),
1815 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1816 * rx1, rx12, b (2 bits each)
1818 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
1821 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1822 * for ar9280 (0xa20c/b20c 5:0)
1824 .xatten1DB = {0x1b, 0x1b, 0x1b},
1827 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1828 * for ar9280 (0xa20c/b20c 16:12
1830 .xatten1Margin = {0x15, 0x15, 0x15},
1835 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1836 * channels in usual fbin coding format
1838 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1841 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1842 * if the register is per chain
1844 .noiseFloorThreshCh = {-1, 0, 0},
1845 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1848 .txFrameToDataStart = 0x0e,
1849 .txFrameToPaOn = 0x0e,
1850 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1852 .switchSettling = 0x2c,
1853 .adcDesiredSize = -30,
1856 .txFrameToXpaOn = 0xe,
1858 .papdRateMaskHt20 = LE32(0x0c80c080),
1859 .papdRateMaskHt40 = LE32(0x0080c080),
1861 0, 0, 0, 0, 0, 0, 0, 0,
1865 .ant_div_control = 0,
1866 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
1873 /* ar9300_cal_data_per_freq_op_loop 2g */
1875 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1876 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1877 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1879 .calTarget_freqbin_Cck = {
1883 .calTarget_freqbin_2G = {
1888 .calTarget_freqbin_2GHT20 = {
1893 .calTarget_freqbin_2GHT40 = {
1898 .calTargetPowerCck = {
1899 /* 1L-5L,5S,11L,11s */
1900 { {38, 38, 38, 38} },
1901 { {38, 38, 38, 38} },
1903 .calTargetPower2G = {
1905 { {38, 38, 36, 34} },
1906 { {38, 38, 36, 34} },
1907 { {38, 38, 34, 32} },
1909 .calTargetPower2GHT20 = {
1910 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1911 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1912 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1914 .calTargetPower2GHT40 = {
1915 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1916 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1917 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1920 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1921 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1951 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1952 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1953 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1954 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1958 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1959 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1960 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1965 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1966 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1972 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
1973 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
1974 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
1975 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
1979 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1980 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1981 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1985 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1986 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1987 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1992 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1993 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1994 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1999 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2000 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2001 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2002 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2005 .ctlPowerData_2G = {
2006 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2007 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2008 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2010 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2011 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2012 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2014 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2015 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2016 { { 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) } },
2019 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2020 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2023 /* 4 idle,t1,t2,b (4 bits per setting) */
2024 .antCtrlCommon = LE32(0x110),
2025 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2026 .antCtrlCommon2 = LE32(0x22222),
2027 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2029 LE16(0x0), LE16(0x0), LE16(0x0),
2031 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2032 .xatten1DB = {0x13, 0x19, 0x17},
2035 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2036 * for merlin (0xa20c/b20c 16:12
2038 .xatten1Margin = {0x19, 0x19, 0x19},
2041 /* spurChans spur channels in usual fbin coding format */
2042 .spurChans = {0, 0, 0, 0, 0},
2043 /* noiseFloorThreshch check if the register is per chain */
2044 .noiseFloorThreshCh = {-1, 0, 0},
2045 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2048 .txFrameToDataStart = 0x0e,
2049 .txFrameToPaOn = 0x0e,
2050 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2052 .switchSettling = 0x2d,
2053 .adcDesiredSize = -30,
2056 .txFrameToXpaOn = 0xe,
2058 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2059 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2061 0, 0, 0, 0, 0, 0, 0, 0,
2066 .tempSlopeHigh = 105,
2067 .xatten1DBLow = {0x10, 0x14, 0x10},
2068 .xatten1MarginLow = {0x19, 0x19 , 0x19},
2069 .xatten1DBHigh = {0x1d, 0x20, 0x24},
2070 .xatten1MarginHigh = {0x10, 0x10, 0x10}
2115 .calTarget_freqbin_5G = {
2125 .calTarget_freqbin_5GHT20 = {
2135 .calTarget_freqbin_5GHT40 = {
2145 .calTargetPower5G = {
2147 { {32, 32, 28, 26} },
2148 { {32, 32, 28, 26} },
2149 { {32, 32, 28, 26} },
2150 { {32, 32, 26, 24} },
2151 { {32, 32, 26, 24} },
2152 { {32, 32, 24, 22} },
2153 { {30, 30, 24, 22} },
2154 { {30, 30, 24, 22} },
2156 .calTargetPower5GHT20 = {
2158 * 0_8_16,1-3_9-11_17-19,
2159 * 4,5,6,7,12,13,14,15,20,21,22,23
2161 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2162 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2163 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2164 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2165 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2166 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2167 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2168 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2170 .calTargetPower5GHT40 = {
2172 * 0_8_16,1-3_9-11_17-19,
2173 * 4,5,6,7,12,13,14,15,20,21,22,23
2175 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2176 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2177 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2178 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2179 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2180 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2181 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2182 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2185 0x10, 0x16, 0x18, 0x40, 0x46,
2186 0x48, 0x30, 0x36, 0x38
2190 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2191 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2192 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2193 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2194 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2195 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2196 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2197 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2200 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2201 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2202 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2203 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2204 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2205 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2206 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2207 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2211 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2212 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2213 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2214 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2215 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2216 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2217 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2218 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2222 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2223 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2224 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2225 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2226 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2227 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2228 /* Data[3].ctledges[6].bchannel */ 0xFF,
2229 /* Data[3].ctledges[7].bchannel */ 0xFF,
2233 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2234 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2235 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2236 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2237 /* Data[4].ctledges[4].bchannel */ 0xFF,
2238 /* Data[4].ctledges[5].bchannel */ 0xFF,
2239 /* Data[4].ctledges[6].bchannel */ 0xFF,
2240 /* Data[4].ctledges[7].bchannel */ 0xFF,
2244 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2245 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2246 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2247 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2248 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2249 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2250 /* Data[5].ctledges[6].bchannel */ 0xFF,
2251 /* Data[5].ctledges[7].bchannel */ 0xFF
2255 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2256 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2257 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2258 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2259 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2260 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2261 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2262 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2266 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2267 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2268 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2269 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2270 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2271 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2272 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2273 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2277 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2278 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2279 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2280 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2281 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2282 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2283 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2284 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2287 .ctlPowerData_5G = {
2290 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2291 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2296 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2297 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2302 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2303 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2308 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2309 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2314 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2315 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2320 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2321 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2326 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2327 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2332 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2333 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2338 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2339 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2345 static const struct ar9300_eeprom ar9300_h116 = {
2347 .templateVersion = 4,
2348 .macAddr = {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2349 .custData = {"h116-041-f0000"},
2351 .regDmn = { LE16(0), LE16(0x1f) },
2352 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2354 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2358 .blueToothOptions = 0,
2360 .deviceType = 5, /* takes lower byte in eeprom location */
2361 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
2362 .params_for_tuning_caps = {0, 0},
2363 .featureEnable = 0x0d,
2365 * bit0 - enable tx temp comp - disabled
2366 * bit1 - enable tx volt comp - disabled
2367 * bit2 - enable fastClock - enabled
2368 * bit3 - enable doubling - enabled
2369 * bit4 - enable internal regulator - disabled
2370 * bit5 - enable pa predistortion - disabled
2372 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
2373 .eepromWriteEnableGpio = 6,
2374 .wlanDisableGpio = 0,
2376 .rxBandSelectGpio = 0xff,
2381 /* ar9300_modal_eep_header 2g */
2382 /* 4 idle,t1,t2,b(4 bits per setting) */
2383 .antCtrlCommon = LE32(0x110),
2384 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2385 .antCtrlCommon2 = LE32(0x44444),
2388 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2389 * rx1, rx12, b (2 bits each)
2391 .antCtrlChain = { LE16(0x10), LE16(0x10), LE16(0x10) },
2394 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2395 * for ar9280 (0xa20c/b20c 5:0)
2397 .xatten1DB = {0x1f, 0x1f, 0x1f},
2400 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2401 * for ar9280 (0xa20c/b20c 16:12
2403 .xatten1Margin = {0x12, 0x12, 0x12},
2408 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2409 * channels in usual fbin coding format
2411 .spurChans = {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2414 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2415 * if the register is per chain
2417 .noiseFloorThreshCh = {-1, 0, 0},
2418 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2421 .txFrameToDataStart = 0x0e,
2422 .txFrameToPaOn = 0x0e,
2423 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2425 .switchSettling = 0x2c,
2426 .adcDesiredSize = -30,
2429 .txFrameToXpaOn = 0xe,
2431 .papdRateMaskHt20 = LE32(0x0c80C080),
2432 .papdRateMaskHt40 = LE32(0x0080C080),
2434 0, 0, 0, 0, 0, 0, 0, 0,
2438 .ant_div_control = 0,
2439 .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2446 /* ar9300_cal_data_per_freq_op_loop 2g */
2448 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2449 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2450 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2452 .calTarget_freqbin_Cck = {
2456 .calTarget_freqbin_2G = {
2461 .calTarget_freqbin_2GHT20 = {
2466 .calTarget_freqbin_2GHT40 = {
2471 .calTargetPowerCck = {
2472 /* 1L-5L,5S,11L,11S */
2473 { {34, 34, 34, 34} },
2474 { {34, 34, 34, 34} },
2476 .calTargetPower2G = {
2478 { {34, 34, 32, 32} },
2479 { {34, 34, 32, 32} },
2480 { {34, 34, 32, 32} },
2482 .calTargetPower2GHT20 = {
2483 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2484 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2485 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2487 .calTargetPower2GHT40 = {
2488 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2489 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2490 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2493 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2494 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2524 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2525 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2526 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2527 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2531 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2532 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2533 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2538 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2539 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2545 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2546 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2547 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2548 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2552 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2553 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2554 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2558 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2559 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2560 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2565 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2566 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2567 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2572 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2573 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2574 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2575 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2578 .ctlPowerData_2G = {
2579 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2580 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2581 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2583 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2584 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2585 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2587 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), 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, 0), CTL(60, 0) } },
2592 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2593 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2596 /* 4 idle,t1,t2,b (4 bits per setting) */
2597 .antCtrlCommon = LE32(0x220),
2598 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2599 .antCtrlCommon2 = LE32(0x44444),
2600 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2602 LE16(0x150), LE16(0x150), LE16(0x150),
2604 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2605 .xatten1DB = {0x19, 0x19, 0x19},
2608 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2609 * for merlin (0xa20c/b20c 16:12
2611 .xatten1Margin = {0x14, 0x14, 0x14},
2614 /* spurChans spur channels in usual fbin coding format */
2615 .spurChans = {0, 0, 0, 0, 0},
2616 /* noiseFloorThreshCh Check if the register is per chain */
2617 .noiseFloorThreshCh = {-1, 0, 0},
2618 .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2621 .txFrameToDataStart = 0x0e,
2622 .txFrameToPaOn = 0x0e,
2623 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2625 .switchSettling = 0x2d,
2626 .adcDesiredSize = -30,
2629 .txFrameToXpaOn = 0xe,
2631 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2632 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2634 0, 0, 0, 0, 0, 0, 0, 0,
2639 .tempSlopeHigh = 50,
2640 .xatten1DBLow = {0, 0, 0},
2641 .xatten1MarginLow = {0, 0, 0},
2642 .xatten1DBHigh = {0, 0, 0},
2643 .xatten1MarginHigh = {0, 0, 0}
2688 .calTarget_freqbin_5G = {
2698 .calTarget_freqbin_5GHT20 = {
2708 .calTarget_freqbin_5GHT40 = {
2718 .calTargetPower5G = {
2720 { {30, 30, 28, 24} },
2721 { {30, 30, 28, 24} },
2722 { {30, 30, 28, 24} },
2723 { {30, 30, 28, 24} },
2724 { {30, 30, 28, 24} },
2725 { {30, 30, 28, 24} },
2726 { {30, 30, 28, 24} },
2727 { {30, 30, 28, 24} },
2729 .calTargetPower5GHT20 = {
2731 * 0_8_16,1-3_9-11_17-19,
2732 * 4,5,6,7,12,13,14,15,20,21,22,23
2734 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2735 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2736 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2737 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2738 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2739 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2740 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2741 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2743 .calTargetPower5GHT40 = {
2745 * 0_8_16,1-3_9-11_17-19,
2746 * 4,5,6,7,12,13,14,15,20,21,22,23
2748 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2749 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2750 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2751 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2752 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2753 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2754 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2755 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2758 0x10, 0x16, 0x18, 0x40, 0x46,
2759 0x48, 0x30, 0x36, 0x38
2763 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2764 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2765 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2766 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2767 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2768 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2769 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2770 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2773 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2774 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2775 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2776 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2777 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2778 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2779 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2780 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2784 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2785 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2786 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2787 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2788 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2789 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2790 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2791 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2795 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2796 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2797 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2798 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2799 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2800 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2801 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2802 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2806 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2807 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2808 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2809 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2810 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2811 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2812 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2813 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2817 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2818 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2819 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2820 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2821 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2822 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2823 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2824 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2828 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2829 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2830 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2831 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2832 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2833 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2834 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2835 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2839 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2840 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2841 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2842 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2843 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2844 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2845 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2846 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2850 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2851 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2852 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2853 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2854 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2855 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2856 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2857 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2860 .ctlPowerData_5G = {
2863 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2864 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2869 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2870 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2875 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2876 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2881 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2882 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2887 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2888 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2893 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2894 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2899 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2900 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2905 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2906 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2911 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2912 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2919 static const struct ar9300_eeprom *ar9300_eep_templates[] = {
2927 static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2929 #define N_LOOP (sizeof(ar9300_eep_templates) / sizeof(ar9300_eep_templates[0]))
2932 for (it = 0; it < N_LOOP; it++)
2933 if (ar9300_eep_templates[it]->templateVersion == id)
2934 return ar9300_eep_templates[it];
2940 static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
2942 if (fbin == AR5416_BCHAN_UNUSED)
2945 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
2948 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
2953 static int interpolate(int x, int xa, int xb, int ya, int yb)
2955 int bf, factor, plus;
2957 bf = 2 * (yb - ya) * (x - xa) / (xb - xa);
2960 return ya + factor + plus;
2963 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2964 enum eeprom_param param)
2966 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2967 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
2971 return get_unaligned_be16(eep->macAddr);
2973 return get_unaligned_be16(eep->macAddr + 2);
2975 return get_unaligned_be16(eep->macAddr + 4);
2977 return le16_to_cpu(pBase->regDmn[0]);
2979 return pBase->deviceCap;
2981 return pBase->opCapFlags.opFlags;
2983 return pBase->rfSilent;
2985 return (pBase->txrxMask >> 4) & 0xf;
2987 return pBase->txrxMask & 0xf;
2988 case EEP_DRIVE_STRENGTH:
2989 #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1
2990 return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
2991 case EEP_INTERNAL_REGULATOR:
2992 /* Bit 4 is internal regulator flag */
2993 return (pBase->featureEnable & 0x10) >> 4;
2995 return le32_to_cpu(pBase->swreg);
2997 return !!(pBase->featureEnable & BIT(5));
2998 case EEP_CHAIN_MASK_REDUCE:
2999 return (pBase->miscConfiguration >> 0x3) & 0x1;
3000 case EEP_ANT_DIV_CTL1:
3001 return eep->base_ext1.ant_div_control;
3002 case EEP_ANTENNA_GAIN_5G:
3003 return eep->modalHeader5G.antennaGain;
3004 case EEP_ANTENNA_GAIN_2G:
3005 return eep->modalHeader2G.antennaGain;
3006 case EEP_QUICK_DROP:
3007 return pBase->miscConfiguration & BIT(1);
3013 static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
3018 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3021 *buffer = (val >> (8 * (address % 2))) & 0xff;
3025 static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
3030 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
3033 buffer[0] = val >> 8;
3034 buffer[1] = val & 0xff;
3039 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
3042 struct ath_common *common = ath9k_hw_common(ah);
3045 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
3046 ath_dbg(common, ATH_DBG_EEPROM,
3047 "eeprom address not in range\n");
3052 * Since we're reading the bytes in reverse order from a little-endian
3053 * word stream, an even address means we only use the lower half of
3054 * the 16-bit word at that address
3056 if (address % 2 == 0) {
3057 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
3063 for (i = 0; i < count / 2; i++) {
3064 if (!ar9300_eeprom_read_word(common, address, buffer))
3072 if (!ar9300_eeprom_read_byte(common, address, buffer))
3078 ath_dbg(common, ATH_DBG_EEPROM,
3079 "unable to read eeprom region at offset %d\n", address);
3083 static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3085 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3087 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3088 AR9300_OTP_STATUS_VALID, 1000))
3091 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3095 static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3101 for (i = 0; i < count; i++) {
3102 int offset = 8 * ((address - i) % 4);
3103 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3106 buffer[i] = (data >> offset) & 0xff;
3113 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3114 int *length, int *major, int *minor)
3116 unsigned long value[4];
3122 *code = ((value[0] >> 5) & 0x0007);
3123 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3124 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3125 *major = (value[2] & 0x000f);
3126 *minor = (value[3] & 0x00ff);
3129 static u16 ar9300_comp_cksum(u8 *data, int dsize)
3131 int it, checksum = 0;
3133 for (it = 0; it < dsize; it++) {
3134 checksum += data[it];
3141 static bool ar9300_uncompress_block(struct ath_hw *ah,
3151 struct ath_common *common = ath9k_hw_common(ah);
3155 for (it = 0; it < size; it += (length+2)) {
3159 length = block[it+1];
3162 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
3163 ath_dbg(common, ATH_DBG_EEPROM,
3164 "Restore at %d: spot=%d offset=%d length=%d\n",
3165 it, spot, offset, length);
3166 memcpy(&mptr[spot], &block[it+2], length);
3168 } else if (length > 0) {
3169 ath_dbg(common, ATH_DBG_EEPROM,
3170 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3171 it, spot, offset, length);
3178 static int ar9300_compress_decision(struct ath_hw *ah,
3183 u8 *word, int length, int mdata_size)
3185 struct ath_common *common = ath9k_hw_common(ah);
3186 const struct ar9300_eeprom *eep = NULL;
3190 if (length != mdata_size) {
3191 ath_dbg(common, ATH_DBG_EEPROM,
3192 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3193 mdata_size, length);
3196 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
3197 ath_dbg(common, ATH_DBG_EEPROM,
3198 "restored eeprom %d: uncompressed, length %d\n",
3201 case _CompressBlock:
3202 if (reference == 0) {
3204 eep = ar9003_eeprom_struct_find_by_id(reference);
3206 ath_dbg(common, ATH_DBG_EEPROM,
3207 "can't find reference eeprom struct %d\n",
3211 memcpy(mptr, eep, mdata_size);
3213 ath_dbg(common, ATH_DBG_EEPROM,
3214 "restore eeprom %d: block, reference %d, length %d\n",
3215 it, reference, length);
3216 ar9300_uncompress_block(ah, mptr, mdata_size,
3217 (u8 *) (word + COMP_HDR_LEN), length);
3220 ath_dbg(common, ATH_DBG_EEPROM,
3221 "unknown compression code %d\n", code);
3227 typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3230 static bool ar9300_check_header(void *data)
3233 return !(*word == 0 || *word == ~0);
3236 static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3241 if (!read(ah, base_addr, header, 4))
3244 return ar9300_check_header(header);
3247 static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3250 struct ath_common *common = ath9k_hw_common(ah);
3251 u16 *data = (u16 *) mptr;
3254 for (i = 0; i < mdata_size / 2; i++, data++)
3255 ath9k_hw_nvram_read(common, i, data);
3260 * Read the configuration data from the eeprom.
3261 * The data can be put in any specified memory buffer.
3263 * Returns -1 on error.
3264 * Returns address of next memory location on success.
3266 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3267 u8 *mptr, int mdata_size)
3274 int reference, length, major, minor;
3277 u16 checksum, mchecksum;
3278 struct ath_common *common = ath9k_hw_common(ah);
3279 eeprom_read_op read;
3281 if (ath9k_hw_use_flash(ah))
3282 return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
3284 word = kzalloc(2048, GFP_KERNEL);
3288 memcpy(mptr, &ar9300_default, mdata_size);
3290 read = ar9300_read_eeprom;
3291 if (AR_SREV_9485(ah))
3292 cptr = AR9300_BASE_ADDR_4K;
3293 else if (AR_SREV_9330(ah))
3294 cptr = AR9300_BASE_ADDR_512;
3296 cptr = AR9300_BASE_ADDR;
3297 ath_dbg(common, ATH_DBG_EEPROM,
3298 "Trying EEPROM access at Address 0x%04x\n", cptr);
3299 if (ar9300_check_eeprom_header(ah, read, cptr))
3302 cptr = AR9300_BASE_ADDR_512;
3303 ath_dbg(common, ATH_DBG_EEPROM,
3304 "Trying EEPROM access at Address 0x%04x\n", cptr);
3305 if (ar9300_check_eeprom_header(ah, read, cptr))
3308 read = ar9300_read_otp;
3309 cptr = AR9300_BASE_ADDR;
3310 ath_dbg(common, ATH_DBG_EEPROM,
3311 "Trying OTP access at Address 0x%04x\n", cptr);
3312 if (ar9300_check_eeprom_header(ah, read, cptr))
3315 cptr = AR9300_BASE_ADDR_512;
3316 ath_dbg(common, ATH_DBG_EEPROM,
3317 "Trying OTP access at Address 0x%04x\n", cptr);
3318 if (ar9300_check_eeprom_header(ah, read, cptr))
3324 ath_dbg(common, ATH_DBG_EEPROM, "Found valid EEPROM data\n");
3326 for (it = 0; it < MSTATE; it++) {
3327 if (!read(ah, cptr, word, COMP_HDR_LEN))
3330 if (!ar9300_check_header(word))
3333 ar9300_comp_hdr_unpack(word, &code, &reference,
3334 &length, &major, &minor);
3335 ath_dbg(common, ATH_DBG_EEPROM,
3336 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3337 cptr, code, reference, length, major, minor);
3338 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3339 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3340 ath_dbg(common, ATH_DBG_EEPROM,
3341 "Skipping bad header\n");
3342 cptr -= COMP_HDR_LEN;
3347 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3348 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3349 mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
3350 ath_dbg(common, ATH_DBG_EEPROM,
3351 "checksum %x %x\n", checksum, mchecksum);
3352 if (checksum == mchecksum) {
3353 ar9300_compress_decision(ah, it, code, reference, mptr,
3354 word, length, mdata_size);
3356 ath_dbg(common, ATH_DBG_EEPROM,
3357 "skipping block with bad checksum\n");
3359 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3371 * Restore the configuration structure by reading the eeprom.
3372 * This function destroys any existing in-memory structure
3375 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
3377 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
3379 if (ar9300_eeprom_restore_internal(ah, mptr,
3380 sizeof(struct ar9300_eeprom)) < 0)
3386 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3387 static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
3388 struct ar9300_modal_eep_header *modal_hdr)
3390 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
3391 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
3392 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
3393 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
3394 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
3395 PR_EEP("Ant. Gain", modal_hdr->antennaGain);
3396 PR_EEP("Switch Settle", modal_hdr->switchSettling);
3397 PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
3398 PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
3399 PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
3400 PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
3401 PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
3402 PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
3403 PR_EEP("Temp Slope", modal_hdr->tempSlope);
3404 PR_EEP("Volt Slope", modal_hdr->voltSlope);
3405 PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
3406 PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
3407 PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
3408 PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
3409 PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
3410 PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
3411 PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
3412 PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
3413 PR_EEP("Quick Drop", modal_hdr->quick_drop);
3414 PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
3415 PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
3416 PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
3417 PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
3418 PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
3419 PR_EEP("txClip", modal_hdr->txClip);
3420 PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
3425 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3426 u8 *buf, u32 len, u32 size)
3428 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3429 struct ar9300_base_eep_hdr *pBase;
3431 if (!dump_base_hdr) {
3432 len += snprintf(buf + len, size - len,
3433 "%20s :\n", "2GHz modal Header");
3434 len += ar9003_dump_modal_eeprom(buf, len, size,
3435 &eep->modalHeader2G);
3436 len += snprintf(buf + len, size - len,
3437 "%20s :\n", "5GHz modal Header");
3438 len += ar9003_dump_modal_eeprom(buf, len, size,
3439 &eep->modalHeader5G);
3443 pBase = &eep->baseEepHeader;
3445 PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
3446 PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
3447 PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
3448 PR_EEP("TX Mask", (pBase->txrxMask >> 4));
3449 PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
3450 PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
3451 AR5416_OPFLAGS_11A));
3452 PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
3453 AR5416_OPFLAGS_11G));
3454 PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
3455 AR5416_OPFLAGS_N_2G_HT20));
3456 PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
3457 AR5416_OPFLAGS_N_2G_HT40));
3458 PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
3459 AR5416_OPFLAGS_N_5G_HT20));
3460 PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
3461 AR5416_OPFLAGS_N_5G_HT40));
3462 PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
3463 PR_EEP("RF Silent", pBase->rfSilent);
3464 PR_EEP("BT option", pBase->blueToothOptions);
3465 PR_EEP("Device Cap", pBase->deviceCap);
3466 PR_EEP("Device Type", pBase->deviceType);
3467 PR_EEP("Power Table Offset", pBase->pwrTableOffset);
3468 PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
3469 PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
3470 PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
3471 PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
3472 PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
3473 PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
3474 PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
3475 PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
3476 PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
3477 PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1)));
3478 PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
3479 PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
3480 PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
3481 PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
3482 PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
3483 PR_EEP("Tx Gain", pBase->txrxgain >> 4);
3484 PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
3485 PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
3487 len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
3488 ah->eeprom.ar9300_eep.macAddr);
3496 static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
3497 u8 *buf, u32 len, u32 size)
3503 /* XXX: review hardware docs */
3504 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
3506 return ah->eeprom.ar9300_eep.eepromVersion;
3509 /* XXX: could be read from the eepromVersion, not sure yet */
3510 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3515 static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
3517 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3520 return eep->modalHeader2G.xpaBiasLvl;
3522 return eep->modalHeader5G.xpaBiasLvl;
3525 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3527 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
3529 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3530 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3531 else if (AR_SREV_9462(ah))
3532 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3534 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3535 REG_RMW_FIELD(ah, AR_CH0_THERM,
3536 AR_CH0_THERM_XPABIASLVL_MSB,
3538 REG_RMW_FIELD(ah, AR_CH0_THERM,
3539 AR_CH0_THERM_XPASHORT2GND, 1);
3543 static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz)
3545 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3549 val = eep->modalHeader2G.switchcomspdt;
3551 val = eep->modalHeader5G.switchcomspdt;
3552 return le32_to_cpu(val);
3556 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
3558 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3562 val = eep->modalHeader2G.antCtrlCommon;
3564 val = eep->modalHeader5G.antCtrlCommon;
3565 return le32_to_cpu(val);
3568 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
3570 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3574 val = eep->modalHeader2G.antCtrlCommon2;
3576 val = eep->modalHeader5G.antCtrlCommon2;
3577 return le32_to_cpu(val);
3580 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
3584 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3587 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
3589 val = eep->modalHeader2G.antCtrlChain[chain];
3591 val = eep->modalHeader5G.antCtrlChain[chain];
3594 return le16_to_cpu(val);
3597 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3602 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3603 AR_PHY_SWITCH_CHAIN_0,
3604 AR_PHY_SWITCH_CHAIN_1,
3605 AR_PHY_SWITCH_CHAIN_2,
3608 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3610 if (AR_SREV_9462(ah)) {
3611 if (AR_SREV_9462_10(ah)) {
3612 value &= ~AR_SWITCH_TABLE_COM_SPDT;
3613 value |= 0x00100000;
3615 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3616 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3618 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3619 AR_SWITCH_TABLE_COM_ALL, value);
3623 * AR9462 defines new switch table for BT/WLAN,
3624 * here's new field name in XXX.ref for both 2G and 5G.
3625 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3626 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3627 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3629 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3630 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3632 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3633 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3635 if (AR_SREV_9462_20_OR_LATER(ah)) {
3636 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3637 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3638 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
3641 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
3642 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
3644 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
3645 if ((ah->rxchainmask & BIT(chain)) ||
3646 (ah->txchainmask & BIT(chain))) {
3647 value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
3649 REG_RMW_FIELD(ah, switch_chain_reg[chain],
3650 AR_SWITCH_TABLE_ALL, value);
3654 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3655 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3657 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3658 * are the fields present
3660 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3661 regval &= (~AR_ANT_DIV_CTRL_ALL);
3662 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3664 regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
3665 regval |= ((value >> 6) & 0x1) <<
3666 AR_PHY_9485_ANT_DIV_LNADIV_S;
3667 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3669 /*enable fast_div */
3670 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3671 regval &= (~AR_FAST_DIV_ENABLE);
3672 regval |= ((value >> 7) & 0x1) <<
3673 AR_FAST_DIV_ENABLE_S;
3674 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3676 ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
3677 /* check whether antenna diversity is enabled */
3678 if ((ant_div_ctl1 >> 0x6) == 0x3) {
3679 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3681 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3684 regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
3685 AR_PHY_9485_ANT_DIV_ALT_LNACONF |
3686 AR_PHY_9485_ANT_DIV_ALT_GAINTB |
3687 AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
3688 /* by default use LNA1 for the main antenna */
3689 regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
3690 AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
3691 regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
3692 AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
3693 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3701 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
3706 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
3708 if (!drive_strength)
3711 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
3719 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
3721 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
3732 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
3734 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
3739 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
3742 static u16 ar9003_hw_atten_chain_get(struct ath_hw *ah, int chain,
3743 struct ath9k_channel *chan)
3747 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3749 if (chain >= 0 && chain < 3) {
3750 if (IS_CHAN_2GHZ(chan))
3751 return eep->modalHeader2G.xatten1DB[chain];
3752 else if (eep->base_ext2.xatten1DBLow[chain] != 0) {
3753 t[0] = eep->base_ext2.xatten1DBLow[chain];
3755 t[1] = eep->modalHeader5G.xatten1DB[chain];
3757 t[2] = eep->base_ext2.xatten1DBHigh[chain];
3759 value = ar9003_hw_power_interpolate((s32) chan->channel,
3763 return eep->modalHeader5G.xatten1DB[chain];
3770 static u16 ar9003_hw_atten_chain_get_margin(struct ath_hw *ah, int chain,
3771 struct ath9k_channel *chan)
3775 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3777 if (chain >= 0 && chain < 3) {
3778 if (IS_CHAN_2GHZ(chan))
3779 return eep->modalHeader2G.xatten1Margin[chain];
3780 else if (eep->base_ext2.xatten1MarginLow[chain] != 0) {
3781 t[0] = eep->base_ext2.xatten1MarginLow[chain];
3783 t[1] = eep->modalHeader5G.xatten1Margin[chain];
3785 t[2] = eep->base_ext2.xatten1MarginHigh[chain];
3787 value = ar9003_hw_power_interpolate((s32) chan->channel,
3791 return eep->modalHeader5G.xatten1Margin[chain];
3797 static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
3801 unsigned long ext_atten_reg[3] = {AR_PHY_EXT_ATTEN_CTL_0,
3802 AR_PHY_EXT_ATTEN_CTL_1,
3803 AR_PHY_EXT_ATTEN_CTL_2,
3806 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3807 for (i = 0; i < 3; i++) {
3808 if (ah->txchainmask & BIT(i)) {
3809 value = ar9003_hw_atten_chain_get(ah, i, chan);
3810 REG_RMW_FIELD(ah, ext_atten_reg[i],
3811 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
3813 value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
3814 REG_RMW_FIELD(ah, ext_atten_reg[i],
3815 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
3821 static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
3825 while (pmu_set != REG_READ(ah, pmu_reg)) {
3828 REG_WRITE(ah, pmu_reg, pmu_set);
3835 static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3837 int internal_regulator =
3838 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
3841 if (internal_regulator) {
3842 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3845 reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
3846 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3847 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3850 if (AR_SREV_9330(ah)) {
3851 if (ah->is_clk_25mhz) {
3852 reg_pmu_set = (3 << 1) | (8 << 4) |
3853 (3 << 8) | (1 << 14) |
3854 (6 << 17) | (1 << 20) |
3857 reg_pmu_set = (4 << 1) | (7 << 4) |
3858 (3 << 8) | (1 << 14) |
3859 (6 << 17) | (1 << 20) |
3863 reg_pmu_set = (5 << 1) | (7 << 4) |
3864 (2 << 8) | (2 << 14) |
3865 (6 << 17) | (1 << 20) |
3866 (3 << 24) | (1 << 28);
3869 REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
3870 if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
3873 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0xFFC00000)
3875 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3876 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3879 reg_pmu_set = (REG_READ(ah, AR_PHY_PMU2) & ~0x00200000)
3881 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3882 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3884 } else if (AR_SREV_9462(ah)) {
3885 reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
3886 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3888 /* Internal regulator is ON. Write swreg register. */
3889 reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
3890 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3891 REG_READ(ah, AR_RTC_REG_CONTROL1) &
3892 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
3893 REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
3894 /* Set REG_CONTROL1.SWREG_PROGRAM */
3895 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
3897 AR_RTC_REG_CONTROL1) |
3898 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
3901 if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
3902 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
3903 while (REG_READ_FIELD(ah, AR_PHY_PMU2,
3907 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3908 while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
3911 REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
3912 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3915 } else if (AR_SREV_9462(ah))
3916 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3918 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
3919 AR_RTC_FORCE_SWREG_PRD;
3920 REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
3926 static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3928 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3929 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3931 if (eep->baseEepHeader.featureEnable & 0x40) {
3932 tuning_caps_param &= 0x7f;
3933 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
3935 REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPOUTDAC,
3940 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
3942 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3943 int quick_drop = ath9k_hw_ar9300_get_eeprom(ah, EEP_QUICK_DROP);
3944 s32 t[3], f[3] = {5180, 5500, 5785};
3950 quick_drop = eep->modalHeader2G.quick_drop;
3952 t[0] = eep->base_ext1.quick_drop_low;
3953 t[1] = eep->modalHeader5G.quick_drop;
3954 t[2] = eep->base_ext1.quick_drop_high;
3955 quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
3957 REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
3960 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq)
3962 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3965 value = (freq < 4000) ? eep->modalHeader2G.txEndToXpaOff :
3966 eep->modalHeader5G.txEndToXpaOff;
3968 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3969 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
3970 REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
3971 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
3974 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
3975 struct ath9k_channel *chan)
3977 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
3978 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
3979 ar9003_hw_drive_strength_apply(ah);
3980 ar9003_hw_atten_apply(ah, chan);
3981 ar9003_hw_quick_drop_apply(ah, chan->channel);
3982 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah))
3983 ar9003_hw_internal_regulator_apply(ah);
3984 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3985 ar9003_hw_apply_tuning_caps(ah);
3986 ar9003_hw_txend_to_xpa_off_apply(ah, chan->channel);
3989 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
3990 struct ath9k_channel *chan)
3995 * Returns the interpolated y value corresponding to the specified x value
3996 * from the np ordered pairs of data (px,py).
3997 * The pairs do not have to be in any order.
3998 * If the specified x value is less than any of the px,
3999 * the returned y value is equal to the py for the lowest px.
4000 * If the specified x value is greater than any of the px,
4001 * the returned y value is equal to the py for the highest px.
4003 static int ar9003_hw_power_interpolate(int32_t x,
4004 int32_t *px, int32_t *py, u_int16_t np)
4007 int lx = 0, ly = 0, lhave = 0;
4008 int hx = 0, hy = 0, hhave = 0;
4015 /* identify best lower and higher x calibration measurement */
4016 for (ip = 0; ip < np; ip++) {
4019 /* this measurement is higher than our desired x */
4021 if (!hhave || dx > (x - hx)) {
4022 /* new best higher x measurement */
4028 /* this measurement is lower than our desired x */
4030 if (!lhave || dx < (x - lx)) {
4031 /* new best lower x measurement */
4039 /* the low x is good */
4041 /* so is the high x */
4043 /* they're the same, so just pick one */
4046 else /* interpolate */
4047 y = interpolate(x, lx, hx, ly, hy);
4048 } else /* only low is good, use it */
4050 } else if (hhave) /* only high is good, use it */
4052 else /* nothing is good,this should never happen unless np=0, ???? */
4057 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
4058 u16 rateIndex, u16 freq, bool is2GHz)
4061 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4062 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4063 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4064 struct cal_tgt_pow_legacy *pEepromTargetPwr;
4068 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4069 pEepromTargetPwr = eep->calTargetPower2G;
4070 pFreqBin = eep->calTarget_freqbin_2G;
4072 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4073 pEepromTargetPwr = eep->calTargetPower5G;
4074 pFreqBin = eep->calTarget_freqbin_5G;
4078 * create array of channels and targetpower from
4079 * targetpower piers stored on eeprom
4081 for (i = 0; i < numPiers; i++) {
4082 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
4083 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4086 /* interpolate to get target power for given frequency */
4087 return (u8) ar9003_hw_power_interpolate((s32) freq,
4089 targetPowerArray, numPiers);
4092 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
4094 u16 freq, bool is2GHz)
4097 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
4098 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
4099 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4100 struct cal_tgt_pow_ht *pEepromTargetPwr;
4104 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
4105 pEepromTargetPwr = eep->calTargetPower2GHT20;
4106 pFreqBin = eep->calTarget_freqbin_2GHT20;
4108 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
4109 pEepromTargetPwr = eep->calTargetPower5GHT20;
4110 pFreqBin = eep->calTarget_freqbin_5GHT20;
4114 * create array of channels and targetpower
4115 * from targetpower piers stored on eeprom
4117 for (i = 0; i < numPiers; i++) {
4118 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
4119 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4122 /* interpolate to get target power for given frequency */
4123 return (u8) ar9003_hw_power_interpolate((s32) freq,
4125 targetPowerArray, numPiers);
4128 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
4130 u16 freq, bool is2GHz)
4133 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
4134 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
4135 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4136 struct cal_tgt_pow_ht *pEepromTargetPwr;
4140 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
4141 pEepromTargetPwr = eep->calTargetPower2GHT40;
4142 pFreqBin = eep->calTarget_freqbin_2GHT40;
4144 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
4145 pEepromTargetPwr = eep->calTargetPower5GHT40;
4146 pFreqBin = eep->calTarget_freqbin_5GHT40;
4150 * create array of channels and targetpower from
4151 * targetpower piers stored on eeprom
4153 for (i = 0; i < numPiers; i++) {
4154 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
4155 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4158 /* interpolate to get target power for given frequency */
4159 return (u8) ar9003_hw_power_interpolate((s32) freq,
4161 targetPowerArray, numPiers);
4164 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
4165 u16 rateIndex, u16 freq)
4167 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
4168 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4169 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
4170 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4171 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
4172 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
4175 * create array of channels and targetpower from
4176 * targetpower piers stored on eeprom
4178 for (i = 0; i < numPiers; i++) {
4179 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
4180 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
4183 /* interpolate to get target power for given frequency */
4184 return (u8) ar9003_hw_power_interpolate((s32) freq,
4186 targetPowerArray, numPiers);
4189 /* Set tx power registers to array of values passed in */
4190 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4192 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4193 /* make sure forced gain is not set */
4194 REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0);
4196 /* Write the OFDM power per rate set */
4198 /* 6 (LSB), 9, 12, 18 (MSB) */
4199 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0),
4200 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4201 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
4202 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4203 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4205 /* 24 (LSB), 36, 48, 54 (MSB) */
4206 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1),
4207 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
4208 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
4209 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
4210 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
4212 /* Write the CCK power per rate set */
4214 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4215 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2),
4216 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
4217 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4218 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4219 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
4221 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4222 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3),
4223 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
4224 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
4225 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
4226 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4229 /* Write the power for duplicated frames - HT40 */
4231 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4232 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
4233 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4234 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4235 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4236 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4239 /* Write the HT20 power per rate set */
4241 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4242 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4),
4243 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
4244 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
4245 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
4246 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
4249 /* 6 (LSB), 7, 12, 13 (MSB) */
4250 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5),
4251 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
4252 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
4253 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
4254 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
4257 /* 14 (LSB), 15, 20, 21 */
4258 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9),
4259 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
4260 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
4261 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
4262 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
4265 /* Mixed HT20 and HT40 rates */
4267 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4268 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10),
4269 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
4270 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
4271 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
4272 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
4276 * Write the HT40 power per rate set
4277 * correct PAR difference between HT40 and HT20/LEGACY
4278 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4280 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6),
4281 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
4282 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
4283 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
4284 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
4287 /* 6 (LSB), 7, 12, 13 (MSB) */
4288 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7),
4289 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
4290 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
4291 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
4292 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
4295 /* 14 (LSB), 15, 20, 21 */
4296 REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11),
4297 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
4298 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
4299 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
4300 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
4307 static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
4308 u8 *targetPowerValT2)
4310 /* XXX: hard code for now, need to get from eeprom struct */
4311 u8 ht40PowerIncForPdadc = 0;
4312 bool is2GHz = false;
4314 struct ath_common *common = ath9k_hw_common(ah);
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,
4331 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
4332 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
4334 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
4335 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
4336 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
4337 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
4338 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
4339 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
4340 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
4341 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4343 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
4344 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4346 targetPowerValT2[ALL_TARGET_HT20_4] =
4347 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4349 targetPowerValT2[ALL_TARGET_HT20_5] =
4350 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4352 targetPowerValT2[ALL_TARGET_HT20_6] =
4353 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4355 targetPowerValT2[ALL_TARGET_HT20_7] =
4356 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4358 targetPowerValT2[ALL_TARGET_HT20_12] =
4359 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4361 targetPowerValT2[ALL_TARGET_HT20_13] =
4362 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4364 targetPowerValT2[ALL_TARGET_HT20_14] =
4365 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4367 targetPowerValT2[ALL_TARGET_HT20_15] =
4368 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4370 targetPowerValT2[ALL_TARGET_HT20_20] =
4371 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4373 targetPowerValT2[ALL_TARGET_HT20_21] =
4374 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4376 targetPowerValT2[ALL_TARGET_HT20_22] =
4377 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4379 targetPowerValT2[ALL_TARGET_HT20_23] =
4380 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4382 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
4383 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
4384 is2GHz) + ht40PowerIncForPdadc;
4385 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
4386 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
4388 is2GHz) + ht40PowerIncForPdadc;
4389 targetPowerValT2[ALL_TARGET_HT40_4] =
4390 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
4391 is2GHz) + ht40PowerIncForPdadc;
4392 targetPowerValT2[ALL_TARGET_HT40_5] =
4393 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
4394 is2GHz) + ht40PowerIncForPdadc;
4395 targetPowerValT2[ALL_TARGET_HT40_6] =
4396 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
4397 is2GHz) + ht40PowerIncForPdadc;
4398 targetPowerValT2[ALL_TARGET_HT40_7] =
4399 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
4400 is2GHz) + ht40PowerIncForPdadc;
4401 targetPowerValT2[ALL_TARGET_HT40_12] =
4402 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
4403 is2GHz) + ht40PowerIncForPdadc;
4404 targetPowerValT2[ALL_TARGET_HT40_13] =
4405 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
4406 is2GHz) + ht40PowerIncForPdadc;
4407 targetPowerValT2[ALL_TARGET_HT40_14] =
4408 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
4409 is2GHz) + ht40PowerIncForPdadc;
4410 targetPowerValT2[ALL_TARGET_HT40_15] =
4411 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
4412 is2GHz) + ht40PowerIncForPdadc;
4413 targetPowerValT2[ALL_TARGET_HT40_20] =
4414 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
4415 is2GHz) + ht40PowerIncForPdadc;
4416 targetPowerValT2[ALL_TARGET_HT40_21] =
4417 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
4418 is2GHz) + ht40PowerIncForPdadc;
4419 targetPowerValT2[ALL_TARGET_HT40_22] =
4420 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
4421 is2GHz) + ht40PowerIncForPdadc;
4422 targetPowerValT2[ALL_TARGET_HT40_23] =
4423 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
4424 is2GHz) + ht40PowerIncForPdadc;
4426 for (i = 0; i < ar9300RateSize; i++) {
4427 ath_dbg(common, ATH_DBG_EEPROM,
4428 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
4432 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
4438 int *ptemperature, int *pvoltage)
4441 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
4443 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4444 struct ath_common *common = ath9k_hw_common(ah);
4446 if (ichain >= AR9300_MAX_CHAINS) {
4447 ath_dbg(common, ATH_DBG_EEPROM,
4448 "Invalid chain index, must be less than %d\n",
4453 if (mode) { /* 5GHz */
4454 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
4455 ath_dbg(common, ATH_DBG_EEPROM,
4456 "Invalid 5GHz cal pier index, must be less than %d\n",
4457 AR9300_NUM_5G_CAL_PIERS);
4460 pCalPier = &(eep->calFreqPier5G[ipier]);
4461 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
4464 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
4465 ath_dbg(common, ATH_DBG_EEPROM,
4466 "Invalid 2GHz cal pier index, must be less than %d\n",
4467 AR9300_NUM_2G_CAL_PIERS);
4471 pCalPier = &(eep->calFreqPier2G[ipier]);
4472 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
4476 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
4477 *pcorrection = pCalPierStruct->refPower;
4478 *ptemperature = pCalPierStruct->tempMeas;
4479 *pvoltage = pCalPierStruct->voltMeas;
4484 static int ar9003_hw_power_control_override(struct ath_hw *ah,
4487 int *voltage, int *temperature)
4490 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4493 REG_RMW(ah, AR_PHY_TPC_11_B0,
4494 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4495 AR_PHY_TPC_OLPC_GAIN_DELTA);
4496 if (ah->caps.tx_chainmask & BIT(1))
4497 REG_RMW(ah, AR_PHY_TPC_11_B1,
4498 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4499 AR_PHY_TPC_OLPC_GAIN_DELTA);
4500 if (ah->caps.tx_chainmask & BIT(2))
4501 REG_RMW(ah, AR_PHY_TPC_11_B2,
4502 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
4503 AR_PHY_TPC_OLPC_GAIN_DELTA);
4505 /* enable open loop power control on chip */
4506 REG_RMW(ah, AR_PHY_TPC_6_B0,
4507 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4508 AR_PHY_TPC_6_ERROR_EST_MODE);
4509 if (ah->caps.tx_chainmask & BIT(1))
4510 REG_RMW(ah, AR_PHY_TPC_6_B1,
4511 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4512 AR_PHY_TPC_6_ERROR_EST_MODE);
4513 if (ah->caps.tx_chainmask & BIT(2))
4514 REG_RMW(ah, AR_PHY_TPC_6_B2,
4515 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
4516 AR_PHY_TPC_6_ERROR_EST_MODE);
4519 * enable temperature compensation
4520 * Need to use register names
4522 if (frequency < 4000)
4523 tempSlope = eep->modalHeader2G.tempSlope;
4524 else if (eep->base_ext2.tempSlopeLow != 0) {
4525 t[0] = eep->base_ext2.tempSlopeLow;
4527 t[1] = eep->modalHeader5G.tempSlope;
4529 t[2] = eep->base_ext2.tempSlopeHigh;
4531 tempSlope = ar9003_hw_power_interpolate((s32) frequency,
4534 tempSlope = eep->modalHeader5G.tempSlope;
4536 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
4538 if (AR_SREV_9462_20(ah))
4539 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4540 AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope);
4543 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
4549 /* Apply the recorded correction values. */
4550 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
4552 int ichain, ipier, npier;
4554 int lfrequency[AR9300_MAX_CHAINS],
4555 lcorrection[AR9300_MAX_CHAINS],
4556 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
4557 int hfrequency[AR9300_MAX_CHAINS],
4558 hcorrection[AR9300_MAX_CHAINS],
4559 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
4561 int correction[AR9300_MAX_CHAINS],
4562 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
4563 int pfrequency, pcorrection, ptemperature, pvoltage;
4564 struct ath_common *common = ath9k_hw_common(ah);
4566 mode = (frequency >= 4000);
4568 npier = AR9300_NUM_5G_CAL_PIERS;
4570 npier = AR9300_NUM_2G_CAL_PIERS;
4572 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4573 lfrequency[ichain] = 0;
4574 hfrequency[ichain] = 100000;
4576 /* identify best lower and higher frequency calibration measurement */
4577 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4578 for (ipier = 0; ipier < npier; ipier++) {
4579 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
4580 &pfrequency, &pcorrection,
4581 &ptemperature, &pvoltage)) {
4582 fdiff = frequency - pfrequency;
4585 * this measurement is higher than
4586 * our desired frequency
4589 if (hfrequency[ichain] <= 0 ||
4590 hfrequency[ichain] >= 100000 ||
4592 (frequency - hfrequency[ichain])) {
4595 * frequency measurement
4597 hfrequency[ichain] = pfrequency;
4598 hcorrection[ichain] =
4600 htemperature[ichain] =
4602 hvoltage[ichain] = pvoltage;
4606 if (lfrequency[ichain] <= 0
4608 (frequency - lfrequency[ichain])) {
4611 * frequency measurement
4613 lfrequency[ichain] = pfrequency;
4614 lcorrection[ichain] =
4616 ltemperature[ichain] =
4618 lvoltage[ichain] = pvoltage;
4626 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
4627 ath_dbg(common, ATH_DBG_EEPROM,
4628 "ch=%d f=%d low=%d %d h=%d %d\n",
4629 ichain, frequency, lfrequency[ichain],
4630 lcorrection[ichain], hfrequency[ichain],
4631 hcorrection[ichain]);
4632 /* they're the same, so just pick one */
4633 if (hfrequency[ichain] == lfrequency[ichain]) {
4634 correction[ichain] = lcorrection[ichain];
4635 voltage[ichain] = lvoltage[ichain];
4636 temperature[ichain] = ltemperature[ichain];
4638 /* the low frequency is good */
4639 else if (frequency - lfrequency[ichain] < 1000) {
4640 /* so is the high frequency, interpolate */
4641 if (hfrequency[ichain] - frequency < 1000) {
4643 correction[ichain] = interpolate(frequency,
4646 lcorrection[ichain],
4647 hcorrection[ichain]);
4649 temperature[ichain] = interpolate(frequency,
4652 ltemperature[ichain],
4653 htemperature[ichain]);
4655 voltage[ichain] = interpolate(frequency,
4661 /* only low is good, use it */
4663 correction[ichain] = lcorrection[ichain];
4664 temperature[ichain] = ltemperature[ichain];
4665 voltage[ichain] = lvoltage[ichain];
4668 /* only high is good, use it */
4669 else if (hfrequency[ichain] - frequency < 1000) {
4670 correction[ichain] = hcorrection[ichain];
4671 temperature[ichain] = htemperature[ichain];
4672 voltage[ichain] = hvoltage[ichain];
4673 } else { /* nothing is good, presume 0???? */
4674 correction[ichain] = 0;
4675 temperature[ichain] = 0;
4676 voltage[ichain] = 0;
4680 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
4683 ath_dbg(common, ATH_DBG_EEPROM,
4684 "for frequency=%d, calibration correction = %d %d %d\n",
4685 frequency, correction[0], correction[1], correction[2]);
4690 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
4695 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4696 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4699 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
4701 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
4704 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4710 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
4711 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
4713 u8 *ctl_freqbin = is2GHz ?
4714 &eep->ctl_freqbin_2G[idx][0] :
4715 &eep->ctl_freqbin_5G[idx][0];
4718 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
4719 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
4720 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
4722 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
4723 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
4724 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4727 return MAX_RATE_POWER;
4731 * Find the maximum conformance test limit for the given channel and CTL info
4733 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4734 u16 freq, int idx, bool is2GHz)
4736 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4737 u8 *ctl_freqbin = is2GHz ?
4738 &eep->ctl_freqbin_2G[idx][0] :
4739 &eep->ctl_freqbin_5G[idx][0];
4740 u16 num_edges = is2GHz ?
4741 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
4744 /* Get the edge power */
4746 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
4749 * If there's an exact channel match or an inband flag set
4750 * on the lower channel use the given rdEdgePower
4752 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
4754 ar9003_hw_get_direct_edge_power(eep, idx,
4757 } else if ((edge > 0) &&
4758 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
4761 ar9003_hw_get_indirect_edge_power(eep, idx,
4765 * Leave loop - no more affecting edges possible in
4766 * this monotonic increasing list
4771 return twiceMaxEdgePower;
4774 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4775 struct ath9k_channel *chan,
4776 u8 *pPwrArray, u16 cfgCtl,
4777 u8 antenna_reduction,
4780 struct ath_common *common = ath9k_hw_common(ah);
4781 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4782 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4784 u16 scaledPower = 0, minCtlPower;
4785 static const u16 ctlModesFor11a[] = {
4786 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4788 static const u16 ctlModesFor11g[] = {
4789 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
4790 CTL_11G_EXT, CTL_2GHT40
4793 const u16 *pCtlMode;
4795 struct chan_centers centers;
4798 u16 twiceMinEdgePower;
4799 bool is2ghz = IS_CHAN_2GHZ(chan);
4801 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
4802 scaledPower = powerLimit - antenna_reduction;
4805 * Reduce scaled Power by number of chains active to get
4806 * to per chain tx power level
4808 switch (ar5416_get_ntxchains(ah->txchainmask)) {
4812 if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
4813 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
4818 if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
4819 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
4825 scaledPower = max((u16)0, scaledPower);
4828 * Get target powers from EEPROM - our baseline for TX Power
4831 /* Setup for CTL modes */
4832 /* CTL_11B, CTL_11G, CTL_2GHT20 */
4834 ARRAY_SIZE(ctlModesFor11g) -
4835 SUB_NUM_CTL_MODES_AT_2G_40;
4836 pCtlMode = ctlModesFor11g;
4837 if (IS_CHAN_HT40(chan))
4839 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4841 /* Setup for CTL modes */
4842 /* CTL_11A, CTL_5GHT20 */
4843 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
4844 SUB_NUM_CTL_MODES_AT_5G_40;
4845 pCtlMode = ctlModesFor11a;
4846 if (IS_CHAN_HT40(chan))
4848 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4852 * For MIMO, need to apply regulatory caps individually across
4853 * dynamically running modes: CCK, OFDM, HT20, HT40
4855 * The outer loop walks through each possible applicable runtime mode.
4856 * The inner loop walks through each ctlIndex entry in EEPROM.
4857 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
4859 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4860 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
4861 (pCtlMode[ctlMode] == CTL_2GHT40);
4863 freq = centers.synth_center;
4864 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4865 freq = centers.ext_center;
4867 freq = centers.ctl_center;
4869 ath_dbg(common, ATH_DBG_REGULATORY,
4870 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
4871 ctlMode, numCtlModes, isHt40CtlMode,
4872 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4874 /* walk through each CTL index stored in EEPROM */
4876 ctlIndex = pEepData->ctlIndex_2G;
4877 ctlNum = AR9300_NUM_CTLS_2G;
4879 ctlIndex = pEepData->ctlIndex_5G;
4880 ctlNum = AR9300_NUM_CTLS_5G;
4883 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
4884 ath_dbg(common, ATH_DBG_REGULATORY,
4885 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
4886 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
4890 * compare test group from regulatory
4891 * channel list with test mode from pCtlMode
4894 if ((((cfgCtl & ~CTL_MODE_M) |
4895 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4897 (((cfgCtl & ~CTL_MODE_M) |
4898 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4899 ((ctlIndex[i] & CTL_MODE_M) |
4902 ar9003_hw_get_max_edge_power(pEepData,
4906 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
4908 * Find the minimum of all CTL
4909 * edge powers that apply to
4913 min(twiceMaxEdgePower,
4924 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
4926 ath_dbg(common, ATH_DBG_REGULATORY,
4927 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
4928 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4929 scaledPower, minCtlPower);
4931 /* Apply ctl mode to correct target power set */
4932 switch (pCtlMode[ctlMode]) {
4934 for (i = ALL_TARGET_LEGACY_1L_5L;
4935 i <= ALL_TARGET_LEGACY_11S; i++)
4937 (u8)min((u16)pPwrArray[i],
4942 for (i = ALL_TARGET_LEGACY_6_24;
4943 i <= ALL_TARGET_LEGACY_54; i++)
4945 (u8)min((u16)pPwrArray[i],
4950 for (i = ALL_TARGET_HT20_0_8_16;
4951 i <= ALL_TARGET_HT20_21; i++)
4953 (u8)min((u16)pPwrArray[i],
4955 pPwrArray[ALL_TARGET_HT20_22] =
4956 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
4958 pPwrArray[ALL_TARGET_HT20_23] =
4959 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
4964 for (i = ALL_TARGET_HT40_0_8_16;
4965 i <= ALL_TARGET_HT40_23; i++)
4967 (u8)min((u16)pPwrArray[i],
4973 } /* end ctl mode checking */
4976 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
4978 u8 mod_idx = mcs_idx % 8;
4981 return mod_idx ? (base_pwridx + 1) : base_pwridx;
4983 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
4986 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4987 struct ath9k_channel *chan, u16 cfgCtl,
4988 u8 twiceAntennaReduction,
4989 u8 powerLimit, bool test)
4991 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4992 struct ath_common *common = ath9k_hw_common(ah);
4993 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4994 struct ar9300_modal_eep_header *modal_hdr;
4995 u8 targetPowerValT2[ar9300RateSize];
4996 u8 target_power_val_t2_eep[ar9300RateSize];
4997 unsigned int i = 0, paprd_scale_factor = 0;
4998 u8 pwr_idx, min_pwridx = 0;
5000 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
5002 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
5003 if (IS_CHAN_2GHZ(chan))
5004 modal_hdr = &eep->modalHeader2G;
5006 modal_hdr = &eep->modalHeader5G;
5008 ah->paprd_ratemask =
5009 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
5010 AR9300_PAPRD_RATE_MASK;
5012 ah->paprd_ratemask_ht40 =
5013 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
5014 AR9300_PAPRD_RATE_MASK;
5016 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
5017 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
5018 ALL_TARGET_HT20_0_8_16;
5020 if (!ah->paprd_table_write_done) {
5021 memcpy(target_power_val_t2_eep, targetPowerValT2,
5022 sizeof(targetPowerValT2));
5023 for (i = 0; i < 24; i++) {
5024 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
5025 if (ah->paprd_ratemask & (1 << i)) {
5026 if (targetPowerValT2[pwr_idx] &&
5027 targetPowerValT2[pwr_idx] ==
5028 target_power_val_t2_eep[pwr_idx])
5029 targetPowerValT2[pwr_idx] -=
5034 memcpy(target_power_val_t2_eep, targetPowerValT2,
5035 sizeof(targetPowerValT2));
5038 ar9003_hw_set_power_per_rate_table(ah, chan,
5039 targetPowerValT2, cfgCtl,
5040 twiceAntennaReduction,
5043 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
5044 for (i = 0; i < ar9300RateSize; i++) {
5045 if ((ah->paprd_ratemask & (1 << i)) &&
5046 (abs(targetPowerValT2[i] -
5047 target_power_val_t2_eep[i]) >
5048 paprd_scale_factor)) {
5049 ah->paprd_ratemask &= ~(1 << i);
5050 ath_dbg(common, ATH_DBG_EEPROM,
5051 "paprd disabled for mcs %d\n", i);
5056 regulatory->max_power_level = 0;
5057 for (i = 0; i < ar9300RateSize; i++) {
5058 if (targetPowerValT2[i] > regulatory->max_power_level)
5059 regulatory->max_power_level = targetPowerValT2[i];
5062 ath9k_hw_update_regulatory_maxpower(ah);
5067 for (i = 0; i < ar9300RateSize; i++) {
5068 ath_dbg(common, ATH_DBG_EEPROM,
5069 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
5072 ah->txpower_limit = regulatory->max_power_level;
5074 /* Write target power array to registers */
5075 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
5076 ar9003_hw_calibration_apply(ah, chan->channel);
5078 if (IS_CHAN_2GHZ(chan)) {
5079 if (IS_CHAN_HT40(chan))
5080 i = ALL_TARGET_HT40_0_8_16;
5082 i = ALL_TARGET_HT20_0_8_16;
5084 if (IS_CHAN_HT40(chan))
5085 i = ALL_TARGET_HT40_7;
5087 i = ALL_TARGET_HT20_7;
5089 ah->paprd_target_power = targetPowerValT2[i];
5092 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
5098 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
5100 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5102 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
5105 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
5107 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5109 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
5112 u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz)
5114 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5117 return eep->modalHeader2G.spurChans;
5119 return eep->modalHeader5G.spurChans;
5122 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5123 struct ath9k_channel *chan)
5125 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
5127 if (IS_CHAN_2GHZ(chan))
5128 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
5129 AR9300_PAPRD_SCALE_1);
5131 if (chan->channel >= 5700)
5132 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5133 AR9300_PAPRD_SCALE_1);
5134 else if (chan->channel >= 5400)
5135 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5136 AR9300_PAPRD_SCALE_2);
5138 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5139 AR9300_PAPRD_SCALE_1);
5143 const struct eeprom_ops eep_ar9300_ops = {
5144 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
5145 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
5146 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
5147 .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
5148 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
5149 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
5150 .set_board_values = ath9k_hw_ar9300_set_board_values,
5151 .set_addac = ath9k_hw_ar9300_set_addac,
5152 .set_txpower = ath9k_hw_ar9300_set_txpower,
5153 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel