2 * Copyright (c) 2008-2009 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.
19 static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw
*ah
)
21 return ((ah
->eeprom
.map4k
.baseEepHeader
.version
>> 12) & 0xF);
24 static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw
*ah
)
26 return ((ah
->eeprom
.map4k
.baseEepHeader
.version
) & 0xFFF);
29 static bool ath9k_hw_4k_fill_eeprom(struct ath_hw
*ah
)
31 #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
32 u16
*eep_data
= (u16
*)&ah
->eeprom
.map4k
;
33 int addr
, eep_start_loc
= 0;
37 if (!ath9k_hw_use_flash(ah
)) {
38 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
39 "Reading from EEPROM, not flash\n");
42 for (addr
= 0; addr
< SIZE_EEPROM_4K
; addr
++) {
43 if (!ath9k_hw_nvram_read(ah
, addr
+ eep_start_loc
, eep_data
)) {
44 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
45 "Unable to read eeprom region \n");
55 static int ath9k_hw_4k_check_eeprom(struct ath_hw
*ah
)
57 #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
58 struct ar5416_eeprom_4k
*eep
=
59 (struct ar5416_eeprom_4k
*) &ah
->eeprom
.map4k
;
60 u16
*eepdata
, temp
, magic
, magic2
;
62 bool need_swap
= false;
66 if (!ath9k_hw_use_flash(ah
)) {
67 if (!ath9k_hw_nvram_read(ah
, AR5416_EEPROM_MAGIC_OFFSET
,
69 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
70 "Reading Magic # failed\n");
74 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
75 "Read Magic = 0x%04X\n", magic
);
77 if (magic
!= AR5416_EEPROM_MAGIC
) {
78 magic2
= swab16(magic
);
80 if (magic2
== AR5416_EEPROM_MAGIC
) {
82 eepdata
= (u16
*) (&ah
->eeprom
);
84 for (addr
= 0; addr
< EEPROM_4K_SIZE
; addr
++) {
85 temp
= swab16(*eepdata
);
90 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
91 "Invalid EEPROM Magic. "
92 "endianness mismatch.\n");
98 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
, "need_swap = %s.\n",
99 need_swap
? "True" : "False");
102 el
= swab16(ah
->eeprom
.map4k
.baseEepHeader
.length
);
104 el
= ah
->eeprom
.map4k
.baseEepHeader
.length
;
106 if (el
> sizeof(struct ar5416_eeprom_4k
))
107 el
= sizeof(struct ar5416_eeprom_4k
) / sizeof(u16
);
109 el
= el
/ sizeof(u16
);
111 eepdata
= (u16
*)(&ah
->eeprom
);
113 for (i
= 0; i
< el
; i
++)
120 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
121 "EEPROM Endianness is not native.. Changing\n");
123 word
= swab16(eep
->baseEepHeader
.length
);
124 eep
->baseEepHeader
.length
= word
;
126 word
= swab16(eep
->baseEepHeader
.checksum
);
127 eep
->baseEepHeader
.checksum
= word
;
129 word
= swab16(eep
->baseEepHeader
.version
);
130 eep
->baseEepHeader
.version
= word
;
132 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
133 eep
->baseEepHeader
.regDmn
[0] = word
;
135 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
136 eep
->baseEepHeader
.regDmn
[1] = word
;
138 word
= swab16(eep
->baseEepHeader
.rfSilent
);
139 eep
->baseEepHeader
.rfSilent
= word
;
141 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
142 eep
->baseEepHeader
.blueToothOptions
= word
;
144 word
= swab16(eep
->baseEepHeader
.deviceCap
);
145 eep
->baseEepHeader
.deviceCap
= word
;
147 integer
= swab32(eep
->modalHeader
.antCtrlCommon
);
148 eep
->modalHeader
.antCtrlCommon
= integer
;
150 for (i
= 0; i
< AR5416_EEP4K_MAX_CHAINS
; i
++) {
151 integer
= swab32(eep
->modalHeader
.antCtrlChain
[i
]);
152 eep
->modalHeader
.antCtrlChain
[i
] = integer
;
155 for (i
= 0; i
< AR5416_EEPROM_MODAL_SPURS
; i
++) {
156 word
= swab16(eep
->modalHeader
.spurChans
[i
].spurChan
);
157 eep
->modalHeader
.spurChans
[i
].spurChan
= word
;
161 if (sum
!= 0xffff || ah
->eep_ops
->get_eeprom_ver(ah
) != AR5416_EEP_VER
||
162 ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_NO_BACK_VER
) {
163 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
164 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
165 sum
, ah
->eep_ops
->get_eeprom_ver(ah
));
170 #undef EEPROM_4K_SIZE
173 static u32
ath9k_hw_4k_get_eeprom(struct ath_hw
*ah
,
174 enum eeprom_param param
)
176 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
177 struct modal_eep_4k_header
*pModal
= &eep
->modalHeader
;
178 struct base_eep_header_4k
*pBase
= &eep
->baseEepHeader
;
182 return pModal
->noiseFloorThreshCh
[0];
183 case AR_EEPROM_MAC(0):
184 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
185 case AR_EEPROM_MAC(1):
186 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
187 case AR_EEPROM_MAC(2):
188 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
190 return pBase
->regDmn
[0];
192 return pBase
->regDmn
[1];
194 return pBase
->deviceCap
;
196 return pBase
->opCapFlags
;
198 return pBase
->rfSilent
;
202 return pModal
->db1_1
;
204 return pBase
->version
& AR5416_EEP_VER_MINOR_MASK
;
206 return pBase
->txMask
;
208 return pBase
->rxMask
;
216 static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw
*ah
,
217 struct ath9k_channel
*chan
,
218 struct cal_data_per_freq_4k
*pRawDataSet
,
219 u8
*bChans
, u16 availPiers
,
220 u16 tPdGainOverlap
, int16_t *pMinCalPower
,
221 u16
*pPdGainBoundaries
, u8
*pPDADCValues
,
224 #define TMP_VAL_VPD_TABLE \
225 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
228 u16 idxL
= 0, idxR
= 0, numPiers
;
229 static u8 vpdTableL
[AR5416_EEP4K_NUM_PD_GAINS
]
230 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
231 static u8 vpdTableR
[AR5416_EEP4K_NUM_PD_GAINS
]
232 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
233 static u8 vpdTableI
[AR5416_EEP4K_NUM_PD_GAINS
]
234 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
236 u8
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
237 u8 minPwrT4
[AR5416_EEP4K_NUM_PD_GAINS
];
238 u8 maxPwrT4
[AR5416_EEP4K_NUM_PD_GAINS
];
241 u16 sizeCurrVpdTable
, maxIndex
, tgtIndex
;
243 int16_t minDelta
= 0;
244 struct chan_centers centers
;
245 #define PD_GAIN_BOUNDARY_DEFAULT 58;
247 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
249 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
250 if (bChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
254 match
= ath9k_hw_get_lower_upper_index(
255 (u8
)FREQ2FBIN(centers
.synth_center
,
256 IS_CHAN_2GHZ(chan
)), bChans
, numPiers
,
260 for (i
= 0; i
< numXpdGains
; i
++) {
261 minPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][0];
262 maxPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][4];
263 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
264 pRawDataSet
[idxL
].pwrPdg
[i
],
265 pRawDataSet
[idxL
].vpdPdg
[i
],
266 AR5416_EEP4K_PD_GAIN_ICEPTS
,
270 for (i
= 0; i
< numXpdGains
; i
++) {
271 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
272 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
273 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
274 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
276 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
279 min(pPwrL
[AR5416_EEP4K_PD_GAIN_ICEPTS
- 1],
280 pPwrR
[AR5416_EEP4K_PD_GAIN_ICEPTS
- 1]);
283 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
285 AR5416_EEP4K_PD_GAIN_ICEPTS
,
287 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
289 AR5416_EEP4K_PD_GAIN_ICEPTS
,
292 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
294 (u8
)(ath9k_hw_interpolate((u16
)
299 bChans
[idxL
], bChans
[idxR
],
300 vpdTableL
[i
][j
], vpdTableR
[i
][j
]));
305 *pMinCalPower
= (int16_t)(minPwrT4
[0] / 2);
309 for (i
= 0; i
< numXpdGains
; i
++) {
310 if (i
== (numXpdGains
- 1))
311 pPdGainBoundaries
[i
] =
312 (u16
)(maxPwrT4
[i
] / 2);
314 pPdGainBoundaries
[i
] =
315 (u16
)((maxPwrT4
[i
] + minPwrT4
[i
+ 1]) / 4);
317 pPdGainBoundaries
[i
] =
318 min((u16
)AR5416_MAX_RATE_POWER
, pPdGainBoundaries
[i
]);
320 if ((i
== 0) && !AR_SREV_5416_20_OR_LATER(ah
)) {
321 minDelta
= pPdGainBoundaries
[0] - 23;
322 pPdGainBoundaries
[0] = 23;
328 if (AR_SREV_9280_10_OR_LATER(ah
))
329 ss
= (int16_t)(0 - (minPwrT4
[i
] / 2));
333 ss
= (int16_t)((pPdGainBoundaries
[i
- 1] -
335 tPdGainOverlap
+ 1 + minDelta
);
337 vpdStep
= (int16_t)(vpdTableI
[i
][1] - vpdTableI
[i
][0]);
338 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
340 while ((ss
< 0) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
341 tmpVal
= (int16_t)(vpdTableI
[i
][0] + ss
* vpdStep
);
342 pPDADCValues
[k
++] = (u8
)((tmpVal
< 0) ? 0 : tmpVal
);
346 sizeCurrVpdTable
= (u8
) ((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
347 tgtIndex
= (u8
)(pPdGainBoundaries
[i
] + tPdGainOverlap
-
349 maxIndex
= (tgtIndex
< sizeCurrVpdTable
) ?
350 tgtIndex
: sizeCurrVpdTable
;
352 while ((ss
< maxIndex
) && (k
< (AR5416_NUM_PDADC_VALUES
- 1)))
353 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
355 vpdStep
= (int16_t)(vpdTableI
[i
][sizeCurrVpdTable
- 1] -
356 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
357 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
359 if (tgtIndex
>= maxIndex
) {
360 while ((ss
<= tgtIndex
) &&
361 (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
362 tmpVal
= (int16_t) TMP_VAL_VPD_TABLE
;
363 pPDADCValues
[k
++] = (u8
)((tmpVal
> 255) ?
370 while (i
< AR5416_EEP4K_PD_GAINS_IN_MASK
) {
371 pPdGainBoundaries
[i
] = PD_GAIN_BOUNDARY_DEFAULT
;
375 while (k
< AR5416_NUM_PDADC_VALUES
) {
376 pPDADCValues
[k
] = pPDADCValues
[k
- 1];
381 #undef TMP_VAL_VPD_TABLE
384 static void ath9k_hw_set_4k_power_cal_table(struct ath_hw
*ah
,
385 struct ath9k_channel
*chan
,
386 int16_t *pTxPowerIndexOffset
)
388 struct ar5416_eeprom_4k
*pEepData
= &ah
->eeprom
.map4k
;
389 struct cal_data_per_freq_4k
*pRawDataset
;
390 u8
*pCalBChans
= NULL
;
391 u16 pdGainOverlap_t2
;
392 static u8 pdadcValues
[AR5416_NUM_PDADC_VALUES
];
393 u16 gainBoundaries
[AR5416_EEP4K_PD_GAINS_IN_MASK
];
395 int16_t tMinCalPower
;
396 u16 numXpdGain
, xpdMask
;
397 u16 xpdGainValues
[AR5416_EEP4K_NUM_PD_GAINS
] = { 0, 0 };
398 u32 reg32
, regOffset
, regChainOffset
;
400 xpdMask
= pEepData
->modalHeader
.xpdGain
;
402 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
403 AR5416_EEP_MINOR_VER_2
) {
405 pEepData
->modalHeader
.pdGainOverlap
;
407 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
408 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
411 pCalBChans
= pEepData
->calFreqPier2G
;
412 numPiers
= AR5416_EEP4K_NUM_2G_CAL_PIERS
;
416 for (i
= 1; i
<= AR5416_EEP4K_PD_GAINS_IN_MASK
; i
++) {
417 if ((xpdMask
>> (AR5416_EEP4K_PD_GAINS_IN_MASK
- i
)) & 1) {
418 if (numXpdGain
>= AR5416_EEP4K_NUM_PD_GAINS
)
420 xpdGainValues
[numXpdGain
] =
421 (u16
)(AR5416_EEP4K_PD_GAINS_IN_MASK
- i
);
426 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
427 (numXpdGain
- 1) & 0x3);
428 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
430 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
432 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
, 0);
434 for (i
= 0; i
< AR5416_EEP4K_MAX_CHAINS
; i
++) {
435 if (AR_SREV_5416_20_OR_LATER(ah
) &&
436 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) &&
438 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
440 regChainOffset
= i
* 0x1000;
442 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
443 pRawDataset
= pEepData
->calPierData2G
[i
];
445 ath9k_hw_get_4k_gain_boundaries_pdadcs(ah
, chan
,
446 pRawDataset
, pCalBChans
,
447 numPiers
, pdGainOverlap_t2
,
448 &tMinCalPower
, gainBoundaries
,
449 pdadcValues
, numXpdGain
);
451 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
)) {
452 REG_WRITE(ah
, AR_PHY_TPCRG5
+ regChainOffset
,
454 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)
455 | SM(gainBoundaries
[0],
456 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1
)
457 | SM(gainBoundaries
[1],
458 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2
)
459 | SM(gainBoundaries
[2],
460 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3
)
461 | SM(gainBoundaries
[3],
462 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4
));
465 regOffset
= AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
466 for (j
= 0; j
< 32; j
++) {
467 reg32
= ((pdadcValues
[4 * j
+ 0] & 0xFF) << 0) |
468 ((pdadcValues
[4 * j
+ 1] & 0xFF) << 8) |
469 ((pdadcValues
[4 * j
+ 2] & 0xFF) << 16)|
470 ((pdadcValues
[4 * j
+ 3] & 0xFF) << 24);
471 REG_WRITE(ah
, regOffset
, reg32
);
473 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
474 "PDADC (%d,%4x): %4.4x %8.8x\n",
475 i
, regChainOffset
, regOffset
,
477 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
479 "PDADC %3d Value %3d | "
480 "PDADC %3d Value %3d | "
481 "PDADC %3d Value %3d | "
482 "PDADC %3d Value %3d |\n",
483 i
, 4 * j
, pdadcValues
[4 * j
],
484 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
485 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
487 pdadcValues
[4 * j
+ 3]);
494 *pTxPowerIndexOffset
= 0;
497 static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw
*ah
,
498 struct ath9k_channel
*chan
,
501 u16 AntennaReduction
,
502 u16 twiceMaxRegulatoryPower
,
505 #define CMP_TEST_GRP \
506 (((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) == \
507 pEepData->ctlIndex[i]) \
508 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
509 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
511 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
513 int16_t twiceLargestAntenna
;
514 u16 twiceMinEdgePower
;
515 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
516 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
517 u16 numCtlModes
, *pCtlMode
, ctlMode
, freq
;
518 struct chan_centers centers
;
519 struct cal_ctl_data_4k
*rep
;
520 struct ar5416_eeprom_4k
*pEepData
= &ah
->eeprom
.map4k
;
521 static const u16 tpScaleReductionTable
[5] =
522 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
523 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
526 struct cal_target_power_leg targetPowerOfdmExt
= {
527 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
530 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
533 u16 ctlModesFor11g
[] =
534 { CTL_11B
, CTL_11G
, CTL_2GHT20
, CTL_11B_EXT
, CTL_11G_EXT
,
538 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
540 twiceLargestAntenna
= pEepData
->modalHeader
.antennaGainCh
[0];
541 twiceLargestAntenna
= (int16_t)min(AntennaReduction
-
542 twiceLargestAntenna
, 0);
544 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
545 if (regulatory
->tp_scale
!= ATH9K_TP_SCALE_MAX
) {
546 maxRegAllowedPower
-=
547 (tpScaleReductionTable
[(regulatory
->tp_scale
)] * 2);
550 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
551 scaledPower
= max((u16
)0, scaledPower
);
553 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
) - SUB_NUM_CTL_MODES_AT_2G_40
;
554 pCtlMode
= ctlModesFor11g
;
556 ath9k_hw_get_legacy_target_powers(ah
, chan
,
557 pEepData
->calTargetPowerCck
,
558 AR5416_NUM_2G_CCK_TARGET_POWERS
,
559 &targetPowerCck
, 4, false);
560 ath9k_hw_get_legacy_target_powers(ah
, chan
,
561 pEepData
->calTargetPower2G
,
562 AR5416_NUM_2G_20_TARGET_POWERS
,
563 &targetPowerOfdm
, 4, false);
564 ath9k_hw_get_target_powers(ah
, chan
,
565 pEepData
->calTargetPower2GHT20
,
566 AR5416_NUM_2G_20_TARGET_POWERS
,
567 &targetPowerHt20
, 8, false);
569 if (IS_CHAN_HT40(chan
)) {
570 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
571 ath9k_hw_get_target_powers(ah
, chan
,
572 pEepData
->calTargetPower2GHT40
,
573 AR5416_NUM_2G_40_TARGET_POWERS
,
574 &targetPowerHt40
, 8, true);
575 ath9k_hw_get_legacy_target_powers(ah
, chan
,
576 pEepData
->calTargetPowerCck
,
577 AR5416_NUM_2G_CCK_TARGET_POWERS
,
578 &targetPowerCckExt
, 4, true);
579 ath9k_hw_get_legacy_target_powers(ah
, chan
,
580 pEepData
->calTargetPower2G
,
581 AR5416_NUM_2G_20_TARGET_POWERS
,
582 &targetPowerOfdmExt
, 4, true);
585 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
586 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
587 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
590 freq
= centers
.synth_center
;
591 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
592 freq
= centers
.ext_center
;
594 freq
= centers
.ctl_center
;
596 if (ah
->eep_ops
->get_eeprom_ver(ah
) == 14 &&
597 ah
->eep_ops
->get_eeprom_rev(ah
) <= 2)
598 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
600 for (i
= 0; (i
< AR5416_EEP4K_NUM_CTLS
) &&
601 pEepData
->ctlIndex
[i
]; i
++) {
604 rep
= &(pEepData
->ctlData
[i
]);
606 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(
609 ar5416_get_ntxchains(ah
->txchainmask
) - 1],
611 AR5416_EEP4K_NUM_BAND_EDGES
);
613 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
615 min(twiceMaxEdgePower
,
618 twiceMaxEdgePower
= twiceMinEdgePower
;
624 minCtlPower
= (u8
)min(twiceMaxEdgePower
, scaledPower
);
626 switch (pCtlMode
[ctlMode
]) {
628 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
); i
++) {
629 targetPowerCck
.tPow2x
[i
] =
630 min((u16
)targetPowerCck
.tPow2x
[i
],
635 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
); i
++) {
636 targetPowerOfdm
.tPow2x
[i
] =
637 min((u16
)targetPowerOfdm
.tPow2x
[i
],
642 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++) {
643 targetPowerHt20
.tPow2x
[i
] =
644 min((u16
)targetPowerHt20
.tPow2x
[i
],
649 targetPowerCckExt
.tPow2x
[0] =
650 min((u16
)targetPowerCckExt
.tPow2x
[0],
654 targetPowerOfdmExt
.tPow2x
[0] =
655 min((u16
)targetPowerOfdmExt
.tPow2x
[0],
659 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
660 targetPowerHt40
.tPow2x
[i
] =
661 min((u16
)targetPowerHt40
.tPow2x
[i
],
670 ratesArray
[rate6mb
] =
671 ratesArray
[rate9mb
] =
672 ratesArray
[rate12mb
] =
673 ratesArray
[rate18mb
] =
674 ratesArray
[rate24mb
] =
675 targetPowerOfdm
.tPow2x
[0];
677 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
678 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
679 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
680 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
682 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
683 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
685 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
686 ratesArray
[rate2s
] = ratesArray
[rate2l
] = targetPowerCck
.tPow2x
[1];
687 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] = targetPowerCck
.tPow2x
[2];
688 ratesArray
[rate11s
] = ratesArray
[rate11l
] = targetPowerCck
.tPow2x
[3];
690 if (IS_CHAN_HT40(chan
)) {
691 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
692 ratesArray
[rateHt40_0
+ i
] =
693 targetPowerHt40
.tPow2x
[i
];
695 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
696 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
697 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
698 ratesArray
[rateExtCck
] = targetPowerCckExt
.tPow2x
[0];
704 static void ath9k_hw_4k_set_txpower(struct ath_hw
*ah
,
705 struct ath9k_channel
*chan
,
707 u8 twiceAntennaReduction
,
708 u8 twiceMaxRegulatoryPower
,
711 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
712 struct ar5416_eeprom_4k
*pEepData
= &ah
->eeprom
.map4k
;
713 struct modal_eep_4k_header
*pModal
= &pEepData
->modalHeader
;
714 int16_t ratesArray
[Ar5416RateSize
];
715 int16_t txPowerIndexOffset
= 0;
716 u8 ht40PowerIncForPdadc
= 2;
719 memset(ratesArray
, 0, sizeof(ratesArray
));
721 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
722 AR5416_EEP_MINOR_VER_2
) {
723 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
726 ath9k_hw_set_4k_power_per_rate_table(ah
, chan
,
727 &ratesArray
[0], cfgCtl
,
728 twiceAntennaReduction
,
729 twiceMaxRegulatoryPower
,
732 ath9k_hw_set_4k_power_cal_table(ah
, chan
, &txPowerIndexOffset
);
734 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
735 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
736 if (ratesArray
[i
] > AR5416_MAX_RATE_POWER
)
737 ratesArray
[i
] = AR5416_MAX_RATE_POWER
;
741 /* Update regulatory */
744 if (IS_CHAN_HT40(chan
))
746 else if (IS_CHAN_HT20(chan
))
749 regulatory
->max_power_level
= ratesArray
[i
];
751 if (AR_SREV_9280_10_OR_LATER(ah
)) {
752 for (i
= 0; i
< Ar5416RateSize
; i
++)
753 ratesArray
[i
] -= AR5416_PWR_TABLE_OFFSET
* 2;
756 /* OFDM power per rate */
757 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
758 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
759 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
760 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
761 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
762 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
763 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
764 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
765 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
766 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
768 /* CCK power per rate */
769 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
770 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
771 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
772 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
773 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
774 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
775 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
776 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
777 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
778 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
780 /* HT20 power per rate */
781 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
782 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
783 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
784 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
785 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
786 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
787 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
788 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
789 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
790 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
792 /* HT40 power per rate */
793 if (IS_CHAN_HT40(chan
)) {
794 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
795 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
796 ht40PowerIncForPdadc
, 24)
797 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
798 ht40PowerIncForPdadc
, 16)
799 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
800 ht40PowerIncForPdadc
, 8)
801 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
802 ht40PowerIncForPdadc
, 0));
803 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
804 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
805 ht40PowerIncForPdadc
, 24)
806 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
807 ht40PowerIncForPdadc
, 16)
808 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
809 ht40PowerIncForPdadc
, 8)
810 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
811 ht40PowerIncForPdadc
, 0));
812 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
813 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
814 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
815 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
816 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
820 static void ath9k_hw_4k_set_addac(struct ath_hw
*ah
,
821 struct ath9k_channel
*chan
)
823 struct modal_eep_4k_header
*pModal
;
824 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
827 if (ah
->hw_version
.macVersion
!= AR_SREV_VERSION_9160
)
830 if (ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_MINOR_VER_7
)
833 pModal
= &eep
->modalHeader
;
835 if (pModal
->xpaBiasLvl
!= 0xff) {
836 biaslevel
= pModal
->xpaBiasLvl
;
837 INI_RA(&ah
->iniAddac
, 7, 1) =
838 (INI_RA(&ah
->iniAddac
, 7, 1) & (~0x18)) | biaslevel
<< 3;
842 static void ath9k_hw_4k_set_gain(struct ath_hw
*ah
,
843 struct modal_eep_4k_header
*pModal
,
844 struct ar5416_eeprom_4k
*eep
,
847 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
,
848 pModal
->antCtrlChain
[0]);
850 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0),
851 (REG_READ(ah
, AR_PHY_TIMING_CTRL4(0)) &
852 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
853 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
854 SM(pModal
->iqCalICh
[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
855 SM(pModal
->iqCalQCh
[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
857 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
858 AR5416_EEP_MINOR_VER_3
) {
859 txRxAttenLocal
= pModal
->txRxAttenCh
[0];
861 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
862 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
, pModal
->bswMargin
[0]);
863 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
864 AR_PHY_GAIN_2GHZ_XATTEN1_DB
, pModal
->bswAtten
[0]);
865 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
866 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
867 pModal
->xatten2Margin
[0]);
868 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
869 AR_PHY_GAIN_2GHZ_XATTEN2_DB
, pModal
->xatten2Db
[0]);
871 /* Set the block 1 value to block 0 value */
872 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
873 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
874 pModal
->bswMargin
[0]);
875 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
876 AR_PHY_GAIN_2GHZ_XATTEN1_DB
, pModal
->bswAtten
[0]);
877 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
878 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
879 pModal
->xatten2Margin
[0]);
880 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
881 AR_PHY_GAIN_2GHZ_XATTEN2_DB
,
882 pModal
->xatten2Db
[0]);
885 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
,
886 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
887 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
,
888 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[0]);
890 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ 0x1000,
891 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
892 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ 0x1000,
893 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[0]);
895 if (AR_SREV_9285_11(ah
))
896 REG_WRITE(ah
, AR9285_AN_TOP4
, (AR9285_AN_TOP4_DEFAULT
| 0x14));
900 * Read EEPROM header info and program the device for correct operation
901 * given the channel value.
903 static void ath9k_hw_4k_set_board_values(struct ath_hw
*ah
,
904 struct ath9k_channel
*chan
)
906 struct modal_eep_4k_header
*pModal
;
907 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
909 u8 ob
[5], db1
[5], db2
[5];
910 u8 ant_div_control1
, ant_div_control2
;
913 pModal
= &eep
->modalHeader
;
916 REG_WRITE(ah
, AR_PHY_SWITCH_COM
,
917 ah
->eep_ops
->get_eeprom_antenna_cfg(ah
, chan
));
919 /* Single chain for 4K EEPROM*/
920 ath9k_hw_4k_set_gain(ah
, pModal
, eep
, txRxAttenLocal
);
922 /* Initialize Ant Diversity settings from EEPROM */
923 if (pModal
->version
>= 3) {
924 ant_div_control1
= pModal
->antdiv_ctl1
;
925 ant_div_control2
= pModal
->antdiv_ctl2
;
927 regVal
= REG_READ(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
);
928 regVal
&= (~(AR_PHY_9285_ANT_DIV_CTL_ALL
));
930 regVal
|= SM(ant_div_control1
,
931 AR_PHY_9285_ANT_DIV_CTL
);
932 regVal
|= SM(ant_div_control2
,
933 AR_PHY_9285_ANT_DIV_ALT_LNACONF
);
934 regVal
|= SM((ant_div_control2
>> 2),
935 AR_PHY_9285_ANT_DIV_MAIN_LNACONF
);
936 regVal
|= SM((ant_div_control1
>> 1),
937 AR_PHY_9285_ANT_DIV_ALT_GAINTB
);
938 regVal
|= SM((ant_div_control1
>> 2),
939 AR_PHY_9285_ANT_DIV_MAIN_GAINTB
);
942 REG_WRITE(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
, regVal
);
943 regVal
= REG_READ(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
);
944 regVal
= REG_READ(ah
, AR_PHY_CCK_DETECT
);
945 regVal
&= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV
);
946 regVal
|= SM((ant_div_control1
>> 3),
947 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV
);
949 REG_WRITE(ah
, AR_PHY_CCK_DETECT
, regVal
);
950 regVal
= REG_READ(ah
, AR_PHY_CCK_DETECT
);
953 if (pModal
->version
>= 2) {
954 ob
[0] = pModal
->ob_0
;
955 ob
[1] = pModal
->ob_1
;
956 ob
[2] = pModal
->ob_2
;
957 ob
[3] = pModal
->ob_3
;
958 ob
[4] = pModal
->ob_4
;
960 db1
[0] = pModal
->db1_0
;
961 db1
[1] = pModal
->db1_1
;
962 db1
[2] = pModal
->db1_2
;
963 db1
[3] = pModal
->db1_3
;
964 db1
[4] = pModal
->db1_4
;
966 db2
[0] = pModal
->db2_0
;
967 db2
[1] = pModal
->db2_1
;
968 db2
[2] = pModal
->db2_2
;
969 db2
[3] = pModal
->db2_3
;
970 db2
[4] = pModal
->db2_4
;
971 } else if (pModal
->version
== 1) {
972 ob
[0] = pModal
->ob_0
;
973 ob
[1] = ob
[2] = ob
[3] = ob
[4] = pModal
->ob_1
;
974 db1
[0] = pModal
->db1_0
;
975 db1
[1] = db1
[2] = db1
[3] = db1
[4] = pModal
->db1_1
;
976 db2
[0] = pModal
->db2_0
;
977 db2
[1] = db2
[2] = db2
[3] = db2
[4] = pModal
->db2_1
;
981 for (i
= 0; i
< 5; i
++) {
982 ob
[i
] = pModal
->ob_0
;
983 db1
[i
] = pModal
->db1_0
;
984 db2
[i
] = pModal
->db1_0
;
988 if (AR_SREV_9271(ah
)) {
989 ath9k_hw_analog_shift_rmw(ah
,
991 AR9271_AN_RF2G3_OB_cck
,
992 AR9271_AN_RF2G3_OB_cck_S
,
994 ath9k_hw_analog_shift_rmw(ah
,
996 AR9271_AN_RF2G3_OB_psk
,
997 AR9271_AN_RF2G3_OB_psk_S
,
999 ath9k_hw_analog_shift_rmw(ah
,
1001 AR9271_AN_RF2G3_OB_qam
,
1002 AR9271_AN_RF2G3_OB_qam_S
,
1004 ath9k_hw_analog_shift_rmw(ah
,
1006 AR9271_AN_RF2G3_DB_1
,
1007 AR9271_AN_RF2G3_DB_1_S
,
1009 ath9k_hw_analog_shift_rmw(ah
,
1011 AR9271_AN_RF2G4_DB_2
,
1012 AR9271_AN_RF2G4_DB_2_S
,
1015 ath9k_hw_analog_shift_rmw(ah
,
1017 AR9285_AN_RF2G3_OB_0
,
1018 AR9285_AN_RF2G3_OB_0_S
,
1020 ath9k_hw_analog_shift_rmw(ah
,
1022 AR9285_AN_RF2G3_OB_1
,
1023 AR9285_AN_RF2G3_OB_1_S
,
1025 ath9k_hw_analog_shift_rmw(ah
,
1027 AR9285_AN_RF2G3_OB_2
,
1028 AR9285_AN_RF2G3_OB_2_S
,
1030 ath9k_hw_analog_shift_rmw(ah
,
1032 AR9285_AN_RF2G3_OB_3
,
1033 AR9285_AN_RF2G3_OB_3_S
,
1035 ath9k_hw_analog_shift_rmw(ah
,
1037 AR9285_AN_RF2G3_OB_4
,
1038 AR9285_AN_RF2G3_OB_4_S
,
1041 ath9k_hw_analog_shift_rmw(ah
,
1043 AR9285_AN_RF2G3_DB1_0
,
1044 AR9285_AN_RF2G3_DB1_0_S
,
1046 ath9k_hw_analog_shift_rmw(ah
,
1048 AR9285_AN_RF2G3_DB1_1
,
1049 AR9285_AN_RF2G3_DB1_1_S
,
1051 ath9k_hw_analog_shift_rmw(ah
,
1053 AR9285_AN_RF2G3_DB1_2
,
1054 AR9285_AN_RF2G3_DB1_2_S
,
1056 ath9k_hw_analog_shift_rmw(ah
,
1058 AR9285_AN_RF2G4_DB1_3
,
1059 AR9285_AN_RF2G4_DB1_3_S
,
1061 ath9k_hw_analog_shift_rmw(ah
,
1063 AR9285_AN_RF2G4_DB1_4
,
1064 AR9285_AN_RF2G4_DB1_4_S
, db1
[4]);
1066 ath9k_hw_analog_shift_rmw(ah
,
1068 AR9285_AN_RF2G4_DB2_0
,
1069 AR9285_AN_RF2G4_DB2_0_S
,
1071 ath9k_hw_analog_shift_rmw(ah
,
1073 AR9285_AN_RF2G4_DB2_1
,
1074 AR9285_AN_RF2G4_DB2_1_S
,
1076 ath9k_hw_analog_shift_rmw(ah
,
1078 AR9285_AN_RF2G4_DB2_2
,
1079 AR9285_AN_RF2G4_DB2_2_S
,
1081 ath9k_hw_analog_shift_rmw(ah
,
1083 AR9285_AN_RF2G4_DB2_3
,
1084 AR9285_AN_RF2G4_DB2_3_S
,
1086 ath9k_hw_analog_shift_rmw(ah
,
1088 AR9285_AN_RF2G4_DB2_4
,
1089 AR9285_AN_RF2G4_DB2_4_S
,
1094 if (AR_SREV_9285_11(ah
))
1095 REG_WRITE(ah
, AR9285_AN_TOP4
, AR9285_AN_TOP4_DEFAULT
);
1097 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
, AR_PHY_SETTLING_SWITCH
,
1098 pModal
->switchSettling
);
1099 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
, AR_PHY_DESIRED_SZ_ADC
,
1100 pModal
->adcDesiredSize
);
1102 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
1103 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
) |
1104 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAB_OFF
) |
1105 SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAA_ON
) |
1106 SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
1108 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
1109 pModal
->txEndToRxOn
);
1110 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR9280_PHY_CCA_THRESH62
,
1112 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
, AR_PHY_EXT_CCA0_THRESH62
,
1115 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1116 AR5416_EEP_MINOR_VER_2
) {
1117 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_DATA_START
,
1118 pModal
->txFrameToDataStart
);
1119 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_PA_ON
,
1120 pModal
->txFrameToPaOn
);
1123 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1124 AR5416_EEP_MINOR_VER_3
) {
1125 if (IS_CHAN_HT40(chan
))
1126 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
1127 AR_PHY_SETTLING_SWITCH
,
1128 pModal
->swSettleHt40
);
1132 static u16
ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw
*ah
,
1133 struct ath9k_channel
*chan
)
1135 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
1136 struct modal_eep_4k_header
*pModal
= &eep
->modalHeader
;
1138 return pModal
->antCtrlCommon
& 0xFFFF;
1141 static u8
ath9k_hw_4k_get_num_ant_config(struct ath_hw
*ah
,
1142 enum ieee80211_band freq_band
)
1147 static u16
ath9k_hw_4k_get_spur_channel(struct ath_hw
*ah
, u16 i
, bool is2GHz
)
1149 #define EEP_MAP4K_SPURCHAN \
1150 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
1152 u16 spur_val
= AR_NO_SPUR
;
1154 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1155 "Getting spur idx %d is2Ghz. %d val %x\n",
1156 i
, is2GHz
, ah
->config
.spurchans
[i
][is2GHz
]);
1158 switch (ah
->config
.spurmode
) {
1161 case SPUR_ENABLE_IOCTL
:
1162 spur_val
= ah
->config
.spurchans
[i
][is2GHz
];
1163 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1164 "Getting spur val from new loc. %d\n", spur_val
);
1166 case SPUR_ENABLE_EEPROM
:
1167 spur_val
= EEP_MAP4K_SPURCHAN
;
1173 #undef EEP_MAP4K_SPURCHAN
1176 const struct eeprom_ops eep_4k_ops
= {
1177 .check_eeprom
= ath9k_hw_4k_check_eeprom
,
1178 .get_eeprom
= ath9k_hw_4k_get_eeprom
,
1179 .fill_eeprom
= ath9k_hw_4k_fill_eeprom
,
1180 .get_eeprom_ver
= ath9k_hw_4k_get_eeprom_ver
,
1181 .get_eeprom_rev
= ath9k_hw_4k_get_eeprom_rev
,
1182 .get_num_ant_config
= ath9k_hw_4k_get_num_ant_config
,
1183 .get_eeprom_antenna_cfg
= ath9k_hw_4k_get_eeprom_antenna_cfg
,
1184 .set_board_values
= ath9k_hw_4k_set_board_values
,
1185 .set_addac
= ath9k_hw_4k_set_addac
,
1186 .set_txpower
= ath9k_hw_4k_set_txpower
,
1187 .get_spur_channel
= ath9k_hw_4k_get_spur_channel