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 struct ath_common
*common
= ath9k_hw_common(ah
);
33 u16
*eep_data
= (u16
*)&ah
->eeprom
.map4k
;
34 int addr
, eep_start_loc
= 0;
38 if (!ath9k_hw_use_flash(ah
)) {
39 ath_print(common
, ATH_DBG_EEPROM
,
40 "Reading from EEPROM, not flash\n");
43 for (addr
= 0; addr
< SIZE_EEPROM_4K
; addr
++) {
44 if (!ath9k_hw_nvram_read(common
, addr
+ eep_start_loc
, eep_data
)) {
45 ath_print(common
, ATH_DBG_EEPROM
,
46 "Unable to read eeprom region \n");
56 static int ath9k_hw_4k_check_eeprom(struct ath_hw
*ah
)
58 #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
59 struct ath_common
*common
= ath9k_hw_common(ah
);
60 struct ar5416_eeprom_4k
*eep
=
61 (struct ar5416_eeprom_4k
*) &ah
->eeprom
.map4k
;
62 u16
*eepdata
, temp
, magic
, magic2
;
64 bool need_swap
= false;
68 if (!ath9k_hw_use_flash(ah
)) {
69 if (!ath9k_hw_nvram_read(common
, AR5416_EEPROM_MAGIC_OFFSET
,
71 ath_print(common
, ATH_DBG_FATAL
,
72 "Reading Magic # failed\n");
76 ath_print(common
, ATH_DBG_EEPROM
,
77 "Read Magic = 0x%04X\n", magic
);
79 if (magic
!= AR5416_EEPROM_MAGIC
) {
80 magic2
= swab16(magic
);
82 if (magic2
== AR5416_EEPROM_MAGIC
) {
84 eepdata
= (u16
*) (&ah
->eeprom
);
86 for (addr
= 0; addr
< EEPROM_4K_SIZE
; addr
++) {
87 temp
= swab16(*eepdata
);
92 ath_print(common
, ATH_DBG_FATAL
,
93 "Invalid EEPROM Magic. "
94 "endianness mismatch.\n");
100 ath_print(common
, ATH_DBG_EEPROM
, "need_swap = %s.\n",
101 need_swap
? "True" : "False");
104 el
= swab16(ah
->eeprom
.map4k
.baseEepHeader
.length
);
106 el
= ah
->eeprom
.map4k
.baseEepHeader
.length
;
108 if (el
> sizeof(struct ar5416_eeprom_4k
))
109 el
= sizeof(struct ar5416_eeprom_4k
) / sizeof(u16
);
111 el
= el
/ sizeof(u16
);
113 eepdata
= (u16
*)(&ah
->eeprom
);
115 for (i
= 0; i
< el
; i
++)
122 ath_print(common
, ATH_DBG_EEPROM
,
123 "EEPROM Endianness is not native.. Changing\n");
125 word
= swab16(eep
->baseEepHeader
.length
);
126 eep
->baseEepHeader
.length
= word
;
128 word
= swab16(eep
->baseEepHeader
.checksum
);
129 eep
->baseEepHeader
.checksum
= word
;
131 word
= swab16(eep
->baseEepHeader
.version
);
132 eep
->baseEepHeader
.version
= word
;
134 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
135 eep
->baseEepHeader
.regDmn
[0] = word
;
137 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
138 eep
->baseEepHeader
.regDmn
[1] = word
;
140 word
= swab16(eep
->baseEepHeader
.rfSilent
);
141 eep
->baseEepHeader
.rfSilent
= word
;
143 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
144 eep
->baseEepHeader
.blueToothOptions
= word
;
146 word
= swab16(eep
->baseEepHeader
.deviceCap
);
147 eep
->baseEepHeader
.deviceCap
= word
;
149 integer
= swab32(eep
->modalHeader
.antCtrlCommon
);
150 eep
->modalHeader
.antCtrlCommon
= integer
;
152 for (i
= 0; i
< AR5416_EEP4K_MAX_CHAINS
; i
++) {
153 integer
= swab32(eep
->modalHeader
.antCtrlChain
[i
]);
154 eep
->modalHeader
.antCtrlChain
[i
] = integer
;
157 for (i
= 0; i
< AR5416_EEPROM_MODAL_SPURS
; i
++) {
158 word
= swab16(eep
->modalHeader
.spurChans
[i
].spurChan
);
159 eep
->modalHeader
.spurChans
[i
].spurChan
= word
;
163 if (sum
!= 0xffff || ah
->eep_ops
->get_eeprom_ver(ah
) != AR5416_EEP_VER
||
164 ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_NO_BACK_VER
) {
165 ath_print(common
, ATH_DBG_FATAL
,
166 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
167 sum
, ah
->eep_ops
->get_eeprom_ver(ah
));
172 #undef EEPROM_4K_SIZE
175 static u32
ath9k_hw_4k_get_eeprom(struct ath_hw
*ah
,
176 enum eeprom_param param
)
178 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
179 struct modal_eep_4k_header
*pModal
= &eep
->modalHeader
;
180 struct base_eep_header_4k
*pBase
= &eep
->baseEepHeader
;
184 return pModal
->noiseFloorThreshCh
[0];
185 case AR_EEPROM_MAC(0):
186 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
187 case AR_EEPROM_MAC(1):
188 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
189 case AR_EEPROM_MAC(2):
190 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
192 return pBase
->regDmn
[0];
194 return pBase
->regDmn
[1];
196 return pBase
->deviceCap
;
198 return pBase
->opCapFlags
;
200 return pBase
->rfSilent
;
204 return pModal
->db1_1
;
206 return pBase
->version
& AR5416_EEP_VER_MINOR_MASK
;
208 return pBase
->txMask
;
210 return pBase
->rxMask
;
213 case EEP_PWR_TABLE_OFFSET
:
214 return AR5416_PWR_TABLE_OFFSET_DB
;
220 static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw
*ah
,
221 struct ath9k_channel
*chan
,
222 struct cal_data_per_freq_4k
*pRawDataSet
,
223 u8
*bChans
, u16 availPiers
,
224 u16 tPdGainOverlap
, int16_t *pMinCalPower
,
225 u16
*pPdGainBoundaries
, u8
*pPDADCValues
,
228 #define TMP_VAL_VPD_TABLE \
229 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
232 u16 idxL
= 0, idxR
= 0, numPiers
;
233 static u8 vpdTableL
[AR5416_EEP4K_NUM_PD_GAINS
]
234 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
235 static u8 vpdTableR
[AR5416_EEP4K_NUM_PD_GAINS
]
236 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
237 static u8 vpdTableI
[AR5416_EEP4K_NUM_PD_GAINS
]
238 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
240 u8
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
241 u8 minPwrT4
[AR5416_EEP4K_NUM_PD_GAINS
];
242 u8 maxPwrT4
[AR5416_EEP4K_NUM_PD_GAINS
];
245 u16 sizeCurrVpdTable
, maxIndex
, tgtIndex
;
247 int16_t minDelta
= 0;
248 struct chan_centers centers
;
249 #define PD_GAIN_BOUNDARY_DEFAULT 58;
251 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
253 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
254 if (bChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
258 match
= ath9k_hw_get_lower_upper_index(
259 (u8
)FREQ2FBIN(centers
.synth_center
,
260 IS_CHAN_2GHZ(chan
)), bChans
, numPiers
,
264 for (i
= 0; i
< numXpdGains
; i
++) {
265 minPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][0];
266 maxPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][4];
267 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
268 pRawDataSet
[idxL
].pwrPdg
[i
],
269 pRawDataSet
[idxL
].vpdPdg
[i
],
270 AR5416_EEP4K_PD_GAIN_ICEPTS
,
274 for (i
= 0; i
< numXpdGains
; i
++) {
275 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
276 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
277 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
278 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
280 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
283 min(pPwrL
[AR5416_EEP4K_PD_GAIN_ICEPTS
- 1],
284 pPwrR
[AR5416_EEP4K_PD_GAIN_ICEPTS
- 1]);
287 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
289 AR5416_EEP4K_PD_GAIN_ICEPTS
,
291 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
293 AR5416_EEP4K_PD_GAIN_ICEPTS
,
296 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
298 (u8
)(ath9k_hw_interpolate((u16
)
303 bChans
[idxL
], bChans
[idxR
],
304 vpdTableL
[i
][j
], vpdTableR
[i
][j
]));
309 *pMinCalPower
= (int16_t)(minPwrT4
[0] / 2);
313 for (i
= 0; i
< numXpdGains
; i
++) {
314 if (i
== (numXpdGains
- 1))
315 pPdGainBoundaries
[i
] =
316 (u16
)(maxPwrT4
[i
] / 2);
318 pPdGainBoundaries
[i
] =
319 (u16
)((maxPwrT4
[i
] + minPwrT4
[i
+ 1]) / 4);
321 pPdGainBoundaries
[i
] =
322 min((u16
)AR5416_MAX_RATE_POWER
, pPdGainBoundaries
[i
]);
324 if ((i
== 0) && !AR_SREV_5416_20_OR_LATER(ah
)) {
325 minDelta
= pPdGainBoundaries
[0] - 23;
326 pPdGainBoundaries
[0] = 23;
332 if (AR_SREV_9280_10_OR_LATER(ah
))
333 ss
= (int16_t)(0 - (minPwrT4
[i
] / 2));
337 ss
= (int16_t)((pPdGainBoundaries
[i
- 1] -
339 tPdGainOverlap
+ 1 + minDelta
);
341 vpdStep
= (int16_t)(vpdTableI
[i
][1] - vpdTableI
[i
][0]);
342 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
344 while ((ss
< 0) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
345 tmpVal
= (int16_t)(vpdTableI
[i
][0] + ss
* vpdStep
);
346 pPDADCValues
[k
++] = (u8
)((tmpVal
< 0) ? 0 : tmpVal
);
350 sizeCurrVpdTable
= (u8
) ((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
351 tgtIndex
= (u8
)(pPdGainBoundaries
[i
] + tPdGainOverlap
-
353 maxIndex
= (tgtIndex
< sizeCurrVpdTable
) ?
354 tgtIndex
: sizeCurrVpdTable
;
356 while ((ss
< maxIndex
) && (k
< (AR5416_NUM_PDADC_VALUES
- 1)))
357 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
359 vpdStep
= (int16_t)(vpdTableI
[i
][sizeCurrVpdTable
- 1] -
360 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
361 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
363 if (tgtIndex
>= maxIndex
) {
364 while ((ss
<= tgtIndex
) &&
365 (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
366 tmpVal
= (int16_t) TMP_VAL_VPD_TABLE
;
367 pPDADCValues
[k
++] = (u8
)((tmpVal
> 255) ?
374 while (i
< AR5416_EEP4K_PD_GAINS_IN_MASK
) {
375 pPdGainBoundaries
[i
] = PD_GAIN_BOUNDARY_DEFAULT
;
379 while (k
< AR5416_NUM_PDADC_VALUES
) {
380 pPDADCValues
[k
] = pPDADCValues
[k
- 1];
385 #undef TMP_VAL_VPD_TABLE
388 static void ath9k_hw_set_4k_power_cal_table(struct ath_hw
*ah
,
389 struct ath9k_channel
*chan
,
390 int16_t *pTxPowerIndexOffset
)
392 struct ath_common
*common
= ath9k_hw_common(ah
);
393 struct ar5416_eeprom_4k
*pEepData
= &ah
->eeprom
.map4k
;
394 struct cal_data_per_freq_4k
*pRawDataset
;
395 u8
*pCalBChans
= NULL
;
396 u16 pdGainOverlap_t2
;
397 static u8 pdadcValues
[AR5416_NUM_PDADC_VALUES
];
398 u16 gainBoundaries
[AR5416_EEP4K_PD_GAINS_IN_MASK
];
400 int16_t tMinCalPower
;
401 u16 numXpdGain
, xpdMask
;
402 u16 xpdGainValues
[AR5416_EEP4K_NUM_PD_GAINS
] = { 0, 0 };
403 u32 reg32
, regOffset
, regChainOffset
;
405 xpdMask
= pEepData
->modalHeader
.xpdGain
;
407 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
408 AR5416_EEP_MINOR_VER_2
) {
410 pEepData
->modalHeader
.pdGainOverlap
;
412 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
413 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
416 pCalBChans
= pEepData
->calFreqPier2G
;
417 numPiers
= AR5416_EEP4K_NUM_2G_CAL_PIERS
;
421 for (i
= 1; i
<= AR5416_EEP4K_PD_GAINS_IN_MASK
; i
++) {
422 if ((xpdMask
>> (AR5416_EEP4K_PD_GAINS_IN_MASK
- i
)) & 1) {
423 if (numXpdGain
>= AR5416_EEP4K_NUM_PD_GAINS
)
425 xpdGainValues
[numXpdGain
] =
426 (u16
)(AR5416_EEP4K_PD_GAINS_IN_MASK
- i
);
431 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
432 (numXpdGain
- 1) & 0x3);
433 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
435 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
437 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
, 0);
439 for (i
= 0; i
< AR5416_EEP4K_MAX_CHAINS
; i
++) {
440 if (AR_SREV_5416_20_OR_LATER(ah
) &&
441 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) &&
443 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
445 regChainOffset
= i
* 0x1000;
447 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
448 pRawDataset
= pEepData
->calPierData2G
[i
];
450 ath9k_hw_get_4k_gain_boundaries_pdadcs(ah
, chan
,
451 pRawDataset
, pCalBChans
,
452 numPiers
, pdGainOverlap_t2
,
453 &tMinCalPower
, gainBoundaries
,
454 pdadcValues
, numXpdGain
);
456 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
)) {
457 REG_WRITE(ah
, AR_PHY_TPCRG5
+ regChainOffset
,
459 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)
460 | SM(gainBoundaries
[0],
461 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1
)
462 | SM(gainBoundaries
[1],
463 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2
)
464 | SM(gainBoundaries
[2],
465 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3
)
466 | SM(gainBoundaries
[3],
467 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4
));
470 regOffset
= AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
471 for (j
= 0; j
< 32; j
++) {
472 reg32
= ((pdadcValues
[4 * j
+ 0] & 0xFF) << 0) |
473 ((pdadcValues
[4 * j
+ 1] & 0xFF) << 8) |
474 ((pdadcValues
[4 * j
+ 2] & 0xFF) << 16)|
475 ((pdadcValues
[4 * j
+ 3] & 0xFF) << 24);
476 REG_WRITE(ah
, regOffset
, reg32
);
478 ath_print(common
, ATH_DBG_EEPROM
,
479 "PDADC (%d,%4x): %4.4x %8.8x\n",
480 i
, regChainOffset
, regOffset
,
482 ath_print(common
, ATH_DBG_EEPROM
,
484 "PDADC %3d Value %3d | "
485 "PDADC %3d Value %3d | "
486 "PDADC %3d Value %3d | "
487 "PDADC %3d Value %3d |\n",
488 i
, 4 * j
, pdadcValues
[4 * j
],
489 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
490 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
492 pdadcValues
[4 * j
+ 3]);
499 *pTxPowerIndexOffset
= 0;
502 static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw
*ah
,
503 struct ath9k_channel
*chan
,
506 u16 AntennaReduction
,
507 u16 twiceMaxRegulatoryPower
,
510 #define CMP_TEST_GRP \
511 (((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) == \
512 pEepData->ctlIndex[i]) \
513 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
514 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
516 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
518 int16_t twiceLargestAntenna
;
519 u16 twiceMinEdgePower
;
520 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
521 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
522 u16 numCtlModes
, *pCtlMode
, ctlMode
, freq
;
523 struct chan_centers centers
;
524 struct cal_ctl_data_4k
*rep
;
525 struct ar5416_eeprom_4k
*pEepData
= &ah
->eeprom
.map4k
;
526 static const u16 tpScaleReductionTable
[5] =
527 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
528 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
531 struct cal_target_power_leg targetPowerOfdmExt
= {
532 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
535 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
538 u16 ctlModesFor11g
[] =
539 { CTL_11B
, CTL_11G
, CTL_2GHT20
, CTL_11B_EXT
, CTL_11G_EXT
,
543 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
545 twiceLargestAntenna
= pEepData
->modalHeader
.antennaGainCh
[0];
546 twiceLargestAntenna
= (int16_t)min(AntennaReduction
-
547 twiceLargestAntenna
, 0);
549 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
550 if (regulatory
->tp_scale
!= ATH9K_TP_SCALE_MAX
) {
551 maxRegAllowedPower
-=
552 (tpScaleReductionTable
[(regulatory
->tp_scale
)] * 2);
555 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
556 scaledPower
= max((u16
)0, scaledPower
);
558 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
) - SUB_NUM_CTL_MODES_AT_2G_40
;
559 pCtlMode
= ctlModesFor11g
;
561 ath9k_hw_get_legacy_target_powers(ah
, chan
,
562 pEepData
->calTargetPowerCck
,
563 AR5416_NUM_2G_CCK_TARGET_POWERS
,
564 &targetPowerCck
, 4, false);
565 ath9k_hw_get_legacy_target_powers(ah
, chan
,
566 pEepData
->calTargetPower2G
,
567 AR5416_NUM_2G_20_TARGET_POWERS
,
568 &targetPowerOfdm
, 4, false);
569 ath9k_hw_get_target_powers(ah
, chan
,
570 pEepData
->calTargetPower2GHT20
,
571 AR5416_NUM_2G_20_TARGET_POWERS
,
572 &targetPowerHt20
, 8, false);
574 if (IS_CHAN_HT40(chan
)) {
575 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
576 ath9k_hw_get_target_powers(ah
, chan
,
577 pEepData
->calTargetPower2GHT40
,
578 AR5416_NUM_2G_40_TARGET_POWERS
,
579 &targetPowerHt40
, 8, true);
580 ath9k_hw_get_legacy_target_powers(ah
, chan
,
581 pEepData
->calTargetPowerCck
,
582 AR5416_NUM_2G_CCK_TARGET_POWERS
,
583 &targetPowerCckExt
, 4, true);
584 ath9k_hw_get_legacy_target_powers(ah
, chan
,
585 pEepData
->calTargetPower2G
,
586 AR5416_NUM_2G_20_TARGET_POWERS
,
587 &targetPowerOfdmExt
, 4, true);
590 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
591 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
592 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
595 freq
= centers
.synth_center
;
596 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
597 freq
= centers
.ext_center
;
599 freq
= centers
.ctl_center
;
601 if (ah
->eep_ops
->get_eeprom_ver(ah
) == 14 &&
602 ah
->eep_ops
->get_eeprom_rev(ah
) <= 2)
603 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
605 for (i
= 0; (i
< AR5416_EEP4K_NUM_CTLS
) &&
606 pEepData
->ctlIndex
[i
]; i
++) {
609 rep
= &(pEepData
->ctlData
[i
]);
611 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(
614 ar5416_get_ntxchains(ah
->txchainmask
) - 1],
616 AR5416_EEP4K_NUM_BAND_EDGES
);
618 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
620 min(twiceMaxEdgePower
,
623 twiceMaxEdgePower
= twiceMinEdgePower
;
629 minCtlPower
= (u8
)min(twiceMaxEdgePower
, scaledPower
);
631 switch (pCtlMode
[ctlMode
]) {
633 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
); i
++) {
634 targetPowerCck
.tPow2x
[i
] =
635 min((u16
)targetPowerCck
.tPow2x
[i
],
640 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
); i
++) {
641 targetPowerOfdm
.tPow2x
[i
] =
642 min((u16
)targetPowerOfdm
.tPow2x
[i
],
647 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++) {
648 targetPowerHt20
.tPow2x
[i
] =
649 min((u16
)targetPowerHt20
.tPow2x
[i
],
654 targetPowerCckExt
.tPow2x
[0] =
655 min((u16
)targetPowerCckExt
.tPow2x
[0],
659 targetPowerOfdmExt
.tPow2x
[0] =
660 min((u16
)targetPowerOfdmExt
.tPow2x
[0],
664 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
665 targetPowerHt40
.tPow2x
[i
] =
666 min((u16
)targetPowerHt40
.tPow2x
[i
],
675 ratesArray
[rate6mb
] =
676 ratesArray
[rate9mb
] =
677 ratesArray
[rate12mb
] =
678 ratesArray
[rate18mb
] =
679 ratesArray
[rate24mb
] =
680 targetPowerOfdm
.tPow2x
[0];
682 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
683 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
684 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
685 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
687 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
688 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
690 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
691 ratesArray
[rate2s
] = ratesArray
[rate2l
] = targetPowerCck
.tPow2x
[1];
692 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] = targetPowerCck
.tPow2x
[2];
693 ratesArray
[rate11s
] = ratesArray
[rate11l
] = targetPowerCck
.tPow2x
[3];
695 if (IS_CHAN_HT40(chan
)) {
696 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
697 ratesArray
[rateHt40_0
+ i
] =
698 targetPowerHt40
.tPow2x
[i
];
700 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
701 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
702 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
703 ratesArray
[rateExtCck
] = targetPowerCckExt
.tPow2x
[0];
709 static void ath9k_hw_4k_set_txpower(struct ath_hw
*ah
,
710 struct ath9k_channel
*chan
,
712 u8 twiceAntennaReduction
,
713 u8 twiceMaxRegulatoryPower
,
716 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
717 struct ar5416_eeprom_4k
*pEepData
= &ah
->eeprom
.map4k
;
718 struct modal_eep_4k_header
*pModal
= &pEepData
->modalHeader
;
719 int16_t ratesArray
[Ar5416RateSize
];
720 int16_t txPowerIndexOffset
= 0;
721 u8 ht40PowerIncForPdadc
= 2;
724 memset(ratesArray
, 0, sizeof(ratesArray
));
726 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
727 AR5416_EEP_MINOR_VER_2
) {
728 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
731 ath9k_hw_set_4k_power_per_rate_table(ah
, chan
,
732 &ratesArray
[0], cfgCtl
,
733 twiceAntennaReduction
,
734 twiceMaxRegulatoryPower
,
737 ath9k_hw_set_4k_power_cal_table(ah
, chan
, &txPowerIndexOffset
);
739 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
740 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
741 if (ratesArray
[i
] > AR5416_MAX_RATE_POWER
)
742 ratesArray
[i
] = AR5416_MAX_RATE_POWER
;
746 /* Update regulatory */
749 if (IS_CHAN_HT40(chan
))
751 else if (IS_CHAN_HT20(chan
))
754 regulatory
->max_power_level
= ratesArray
[i
];
756 if (AR_SREV_9280_10_OR_LATER(ah
)) {
757 for (i
= 0; i
< Ar5416RateSize
; i
++)
758 ratesArray
[i
] -= AR5416_PWR_TABLE_OFFSET_DB
* 2;
761 /* OFDM power per rate */
762 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
763 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
764 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
765 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
766 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
767 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
768 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
769 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
770 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
771 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
773 /* CCK power per rate */
774 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
775 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
776 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
777 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
778 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
779 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
780 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
781 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
782 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
783 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
785 /* HT20 power per rate */
786 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
787 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
788 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
789 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
790 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
791 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
792 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
793 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
794 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
795 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
797 /* HT40 power per rate */
798 if (IS_CHAN_HT40(chan
)) {
799 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
800 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
801 ht40PowerIncForPdadc
, 24)
802 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
803 ht40PowerIncForPdadc
, 16)
804 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
805 ht40PowerIncForPdadc
, 8)
806 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
807 ht40PowerIncForPdadc
, 0));
808 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
809 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
810 ht40PowerIncForPdadc
, 24)
811 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
812 ht40PowerIncForPdadc
, 16)
813 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
814 ht40PowerIncForPdadc
, 8)
815 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
816 ht40PowerIncForPdadc
, 0));
817 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
818 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
819 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
820 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
821 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
825 static void ath9k_hw_4k_set_addac(struct ath_hw
*ah
,
826 struct ath9k_channel
*chan
)
828 struct modal_eep_4k_header
*pModal
;
829 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
832 if (ah
->hw_version
.macVersion
!= AR_SREV_VERSION_9160
)
835 if (ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_MINOR_VER_7
)
838 pModal
= &eep
->modalHeader
;
840 if (pModal
->xpaBiasLvl
!= 0xff) {
841 biaslevel
= pModal
->xpaBiasLvl
;
842 INI_RA(&ah
->iniAddac
, 7, 1) =
843 (INI_RA(&ah
->iniAddac
, 7, 1) & (~0x18)) | biaslevel
<< 3;
847 static void ath9k_hw_4k_set_gain(struct ath_hw
*ah
,
848 struct modal_eep_4k_header
*pModal
,
849 struct ar5416_eeprom_4k
*eep
,
852 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
,
853 pModal
->antCtrlChain
[0]);
855 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0),
856 (REG_READ(ah
, AR_PHY_TIMING_CTRL4(0)) &
857 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
858 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
859 SM(pModal
->iqCalICh
[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
860 SM(pModal
->iqCalQCh
[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
862 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
863 AR5416_EEP_MINOR_VER_3
) {
864 txRxAttenLocal
= pModal
->txRxAttenCh
[0];
866 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
867 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
, pModal
->bswMargin
[0]);
868 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
869 AR_PHY_GAIN_2GHZ_XATTEN1_DB
, pModal
->bswAtten
[0]);
870 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
871 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
872 pModal
->xatten2Margin
[0]);
873 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
874 AR_PHY_GAIN_2GHZ_XATTEN2_DB
, pModal
->xatten2Db
[0]);
876 /* Set the block 1 value to block 0 value */
877 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
878 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
879 pModal
->bswMargin
[0]);
880 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
881 AR_PHY_GAIN_2GHZ_XATTEN1_DB
, pModal
->bswAtten
[0]);
882 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
883 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
884 pModal
->xatten2Margin
[0]);
885 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
886 AR_PHY_GAIN_2GHZ_XATTEN2_DB
,
887 pModal
->xatten2Db
[0]);
890 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
,
891 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
892 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
,
893 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[0]);
895 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ 0x1000,
896 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
897 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ 0x1000,
898 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[0]);
900 if (AR_SREV_9285_11(ah
))
901 REG_WRITE(ah
, AR9285_AN_TOP4
, (AR9285_AN_TOP4_DEFAULT
| 0x14));
905 * Read EEPROM header info and program the device for correct operation
906 * given the channel value.
908 static void ath9k_hw_4k_set_board_values(struct ath_hw
*ah
,
909 struct ath9k_channel
*chan
)
911 struct modal_eep_4k_header
*pModal
;
912 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
914 u8 ob
[5], db1
[5], db2
[5];
915 u8 ant_div_control1
, ant_div_control2
;
918 pModal
= &eep
->modalHeader
;
921 REG_WRITE(ah
, AR_PHY_SWITCH_COM
,
922 ah
->eep_ops
->get_eeprom_antenna_cfg(ah
, chan
));
924 /* Single chain for 4K EEPROM*/
925 ath9k_hw_4k_set_gain(ah
, pModal
, eep
, txRxAttenLocal
);
927 /* Initialize Ant Diversity settings from EEPROM */
928 if (pModal
->version
>= 3) {
929 ant_div_control1
= pModal
->antdiv_ctl1
;
930 ant_div_control2
= pModal
->antdiv_ctl2
;
932 regVal
= REG_READ(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
);
933 regVal
&= (~(AR_PHY_9285_ANT_DIV_CTL_ALL
));
935 regVal
|= SM(ant_div_control1
,
936 AR_PHY_9285_ANT_DIV_CTL
);
937 regVal
|= SM(ant_div_control2
,
938 AR_PHY_9285_ANT_DIV_ALT_LNACONF
);
939 regVal
|= SM((ant_div_control2
>> 2),
940 AR_PHY_9285_ANT_DIV_MAIN_LNACONF
);
941 regVal
|= SM((ant_div_control1
>> 1),
942 AR_PHY_9285_ANT_DIV_ALT_GAINTB
);
943 regVal
|= SM((ant_div_control1
>> 2),
944 AR_PHY_9285_ANT_DIV_MAIN_GAINTB
);
947 REG_WRITE(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
, regVal
);
948 regVal
= REG_READ(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
);
949 regVal
= REG_READ(ah
, AR_PHY_CCK_DETECT
);
950 regVal
&= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV
);
951 regVal
|= SM((ant_div_control1
>> 3),
952 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV
);
954 REG_WRITE(ah
, AR_PHY_CCK_DETECT
, regVal
);
955 regVal
= REG_READ(ah
, AR_PHY_CCK_DETECT
);
958 if (pModal
->version
>= 2) {
959 ob
[0] = pModal
->ob_0
;
960 ob
[1] = pModal
->ob_1
;
961 ob
[2] = pModal
->ob_2
;
962 ob
[3] = pModal
->ob_3
;
963 ob
[4] = pModal
->ob_4
;
965 db1
[0] = pModal
->db1_0
;
966 db1
[1] = pModal
->db1_1
;
967 db1
[2] = pModal
->db1_2
;
968 db1
[3] = pModal
->db1_3
;
969 db1
[4] = pModal
->db1_4
;
971 db2
[0] = pModal
->db2_0
;
972 db2
[1] = pModal
->db2_1
;
973 db2
[2] = pModal
->db2_2
;
974 db2
[3] = pModal
->db2_3
;
975 db2
[4] = pModal
->db2_4
;
976 } else if (pModal
->version
== 1) {
977 ob
[0] = pModal
->ob_0
;
978 ob
[1] = ob
[2] = ob
[3] = ob
[4] = pModal
->ob_1
;
979 db1
[0] = pModal
->db1_0
;
980 db1
[1] = db1
[2] = db1
[3] = db1
[4] = pModal
->db1_1
;
981 db2
[0] = pModal
->db2_0
;
982 db2
[1] = db2
[2] = db2
[3] = db2
[4] = pModal
->db2_1
;
986 for (i
= 0; i
< 5; i
++) {
987 ob
[i
] = pModal
->ob_0
;
988 db1
[i
] = pModal
->db1_0
;
989 db2
[i
] = pModal
->db1_0
;
993 if (AR_SREV_9271(ah
)) {
994 ath9k_hw_analog_shift_rmw(ah
,
996 AR9271_AN_RF2G3_OB_cck
,
997 AR9271_AN_RF2G3_OB_cck_S
,
999 ath9k_hw_analog_shift_rmw(ah
,
1001 AR9271_AN_RF2G3_OB_psk
,
1002 AR9271_AN_RF2G3_OB_psk_S
,
1004 ath9k_hw_analog_shift_rmw(ah
,
1006 AR9271_AN_RF2G3_OB_qam
,
1007 AR9271_AN_RF2G3_OB_qam_S
,
1009 ath9k_hw_analog_shift_rmw(ah
,
1011 AR9271_AN_RF2G3_DB_1
,
1012 AR9271_AN_RF2G3_DB_1_S
,
1014 ath9k_hw_analog_shift_rmw(ah
,
1016 AR9271_AN_RF2G4_DB_2
,
1017 AR9271_AN_RF2G4_DB_2_S
,
1020 ath9k_hw_analog_shift_rmw(ah
,
1022 AR9285_AN_RF2G3_OB_0
,
1023 AR9285_AN_RF2G3_OB_0_S
,
1025 ath9k_hw_analog_shift_rmw(ah
,
1027 AR9285_AN_RF2G3_OB_1
,
1028 AR9285_AN_RF2G3_OB_1_S
,
1030 ath9k_hw_analog_shift_rmw(ah
,
1032 AR9285_AN_RF2G3_OB_2
,
1033 AR9285_AN_RF2G3_OB_2_S
,
1035 ath9k_hw_analog_shift_rmw(ah
,
1037 AR9285_AN_RF2G3_OB_3
,
1038 AR9285_AN_RF2G3_OB_3_S
,
1040 ath9k_hw_analog_shift_rmw(ah
,
1042 AR9285_AN_RF2G3_OB_4
,
1043 AR9285_AN_RF2G3_OB_4_S
,
1046 ath9k_hw_analog_shift_rmw(ah
,
1048 AR9285_AN_RF2G3_DB1_0
,
1049 AR9285_AN_RF2G3_DB1_0_S
,
1051 ath9k_hw_analog_shift_rmw(ah
,
1053 AR9285_AN_RF2G3_DB1_1
,
1054 AR9285_AN_RF2G3_DB1_1_S
,
1056 ath9k_hw_analog_shift_rmw(ah
,
1058 AR9285_AN_RF2G3_DB1_2
,
1059 AR9285_AN_RF2G3_DB1_2_S
,
1061 ath9k_hw_analog_shift_rmw(ah
,
1063 AR9285_AN_RF2G4_DB1_3
,
1064 AR9285_AN_RF2G4_DB1_3_S
,
1066 ath9k_hw_analog_shift_rmw(ah
,
1068 AR9285_AN_RF2G4_DB1_4
,
1069 AR9285_AN_RF2G4_DB1_4_S
, db1
[4]);
1071 ath9k_hw_analog_shift_rmw(ah
,
1073 AR9285_AN_RF2G4_DB2_0
,
1074 AR9285_AN_RF2G4_DB2_0_S
,
1076 ath9k_hw_analog_shift_rmw(ah
,
1078 AR9285_AN_RF2G4_DB2_1
,
1079 AR9285_AN_RF2G4_DB2_1_S
,
1081 ath9k_hw_analog_shift_rmw(ah
,
1083 AR9285_AN_RF2G4_DB2_2
,
1084 AR9285_AN_RF2G4_DB2_2_S
,
1086 ath9k_hw_analog_shift_rmw(ah
,
1088 AR9285_AN_RF2G4_DB2_3
,
1089 AR9285_AN_RF2G4_DB2_3_S
,
1091 ath9k_hw_analog_shift_rmw(ah
,
1093 AR9285_AN_RF2G4_DB2_4
,
1094 AR9285_AN_RF2G4_DB2_4_S
,
1099 if (AR_SREV_9285_11(ah
))
1100 REG_WRITE(ah
, AR9285_AN_TOP4
, AR9285_AN_TOP4_DEFAULT
);
1102 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
, AR_PHY_SETTLING_SWITCH
,
1103 pModal
->switchSettling
);
1104 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
, AR_PHY_DESIRED_SZ_ADC
,
1105 pModal
->adcDesiredSize
);
1107 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
1108 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
) |
1109 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAB_OFF
) |
1110 SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAA_ON
) |
1111 SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
1113 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
1114 pModal
->txEndToRxOn
);
1115 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR9280_PHY_CCA_THRESH62
,
1117 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
, AR_PHY_EXT_CCA0_THRESH62
,
1120 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1121 AR5416_EEP_MINOR_VER_2
) {
1122 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_DATA_START
,
1123 pModal
->txFrameToDataStart
);
1124 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_PA_ON
,
1125 pModal
->txFrameToPaOn
);
1128 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1129 AR5416_EEP_MINOR_VER_3
) {
1130 if (IS_CHAN_HT40(chan
))
1131 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
1132 AR_PHY_SETTLING_SWITCH
,
1133 pModal
->swSettleHt40
);
1137 static u16
ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw
*ah
,
1138 struct ath9k_channel
*chan
)
1140 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
1141 struct modal_eep_4k_header
*pModal
= &eep
->modalHeader
;
1143 return pModal
->antCtrlCommon
& 0xFFFF;
1146 static u8
ath9k_hw_4k_get_num_ant_config(struct ath_hw
*ah
,
1147 enum ieee80211_band freq_band
)
1152 static u16
ath9k_hw_4k_get_spur_channel(struct ath_hw
*ah
, u16 i
, bool is2GHz
)
1154 #define EEP_MAP4K_SPURCHAN \
1155 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
1156 struct ath_common
*common
= ath9k_hw_common(ah
);
1158 u16 spur_val
= AR_NO_SPUR
;
1160 ath_print(common
, ATH_DBG_ANI
,
1161 "Getting spur idx %d is2Ghz. %d val %x\n",
1162 i
, is2GHz
, ah
->config
.spurchans
[i
][is2GHz
]);
1164 switch (ah
->config
.spurmode
) {
1167 case SPUR_ENABLE_IOCTL
:
1168 spur_val
= ah
->config
.spurchans
[i
][is2GHz
];
1169 ath_print(common
, ATH_DBG_ANI
,
1170 "Getting spur val from new loc. %d\n", spur_val
);
1172 case SPUR_ENABLE_EEPROM
:
1173 spur_val
= EEP_MAP4K_SPURCHAN
;
1179 #undef EEP_MAP4K_SPURCHAN
1182 const struct eeprom_ops eep_4k_ops
= {
1183 .check_eeprom
= ath9k_hw_4k_check_eeprom
,
1184 .get_eeprom
= ath9k_hw_4k_get_eeprom
,
1185 .fill_eeprom
= ath9k_hw_4k_fill_eeprom
,
1186 .get_eeprom_ver
= ath9k_hw_4k_get_eeprom_ver
,
1187 .get_eeprom_rev
= ath9k_hw_4k_get_eeprom_rev
,
1188 .get_num_ant_config
= ath9k_hw_4k_get_num_ant_config
,
1189 .get_eeprom_antenna_cfg
= ath9k_hw_4k_get_eeprom_antenna_cfg
,
1190 .set_board_values
= ath9k_hw_4k_set_board_values
,
1191 .set_addac
= ath9k_hw_4k_set_addac
,
1192 .set_txpower
= ath9k_hw_4k_set_txpower
,
1193 .get_spur_channel
= ath9k_hw_4k_get_spur_channel