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.
18 #include "ar9002_phy.h"
20 static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw
*ah
)
22 return ((ah
->eeprom
.map4k
.baseEepHeader
.version
>> 12) & 0xF);
25 static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw
*ah
)
27 return ((ah
->eeprom
.map4k
.baseEepHeader
.version
) & 0xFFF);
30 static bool ath9k_hw_4k_fill_eeprom(struct ath_hw
*ah
)
32 #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
33 struct ath_common
*common
= ath9k_hw_common(ah
);
34 u16
*eep_data
= (u16
*)&ah
->eeprom
.map4k
;
35 int addr
, eep_start_loc
= 0;
39 if (!ath9k_hw_use_flash(ah
)) {
40 ath_print(common
, ATH_DBG_EEPROM
,
41 "Reading from EEPROM, not flash\n");
44 for (addr
= 0; addr
< SIZE_EEPROM_4K
; addr
++) {
45 if (!ath9k_hw_nvram_read(common
, addr
+ eep_start_loc
, eep_data
)) {
46 ath_print(common
, ATH_DBG_EEPROM
,
47 "Unable to read eeprom region\n");
57 static int ath9k_hw_4k_check_eeprom(struct ath_hw
*ah
)
59 #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
60 struct ath_common
*common
= ath9k_hw_common(ah
);
61 struct ar5416_eeprom_4k
*eep
=
62 (struct ar5416_eeprom_4k
*) &ah
->eeprom
.map4k
;
63 u16
*eepdata
, temp
, magic
, magic2
;
65 bool need_swap
= false;
69 if (!ath9k_hw_use_flash(ah
)) {
70 if (!ath9k_hw_nvram_read(common
, AR5416_EEPROM_MAGIC_OFFSET
,
72 ath_print(common
, ATH_DBG_FATAL
,
73 "Reading Magic # failed\n");
77 ath_print(common
, ATH_DBG_EEPROM
,
78 "Read Magic = 0x%04X\n", magic
);
80 if (magic
!= AR5416_EEPROM_MAGIC
) {
81 magic2
= swab16(magic
);
83 if (magic2
== AR5416_EEPROM_MAGIC
) {
85 eepdata
= (u16
*) (&ah
->eeprom
);
87 for (addr
= 0; addr
< EEPROM_4K_SIZE
; addr
++) {
88 temp
= swab16(*eepdata
);
93 ath_print(common
, ATH_DBG_FATAL
,
94 "Invalid EEPROM Magic. "
95 "endianness mismatch.\n");
101 ath_print(common
, ATH_DBG_EEPROM
, "need_swap = %s.\n",
102 need_swap
? "True" : "False");
105 el
= swab16(ah
->eeprom
.map4k
.baseEepHeader
.length
);
107 el
= ah
->eeprom
.map4k
.baseEepHeader
.length
;
109 if (el
> sizeof(struct ar5416_eeprom_4k
))
110 el
= sizeof(struct ar5416_eeprom_4k
) / sizeof(u16
);
112 el
= el
/ sizeof(u16
);
114 eepdata
= (u16
*)(&ah
->eeprom
);
116 for (i
= 0; i
< el
; i
++)
123 ath_print(common
, ATH_DBG_EEPROM
,
124 "EEPROM Endianness is not native.. Changing\n");
126 word
= swab16(eep
->baseEepHeader
.length
);
127 eep
->baseEepHeader
.length
= word
;
129 word
= swab16(eep
->baseEepHeader
.checksum
);
130 eep
->baseEepHeader
.checksum
= word
;
132 word
= swab16(eep
->baseEepHeader
.version
);
133 eep
->baseEepHeader
.version
= word
;
135 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
136 eep
->baseEepHeader
.regDmn
[0] = word
;
138 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
139 eep
->baseEepHeader
.regDmn
[1] = word
;
141 word
= swab16(eep
->baseEepHeader
.rfSilent
);
142 eep
->baseEepHeader
.rfSilent
= word
;
144 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
145 eep
->baseEepHeader
.blueToothOptions
= word
;
147 word
= swab16(eep
->baseEepHeader
.deviceCap
);
148 eep
->baseEepHeader
.deviceCap
= word
;
150 integer
= swab32(eep
->modalHeader
.antCtrlCommon
);
151 eep
->modalHeader
.antCtrlCommon
= integer
;
153 for (i
= 0; i
< AR5416_EEP4K_MAX_CHAINS
; i
++) {
154 integer
= swab32(eep
->modalHeader
.antCtrlChain
[i
]);
155 eep
->modalHeader
.antCtrlChain
[i
] = integer
;
158 for (i
= 0; i
< AR5416_EEPROM_MODAL_SPURS
; i
++) {
159 word
= swab16(eep
->modalHeader
.spurChans
[i
].spurChan
);
160 eep
->modalHeader
.spurChans
[i
].spurChan
= word
;
164 if (sum
!= 0xffff || ah
->eep_ops
->get_eeprom_ver(ah
) != AR5416_EEP_VER
||
165 ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_NO_BACK_VER
) {
166 ath_print(common
, ATH_DBG_FATAL
,
167 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
168 sum
, ah
->eep_ops
->get_eeprom_ver(ah
));
173 #undef EEPROM_4K_SIZE
176 static u32
ath9k_hw_4k_get_eeprom(struct ath_hw
*ah
,
177 enum eeprom_param param
)
179 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
180 struct modal_eep_4k_header
*pModal
= &eep
->modalHeader
;
181 struct base_eep_header_4k
*pBase
= &eep
->baseEepHeader
;
185 return pModal
->noiseFloorThreshCh
[0];
187 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
189 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
191 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
193 return pBase
->regDmn
[0];
195 return pBase
->regDmn
[1];
197 return pBase
->deviceCap
;
199 return pBase
->opCapFlags
;
201 return pBase
->rfSilent
;
205 return pModal
->db1_1
;
207 return pBase
->version
& AR5416_EEP_VER_MINOR_MASK
;
209 return pBase
->txMask
;
211 return pBase
->rxMask
;
214 case EEP_PWR_TABLE_OFFSET
:
215 return AR5416_PWR_TABLE_OFFSET_DB
;
221 static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw
*ah
,
222 struct ath9k_channel
*chan
,
223 struct cal_data_per_freq_4k
*pRawDataSet
,
224 u8
*bChans
, u16 availPiers
,
225 u16 tPdGainOverlap
, int16_t *pMinCalPower
,
226 u16
*pPdGainBoundaries
, u8
*pPDADCValues
,
229 #define TMP_VAL_VPD_TABLE \
230 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
233 u16 idxL
= 0, idxR
= 0, numPiers
;
234 static u8 vpdTableL
[AR5416_EEP4K_NUM_PD_GAINS
]
235 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
236 static u8 vpdTableR
[AR5416_EEP4K_NUM_PD_GAINS
]
237 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
238 static u8 vpdTableI
[AR5416_EEP4K_NUM_PD_GAINS
]
239 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
241 u8
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
242 u8 minPwrT4
[AR5416_EEP4K_NUM_PD_GAINS
];
243 u8 maxPwrT4
[AR5416_EEP4K_NUM_PD_GAINS
];
246 u16 sizeCurrVpdTable
, maxIndex
, tgtIndex
;
248 int16_t minDelta
= 0;
249 struct chan_centers centers
;
250 #define PD_GAIN_BOUNDARY_DEFAULT 58;
252 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
254 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
255 if (bChans
[numPiers
] == AR5416_BCHAN_UNUSED
)
259 match
= ath9k_hw_get_lower_upper_index(
260 (u8
)FREQ2FBIN(centers
.synth_center
,
261 IS_CHAN_2GHZ(chan
)), bChans
, numPiers
,
265 for (i
= 0; i
< numXpdGains
; i
++) {
266 minPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][0];
267 maxPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][4];
268 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
269 pRawDataSet
[idxL
].pwrPdg
[i
],
270 pRawDataSet
[idxL
].vpdPdg
[i
],
271 AR5416_EEP4K_PD_GAIN_ICEPTS
,
275 for (i
= 0; i
< numXpdGains
; i
++) {
276 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
277 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
278 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
279 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
281 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
284 min(pPwrL
[AR5416_EEP4K_PD_GAIN_ICEPTS
- 1],
285 pPwrR
[AR5416_EEP4K_PD_GAIN_ICEPTS
- 1]);
288 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
290 AR5416_EEP4K_PD_GAIN_ICEPTS
,
292 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
294 AR5416_EEP4K_PD_GAIN_ICEPTS
,
297 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
299 (u8
)(ath9k_hw_interpolate((u16
)
304 bChans
[idxL
], bChans
[idxR
],
305 vpdTableL
[i
][j
], vpdTableR
[i
][j
]));
310 *pMinCalPower
= (int16_t)(minPwrT4
[0] / 2);
314 for (i
= 0; i
< numXpdGains
; i
++) {
315 if (i
== (numXpdGains
- 1))
316 pPdGainBoundaries
[i
] =
317 (u16
)(maxPwrT4
[i
] / 2);
319 pPdGainBoundaries
[i
] =
320 (u16
)((maxPwrT4
[i
] + minPwrT4
[i
+ 1]) / 4);
322 pPdGainBoundaries
[i
] =
323 min((u16
)AR5416_MAX_RATE_POWER
, pPdGainBoundaries
[i
]);
325 if ((i
== 0) && !AR_SREV_5416_20_OR_LATER(ah
)) {
326 minDelta
= pPdGainBoundaries
[0] - 23;
327 pPdGainBoundaries
[0] = 23;
333 if (AR_SREV_9280_10_OR_LATER(ah
))
334 ss
= (int16_t)(0 - (minPwrT4
[i
] / 2));
338 ss
= (int16_t)((pPdGainBoundaries
[i
- 1] -
340 tPdGainOverlap
+ 1 + minDelta
);
342 vpdStep
= (int16_t)(vpdTableI
[i
][1] - vpdTableI
[i
][0]);
343 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
345 while ((ss
< 0) && (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
346 tmpVal
= (int16_t)(vpdTableI
[i
][0] + ss
* vpdStep
);
347 pPDADCValues
[k
++] = (u8
)((tmpVal
< 0) ? 0 : tmpVal
);
351 sizeCurrVpdTable
= (u8
) ((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
352 tgtIndex
= (u8
)(pPdGainBoundaries
[i
] + tPdGainOverlap
-
354 maxIndex
= (tgtIndex
< sizeCurrVpdTable
) ?
355 tgtIndex
: sizeCurrVpdTable
;
357 while ((ss
< maxIndex
) && (k
< (AR5416_NUM_PDADC_VALUES
- 1)))
358 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
360 vpdStep
= (int16_t)(vpdTableI
[i
][sizeCurrVpdTable
- 1] -
361 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
362 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
364 if (tgtIndex
>= maxIndex
) {
365 while ((ss
<= tgtIndex
) &&
366 (k
< (AR5416_NUM_PDADC_VALUES
- 1))) {
367 tmpVal
= (int16_t) TMP_VAL_VPD_TABLE
;
368 pPDADCValues
[k
++] = (u8
)((tmpVal
> 255) ?
375 while (i
< AR5416_EEP4K_PD_GAINS_IN_MASK
) {
376 pPdGainBoundaries
[i
] = PD_GAIN_BOUNDARY_DEFAULT
;
380 while (k
< AR5416_NUM_PDADC_VALUES
) {
381 pPDADCValues
[k
] = pPDADCValues
[k
- 1];
386 #undef TMP_VAL_VPD_TABLE
389 static void ath9k_hw_set_4k_power_cal_table(struct ath_hw
*ah
,
390 struct ath9k_channel
*chan
,
391 int16_t *pTxPowerIndexOffset
)
393 struct ath_common
*common
= ath9k_hw_common(ah
);
394 struct ar5416_eeprom_4k
*pEepData
= &ah
->eeprom
.map4k
;
395 struct cal_data_per_freq_4k
*pRawDataset
;
396 u8
*pCalBChans
= NULL
;
397 u16 pdGainOverlap_t2
;
398 static u8 pdadcValues
[AR5416_NUM_PDADC_VALUES
];
399 u16 gainBoundaries
[AR5416_EEP4K_PD_GAINS_IN_MASK
];
401 int16_t tMinCalPower
;
402 u16 numXpdGain
, xpdMask
;
403 u16 xpdGainValues
[AR5416_EEP4K_NUM_PD_GAINS
] = { 0, 0 };
404 u32 reg32
, regOffset
, regChainOffset
;
406 xpdMask
= pEepData
->modalHeader
.xpdGain
;
408 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
409 AR5416_EEP_MINOR_VER_2
) {
411 pEepData
->modalHeader
.pdGainOverlap
;
413 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
414 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
417 pCalBChans
= pEepData
->calFreqPier2G
;
418 numPiers
= AR5416_EEP4K_NUM_2G_CAL_PIERS
;
422 for (i
= 1; i
<= AR5416_EEP4K_PD_GAINS_IN_MASK
; i
++) {
423 if ((xpdMask
>> (AR5416_EEP4K_PD_GAINS_IN_MASK
- i
)) & 1) {
424 if (numXpdGain
>= AR5416_EEP4K_NUM_PD_GAINS
)
426 xpdGainValues
[numXpdGain
] =
427 (u16
)(AR5416_EEP4K_PD_GAINS_IN_MASK
- i
);
432 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
433 (numXpdGain
- 1) & 0x3);
434 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
436 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
438 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
, 0);
440 for (i
= 0; i
< AR5416_EEP4K_MAX_CHAINS
; i
++) {
441 if (AR_SREV_5416_20_OR_LATER(ah
) &&
442 (ah
->rxchainmask
== 5 || ah
->txchainmask
== 5) &&
444 regChainOffset
= (i
== 1) ? 0x2000 : 0x1000;
446 regChainOffset
= i
* 0x1000;
448 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
449 pRawDataset
= pEepData
->calPierData2G
[i
];
451 ath9k_hw_get_4k_gain_boundaries_pdadcs(ah
, chan
,
452 pRawDataset
, pCalBChans
,
453 numPiers
, pdGainOverlap_t2
,
454 &tMinCalPower
, gainBoundaries
,
455 pdadcValues
, numXpdGain
);
457 ENABLE_REGWRITE_BUFFER(ah
);
459 if ((i
== 0) || AR_SREV_5416_20_OR_LATER(ah
)) {
460 REG_WRITE(ah
, AR_PHY_TPCRG5
+ regChainOffset
,
462 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
)
463 | SM(gainBoundaries
[0],
464 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1
)
465 | SM(gainBoundaries
[1],
466 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2
)
467 | SM(gainBoundaries
[2],
468 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3
)
469 | SM(gainBoundaries
[3],
470 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4
));
473 regOffset
= AR_PHY_BASE
+ (672 << 2) + regChainOffset
;
474 for (j
= 0; j
< 32; j
++) {
475 reg32
= ((pdadcValues
[4 * j
+ 0] & 0xFF) << 0) |
476 ((pdadcValues
[4 * j
+ 1] & 0xFF) << 8) |
477 ((pdadcValues
[4 * j
+ 2] & 0xFF) << 16)|
478 ((pdadcValues
[4 * j
+ 3] & 0xFF) << 24);
479 REG_WRITE(ah
, regOffset
, reg32
);
481 ath_print(common
, ATH_DBG_EEPROM
,
482 "PDADC (%d,%4x): %4.4x %8.8x\n",
483 i
, regChainOffset
, regOffset
,
485 ath_print(common
, ATH_DBG_EEPROM
,
487 "PDADC %3d Value %3d | "
488 "PDADC %3d Value %3d | "
489 "PDADC %3d Value %3d | "
490 "PDADC %3d Value %3d |\n",
491 i
, 4 * j
, pdadcValues
[4 * j
],
492 4 * j
+ 1, pdadcValues
[4 * j
+ 1],
493 4 * j
+ 2, pdadcValues
[4 * j
+ 2],
495 pdadcValues
[4 * j
+ 3]);
500 REGWRITE_BUFFER_FLUSH(ah
);
501 DISABLE_REGWRITE_BUFFER(ah
);
505 *pTxPowerIndexOffset
= 0;
508 static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw
*ah
,
509 struct ath9k_channel
*chan
,
512 u16 AntennaReduction
,
513 u16 twiceMaxRegulatoryPower
,
516 #define CMP_TEST_GRP \
517 (((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) == \
518 pEepData->ctlIndex[i]) \
519 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
520 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
522 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
524 int16_t twiceLargestAntenna
;
525 u16 twiceMinEdgePower
;
526 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
527 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
528 u16 numCtlModes
, *pCtlMode
, ctlMode
, freq
;
529 struct chan_centers centers
;
530 struct cal_ctl_data_4k
*rep
;
531 struct ar5416_eeprom_4k
*pEepData
= &ah
->eeprom
.map4k
;
532 static const u16 tpScaleReductionTable
[5] =
533 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
534 struct cal_target_power_leg targetPowerOfdm
, targetPowerCck
= {
537 struct cal_target_power_leg targetPowerOfdmExt
= {
538 0, { 0, 0, 0, 0} }, targetPowerCckExt
= {
541 struct cal_target_power_ht targetPowerHt20
, targetPowerHt40
= {
544 u16 ctlModesFor11g
[] =
545 { CTL_11B
, CTL_11G
, CTL_2GHT20
, CTL_11B_EXT
, CTL_11G_EXT
,
549 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
551 twiceLargestAntenna
= pEepData
->modalHeader
.antennaGainCh
[0];
552 twiceLargestAntenna
= (int16_t)min(AntennaReduction
-
553 twiceLargestAntenna
, 0);
555 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
556 if (regulatory
->tp_scale
!= ATH9K_TP_SCALE_MAX
) {
557 maxRegAllowedPower
-=
558 (tpScaleReductionTable
[(regulatory
->tp_scale
)] * 2);
561 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
562 scaledPower
= max((u16
)0, scaledPower
);
564 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
) - SUB_NUM_CTL_MODES_AT_2G_40
;
565 pCtlMode
= ctlModesFor11g
;
567 ath9k_hw_get_legacy_target_powers(ah
, chan
,
568 pEepData
->calTargetPowerCck
,
569 AR5416_NUM_2G_CCK_TARGET_POWERS
,
570 &targetPowerCck
, 4, false);
571 ath9k_hw_get_legacy_target_powers(ah
, chan
,
572 pEepData
->calTargetPower2G
,
573 AR5416_NUM_2G_20_TARGET_POWERS
,
574 &targetPowerOfdm
, 4, false);
575 ath9k_hw_get_target_powers(ah
, chan
,
576 pEepData
->calTargetPower2GHT20
,
577 AR5416_NUM_2G_20_TARGET_POWERS
,
578 &targetPowerHt20
, 8, false);
580 if (IS_CHAN_HT40(chan
)) {
581 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
582 ath9k_hw_get_target_powers(ah
, chan
,
583 pEepData
->calTargetPower2GHT40
,
584 AR5416_NUM_2G_40_TARGET_POWERS
,
585 &targetPowerHt40
, 8, true);
586 ath9k_hw_get_legacy_target_powers(ah
, chan
,
587 pEepData
->calTargetPowerCck
,
588 AR5416_NUM_2G_CCK_TARGET_POWERS
,
589 &targetPowerCckExt
, 4, true);
590 ath9k_hw_get_legacy_target_powers(ah
, chan
,
591 pEepData
->calTargetPower2G
,
592 AR5416_NUM_2G_20_TARGET_POWERS
,
593 &targetPowerOfdmExt
, 4, true);
596 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
597 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
598 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
601 freq
= centers
.synth_center
;
602 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
603 freq
= centers
.ext_center
;
605 freq
= centers
.ctl_center
;
607 if (ah
->eep_ops
->get_eeprom_ver(ah
) == 14 &&
608 ah
->eep_ops
->get_eeprom_rev(ah
) <= 2)
609 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
611 for (i
= 0; (i
< AR5416_EEP4K_NUM_CTLS
) &&
612 pEepData
->ctlIndex
[i
]; i
++) {
615 rep
= &(pEepData
->ctlData
[i
]);
617 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(
620 ar5416_get_ntxchains(ah
->txchainmask
) - 1],
622 AR5416_EEP4K_NUM_BAND_EDGES
);
624 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
) {
626 min(twiceMaxEdgePower
,
629 twiceMaxEdgePower
= twiceMinEdgePower
;
635 minCtlPower
= (u8
)min(twiceMaxEdgePower
, scaledPower
);
637 switch (pCtlMode
[ctlMode
]) {
639 for (i
= 0; i
< ARRAY_SIZE(targetPowerCck
.tPow2x
); i
++) {
640 targetPowerCck
.tPow2x
[i
] =
641 min((u16
)targetPowerCck
.tPow2x
[i
],
646 for (i
= 0; i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
); i
++) {
647 targetPowerOfdm
.tPow2x
[i
] =
648 min((u16
)targetPowerOfdm
.tPow2x
[i
],
653 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++) {
654 targetPowerHt20
.tPow2x
[i
] =
655 min((u16
)targetPowerHt20
.tPow2x
[i
],
660 targetPowerCckExt
.tPow2x
[0] =
661 min((u16
)targetPowerCckExt
.tPow2x
[0],
665 targetPowerOfdmExt
.tPow2x
[0] =
666 min((u16
)targetPowerOfdmExt
.tPow2x
[0],
670 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
671 targetPowerHt40
.tPow2x
[i
] =
672 min((u16
)targetPowerHt40
.tPow2x
[i
],
681 ratesArray
[rate6mb
] =
682 ratesArray
[rate9mb
] =
683 ratesArray
[rate12mb
] =
684 ratesArray
[rate18mb
] =
685 ratesArray
[rate24mb
] =
686 targetPowerOfdm
.tPow2x
[0];
688 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
689 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
690 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
691 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
693 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
694 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
696 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
697 ratesArray
[rate2s
] = ratesArray
[rate2l
] = targetPowerCck
.tPow2x
[1];
698 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] = targetPowerCck
.tPow2x
[2];
699 ratesArray
[rate11s
] = ratesArray
[rate11l
] = targetPowerCck
.tPow2x
[3];
701 if (IS_CHAN_HT40(chan
)) {
702 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++) {
703 ratesArray
[rateHt40_0
+ i
] =
704 targetPowerHt40
.tPow2x
[i
];
706 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
707 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
708 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
709 ratesArray
[rateExtCck
] = targetPowerCckExt
.tPow2x
[0];
715 static void ath9k_hw_4k_set_txpower(struct ath_hw
*ah
,
716 struct ath9k_channel
*chan
,
718 u8 twiceAntennaReduction
,
719 u8 twiceMaxRegulatoryPower
,
722 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
723 struct ar5416_eeprom_4k
*pEepData
= &ah
->eeprom
.map4k
;
724 struct modal_eep_4k_header
*pModal
= &pEepData
->modalHeader
;
725 int16_t ratesArray
[Ar5416RateSize
];
726 int16_t txPowerIndexOffset
= 0;
727 u8 ht40PowerIncForPdadc
= 2;
730 memset(ratesArray
, 0, sizeof(ratesArray
));
732 if ((pEepData
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
733 AR5416_EEP_MINOR_VER_2
) {
734 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
737 ath9k_hw_set_4k_power_per_rate_table(ah
, chan
,
738 &ratesArray
[0], cfgCtl
,
739 twiceAntennaReduction
,
740 twiceMaxRegulatoryPower
,
743 ath9k_hw_set_4k_power_cal_table(ah
, chan
, &txPowerIndexOffset
);
745 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
746 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
747 if (ratesArray
[i
] > AR5416_MAX_RATE_POWER
)
748 ratesArray
[i
] = AR5416_MAX_RATE_POWER
;
752 /* Update regulatory */
755 if (IS_CHAN_HT40(chan
))
757 else if (IS_CHAN_HT20(chan
))
760 regulatory
->max_power_level
= ratesArray
[i
];
762 if (AR_SREV_9280_10_OR_LATER(ah
)) {
763 for (i
= 0; i
< Ar5416RateSize
; i
++)
764 ratesArray
[i
] -= AR5416_PWR_TABLE_OFFSET_DB
* 2;
767 ENABLE_REGWRITE_BUFFER(ah
);
769 /* OFDM power per rate */
770 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
771 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
772 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
773 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
774 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
775 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
776 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
777 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
778 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
779 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
781 /* CCK power per rate */
782 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
783 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
784 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
785 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
786 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
787 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
788 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
789 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
790 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
791 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
793 /* HT20 power per rate */
794 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
795 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
796 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
797 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
798 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
799 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
800 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
801 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
802 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
803 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
805 /* HT40 power per rate */
806 if (IS_CHAN_HT40(chan
)) {
807 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
808 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
809 ht40PowerIncForPdadc
, 24)
810 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
811 ht40PowerIncForPdadc
, 16)
812 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
813 ht40PowerIncForPdadc
, 8)
814 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
815 ht40PowerIncForPdadc
, 0));
816 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
817 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
818 ht40PowerIncForPdadc
, 24)
819 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
820 ht40PowerIncForPdadc
, 16)
821 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
822 ht40PowerIncForPdadc
, 8)
823 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
824 ht40PowerIncForPdadc
, 0));
825 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
826 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
827 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
828 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
829 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
832 REGWRITE_BUFFER_FLUSH(ah
);
833 DISABLE_REGWRITE_BUFFER(ah
);
836 static void ath9k_hw_4k_set_addac(struct ath_hw
*ah
,
837 struct ath9k_channel
*chan
)
839 struct modal_eep_4k_header
*pModal
;
840 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
843 if (ah
->hw_version
.macVersion
!= AR_SREV_VERSION_9160
)
846 if (ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_MINOR_VER_7
)
849 pModal
= &eep
->modalHeader
;
851 if (pModal
->xpaBiasLvl
!= 0xff) {
852 biaslevel
= pModal
->xpaBiasLvl
;
853 INI_RA(&ah
->iniAddac
, 7, 1) =
854 (INI_RA(&ah
->iniAddac
, 7, 1) & (~0x18)) | biaslevel
<< 3;
858 static void ath9k_hw_4k_set_gain(struct ath_hw
*ah
,
859 struct modal_eep_4k_header
*pModal
,
860 struct ar5416_eeprom_4k
*eep
,
863 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
,
864 pModal
->antCtrlChain
[0]);
866 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0),
867 (REG_READ(ah
, AR_PHY_TIMING_CTRL4(0)) &
868 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
869 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
870 SM(pModal
->iqCalICh
[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
871 SM(pModal
->iqCalQCh
[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
873 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
874 AR5416_EEP_MINOR_VER_3
) {
875 txRxAttenLocal
= pModal
->txRxAttenCh
[0];
877 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
878 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
, pModal
->bswMargin
[0]);
879 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
880 AR_PHY_GAIN_2GHZ_XATTEN1_DB
, pModal
->bswAtten
[0]);
881 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
882 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
883 pModal
->xatten2Margin
[0]);
884 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
,
885 AR_PHY_GAIN_2GHZ_XATTEN2_DB
, pModal
->xatten2Db
[0]);
887 /* Set the block 1 value to block 0 value */
888 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
889 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
890 pModal
->bswMargin
[0]);
891 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
892 AR_PHY_GAIN_2GHZ_XATTEN1_DB
, pModal
->bswAtten
[0]);
893 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
894 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN
,
895 pModal
->xatten2Margin
[0]);
896 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ 0x1000,
897 AR_PHY_GAIN_2GHZ_XATTEN2_DB
,
898 pModal
->xatten2Db
[0]);
901 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
,
902 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
903 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
,
904 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[0]);
906 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ 0x1000,
907 AR9280_PHY_RXGAIN_TXRX_ATTEN
, txRxAttenLocal
);
908 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ 0x1000,
909 AR9280_PHY_RXGAIN_TXRX_MARGIN
, pModal
->rxTxMarginCh
[0]);
911 if (AR_SREV_9285_11(ah
))
912 REG_WRITE(ah
, AR9285_AN_TOP4
, (AR9285_AN_TOP4_DEFAULT
| 0x14));
916 * Read EEPROM header info and program the device for correct operation
917 * given the channel value.
919 static void ath9k_hw_4k_set_board_values(struct ath_hw
*ah
,
920 struct ath9k_channel
*chan
)
922 struct modal_eep_4k_header
*pModal
;
923 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
925 u8 ob
[5], db1
[5], db2
[5];
926 u8 ant_div_control1
, ant_div_control2
;
929 pModal
= &eep
->modalHeader
;
932 REG_WRITE(ah
, AR_PHY_SWITCH_COM
,
933 ah
->eep_ops
->get_eeprom_antenna_cfg(ah
, chan
));
935 /* Single chain for 4K EEPROM*/
936 ath9k_hw_4k_set_gain(ah
, pModal
, eep
, txRxAttenLocal
);
938 /* Initialize Ant Diversity settings from EEPROM */
939 if (pModal
->version
>= 3) {
940 ant_div_control1
= pModal
->antdiv_ctl1
;
941 ant_div_control2
= pModal
->antdiv_ctl2
;
943 regVal
= REG_READ(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
);
944 regVal
&= (~(AR_PHY_9285_ANT_DIV_CTL_ALL
));
946 regVal
|= SM(ant_div_control1
,
947 AR_PHY_9285_ANT_DIV_CTL
);
948 regVal
|= SM(ant_div_control2
,
949 AR_PHY_9285_ANT_DIV_ALT_LNACONF
);
950 regVal
|= SM((ant_div_control2
>> 2),
951 AR_PHY_9285_ANT_DIV_MAIN_LNACONF
);
952 regVal
|= SM((ant_div_control1
>> 1),
953 AR_PHY_9285_ANT_DIV_ALT_GAINTB
);
954 regVal
|= SM((ant_div_control1
>> 2),
955 AR_PHY_9285_ANT_DIV_MAIN_GAINTB
);
958 REG_WRITE(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
, regVal
);
959 regVal
= REG_READ(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
);
960 regVal
= REG_READ(ah
, AR_PHY_CCK_DETECT
);
961 regVal
&= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV
);
962 regVal
|= SM((ant_div_control1
>> 3),
963 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV
);
965 REG_WRITE(ah
, AR_PHY_CCK_DETECT
, regVal
);
966 regVal
= REG_READ(ah
, AR_PHY_CCK_DETECT
);
969 if (pModal
->version
>= 2) {
970 ob
[0] = pModal
->ob_0
;
971 ob
[1] = pModal
->ob_1
;
972 ob
[2] = pModal
->ob_2
;
973 ob
[3] = pModal
->ob_3
;
974 ob
[4] = pModal
->ob_4
;
976 db1
[0] = pModal
->db1_0
;
977 db1
[1] = pModal
->db1_1
;
978 db1
[2] = pModal
->db1_2
;
979 db1
[3] = pModal
->db1_3
;
980 db1
[4] = pModal
->db1_4
;
982 db2
[0] = pModal
->db2_0
;
983 db2
[1] = pModal
->db2_1
;
984 db2
[2] = pModal
->db2_2
;
985 db2
[3] = pModal
->db2_3
;
986 db2
[4] = pModal
->db2_4
;
987 } else if (pModal
->version
== 1) {
988 ob
[0] = pModal
->ob_0
;
989 ob
[1] = ob
[2] = ob
[3] = ob
[4] = pModal
->ob_1
;
990 db1
[0] = pModal
->db1_0
;
991 db1
[1] = db1
[2] = db1
[3] = db1
[4] = pModal
->db1_1
;
992 db2
[0] = pModal
->db2_0
;
993 db2
[1] = db2
[2] = db2
[3] = db2
[4] = pModal
->db2_1
;
997 for (i
= 0; i
< 5; i
++) {
998 ob
[i
] = pModal
->ob_0
;
999 db1
[i
] = pModal
->db1_0
;
1000 db2
[i
] = pModal
->db1_0
;
1004 if (AR_SREV_9271(ah
)) {
1005 ath9k_hw_analog_shift_rmw(ah
,
1007 AR9271_AN_RF2G3_OB_cck
,
1008 AR9271_AN_RF2G3_OB_cck_S
,
1010 ath9k_hw_analog_shift_rmw(ah
,
1012 AR9271_AN_RF2G3_OB_psk
,
1013 AR9271_AN_RF2G3_OB_psk_S
,
1015 ath9k_hw_analog_shift_rmw(ah
,
1017 AR9271_AN_RF2G3_OB_qam
,
1018 AR9271_AN_RF2G3_OB_qam_S
,
1020 ath9k_hw_analog_shift_rmw(ah
,
1022 AR9271_AN_RF2G3_DB_1
,
1023 AR9271_AN_RF2G3_DB_1_S
,
1025 ath9k_hw_analog_shift_rmw(ah
,
1027 AR9271_AN_RF2G4_DB_2
,
1028 AR9271_AN_RF2G4_DB_2_S
,
1031 ath9k_hw_analog_shift_rmw(ah
,
1033 AR9285_AN_RF2G3_OB_0
,
1034 AR9285_AN_RF2G3_OB_0_S
,
1036 ath9k_hw_analog_shift_rmw(ah
,
1038 AR9285_AN_RF2G3_OB_1
,
1039 AR9285_AN_RF2G3_OB_1_S
,
1041 ath9k_hw_analog_shift_rmw(ah
,
1043 AR9285_AN_RF2G3_OB_2
,
1044 AR9285_AN_RF2G3_OB_2_S
,
1046 ath9k_hw_analog_shift_rmw(ah
,
1048 AR9285_AN_RF2G3_OB_3
,
1049 AR9285_AN_RF2G3_OB_3_S
,
1051 ath9k_hw_analog_shift_rmw(ah
,
1053 AR9285_AN_RF2G3_OB_4
,
1054 AR9285_AN_RF2G3_OB_4_S
,
1057 ath9k_hw_analog_shift_rmw(ah
,
1059 AR9285_AN_RF2G3_DB1_0
,
1060 AR9285_AN_RF2G3_DB1_0_S
,
1062 ath9k_hw_analog_shift_rmw(ah
,
1064 AR9285_AN_RF2G3_DB1_1
,
1065 AR9285_AN_RF2G3_DB1_1_S
,
1067 ath9k_hw_analog_shift_rmw(ah
,
1069 AR9285_AN_RF2G3_DB1_2
,
1070 AR9285_AN_RF2G3_DB1_2_S
,
1072 ath9k_hw_analog_shift_rmw(ah
,
1074 AR9285_AN_RF2G4_DB1_3
,
1075 AR9285_AN_RF2G4_DB1_3_S
,
1077 ath9k_hw_analog_shift_rmw(ah
,
1079 AR9285_AN_RF2G4_DB1_4
,
1080 AR9285_AN_RF2G4_DB1_4_S
, db1
[4]);
1082 ath9k_hw_analog_shift_rmw(ah
,
1084 AR9285_AN_RF2G4_DB2_0
,
1085 AR9285_AN_RF2G4_DB2_0_S
,
1087 ath9k_hw_analog_shift_rmw(ah
,
1089 AR9285_AN_RF2G4_DB2_1
,
1090 AR9285_AN_RF2G4_DB2_1_S
,
1092 ath9k_hw_analog_shift_rmw(ah
,
1094 AR9285_AN_RF2G4_DB2_2
,
1095 AR9285_AN_RF2G4_DB2_2_S
,
1097 ath9k_hw_analog_shift_rmw(ah
,
1099 AR9285_AN_RF2G4_DB2_3
,
1100 AR9285_AN_RF2G4_DB2_3_S
,
1102 ath9k_hw_analog_shift_rmw(ah
,
1104 AR9285_AN_RF2G4_DB2_4
,
1105 AR9285_AN_RF2G4_DB2_4_S
,
1110 if (AR_SREV_9285_11(ah
))
1111 REG_WRITE(ah
, AR9285_AN_TOP4
, AR9285_AN_TOP4_DEFAULT
);
1113 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
, AR_PHY_SETTLING_SWITCH
,
1114 pModal
->switchSettling
);
1115 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
, AR_PHY_DESIRED_SZ_ADC
,
1116 pModal
->adcDesiredSize
);
1118 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
1119 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
) |
1120 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAB_OFF
) |
1121 SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAA_ON
) |
1122 SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
1124 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
1125 pModal
->txEndToRxOn
);
1127 if (AR_SREV_9271_10(ah
))
1128 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
, AR_PHY_TX_END_TO_A2_RX_ON
,
1129 pModal
->txEndToRxOn
);
1130 REG_RMW_FIELD(ah
, AR_PHY_CCA
, AR9280_PHY_CCA_THRESH62
,
1132 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
, AR_PHY_EXT_CCA0_THRESH62
,
1135 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1136 AR5416_EEP_MINOR_VER_2
) {
1137 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_DATA_START
,
1138 pModal
->txFrameToDataStart
);
1139 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
, AR_PHY_TX_END_PA_ON
,
1140 pModal
->txFrameToPaOn
);
1143 if ((eep
->baseEepHeader
.version
& AR5416_EEP_VER_MINOR_MASK
) >=
1144 AR5416_EEP_MINOR_VER_3
) {
1145 if (IS_CHAN_HT40(chan
))
1146 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
1147 AR_PHY_SETTLING_SWITCH
,
1148 pModal
->swSettleHt40
);
1152 static u32
ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw
*ah
,
1153 struct ath9k_channel
*chan
)
1155 struct ar5416_eeprom_4k
*eep
= &ah
->eeprom
.map4k
;
1156 struct modal_eep_4k_header
*pModal
= &eep
->modalHeader
;
1158 return pModal
->antCtrlCommon
;
1161 static u8
ath9k_hw_4k_get_num_ant_config(struct ath_hw
*ah
,
1162 enum ieee80211_band freq_band
)
1167 static u16
ath9k_hw_4k_get_spur_channel(struct ath_hw
*ah
, u16 i
, bool is2GHz
)
1169 #define EEP_MAP4K_SPURCHAN \
1170 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
1171 struct ath_common
*common
= ath9k_hw_common(ah
);
1173 u16 spur_val
= AR_NO_SPUR
;
1175 ath_print(common
, ATH_DBG_ANI
,
1176 "Getting spur idx %d is2Ghz. %d val %x\n",
1177 i
, is2GHz
, ah
->config
.spurchans
[i
][is2GHz
]);
1179 switch (ah
->config
.spurmode
) {
1182 case SPUR_ENABLE_IOCTL
:
1183 spur_val
= ah
->config
.spurchans
[i
][is2GHz
];
1184 ath_print(common
, ATH_DBG_ANI
,
1185 "Getting spur val from new loc. %d\n", spur_val
);
1187 case SPUR_ENABLE_EEPROM
:
1188 spur_val
= EEP_MAP4K_SPURCHAN
;
1194 #undef EEP_MAP4K_SPURCHAN
1197 const struct eeprom_ops eep_4k_ops
= {
1198 .check_eeprom
= ath9k_hw_4k_check_eeprom
,
1199 .get_eeprom
= ath9k_hw_4k_get_eeprom
,
1200 .fill_eeprom
= ath9k_hw_4k_fill_eeprom
,
1201 .get_eeprom_ver
= ath9k_hw_4k_get_eeprom_ver
,
1202 .get_eeprom_rev
= ath9k_hw_4k_get_eeprom_rev
,
1203 .get_num_ant_config
= ath9k_hw_4k_get_num_ant_config
,
1204 .get_eeprom_antenna_cfg
= ath9k_hw_4k_get_eeprom_antenna_cfg
,
1205 .set_board_values
= ath9k_hw_4k_set_board_values
,
1206 .set_addac
= ath9k_hw_4k_set_addac
,
1207 .set_txpower
= ath9k_hw_4k_set_txpower
,
1208 .get_spur_channel
= ath9k_hw_4k_get_spur_channel