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
;
33 int addr
, eep_start_loc
= AR9287_EEP_START_LOC
;
34 eep_data
= (u16
*)eep
;
36 if (!ath9k_hw_use_flash(ah
)) {
37 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
38 "Reading from EEPROM, not flash\n");
41 for (addr
= 0; addr
< sizeof(struct ar9287_eeprom
) / sizeof(u16
);
43 if (!ath9k_hw_nvram_read(ah
, addr
+ eep_start_loc
, eep_data
)) {
44 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
45 "Unable to read eeprom region \n");
53 static int ath9k_hw_AR9287_check_eeprom(struct ath_hw
*ah
)
55 u32 sum
= 0, el
, integer
;
56 u16 temp
, word
, magic
, magic2
, *eepdata
;
58 bool need_swap
= false;
59 struct ar9287_eeprom
*eep
= &ah
->eeprom
.map9287
;
61 if (!ath9k_hw_use_flash(ah
)) {
62 if (!ath9k_hw_nvram_read
63 (ah
, AR5416_EEPROM_MAGIC_OFFSET
, &magic
)) {
64 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
65 "Reading Magic # failed\n");
69 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
70 "Read Magic = 0x%04X\n", magic
);
71 if (magic
!= AR5416_EEPROM_MAGIC
) {
72 magic2
= swab16(magic
);
74 if (magic2
== AR5416_EEPROM_MAGIC
) {
76 eepdata
= (u16
*)(&ah
->eeprom
);
79 addr
< sizeof(struct ar9287_eeprom
) / sizeof(u16
);
81 temp
= swab16(*eepdata
);
86 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
87 "Invalid EEPROM Magic. "
88 "endianness mismatch.\n");
93 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
, "need_swap = %s.\n", need_swap
?
97 el
= swab16(ah
->eeprom
.map9287
.baseEepHeader
.length
);
99 el
= ah
->eeprom
.map9287
.baseEepHeader
.length
;
101 if (el
> sizeof(struct ar9287_eeprom
))
102 el
= sizeof(struct ar9287_eeprom
) / sizeof(u16
);
104 el
= el
/ sizeof(u16
);
106 eepdata
= (u16
*)(&ah
->eeprom
);
107 for (i
= 0; i
< el
; i
++)
111 word
= swab16(eep
->baseEepHeader
.length
);
112 eep
->baseEepHeader
.length
= word
;
114 word
= swab16(eep
->baseEepHeader
.checksum
);
115 eep
->baseEepHeader
.checksum
= word
;
117 word
= swab16(eep
->baseEepHeader
.version
);
118 eep
->baseEepHeader
.version
= word
;
120 word
= swab16(eep
->baseEepHeader
.regDmn
[0]);
121 eep
->baseEepHeader
.regDmn
[0] = word
;
123 word
= swab16(eep
->baseEepHeader
.regDmn
[1]);
124 eep
->baseEepHeader
.regDmn
[1] = word
;
126 word
= swab16(eep
->baseEepHeader
.rfSilent
);
127 eep
->baseEepHeader
.rfSilent
= word
;
129 word
= swab16(eep
->baseEepHeader
.blueToothOptions
);
130 eep
->baseEepHeader
.blueToothOptions
= word
;
132 word
= swab16(eep
->baseEepHeader
.deviceCap
);
133 eep
->baseEepHeader
.deviceCap
= word
;
135 integer
= swab32(eep
->modalHeader
.antCtrlCommon
);
136 eep
->modalHeader
.antCtrlCommon
= integer
;
138 for (i
= 0; i
< AR9287_MAX_CHAINS
; i
++) {
139 integer
= swab32(eep
->modalHeader
.antCtrlChain
[i
]);
140 eep
->modalHeader
.antCtrlChain
[i
] = integer
;
143 for (i
= 0; i
< AR9287_EEPROM_MODAL_SPURS
; i
++) {
144 word
= swab16(eep
->modalHeader
.spurChans
[i
].spurChan
);
145 eep
->modalHeader
.spurChans
[i
].spurChan
= word
;
149 if (sum
!= 0xffff || ah
->eep_ops
->get_eeprom_ver(ah
) != AR9287_EEP_VER
150 || ah
->eep_ops
->get_eeprom_rev(ah
) < AR5416_EEP_NO_BACK_VER
) {
151 DPRINTF(ah
->ah_sc
, ATH_DBG_FATAL
,
152 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
153 sum
, ah
->eep_ops
->get_eeprom_ver(ah
));
160 static u32
ath9k_hw_AR9287_get_eeprom(struct ath_hw
*ah
,
161 enum eeprom_param param
)
163 struct ar9287_eeprom
*eep
= &ah
->eeprom
.map9287
;
164 struct modal_eep_ar9287_header
*pModal
= &eep
->modalHeader
;
165 struct base_eep_ar9287_header
*pBase
= &eep
->baseEepHeader
;
168 ver_minor
= pBase
->version
& AR9287_EEP_VER_MINOR_MASK
;
171 return pModal
->noiseFloorThreshCh
[0];
172 case AR_EEPROM_MAC(0):
173 return pBase
->macAddr
[0] << 8 | pBase
->macAddr
[1];
174 case AR_EEPROM_MAC(1):
175 return pBase
->macAddr
[2] << 8 | pBase
->macAddr
[3];
176 case AR_EEPROM_MAC(2):
177 return pBase
->macAddr
[4] << 8 | pBase
->macAddr
[5];
179 return pBase
->regDmn
[0];
181 return pBase
->regDmn
[1];
183 return pBase
->deviceCap
;
185 return pBase
->opCapFlags
;
187 return pBase
->rfSilent
;
191 return pBase
->txMask
;
193 return pBase
->rxMask
;
195 return pBase
->deviceType
;
197 return pBase
->openLoopPwrCntl
;
198 case EEP_TEMPSENSE_SLOPE
:
199 if (ver_minor
>= AR9287_EEP_MINOR_VER_2
)
200 return pBase
->tempSensSlope
;
203 case EEP_TEMPSENSE_SLOPE_PAL_ON
:
204 if (ver_minor
>= AR9287_EEP_MINOR_VER_3
)
205 return pBase
->tempSensSlopePalOn
;
214 static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw
*ah
,
215 struct ath9k_channel
*chan
,
216 struct cal_data_per_freq_ar9287
*pRawDataSet
,
217 u8
*bChans
, u16 availPiers
,
218 u16 tPdGainOverlap
, int16_t *pMinCalPower
,
219 u16
*pPdGainBoundaries
, u8
*pPDADCValues
,
222 #define TMP_VAL_VPD_TABLE \
223 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
227 u16 idxL
= 0, idxR
= 0, numPiers
;
228 u8
*pVpdL
, *pVpdR
, *pPwrL
, *pPwrR
;
229 u8 minPwrT4
[AR9287_NUM_PD_GAINS
];
230 u8 maxPwrT4
[AR9287_NUM_PD_GAINS
];
233 u16 sizeCurrVpdTable
, maxIndex
, tgtIndex
;
235 int16_t minDelta
= 0;
236 struct chan_centers centers
;
237 static u8 vpdTableL
[AR5416_EEP4K_NUM_PD_GAINS
]
238 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
239 static u8 vpdTableR
[AR5416_EEP4K_NUM_PD_GAINS
]
240 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
241 static u8 vpdTableI
[AR5416_EEP4K_NUM_PD_GAINS
]
242 [AR5416_MAX_PWR_RANGE_IN_HALF_DB
];
244 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
246 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
247 if (bChans
[numPiers
] == AR9287_BCHAN_UNUSED
)
251 match
= ath9k_hw_get_lower_upper_index(
252 (u8
)FREQ2FBIN(centers
.synth_center
,
253 IS_CHAN_2GHZ(chan
)), bChans
, numPiers
,
257 for (i
= 0; i
< numXpdGains
; i
++) {
258 minPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][0];
259 maxPwrT4
[i
] = pRawDataSet
[idxL
].pwrPdg
[i
][4];
260 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
261 pRawDataSet
[idxL
].pwrPdg
[i
],
262 pRawDataSet
[idxL
].vpdPdg
[i
],
263 AR9287_PD_GAIN_ICEPTS
, vpdTableI
[i
]);
266 for (i
= 0; i
< numXpdGains
; i
++) {
267 pVpdL
= pRawDataSet
[idxL
].vpdPdg
[i
];
268 pPwrL
= pRawDataSet
[idxL
].pwrPdg
[i
];
269 pVpdR
= pRawDataSet
[idxR
].vpdPdg
[i
];
270 pPwrR
= pRawDataSet
[idxR
].pwrPdg
[i
];
272 minPwrT4
[i
] = max(pPwrL
[0], pPwrR
[0]);
275 min(pPwrL
[AR9287_PD_GAIN_ICEPTS
- 1],
276 pPwrR
[AR9287_PD_GAIN_ICEPTS
- 1]);
278 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
280 AR9287_PD_GAIN_ICEPTS
,
282 ath9k_hw_fill_vpd_table(minPwrT4
[i
], maxPwrT4
[i
],
284 AR9287_PD_GAIN_ICEPTS
,
287 for (j
= 0; j
<= (maxPwrT4
[i
] - minPwrT4
[i
]) / 2; j
++) {
289 (u8
)(ath9k_hw_interpolate((u16
)
290 FREQ2FBIN(centers
. synth_center
,
292 bChans
[idxL
], bChans
[idxR
],
293 vpdTableL
[i
][j
], vpdTableR
[i
][j
]));
297 *pMinCalPower
= (int16_t)(minPwrT4
[0] / 2);
300 for (i
= 0; i
< numXpdGains
; i
++) {
301 if (i
== (numXpdGains
- 1))
302 pPdGainBoundaries
[i
] = (u16
)(maxPwrT4
[i
] / 2);
304 pPdGainBoundaries
[i
] = (u16
)((maxPwrT4
[i
] +
307 pPdGainBoundaries
[i
] = min((u16
)AR5416_MAX_RATE_POWER
,
308 pPdGainBoundaries
[i
]);
311 if ((i
== 0) && !AR_SREV_5416_20_OR_LATER(ah
)) {
312 minDelta
= pPdGainBoundaries
[0] - 23;
313 pPdGainBoundaries
[0] = 23;
318 if (AR_SREV_9280_10_OR_LATER(ah
))
319 ss
= (int16_t)(0 - (minPwrT4
[i
] / 2));
323 ss
= (int16_t)((pPdGainBoundaries
[i
-1] -
325 tPdGainOverlap
+ 1 + minDelta
);
327 vpdStep
= (int16_t)(vpdTableI
[i
][1] - vpdTableI
[i
][0]);
328 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
329 while ((ss
< 0) && (k
< (AR9287_NUM_PDADC_VALUES
- 1))) {
330 tmpVal
= (int16_t)(vpdTableI
[i
][0] + ss
* vpdStep
);
331 pPDADCValues
[k
++] = (u8
)((tmpVal
< 0) ? 0 : tmpVal
);
335 sizeCurrVpdTable
= (u8
)((maxPwrT4
[i
] - minPwrT4
[i
]) / 2 + 1);
336 tgtIndex
= (u8
)(pPdGainBoundaries
[i
] +
337 tPdGainOverlap
- (minPwrT4
[i
] / 2));
338 maxIndex
= (tgtIndex
< sizeCurrVpdTable
) ?
339 tgtIndex
: sizeCurrVpdTable
;
341 while ((ss
< maxIndex
) && (k
< (AR9287_NUM_PDADC_VALUES
- 1)))
342 pPDADCValues
[k
++] = vpdTableI
[i
][ss
++];
344 vpdStep
= (int16_t)(vpdTableI
[i
][sizeCurrVpdTable
- 1] -
345 vpdTableI
[i
][sizeCurrVpdTable
- 2]);
346 vpdStep
= (int16_t)((vpdStep
< 1) ? 1 : vpdStep
);
347 if (tgtIndex
> maxIndex
) {
348 while ((ss
<= tgtIndex
) &&
349 (k
< (AR9287_NUM_PDADC_VALUES
- 1))) {
350 tmpVal
= (int16_t) TMP_VAL_VPD_TABLE
;
351 pPDADCValues
[k
++] = (u8
)((tmpVal
> 255) ?
358 while (i
< AR9287_PD_GAINS_IN_MASK
) {
359 pPdGainBoundaries
[i
] = pPdGainBoundaries
[i
-1];
363 while (k
< AR9287_NUM_PDADC_VALUES
) {
364 pPDADCValues
[k
] = pPDADCValues
[k
-1];
368 #undef TMP_VAL_VPD_TABLE
371 static void ar9287_eeprom_get_tx_gain_index(struct ath_hw
*ah
,
372 struct ath9k_channel
*chan
,
373 struct cal_data_op_loop_ar9287
*pRawDatasetOpLoop
,
374 u8
*pCalChans
, u16 availPiers
,
377 u16 idxL
= 0, idxR
= 0, numPiers
;
379 struct chan_centers centers
;
381 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
383 for (numPiers
= 0; numPiers
< availPiers
; numPiers
++) {
384 if (pCalChans
[numPiers
] == AR9287_BCHAN_UNUSED
)
388 match
= ath9k_hw_get_lower_upper_index(
389 (u8
)FREQ2FBIN(centers
.synth_center
, IS_CHAN_2GHZ(chan
)),
394 *pPwr
= (int8_t) pRawDatasetOpLoop
[idxL
].pwrPdg
[0][0];
396 *pPwr
= ((int8_t) pRawDatasetOpLoop
[idxL
].pwrPdg
[0][0] +
397 (int8_t) pRawDatasetOpLoop
[idxR
].pwrPdg
[0][0])/2;
402 static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw
*ah
,
403 int32_t txPower
, u16 chain
)
408 tmpVal
= REG_READ(ah
, 0xa270);
409 tmpVal
= tmpVal
& 0xFCFFFFFF;
410 tmpVal
= tmpVal
| (0x3 << 24);
411 REG_WRITE(ah
, 0xa270, tmpVal
);
413 tmpVal
= REG_READ(ah
, 0xb270);
414 tmpVal
= tmpVal
& 0xFCFFFFFF;
415 tmpVal
= tmpVal
| (0x3 << 24);
416 REG_WRITE(ah
, 0xb270, tmpVal
);
419 tmpVal
= REG_READ(ah
, 0xa398);
420 tmpVal
= tmpVal
& 0xff00ffff;
422 tmpVal
= tmpVal
| (a
<< 16);
423 REG_WRITE(ah
, 0xa398, tmpVal
);
427 tmpVal
= REG_READ(ah
, 0xb398);
428 tmpVal
= tmpVal
& 0xff00ffff;
430 tmpVal
= tmpVal
| (a
<< 16);
431 REG_WRITE(ah
, 0xb398, tmpVal
);
435 static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw
*ah
,
436 struct ath9k_channel
*chan
,
437 int16_t *pTxPowerIndexOffset
)
439 struct cal_data_per_freq_ar9287
*pRawDataset
;
440 struct cal_data_op_loop_ar9287
*pRawDatasetOpenLoop
;
441 u8
*pCalBChans
= NULL
;
442 u16 pdGainOverlap_t2
;
443 u8 pdadcValues
[AR9287_NUM_PDADC_VALUES
];
444 u16 gainBoundaries
[AR9287_PD_GAINS_IN_MASK
];
445 u16 numPiers
= 0, i
, j
;
446 int16_t tMinCalPower
;
447 u16 numXpdGain
, xpdMask
;
448 u16 xpdGainValues
[AR9287_NUM_PD_GAINS
] = {0, 0, 0, 0};
449 u32 reg32
, regOffset
, regChainOffset
;
450 int16_t modalIdx
, diff
= 0;
451 struct ar9287_eeprom
*pEepData
= &ah
->eeprom
.map9287
;
452 modalIdx
= IS_CHAN_2GHZ(chan
) ? 1 : 0;
453 xpdMask
= pEepData
->modalHeader
.xpdGain
;
454 if ((pEepData
->baseEepHeader
.version
& AR9287_EEP_VER_MINOR_MASK
) >=
455 AR9287_EEP_MINOR_VER_2
)
456 pdGainOverlap_t2
= pEepData
->modalHeader
.pdGainOverlap
;
458 pdGainOverlap_t2
= (u16
)(MS(REG_READ(ah
, AR_PHY_TPCRG5
),
459 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
));
461 if (IS_CHAN_2GHZ(chan
)) {
462 pCalBChans
= pEepData
->calFreqPier2G
;
463 numPiers
= AR9287_NUM_2G_CAL_PIERS
;
464 if (ath9k_hw_AR9287_get_eeprom(ah
, EEP_OL_PWRCTRL
)) {
465 pRawDatasetOpenLoop
=
466 (struct cal_data_op_loop_ar9287
*)
467 pEepData
->calPierData2G
[0];
468 ah
->initPDADC
= pRawDatasetOpenLoop
->vpdPdg
[0][0];
473 for (i
= 1; i
<= AR9287_PD_GAINS_IN_MASK
; i
++) {
474 if ((xpdMask
>> (AR9287_PD_GAINS_IN_MASK
- i
)) & 1) {
475 if (numXpdGain
>= AR9287_NUM_PD_GAINS
)
477 xpdGainValues
[numXpdGain
] =
478 (u16
)(AR9287_PD_GAINS_IN_MASK
-i
);
483 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_NUM_PD_GAIN
,
484 (numXpdGain
- 1) & 0x3);
485 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_1
,
487 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_2
,
489 REG_RMW_FIELD(ah
, AR_PHY_TPCRG1
, AR_PHY_TPCRG1_PD_GAIN_3
,
492 for (i
= 0; i
< AR9287_MAX_CHAINS
; i
++) {
493 regChainOffset
= i
* 0x1000;
494 if (pEepData
->baseEepHeader
.txMask
& (1 << i
)) {
495 pRawDatasetOpenLoop
= (struct cal_data_op_loop_ar9287
*)
496 pEepData
->calPierData2G
[i
];
497 if (ath9k_hw_AR9287_get_eeprom(ah
, EEP_OL_PWRCTRL
)) {
499 ar9287_eeprom_get_tx_gain_index(ah
, chan
,
501 pCalBChans
, numPiers
,
503 ar9287_eeprom_olpc_set_pdadcs(ah
, txPower
, i
);
506 (struct cal_data_per_freq_ar9287
*)
507 pEepData
->calPierData2G
[i
];
508 ath9k_hw_get_AR9287_gain_boundaries_pdadcs(
509 ah
, chan
, pRawDataset
,
510 pCalBChans
, numPiers
,
512 &tMinCalPower
, gainBoundaries
,
513 pdadcValues
, numXpdGain
);
517 if (!ath9k_hw_AR9287_get_eeprom(
518 ah
, EEP_OL_PWRCTRL
)) {
519 REG_WRITE(ah
, AR_PHY_TPCRG5
+
522 AR_PHY_TPCRG5_PD_GAIN_OVERLAP
) |
523 SM(gainBoundaries
[0],
524 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1
)
525 | SM(gainBoundaries
[1],
526 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2
)
527 | SM(gainBoundaries
[2],
528 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3
)
529 | SM(gainBoundaries
[3],
530 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4
));
534 if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB
!=
535 pEepData
->baseEepHeader
.pwrTableOffset
) {
537 (pEepData
->baseEepHeader
.pwrTableOffset
538 - (int32_t)AR9287_PWR_TABLE_OFFSET_DB
);
542 j
< ((u16
)AR9287_NUM_PDADC_VALUES
-diff
);
544 pdadcValues
[j
] = pdadcValues
[j
+diff
];
546 for (j
= (u16
)(AR9287_NUM_PDADC_VALUES
-diff
);
547 j
< AR9287_NUM_PDADC_VALUES
; j
++)
550 AR9287_NUM_PDADC_VALUES
-diff
];
553 if (!ath9k_hw_AR9287_get_eeprom(ah
, EEP_OL_PWRCTRL
)) {
554 regOffset
= AR_PHY_BASE
+ (672 << 2) +
556 for (j
= 0; j
< 32; j
++) {
557 reg32
= ((pdadcValues
[4*j
+ 0]
559 ((pdadcValues
[4*j
+ 1]
561 ((pdadcValues
[4*j
+ 2]
563 ((pdadcValues
[4*j
+ 3]
565 REG_WRITE(ah
, regOffset
, reg32
);
567 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
568 "PDADC (%d,%4x): %4.4x %8.8x\n",
569 i
, regChainOffset
, regOffset
,
572 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
574 "PDADC %3d Value %3d | "
575 "PDADC %3d Value %3d | "
576 "PDADC %3d Value %3d | "
577 "PDADC %3d Value %3d |\n",
578 i
, 4 * j
, pdadcValues
[4 * j
],
580 pdadcValues
[4 * j
+ 1],
582 pdadcValues
[4 * j
+ 2],
584 pdadcValues
[4 * j
+ 3]);
592 *pTxPowerIndexOffset
= 0;
595 static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw
*ah
,
596 struct ath9k_channel
*chan
, int16_t *ratesArray
, u16 cfgCtl
,
597 u16 AntennaReduction
, u16 twiceMaxRegulatoryPower
,
600 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
601 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
602 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
603 u16 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
604 static const u16 tpScaleReductionTable
[5] =
605 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER
};
607 int16_t twiceLargestAntenna
;
608 struct cal_ctl_data_ar9287
*rep
;
609 struct cal_target_power_leg targetPowerOfdm
= {0, {0, 0, 0, 0} },
610 targetPowerCck
= {0, {0, 0, 0, 0} };
611 struct cal_target_power_leg targetPowerOfdmExt
= {0, {0, 0, 0, 0} },
612 targetPowerCckExt
= {0, {0, 0, 0, 0} };
613 struct cal_target_power_ht targetPowerHt20
,
614 targetPowerHt40
= {0, {0, 0, 0, 0} };
615 u16 scaledPower
= 0, minCtlPower
, maxRegAllowedPower
;
616 u16 ctlModesFor11g
[] =
617 {CTL_11B
, CTL_11G
, CTL_2GHT20
,
618 CTL_11B_EXT
, CTL_11G_EXT
, CTL_2GHT40
};
619 u16 numCtlModes
= 0, *pCtlMode
= NULL
, ctlMode
, freq
;
620 struct chan_centers centers
;
622 u16 twiceMinEdgePower
;
623 struct ar9287_eeprom
*pEepData
= &ah
->eeprom
.map9287
;
624 tx_chainmask
= ah
->txchainmask
;
626 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
628 twiceLargestAntenna
= max(pEepData
->modalHeader
.antennaGainCh
[0],
629 pEepData
->modalHeader
.antennaGainCh
[1]);
631 twiceLargestAntenna
= (int16_t)min((AntennaReduction
) -
632 twiceLargestAntenna
, 0);
634 maxRegAllowedPower
= twiceMaxRegulatoryPower
+ twiceLargestAntenna
;
635 if (regulatory
->tp_scale
!= ATH9K_TP_SCALE_MAX
)
636 maxRegAllowedPower
-=
637 (tpScaleReductionTable
[(regulatory
->tp_scale
)] * 2);
639 scaledPower
= min(powerLimit
, maxRegAllowedPower
);
641 switch (ar5416_get_ntxchains(tx_chainmask
)) {
645 scaledPower
-= REDUCE_SCALED_POWER_BY_TWO_CHAIN
;
648 scaledPower
-= REDUCE_SCALED_POWER_BY_THREE_CHAIN
;
651 scaledPower
= max((u16
)0, scaledPower
);
653 if (IS_CHAN_2GHZ(chan
)) {
655 ARRAY_SIZE(ctlModesFor11g
) - SUB_NUM_CTL_MODES_AT_2G_40
;
656 pCtlMode
= ctlModesFor11g
;
658 ath9k_hw_get_legacy_target_powers(ah
, chan
,
659 pEepData
->calTargetPowerCck
,
660 AR9287_NUM_2G_CCK_TARGET_POWERS
,
661 &targetPowerCck
, 4, false);
662 ath9k_hw_get_legacy_target_powers(ah
, chan
,
663 pEepData
->calTargetPower2G
,
664 AR9287_NUM_2G_20_TARGET_POWERS
,
665 &targetPowerOfdm
, 4, false);
666 ath9k_hw_get_target_powers(ah
, chan
,
667 pEepData
->calTargetPower2GHT20
,
668 AR9287_NUM_2G_20_TARGET_POWERS
,
669 &targetPowerHt20
, 8, false);
671 if (IS_CHAN_HT40(chan
)) {
672 numCtlModes
= ARRAY_SIZE(ctlModesFor11g
);
673 ath9k_hw_get_target_powers(ah
, chan
,
674 pEepData
->calTargetPower2GHT40
,
675 AR9287_NUM_2G_40_TARGET_POWERS
,
676 &targetPowerHt40
, 8, true);
677 ath9k_hw_get_legacy_target_powers(ah
, chan
,
678 pEepData
->calTargetPowerCck
,
679 AR9287_NUM_2G_CCK_TARGET_POWERS
,
680 &targetPowerCckExt
, 4, true);
681 ath9k_hw_get_legacy_target_powers(ah
, chan
,
682 pEepData
->calTargetPower2G
,
683 AR9287_NUM_2G_20_TARGET_POWERS
,
684 &targetPowerOfdmExt
, 4, true);
688 for (ctlMode
= 0; ctlMode
< numCtlModes
; ctlMode
++) {
689 bool isHt40CtlMode
= (pCtlMode
[ctlMode
] == CTL_5GHT40
) ||
690 (pCtlMode
[ctlMode
] == CTL_2GHT40
);
692 freq
= centers
.synth_center
;
693 else if (pCtlMode
[ctlMode
] & EXT_ADDITIVE
)
694 freq
= centers
.ext_center
;
696 freq
= centers
.ctl_center
;
698 if (ah
->eep_ops
->get_eeprom_ver(ah
) == 14 &&
699 ah
->eep_ops
->get_eeprom_rev(ah
) <= 2)
700 twiceMaxEdgePower
= AR5416_MAX_RATE_POWER
;
702 for (i
= 0; (i
< AR9287_NUM_CTLS
) && pEepData
->ctlIndex
[i
]; i
++) {
703 if ((((cfgCtl
& ~CTL_MODE_M
) |
704 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
705 pEepData
->ctlIndex
[i
]) ||
706 (((cfgCtl
& ~CTL_MODE_M
) |
707 (pCtlMode
[ctlMode
] & CTL_MODE_M
)) ==
708 ((pEepData
->ctlIndex
[i
] &
709 CTL_MODE_M
) | SD_NO_CTL
))) {
711 rep
= &(pEepData
->ctlData
[i
]);
712 twiceMinEdgePower
= ath9k_hw_get_max_edge_power(
714 rep
->ctlEdges
[ar5416_get_ntxchains(
716 IS_CHAN_2GHZ(chan
), AR5416_NUM_BAND_EDGES
);
718 if ((cfgCtl
& ~CTL_MODE_M
) == SD_NO_CTL
)
719 twiceMaxEdgePower
= min(
723 twiceMaxEdgePower
= twiceMinEdgePower
;
729 minCtlPower
= (u8
)min(twiceMaxEdgePower
, scaledPower
);
731 switch (pCtlMode
[ctlMode
]) {
734 i
< ARRAY_SIZE(targetPowerCck
.tPow2x
);
736 targetPowerCck
.tPow2x
[i
] = (u8
)min(
737 (u16
)targetPowerCck
.tPow2x
[i
],
744 i
< ARRAY_SIZE(targetPowerOfdm
.tPow2x
);
746 targetPowerOfdm
.tPow2x
[i
] = (u8
)min(
747 (u16
)targetPowerOfdm
.tPow2x
[i
],
754 i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
);
756 targetPowerHt20
.tPow2x
[i
] = (u8
)min(
757 (u16
)targetPowerHt20
.tPow2x
[i
],
762 targetPowerCckExt
.tPow2x
[0] = (u8
)min(
763 (u16
)targetPowerCckExt
.tPow2x
[0],
768 targetPowerOfdmExt
.tPow2x
[0] = (u8
)min(
769 (u16
)targetPowerOfdmExt
.tPow2x
[0],
775 i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
);
777 targetPowerHt40
.tPow2x
[i
] = (u8
)min(
778 (u16
)targetPowerHt40
.tPow2x
[i
],
787 ratesArray
[rate6mb
] =
788 ratesArray
[rate9mb
] =
789 ratesArray
[rate12mb
] =
790 ratesArray
[rate18mb
] =
791 ratesArray
[rate24mb
] =
792 targetPowerOfdm
.tPow2x
[0];
794 ratesArray
[rate36mb
] = targetPowerOfdm
.tPow2x
[1];
795 ratesArray
[rate48mb
] = targetPowerOfdm
.tPow2x
[2];
796 ratesArray
[rate54mb
] = targetPowerOfdm
.tPow2x
[3];
797 ratesArray
[rateXr
] = targetPowerOfdm
.tPow2x
[0];
799 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt20
.tPow2x
); i
++)
800 ratesArray
[rateHt20_0
+ i
] = targetPowerHt20
.tPow2x
[i
];
802 if (IS_CHAN_2GHZ(chan
)) {
803 ratesArray
[rate1l
] = targetPowerCck
.tPow2x
[0];
804 ratesArray
[rate2s
] = ratesArray
[rate2l
] =
805 targetPowerCck
.tPow2x
[1];
806 ratesArray
[rate5_5s
] = ratesArray
[rate5_5l
] =
807 targetPowerCck
.tPow2x
[2];
808 ratesArray
[rate11s
] = ratesArray
[rate11l
] =
809 targetPowerCck
.tPow2x
[3];
811 if (IS_CHAN_HT40(chan
)) {
812 for (i
= 0; i
< ARRAY_SIZE(targetPowerHt40
.tPow2x
); i
++)
813 ratesArray
[rateHt40_0
+ i
] = targetPowerHt40
.tPow2x
[i
];
815 ratesArray
[rateDupOfdm
] = targetPowerHt40
.tPow2x
[0];
816 ratesArray
[rateDupCck
] = targetPowerHt40
.tPow2x
[0];
817 ratesArray
[rateExtOfdm
] = targetPowerOfdmExt
.tPow2x
[0];
818 if (IS_CHAN_2GHZ(chan
))
819 ratesArray
[rateExtCck
] = targetPowerCckExt
.tPow2x
[0];
822 #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
823 #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
826 static void ath9k_hw_AR9287_set_txpower(struct ath_hw
*ah
,
827 struct ath9k_channel
*chan
, u16 cfgCtl
,
828 u8 twiceAntennaReduction
,
829 u8 twiceMaxRegulatoryPower
,
832 #define INCREASE_MAXPOW_BY_TWO_CHAIN 6
833 #define INCREASE_MAXPOW_BY_THREE_CHAIN 10
834 struct ath_regulatory
*regulatory
= ath9k_hw_regulatory(ah
);
835 struct ar9287_eeprom
*pEepData
= &ah
->eeprom
.map9287
;
836 struct modal_eep_ar9287_header
*pModal
= &pEepData
->modalHeader
;
837 int16_t ratesArray
[Ar5416RateSize
];
838 int16_t txPowerIndexOffset
= 0;
839 u8 ht40PowerIncForPdadc
= 2;
842 memset(ratesArray
, 0, sizeof(ratesArray
));
844 if ((pEepData
->baseEepHeader
.version
& AR9287_EEP_VER_MINOR_MASK
) >=
845 AR9287_EEP_MINOR_VER_2
)
846 ht40PowerIncForPdadc
= pModal
->ht40PowerIncForPdadc
;
848 ath9k_hw_set_AR9287_power_per_rate_table(ah
, chan
,
849 &ratesArray
[0], cfgCtl
,
850 twiceAntennaReduction
,
851 twiceMaxRegulatoryPower
,
854 ath9k_hw_set_AR9287_power_cal_table(ah
, chan
, &txPowerIndexOffset
);
856 for (i
= 0; i
< ARRAY_SIZE(ratesArray
); i
++) {
857 ratesArray
[i
] = (int16_t)(txPowerIndexOffset
+ ratesArray
[i
]);
858 if (ratesArray
[i
] > AR9287_MAX_RATE_POWER
)
859 ratesArray
[i
] = AR9287_MAX_RATE_POWER
;
862 if (AR_SREV_9280_10_OR_LATER(ah
)) {
863 for (i
= 0; i
< Ar5416RateSize
; i
++)
864 ratesArray
[i
] -= AR9287_PWR_TABLE_OFFSET_DB
* 2;
867 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE1
,
868 ATH9K_POW_SM(ratesArray
[rate18mb
], 24)
869 | ATH9K_POW_SM(ratesArray
[rate12mb
], 16)
870 | ATH9K_POW_SM(ratesArray
[rate9mb
], 8)
871 | ATH9K_POW_SM(ratesArray
[rate6mb
], 0));
873 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE2
,
874 ATH9K_POW_SM(ratesArray
[rate54mb
], 24)
875 | ATH9K_POW_SM(ratesArray
[rate48mb
], 16)
876 | ATH9K_POW_SM(ratesArray
[rate36mb
], 8)
877 | ATH9K_POW_SM(ratesArray
[rate24mb
], 0));
879 if (IS_CHAN_2GHZ(chan
)) {
880 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE3
,
881 ATH9K_POW_SM(ratesArray
[rate2s
], 24)
882 | ATH9K_POW_SM(ratesArray
[rate2l
], 16)
883 | ATH9K_POW_SM(ratesArray
[rateXr
], 8)
884 | ATH9K_POW_SM(ratesArray
[rate1l
], 0));
885 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE4
,
886 ATH9K_POW_SM(ratesArray
[rate11s
], 24)
887 | ATH9K_POW_SM(ratesArray
[rate11l
], 16)
888 | ATH9K_POW_SM(ratesArray
[rate5_5s
], 8)
889 | ATH9K_POW_SM(ratesArray
[rate5_5l
], 0));
892 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE5
,
893 ATH9K_POW_SM(ratesArray
[rateHt20_3
], 24)
894 | ATH9K_POW_SM(ratesArray
[rateHt20_2
], 16)
895 | ATH9K_POW_SM(ratesArray
[rateHt20_1
], 8)
896 | ATH9K_POW_SM(ratesArray
[rateHt20_0
], 0));
898 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE6
,
899 ATH9K_POW_SM(ratesArray
[rateHt20_7
], 24)
900 | ATH9K_POW_SM(ratesArray
[rateHt20_6
], 16)
901 | ATH9K_POW_SM(ratesArray
[rateHt20_5
], 8)
902 | ATH9K_POW_SM(ratesArray
[rateHt20_4
], 0));
904 if (IS_CHAN_HT40(chan
)) {
905 if (ath9k_hw_AR9287_get_eeprom(ah
, EEP_OL_PWRCTRL
)) {
906 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
907 ATH9K_POW_SM(ratesArray
[rateHt40_3
], 24)
908 | ATH9K_POW_SM(ratesArray
[rateHt40_2
], 16)
909 | ATH9K_POW_SM(ratesArray
[rateHt40_1
], 8)
910 | ATH9K_POW_SM(ratesArray
[rateHt40_0
], 0));
912 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
913 ATH9K_POW_SM(ratesArray
[rateHt40_7
], 24)
914 | ATH9K_POW_SM(ratesArray
[rateHt40_6
], 16)
915 | ATH9K_POW_SM(ratesArray
[rateHt40_5
], 8)
916 | ATH9K_POW_SM(ratesArray
[rateHt40_4
], 0));
918 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE7
,
919 ATH9K_POW_SM(ratesArray
[rateHt40_3
] +
920 ht40PowerIncForPdadc
, 24)
921 | ATH9K_POW_SM(ratesArray
[rateHt40_2
] +
922 ht40PowerIncForPdadc
, 16)
923 | ATH9K_POW_SM(ratesArray
[rateHt40_1
] +
924 ht40PowerIncForPdadc
, 8)
925 | ATH9K_POW_SM(ratesArray
[rateHt40_0
] +
926 ht40PowerIncForPdadc
, 0));
928 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE8
,
929 ATH9K_POW_SM(ratesArray
[rateHt40_7
] +
930 ht40PowerIncForPdadc
, 24)
931 | ATH9K_POW_SM(ratesArray
[rateHt40_6
] +
932 ht40PowerIncForPdadc
, 16)
933 | ATH9K_POW_SM(ratesArray
[rateHt40_5
] +
934 ht40PowerIncForPdadc
, 8)
935 | ATH9K_POW_SM(ratesArray
[rateHt40_4
] +
936 ht40PowerIncForPdadc
, 0));
939 REG_WRITE(ah
, AR_PHY_POWER_TX_RATE9
,
940 ATH9K_POW_SM(ratesArray
[rateExtOfdm
], 24)
941 | ATH9K_POW_SM(ratesArray
[rateExtCck
], 16)
942 | ATH9K_POW_SM(ratesArray
[rateDupOfdm
], 8)
943 | ATH9K_POW_SM(ratesArray
[rateDupCck
], 0));
946 if (IS_CHAN_2GHZ(chan
))
951 if (AR_SREV_9280_10_OR_LATER(ah
))
952 regulatory
->max_power_level
=
953 ratesArray
[i
] + AR9287_PWR_TABLE_OFFSET_DB
* 2;
955 regulatory
->max_power_level
= ratesArray
[i
];
957 switch (ar5416_get_ntxchains(ah
->txchainmask
)) {
961 regulatory
->max_power_level
+=
962 INCREASE_MAXPOW_BY_TWO_CHAIN
;
965 regulatory
->max_power_level
+=
966 INCREASE_MAXPOW_BY_THREE_CHAIN
;
969 DPRINTF(ah
->ah_sc
, ATH_DBG_EEPROM
,
970 "Invalid chainmask configuration\n");
975 static void ath9k_hw_AR9287_set_addac(struct ath_hw
*ah
,
976 struct ath9k_channel
*chan
)
980 static void ath9k_hw_AR9287_set_board_values(struct ath_hw
*ah
,
981 struct ath9k_channel
*chan
)
983 struct ar9287_eeprom
*eep
= &ah
->eeprom
.map9287
;
984 struct modal_eep_ar9287_header
*pModal
= &eep
->modalHeader
;
985 u16 antWrites
[AR9287_ANT_16S
];
988 int i
, j
, offset_num
;
990 pModal
= &eep
->modalHeader
;
992 antWrites
[0] = (u16
)((pModal
->antCtrlCommon
>> 28) & 0xF);
993 antWrites
[1] = (u16
)((pModal
->antCtrlCommon
>> 24) & 0xF);
994 antWrites
[2] = (u16
)((pModal
->antCtrlCommon
>> 20) & 0xF);
995 antWrites
[3] = (u16
)((pModal
->antCtrlCommon
>> 16) & 0xF);
996 antWrites
[4] = (u16
)((pModal
->antCtrlCommon
>> 12) & 0xF);
997 antWrites
[5] = (u16
)((pModal
->antCtrlCommon
>> 8) & 0xF);
998 antWrites
[6] = (u16
)((pModal
->antCtrlCommon
>> 4) & 0xF);
999 antWrites
[7] = (u16
)(pModal
->antCtrlCommon
& 0xF);
1003 for (i
= 0, j
= offset_num
; i
< AR9287_MAX_CHAINS
; i
++) {
1004 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 28) & 0xf);
1005 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 10) & 0x3);
1006 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 8) & 0x3);
1008 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 6) & 0x3);
1009 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 4) & 0x3);
1010 antWrites
[j
++] = (u16
)((pModal
->antCtrlChain
[i
] >> 2) & 0x3);
1011 antWrites
[j
++] = (u16
)(pModal
->antCtrlChain
[i
] & 0x3);
1014 REG_WRITE(ah
, AR_PHY_SWITCH_COM
,
1015 ah
->eep_ops
->get_eeprom_antenna_cfg(ah
, chan
));
1017 for (i
= 0; i
< AR9287_MAX_CHAINS
; i
++) {
1018 regChainOffset
= i
* 0x1000;
1020 REG_WRITE(ah
, AR_PHY_SWITCH_CHAIN_0
+ regChainOffset
,
1021 pModal
->antCtrlChain
[i
]);
1023 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
,
1024 (REG_READ(ah
, AR_PHY_TIMING_CTRL4(0) + regChainOffset
)
1025 & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
|
1026 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
)) |
1027 SM(pModal
->iqCalICh
[i
],
1028 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF
) |
1029 SM(pModal
->iqCalQCh
[i
],
1030 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF
));
1032 txRxAttenLocal
= pModal
->txRxAttenCh
[i
];
1034 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
1035 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN
,
1036 pModal
->bswMargin
[i
]);
1037 REG_RMW_FIELD(ah
, AR_PHY_GAIN_2GHZ
+ regChainOffset
,
1038 AR_PHY_GAIN_2GHZ_XATTEN1_DB
,
1039 pModal
->bswAtten
[i
]);
1040 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ regChainOffset
,
1041 AR9280_PHY_RXGAIN_TXRX_ATTEN
,
1043 REG_RMW_FIELD(ah
, AR_PHY_RXGAIN
+ regChainOffset
,
1044 AR9280_PHY_RXGAIN_TXRX_MARGIN
,
1045 pModal
->rxTxMarginCh
[i
]);
1049 if (IS_CHAN_HT40(chan
))
1050 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
1051 AR_PHY_SETTLING_SWITCH
, pModal
->swSettleHt40
);
1053 REG_RMW_FIELD(ah
, AR_PHY_SETTLING
,
1054 AR_PHY_SETTLING_SWITCH
, pModal
->switchSettling
);
1056 REG_RMW_FIELD(ah
, AR_PHY_DESIRED_SZ
,
1057 AR_PHY_DESIRED_SZ_ADC
, pModal
->adcDesiredSize
);
1059 REG_WRITE(ah
, AR_PHY_RF_CTL4
,
1060 SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAA_OFF
)
1061 | SM(pModal
->txEndToXpaOff
, AR_PHY_RF_CTL4_TX_END_XPAB_OFF
)
1062 | SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAA_ON
)
1063 | SM(pModal
->txFrameToXpaOn
, AR_PHY_RF_CTL4_FRAME_XPAB_ON
));
1065 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL3
,
1066 AR_PHY_TX_END_TO_A2_RX_ON
, pModal
->txEndToRxOn
);
1068 REG_RMW_FIELD(ah
, AR_PHY_CCA
,
1069 AR9280_PHY_CCA_THRESH62
, pModal
->thresh62
);
1070 REG_RMW_FIELD(ah
, AR_PHY_EXT_CCA0
,
1071 AR_PHY_EXT_CCA0_THRESH62
, pModal
->thresh62
);
1073 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
, AR9287_AN_RF2G3_DB1
,
1074 AR9287_AN_RF2G3_DB1_S
, pModal
->db1
);
1075 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
, AR9287_AN_RF2G3_DB2
,
1076 AR9287_AN_RF2G3_DB2_S
, pModal
->db2
);
1077 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
,
1078 AR9287_AN_RF2G3_OB_CCK
,
1079 AR9287_AN_RF2G3_OB_CCK_S
, pModal
->ob_cck
);
1080 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
,
1081 AR9287_AN_RF2G3_OB_PSK
,
1082 AR9287_AN_RF2G3_OB_PSK_S
, pModal
->ob_psk
);
1083 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
,
1084 AR9287_AN_RF2G3_OB_QAM
,
1085 AR9287_AN_RF2G3_OB_QAM_S
, pModal
->ob_qam
);
1086 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH0
,
1087 AR9287_AN_RF2G3_OB_PAL_OFF
,
1088 AR9287_AN_RF2G3_OB_PAL_OFF_S
,
1089 pModal
->ob_pal_off
);
1091 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1092 AR9287_AN_RF2G3_DB1
, AR9287_AN_RF2G3_DB1_S
,
1094 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
, AR9287_AN_RF2G3_DB2
,
1095 AR9287_AN_RF2G3_DB2_S
, pModal
->db2
);
1096 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1097 AR9287_AN_RF2G3_OB_CCK
,
1098 AR9287_AN_RF2G3_OB_CCK_S
, pModal
->ob_cck
);
1099 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1100 AR9287_AN_RF2G3_OB_PSK
,
1101 AR9287_AN_RF2G3_OB_PSK_S
, pModal
->ob_psk
);
1102 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1103 AR9287_AN_RF2G3_OB_QAM
,
1104 AR9287_AN_RF2G3_OB_QAM_S
, pModal
->ob_qam
);
1105 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_RF2G3_CH1
,
1106 AR9287_AN_RF2G3_OB_PAL_OFF
,
1107 AR9287_AN_RF2G3_OB_PAL_OFF_S
,
1108 pModal
->ob_pal_off
);
1110 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
,
1111 AR_PHY_TX_END_DATA_START
, pModal
->txFrameToDataStart
);
1112 REG_RMW_FIELD(ah
, AR_PHY_RF_CTL2
,
1113 AR_PHY_TX_END_PA_ON
, pModal
->txFrameToPaOn
);
1115 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_TOP2
,
1116 AR9287_AN_TOP2_XPABIAS_LVL
,
1117 AR9287_AN_TOP2_XPABIAS_LVL_S
,
1118 pModal
->xpaBiasLvl
);
1121 static u8
ath9k_hw_AR9287_get_num_ant_config(struct ath_hw
*ah
,
1122 enum ieee80211_band freq_band
)
1127 static u16
ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw
*ah
,
1128 struct ath9k_channel
*chan
)
1130 struct ar9287_eeprom
*eep
= &ah
->eeprom
.map9287
;
1131 struct modal_eep_ar9287_header
*pModal
= &eep
->modalHeader
;
1133 return pModal
->antCtrlCommon
& 0xFFFF;
1136 static u16
ath9k_hw_AR9287_get_spur_channel(struct ath_hw
*ah
,
1139 #define EEP_MAP9287_SPURCHAN \
1140 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
1141 u16 spur_val
= AR_NO_SPUR
;
1143 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1144 "Getting spur idx %d is2Ghz. %d val %x\n",
1145 i
, is2GHz
, ah
->config
.spurchans
[i
][is2GHz
]);
1147 switch (ah
->config
.spurmode
) {
1150 case SPUR_ENABLE_IOCTL
:
1151 spur_val
= ah
->config
.spurchans
[i
][is2GHz
];
1152 DPRINTF(ah
->ah_sc
, ATH_DBG_ANI
,
1153 "Getting spur val from new loc. %d\n", spur_val
);
1155 case SPUR_ENABLE_EEPROM
:
1156 spur_val
= EEP_MAP9287_SPURCHAN
;
1162 #undef EEP_MAP9287_SPURCHAN
1165 const struct eeprom_ops eep_AR9287_ops
= {
1166 .check_eeprom
= ath9k_hw_AR9287_check_eeprom
,
1167 .get_eeprom
= ath9k_hw_AR9287_get_eeprom
,
1168 .fill_eeprom
= ath9k_hw_AR9287_fill_eeprom
,
1169 .get_eeprom_ver
= ath9k_hw_AR9287_get_eeprom_ver
,
1170 .get_eeprom_rev
= ath9k_hw_AR9287_get_eeprom_rev
,
1171 .get_num_ant_config
= ath9k_hw_AR9287_get_num_ant_config
,
1172 .get_eeprom_antenna_cfg
= ath9k_hw_AR9287_get_eeprom_antenna_cfg
,
1173 .set_board_values
= ath9k_hw_AR9287_set_board_values
,
1174 .set_addac
= ath9k_hw_AR9287_set_addac
,
1175 .set_txpower
= ath9k_hw_AR9287_set_txpower
,
1176 .get_spur_channel
= ath9k_hw_AR9287_get_spur_channel