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_AR9287_get_eeprom_ver(struct ath_hw
*ah
)
21 return (ah
->eeprom
.map9287
.baseEepHeader
.version
>> 12) & 0xF;
24 static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw
*ah
)
26 return (ah
->eeprom
.map9287
.baseEepHeader
.version
) & 0xFFF;
29 static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw
*ah
)
31 struct ar9287_eeprom
*eep
= &ah
->eeprom
.map9287
;
32 struct ath_common
*common
= ath9k_hw_common(ah
);
34 int addr
, eep_start_loc
= AR9287_EEP_START_LOC
;
35 eep_data
= (u16
*)eep
;
37 if (!ath9k_hw_use_flash(ah
)) {
38 ath_print(common
, ATH_DBG_EEPROM
,
39 "Reading from EEPROM, not flash\n");
42 for (addr
= 0; addr
< sizeof(struct ar9287_eeprom
) / sizeof(u16
);
44 if (!ath9k_hw_nvram_read(common
,
45 addr
+ eep_start_loc
, eep_data
)) {
46 ath_print(common
, ATH_DBG_EEPROM
,
47 "Unable to read eeprom region \n");
55 static int ath9k_hw_AR9287_check_eeprom(struct ath_hw
*ah
)
57 u32 sum
= 0, el
, integer
;
58 u16 temp
, word
, magic
, magic2
, *eepdata
;
60 bool need_swap
= false;
61 struct ar9287_eeprom
*eep
= &ah
->eeprom
.map9287
;
62 struct ath_common
*common
= ath9k_hw_common(ah
);
64 if (!ath9k_hw_use_flash(ah
)) {
65 if (!ath9k_hw_nvram_read(common
,
66 AR5416_EEPROM_MAGIC_OFFSET
, &magic
)) {
67 ath_print(common
, ATH_DBG_FATAL
,
68 "Reading Magic # failed\n");
72 ath_print(common
, ATH_DBG_EEPROM
,
73 "Read Magic = 0x%04X\n", magic
);
74 if (magic
!= AR5416_EEPROM_MAGIC
) {
75 magic2
= swab16(magic
);
77 if (magic2
== AR5416_EEPROM_MAGIC
) {
79 eepdata
= (u16
*)(&ah
->eeprom
);
82 addr
< sizeof(struct ar9287_eeprom
) / sizeof(u16
);
84 temp
= swab16(*eepdata
);
89 ath_print(common
, ATH_DBG_FATAL
,
90 "Invalid EEPROM Magic. "
91 "endianness mismatch.\n");
96 ath_print(common
, ATH_DBG_EEPROM
, "need_swap = %s.\n", need_swap
?
100 el
= swab16(ah
->eeprom
.map9287
.baseEepHeader
.length
);
102 el
= ah
->eeprom
.map9287
.baseEepHeader
.length
;
104 if (el
> sizeof(struct ar9287_eeprom
))
105 el
= sizeof(struct ar9287_eeprom
) / sizeof(u16
);
107 el
= el
/ sizeof(u16
);
109 eepdata
= (u16
*)(&ah
->eeprom
);
110 for (i
= 0; i
< el
; i
++)
114 word
= swab16(eep
->baseEepHeader
.length
);
115 eep
->baseEepHeader
.length
= word
;
117 word
= swab16(eep
->baseEepHeader
.checksum
);
118 eep
->baseEepHeader
.checksum
= word
;
120 word
= swab16(eep
->baseEepHeader
.version
);
121 eep
->baseEepHeader
.version
= word
;
123 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
124 eep
->baseEepHeader
.regDmn
[0] = word
;
126 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
127 eep
->baseEepHeader
.regDmn
[1] = word
;
129 word
= swab16(eep
->baseEepHeader
.rfSilent
);
130 eep
->baseEepHeader
.rfSilent
= word
;
132 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
133 eep
->baseEepHeader
.blueToothOptions
= word
;
135 word
= swab16(eep
->baseEepHeader
.deviceCap
);
136 eep
->baseEepHeader
.deviceCap
= word
;
138 integer
= swab32(eep
->modalHeader
.antCtrlCommon
);
139 eep
->modalHeader
.antCtrlCommon
= integer
;
141 for (i
= 0; i
< AR9287_MAX_CHAINS
; i
++) {
142 integer
= swab32(eep
->modalHeader
.antCtrlChain
[i
]);
143 eep
->modalHeader
.antCtrlChain
[i
] = integer
;
146 for (i
= 0; i
< AR9287_EEPROM_MODAL_SPURS
; i
++) {
147 word
= swab16(eep
->modalHeader
.spurChans
[i
].spurChan
);
148 eep
->modalHeader
.spurChans
[i
].spurChan
= word
;
152 if (sum
!= 0xffff || ah
->eep_ops
->get_eeprom_ver(ah
) != AR9287_EEP_VER
153 || ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_NO_BACK_VER
) {
154 ath_print(common
, ATH_DBG_FATAL
,
155 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
156 sum
, ah
->eep_ops
->get_eeprom_ver(ah
));
163 static u32
ath9k_hw_AR9287_get_eeprom(struct ath_hw
*ah
,
164 enum eeprom_param param
)
166 struct ar9287_eeprom
*eep
= &ah
->eeprom
.map9287
;
167 struct modal_eep_ar9287_header
*pModal
= &eep
->modalHeader
;
168 struct base_eep_ar9287_header
*pBase
= &eep
->baseEepHeader
;
171 ver_minor
= pBase
->version
& AR9287_EEP_VER_MINOR_MASK
;
174 return pModal
->noiseFloorThreshCh
[0];
175 case AR_EEPROM_MAC(0):
176 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
177 case AR_EEPROM_MAC(1):
178 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
179 case AR_EEPROM_MAC(2):
180 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
182 return pBase
->regDmn
[0];
184 return pBase
->regDmn
[1];
186 return pBase
->deviceCap
;
188 return pBase
->opCapFlags
;
190 return pBase
->rfSilent
;
194 return pBase
->txMask
;
196 return pBase
->rxMask
;
198 return pBase
->deviceType
;
200 return pBase
->openLoopPwrCntl
;
201 case EEP_TEMPSENSE_SLOPE
:
202 if (ver_minor
>= AR9287_EEP_MINOR_VER_2
)
203 return pBase
->tempSensSlope
;
206 case EEP_TEMPSENSE_SLOPE_PAL_ON
:
207 if (ver_minor
>= AR9287_EEP_MINOR_VER_3
)
208 return pBase
->tempSensSlopePalOn
;
217 static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw
*ah
,
218 struct ath9k_channel
*chan
,
219 struct cal_data_per_freq_ar9287
*pRawDataSet
,
220 u8
*bChans
, u16 availPiers
,
221 u16 tPdGainOverlap
, int16_t *pMinCalPower
,
222 u16
*pPdGainBoundaries
, u8
*pPDADCValues
,
225 #define TMP_VAL_VPD_TABLE \
226 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
230 u16 idxL
= 0, idxR
= 0, numPiers
;
231 u8
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
232 u8 minPwrT4
[AR9287_NUM_PD_GAINS
];
233 u8 maxPwrT4
[AR9287_NUM_PD_GAINS
];
236 u16 sizeCurrVpdTable
, maxIndex
, tgtIndex
;
238 int16_t minDelta
= 0;
239 struct chan_centers centers
;
240 static u8 vpdTableL
[AR5416_EEP4K_NUM_PD_GAINS
]
241 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
242 static u8 vpdTableR
[AR5416_EEP4K_NUM_PD_GAINS
]
243 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
244 static u8 vpdTableI
[AR5416_EEP4K_NUM_PD_GAINS
]
245 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
247 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
249 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
250 if (bChans
[numPiers
] == AR9287_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 AR9287_PD_GAIN_ICEPTS
, vpdTableI
[i
]);
269 for (i
= 0; i
< numXpdGains
; i
++) {
270 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
271 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
272 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
273 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
275 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
278 min(pPwrL
[AR9287_PD_GAIN_ICEPTS
- 1],
279 pPwrR
[AR9287_PD_GAIN_ICEPTS
- 1]);
281 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
283 AR9287_PD_GAIN_ICEPTS
,
285 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
287 AR9287_PD_GAIN_ICEPTS
,
290 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
292 (u8
)(ath9k_hw_interpolate((u16
)
293 FREQ2FBIN(centers
. synth_center
,
295 bChans
[idxL
], bChans
[idxR
],
296 vpdTableL
[i
][j
], vpdTableR
[i
][j
]));
300 *pMinCalPower
= (int16_t)(minPwrT4
[0] / 2);
303 for (i
= 0; i
< numXpdGains
; i
++) {
304 if (i
== (numXpdGains
- 1))
305 pPdGainBoundaries
[i
] = (u16
)(maxPwrT4
[i
] / 2);
307 pPdGainBoundaries
[i
] = (u16
)((maxPwrT4
[i
] +
310 pPdGainBoundaries
[i
] = min((u16
)AR5416_MAX_RATE_POWER
,
311 pPdGainBoundaries
[i
]);
314 if ((i
== 0) && !AR_SREV_5416_20_OR_LATER(ah
)) {
315 minDelta
= pPdGainBoundaries
[0] - 23;
316 pPdGainBoundaries
[0] = 23;
321 if (AR_SREV_9280_10_OR_LATER(ah
))
322 ss
= (int16_t)(0 - (minPwrT4
[i
] / 2));
326 ss
= (int16_t)((pPdGainBoundaries
[i
-1] -
328 tPdGainOverlap
+ 1 + minDelta
);
330 vpdStep
= (int16_t)(vpdTableI
[i
][1] - vpdTableI
[i
][0]);
331 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
332 while ((ss
< 0) && (k
< (AR9287_NUM_PDADC_VALUES
- 1))) {
333 tmpVal
= (int16_t)(vpdTableI
[i
][0] + ss
* vpdStep
);
334 pPDADCValues
[k
++] = (u8
)((tmpVal
< 0) ? 0 : tmpVal
);
338 sizeCurrVpdTable
= (u8
)((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
339 tgtIndex
= (u8
)(pPdGainBoundaries
[i
] +
340 tPdGainOverlap
- (minPwrT4
[i
] / 2));
341 maxIndex
= (tgtIndex
< sizeCurrVpdTable
) ?
342 tgtIndex
: sizeCurrVpdTable
;
344 while ((ss
< maxIndex
) && (k
< (AR9287_NUM_PDADC_VALUES
- 1)))
345 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
347 vpdStep
= (int16_t)(vpdTableI
[i
][sizeCurrVpdTable
- 1] -
348 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
349 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
350 if (tgtIndex
> maxIndex
) {
351 while ((ss
<= tgtIndex
) &&
352 (k
< (AR9287_NUM_PDADC_VALUES
- 1))) {
353 tmpVal
= (int16_t) TMP_VAL_VPD_TABLE
;
354 pPDADCValues
[k
++] = (u8
)((tmpVal
> 255) ?
361 while (i
< AR9287_PD_GAINS_IN_MASK
) {
362 pPdGainBoundaries
[i
] = pPdGainBoundaries
[i
-1];
366 while (k
< AR9287_NUM_PDADC_VALUES
) {
367 pPDADCValues
[k
] = pPDADCValues
[k
-1];
371 #undef TMP_VAL_VPD_TABLE
374 static void ar9287_eeprom_get_tx_gain_index(struct ath_hw
*ah
,
375 struct ath9k_channel
*chan
,
376 struct cal_data_op_loop_ar9287
*pRawDatasetOpLoop
,
377 u8
*pCalChans
, u16 availPiers
,
380 u16 idxL
= 0, idxR
= 0, numPiers
;
382 struct chan_centers centers
;
384 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
386 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
387 if (pCalChans
[numPiers
] == AR9287_BCHAN_UNUSED
)
391 match
= ath9k_hw_get_lower_upper_index(
392 (u8
)FREQ2FBIN(centers
.synth_center
, IS_CHAN_2GHZ(chan
)),
397 *pPwr
= (int8_t) pRawDatasetOpLoop
[idxL
].pwrPdg
[0][0];
399 *pPwr
= ((int8_t) pRawDatasetOpLoop
[idxL
].pwrPdg
[0][0] +
400 (int8_t) pRawDatasetOpLoop
[idxR
].pwrPdg
[0][0])/2;
405 static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw
*ah
,
406 int32_t txPower
, u16 chain
)
411 tmpVal
= REG_READ(ah
, 0xa270);
412 tmpVal
= tmpVal
& 0xFCFFFFFF;
413 tmpVal
= tmpVal
| (0x3 << 24);
414 REG_WRITE(ah
, 0xa270, tmpVal
);
416 tmpVal
= REG_READ(ah
, 0xb270);
417 tmpVal
= tmpVal
& 0xFCFFFFFF;
418 tmpVal
= tmpVal
| (0x3 << 24);
419 REG_WRITE(ah
, 0xb270, tmpVal
);
422 tmpVal
= REG_READ(ah
, 0xa398);
423 tmpVal
= tmpVal
& 0xff00ffff;
425 tmpVal
= tmpVal
| (a
<< 16);
426 REG_WRITE(ah
, 0xa398, tmpVal
);
430 tmpVal
= REG_READ(ah
, 0xb398);
431 tmpVal
= tmpVal
& 0xff00ffff;
433 tmpVal
= tmpVal
| (a
<< 16);
434 REG_WRITE(ah
, 0xb398, tmpVal
);
438 static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw
*ah
,
439 struct ath9k_channel
*chan
,
440 int16_t *pTxPowerIndexOffset
)
442 struct ath_common
*common
= ath9k_hw_common(ah
);
443 struct cal_data_per_freq_ar9287
*pRawDataset
;
444 struct cal_data_op_loop_ar9287
*pRawDatasetOpenLoop
;
445 u8
*pCalBChans
= NULL
;
446 u16 pdGainOverlap_t2
;
447 u8 pdadcValues
[AR9287_NUM_PDADC_VALUES
];
448 u16 gainBoundaries
[AR9287_PD_GAINS_IN_MASK
];
449 u16 numPiers
= 0, i
, j
;
450 int16_t tMinCalPower
;
451 u16 numXpdGain
, xpdMask
;
452 u16 xpdGainValues
[AR9287_NUM_PD_GAINS
] = {0, 0, 0, 0};
453 u32 reg32
, regOffset
, regChainOffset
;
454 int16_t modalIdx
, diff
= 0;
455 struct ar9287_eeprom
*pEepData
= &ah
->eeprom
.map9287
;
456 modalIdx
= IS_CHAN_2GHZ(chan
) ? 1 : 0;
457 xpdMask
= pEepData
->modalHeader
.xpdGain
;
458 if ((pEepData
->baseEepHeader
.version
& AR9287_EEP_VER_MINOR_MASK
) >=
459 AR9287_EEP_MINOR_VER_2
)
460 pdGainOverlap_t2
= pEepData
->modalHeader
.pdGainOverlap
;
462 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
463 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
465 if (IS_CHAN_2GHZ(chan
)) {
466 pCalBChans
= pEepData
->calFreqPier2G
;
467 numPiers
= AR9287_NUM_2G_CAL_PIERS
;
468 if (ath9k_hw_AR9287_get_eeprom(ah
, EEP_OL_PWRCTRL
)) {
469 pRawDatasetOpenLoop
=
470 (struct cal_data_op_loop_ar9287
*)
471 pEepData
->calPierData2G
[0];
472 ah
->initPDADC
= pRawDatasetOpenLoop
->vpdPdg
[0][0];
477 for (i
= 1; i
<= AR9287_PD_GAINS_IN_MASK
; i
++) {
478 if ((xpdMask
>> (AR9287_PD_GAINS_IN_MASK
- i
)) & 1) {
479 if (numXpdGain
>= AR9287_NUM_PD_GAINS
)
481 xpdGainValues
[numXpdGain
] =
482 (u16
)(AR9287_PD_GAINS_IN_MASK
-i
);
487 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
488 (numXpdGain
- 1) & 0x3);
489 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
491 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
493 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
,
496 for (i
= 0; i
< AR9287_MAX_CHAINS
; i
++) {
497 regChainOffset
= i
* 0x1000;
498 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
499 pRawDatasetOpenLoop
= (struct cal_data_op_loop_ar9287
*)
500 pEepData
->calPierData2G
[i
];
501 if (ath9k_hw_AR9287_get_eeprom(ah
, EEP_OL_PWRCTRL
)) {
503 ar9287_eeprom_get_tx_gain_index(ah
, chan
,
505 pCalBChans
, numPiers
,
507 ar9287_eeprom_olpc_set_pdadcs(ah
, txPower
, i
);
510 (struct cal_data_per_freq_ar9287
*)
511 pEepData
->calPierData2G
[i
];
512 ath9k_hw_get_AR9287_gain_boundaries_pdadcs(
513 ah
, chan
, pRawDataset
,
514 pCalBChans
, numPiers
,
516 &tMinCalPower
, gainBoundaries
,
517 pdadcValues
, numXpdGain
);
521 if (!ath9k_hw_AR9287_get_eeprom(
522 ah
, EEP_OL_PWRCTRL
)) {
523 REG_WRITE(ah
, AR_PHY_TPCRG5
+
526 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
) |
527 SM(gainBoundaries
[0],
528 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1
)
529 | SM(gainBoundaries
[1],
530 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2
)
531 | SM(gainBoundaries
[2],
532 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3
)
533 | SM(gainBoundaries
[3],
534 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4
));
538 if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB
!=
539 pEepData
->baseEepHeader
.pwrTableOffset
) {
541 (pEepData
->baseEepHeader
.pwrTableOffset
542 - (int32_t)AR9287_PWR_TABLE_OFFSET_DB
);
546 j
< ((u16
)AR9287_NUM_PDADC_VALUES
-diff
);
548 pdadcValues
[j
] = pdadcValues
[j
+diff
];
550 for (j
= (u16
)(AR9287_NUM_PDADC_VALUES
-diff
);
551 j
< AR9287_NUM_PDADC_VALUES
; j
++)
554 AR9287_NUM_PDADC_VALUES
-diff
];
557 if (!ath9k_hw_AR9287_get_eeprom(ah
, EEP_OL_PWRCTRL
)) {
558 regOffset
= AR_PHY_BASE
+ (672 << 2) +
560 for (j
= 0; j
< 32; j
++) {
561 reg32
= ((pdadcValues
[4*j
+ 0]
563 ((pdadcValues
[4*j
+ 1]
565 ((pdadcValues
[4*j
+ 2]
567 ((pdadcValues
[4*j
+ 3]
569 REG_WRITE(ah
, regOffset
, reg32
);
571 ath_print(common
, ATH_DBG_EEPROM
,
572 "PDADC (%d,%4x): %4.4x "
574 i
, regChainOffset
, regOffset
,
577 ath_print(common
, ATH_DBG_EEPROM
,
579 "PDADC %3d Value %3d | "
580 "PDADC %3d Value %3d | "
581 "PDADC %3d Value %3d | "
582 "PDADC %3d Value %3d |\n",
583 i
, 4 * j
, pdadcValues
[4 * j
],
585 pdadcValues
[4 * j
+ 1],
587 pdadcValues
[4 * j
+ 2],
589 pdadcValues
[4 * j
+ 3]);
597 *pTxPowerIndexOffset
= 0;
600 static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw
*ah
,
601 struct ath9k_channel
*chan
, int16_t *ratesArray
, u16 cfgCtl
,
602 u16 AntennaReduction
, u16 twiceMaxRegulatoryPower
,
605 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
606 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
607 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
608 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
609 static const u16 tpScaleReductionTable
[5] =
610 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
612 int16_t twiceLargestAntenna
;
613 struct cal_ctl_data_ar9287
*rep
;
614 struct cal_target_power_leg targetPowerOfdm
= {0, {0, 0, 0, 0} },
615 targetPowerCck
= {0, {0, 0, 0, 0} };
616 struct cal_target_power_leg targetPowerOfdmExt
= {0, {0, 0, 0, 0} },
617 targetPowerCckExt
= {0, {0, 0, 0, 0} };
618 struct cal_target_power_ht targetPowerHt20
,
619 targetPowerHt40
= {0, {0, 0, 0, 0} };
620 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
621 u16 ctlModesFor11g
[] =
622 {CTL_11B
, CTL_11G
, CTL_2GHT20
,
623 CTL_11B_EXT
, CTL_11G_EXT
, CTL_2GHT40
};
624 u16 numCtlModes
= 0, *pCtlMode
= NULL
, ctlMode
, freq
;
625 struct chan_centers centers
;
627 u16 twiceMinEdgePower
;
628 struct ar9287_eeprom
*pEepData
= &ah
->eeprom
.map9287
;
629 tx_chainmask
= ah
->txchainmask
;
631 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
633 twiceLargestAntenna
= max(pEepData
->modalHeader
.antennaGainCh
[0],
634 pEepData
->modalHeader
.antennaGainCh
[1]);
636 twiceLargestAntenna
= (int16_t)min((AntennaReduction
) -
637 twiceLargestAntenna
, 0);
639 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
640 if (regulatory
->tp_scale
!= ATH9K_TP_SCALE_MAX
)
641 maxRegAllowedPower
-=
642 (tpScaleReductionTable
[(regulatory
->tp_scale
)] * 2);
644 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
646 switch (ar5416_get_ntxchains(tx_chainmask
)) {
650 scaledPower
-= REDUCE_SCALED_POWER_BY_TWO_CHAIN
;
653 scaledPower
-= REDUCE_SCALED_POWER_BY_THREE_CHAIN
;
656 scaledPower
= max((u16
)0, scaledPower
);
658 if (IS_CHAN_2GHZ(chan
)) {
660 ARRAY_SIZE(ctlModesFor11g
) - SUB_NUM_CTL_MODES_AT_2G_40
;
661 pCtlMode
= ctlModesFor11g
;
663 ath9k_hw_get_legacy_target_powers(ah
, chan
,
664 pEepData
->calTargetPowerCck
,
665 AR9287_NUM_2G_CCK_TARGET_POWERS
,
666 &targetPowerCck
, 4, false);
667 ath9k_hw_get_legacy_target_powers(ah
, chan
,
668 pEepData
->calTargetPower2G
,
669 AR9287_NUM_2G_20_TARGET_POWERS
,
670 &targetPowerOfdm
, 4, false);
671 ath9k_hw_get_target_powers(ah
, chan
,
672 pEepData
->calTargetPower2GHT20
,
673 AR9287_NUM_2G_20_TARGET_POWERS
,
674 &targetPowerHt20
, 8, false);
676 if (IS_CHAN_HT40(chan
)) {
677 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
678 ath9k_hw_get_target_powers(ah
, chan
,
679 pEepData
->calTargetPower2GHT40
,
680 AR9287_NUM_2G_40_TARGET_POWERS
,
681 &targetPowerHt40
, 8, true);
682 ath9k_hw_get_legacy_target_powers(ah
, chan
,
683 pEepData
->calTargetPowerCck
,
684 AR9287_NUM_2G_CCK_TARGET_POWERS
,
685 &targetPowerCckExt
, 4, true);
686 ath9k_hw_get_legacy_target_powers(ah
, chan
,
687 pEepData
->calTargetPower2G
,
688 AR9287_NUM_2G_20_TARGET_POWERS
,
689 &targetPowerOfdmExt
, 4, true);
693 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
694 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
695 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
697 freq
= centers
.synth_center
;
698 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
699 freq
= centers
.ext_center
;
701 freq
= centers
.ctl_center
;
703 if (ah
->eep_ops
->get_eeprom_ver(ah
) == 14 &&
704 ah
->eep_ops
->get_eeprom_rev(ah
) <= 2)
705 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
707 for (i
= 0; (i
< AR9287_NUM_CTLS
) && pEepData
->ctlIndex
[i
]; i
++) {
708 if ((((cfgCtl
& ~CTL_MODE_M
) |
709 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
710 pEepData
->ctlIndex
[i
]) ||
711 (((cfgCtl
& ~CTL_MODE_M
) |
712 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
713 ((pEepData
->ctlIndex
[i
] &
714 CTL_MODE_M
) | SD_NO_CTL
))) {
716 rep
= &(pEepData
->ctlData
[i
]);
717 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(
719 rep
->ctlEdges
[ar5416_get_ntxchains(
721 IS_CHAN_2GHZ(chan
), AR5416_NUM_BAND_EDGES
);
723 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
)
724 twiceMaxEdgePower
= min(
728 twiceMaxEdgePower
= twiceMinEdgePower
;
734 minCtlPower
= (u8
)min(twiceMaxEdgePower
, scaledPower
);
736 switch (pCtlMode
[ctlMode
]) {
739 i
< ARRAY_SIZE(targetPowerCck
.tPow2x
);
741 targetPowerCck
.tPow2x
[i
] = (u8
)min(
742 (u16
)targetPowerCck
.tPow2x
[i
],
749 i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
);
751 targetPowerOfdm
.tPow2x
[i
] = (u8
)min(
752 (u16
)targetPowerOfdm
.tPow2x
[i
],
759 i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
);
761 targetPowerHt20
.tPow2x
[i
] = (u8
)min(
762 (u16
)targetPowerHt20
.tPow2x
[i
],
767 targetPowerCckExt
.tPow2x
[0] = (u8
)min(
768 (u16
)targetPowerCckExt
.tPow2x
[0],
773 targetPowerOfdmExt
.tPow2x
[0] = (u8
)min(
774 (u16
)targetPowerOfdmExt
.tPow2x
[0],
780 i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
);
782 targetPowerHt40
.tPow2x
[i
] = (u8
)min(
783 (u16
)targetPowerHt40
.tPow2x
[i
],
792 ratesArray
[rate6mb
] =
793 ratesArray
[rate9mb
] =
794 ratesArray
[rate12mb
] =
795 ratesArray
[rate18mb
] =
796 ratesArray
[rate24mb
] =
797 targetPowerOfdm
.tPow2x
[0];
799 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
800 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
801 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
802 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
804 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
805 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
807 if (IS_CHAN_2GHZ(chan
)) {
808 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
809 ratesArray
[rate2s
] = ratesArray
[rate2l
] =
810 targetPowerCck
.tPow2x
[1];
811 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] =
812 targetPowerCck
.tPow2x
[2];
813 ratesArray
[rate11s
] = ratesArray
[rate11l
] =
814 targetPowerCck
.tPow2x
[3];
816 if (IS_CHAN_HT40(chan
)) {
817 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++)
818 ratesArray
[rateHt40_0
+ i
] = targetPowerHt40
.tPow2x
[i
];
820 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
821 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
822 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
823 if (IS_CHAN_2GHZ(chan
))
824 ratesArray
[rateExtCck
] = targetPowerCckExt
.tPow2x
[0];
827 #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
828 #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
831 static void ath9k_hw_AR9287_set_txpower(struct ath_hw
*ah
,
832 struct ath9k_channel
*chan
, u16 cfgCtl
,
833 u8 twiceAntennaReduction
,
834 u8 twiceMaxRegulatoryPower
,
837 #define INCREASE_MAXPOW_BY_TWO_CHAIN 6
838 #define INCREASE_MAXPOW_BY_THREE_CHAIN 10
839 struct ath_common
*common
= ath9k_hw_common(ah
);
840 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
841 struct ar9287_eeprom
*pEepData
= &ah
->eeprom
.map9287
;
842 struct modal_eep_ar9287_header
*pModal
= &pEepData
->modalHeader
;
843 int16_t ratesArray
[Ar5416RateSize
];
844 int16_t txPowerIndexOffset
= 0;
845 u8 ht40PowerIncForPdadc
= 2;
848 memset(ratesArray
, 0, sizeof(ratesArray
));
850 if ((pEepData
->baseEepHeader
.version
& AR9287_EEP_VER_MINOR_MASK
) >=
851 AR9287_EEP_MINOR_VER_2
)
852 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
854 ath9k_hw_set_AR9287_power_per_rate_table(ah
, chan
,
855 &ratesArray
[0], cfgCtl
,
856 twiceAntennaReduction
,
857 twiceMaxRegulatoryPower
,
860 ath9k_hw_set_AR9287_power_cal_table(ah
, chan
, &txPowerIndexOffset
);
862 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
863 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
864 if (ratesArray
[i
] > AR9287_MAX_RATE_POWER
)
865 ratesArray
[i
] = AR9287_MAX_RATE_POWER
;
868 if (AR_SREV_9280_10_OR_LATER(ah
)) {
869 for (i
= 0; i
< Ar5416RateSize
; i
++)
870 ratesArray
[i
] -= AR9287_PWR_TABLE_OFFSET_DB
* 2;
873 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
874 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
875 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
876 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
877 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
879 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
880 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
881 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
882 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
883 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
885 if (IS_CHAN_2GHZ(chan
)) {
886 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
887 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
888 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
889 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
890 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
891 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
892 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
893 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
894 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
895 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
898 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
899 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
900 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
901 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
902 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
904 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
905 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
906 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
907 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
908 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
910 if (IS_CHAN_HT40(chan
)) {
911 if (ath9k_hw_AR9287_get_eeprom(ah
, EEP_OL_PWRCTRL
)) {
912 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
913 ATH9K_POW_SM(ratesArray
[rateHt40_3
], 24)
914 | ATH9K_POW_SM(ratesArray
[rateHt40_2
], 16)
915 | ATH9K_POW_SM(ratesArray
[rateHt40_1
], 8)
916 | ATH9K_POW_SM(ratesArray
[rateHt40_0
], 0));
918 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
919 ATH9K_POW_SM(ratesArray
[rateHt40_7
], 24)
920 | ATH9K_POW_SM(ratesArray
[rateHt40_6
], 16)
921 | ATH9K_POW_SM(ratesArray
[rateHt40_5
], 8)
922 | ATH9K_POW_SM(ratesArray
[rateHt40_4
], 0));
924 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
925 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
926 ht40PowerIncForPdadc
, 24)
927 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
928 ht40PowerIncForPdadc
, 16)
929 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
930 ht40PowerIncForPdadc
, 8)
931 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
932 ht40PowerIncForPdadc
, 0));
934 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
935 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
936 ht40PowerIncForPdadc
, 24)
937 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
938 ht40PowerIncForPdadc
, 16)
939 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
940 ht40PowerIncForPdadc
, 8)
941 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
942 ht40PowerIncForPdadc
, 0));
945 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
946 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
947 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
948 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
949 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
952 if (IS_CHAN_2GHZ(chan
))
957 if (AR_SREV_9280_10_OR_LATER(ah
))
958 regulatory
->max_power_level
=
959 ratesArray
[i
] + AR9287_PWR_TABLE_OFFSET_DB
* 2;
961 regulatory
->max_power_level
= ratesArray
[i
];
963 switch (ar5416_get_ntxchains(ah
->txchainmask
)) {
967 regulatory
->max_power_level
+=
968 INCREASE_MAXPOW_BY_TWO_CHAIN
;
971 regulatory
->max_power_level
+=
972 INCREASE_MAXPOW_BY_THREE_CHAIN
;
975 ath_print(common
, ATH_DBG_EEPROM
,
976 "Invalid chainmask configuration\n");
981 static void ath9k_hw_AR9287_set_addac(struct ath_hw
*ah
,
982 struct ath9k_channel
*chan
)
986 static void ath9k_hw_AR9287_set_board_values(struct ath_hw
*ah
,
987 struct ath9k_channel
*chan
)
989 struct ar9287_eeprom
*eep
= &ah
->eeprom
.map9287
;
990 struct modal_eep_ar9287_header
*pModal
= &eep
->modalHeader
;
991 u16 antWrites
[AR9287_ANT_16S
];
994 int i
, j
, offset_num
;
996 pModal
= &eep
->modalHeader
;
998 antWrites
[0] = (u16
)((pModal
->antCtrlCommon
>> 28) & 0xF);
999 antWrites
[1] = (u16
)((pModal
->antCtrlCommon
>> 24) & 0xF);
1000 antWrites
[2] = (u16
)((pModal
->antCtrlCommon
>> 20) & 0xF);
1001 antWrites
[3] = (u16
)((pModal
->antCtrlCommon
>> 16) & 0xF);
1002 antWrites
[4] = (u16
)((pModal
->antCtrlCommon
>> 12) & 0xF);
1003 antWrites
[5] = (u16
)((pModal
->antCtrlCommon
>> 8) & 0xF);
1004 antWrites
[6] = (u16
)((pModal
->antCtrlCommon
>> 4) & 0xF);
1005 antWrites
[7] = (u16
)(pModal
->antCtrlCommon
& 0xF);
1009 for (i
= 0, j
= offset_num
; i
< AR9287_MAX_CHAINS
; i
++) {
1010 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 28) & 0xf);
1011 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 10) & 0x3);
1012 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 8) & 0x3);
1014 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 6) & 0x3);
1015 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 4) & 0x3);
1016 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 2) & 0x3);
1017 antWrites
[j
++] = (u16
)(pModal
->antCtrlChain
[i
] & 0x3);
1020 REG_WRITE(ah
, AR_PHY_SWITCH_COM
,
1021 ah
->eep_ops
->get_eeprom_antenna_cfg(ah
, chan
));
1023 for (i
= 0; i
< AR9287_MAX_CHAINS
; i
++) {
1024 regChainOffset
= i
* 0x1000;
1026 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
+ regChainOffset
,
1027 pModal
->antCtrlChain
[i
]);
1029 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
,
1030 (REG_READ(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
)
1031 & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
1032 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
1033 SM(pModal
->iqCalICh
[i
],
1034 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
1035 SM(pModal
->iqCalQCh
[i
],
1036 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
1038 txRxAttenLocal
= pModal
->txRxAttenCh
[i
];
1040 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
1041 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
1042 pModal
->bswMargin
[i
]);
1043 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
1044 AR_PHY_GAIN_2GHZ_XATTEN1_DB
,
1045 pModal
->bswAtten
[i
]);
1046 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ regChainOffset
,
1047 AR9280_PHY_RXGAIN_TXRX_ATTEN
,
1049 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ regChainOffset
,
1050 AR9280_PHY_RXGAIN_TXRX_MARGIN
,
1051 pModal
->rxTxMarginCh
[i
]);
1055 if (IS_CHAN_HT40(chan
))
1056 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
1057 AR_PHY_SETTLING_SWITCH
, pModal
->swSettleHt40
);
1059 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
1060 AR_PHY_SETTLING_SWITCH
, pModal
->switchSettling
);
1062 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
,
1063 AR_PHY_DESIRED_SZ_ADC
, pModal
->adcDesiredSize
);
1065 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
1066 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
)
1067 | SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAB_OFF
)
1068 | SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAA_ON
)
1069 | SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
1071 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
,
1072 AR_PHY_TX_END_TO_A2_RX_ON
, pModal
->txEndToRxOn
);
1074 REG_RMW_FIELD(ah
, AR_PHY_CCA
,
1075 AR9280_PHY_CCA_THRESH62
, pModal
->thresh62
);
1076 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
,
1077 AR_PHY_EXT_CCA0_THRESH62
, pModal
->thresh62
);
1079 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
, AR9287_AN_RF2G3_DB1
,
1080 AR9287_AN_RF2G3_DB1_S
, pModal
->db1
);
1081 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
, AR9287_AN_RF2G3_DB2
,
1082 AR9287_AN_RF2G3_DB2_S
, pModal
->db2
);
1083 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
,
1084 AR9287_AN_RF2G3_OB_CCK
,
1085 AR9287_AN_RF2G3_OB_CCK_S
, pModal
->ob_cck
);
1086 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
,
1087 AR9287_AN_RF2G3_OB_PSK
,
1088 AR9287_AN_RF2G3_OB_PSK_S
, pModal
->ob_psk
);
1089 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
,
1090 AR9287_AN_RF2G3_OB_QAM
,
1091 AR9287_AN_RF2G3_OB_QAM_S
, pModal
->ob_qam
);
1092 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
,
1093 AR9287_AN_RF2G3_OB_PAL_OFF
,
1094 AR9287_AN_RF2G3_OB_PAL_OFF_S
,
1095 pModal
->ob_pal_off
);
1097 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1098 AR9287_AN_RF2G3_DB1
, AR9287_AN_RF2G3_DB1_S
,
1100 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
, AR9287_AN_RF2G3_DB2
,
1101 AR9287_AN_RF2G3_DB2_S
, pModal
->db2
);
1102 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1103 AR9287_AN_RF2G3_OB_CCK
,
1104 AR9287_AN_RF2G3_OB_CCK_S
, pModal
->ob_cck
);
1105 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1106 AR9287_AN_RF2G3_OB_PSK
,
1107 AR9287_AN_RF2G3_OB_PSK_S
, pModal
->ob_psk
);
1108 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1109 AR9287_AN_RF2G3_OB_QAM
,
1110 AR9287_AN_RF2G3_OB_QAM_S
, pModal
->ob_qam
);
1111 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1112 AR9287_AN_RF2G3_OB_PAL_OFF
,
1113 AR9287_AN_RF2G3_OB_PAL_OFF_S
,
1114 pModal
->ob_pal_off
);
1116 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
,
1117 AR_PHY_TX_END_DATA_START
, pModal
->txFrameToDataStart
);
1118 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
,
1119 AR_PHY_TX_END_PA_ON
, pModal
->txFrameToPaOn
);
1121 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_TOP2
,
1122 AR9287_AN_TOP2_XPABIAS_LVL
,
1123 AR9287_AN_TOP2_XPABIAS_LVL_S
,
1124 pModal
->xpaBiasLvl
);
1127 static u8
ath9k_hw_AR9287_get_num_ant_config(struct ath_hw
*ah
,
1128 enum ieee80211_band freq_band
)
1133 static u16
ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw
*ah
,
1134 struct ath9k_channel
*chan
)
1136 struct ar9287_eeprom
*eep
= &ah
->eeprom
.map9287
;
1137 struct modal_eep_ar9287_header
*pModal
= &eep
->modalHeader
;
1139 return pModal
->antCtrlCommon
& 0xFFFF;
1142 static u16
ath9k_hw_AR9287_get_spur_channel(struct ath_hw
*ah
,
1145 #define EEP_MAP9287_SPURCHAN \
1146 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
1147 struct ath_common
*common
= ath9k_hw_common(ah
);
1148 u16 spur_val
= AR_NO_SPUR
;
1150 ath_print(common
, ATH_DBG_ANI
,
1151 "Getting spur idx %d is2Ghz. %d val %x\n",
1152 i
, is2GHz
, ah
->config
.spurchans
[i
][is2GHz
]);
1154 switch (ah
->config
.spurmode
) {
1157 case SPUR_ENABLE_IOCTL
:
1158 spur_val
= ah
->config
.spurchans
[i
][is2GHz
];
1159 ath_print(common
, ATH_DBG_ANI
,
1160 "Getting spur val from new loc. %d\n", spur_val
);
1162 case SPUR_ENABLE_EEPROM
:
1163 spur_val
= EEP_MAP9287_SPURCHAN
;
1169 #undef EEP_MAP9287_SPURCHAN
1172 const struct eeprom_ops eep_AR9287_ops
= {
1173 .check_eeprom
= ath9k_hw_AR9287_check_eeprom
,
1174 .get_eeprom
= ath9k_hw_AR9287_get_eeprom
,
1175 .fill_eeprom
= ath9k_hw_AR9287_fill_eeprom
,
1176 .get_eeprom_ver
= ath9k_hw_AR9287_get_eeprom_ver
,
1177 .get_eeprom_rev
= ath9k_hw_AR9287_get_eeprom_rev
,
1178 .get_num_ant_config
= ath9k_hw_AR9287_get_num_ant_config
,
1179 .get_eeprom_antenna_cfg
= ath9k_hw_AR9287_get_eeprom_antenna_cfg
,
1180 .set_board_values
= ath9k_hw_AR9287_set_board_values
,
1181 .set_addac
= ath9k_hw_AR9287_set_addac
,
1182 .set_txpower
= ath9k_hw_AR9287_set_txpower
,
1183 .get_spur_channel
= ath9k_hw_AR9287_get_spur_channel