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 <linux/unaligned.h>
18 #include <linux/kernel.h>
20 #include "ar9003_phy.h"
21 #include "ar9003_eeprom.h"
22 #include "ar9003_mci.h"
24 #define COMP_HDR_LEN 4
25 #define COMP_CKSUM_LEN 2
27 #define LE16(x) cpu_to_le16(x)
28 #define LE32(x) cpu_to_le32(x)
30 /* Local defines to distinguish between extension and control CTL's */
31 #define EXT_ADDITIVE (0x8000)
32 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
33 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
34 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
36 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
37 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
39 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
41 #define EEPROM_DATA_LEN_9485 1088
43 static int ar9003_hw_power_interpolate(int32_t x
,
44 int32_t *px
, int32_t *py
, u_int16_t np
);
46 static const struct ar9300_eeprom ar9300_default
= {
49 .macAddr
= {0, 2, 3, 4, 5, 6},
50 .custData
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
53 .regDmn
= { LE16(0), LE16(0x1f) },
54 .txrxMask
= 0x77, /* 4 bits tx and 4 bits rx */
56 .opFlags
= AR5416_OPFLAGS_11G
| AR5416_OPFLAGS_11A
,
57 .eepMisc
= AR9300_EEPMISC_LITTLE_ENDIAN
,
60 .blueToothOptions
= 0,
62 .deviceType
= 5, /* takes lower byte in eeprom location */
63 .pwrTableOffset
= AR9300_PWR_TABLE_OFFSET
,
64 .params_for_tuning_caps
= {0, 0},
65 .featureEnable
= 0x0c,
67 * bit0 - enable tx temp comp - disabled
68 * bit1 - enable tx volt comp - disabled
69 * bit2 - enable fastClock - enabled
70 * bit3 - enable doubling - enabled
71 * bit4 - enable internal regulator - disabled
72 * bit5 - enable pa predistortion - disabled
74 .miscConfiguration
= 0, /* bit0 - turn down drivestrength */
75 .eepromWriteEnableGpio
= 3,
78 .rxBandSelectGpio
= 0xff,
83 /* ar9300_modal_eep_header 2g */
84 /* 4 idle,t1,t2,b(4 bits per setting) */
85 .antCtrlCommon
= LE32(0x110),
86 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
87 .antCtrlCommon2
= LE32(0x22222),
90 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
91 * rx1, rx12, b (2 bits each)
93 .antCtrlChain
= { LE16(0x150), LE16(0x150), LE16(0x150) },
96 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
97 * for ar9280 (0xa20c/b20c 5:0)
99 .xatten1DB
= {0, 0, 0},
102 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
103 * for ar9280 (0xa20c/b20c 16:12
105 .xatten1Margin
= {0, 0, 0},
110 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
111 * channels in usual fbin coding format
113 .spurChans
= {0, 0, 0, 0, 0},
116 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
117 * if the register is per chain
119 .noiseFloorThreshCh
= {-1, 0, 0},
120 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
123 .txFrameToDataStart
= 0x0e,
124 .txFrameToPaOn
= 0x0e,
125 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
127 .switchSettling
= 0x2c,
128 .adcDesiredSize
= -30,
131 .txFrameToXpaOn
= 0xe,
133 .papdRateMaskHt20
= LE32(0x0cf0e0e0),
134 .papdRateMaskHt40
= LE32(0x6cf0e0e0),
136 .xlna_bias_strength
= 0,
142 .ant_div_control
= 0,
144 .tempslopextension
= {0, 0, 0, 0, 0, 0, 0, 0}
151 /* ar9300_cal_data_per_freq_op_loop 2g */
153 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
154 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
155 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
157 .calTarget_freqbin_Cck
= {
161 .calTarget_freqbin_2G
= {
166 .calTarget_freqbin_2GHT20
= {
171 .calTarget_freqbin_2GHT40
= {
176 .calTargetPowerCck
= {
177 /* 1L-5L,5S,11L,11S */
178 { {36, 36, 36, 36} },
179 { {36, 36, 36, 36} },
181 .calTargetPower2G
= {
183 { {32, 32, 28, 24} },
184 { {32, 32, 28, 24} },
185 { {32, 32, 28, 24} },
187 .calTargetPower2GHT20
= {
188 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
189 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
190 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
192 .calTargetPower2GHT40
= {
193 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
194 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
195 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
198 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
199 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
229 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
230 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
231 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
232 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
236 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
237 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
238 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
243 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
244 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
250 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
251 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
252 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
253 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
257 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
258 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
259 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
263 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
264 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
265 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
270 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
271 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
272 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
277 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
278 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
279 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
280 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
284 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
285 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
286 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
288 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
289 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
290 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
292 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
293 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
294 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
296 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
297 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
298 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
301 /* 4 idle,t1,t2,b (4 bits per setting) */
302 .antCtrlCommon
= LE32(0x110),
303 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
304 .antCtrlCommon2
= LE32(0x22222),
305 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
307 LE16(0x000), LE16(0x000), LE16(0x000),
309 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
310 .xatten1DB
= {0, 0, 0},
313 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
314 * for merlin (0xa20c/b20c 16:12
316 .xatten1Margin
= {0, 0, 0},
319 /* spurChans spur channels in usual fbin coding format */
320 .spurChans
= {0, 0, 0, 0, 0},
321 /* noiseFloorThreshCh Check if the register is per chain */
322 .noiseFloorThreshCh
= {-1, 0, 0},
323 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
326 .txFrameToDataStart
= 0x0e,
327 .txFrameToPaOn
= 0x0e,
328 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
330 .switchSettling
= 0x2d,
331 .adcDesiredSize
= -30,
334 .txFrameToXpaOn
= 0xe,
336 .papdRateMaskHt20
= LE32(0x0c80c080),
337 .papdRateMaskHt40
= LE32(0x0080c080),
339 .xlna_bias_strength
= 0,
347 .xatten1DBLow
= {0, 0, 0},
348 .xatten1MarginLow
= {0, 0, 0},
349 .xatten1DBHigh
= {0, 0, 0},
350 .xatten1MarginHigh
= {0, 0, 0}
395 .calTarget_freqbin_5G
= {
405 .calTarget_freqbin_5GHT20
= {
415 .calTarget_freqbin_5GHT40
= {
425 .calTargetPower5G
= {
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} },
434 { {20, 20, 20, 10} },
436 .calTargetPower5GHT20
= {
438 * 0_8_16,1-3_9-11_17-19,
439 * 4,5,6,7,12,13,14,15,20,21,22,23
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} },
448 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
450 .calTargetPower5GHT40
= {
452 * 0_8_16,1-3_9-11_17-19,
453 * 4,5,6,7,12,13,14,15,20,21,22,23
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} },
462 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
465 0x10, 0x16, 0x18, 0x40, 0x46,
466 0x48, 0x30, 0x36, 0x38
470 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
471 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
472 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
473 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
474 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
475 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
476 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
477 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
480 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
481 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
482 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
483 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
484 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
485 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
486 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
487 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
491 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
492 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
493 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
494 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
495 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
496 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
497 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
498 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
502 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
503 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
504 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
505 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
506 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
507 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
508 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
509 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
513 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
514 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
515 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
516 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
517 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
518 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
519 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
520 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
524 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
525 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
526 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
527 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
528 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
529 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
530 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
531 /* Data[5].ctlEdges[7].bChannel */ 0xFF
535 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
536 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
537 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
538 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
539 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
540 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
541 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
542 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
546 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
547 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
548 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
549 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
550 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
551 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
552 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
553 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
557 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
558 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
559 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
560 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
561 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
562 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
563 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
564 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
570 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
571 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
576 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
577 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
582 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
583 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
588 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
589 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
594 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
595 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
600 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
601 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
606 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
607 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
612 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
613 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
618 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
619 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
625 static const struct ar9300_eeprom ar9300_x113
= {
627 .templateVersion
= 6,
628 .macAddr
= {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
629 .custData
= {"x113-023-f0000"},
631 .regDmn
= { LE16(0), LE16(0x1f) },
632 .txrxMask
= 0x77, /* 4 bits tx and 4 bits rx */
634 .opFlags
= AR5416_OPFLAGS_11A
,
635 .eepMisc
= AR9300_EEPMISC_LITTLE_ENDIAN
,
638 .blueToothOptions
= 0,
640 .deviceType
= 5, /* takes lower byte in eeprom location */
641 .pwrTableOffset
= AR9300_PWR_TABLE_OFFSET
,
642 .params_for_tuning_caps
= {0, 0},
643 .featureEnable
= 0x0d,
645 * bit0 - enable tx temp comp - disabled
646 * bit1 - enable tx volt comp - disabled
647 * bit2 - enable fastClock - enabled
648 * bit3 - enable doubling - enabled
649 * bit4 - enable internal regulator - disabled
650 * bit5 - enable pa predistortion - disabled
652 .miscConfiguration
= 0, /* bit0 - turn down drivestrength */
653 .eepromWriteEnableGpio
= 6,
654 .wlanDisableGpio
= 0,
656 .rxBandSelectGpio
= 0xff,
661 /* ar9300_modal_eep_header 2g */
662 /* 4 idle,t1,t2,b(4 bits per setting) */
663 .antCtrlCommon
= LE32(0x110),
664 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
665 .antCtrlCommon2
= LE32(0x44444),
668 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
669 * rx1, rx12, b (2 bits each)
671 .antCtrlChain
= { LE16(0x150), LE16(0x150), LE16(0x150) },
674 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
675 * for ar9280 (0xa20c/b20c 5:0)
677 .xatten1DB
= {0, 0, 0},
680 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
681 * for ar9280 (0xa20c/b20c 16:12
683 .xatten1Margin
= {0, 0, 0},
688 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
689 * channels in usual fbin coding format
691 .spurChans
= {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
694 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
695 * if the register is per chain
697 .noiseFloorThreshCh
= {-1, 0, 0},
698 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
701 .txFrameToDataStart
= 0x0e,
702 .txFrameToPaOn
= 0x0e,
703 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
705 .switchSettling
= 0x2c,
706 .adcDesiredSize
= -30,
709 .txFrameToXpaOn
= 0xe,
711 .papdRateMaskHt20
= LE32(0x0c80c080),
712 .papdRateMaskHt40
= LE32(0x0080c080),
714 .xlna_bias_strength
= 0,
720 .ant_div_control
= 0,
722 .tempslopextension
= {0, 0, 0, 0, 0, 0, 0, 0}
729 /* ar9300_cal_data_per_freq_op_loop 2g */
731 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
732 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
733 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
735 .calTarget_freqbin_Cck
= {
739 .calTarget_freqbin_2G
= {
744 .calTarget_freqbin_2GHT20
= {
749 .calTarget_freqbin_2GHT40
= {
754 .calTargetPowerCck
= {
755 /* 1L-5L,5S,11L,11S */
756 { {34, 34, 34, 34} },
757 { {34, 34, 34, 34} },
759 .calTargetPower2G
= {
761 { {34, 34, 32, 32} },
762 { {34, 34, 32, 32} },
763 { {34, 34, 32, 32} },
765 .calTargetPower2GHT20
= {
766 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
767 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
768 { {32, 32, 32, 32, 32, 28, 32, 32, 30, 28, 0, 0, 0, 0} },
770 .calTargetPower2GHT40
= {
771 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
772 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
773 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
776 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
777 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
807 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
808 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
809 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
810 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
814 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
815 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
816 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
821 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
822 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
828 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
829 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
830 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
831 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
835 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
836 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
837 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
841 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
842 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
843 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
848 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
849 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
850 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
855 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
856 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
857 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
858 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
862 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
863 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
864 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
866 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), 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, 1), CTL(60, 0) } },
871 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
872 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
874 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
875 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
876 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
879 /* 4 idle,t1,t2,b (4 bits per setting) */
880 .antCtrlCommon
= LE32(0x220),
881 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
882 .antCtrlCommon2
= LE32(0x11111),
883 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
885 LE16(0x150), LE16(0x150), LE16(0x150),
887 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
888 .xatten1DB
= {0, 0, 0},
891 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
892 * for merlin (0xa20c/b20c 16:12
894 .xatten1Margin
= {0, 0, 0},
897 /* spurChans spur channels in usual fbin coding format */
898 .spurChans
= {FREQ2FBIN(5500, 0), 0, 0, 0, 0},
899 /* noiseFloorThreshCh Check if the register is per chain */
900 .noiseFloorThreshCh
= {-1, 0, 0},
901 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
904 .txFrameToDataStart
= 0x0e,
905 .txFrameToPaOn
= 0x0e,
906 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
908 .switchSettling
= 0x2d,
909 .adcDesiredSize
= -30,
912 .txFrameToXpaOn
= 0xe,
914 .papdRateMaskHt20
= LE32(0x0cf0e0e0),
915 .papdRateMaskHt40
= LE32(0x6cf0e0e0),
917 .xlna_bias_strength
= 0,
924 .tempSlopeHigh
= 105,
925 .xatten1DBLow
= {0, 0, 0},
926 .xatten1MarginLow
= {0, 0, 0},
927 .xatten1DBHigh
= {0, 0, 0},
928 .xatten1MarginHigh
= {0, 0, 0}
973 .calTarget_freqbin_5G
= {
983 .calTarget_freqbin_5GHT20
= {
993 .calTarget_freqbin_5GHT40
= {
1003 .calTargetPower5G
= {
1005 { {42, 40, 40, 34} },
1006 { {42, 40, 40, 34} },
1007 { {42, 40, 40, 34} },
1008 { {42, 40, 40, 34} },
1009 { {42, 40, 40, 34} },
1010 { {42, 40, 40, 34} },
1011 { {42, 40, 40, 34} },
1012 { {42, 40, 40, 34} },
1014 .calTargetPower5GHT20
= {
1016 * 0_8_16,1-3_9-11_17-19,
1017 * 4,5,6,7,12,13,14,15,20,21,22,23
1019 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1020 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1021 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1022 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1023 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1024 { {40, 40, 40, 40, 32, 28, 40, 40, 32, 28, 40, 40, 32, 20} },
1025 { {38, 38, 38, 38, 32, 28, 38, 38, 32, 28, 38, 38, 32, 26} },
1026 { {36, 36, 36, 36, 32, 28, 36, 36, 32, 28, 36, 36, 32, 26} },
1028 .calTargetPower5GHT40
= {
1030 * 0_8_16,1-3_9-11_17-19,
1031 * 4,5,6,7,12,13,14,15,20,21,22,23
1033 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1034 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1035 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1036 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1037 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1038 { {40, 40, 40, 38, 30, 26, 40, 40, 30, 26, 40, 40, 30, 24} },
1039 { {36, 36, 36, 36, 30, 26, 36, 36, 30, 26, 36, 36, 30, 24} },
1040 { {34, 34, 34, 34, 30, 26, 34, 34, 30, 26, 34, 34, 30, 24} },
1043 0x10, 0x16, 0x18, 0x40, 0x46,
1044 0x48, 0x30, 0x36, 0x38
1048 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1049 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1050 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1051 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1052 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1053 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1054 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1055 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1058 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1059 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1060 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1061 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1062 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1063 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1064 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1065 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1069 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1070 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1071 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1072 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1073 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1074 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1075 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1076 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1080 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1081 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1082 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1083 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1084 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1085 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1086 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1087 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1091 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1092 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1093 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1094 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1095 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1096 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1097 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1098 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1102 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1103 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1104 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1105 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1106 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1107 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1108 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1109 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1113 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1114 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1115 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1116 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1117 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1118 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1119 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1120 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1124 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1125 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1126 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1127 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1128 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1129 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1130 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1131 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1135 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1136 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1137 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1138 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1139 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1140 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1141 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1142 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1145 .ctlPowerData_5G
= {
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, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1155 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1160 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1161 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1166 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1167 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1172 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1173 CTL(60, 0), 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, 0), CTL(60, 0), CTL(60, 0),
1184 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1185 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1190 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1191 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1196 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1197 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1204 static const struct ar9300_eeprom ar9300_h112
= {
1206 .templateVersion
= 3,
1207 .macAddr
= {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1208 .custData
= {"h112-241-f0000"},
1210 .regDmn
= { LE16(0), LE16(0x1f) },
1211 .txrxMask
= 0x77, /* 4 bits tx and 4 bits rx */
1213 .opFlags
= AR5416_OPFLAGS_11G
| AR5416_OPFLAGS_11A
,
1214 .eepMisc
= AR9300_EEPMISC_LITTLE_ENDIAN
,
1217 .blueToothOptions
= 0,
1219 .deviceType
= 5, /* takes lower byte in eeprom location */
1220 .pwrTableOffset
= AR9300_PWR_TABLE_OFFSET
,
1221 .params_for_tuning_caps
= {0, 0},
1222 .featureEnable
= 0x0d,
1224 * bit0 - enable tx temp comp - disabled
1225 * bit1 - enable tx volt comp - disabled
1226 * bit2 - enable fastClock - enabled
1227 * bit3 - enable doubling - enabled
1228 * bit4 - enable internal regulator - disabled
1229 * bit5 - enable pa predistortion - disabled
1231 .miscConfiguration
= 0, /* bit0 - turn down drivestrength */
1232 .eepromWriteEnableGpio
= 6,
1233 .wlanDisableGpio
= 0,
1235 .rxBandSelectGpio
= 0xff,
1240 /* ar9300_modal_eep_header 2g */
1241 /* 4 idle,t1,t2,b(4 bits per setting) */
1242 .antCtrlCommon
= LE32(0x110),
1243 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1244 .antCtrlCommon2
= LE32(0x44444),
1247 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
1248 * rx1, rx12, b (2 bits each)
1250 .antCtrlChain
= { LE16(0x150), LE16(0x150), LE16(0x150) },
1253 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
1254 * for ar9280 (0xa20c/b20c 5:0)
1256 .xatten1DB
= {0, 0, 0},
1259 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1260 * for ar9280 (0xa20c/b20c 16:12
1262 .xatten1Margin
= {0, 0, 0},
1267 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
1268 * channels in usual fbin coding format
1270 .spurChans
= {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1273 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
1274 * if the register is per chain
1276 .noiseFloorThreshCh
= {-1, 0, 0},
1277 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1280 .txFrameToDataStart
= 0x0e,
1281 .txFrameToPaOn
= 0x0e,
1282 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1284 .switchSettling
= 0x2c,
1285 .adcDesiredSize
= -30,
1288 .txFrameToXpaOn
= 0xe,
1290 .papdRateMaskHt20
= LE32(0x0c80c080),
1291 .papdRateMaskHt40
= LE32(0x0080c080),
1293 .xlna_bias_strength
= 0,
1295 0, 0, 0, 0, 0, 0, 0,
1299 .ant_div_control
= 0,
1301 .tempslopextension
= {0, 0, 0, 0, 0, 0, 0, 0}
1308 /* ar9300_cal_data_per_freq_op_loop 2g */
1310 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1311 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1312 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1314 .calTarget_freqbin_Cck
= {
1318 .calTarget_freqbin_2G
= {
1323 .calTarget_freqbin_2GHT20
= {
1328 .calTarget_freqbin_2GHT40
= {
1333 .calTargetPowerCck
= {
1334 /* 1L-5L,5S,11L,11S */
1335 { {34, 34, 34, 34} },
1336 { {34, 34, 34, 34} },
1338 .calTargetPower2G
= {
1340 { {34, 34, 32, 32} },
1341 { {34, 34, 32, 32} },
1342 { {34, 34, 32, 32} },
1344 .calTargetPower2GHT20
= {
1345 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1346 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1347 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 28, 28, 28, 24} },
1349 .calTargetPower2GHT40
= {
1350 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1351 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1352 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 26, 26, 26, 22} },
1355 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1356 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1386 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1387 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1388 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1389 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
1393 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1394 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1395 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1400 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1401 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1407 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1408 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1409 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1410 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1414 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1415 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1416 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1420 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1421 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1422 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1427 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
1428 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
1429 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
1434 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
1435 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
1436 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
1437 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
1440 .ctlPowerData_2G
= {
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) } },
1443 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
1445 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
1446 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1447 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1449 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
1450 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1451 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1453 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
1454 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1455 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
1458 /* 4 idle,t1,t2,b (4 bits per setting) */
1459 .antCtrlCommon
= LE32(0x220),
1460 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
1461 .antCtrlCommon2
= LE32(0x44444),
1462 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
1464 LE16(0x150), LE16(0x150), LE16(0x150),
1466 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
1467 .xatten1DB
= {0, 0, 0},
1470 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
1471 * for merlin (0xa20c/b20c 16:12
1473 .xatten1Margin
= {0, 0, 0},
1476 /* spurChans spur channels in usual fbin coding format */
1477 .spurChans
= {0, 0, 0, 0, 0},
1478 /* noiseFloorThreshCh Check if the register is per chain */
1479 .noiseFloorThreshCh
= {-1, 0, 0},
1480 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1483 .txFrameToDataStart
= 0x0e,
1484 .txFrameToPaOn
= 0x0e,
1485 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1487 .switchSettling
= 0x2d,
1488 .adcDesiredSize
= -30,
1491 .txFrameToXpaOn
= 0xe,
1493 .papdRateMaskHt20
= LE32(0x0cf0e0e0),
1494 .papdRateMaskHt40
= LE32(0x6cf0e0e0),
1496 .xlna_bias_strength
= 0,
1498 0, 0, 0, 0, 0, 0, 0,
1503 .tempSlopeHigh
= 50,
1504 .xatten1DBLow
= {0, 0, 0},
1505 .xatten1MarginLow
= {0, 0, 0},
1506 .xatten1DBHigh
= {0, 0, 0},
1507 .xatten1MarginHigh
= {0, 0, 0}
1552 .calTarget_freqbin_5G
= {
1562 .calTarget_freqbin_5GHT20
= {
1572 .calTarget_freqbin_5GHT40
= {
1582 .calTargetPower5G
= {
1584 { {30, 30, 28, 24} },
1585 { {30, 30, 28, 24} },
1586 { {30, 30, 28, 24} },
1587 { {30, 30, 28, 24} },
1588 { {30, 30, 28, 24} },
1589 { {30, 30, 28, 24} },
1590 { {30, 30, 28, 24} },
1591 { {30, 30, 28, 24} },
1593 .calTargetPower5GHT20
= {
1595 * 0_8_16,1-3_9-11_17-19,
1596 * 4,5,6,7,12,13,14,15,20,21,22,23
1598 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1599 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 20, 20, 20, 16} },
1600 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1601 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 18, 18, 18, 16} },
1602 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1603 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 16, 16, 16, 14} },
1604 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1605 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 14, 14, 14, 12} },
1607 .calTargetPower5GHT40
= {
1609 * 0_8_16,1-3_9-11_17-19,
1610 * 4,5,6,7,12,13,14,15,20,21,22,23
1612 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1613 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 18, 18, 18, 14} },
1614 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1615 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 16, 16, 16, 12} },
1616 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1617 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 14, 14, 14, 10} },
1618 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1619 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 12, 12, 12, 8} },
1622 0x10, 0x16, 0x18, 0x40, 0x46,
1623 0x48, 0x30, 0x36, 0x38
1627 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1628 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1629 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1630 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1631 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
1632 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1633 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1634 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1637 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1638 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1639 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
1640 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1641 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
1642 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1643 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1644 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1648 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1649 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1650 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1651 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
1652 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
1653 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
1654 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
1655 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
1659 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1660 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1661 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
1662 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
1663 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1664 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1665 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
1666 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
1670 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1671 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1672 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
1673 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
1674 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
1675 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
1676 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
1677 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
1681 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1682 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
1683 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
1684 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1685 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
1686 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1687 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
1688 /* Data[5].ctlEdges[7].bChannel */ 0xFF
1692 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1693 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
1694 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
1695 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
1696 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
1697 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
1698 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
1699 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
1703 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
1704 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
1705 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
1706 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
1707 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
1708 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
1709 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
1710 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
1714 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
1715 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
1716 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
1717 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
1718 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
1719 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
1720 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
1721 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
1724 .ctlPowerData_5G
= {
1727 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1728 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1733 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1734 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1739 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1740 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1745 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1746 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1751 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1752 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1757 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1758 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
1763 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1764 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
1769 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1770 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
1775 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
1776 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
1783 static const struct ar9300_eeprom ar9300_x112
= {
1785 .templateVersion
= 5,
1786 .macAddr
= {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
1787 .custData
= {"x112-041-f0000"},
1789 .regDmn
= { LE16(0), LE16(0x1f) },
1790 .txrxMask
= 0x77, /* 4 bits tx and 4 bits rx */
1792 .opFlags
= AR5416_OPFLAGS_11G
| AR5416_OPFLAGS_11A
,
1793 .eepMisc
= AR9300_EEPMISC_LITTLE_ENDIAN
,
1796 .blueToothOptions
= 0,
1798 .deviceType
= 5, /* takes lower byte in eeprom location */
1799 .pwrTableOffset
= AR9300_PWR_TABLE_OFFSET
,
1800 .params_for_tuning_caps
= {0, 0},
1801 .featureEnable
= 0x0d,
1803 * bit0 - enable tx temp comp - disabled
1804 * bit1 - enable tx volt comp - disabled
1805 * bit2 - enable fastclock - enabled
1806 * bit3 - enable doubling - enabled
1807 * bit4 - enable internal regulator - disabled
1808 * bit5 - enable pa predistortion - disabled
1810 .miscConfiguration
= 0, /* bit0 - turn down drivestrength */
1811 .eepromWriteEnableGpio
= 6,
1812 .wlanDisableGpio
= 0,
1814 .rxBandSelectGpio
= 0xff,
1819 /* ar9300_modal_eep_header 2g */
1820 /* 4 idle,t1,t2,b(4 bits per setting) */
1821 .antCtrlCommon
= LE32(0x110),
1822 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
1823 .antCtrlCommon2
= LE32(0x22222),
1826 * antCtrlChain[ar9300_max_chains]; 6 idle, t, r,
1827 * rx1, rx12, b (2 bits each)
1829 .antCtrlChain
= { LE16(0x10), LE16(0x10), LE16(0x10) },
1832 * xatten1DB[AR9300_max_chains]; 3 xatten1_db
1833 * for ar9280 (0xa20c/b20c 5:0)
1835 .xatten1DB
= {0x1b, 0x1b, 0x1b},
1838 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
1839 * for ar9280 (0xa20c/b20c 16:12
1841 .xatten1Margin
= {0x15, 0x15, 0x15},
1846 * spurChans[OSPrey_eeprom_modal_sPURS]; spur
1847 * channels in usual fbin coding format
1849 .spurChans
= {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
1852 * noiseFloorThreshch[ar9300_max_cHAINS]; 3 Check
1853 * if the register is per chain
1855 .noiseFloorThreshCh
= {-1, 0, 0},
1856 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1859 .txFrameToDataStart
= 0x0e,
1860 .txFrameToPaOn
= 0x0e,
1861 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
1863 .switchSettling
= 0x2c,
1864 .adcDesiredSize
= -30,
1867 .txFrameToXpaOn
= 0xe,
1869 .papdRateMaskHt20
= LE32(0x0c80c080),
1870 .papdRateMaskHt40
= LE32(0x0080c080),
1872 .xlna_bias_strength
= 0,
1874 0, 0, 0, 0, 0, 0, 0,
1878 .ant_div_control
= 0,
1880 .tempslopextension
= {0, 0, 0, 0, 0, 0, 0, 0}
1887 /* ar9300_cal_data_per_freq_op_loop 2g */
1889 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1890 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1891 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
1893 .calTarget_freqbin_Cck
= {
1897 .calTarget_freqbin_2G
= {
1902 .calTarget_freqbin_2GHT20
= {
1907 .calTarget_freqbin_2GHT40
= {
1912 .calTargetPowerCck
= {
1913 /* 1L-5L,5S,11L,11s */
1914 { {38, 38, 38, 38} },
1915 { {38, 38, 38, 38} },
1917 .calTargetPower2G
= {
1919 { {38, 38, 36, 34} },
1920 { {38, 38, 36, 34} },
1921 { {38, 38, 34, 32} },
1923 .calTargetPower2GHT20
= {
1924 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1925 { {36, 36, 36, 36, 36, 34, 36, 34, 32, 30, 30, 30, 28, 26} },
1926 { {36, 36, 36, 36, 36, 34, 34, 32, 30, 28, 28, 28, 28, 26} },
1928 .calTargetPower2GHT40
= {
1929 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1930 { {36, 36, 36, 36, 34, 32, 34, 32, 30, 28, 28, 28, 28, 24} },
1931 { {36, 36, 36, 36, 34, 32, 32, 30, 28, 26, 26, 26, 26, 24} },
1934 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
1935 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
1965 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1966 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1967 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1968 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(2484, 1),
1972 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1973 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1974 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1979 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1980 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1986 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
1987 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
1988 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
1989 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
1993 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
1994 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
1995 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
1999 /* Data[9].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2000 /* Data[9].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2001 /* Data[9].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2006 /* Data[10].ctledges[0].bchannel */ FREQ2FBIN(2412, 1),
2007 /* Data[10].ctledges[1].bchannel */ FREQ2FBIN(2417, 1),
2008 /* Data[10].ctledges[2].bchannel */ FREQ2FBIN(2472, 1),
2013 /* Data[11].ctledges[0].bchannel */ FREQ2FBIN(2422, 1),
2014 /* Data[11].ctledges[1].bchannel */ FREQ2FBIN(2427, 1),
2015 /* Data[11].ctledges[2].bchannel */ FREQ2FBIN(2447, 1),
2016 /* Data[11].ctledges[3].bchannel */ FREQ2FBIN(2462, 1),
2019 .ctlPowerData_2G
= {
2020 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2021 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2022 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2024 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2025 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2026 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2028 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2029 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2030 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2032 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2033 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2034 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2037 /* 4 idle,t1,t2,b (4 bits per setting) */
2038 .antCtrlCommon
= LE32(0x110),
2039 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2040 .antCtrlCommon2
= LE32(0x22222),
2041 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2043 LE16(0x0), LE16(0x0), LE16(0x0),
2045 /* xatten1DB 3 xatten1_db for ar9280 (0xa20c/b20c 5:0) */
2046 .xatten1DB
= {0x13, 0x19, 0x17},
2049 * xatten1Margin[ar9300_max_chains]; 3 xatten1_margin
2050 * for merlin (0xa20c/b20c 16:12
2052 .xatten1Margin
= {0x19, 0x19, 0x19},
2055 /* spurChans spur channels in usual fbin coding format */
2056 .spurChans
= {0, 0, 0, 0, 0},
2057 /* noiseFloorThreshch check if the register is per chain */
2058 .noiseFloorThreshCh
= {-1, 0, 0},
2059 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2062 .txFrameToDataStart
= 0x0e,
2063 .txFrameToPaOn
= 0x0e,
2064 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2066 .switchSettling
= 0x2d,
2067 .adcDesiredSize
= -30,
2070 .txFrameToXpaOn
= 0xe,
2072 .papdRateMaskHt20
= LE32(0x0cf0e0e0),
2073 .papdRateMaskHt40
= LE32(0x6cf0e0e0),
2075 .xlna_bias_strength
= 0,
2077 0, 0, 0, 0, 0, 0, 0,
2082 .tempSlopeHigh
= 105,
2083 .xatten1DBLow
= {0x10, 0x14, 0x10},
2084 .xatten1MarginLow
= {0x19, 0x19 , 0x19},
2085 .xatten1DBHigh
= {0x1d, 0x20, 0x24},
2086 .xatten1MarginHigh
= {0x10, 0x10, 0x10}
2131 .calTarget_freqbin_5G
= {
2141 .calTarget_freqbin_5GHT20
= {
2151 .calTarget_freqbin_5GHT40
= {
2161 .calTargetPower5G
= {
2163 { {32, 32, 28, 26} },
2164 { {32, 32, 28, 26} },
2165 { {32, 32, 28, 26} },
2166 { {32, 32, 26, 24} },
2167 { {32, 32, 26, 24} },
2168 { {32, 32, 24, 22} },
2169 { {30, 30, 24, 22} },
2170 { {30, 30, 24, 22} },
2172 .calTargetPower5GHT20
= {
2174 * 0_8_16,1-3_9-11_17-19,
2175 * 4,5,6,7,12,13,14,15,20,21,22,23
2177 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2178 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2179 { {32, 32, 32, 32, 28, 26, 32, 28, 26, 24, 24, 24, 22, 22} },
2180 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 22, 22, 20, 20} },
2181 { {32, 32, 32, 32, 28, 26, 32, 26, 24, 22, 20, 18, 16, 16} },
2182 { {32, 32, 32, 32, 28, 26, 32, 24, 20, 16, 18, 16, 14, 14} },
2183 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2184 { {30, 30, 30, 30, 28, 26, 30, 24, 20, 16, 18, 16, 14, 14} },
2186 .calTargetPower5GHT40
= {
2188 * 0_8_16,1-3_9-11_17-19,
2189 * 4,5,6,7,12,13,14,15,20,21,22,23
2191 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2192 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2193 { {32, 32, 32, 30, 28, 26, 30, 28, 26, 24, 24, 24, 22, 22} },
2194 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 22, 22, 20, 20} },
2195 { {32, 32, 32, 30, 28, 26, 30, 26, 24, 22, 20, 18, 16, 16} },
2196 { {32, 32, 32, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2197 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2198 { {30, 30, 30, 30, 28, 26, 30, 22, 20, 16, 18, 16, 14, 14} },
2201 0x10, 0x16, 0x18, 0x40, 0x46,
2202 0x48, 0x30, 0x36, 0x38
2206 /* Data[0].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2207 /* Data[0].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2208 /* Data[0].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2209 /* Data[0].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2210 /* Data[0].ctledges[4].bchannel */ FREQ2FBIN(5600, 0),
2211 /* Data[0].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2212 /* Data[0].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2213 /* Data[0].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2216 /* Data[1].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2217 /* Data[1].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2218 /* Data[1].ctledges[2].bchannel */ FREQ2FBIN(5280, 0),
2219 /* Data[1].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2220 /* Data[1].ctledges[4].bchannel */ FREQ2FBIN(5520, 0),
2221 /* Data[1].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2222 /* Data[1].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2223 /* Data[1].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2227 /* Data[2].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2228 /* Data[2].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2229 /* Data[2].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2230 /* Data[2].ctledges[3].bchannel */ FREQ2FBIN(5310, 0),
2231 /* Data[2].ctledges[4].bchannel */ FREQ2FBIN(5510, 0),
2232 /* Data[2].ctledges[5].bchannel */ FREQ2FBIN(5550, 0),
2233 /* Data[2].ctledges[6].bchannel */ FREQ2FBIN(5670, 0),
2234 /* Data[2].ctledges[7].bchannel */ FREQ2FBIN(5755, 0)
2238 /* Data[3].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2239 /* Data[3].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2240 /* Data[3].ctledges[2].bchannel */ FREQ2FBIN(5260, 0),
2241 /* Data[3].ctledges[3].bchannel */ FREQ2FBIN(5320, 0),
2242 /* Data[3].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2243 /* Data[3].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2244 /* Data[3].ctledges[6].bchannel */ 0xFF,
2245 /* Data[3].ctledges[7].bchannel */ 0xFF,
2249 /* Data[4].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2250 /* Data[4].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2251 /* Data[4].ctledges[2].bchannel */ FREQ2FBIN(5500, 0),
2252 /* Data[4].ctledges[3].bchannel */ FREQ2FBIN(5700, 0),
2253 /* Data[4].ctledges[4].bchannel */ 0xFF,
2254 /* Data[4].ctledges[5].bchannel */ 0xFF,
2255 /* Data[4].ctledges[6].bchannel */ 0xFF,
2256 /* Data[4].ctledges[7].bchannel */ 0xFF,
2260 /* Data[5].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2261 /* Data[5].ctledges[1].bchannel */ FREQ2FBIN(5270, 0),
2262 /* Data[5].ctledges[2].bchannel */ FREQ2FBIN(5310, 0),
2263 /* Data[5].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2264 /* Data[5].ctledges[4].bchannel */ FREQ2FBIN(5590, 0),
2265 /* Data[5].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2266 /* Data[5].ctledges[6].bchannel */ 0xFF,
2267 /* Data[5].ctledges[7].bchannel */ 0xFF
2271 /* Data[6].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2272 /* Data[6].ctledges[1].bchannel */ FREQ2FBIN(5200, 0),
2273 /* Data[6].ctledges[2].bchannel */ FREQ2FBIN(5220, 0),
2274 /* Data[6].ctledges[3].bchannel */ FREQ2FBIN(5260, 0),
2275 /* Data[6].ctledges[4].bchannel */ FREQ2FBIN(5500, 0),
2276 /* Data[6].ctledges[5].bchannel */ FREQ2FBIN(5600, 0),
2277 /* Data[6].ctledges[6].bchannel */ FREQ2FBIN(5700, 0),
2278 /* Data[6].ctledges[7].bchannel */ FREQ2FBIN(5745, 0)
2282 /* Data[7].ctledges[0].bchannel */ FREQ2FBIN(5180, 0),
2283 /* Data[7].ctledges[1].bchannel */ FREQ2FBIN(5260, 0),
2284 /* Data[7].ctledges[2].bchannel */ FREQ2FBIN(5320, 0),
2285 /* Data[7].ctledges[3].bchannel */ FREQ2FBIN(5500, 0),
2286 /* Data[7].ctledges[4].bchannel */ FREQ2FBIN(5560, 0),
2287 /* Data[7].ctledges[5].bchannel */ FREQ2FBIN(5700, 0),
2288 /* Data[7].ctledges[6].bchannel */ FREQ2FBIN(5745, 0),
2289 /* Data[7].ctledges[7].bchannel */ FREQ2FBIN(5825, 0)
2293 /* Data[8].ctledges[0].bchannel */ FREQ2FBIN(5190, 0),
2294 /* Data[8].ctledges[1].bchannel */ FREQ2FBIN(5230, 0),
2295 /* Data[8].ctledges[2].bchannel */ FREQ2FBIN(5270, 0),
2296 /* Data[8].ctledges[3].bchannel */ FREQ2FBIN(5510, 0),
2297 /* Data[8].ctledges[4].bchannel */ FREQ2FBIN(5550, 0),
2298 /* Data[8].ctledges[5].bchannel */ FREQ2FBIN(5670, 0),
2299 /* Data[8].ctledges[6].bchannel */ FREQ2FBIN(5755, 0),
2300 /* Data[8].ctledges[7].bchannel */ FREQ2FBIN(5795, 0)
2303 .ctlPowerData_5G
= {
2306 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2307 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2312 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2313 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2318 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2319 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2324 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2325 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2330 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2331 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2336 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2337 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2342 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2343 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2348 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2349 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2354 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2355 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2361 static const struct ar9300_eeprom ar9300_h116
= {
2363 .templateVersion
= 4,
2364 .macAddr
= {0x00, 0x03, 0x7f, 0x0, 0x0, 0x0},
2365 .custData
= {"h116-041-f0000"},
2367 .regDmn
= { LE16(0), LE16(0x1f) },
2368 .txrxMask
= 0x33, /* 4 bits tx and 4 bits rx */
2370 .opFlags
= AR5416_OPFLAGS_11G
| AR5416_OPFLAGS_11A
,
2371 .eepMisc
= AR9300_EEPMISC_LITTLE_ENDIAN
,
2374 .blueToothOptions
= 0,
2376 .deviceType
= 5, /* takes lower byte in eeprom location */
2377 .pwrTableOffset
= AR9300_PWR_TABLE_OFFSET
,
2378 .params_for_tuning_caps
= {0, 0},
2379 .featureEnable
= 0x0d,
2381 * bit0 - enable tx temp comp - disabled
2382 * bit1 - enable tx volt comp - disabled
2383 * bit2 - enable fastClock - enabled
2384 * bit3 - enable doubling - enabled
2385 * bit4 - enable internal regulator - disabled
2386 * bit5 - enable pa predistortion - disabled
2388 .miscConfiguration
= 0, /* bit0 - turn down drivestrength */
2389 .eepromWriteEnableGpio
= 6,
2390 .wlanDisableGpio
= 0,
2392 .rxBandSelectGpio
= 0xff,
2397 /* ar9300_modal_eep_header 2g */
2398 /* 4 idle,t1,t2,b(4 bits per setting) */
2399 .antCtrlCommon
= LE32(0x110),
2400 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
2401 .antCtrlCommon2
= LE32(0x44444),
2404 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
2405 * rx1, rx12, b (2 bits each)
2407 .antCtrlChain
= { LE16(0x10), LE16(0x10), LE16(0x10) },
2410 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
2411 * for ar9280 (0xa20c/b20c 5:0)
2413 .xatten1DB
= {0x1f, 0x1f, 0x1f},
2416 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2417 * for ar9280 (0xa20c/b20c 16:12
2419 .xatten1Margin
= {0x12, 0x12, 0x12},
2424 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
2425 * channels in usual fbin coding format
2427 .spurChans
= {FREQ2FBIN(2464, 1), 0, 0, 0, 0},
2430 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
2431 * if the register is per chain
2433 .noiseFloorThreshCh
= {-1, 0, 0},
2434 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2437 .txFrameToDataStart
= 0x0e,
2438 .txFrameToPaOn
= 0x0e,
2439 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2441 .switchSettling
= 0x2c,
2442 .adcDesiredSize
= -30,
2445 .txFrameToXpaOn
= 0xe,
2447 .papdRateMaskHt20
= LE32(0x0c80C080),
2448 .papdRateMaskHt40
= LE32(0x0080C080),
2450 .xlna_bias_strength
= 0,
2452 0, 0, 0, 0, 0, 0, 0,
2456 .ant_div_control
= 0,
2458 .tempslopextension
= {0, 0, 0, 0, 0, 0, 0, 0}
2465 /* ar9300_cal_data_per_freq_op_loop 2g */
2467 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2468 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2469 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
2471 .calTarget_freqbin_Cck
= {
2475 .calTarget_freqbin_2G
= {
2480 .calTarget_freqbin_2GHT20
= {
2485 .calTarget_freqbin_2GHT40
= {
2490 .calTargetPowerCck
= {
2491 /* 1L-5L,5S,11L,11S */
2492 { {34, 34, 34, 34} },
2493 { {34, 34, 34, 34} },
2495 .calTargetPower2G
= {
2497 { {34, 34, 32, 32} },
2498 { {34, 34, 32, 32} },
2499 { {34, 34, 32, 32} },
2501 .calTargetPower2GHT20
= {
2502 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2503 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2504 { {32, 32, 32, 32, 32, 30, 32, 32, 30, 28, 0, 0, 0, 0} },
2506 .calTargetPower2GHT40
= {
2507 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2508 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2509 { {30, 30, 30, 30, 30, 28, 30, 30, 28, 26, 0, 0, 0, 0} },
2512 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
2513 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
2543 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2544 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2545 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2546 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
2550 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2551 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2552 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2557 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2558 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2564 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2565 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2566 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2567 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2571 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2572 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2573 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2577 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2578 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2579 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2584 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
2585 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
2586 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
2591 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
2592 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
2593 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
2594 /* Data[11].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
2597 .ctlPowerData_2G
= {
2598 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2599 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2600 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
2602 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } },
2603 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2604 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2606 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
2607 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2608 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2610 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
2611 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2612 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
2615 /* 4 idle,t1,t2,b (4 bits per setting) */
2616 .antCtrlCommon
= LE32(0x220),
2617 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
2618 .antCtrlCommon2
= LE32(0x44444),
2619 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
2621 LE16(0x150), LE16(0x150), LE16(0x150),
2623 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
2624 .xatten1DB
= {0x19, 0x19, 0x19},
2627 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
2628 * for merlin (0xa20c/b20c 16:12
2630 .xatten1Margin
= {0x14, 0x14, 0x14},
2633 /* spurChans spur channels in usual fbin coding format */
2634 .spurChans
= {0, 0, 0, 0, 0},
2635 /* noiseFloorThreshCh Check if the register is per chain */
2636 .noiseFloorThreshCh
= {-1, 0, 0},
2637 .reserved
= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2640 .txFrameToDataStart
= 0x0e,
2641 .txFrameToPaOn
= 0x0e,
2642 .txClip
= 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
2644 .switchSettling
= 0x2d,
2645 .adcDesiredSize
= -30,
2648 .txFrameToXpaOn
= 0xe,
2650 .papdRateMaskHt20
= LE32(0x0cf0e0e0),
2651 .papdRateMaskHt40
= LE32(0x6cf0e0e0),
2653 .xlna_bias_strength
= 0,
2655 0, 0, 0, 0, 0, 0, 0,
2660 .tempSlopeHigh
= 50,
2661 .xatten1DBLow
= {0, 0, 0},
2662 .xatten1MarginLow
= {0, 0, 0},
2663 .xatten1DBHigh
= {0, 0, 0},
2664 .xatten1MarginHigh
= {0, 0, 0}
2709 .calTarget_freqbin_5G
= {
2719 .calTarget_freqbin_5GHT20
= {
2729 .calTarget_freqbin_5GHT40
= {
2739 .calTargetPower5G
= {
2741 { {30, 30, 28, 24} },
2742 { {30, 30, 28, 24} },
2743 { {30, 30, 28, 24} },
2744 { {30, 30, 28, 24} },
2745 { {30, 30, 28, 24} },
2746 { {30, 30, 28, 24} },
2747 { {30, 30, 28, 24} },
2748 { {30, 30, 28, 24} },
2750 .calTargetPower5GHT20
= {
2752 * 0_8_16,1-3_9-11_17-19,
2753 * 4,5,6,7,12,13,14,15,20,21,22,23
2755 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2756 { {30, 30, 30, 28, 24, 20, 30, 28, 24, 20, 0, 0, 0, 0} },
2757 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2758 { {30, 30, 30, 26, 22, 18, 30, 26, 22, 18, 0, 0, 0, 0} },
2759 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2760 { {30, 30, 30, 24, 20, 16, 30, 24, 20, 16, 0, 0, 0, 0} },
2761 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2762 { {30, 30, 30, 22, 18, 14, 30, 22, 18, 14, 0, 0, 0, 0} },
2764 .calTargetPower5GHT40
= {
2766 * 0_8_16,1-3_9-11_17-19,
2767 * 4,5,6,7,12,13,14,15,20,21,22,23
2769 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2770 { {28, 28, 28, 26, 22, 18, 28, 26, 22, 18, 0, 0, 0, 0} },
2771 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2772 { {28, 28, 28, 24, 20, 16, 28, 24, 20, 16, 0, 0, 0, 0} },
2773 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2774 { {28, 28, 28, 22, 18, 14, 28, 22, 18, 14, 0, 0, 0, 0} },
2775 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2776 { {28, 28, 28, 20, 16, 12, 28, 20, 16, 12, 0, 0, 0, 0} },
2779 0x10, 0x16, 0x18, 0x40, 0x46,
2780 0x48, 0x30, 0x36, 0x38
2784 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2785 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2786 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2787 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2788 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
2789 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2790 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2791 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2794 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2795 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2796 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
2797 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2798 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
2799 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2800 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2801 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2805 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2806 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2807 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2808 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
2809 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
2810 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
2811 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
2812 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
2816 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2817 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2818 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
2819 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
2820 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2821 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2822 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
2823 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
2827 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2828 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2829 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
2830 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
2831 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
2832 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
2833 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
2834 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
2838 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2839 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
2840 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
2841 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2842 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
2843 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2844 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
2845 /* Data[5].ctlEdges[7].bChannel */ 0xFF
2849 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2850 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
2851 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
2852 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
2853 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
2854 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
2855 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
2856 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
2860 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
2861 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
2862 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
2863 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
2864 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
2865 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
2866 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
2867 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
2871 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
2872 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
2873 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
2874 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
2875 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
2876 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
2877 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
2878 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
2881 .ctlPowerData_5G
= {
2884 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2885 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2890 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2891 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2896 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2897 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2902 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2903 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2908 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2909 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2914 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2915 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
2920 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2921 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
2926 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2927 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
2932 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
2933 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
2940 static const struct ar9300_eeprom
*ar9300_eep_templates
[] = {
2948 static const struct ar9300_eeprom
*ar9003_eeprom_struct_find_by_id(int id
)
2952 for (it
= 0; it
< ARRAY_SIZE(ar9300_eep_templates
); it
++)
2953 if (ar9300_eep_templates
[it
]->templateVersion
== id
)
2954 return ar9300_eep_templates
[it
];
2958 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw
*ah
)
2963 static int interpolate(int x
, int xa
, int xb
, int ya
, int yb
)
2965 int bf
, factor
, plus
;
2967 bf
= 2 * (yb
- ya
) * (x
- xa
) / (xb
- xa
);
2970 return ya
+ factor
+ plus
;
2973 static u32
ath9k_hw_ar9300_get_eeprom(struct ath_hw
*ah
,
2974 enum eeprom_param param
)
2976 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
2977 struct ar9300_base_eep_hdr
*pBase
= &eep
->baseEepHeader
;
2981 return get_unaligned_be16(eep
->macAddr
);
2983 return get_unaligned_be16(eep
->macAddr
+ 2);
2985 return get_unaligned_be16(eep
->macAddr
+ 4);
2987 return le16_to_cpu(pBase
->regDmn
[0]);
2989 return pBase
->deviceCap
;
2991 return pBase
->opCapFlags
.opFlags
;
2993 return pBase
->rfSilent
;
2995 return (pBase
->txrxMask
>> 4) & 0xf;
2997 return pBase
->txrxMask
& 0xf;
2999 return !!(pBase
->featureEnable
& BIT(5));
3000 case EEP_CHAIN_MASK_REDUCE
:
3001 return (pBase
->miscConfiguration
>> 0x3) & 0x1;
3002 case EEP_ANT_DIV_CTL1
:
3003 if (AR_SREV_9565(ah
))
3004 return AR9300_EEP_ANTDIV_CONTROL_DEFAULT_VALUE
;
3006 return eep
->base_ext1
.ant_div_control
;
3007 case EEP_ANTENNA_GAIN_5G
:
3008 return eep
->modalHeader5G
.antennaGain
;
3009 case EEP_ANTENNA_GAIN_2G
:
3010 return eep
->modalHeader2G
.antennaGain
;
3016 static bool ar9300_eeprom_read_byte(struct ath_hw
*ah
, int address
,
3021 if (unlikely(!ath9k_hw_nvram_read(ah
, address
/ 2, &val
)))
3024 *buffer
= (val
>> (8 * (address
% 2))) & 0xff;
3028 static bool ar9300_eeprom_read_word(struct ath_hw
*ah
, int address
,
3033 if (unlikely(!ath9k_hw_nvram_read(ah
, address
/ 2, &val
)))
3036 buffer
[0] = val
>> 8;
3037 buffer
[1] = val
& 0xff;
3042 static bool ar9300_read_eeprom(struct ath_hw
*ah
, int address
, u8
*buffer
,
3045 struct ath_common
*common
= ath9k_hw_common(ah
);
3048 if ((address
< 0) || ((address
+ count
) / 2 > AR9300_EEPROM_SIZE
- 1)) {
3049 ath_dbg(common
, EEPROM
, "eeprom address not in range\n");
3054 * Since we're reading the bytes in reverse order from a little-endian
3055 * word stream, an even address means we only use the lower half of
3056 * the 16-bit word at that address
3058 if (address
% 2 == 0) {
3059 if (!ar9300_eeprom_read_byte(ah
, address
--, buffer
++))
3065 for (i
= 0; i
< count
/ 2; i
++) {
3066 if (!ar9300_eeprom_read_word(ah
, address
, buffer
))
3074 if (!ar9300_eeprom_read_byte(ah
, address
, buffer
))
3080 ath_dbg(common
, EEPROM
, "unable to read eeprom region at offset %d\n",
3085 static bool ar9300_otp_read_word(struct ath_hw
*ah
, int addr
, u32
*data
)
3087 REG_READ(ah
, AR9300_OTP_BASE(ah
) + (4 * addr
));
3089 if (!ath9k_hw_wait(ah
, AR9300_OTP_STATUS(ah
), AR9300_OTP_STATUS_TYPE
,
3090 AR9300_OTP_STATUS_VALID
, 1000))
3093 *data
= REG_READ(ah
, AR9300_OTP_READ_DATA(ah
));
3097 static bool ar9300_read_otp(struct ath_hw
*ah
, int address
, u8
*buffer
,
3103 for (i
= 0; i
< count
; i
++) {
3104 int offset
= 8 * ((address
- i
) % 4);
3105 if (!ar9300_otp_read_word(ah
, (address
- i
) / 4, &data
))
3108 buffer
[i
] = (data
>> offset
) & 0xff;
3115 static void ar9300_comp_hdr_unpack(u8
*best
, int *code
, int *reference
,
3116 int *length
, int *major
, int *minor
)
3118 unsigned long value
[4];
3124 *code
= ((value
[0] >> 5) & 0x0007);
3125 *reference
= (value
[0] & 0x001f) | ((value
[1] >> 2) & 0x0020);
3126 *length
= ((value
[1] << 4) & 0x07f0) | ((value
[2] >> 4) & 0x000f);
3127 *major
= (value
[2] & 0x000f);
3128 *minor
= (value
[3] & 0x00ff);
3131 static u16
ar9300_comp_cksum(u8
*data
, int dsize
)
3133 int it
, checksum
= 0;
3135 for (it
= 0; it
< dsize
; it
++) {
3136 checksum
+= data
[it
];
3143 static bool ar9300_uncompress_block(struct ath_hw
*ah
,
3153 struct ath_common
*common
= ath9k_hw_common(ah
);
3157 for (it
= 0; it
< size
; it
+= (length
+2)) {
3161 length
= block
[it
+1];
3164 if (length
> 0 && spot
>= 0 && spot
+length
<= mdataSize
) {
3165 ath_dbg(common
, EEPROM
,
3166 "Restore at %d: spot=%d offset=%d length=%d\n",
3167 it
, spot
, offset
, length
);
3168 memcpy(&mptr
[spot
], &block
[it
+2], length
);
3170 } else if (length
> 0) {
3171 ath_dbg(common
, EEPROM
,
3172 "Bad restore at %d: spot=%d offset=%d length=%d\n",
3173 it
, spot
, offset
, length
);
3180 static int ar9300_compress_decision(struct ath_hw
*ah
,
3185 u8
*word
, int length
, int mdata_size
)
3187 struct ath_common
*common
= ath9k_hw_common(ah
);
3188 const struct ar9300_eeprom
*eep
= NULL
;
3192 if (length
!= mdata_size
) {
3193 ath_dbg(common
, EEPROM
,
3194 "EEPROM structure size mismatch memory=%d eeprom=%d\n",
3195 mdata_size
, length
);
3198 memcpy(mptr
, word
+ COMP_HDR_LEN
, length
);
3199 ath_dbg(common
, EEPROM
,
3200 "restored eeprom %d: uncompressed, length %d\n",
3203 case _CompressBlock
:
3204 if (reference
!= 0) {
3205 eep
= ar9003_eeprom_struct_find_by_id(reference
);
3207 ath_dbg(common
, EEPROM
,
3208 "can't find reference eeprom struct %d\n",
3212 memcpy(mptr
, eep
, mdata_size
);
3214 ath_dbg(common
, EEPROM
,
3215 "restore eeprom %d: block, reference %d, length %d\n",
3216 it
, reference
, length
);
3217 ar9300_uncompress_block(ah
, mptr
, mdata_size
,
3218 (word
+ COMP_HDR_LEN
), length
);
3221 ath_dbg(common
, EEPROM
, "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 u16
*data
= (u16
*) mptr
;
3253 for (i
= 0; i
< mdata_size
/ 2; i
++, data
++)
3254 if (!ath9k_hw_nvram_read(ah
, i
, data
))
3260 * Read the configuration data from the eeprom.
3261 * The data can be put in any specified memory buffer.
3263 * Returns -1 on error.
3264 * Returns address of next memory location on success.
3266 static int ar9300_eeprom_restore_internal(struct ath_hw
*ah
,
3267 u8
*mptr
, int mdata_size
)
3274 int reference
, length
, major
, minor
;
3277 u16 checksum
, mchecksum
;
3278 struct ath_common
*common
= ath9k_hw_common(ah
);
3279 struct ar9300_eeprom
*eep
;
3280 eeprom_read_op read
;
3282 if (ath9k_hw_use_flash(ah
)) {
3285 if (ar9300_eeprom_restore_flash(ah
, mptr
, mdata_size
))
3288 /* check if eeprom contains valid data */
3289 eep
= (struct ar9300_eeprom
*) mptr
;
3290 txrx
= eep
->baseEepHeader
.txrxMask
;
3291 if (txrx
!= 0 && txrx
!= 0xff)
3295 word
= kzalloc(2048, GFP_KERNEL
);
3299 memcpy(mptr
, &ar9300_default
, mdata_size
);
3301 read
= ar9300_read_eeprom
;
3302 if (AR_SREV_9485(ah
))
3303 cptr
= AR9300_BASE_ADDR_4K
;
3304 else if (AR_SREV_9330(ah
))
3305 cptr
= AR9300_BASE_ADDR_512
;
3307 cptr
= AR9300_BASE_ADDR
;
3308 ath_dbg(common
, EEPROM
, "Trying EEPROM access at Address 0x%04x\n",
3310 if (ar9300_check_eeprom_header(ah
, read
, cptr
))
3313 cptr
= AR9300_BASE_ADDR_4K
;
3314 ath_dbg(common
, EEPROM
, "Trying EEPROM access at Address 0x%04x\n",
3316 if (ar9300_check_eeprom_header(ah
, read
, cptr
))
3319 cptr
= AR9300_BASE_ADDR_512
;
3320 ath_dbg(common
, EEPROM
, "Trying EEPROM access at Address 0x%04x\n",
3322 if (ar9300_check_eeprom_header(ah
, read
, cptr
))
3325 read
= ar9300_read_otp
;
3326 cptr
= AR9300_BASE_ADDR
;
3327 ath_dbg(common
, EEPROM
, "Trying OTP access at Address 0x%04x\n", cptr
);
3328 if (ar9300_check_eeprom_header(ah
, read
, cptr
))
3331 cptr
= AR9300_BASE_ADDR_512
;
3332 ath_dbg(common
, EEPROM
, "Trying OTP access at Address 0x%04x\n", cptr
);
3333 if (ar9300_check_eeprom_header(ah
, read
, cptr
))
3339 ath_dbg(common
, EEPROM
, "Found valid EEPROM data\n");
3341 for (it
= 0; it
< MSTATE
; it
++) {
3342 if (!read(ah
, cptr
, word
, COMP_HDR_LEN
))
3345 if (!ar9300_check_header(word
))
3348 ar9300_comp_hdr_unpack(word
, &code
, &reference
,
3349 &length
, &major
, &minor
);
3350 ath_dbg(common
, EEPROM
,
3351 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3352 cptr
, code
, reference
, length
, major
, minor
);
3353 if ((!AR_SREV_9485(ah
) && length
>= 1024) ||
3354 (AR_SREV_9485(ah
) && length
> EEPROM_DATA_LEN_9485
) ||
3356 ath_dbg(common
, EEPROM
, "Skipping bad header\n");
3357 cptr
-= COMP_HDR_LEN
;
3362 read(ah
, cptr
, word
, COMP_HDR_LEN
+ osize
+ COMP_CKSUM_LEN
);
3363 checksum
= ar9300_comp_cksum(&word
[COMP_HDR_LEN
], length
);
3364 mchecksum
= get_unaligned_le16(&word
[COMP_HDR_LEN
+ osize
]);
3365 ath_dbg(common
, EEPROM
, "checksum %x %x\n",
3366 checksum
, mchecksum
);
3367 if (checksum
== mchecksum
) {
3368 ar9300_compress_decision(ah
, it
, code
, reference
, mptr
,
3369 word
, length
, mdata_size
);
3371 ath_dbg(common
, EEPROM
,
3372 "skipping block with bad checksum\n");
3374 cptr
-= (COMP_HDR_LEN
+ osize
+ COMP_CKSUM_LEN
);
3386 * Restore the configuration structure by reading the eeprom.
3387 * This function destroys any existing in-memory structure
3390 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw
*ah
)
3392 u8
*mptr
= (u8
*) &ah
->eeprom
.ar9300_eep
;
3394 if (ar9300_eeprom_restore_internal(ah
, mptr
,
3395 sizeof(struct ar9300_eeprom
)) < 0)
3401 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
3402 static u32
ar9003_dump_modal_eeprom(char *buf
, u32 len
, u32 size
,
3403 struct ar9300_modal_eep_header
*modal_hdr
)
3405 PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr
->antCtrlChain
[0]));
3406 PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr
->antCtrlChain
[1]));
3407 PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr
->antCtrlChain
[2]));
3408 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr
->antCtrlCommon
));
3409 PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr
->antCtrlCommon2
));
3410 PR_EEP("Ant. Gain", modal_hdr
->antennaGain
);
3411 PR_EEP("Switch Settle", modal_hdr
->switchSettling
);
3412 PR_EEP("Chain0 xatten1DB", modal_hdr
->xatten1DB
[0]);
3413 PR_EEP("Chain1 xatten1DB", modal_hdr
->xatten1DB
[1]);
3414 PR_EEP("Chain2 xatten1DB", modal_hdr
->xatten1DB
[2]);
3415 PR_EEP("Chain0 xatten1Margin", modal_hdr
->xatten1Margin
[0]);
3416 PR_EEP("Chain1 xatten1Margin", modal_hdr
->xatten1Margin
[1]);
3417 PR_EEP("Chain2 xatten1Margin", modal_hdr
->xatten1Margin
[2]);
3418 PR_EEP("Temp Slope", modal_hdr
->tempSlope
);
3419 PR_EEP("Volt Slope", modal_hdr
->voltSlope
);
3420 PR_EEP("spur Channels0", modal_hdr
->spurChans
[0]);
3421 PR_EEP("spur Channels1", modal_hdr
->spurChans
[1]);
3422 PR_EEP("spur Channels2", modal_hdr
->spurChans
[2]);
3423 PR_EEP("spur Channels3", modal_hdr
->spurChans
[3]);
3424 PR_EEP("spur Channels4", modal_hdr
->spurChans
[4]);
3425 PR_EEP("Chain0 NF Threshold", modal_hdr
->noiseFloorThreshCh
[0]);
3426 PR_EEP("Chain1 NF Threshold", modal_hdr
->noiseFloorThreshCh
[1]);
3427 PR_EEP("Chain2 NF Threshold", modal_hdr
->noiseFloorThreshCh
[2]);
3428 PR_EEP("Quick Drop", modal_hdr
->quick_drop
);
3429 PR_EEP("txEndToXpaOff", modal_hdr
->txEndToXpaOff
);
3430 PR_EEP("xPA Bias Level", modal_hdr
->xpaBiasLvl
);
3431 PR_EEP("txFrameToDataStart", modal_hdr
->txFrameToDataStart
);
3432 PR_EEP("txFrameToPaOn", modal_hdr
->txFrameToPaOn
);
3433 PR_EEP("txFrameToXpaOn", modal_hdr
->txFrameToXpaOn
);
3434 PR_EEP("txClip", modal_hdr
->txClip
);
3435 PR_EEP("ADC Desired size", modal_hdr
->adcDesiredSize
);
3440 static u32
ar9003_dump_cal_data(struct ath_hw
*ah
, char *buf
, u32 len
, u32 size
,
3443 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
3444 struct ar9300_base_eep_hdr
*pBase
;
3445 struct ar9300_cal_data_per_freq_op_loop
*cal_pier
;
3450 pBase
= &eep
->baseEepHeader
;
3453 cal_pier_nr
= AR9300_NUM_2G_CAL_PIERS
;
3455 cal_pier_nr
= AR9300_NUM_5G_CAL_PIERS
;
3457 for (i
= 0; i
< AR9300_MAX_CHAINS
; i
++) {
3458 if (!((pBase
->txrxMask
>> i
) & 1))
3461 len
+= scnprintf(buf
+ len
, size
- len
, "Chain %d\n", i
);
3463 len
+= scnprintf(buf
+ len
, size
- len
,
3464 "Freq\t ref\tvolt\ttemp\tnf_cal\tnf_pow\trx_temp\n");
3466 for (j
= 0; j
< cal_pier_nr
; j
++) {
3468 cal_pier
= &eep
->calPierData2G
[i
][j
];
3469 freq
= 2300 + eep
->calFreqPier2G
[j
];
3471 cal_pier
= &eep
->calPierData5G
[i
][j
];
3472 freq
= 4800 + eep
->calFreqPier5G
[j
] * 5;
3475 len
+= scnprintf(buf
+ len
, size
- len
,
3478 len
+= scnprintf(buf
+ len
, size
- len
,
3479 "%d\t%d\t%d\t%d\t%d\t%d\n",
3483 cal_pier
->rxTempMeas
?
3484 N2DBM(cal_pier
->rxNoisefloorCal
) : 0,
3485 cal_pier
->rxTempMeas
?
3486 N2DBM(cal_pier
->rxNoisefloorPower
) : 0,
3487 cal_pier
->rxTempMeas
);
3494 static u32
ath9k_hw_ar9003_dump_eeprom(struct ath_hw
*ah
, bool dump_base_hdr
,
3495 u8
*buf
, u32 len
, u32 size
)
3497 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
3498 struct ar9300_base_eep_hdr
*pBase
;
3500 if (!dump_base_hdr
) {
3501 len
+= scnprintf(buf
+ len
, size
- len
,
3502 "%20s :\n", "2GHz modal Header");
3503 len
= ar9003_dump_modal_eeprom(buf
, len
, size
,
3504 &eep
->modalHeader2G
);
3506 len
+= scnprintf(buf
+ len
, size
- len
, "Calibration data\n");
3507 len
= ar9003_dump_cal_data(ah
, buf
, len
, size
, true);
3509 len
+= scnprintf(buf
+ len
, size
- len
,
3510 "%20s :\n", "5GHz modal Header");
3511 len
= ar9003_dump_modal_eeprom(buf
, len
, size
,
3512 &eep
->modalHeader5G
);
3514 len
+= scnprintf(buf
+ len
, size
- len
, "Calibration data\n");
3515 len
= ar9003_dump_cal_data(ah
, buf
, len
, size
, false);
3520 pBase
= &eep
->baseEepHeader
;
3522 PR_EEP("EEPROM Version", ah
->eeprom
.ar9300_eep
.eepromVersion
);
3523 PR_EEP("RegDomain1", le16_to_cpu(pBase
->regDmn
[0]));
3524 PR_EEP("RegDomain2", le16_to_cpu(pBase
->regDmn
[1]));
3525 PR_EEP("TX Mask", (pBase
->txrxMask
>> 4));
3526 PR_EEP("RX Mask", (pBase
->txrxMask
& 0x0f));
3527 PR_EEP("Allow 5GHz", !!(pBase
->opCapFlags
.opFlags
&
3528 AR5416_OPFLAGS_11A
));
3529 PR_EEP("Allow 2GHz", !!(pBase
->opCapFlags
.opFlags
&
3530 AR5416_OPFLAGS_11G
));
3531 PR_EEP("Disable 2GHz HT20", !!(pBase
->opCapFlags
.opFlags
&
3532 AR5416_OPFLAGS_N_2G_HT20
));
3533 PR_EEP("Disable 2GHz HT40", !!(pBase
->opCapFlags
.opFlags
&
3534 AR5416_OPFLAGS_N_2G_HT40
));
3535 PR_EEP("Disable 5Ghz HT20", !!(pBase
->opCapFlags
.opFlags
&
3536 AR5416_OPFLAGS_N_5G_HT20
));
3537 PR_EEP("Disable 5Ghz HT40", !!(pBase
->opCapFlags
.opFlags
&
3538 AR5416_OPFLAGS_N_5G_HT40
));
3539 PR_EEP("Big Endian", !!(pBase
->opCapFlags
.eepMisc
&
3540 AR5416_EEPMISC_BIG_ENDIAN
));
3541 PR_EEP("RF Silent", pBase
->rfSilent
);
3542 PR_EEP("BT option", pBase
->blueToothOptions
);
3543 PR_EEP("Device Cap", pBase
->deviceCap
);
3544 PR_EEP("Device Type", pBase
->deviceType
);
3545 PR_EEP("Power Table Offset", pBase
->pwrTableOffset
);
3546 PR_EEP("Tuning Caps1", pBase
->params_for_tuning_caps
[0]);
3547 PR_EEP("Tuning Caps2", pBase
->params_for_tuning_caps
[1]);
3548 PR_EEP("Enable Tx Temp Comp", !!(pBase
->featureEnable
& BIT(0)));
3549 PR_EEP("Enable Tx Volt Comp", !!(pBase
->featureEnable
& BIT(1)));
3550 PR_EEP("Enable fast clock", !!(pBase
->featureEnable
& BIT(2)));
3551 PR_EEP("Enable doubling", !!(pBase
->featureEnable
& BIT(3)));
3552 PR_EEP("Internal regulator", !!(pBase
->featureEnable
& BIT(4)));
3553 PR_EEP("Enable Paprd", !!(pBase
->featureEnable
& BIT(5)));
3554 PR_EEP("Driver Strength", !!(pBase
->miscConfiguration
& BIT(0)));
3555 PR_EEP("Quick Drop", !!(pBase
->miscConfiguration
& BIT(1)));
3556 PR_EEP("Chain mask Reduce", (pBase
->miscConfiguration
>> 0x3) & 0x1);
3557 PR_EEP("Write enable Gpio", pBase
->eepromWriteEnableGpio
);
3558 PR_EEP("WLAN Disable Gpio", pBase
->wlanDisableGpio
);
3559 PR_EEP("WLAN LED Gpio", pBase
->wlanLedGpio
);
3560 PR_EEP("Rx Band Select Gpio", pBase
->rxBandSelectGpio
);
3561 PR_EEP("Tx Gain", pBase
->txrxgain
>> 4);
3562 PR_EEP("Rx Gain", pBase
->txrxgain
& 0xf);
3563 PR_EEP("SW Reg", le32_to_cpu(pBase
->swreg
));
3565 len
+= scnprintf(buf
+ len
, size
- len
, "%20s : %pM\n", "MacAddress",
3566 ah
->eeprom
.ar9300_eep
.macAddr
);
3574 static u32
ath9k_hw_ar9003_dump_eeprom(struct ath_hw
*ah
, bool dump_base_hdr
,
3575 u8
*buf
, u32 len
, u32 size
)
3581 /* XXX: review hardware docs */
3582 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw
*ah
)
3584 return ah
->eeprom
.ar9300_eep
.eepromVersion
;
3587 /* XXX: could be read from the eepromVersion, not sure yet */
3588 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw
*ah
)
3593 static struct ar9300_modal_eep_header
*ar9003_modal_header(struct ath_hw
*ah
,
3596 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
3599 return &eep
->modalHeader2G
;
3601 return &eep
->modalHeader5G
;
3604 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw
*ah
, bool is2ghz
)
3606 int bias
= ar9003_modal_header(ah
, is2ghz
)->xpaBiasLvl
;
3608 if (AR_SREV_9485(ah
) || AR_SREV_9330(ah
) || AR_SREV_9340(ah
) ||
3609 AR_SREV_9531(ah
) || AR_SREV_9561(ah
))
3610 REG_RMW_FIELD(ah
, AR_CH0_TOP2(ah
), AR_CH0_TOP2_XPABIASLVL
, bias
);
3611 else if (AR_SREV_9462(ah
) || AR_SREV_9550(ah
) || AR_SREV_9565(ah
))
3612 REG_RMW_FIELD(ah
, AR_CH0_TOP(ah
), AR_CH0_TOP_XPABIASLVL
, bias
);
3614 REG_RMW_FIELD(ah
, AR_CH0_TOP(ah
), AR_CH0_TOP_XPABIASLVL
, bias
);
3615 REG_RMW_FIELD(ah
, AR_CH0_THERM(ah
),
3616 AR_CH0_THERM_XPABIASLVL_MSB
,
3618 REG_RMW_FIELD(ah
, AR_CH0_THERM(ah
),
3619 AR_CH0_THERM_XPASHORT2GND
, 1);
3623 static u16
ar9003_switch_com_spdt_get(struct ath_hw
*ah
, bool is2ghz
)
3625 return le16_to_cpu(ar9003_modal_header(ah
, is2ghz
)->switchcomspdt
);
3628 u32
ar9003_hw_ant_ctrl_common_get(struct ath_hw
*ah
, bool is2ghz
)
3630 return le32_to_cpu(ar9003_modal_header(ah
, is2ghz
)->antCtrlCommon
);
3633 u32
ar9003_hw_ant_ctrl_common_2_get(struct ath_hw
*ah
, bool is2ghz
)
3635 return le32_to_cpu(ar9003_modal_header(ah
, is2ghz
)->antCtrlCommon2
);
3638 static u16
ar9003_hw_ant_ctrl_chain_get(struct ath_hw
*ah
, int chain
,
3641 __le16 val
= ar9003_modal_header(ah
, is2ghz
)->antCtrlChain
[chain
];
3642 return le16_to_cpu(val
);
3645 static void ar9003_hw_ant_ctrl_apply(struct ath_hw
*ah
, bool is2ghz
)
3647 struct ath_common
*common
= ath9k_hw_common(ah
);
3648 struct ath9k_hw_capabilities
*pCap
= &ah
->caps
;
3650 u32 regval
, value
, gpio
;
3651 static const u32 switch_chain_reg
[AR9300_MAX_CHAINS
] = {
3652 AR_PHY_SWITCH_CHAIN_0
,
3653 AR_PHY_SWITCH_CHAIN_1
,
3654 AR_PHY_SWITCH_CHAIN_2
,
3657 if (AR_SREV_9485(ah
) && (ar9003_hw_get_rx_gain_idx(ah
) == 0)) {
3658 if (ah
->config
.xlna_gpio
)
3659 gpio
= ah
->config
.xlna_gpio
;
3661 gpio
= AR9300_EXT_LNA_CTL_GPIO_AR9485
;
3663 ath9k_hw_gpio_request_out(ah
, gpio
, NULL
,
3664 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED
);
3667 value
= ar9003_hw_ant_ctrl_common_get(ah
, is2ghz
);
3669 if (AR_SREV_9462(ah
) || AR_SREV_9565(ah
)) {
3670 REG_RMW_FIELD(ah
, AR_PHY_SWITCH_COM
,
3671 AR_SWITCH_TABLE_COM_AR9462_ALL
, value
);
3672 } else if (AR_SREV_9550(ah
) || AR_SREV_9531(ah
) || AR_SREV_9561(ah
)) {
3673 REG_RMW_FIELD(ah
, AR_PHY_SWITCH_COM
,
3674 AR_SWITCH_TABLE_COM_AR9550_ALL
, value
);
3676 REG_RMW_FIELD(ah
, AR_PHY_SWITCH_COM
,
3677 AR_SWITCH_TABLE_COM_ALL
, value
);
3681 * AR9462 defines new switch table for BT/WLAN,
3682 * here's new field name in XXX.ref for both 2G and 5G.
3683 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3684 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
3685 * SWITCH_TABLE_COM_SPDT_WLAN_RX
3687 * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
3688 * SWITCH_TABLE_COM_SPDT_WLAN_TX
3690 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3691 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3693 if (AR_SREV_9462_20_OR_LATER(ah
) || AR_SREV_9565(ah
)) {
3694 value
= ar9003_switch_com_spdt_get(ah
, is2ghz
);
3695 REG_RMW_FIELD(ah
, AR_PHY_GLB_CONTROL
,
3696 AR_SWITCH_TABLE_COM_SPDT_ALL
, value
);
3697 REG_SET_BIT(ah
, AR_PHY_GLB_CONTROL
, AR_BTCOEX_CTRL_SPDT_ENABLE
);
3700 value
= ar9003_hw_ant_ctrl_common_2_get(ah
, is2ghz
);
3701 if (AR_SREV_9485(ah
) && common
->bt_ant_diversity
) {
3702 value
&= ~AR_SWITCH_TABLE_COM2_ALL
;
3703 value
|= ah
->config
.ant_ctrl_comm2g_switch_enable
;
3706 REG_RMW_FIELD(ah
, AR_PHY_SWITCH_COM_2
, AR_SWITCH_TABLE_COM2_ALL
, value
);
3708 if ((AR_SREV_9462(ah
)) && (ah
->rxchainmask
== 0x2)) {
3709 value
= ar9003_hw_ant_ctrl_chain_get(ah
, 1, is2ghz
);
3710 REG_RMW_FIELD(ah
, switch_chain_reg
[0],
3711 AR_SWITCH_TABLE_ALL
, value
);
3714 for (chain
= 0; chain
< AR9300_MAX_CHAINS
; chain
++) {
3715 if ((ah
->rxchainmask
& BIT(chain
)) ||
3716 (ah
->txchainmask
& BIT(chain
))) {
3717 value
= ar9003_hw_ant_ctrl_chain_get(ah
, chain
,
3719 REG_RMW_FIELD(ah
, switch_chain_reg
[chain
],
3720 AR_SWITCH_TABLE_ALL
, value
);
3724 if (AR_SREV_9330(ah
) || AR_SREV_9485(ah
) || AR_SREV_9565(ah
)) {
3725 value
= ath9k_hw_ar9300_get_eeprom(ah
, EEP_ANT_DIV_CTL1
);
3727 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3728 * are the fields present
3730 regval
= REG_READ(ah
, AR_PHY_MC_GAIN_CTRL
);
3731 regval
&= (~AR_ANT_DIV_CTRL_ALL
);
3732 regval
|= (value
& 0x3f) << AR_ANT_DIV_CTRL_ALL_S
;
3734 regval
&= (~AR_PHY_ANT_DIV_LNADIV
);
3735 regval
|= ((value
>> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S
;
3737 if (AR_SREV_9485(ah
) && common
->bt_ant_diversity
)
3738 regval
|= AR_ANT_DIV_ENABLE
;
3740 if (AR_SREV_9565(ah
)) {
3741 if (common
->bt_ant_diversity
) {
3742 regval
|= (1 << AR_PHY_ANT_SW_RX_PROT_S
);
3744 REG_SET_BIT(ah
, AR_PHY_RESTART
,
3745 AR_PHY_RESTART_ENABLE_DIV_M2FLAG
);
3747 /* Force WLAN LNA diversity ON */
3748 REG_SET_BIT(ah
, AR_BTCOEX_WL_LNADIV
,
3749 AR_BTCOEX_WL_LNADIV_FORCE_ON
);
3751 regval
&= ~(1 << AR_PHY_ANT_DIV_LNADIV_S
);
3752 regval
&= ~(1 << AR_PHY_ANT_SW_RX_PROT_S
);
3754 REG_CLR_BIT(ah
, AR_PHY_MC_GAIN_CTRL
,
3755 (1 << AR_PHY_ANT_SW_RX_PROT_S
));
3757 /* Force WLAN LNA diversity OFF */
3758 REG_CLR_BIT(ah
, AR_BTCOEX_WL_LNADIV
,
3759 AR_BTCOEX_WL_LNADIV_FORCE_ON
);
3763 REG_WRITE(ah
, AR_PHY_MC_GAIN_CTRL
, regval
);
3765 /* enable fast_div */
3766 regval
= REG_READ(ah
, AR_PHY_CCK_DETECT
);
3767 regval
&= (~AR_FAST_DIV_ENABLE
);
3768 regval
|= ((value
>> 7) & 0x1) << AR_FAST_DIV_ENABLE_S
;
3770 if ((AR_SREV_9485(ah
) || AR_SREV_9565(ah
))
3771 && common
->bt_ant_diversity
)
3772 regval
|= AR_FAST_DIV_ENABLE
;
3774 REG_WRITE(ah
, AR_PHY_CCK_DETECT
, regval
);
3776 if (pCap
->hw_caps
& ATH9K_HW_CAP_ANT_DIV_COMB
) {
3777 regval
= REG_READ(ah
, AR_PHY_MC_GAIN_CTRL
);
3779 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3782 regval
&= (~(AR_PHY_ANT_DIV_MAIN_LNACONF
|
3783 AR_PHY_ANT_DIV_ALT_LNACONF
|
3784 AR_PHY_ANT_DIV_ALT_GAINTB
|
3785 AR_PHY_ANT_DIV_MAIN_GAINTB
));
3786 /* by default use LNA1 for the main antenna */
3787 regval
|= (ATH_ANT_DIV_COMB_LNA1
<<
3788 AR_PHY_ANT_DIV_MAIN_LNACONF_S
);
3789 regval
|= (ATH_ANT_DIV_COMB_LNA2
<<
3790 AR_PHY_ANT_DIV_ALT_LNACONF_S
);
3791 REG_WRITE(ah
, AR_PHY_MC_GAIN_CTRL
, regval
);
3796 static void ar9003_hw_drive_strength_apply(struct ath_hw
*ah
)
3798 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
3799 struct ar9300_base_eep_hdr
*pBase
= &eep
->baseEepHeader
;
3803 drive_strength
= pBase
->miscConfiguration
& BIT(0);
3804 if (!drive_strength
)
3807 reg
= REG_READ(ah
, AR_PHY_65NM_CH0_BIAS1
);
3815 REG_WRITE(ah
, AR_PHY_65NM_CH0_BIAS1
, reg
);
3817 reg
= REG_READ(ah
, AR_PHY_65NM_CH0_BIAS2
);
3828 REG_WRITE(ah
, AR_PHY_65NM_CH0_BIAS2
, reg
);
3830 reg
= REG_READ(ah
, AR_PHY_65NM_CH0_BIAS4
);
3835 REG_WRITE(ah
, AR_PHY_65NM_CH0_BIAS4
, reg
);
3838 static u16
ar9003_hw_atten_chain_get(struct ath_hw
*ah
, int chain
,
3839 struct ath9k_channel
*chan
)
3843 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
3845 if (chain
>= 0 && chain
< 3) {
3846 if (IS_CHAN_2GHZ(chan
))
3847 return eep
->modalHeader2G
.xatten1DB
[chain
];
3848 else if (eep
->base_ext2
.xatten1DBLow
[chain
] != 0) {
3849 t
[0] = eep
->base_ext2
.xatten1DBLow
[chain
];
3851 t
[1] = eep
->modalHeader5G
.xatten1DB
[chain
];
3853 t
[2] = eep
->base_ext2
.xatten1DBHigh
[chain
];
3855 value
= ar9003_hw_power_interpolate((s32
) chan
->channel
,
3859 return eep
->modalHeader5G
.xatten1DB
[chain
];
3866 static u16
ar9003_hw_atten_chain_get_margin(struct ath_hw
*ah
, int chain
,
3867 struct ath9k_channel
*chan
)
3871 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
3873 if (chain
>= 0 && chain
< 3) {
3874 if (IS_CHAN_2GHZ(chan
))
3875 return eep
->modalHeader2G
.xatten1Margin
[chain
];
3876 else if (eep
->base_ext2
.xatten1MarginLow
[chain
] != 0) {
3877 t
[0] = eep
->base_ext2
.xatten1MarginLow
[chain
];
3879 t
[1] = eep
->modalHeader5G
.xatten1Margin
[chain
];
3881 t
[2] = eep
->base_ext2
.xatten1MarginHigh
[chain
];
3883 value
= ar9003_hw_power_interpolate((s32
) chan
->channel
,
3887 return eep
->modalHeader5G
.xatten1Margin
[chain
];
3893 static void ar9003_hw_atten_apply(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
3897 unsigned long ext_atten_reg
[3] = {AR_PHY_EXT_ATTEN_CTL_0
,
3898 AR_PHY_EXT_ATTEN_CTL_1
,
3899 AR_PHY_EXT_ATTEN_CTL_2
,
3902 if ((AR_SREV_9462(ah
)) && (ah
->rxchainmask
== 0x2)) {
3903 value
= ar9003_hw_atten_chain_get(ah
, 1, chan
);
3904 REG_RMW_FIELD(ah
, ext_atten_reg
[0],
3905 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB
, value
);
3907 value
= ar9003_hw_atten_chain_get_margin(ah
, 1, chan
);
3908 REG_RMW_FIELD(ah
, ext_atten_reg
[0],
3909 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN
,
3913 /* Test value. if 0 then attenuation is unused. Don't load anything. */
3914 for (i
= 0; i
< AR9300_MAX_CHAINS
; i
++) {
3915 if (ah
->txchainmask
& BIT(i
)) {
3916 value
= ar9003_hw_atten_chain_get(ah
, i
, chan
);
3917 REG_RMW_FIELD(ah
, ext_atten_reg
[i
],
3918 AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB
, value
);
3920 if (AR_SREV_9485(ah
) &&
3921 (ar9003_hw_get_rx_gain_idx(ah
) == 0) &&
3922 ah
->config
.xatten_margin_cfg
)
3925 value
= ar9003_hw_atten_chain_get_margin(ah
, i
, chan
);
3927 if (ah
->config
.alt_mingainidx
)
3928 REG_RMW_FIELD(ah
, AR_PHY_EXT_ATTEN_CTL_0
,
3929 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN
,
3932 REG_RMW_FIELD(ah
, ext_atten_reg
[i
],
3933 AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN
,
3939 static bool is_pmu_set(struct ath_hw
*ah
, u32 pmu_reg
, int pmu_set
)
3943 while (pmu_set
!= REG_READ(ah
, pmu_reg
)) {
3946 REG_WRITE(ah
, pmu_reg
, pmu_set
);
3953 void ar9003_hw_internal_regulator_apply(struct ath_hw
*ah
)
3955 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
3956 struct ar9300_base_eep_hdr
*pBase
= &eep
->baseEepHeader
;
3959 if (pBase
->featureEnable
& BIT(4)) {
3960 if (AR_SREV_9330(ah
) || AR_SREV_9485(ah
)) {
3963 reg_pmu_set
= REG_READ(ah
, AR_PHY_PMU2(ah
)) & ~AR_PHY_PMU2_PGM
;
3964 REG_WRITE(ah
, AR_PHY_PMU2(ah
), reg_pmu_set
);
3965 if (!is_pmu_set(ah
, AR_PHY_PMU2(ah
), reg_pmu_set
))
3968 if (AR_SREV_9330(ah
)) {
3969 if (ah
->is_clk_25mhz
) {
3970 reg_pmu_set
= (3 << 1) | (8 << 4) |
3971 (3 << 8) | (1 << 14) |
3972 (6 << 17) | (1 << 20) |
3975 reg_pmu_set
= (4 << 1) | (7 << 4) |
3976 (3 << 8) | (1 << 14) |
3977 (6 << 17) | (1 << 20) |
3981 reg_pmu_set
= (5 << 1) | (7 << 4) |
3982 (2 << 8) | (2 << 14) |
3983 (6 << 17) | (1 << 20) |
3984 (3 << 24) | (1 << 28);
3987 REG_WRITE(ah
, AR_PHY_PMU1(ah
), reg_pmu_set
);
3988 if (!is_pmu_set(ah
, AR_PHY_PMU1(ah
), reg_pmu_set
))
3991 reg_pmu_set
= (REG_READ(ah
, AR_PHY_PMU2(ah
)) & ~0xFFC00000)
3993 REG_WRITE(ah
, AR_PHY_PMU2(ah
), reg_pmu_set
);
3994 if (!is_pmu_set(ah
, AR_PHY_PMU2(ah
), reg_pmu_set
))
3997 reg_pmu_set
= (REG_READ(ah
, AR_PHY_PMU2(ah
)) & ~0x00200000)
3999 REG_WRITE(ah
, AR_PHY_PMU2(ah
), reg_pmu_set
);
4000 if (!is_pmu_set(ah
, AR_PHY_PMU2(ah
), reg_pmu_set
))
4002 } else if (AR_SREV_9462(ah
) || AR_SREV_9565(ah
) ||
4004 reg_val
= le32_to_cpu(pBase
->swreg
);
4005 REG_WRITE(ah
, AR_PHY_PMU1(ah
), reg_val
);
4007 if (AR_SREV_9561(ah
))
4008 REG_WRITE(ah
, AR_PHY_PMU2(ah
), 0x10200000);
4010 /* Internal regulator is ON. Write swreg register. */
4011 reg_val
= le32_to_cpu(pBase
->swreg
);
4012 REG_WRITE(ah
, AR_RTC_REG_CONTROL1
,
4013 REG_READ(ah
, AR_RTC_REG_CONTROL1
) &
4014 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM
));
4015 REG_WRITE(ah
, AR_RTC_REG_CONTROL0
, reg_val
);
4016 /* Set REG_CONTROL1.SWREG_PROGRAM */
4017 REG_WRITE(ah
, AR_RTC_REG_CONTROL1
,
4019 AR_RTC_REG_CONTROL1
) |
4020 AR_RTC_REG_CONTROL1_SWREG_PROGRAM
);
4023 if (AR_SREV_9330(ah
) || AR_SREV_9485(ah
)) {
4024 REG_RMW_FIELD(ah
, AR_PHY_PMU2(ah
), AR_PHY_PMU2_PGM
, 0);
4025 while (REG_READ_FIELD(ah
, AR_PHY_PMU2(ah
),
4029 REG_RMW_FIELD(ah
, AR_PHY_PMU1(ah
), AR_PHY_PMU1_PWD
, 0x1);
4030 while (!REG_READ_FIELD(ah
, AR_PHY_PMU1(ah
),
4033 REG_RMW_FIELD(ah
, AR_PHY_PMU2(ah
), AR_PHY_PMU2_PGM
, 0x1);
4034 while (!REG_READ_FIELD(ah
, AR_PHY_PMU2(ah
),
4037 } else if (AR_SREV_9462(ah
) || AR_SREV_9565(ah
))
4038 REG_RMW_FIELD(ah
, AR_PHY_PMU1(ah
), AR_PHY_PMU1_PWD
, 0x1);
4040 reg_val
= REG_READ(ah
, AR_RTC_SLEEP_CLK(ah
)) |
4041 AR_RTC_FORCE_SWREG_PRD
;
4042 REG_WRITE(ah
, AR_RTC_SLEEP_CLK(ah
), reg_val
);
4048 static void ar9003_hw_apply_tuning_caps(struct ath_hw
*ah
)
4050 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4051 u8 tuning_caps_param
= eep
->baseEepHeader
.params_for_tuning_caps
[0];
4053 if (AR_SREV_9340(ah
) || AR_SREV_9531(ah
))
4056 if (eep
->baseEepHeader
.featureEnable
& 0x40) {
4057 tuning_caps_param
&= 0x7f;
4058 REG_RMW_FIELD(ah
, AR_CH0_XTAL(ah
), AR_CH0_XTAL_CAPINDAC
,
4060 REG_RMW_FIELD(ah
, AR_CH0_XTAL(ah
), AR_CH0_XTAL_CAPOUTDAC
,
4065 static void ar9003_hw_quick_drop_apply(struct ath_hw
*ah
, u16 freq
)
4067 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4068 struct ar9300_base_eep_hdr
*pBase
= &eep
->baseEepHeader
;
4070 s32 t
[3], f
[3] = {5180, 5500, 5785};
4072 if (!(pBase
->miscConfiguration
& BIT(4)))
4075 if (AR_SREV_9300(ah
) || AR_SREV_9580(ah
) || AR_SREV_9340(ah
)) {
4077 quick_drop
= eep
->modalHeader2G
.quick_drop
;
4079 t
[0] = eep
->base_ext1
.quick_drop_low
;
4080 t
[1] = eep
->modalHeader5G
.quick_drop
;
4081 t
[2] = eep
->base_ext1
.quick_drop_high
;
4082 quick_drop
= ar9003_hw_power_interpolate(freq
, f
, t
, 3);
4084 REG_RMW_FIELD(ah
, AR_PHY_AGC
, AR_PHY_AGC_QUICK_DROP
, quick_drop
);
4088 static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw
*ah
, bool is2ghz
)
4092 value
= ar9003_modal_header(ah
, is2ghz
)->txEndToXpaOff
;
4094 REG_RMW_FIELD(ah
, AR_PHY_XPA_TIMING_CTL
,
4095 AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF
, value
);
4096 REG_RMW_FIELD(ah
, AR_PHY_XPA_TIMING_CTL
,
4097 AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF
, value
);
4100 static void ar9003_hw_xpa_timing_control_apply(struct ath_hw
*ah
, bool is2ghz
)
4102 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4105 if (!(eep
->baseEepHeader
.featureEnable
& 0x80))
4108 if (!AR_SREV_9300(ah
) &&
4109 !AR_SREV_9340(ah
) &&
4110 !AR_SREV_9580(ah
) &&
4111 !AR_SREV_9531(ah
) &&
4115 xpa_ctl
= ar9003_modal_header(ah
, is2ghz
)->txFrameToXpaOn
;
4117 REG_RMW_FIELD(ah
, AR_PHY_XPA_TIMING_CTL
,
4118 AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON
, xpa_ctl
);
4120 REG_RMW_FIELD(ah
, AR_PHY_XPA_TIMING_CTL
,
4121 AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON
, xpa_ctl
);
4124 static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw
*ah
, bool is2ghz
)
4126 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4129 if (!(eep
->baseEepHeader
.miscConfiguration
& 0x40))
4132 if (!AR_SREV_9300(ah
))
4135 bias
= ar9003_modal_header(ah
, is2ghz
)->xlna_bias_strength
;
4136 REG_RMW_FIELD(ah
, AR_PHY_65NM_CH0_RXTX4
, AR_PHY_65NM_RXTX4_XLNA_BIAS
,
4139 REG_RMW_FIELD(ah
, AR_PHY_65NM_CH1_RXTX4
, AR_PHY_65NM_RXTX4_XLNA_BIAS
,
4142 REG_RMW_FIELD(ah
, AR_PHY_65NM_CH2_RXTX4
, AR_PHY_65NM_RXTX4_XLNA_BIAS
,
4146 static int ar9003_hw_get_thermometer(struct ath_hw
*ah
)
4148 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4149 struct ar9300_base_eep_hdr
*pBase
= &eep
->baseEepHeader
;
4150 int thermometer
= (pBase
->miscConfiguration
>> 1) & 0x3;
4152 return --thermometer
;
4155 static void ar9003_hw_thermometer_apply(struct ath_hw
*ah
)
4157 struct ath9k_hw_capabilities
*pCap
= &ah
->caps
;
4158 int thermometer
= ar9003_hw_get_thermometer(ah
);
4159 u8 therm_on
= (thermometer
< 0) ? 0 : 1;
4161 REG_RMW_FIELD(ah
, AR_PHY_65NM_CH0_RXTX4
,
4162 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR
, therm_on
);
4163 if (pCap
->chip_chainmask
& BIT(1))
4164 REG_RMW_FIELD(ah
, AR_PHY_65NM_CH1_RXTX4
,
4165 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR
, therm_on
);
4166 if (pCap
->chip_chainmask
& BIT(2))
4167 REG_RMW_FIELD(ah
, AR_PHY_65NM_CH2_RXTX4
,
4168 AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR
, therm_on
);
4170 therm_on
= thermometer
== 0;
4171 REG_RMW_FIELD(ah
, AR_PHY_65NM_CH0_RXTX4
,
4172 AR_PHY_65NM_CH0_RXTX4_THERM_ON
, therm_on
);
4173 if (pCap
->chip_chainmask
& BIT(1)) {
4174 therm_on
= thermometer
== 1;
4175 REG_RMW_FIELD(ah
, AR_PHY_65NM_CH1_RXTX4
,
4176 AR_PHY_65NM_CH0_RXTX4_THERM_ON
, therm_on
);
4178 if (pCap
->chip_chainmask
& BIT(2)) {
4179 therm_on
= thermometer
== 2;
4180 REG_RMW_FIELD(ah
, AR_PHY_65NM_CH2_RXTX4
,
4181 AR_PHY_65NM_CH0_RXTX4_THERM_ON
, therm_on
);
4185 static void ar9003_hw_thermo_cal_apply(struct ath_hw
*ah
)
4187 u32 data
= 0, ko
, kg
;
4189 if (!AR_SREV_9462_20_OR_LATER(ah
))
4192 ar9300_otp_read_word(ah
, 1, &data
);
4194 kg
= (data
>> 8) & 0xff;
4196 REG_RMW_FIELD(ah
, AR_PHY_BB_THERM_ADC_3
,
4197 AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET
, ko
);
4198 REG_RMW_FIELD(ah
, AR_PHY_BB_THERM_ADC_3
,
4199 AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN
,
4204 static void ar9003_hw_apply_minccapwr_thresh(struct ath_hw
*ah
,
4207 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4208 const u_int32_t cca_ctrl
[AR9300_MAX_CHAINS
] = {
4217 if (!(eep
->base_ext1
.misc_enable
& BIT(2)))
4220 if (!(eep
->base_ext1
.misc_enable
& BIT(3)))
4224 for (chain
= 0; chain
< AR9300_MAX_CHAINS
; chain
++) {
4225 if (!(ah
->caps
.tx_chainmask
& BIT(chain
)))
4228 val
= ar9003_modal_header(ah
, is2ghz
)->noiseFloorThreshCh
[chain
];
4229 REG_RMW_FIELD(ah
, cca_ctrl
[chain
],
4230 AR_PHY_EXT_CCA0_THRESH62_1
, val
);
4235 static void ath9k_hw_ar9300_set_board_values(struct ath_hw
*ah
,
4236 struct ath9k_channel
*chan
)
4238 bool is2ghz
= IS_CHAN_2GHZ(chan
);
4239 ar9003_hw_xpa_timing_control_apply(ah
, is2ghz
);
4240 ar9003_hw_xpa_bias_level_apply(ah
, is2ghz
);
4241 ar9003_hw_ant_ctrl_apply(ah
, is2ghz
);
4242 ar9003_hw_drive_strength_apply(ah
);
4243 ar9003_hw_xlna_bias_strength_apply(ah
, is2ghz
);
4244 ar9003_hw_atten_apply(ah
, chan
);
4245 ar9003_hw_quick_drop_apply(ah
, chan
->channel
);
4246 if (!AR_SREV_9330(ah
) && !AR_SREV_9340(ah
) && !AR_SREV_9531(ah
))
4247 ar9003_hw_internal_regulator_apply(ah
);
4248 ar9003_hw_apply_tuning_caps(ah
);
4249 ar9003_hw_apply_minccapwr_thresh(ah
, is2ghz
);
4250 ar9003_hw_txend_to_xpa_off_apply(ah
, is2ghz
);
4251 ar9003_hw_thermometer_apply(ah
);
4252 ar9003_hw_thermo_cal_apply(ah
);
4255 static void ath9k_hw_ar9300_set_addac(struct ath_hw
*ah
,
4256 struct ath9k_channel
*chan
)
4261 * Returns the interpolated y value corresponding to the specified x value
4262 * from the np ordered pairs of data (px,py).
4263 * The pairs do not have to be in any order.
4264 * If the specified x value is less than any of the px,
4265 * the returned y value is equal to the py for the lowest px.
4266 * If the specified x value is greater than any of the px,
4267 * the returned y value is equal to the py for the highest px.
4269 static int ar9003_hw_power_interpolate(int32_t x
,
4270 int32_t *px
, int32_t *py
, u_int16_t np
)
4273 int lx
= 0, ly
= 0, lhave
= 0;
4274 int hx
= 0, hy
= 0, hhave
= 0;
4281 /* identify best lower and higher x calibration measurement */
4282 for (ip
= 0; ip
< np
; ip
++) {
4285 /* this measurement is higher than our desired x */
4287 if (!hhave
|| dx
> (x
- hx
)) {
4288 /* new best higher x measurement */
4294 /* this measurement is lower than our desired x */
4296 if (!lhave
|| dx
< (x
- lx
)) {
4297 /* new best lower x measurement */
4305 /* the low x is good */
4307 /* so is the high x */
4309 /* they're the same, so just pick one */
4312 else /* interpolate */
4313 y
= interpolate(x
, lx
, hx
, ly
, hy
);
4314 } else /* only low is good, use it */
4316 } else if (hhave
) /* only high is good, use it */
4318 else /* nothing is good,this should never happen unless np=0, ???? */
4323 static u8
ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw
*ah
,
4324 u16 rateIndex
, u16 freq
, bool is2GHz
)
4327 s32 targetPowerArray
[AR9300_NUM_5G_20_TARGET_POWERS
];
4328 s32 freqArray
[AR9300_NUM_5G_20_TARGET_POWERS
];
4329 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4330 struct cal_tgt_pow_legacy
*pEepromTargetPwr
;
4334 numPiers
= AR9300_NUM_2G_20_TARGET_POWERS
;
4335 pEepromTargetPwr
= eep
->calTargetPower2G
;
4336 pFreqBin
= eep
->calTarget_freqbin_2G
;
4338 numPiers
= AR9300_NUM_5G_20_TARGET_POWERS
;
4339 pEepromTargetPwr
= eep
->calTargetPower5G
;
4340 pFreqBin
= eep
->calTarget_freqbin_5G
;
4344 * create array of channels and targetpower from
4345 * targetpower piers stored on eeprom
4347 for (i
= 0; i
< numPiers
; i
++) {
4348 freqArray
[i
] = ath9k_hw_fbin2freq(pFreqBin
[i
], is2GHz
);
4349 targetPowerArray
[i
] = pEepromTargetPwr
[i
].tPow2x
[rateIndex
];
4352 /* interpolate to get target power for given frequency */
4353 return (u8
) ar9003_hw_power_interpolate((s32
) freq
,
4355 targetPowerArray
, numPiers
);
4358 static u8
ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw
*ah
,
4360 u16 freq
, bool is2GHz
)
4363 s32 targetPowerArray
[AR9300_NUM_5G_20_TARGET_POWERS
];
4364 s32 freqArray
[AR9300_NUM_5G_20_TARGET_POWERS
];
4365 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4366 struct cal_tgt_pow_ht
*pEepromTargetPwr
;
4370 numPiers
= AR9300_NUM_2G_20_TARGET_POWERS
;
4371 pEepromTargetPwr
= eep
->calTargetPower2GHT20
;
4372 pFreqBin
= eep
->calTarget_freqbin_2GHT20
;
4374 numPiers
= AR9300_NUM_5G_20_TARGET_POWERS
;
4375 pEepromTargetPwr
= eep
->calTargetPower5GHT20
;
4376 pFreqBin
= eep
->calTarget_freqbin_5GHT20
;
4380 * create array of channels and targetpower
4381 * from targetpower piers stored on eeprom
4383 for (i
= 0; i
< numPiers
; i
++) {
4384 freqArray
[i
] = ath9k_hw_fbin2freq(pFreqBin
[i
], is2GHz
);
4385 targetPowerArray
[i
] = pEepromTargetPwr
[i
].tPow2x
[rateIndex
];
4388 /* interpolate to get target power for given frequency */
4389 return (u8
) ar9003_hw_power_interpolate((s32
) freq
,
4391 targetPowerArray
, numPiers
);
4394 static u8
ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw
*ah
,
4396 u16 freq
, bool is2GHz
)
4399 s32 targetPowerArray
[AR9300_NUM_5G_40_TARGET_POWERS
];
4400 s32 freqArray
[AR9300_NUM_5G_40_TARGET_POWERS
];
4401 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4402 struct cal_tgt_pow_ht
*pEepromTargetPwr
;
4406 numPiers
= AR9300_NUM_2G_40_TARGET_POWERS
;
4407 pEepromTargetPwr
= eep
->calTargetPower2GHT40
;
4408 pFreqBin
= eep
->calTarget_freqbin_2GHT40
;
4410 numPiers
= AR9300_NUM_5G_40_TARGET_POWERS
;
4411 pEepromTargetPwr
= eep
->calTargetPower5GHT40
;
4412 pFreqBin
= eep
->calTarget_freqbin_5GHT40
;
4416 * create array of channels and targetpower from
4417 * targetpower piers stored on eeprom
4419 for (i
= 0; i
< numPiers
; i
++) {
4420 freqArray
[i
] = ath9k_hw_fbin2freq(pFreqBin
[i
], is2GHz
);
4421 targetPowerArray
[i
] = pEepromTargetPwr
[i
].tPow2x
[rateIndex
];
4424 /* interpolate to get target power for given frequency */
4425 return (u8
) ar9003_hw_power_interpolate((s32
) freq
,
4427 targetPowerArray
, numPiers
);
4430 static u8
ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw
*ah
,
4431 u16 rateIndex
, u16 freq
)
4433 u16 numPiers
= AR9300_NUM_2G_CCK_TARGET_POWERS
, i
;
4434 s32 targetPowerArray
[AR9300_NUM_2G_CCK_TARGET_POWERS
];
4435 s32 freqArray
[AR9300_NUM_2G_CCK_TARGET_POWERS
];
4436 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4437 struct cal_tgt_pow_legacy
*pEepromTargetPwr
= eep
->calTargetPowerCck
;
4438 u8
*pFreqBin
= eep
->calTarget_freqbin_Cck
;
4441 * create array of channels and targetpower from
4442 * targetpower piers stored on eeprom
4444 for (i
= 0; i
< numPiers
; i
++) {
4445 freqArray
[i
] = ath9k_hw_fbin2freq(pFreqBin
[i
], 1);
4446 targetPowerArray
[i
] = pEepromTargetPwr
[i
].tPow2x
[rateIndex
];
4449 /* interpolate to get target power for given frequency */
4450 return (u8
) ar9003_hw_power_interpolate((s32
) freq
,
4452 targetPowerArray
, numPiers
);
4455 static void ar9003_hw_selfgen_tpc_txpower(struct ath_hw
*ah
,
4456 struct ath9k_channel
*chan
,
4461 /* target power values for self generated frames (ACK,RTS/CTS) */
4462 if (IS_CHAN_2GHZ(chan
)) {
4463 val
= SM(pwr_array
[ALL_TARGET_LEGACY_1L_5L
], AR_TPC_ACK
) |
4464 SM(pwr_array
[ALL_TARGET_LEGACY_1L_5L
], AR_TPC_CTS
) |
4465 SM(0x3f, AR_TPC_CHIRP
) | SM(0x3f, AR_TPC_RPT
);
4467 val
= SM(pwr_array
[ALL_TARGET_LEGACY_6_24
], AR_TPC_ACK
) |
4468 SM(pwr_array
[ALL_TARGET_LEGACY_6_24
], AR_TPC_CTS
) |
4469 SM(0x3f, AR_TPC_CHIRP
) | SM(0x3f, AR_TPC_RPT
);
4471 REG_WRITE(ah
, AR_TPC
, val
);
4474 /* Set tx power registers to array of values passed in */
4475 int ar9003_hw_tx_power_regwrite(struct ath_hw
*ah
, u8
* pPwrArray
)
4477 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
4478 /* make sure forced gain is not set */
4479 REG_WRITE(ah
, AR_PHY_TX_FORCED_GAIN
, 0);
4481 /* Write the OFDM power per rate set */
4483 /* 6 (LSB), 9, 12, 18 (MSB) */
4484 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(0),
4485 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_6_24
], 24) |
4486 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_6_24
], 16) |
4487 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_6_24
], 8) |
4488 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_6_24
], 0));
4490 /* 24 (LSB), 36, 48, 54 (MSB) */
4491 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(1),
4492 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_54
], 24) |
4493 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_48
], 16) |
4494 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_36
], 8) |
4495 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_6_24
], 0));
4497 /* Write the CCK power per rate set */
4499 /* 1L (LSB), reserved, 2L, 2S (MSB) */
4500 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(2),
4501 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_1L_5L
], 24) |
4502 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_1L_5L
], 16) |
4503 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
4504 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_1L_5L
], 0));
4506 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
4507 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(3),
4508 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_11S
], 24) |
4509 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_11L
], 16) |
4510 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_5S
], 8) |
4511 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_1L_5L
], 0)
4514 /* Write the power for duplicated frames - HT40 */
4516 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4517 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(8),
4518 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_6_24
], 24) |
4519 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_1L_5L
], 16) |
4520 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_6_24
], 8) |
4521 POW_SM(pPwrArray
[ALL_TARGET_LEGACY_1L_5L
], 0)
4524 /* Write the HT20 power per rate set */
4526 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
4527 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(4),
4528 POW_SM(pPwrArray
[ALL_TARGET_HT20_5
], 24) |
4529 POW_SM(pPwrArray
[ALL_TARGET_HT20_4
], 16) |
4530 POW_SM(pPwrArray
[ALL_TARGET_HT20_1_3_9_11_17_19
], 8) |
4531 POW_SM(pPwrArray
[ALL_TARGET_HT20_0_8_16
], 0)
4534 /* 6 (LSB), 7, 12, 13 (MSB) */
4535 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(5),
4536 POW_SM(pPwrArray
[ALL_TARGET_HT20_13
], 24) |
4537 POW_SM(pPwrArray
[ALL_TARGET_HT20_12
], 16) |
4538 POW_SM(pPwrArray
[ALL_TARGET_HT20_7
], 8) |
4539 POW_SM(pPwrArray
[ALL_TARGET_HT20_6
], 0)
4542 /* 14 (LSB), 15, 20, 21 */
4543 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(9),
4544 POW_SM(pPwrArray
[ALL_TARGET_HT20_21
], 24) |
4545 POW_SM(pPwrArray
[ALL_TARGET_HT20_20
], 16) |
4546 POW_SM(pPwrArray
[ALL_TARGET_HT20_15
], 8) |
4547 POW_SM(pPwrArray
[ALL_TARGET_HT20_14
], 0)
4550 /* Mixed HT20 and HT40 rates */
4552 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
4553 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(10),
4554 POW_SM(pPwrArray
[ALL_TARGET_HT40_23
], 24) |
4555 POW_SM(pPwrArray
[ALL_TARGET_HT40_22
], 16) |
4556 POW_SM(pPwrArray
[ALL_TARGET_HT20_23
], 8) |
4557 POW_SM(pPwrArray
[ALL_TARGET_HT20_22
], 0)
4561 * Write the HT40 power per rate set
4562 * correct PAR difference between HT40 and HT20/LEGACY
4563 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
4565 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(6),
4566 POW_SM(pPwrArray
[ALL_TARGET_HT40_5
], 24) |
4567 POW_SM(pPwrArray
[ALL_TARGET_HT40_4
], 16) |
4568 POW_SM(pPwrArray
[ALL_TARGET_HT40_1_3_9_11_17_19
], 8) |
4569 POW_SM(pPwrArray
[ALL_TARGET_HT40_0_8_16
], 0)
4572 /* 6 (LSB), 7, 12, 13 (MSB) */
4573 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(7),
4574 POW_SM(pPwrArray
[ALL_TARGET_HT40_13
], 24) |
4575 POW_SM(pPwrArray
[ALL_TARGET_HT40_12
], 16) |
4576 POW_SM(pPwrArray
[ALL_TARGET_HT40_7
], 8) |
4577 POW_SM(pPwrArray
[ALL_TARGET_HT40_6
], 0)
4580 /* 14 (LSB), 15, 20, 21 */
4581 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE(11),
4582 POW_SM(pPwrArray
[ALL_TARGET_HT40_21
], 24) |
4583 POW_SM(pPwrArray
[ALL_TARGET_HT40_20
], 16) |
4584 POW_SM(pPwrArray
[ALL_TARGET_HT40_15
], 8) |
4585 POW_SM(pPwrArray
[ALL_TARGET_HT40_14
], 0)
4592 static void ar9003_hw_get_legacy_target_powers(struct ath_hw
*ah
, u16 freq
,
4593 u8
*targetPowerValT2
,
4596 targetPowerValT2
[ALL_TARGET_LEGACY_6_24
] =
4597 ar9003_hw_eeprom_get_tgt_pwr(ah
, LEGACY_TARGET_RATE_6_24
, freq
,
4599 targetPowerValT2
[ALL_TARGET_LEGACY_36
] =
4600 ar9003_hw_eeprom_get_tgt_pwr(ah
, LEGACY_TARGET_RATE_36
, freq
,
4602 targetPowerValT2
[ALL_TARGET_LEGACY_48
] =
4603 ar9003_hw_eeprom_get_tgt_pwr(ah
, LEGACY_TARGET_RATE_48
, freq
,
4605 targetPowerValT2
[ALL_TARGET_LEGACY_54
] =
4606 ar9003_hw_eeprom_get_tgt_pwr(ah
, LEGACY_TARGET_RATE_54
, freq
,
4610 static void ar9003_hw_get_cck_target_powers(struct ath_hw
*ah
, u16 freq
,
4611 u8
*targetPowerValT2
)
4613 targetPowerValT2
[ALL_TARGET_LEGACY_1L_5L
] =
4614 ar9003_hw_eeprom_get_cck_tgt_pwr(ah
, LEGACY_TARGET_RATE_1L_5L
,
4616 targetPowerValT2
[ALL_TARGET_LEGACY_5S
] =
4617 ar9003_hw_eeprom_get_cck_tgt_pwr(ah
, LEGACY_TARGET_RATE_5S
, freq
);
4618 targetPowerValT2
[ALL_TARGET_LEGACY_11L
] =
4619 ar9003_hw_eeprom_get_cck_tgt_pwr(ah
, LEGACY_TARGET_RATE_11L
, freq
);
4620 targetPowerValT2
[ALL_TARGET_LEGACY_11S
] =
4621 ar9003_hw_eeprom_get_cck_tgt_pwr(ah
, LEGACY_TARGET_RATE_11S
, freq
);
4624 static void ar9003_hw_get_ht20_target_powers(struct ath_hw
*ah
, u16 freq
,
4625 u8
*targetPowerValT2
, bool is2GHz
)
4627 targetPowerValT2
[ALL_TARGET_HT20_0_8_16
] =
4628 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_0_8_16
, freq
,
4630 targetPowerValT2
[ALL_TARGET_HT20_1_3_9_11_17_19
] =
4631 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_1_3_9_11_17_19
,
4633 targetPowerValT2
[ALL_TARGET_HT20_4
] =
4634 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_4
, freq
,
4636 targetPowerValT2
[ALL_TARGET_HT20_5
] =
4637 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_5
, freq
,
4639 targetPowerValT2
[ALL_TARGET_HT20_6
] =
4640 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_6
, freq
,
4642 targetPowerValT2
[ALL_TARGET_HT20_7
] =
4643 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_7
, freq
,
4645 targetPowerValT2
[ALL_TARGET_HT20_12
] =
4646 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_12
, freq
,
4648 targetPowerValT2
[ALL_TARGET_HT20_13
] =
4649 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_13
, freq
,
4651 targetPowerValT2
[ALL_TARGET_HT20_14
] =
4652 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_14
, freq
,
4654 targetPowerValT2
[ALL_TARGET_HT20_15
] =
4655 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_15
, freq
,
4657 targetPowerValT2
[ALL_TARGET_HT20_20
] =
4658 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_20
, freq
,
4660 targetPowerValT2
[ALL_TARGET_HT20_21
] =
4661 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_21
, freq
,
4663 targetPowerValT2
[ALL_TARGET_HT20_22
] =
4664 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_22
, freq
,
4666 targetPowerValT2
[ALL_TARGET_HT20_23
] =
4667 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah
, HT_TARGET_RATE_23
, freq
,
4671 static void ar9003_hw_get_ht40_target_powers(struct ath_hw
*ah
,
4673 u8
*targetPowerValT2
,
4676 /* XXX: hard code for now, need to get from eeprom struct */
4677 u8 ht40PowerIncForPdadc
= 0;
4679 targetPowerValT2
[ALL_TARGET_HT40_0_8_16
] =
4680 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_0_8_16
, freq
,
4681 is2GHz
) + ht40PowerIncForPdadc
;
4682 targetPowerValT2
[ALL_TARGET_HT40_1_3_9_11_17_19
] =
4683 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_1_3_9_11_17_19
,
4685 is2GHz
) + ht40PowerIncForPdadc
;
4686 targetPowerValT2
[ALL_TARGET_HT40_4
] =
4687 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_4
, freq
,
4688 is2GHz
) + ht40PowerIncForPdadc
;
4689 targetPowerValT2
[ALL_TARGET_HT40_5
] =
4690 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_5
, freq
,
4691 is2GHz
) + ht40PowerIncForPdadc
;
4692 targetPowerValT2
[ALL_TARGET_HT40_6
] =
4693 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_6
, freq
,
4694 is2GHz
) + ht40PowerIncForPdadc
;
4695 targetPowerValT2
[ALL_TARGET_HT40_7
] =
4696 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_7
, freq
,
4697 is2GHz
) + ht40PowerIncForPdadc
;
4698 targetPowerValT2
[ALL_TARGET_HT40_12
] =
4699 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_12
, freq
,
4700 is2GHz
) + ht40PowerIncForPdadc
;
4701 targetPowerValT2
[ALL_TARGET_HT40_13
] =
4702 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_13
, freq
,
4703 is2GHz
) + ht40PowerIncForPdadc
;
4704 targetPowerValT2
[ALL_TARGET_HT40_14
] =
4705 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_14
, freq
,
4706 is2GHz
) + ht40PowerIncForPdadc
;
4707 targetPowerValT2
[ALL_TARGET_HT40_15
] =
4708 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_15
, freq
,
4709 is2GHz
) + ht40PowerIncForPdadc
;
4710 targetPowerValT2
[ALL_TARGET_HT40_20
] =
4711 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_20
, freq
,
4712 is2GHz
) + ht40PowerIncForPdadc
;
4713 targetPowerValT2
[ALL_TARGET_HT40_21
] =
4714 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_21
, freq
,
4715 is2GHz
) + ht40PowerIncForPdadc
;
4716 targetPowerValT2
[ALL_TARGET_HT40_22
] =
4717 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_22
, freq
,
4718 is2GHz
) + ht40PowerIncForPdadc
;
4719 targetPowerValT2
[ALL_TARGET_HT40_23
] =
4720 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah
, HT_TARGET_RATE_23
, freq
,
4721 is2GHz
) + ht40PowerIncForPdadc
;
4724 static void ar9003_hw_get_target_power_eeprom(struct ath_hw
*ah
,
4725 struct ath9k_channel
*chan
,
4726 u8
*targetPowerValT2
)
4728 bool is2GHz
= IS_CHAN_2GHZ(chan
);
4730 struct ath_common
*common
= ath9k_hw_common(ah
);
4731 u16 freq
= chan
->channel
;
4734 ar9003_hw_get_cck_target_powers(ah
, freq
, targetPowerValT2
);
4736 ar9003_hw_get_legacy_target_powers(ah
, freq
, targetPowerValT2
, is2GHz
);
4737 ar9003_hw_get_ht20_target_powers(ah
, freq
, targetPowerValT2
, is2GHz
);
4739 if (IS_CHAN_HT40(chan
))
4740 ar9003_hw_get_ht40_target_powers(ah
, freq
, targetPowerValT2
,
4743 for (i
= 0; i
< ar9300RateSize
; i
++) {
4744 ath_dbg(common
, REGULATORY
, "TPC[%02d] 0x%08x\n",
4745 i
, targetPowerValT2
[i
]);
4749 static int ar9003_hw_cal_pier_get(struct ath_hw
*ah
,
4755 int *ptemperature
, int *pvoltage
,
4756 int *pnf_cal
, int *pnf_power
)
4759 struct ar9300_cal_data_per_freq_op_loop
*pCalPierStruct
;
4760 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4761 struct ath_common
*common
= ath9k_hw_common(ah
);
4763 if (ichain
>= AR9300_MAX_CHAINS
) {
4764 ath_dbg(common
, EEPROM
,
4765 "Invalid chain index, must be less than %d\n",
4771 if (ipier
>= AR9300_NUM_2G_CAL_PIERS
) {
4772 ath_dbg(common
, EEPROM
,
4773 "Invalid 2GHz cal pier index, must be less than %d\n",
4774 AR9300_NUM_2G_CAL_PIERS
);
4778 pCalPier
= &(eep
->calFreqPier2G
[ipier
]);
4779 pCalPierStruct
= &(eep
->calPierData2G
[ichain
][ipier
]);
4781 if (ipier
>= AR9300_NUM_5G_CAL_PIERS
) {
4782 ath_dbg(common
, EEPROM
,
4783 "Invalid 5GHz cal pier index, must be less than %d\n",
4784 AR9300_NUM_5G_CAL_PIERS
);
4787 pCalPier
= &(eep
->calFreqPier5G
[ipier
]);
4788 pCalPierStruct
= &(eep
->calPierData5G
[ichain
][ipier
]);
4791 *pfrequency
= ath9k_hw_fbin2freq(*pCalPier
, is2ghz
);
4792 *pcorrection
= pCalPierStruct
->refPower
;
4793 *ptemperature
= pCalPierStruct
->tempMeas
;
4794 *pvoltage
= pCalPierStruct
->voltMeas
;
4795 *pnf_cal
= pCalPierStruct
->rxTempMeas
?
4796 N2DBM(pCalPierStruct
->rxNoisefloorCal
) : 0;
4797 *pnf_power
= pCalPierStruct
->rxTempMeas
?
4798 N2DBM(pCalPierStruct
->rxNoisefloorPower
) : 0;
4803 static void ar9003_hw_power_control_override(struct ath_hw
*ah
,
4806 int *voltage
, int *temperature
)
4808 int temp_slope
= 0, temp_slope1
= 0, temp_slope2
= 0;
4809 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
4810 int f
[8], t
[8], t1
[3], t2
[3], i
;
4812 REG_RMW(ah
, AR_PHY_TPC_11_B0
,
4813 (correction
[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S
),
4814 AR_PHY_TPC_OLPC_GAIN_DELTA
);
4815 if (ah
->caps
.tx_chainmask
& BIT(1))
4816 REG_RMW(ah
, AR_PHY_TPC_11_B1
,
4817 (correction
[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S
),
4818 AR_PHY_TPC_OLPC_GAIN_DELTA
);
4819 if (ah
->caps
.tx_chainmask
& BIT(2))
4820 REG_RMW(ah
, AR_PHY_TPC_11_B2
,
4821 (correction
[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S
),
4822 AR_PHY_TPC_OLPC_GAIN_DELTA
);
4824 /* enable open loop power control on chip */
4825 REG_RMW(ah
, AR_PHY_TPC_6_B0
,
4826 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S
),
4827 AR_PHY_TPC_6_ERROR_EST_MODE
);
4828 if (ah
->caps
.tx_chainmask
& BIT(1))
4829 REG_RMW(ah
, AR_PHY_TPC_6_B1
,
4830 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S
),
4831 AR_PHY_TPC_6_ERROR_EST_MODE
);
4832 if (ah
->caps
.tx_chainmask
& BIT(2))
4833 REG_RMW(ah
, AR_PHY_TPC_6_B2
,
4834 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S
),
4835 AR_PHY_TPC_6_ERROR_EST_MODE
);
4838 * enable temperature compensation
4839 * Need to use register names
4841 if (frequency
< 4000) {
4842 temp_slope
= eep
->modalHeader2G
.tempSlope
;
4844 if (AR_SREV_9550(ah
)) {
4845 t
[0] = eep
->base_ext1
.tempslopextension
[2];
4846 t1
[0] = eep
->base_ext1
.tempslopextension
[3];
4847 t2
[0] = eep
->base_ext1
.tempslopextension
[4];
4850 t
[1] = eep
->modalHeader5G
.tempSlope
;
4851 t1
[1] = eep
->base_ext1
.tempslopextension
[0];
4852 t2
[1] = eep
->base_ext1
.tempslopextension
[1];
4855 t
[2] = eep
->base_ext1
.tempslopextension
[5];
4856 t1
[2] = eep
->base_ext1
.tempslopextension
[6];
4857 t2
[2] = eep
->base_ext1
.tempslopextension
[7];
4860 temp_slope
= ar9003_hw_power_interpolate(frequency
,
4862 temp_slope1
= ar9003_hw_power_interpolate(frequency
,
4864 temp_slope2
= ar9003_hw_power_interpolate(frequency
,
4870 if ((eep
->baseEepHeader
.miscConfiguration
& 0x20) != 0) {
4871 for (i
= 0; i
< 8; i
++) {
4872 t
[i
] = eep
->base_ext1
.tempslopextension
[i
];
4873 f
[i
] = FBIN2FREQ(eep
->calFreqPier5G
[i
], 0);
4875 temp_slope
= ar9003_hw_power_interpolate((s32
) frequency
,
4877 } else if (eep
->base_ext2
.tempSlopeLow
!= 0) {
4878 t
[0] = eep
->base_ext2
.tempSlopeLow
;
4880 t
[1] = eep
->modalHeader5G
.tempSlope
;
4882 t
[2] = eep
->base_ext2
.tempSlopeHigh
;
4884 temp_slope
= ar9003_hw_power_interpolate((s32
) frequency
,
4887 temp_slope
= eep
->modalHeader5G
.tempSlope
;
4892 if (AR_SREV_9550(ah
) || AR_SREV_9531(ah
) || AR_SREV_9561(ah
)) {
4893 u8 txmask
= (eep
->baseEepHeader
.txrxMask
& 0xf0) >> 4;
4896 * AR955x has tempSlope register for each chain.
4897 * Check whether temp_compensation feature is enabled or not.
4899 if (eep
->baseEepHeader
.featureEnable
& 0x1) {
4900 if (frequency
< 4000) {
4901 if (txmask
& BIT(0))
4902 REG_RMW_FIELD(ah
, AR_PHY_TPC_19
,
4903 AR_PHY_TPC_19_ALPHA_THERM
,
4904 eep
->base_ext2
.tempSlopeLow
);
4905 if (txmask
& BIT(1))
4906 REG_RMW_FIELD(ah
, AR_PHY_TPC_19_B1
,
4907 AR_PHY_TPC_19_ALPHA_THERM
,
4909 if (txmask
& BIT(2))
4910 REG_RMW_FIELD(ah
, AR_PHY_TPC_19_B2
,
4911 AR_PHY_TPC_19_ALPHA_THERM
,
4912 eep
->base_ext2
.tempSlopeHigh
);
4914 if (txmask
& BIT(0))
4915 REG_RMW_FIELD(ah
, AR_PHY_TPC_19
,
4916 AR_PHY_TPC_19_ALPHA_THERM
,
4918 if (txmask
& BIT(1))
4919 REG_RMW_FIELD(ah
, AR_PHY_TPC_19_B1
,
4920 AR_PHY_TPC_19_ALPHA_THERM
,
4922 if (txmask
& BIT(2))
4923 REG_RMW_FIELD(ah
, AR_PHY_TPC_19_B2
,
4924 AR_PHY_TPC_19_ALPHA_THERM
,
4929 * If temp compensation is not enabled,
4930 * set all registers to 0.
4932 if (txmask
& BIT(0))
4933 REG_RMW_FIELD(ah
, AR_PHY_TPC_19
,
4934 AR_PHY_TPC_19_ALPHA_THERM
, 0);
4935 if (txmask
& BIT(1))
4936 REG_RMW_FIELD(ah
, AR_PHY_TPC_19_B1
,
4937 AR_PHY_TPC_19_ALPHA_THERM
, 0);
4938 if (txmask
& BIT(2))
4939 REG_RMW_FIELD(ah
, AR_PHY_TPC_19_B2
,
4940 AR_PHY_TPC_19_ALPHA_THERM
, 0);
4943 REG_RMW_FIELD(ah
, AR_PHY_TPC_19
,
4944 AR_PHY_TPC_19_ALPHA_THERM
, temp_slope
);
4947 if (AR_SREV_9462_20_OR_LATER(ah
))
4948 REG_RMW_FIELD(ah
, AR_PHY_TPC_19_B1
,
4949 AR_PHY_TPC_19_B1_ALPHA_THERM
, temp_slope
);
4952 REG_RMW_FIELD(ah
, AR_PHY_TPC_18
, AR_PHY_TPC_18_THERM_CAL_VALUE
,
4956 /* Apply the recorded correction values. */
4957 static int ar9003_hw_calibration_apply(struct ath_hw
*ah
, int frequency
)
4959 int ichain
, ipier
, npier
;
4960 int lfrequency
[AR9300_MAX_CHAINS
],
4961 lcorrection
[AR9300_MAX_CHAINS
],
4962 ltemperature
[AR9300_MAX_CHAINS
], lvoltage
[AR9300_MAX_CHAINS
],
4963 lnf_cal
[AR9300_MAX_CHAINS
], lnf_pwr
[AR9300_MAX_CHAINS
];
4964 int hfrequency
[AR9300_MAX_CHAINS
],
4965 hcorrection
[AR9300_MAX_CHAINS
],
4966 htemperature
[AR9300_MAX_CHAINS
], hvoltage
[AR9300_MAX_CHAINS
],
4967 hnf_cal
[AR9300_MAX_CHAINS
], hnf_pwr
[AR9300_MAX_CHAINS
];
4969 int correction
[AR9300_MAX_CHAINS
],
4970 voltage
[AR9300_MAX_CHAINS
], temperature
[AR9300_MAX_CHAINS
],
4971 nf_cal
[AR9300_MAX_CHAINS
], nf_pwr
[AR9300_MAX_CHAINS
];
4972 int pfrequency
, pcorrection
, ptemperature
, pvoltage
,
4974 struct ath_common
*common
= ath9k_hw_common(ah
);
4975 bool is2ghz
= frequency
< 4000;
4978 npier
= AR9300_NUM_2G_CAL_PIERS
;
4980 npier
= AR9300_NUM_5G_CAL_PIERS
;
4982 for (ichain
= 0; ichain
< AR9300_MAX_CHAINS
; ichain
++) {
4983 lfrequency
[ichain
] = 0;
4984 hfrequency
[ichain
] = 100000;
4986 /* identify best lower and higher frequency calibration measurement */
4987 for (ichain
= 0; ichain
< AR9300_MAX_CHAINS
; ichain
++) {
4988 for (ipier
= 0; ipier
< npier
; ipier
++) {
4989 if (!ar9003_hw_cal_pier_get(ah
, is2ghz
, ipier
, ichain
,
4990 &pfrequency
, &pcorrection
,
4991 &ptemperature
, &pvoltage
,
4992 &pnf_cal
, &pnf_pwr
)) {
4993 fdiff
= frequency
- pfrequency
;
4996 * this measurement is higher than
4997 * our desired frequency
5000 if (hfrequency
[ichain
] <= 0 ||
5001 hfrequency
[ichain
] >= 100000 ||
5003 (frequency
- hfrequency
[ichain
])) {
5006 * frequency measurement
5008 hfrequency
[ichain
] = pfrequency
;
5009 hcorrection
[ichain
] =
5011 htemperature
[ichain
] =
5013 hvoltage
[ichain
] = pvoltage
;
5014 hnf_cal
[ichain
] = pnf_cal
;
5015 hnf_pwr
[ichain
] = pnf_pwr
;
5019 if (lfrequency
[ichain
] <= 0
5021 (frequency
- lfrequency
[ichain
])) {
5024 * frequency measurement
5026 lfrequency
[ichain
] = pfrequency
;
5027 lcorrection
[ichain
] =
5029 ltemperature
[ichain
] =
5031 lvoltage
[ichain
] = pvoltage
;
5032 lnf_cal
[ichain
] = pnf_cal
;
5033 lnf_pwr
[ichain
] = pnf_pwr
;
5041 for (ichain
= 0; ichain
< AR9300_MAX_CHAINS
; ichain
++) {
5042 ath_dbg(common
, EEPROM
,
5043 "ch=%d f=%d low=%d %d h=%d %d n=%d %d p=%d %d\n",
5044 ichain
, frequency
, lfrequency
[ichain
],
5045 lcorrection
[ichain
], hfrequency
[ichain
],
5046 hcorrection
[ichain
], lnf_cal
[ichain
],
5047 hnf_cal
[ichain
], lnf_pwr
[ichain
],
5049 /* they're the same, so just pick one */
5050 if (hfrequency
[ichain
] == lfrequency
[ichain
]) {
5051 correction
[ichain
] = lcorrection
[ichain
];
5052 voltage
[ichain
] = lvoltage
[ichain
];
5053 temperature
[ichain
] = ltemperature
[ichain
];
5054 nf_cal
[ichain
] = lnf_cal
[ichain
];
5055 nf_pwr
[ichain
] = lnf_pwr
[ichain
];
5057 /* the low frequency is good */
5058 else if (frequency
- lfrequency
[ichain
] < 1000) {
5059 /* so is the high frequency, interpolate */
5060 if (hfrequency
[ichain
] - frequency
< 1000) {
5062 correction
[ichain
] = interpolate(frequency
,
5065 lcorrection
[ichain
],
5066 hcorrection
[ichain
]);
5068 temperature
[ichain
] = interpolate(frequency
,
5071 ltemperature
[ichain
],
5072 htemperature
[ichain
]);
5074 voltage
[ichain
] = interpolate(frequency
,
5080 nf_cal
[ichain
] = interpolate(frequency
,
5086 nf_pwr
[ichain
] = interpolate(frequency
,
5092 /* only low is good, use it */
5094 correction
[ichain
] = lcorrection
[ichain
];
5095 temperature
[ichain
] = ltemperature
[ichain
];
5096 voltage
[ichain
] = lvoltage
[ichain
];
5097 nf_cal
[ichain
] = lnf_cal
[ichain
];
5098 nf_pwr
[ichain
] = lnf_pwr
[ichain
];
5101 /* only high is good, use it */
5102 else if (hfrequency
[ichain
] - frequency
< 1000) {
5103 correction
[ichain
] = hcorrection
[ichain
];
5104 temperature
[ichain
] = htemperature
[ichain
];
5105 voltage
[ichain
] = hvoltage
[ichain
];
5106 nf_cal
[ichain
] = hnf_cal
[ichain
];
5107 nf_pwr
[ichain
] = hnf_pwr
[ichain
];
5108 } else { /* nothing is good, presume 0???? */
5109 correction
[ichain
] = 0;
5110 temperature
[ichain
] = 0;
5111 voltage
[ichain
] = 0;
5117 ar9003_hw_power_control_override(ah
, frequency
, correction
, voltage
,
5120 ath_dbg(common
, EEPROM
,
5121 "for frequency=%d, calibration correction = %d %d %d\n",
5122 frequency
, correction
[0], correction
[1], correction
[2]);
5124 /* Store calibrated noise floor values */
5125 for (ichain
= 0; ichain
< AR9300_MAX_CHAINS
; ichain
++)
5127 ah
->nf_2g
.cal
[ichain
] = nf_cal
[ichain
];
5128 ah
->nf_2g
.pwr
[ichain
] = nf_pwr
[ichain
];
5130 ah
->nf_5g
.cal
[ichain
] = nf_cal
[ichain
];
5131 ah
->nf_5g
.pwr
[ichain
] = nf_pwr
[ichain
];
5137 static u16
ar9003_hw_get_direct_edge_power(struct ar9300_eeprom
*eep
,
5142 struct cal_ctl_data_2g
*ctl_2g
= eep
->ctlPowerData_2G
;
5143 struct cal_ctl_data_5g
*ctl_5g
= eep
->ctlPowerData_5G
;
5146 return CTL_EDGE_TPOWER(ctl_2g
[idx
].ctlEdges
[edge
]);
5148 return CTL_EDGE_TPOWER(ctl_5g
[idx
].ctlEdges
[edge
]);
5151 static u16
ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom
*eep
,
5157 struct cal_ctl_data_2g
*ctl_2g
= eep
->ctlPowerData_2G
;
5158 struct cal_ctl_data_5g
*ctl_5g
= eep
->ctlPowerData_5G
;
5160 u8
*ctl_freqbin
= is2GHz
?
5161 &eep
->ctl_freqbin_2G
[idx
][0] :
5162 &eep
->ctl_freqbin_5G
[idx
][0];
5165 if (ath9k_hw_fbin2freq(ctl_freqbin
[edge
- 1], 1) < freq
&&
5166 CTL_EDGE_FLAGS(ctl_2g
[idx
].ctlEdges
[edge
- 1]))
5167 return CTL_EDGE_TPOWER(ctl_2g
[idx
].ctlEdges
[edge
- 1]);
5169 if (ath9k_hw_fbin2freq(ctl_freqbin
[edge
- 1], 0) < freq
&&
5170 CTL_EDGE_FLAGS(ctl_5g
[idx
].ctlEdges
[edge
- 1]))
5171 return CTL_EDGE_TPOWER(ctl_5g
[idx
].ctlEdges
[edge
- 1]);
5174 return MAX_RATE_POWER
;
5178 * Find the maximum conformance test limit for the given channel and CTL info
5180 static u16
ar9003_hw_get_max_edge_power(struct ar9300_eeprom
*eep
,
5181 u16 freq
, int idx
, bool is2GHz
)
5183 u16 twiceMaxEdgePower
= MAX_RATE_POWER
;
5184 u8
*ctl_freqbin
= is2GHz
?
5185 &eep
->ctl_freqbin_2G
[idx
][0] :
5186 &eep
->ctl_freqbin_5G
[idx
][0];
5187 u16 num_edges
= is2GHz
?
5188 AR9300_NUM_BAND_EDGES_2G
: AR9300_NUM_BAND_EDGES_5G
;
5191 /* Get the edge power */
5193 (edge
< num_edges
) && (ctl_freqbin
[edge
] != AR5416_BCHAN_UNUSED
);
5196 * If there's an exact channel match or an inband flag set
5197 * on the lower channel use the given rdEdgePower
5199 if (freq
== ath9k_hw_fbin2freq(ctl_freqbin
[edge
], is2GHz
)) {
5201 ar9003_hw_get_direct_edge_power(eep
, idx
,
5204 } else if ((edge
> 0) &&
5205 (freq
< ath9k_hw_fbin2freq(ctl_freqbin
[edge
],
5208 ar9003_hw_get_indirect_edge_power(eep
, idx
,
5212 * Leave loop - no more affecting edges possible in
5213 * this monotonic increasing list
5219 if (is2GHz
&& !twiceMaxEdgePower
)
5220 twiceMaxEdgePower
= 60;
5222 return twiceMaxEdgePower
;
5225 static void ar9003_hw_set_power_per_rate_table(struct ath_hw
*ah
,
5226 struct ath9k_channel
*chan
,
5227 u8
*pPwrArray
, u16 cfgCtl
,
5228 u8 antenna_reduction
,
5231 struct ath_common
*common
= ath9k_hw_common(ah
);
5232 struct ar9300_eeprom
*pEepData
= &ah
->eeprom
.ar9300_eep
;
5233 u16 twiceMaxEdgePower
;
5235 u16 scaledPower
= 0, minCtlPower
;
5236 static const u16 ctlModesFor11a
[] = {
5237 CTL_11A
, CTL_5GHT20
, CTL_11A_EXT
, CTL_5GHT40
5239 static const u16 ctlModesFor11g
[] = {
5240 CTL_11B
, CTL_11G
, CTL_2GHT20
, CTL_11B_EXT
,
5241 CTL_11G_EXT
, CTL_2GHT40
5244 const u16
*pCtlMode
;
5246 struct chan_centers centers
;
5249 u16 twiceMinEdgePower
;
5250 bool is2ghz
= IS_CHAN_2GHZ(chan
);
5252 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
5253 scaledPower
= ath9k_hw_get_scaled_power(ah
, powerLimit
,
5257 /* Setup for CTL modes */
5258 /* CTL_11B, CTL_11G, CTL_2GHT20 */
5260 ARRAY_SIZE(ctlModesFor11g
) -
5261 SUB_NUM_CTL_MODES_AT_2G_40
;
5262 pCtlMode
= ctlModesFor11g
;
5263 if (IS_CHAN_HT40(chan
))
5265 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
5267 /* Setup for CTL modes */
5268 /* CTL_11A, CTL_5GHT20 */
5269 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
) -
5270 SUB_NUM_CTL_MODES_AT_5G_40
;
5271 pCtlMode
= ctlModesFor11a
;
5272 if (IS_CHAN_HT40(chan
))
5274 numCtlModes
= ARRAY_SIZE(ctlModesFor11a
);
5278 * For MIMO, need to apply regulatory caps individually across
5279 * dynamically running modes: CCK, OFDM, HT20, HT40
5281 * The outer loop walks through each possible applicable runtime mode.
5282 * The inner loop walks through each ctlIndex entry in EEPROM.
5283 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
5285 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
5286 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
5287 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
5289 freq
= centers
.synth_center
;
5290 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
5291 freq
= centers
.ext_center
;
5293 freq
= centers
.ctl_center
;
5295 ath_dbg(common
, REGULATORY
,
5296 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n",
5297 ctlMode
, numCtlModes
, isHt40CtlMode
,
5298 (pCtlMode
[ctlMode
] & EXT_ADDITIVE
));
5300 /* walk through each CTL index stored in EEPROM */
5302 ctlIndex
= pEepData
->ctlIndex_2G
;
5303 ctlNum
= AR9300_NUM_CTLS_2G
;
5305 ctlIndex
= pEepData
->ctlIndex_5G
;
5306 ctlNum
= AR9300_NUM_CTLS_5G
;
5309 twiceMaxEdgePower
= MAX_RATE_POWER
;
5310 for (i
= 0; (i
< ctlNum
) && ctlIndex
[i
]; i
++) {
5311 ath_dbg(common
, REGULATORY
,
5312 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n",
5313 i
, cfgCtl
, pCtlMode
[ctlMode
], ctlIndex
[i
],
5317 * compare test group from regulatory
5318 * channel list with test mode from pCtlMode
5321 if ((((cfgCtl
& ~CTL_MODE_M
) |
5322 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
5324 (((cfgCtl
& ~CTL_MODE_M
) |
5325 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
5326 ((ctlIndex
[i
] & CTL_MODE_M
) |
5329 ar9003_hw_get_max_edge_power(pEepData
,
5333 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
)
5335 * Find the minimum of all CTL
5336 * edge powers that apply to
5340 min(twiceMaxEdgePower
,
5344 twiceMaxEdgePower
= twiceMinEdgePower
;
5350 minCtlPower
= (u8
)min(twiceMaxEdgePower
, scaledPower
);
5352 ath_dbg(common
, REGULATORY
,
5353 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n",
5354 ctlMode
, pCtlMode
[ctlMode
], twiceMaxEdgePower
,
5355 scaledPower
, minCtlPower
);
5357 /* Apply ctl mode to correct target power set */
5358 switch (pCtlMode
[ctlMode
]) {
5360 for (i
= ALL_TARGET_LEGACY_1L_5L
;
5361 i
<= ALL_TARGET_LEGACY_11S
; i
++)
5362 pPwrArray
[i
] = (u8
)min((u16
)pPwrArray
[i
],
5367 for (i
= ALL_TARGET_LEGACY_6_24
;
5368 i
<= ALL_TARGET_LEGACY_54
; i
++)
5369 pPwrArray
[i
] = (u8
)min((u16
)pPwrArray
[i
],
5374 for (i
= ALL_TARGET_HT20_0_8_16
;
5375 i
<= ALL_TARGET_HT20_23
; i
++) {
5376 pPwrArray
[i
] = (u8
)min((u16
)pPwrArray
[i
],
5378 if (ath9k_hw_mci_is_enabled(ah
))
5380 (u8
)min((u16
)pPwrArray
[i
],
5381 ar9003_mci_get_max_txpower(ah
,
5382 pCtlMode
[ctlMode
]));
5387 for (i
= ALL_TARGET_HT40_0_8_16
;
5388 i
<= ALL_TARGET_HT40_23
; i
++) {
5389 pPwrArray
[i
] = (u8
)min((u16
)pPwrArray
[i
],
5391 if (ath9k_hw_mci_is_enabled(ah
))
5393 (u8
)min((u16
)pPwrArray
[i
],
5394 ar9003_mci_get_max_txpower(ah
,
5395 pCtlMode
[ctlMode
]));
5401 } /* end ctl mode checking */
5404 static inline u8
mcsidx_to_tgtpwridx(unsigned int mcs_idx
, u8 base_pwridx
)
5406 u8 mod_idx
= mcs_idx
% 8;
5409 return mod_idx
? (base_pwridx
+ 1) : base_pwridx
;
5411 return base_pwridx
+ 4 * (mcs_idx
/ 8) + mod_idx
- 2;
5414 static void ar9003_paprd_set_txpower(struct ath_hw
*ah
,
5415 struct ath9k_channel
*chan
,
5416 u8
*targetPowerValT2
)
5420 if (!ar9003_is_paprd_enabled(ah
))
5423 if (IS_CHAN_HT40(chan
))
5424 i
= ALL_TARGET_HT40_7
;
5426 i
= ALL_TARGET_HT20_7
;
5428 if (IS_CHAN_2GHZ(chan
)) {
5429 if (!AR_SREV_9330(ah
) && !AR_SREV_9340(ah
) &&
5430 !AR_SREV_9462(ah
) && !AR_SREV_9565(ah
)) {
5431 if (IS_CHAN_HT40(chan
))
5432 i
= ALL_TARGET_HT40_0_8_16
;
5434 i
= ALL_TARGET_HT20_0_8_16
;
5438 ah
->paprd_target_power
= targetPowerValT2
[i
];
5441 static void ath9k_hw_ar9300_set_txpower(struct ath_hw
*ah
,
5442 struct ath9k_channel
*chan
, u16 cfgCtl
,
5443 u8 twiceAntennaReduction
,
5444 u8 powerLimit
, bool test
)
5446 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
5447 struct ath_common
*common
= ath9k_hw_common(ah
);
5448 u8 targetPowerValT2
[ar9300RateSize
];
5449 u8 target_power_val_t2_eep
[ar9300RateSize
];
5450 u8 targetPowerValT2_tpc
[ar9300RateSize
];
5451 unsigned int i
= 0, paprd_scale_factor
= 0;
5452 u8 pwr_idx
, min_pwridx
= 0;
5454 memset(targetPowerValT2
, 0 , sizeof(targetPowerValT2
));
5457 * Get target powers from EEPROM - our baseline for TX Power
5459 ar9003_hw_get_target_power_eeprom(ah
, chan
, targetPowerValT2
);
5461 if (ar9003_is_paprd_enabled(ah
)) {
5462 ah
->paprd_ratemask
=
5463 ar9003_get_paprd_rate_mask_ht20(ah
, IS_CHAN_2GHZ(chan
)) &
5464 AR9300_PAPRD_RATE_MASK
;
5466 ah
->paprd_ratemask_ht40
=
5467 ar9003_get_paprd_rate_mask_ht40(ah
, IS_CHAN_2GHZ(chan
)) &
5468 AR9300_PAPRD_RATE_MASK
;
5470 paprd_scale_factor
= ar9003_get_paprd_scale_factor(ah
, chan
);
5471 min_pwridx
= IS_CHAN_HT40(chan
) ? ALL_TARGET_HT40_0_8_16
:
5472 ALL_TARGET_HT20_0_8_16
;
5474 if (!ah
->paprd_table_write_done
) {
5475 memcpy(target_power_val_t2_eep
, targetPowerValT2
,
5476 sizeof(targetPowerValT2
));
5477 for (i
= 0; i
< 24; i
++) {
5478 pwr_idx
= mcsidx_to_tgtpwridx(i
, min_pwridx
);
5479 if (ah
->paprd_ratemask
& (1 << i
)) {
5480 if (targetPowerValT2
[pwr_idx
] &&
5481 targetPowerValT2
[pwr_idx
] ==
5482 target_power_val_t2_eep
[pwr_idx
])
5483 targetPowerValT2
[pwr_idx
] -=
5488 memcpy(target_power_val_t2_eep
, targetPowerValT2
,
5489 sizeof(targetPowerValT2
));
5492 ar9003_hw_set_power_per_rate_table(ah
, chan
,
5493 targetPowerValT2
, cfgCtl
,
5494 twiceAntennaReduction
,
5497 memcpy(targetPowerValT2_tpc
, targetPowerValT2
,
5498 sizeof(targetPowerValT2
));
5500 if (ar9003_is_paprd_enabled(ah
)) {
5501 for (i
= 0; i
< ar9300RateSize
; i
++) {
5502 if ((ah
->paprd_ratemask
& (1 << i
)) &&
5503 (abs(targetPowerValT2
[i
] -
5504 target_power_val_t2_eep
[i
]) >
5505 paprd_scale_factor
)) {
5506 ah
->paprd_ratemask
&= ~(1 << i
);
5507 ath_dbg(common
, EEPROM
,
5508 "paprd disabled for mcs %d\n", i
);
5513 regulatory
->max_power_level
= 0;
5514 for (i
= 0; i
< ar9300RateSize
; i
++) {
5515 if (targetPowerValT2
[i
] > regulatory
->max_power_level
)
5516 regulatory
->max_power_level
= targetPowerValT2
[i
];
5519 ath9k_hw_update_regulatory_maxpower(ah
);
5524 for (i
= 0; i
< ar9300RateSize
; i
++) {
5525 ath_dbg(common
, REGULATORY
, "TPC[%02d] 0x%08x\n",
5526 i
, targetPowerValT2
[i
]);
5529 /* Write target power array to registers */
5530 ar9003_hw_tx_power_regwrite(ah
, targetPowerValT2
);
5531 ar9003_hw_calibration_apply(ah
, chan
->channel
);
5532 ar9003_paprd_set_txpower(ah
, chan
, targetPowerValT2
);
5534 ar9003_hw_selfgen_tpc_txpower(ah
, chan
, targetPowerValT2
);
5536 /* TPC initializations */
5537 if (ah
->tpc_enabled
) {
5540 ar9003_hw_init_rate_txpower(ah
, targetPowerValT2_tpc
, chan
);
5543 REG_WRITE(ah
, AR_PHY_PWRTX_MAX
,
5544 AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE
);
5545 /* Disable per chain power reduction */
5546 val
= REG_READ(ah
, AR_PHY_POWER_TX_SUB
);
5547 if (AR_SREV_9340(ah
))
5548 REG_WRITE(ah
, AR_PHY_POWER_TX_SUB
,
5551 REG_WRITE(ah
, AR_PHY_POWER_TX_SUB
,
5555 REG_WRITE(ah
, AR_PHY_PWRTX_MAX
, 0);
5559 static u16
ath9k_hw_ar9300_get_spur_channel(struct ath_hw
*ah
,
5565 s32
ar9003_hw_get_tx_gain_idx(struct ath_hw
*ah
)
5567 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
5569 return (eep
->baseEepHeader
.txrxgain
>> 4) & 0xf; /* bits 7:4 */
5572 s32
ar9003_hw_get_rx_gain_idx(struct ath_hw
*ah
)
5574 struct ar9300_eeprom
*eep
= &ah
->eeprom
.ar9300_eep
;
5576 return (eep
->baseEepHeader
.txrxgain
) & 0xf; /* bits 3:0 */
5579 u8
*ar9003_get_spur_chan_ptr(struct ath_hw
*ah
, bool is2ghz
)
5581 return ar9003_modal_header(ah
, is2ghz
)->spurChans
;
5584 u32
ar9003_get_paprd_rate_mask_ht20(struct ath_hw
*ah
, bool is2ghz
)
5586 return le32_to_cpu(ar9003_modal_header(ah
, is2ghz
)->papdRateMaskHt20
);
5589 u32
ar9003_get_paprd_rate_mask_ht40(struct ath_hw
*ah
, bool is2ghz
)
5591 return le32_to_cpu(ar9003_modal_header(ah
, is2ghz
)->papdRateMaskHt40
);
5594 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw
*ah
,
5595 struct ath9k_channel
*chan
)
5597 bool is2ghz
= IS_CHAN_2GHZ(chan
);
5600 return MS(ar9003_get_paprd_rate_mask_ht20(ah
, is2ghz
),
5601 AR9300_PAPRD_SCALE_1
);
5603 if (chan
->channel
>= 5700)
5604 return MS(ar9003_get_paprd_rate_mask_ht20(ah
, is2ghz
),
5605 AR9300_PAPRD_SCALE_1
);
5606 else if (chan
->channel
>= 5400)
5607 return MS(ar9003_get_paprd_rate_mask_ht40(ah
, is2ghz
),
5608 AR9300_PAPRD_SCALE_2
);
5610 return MS(ar9003_get_paprd_rate_mask_ht40(ah
, is2ghz
),
5611 AR9300_PAPRD_SCALE_1
);
5615 static u8
ar9003_get_eepmisc(struct ath_hw
*ah
)
5617 return ah
->eeprom
.ar9300_eep
.baseEepHeader
.opCapFlags
.eepMisc
;
5620 const struct eeprom_ops eep_ar9300_ops
= {
5621 .check_eeprom
= ath9k_hw_ar9300_check_eeprom
,
5622 .get_eeprom
= ath9k_hw_ar9300_get_eeprom
,
5623 .fill_eeprom
= ath9k_hw_ar9300_fill_eeprom
,
5624 .dump_eeprom
= ath9k_hw_ar9003_dump_eeprom
,
5625 .get_eeprom_ver
= ath9k_hw_ar9300_get_eeprom_ver
,
5626 .get_eeprom_rev
= ath9k_hw_ar9300_get_eeprom_rev
,
5627 .set_board_values
= ath9k_hw_ar9300_set_board_values
,
5628 .set_addac
= ath9k_hw_ar9300_set_addac
,
5629 .set_txpower
= ath9k_hw_ar9300_set_txpower
,
5630 .get_spur_channel
= ath9k_hw_ar9300_get_spur_channel
,
5631 .get_eepmisc
= ar9003_get_eepmisc