17 #include <asm/unaligned.h>
21 #define SIZE_EEPROM_AR9287 (sizeof(struct ar9287_eeprom) / sizeof(u16))
23 static int ath9k_hw_ar9287_get_eeprom_ver(
struct ath_hw *
ah)
25 return (ah->
eeprom.
map9287.baseEepHeader.version >> 12) & 0xF;
28 static int ath9k_hw_ar9287_get_eeprom_rev(
struct ath_hw *
ah)
33 static bool __ath9k_hw_ar9287_fill_eeprom(
struct ath_hw *ah)
39 eep_data = (
u16 *)eep;
45 "Unable to read eeprom region\n");
54 static bool __ath9k_hw_usb_ar9287_fill_eeprom(
struct ath_hw *ah)
64 static bool ath9k_hw_ar9287_fill_eeprom(
struct ath_hw *ah)
66 struct ath_common *common = ath9k_hw_common(ah);
73 return __ath9k_hw_usb_ar9287_fill_eeprom(ah);
75 return __ath9k_hw_ar9287_fill_eeprom(ah);
78 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
126 static u32 ath9k_hw_ar9287_dump_eeprom(
struct ath_hw *ah,
bool dump_base_hdr,
132 if (!dump_base_hdr) {
133 len +=
snprintf(buf + len, size - len,
134 "%20s :\n",
"2GHz modal Header");
135 len = ar9287_dump_modal_eeprom(buf, len, size,
165 len +=
snprintf(buf + len, size - len,
"%20s : %pM\n",
"MacAddress",
175 static u32 ath9k_hw_ar9287_dump_eeprom(
struct ath_hw *ah,
bool dump_base_hdr,
183 static int ath9k_hw_ar9287_check_eeprom(
struct ath_hw *ah)
188 bool need_swap =
false;
190 struct ath_common *common = ath9k_hw_common(ah);
195 ath_err(common,
"Reading Magic # failed\n");
215 "Invalid EEPROM Magic. Endianness mismatch.\n");
222 need_swap ?
"True" :
"False");
232 el = el /
sizeof(
u16);
236 for (i = 0; i <
el; i++)
280 ath_err(common,
"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
281 sum, ah->
eep_ops->get_eeprom_ver(ah));
288 static u32 ath9k_hw_ar9287_get_eeprom(
struct ath_hw *ah,
302 return get_unaligned_be16(pBase->
macAddr);
304 return get_unaligned_be16(pBase->
macAddr + 2);
306 return get_unaligned_be16(pBase->
macAddr + 4);
343 static void ar9287_eeprom_get_tx_gain_index(
struct ath_hw *ah,
348 u16 idxL = 0, idxR = 0, numPiers;
354 for (numPiers = 0; numPiers < availPiers; numPiers++) {
361 pCalChans, numPiers, &idxL, &idxR);
364 *pPwr = (
int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0];
366 *pPwr = ((
int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
372 static void ar9287_eeprom_olpc_set_pdadcs(
struct ath_hw *ah,
381 tmpVal = tmpVal & 0xFCFFFFFF;
382 tmpVal = tmpVal | (0x3 << 24);
388 tmpVal = tmpVal & 0xFCFFFFFF;
389 tmpVal = tmpVal | (0x3 << 24);
396 tmpVal = tmpVal & 0xff00ffff;
398 tmpVal = tmpVal | (a << 16);
406 tmpVal = tmpVal & 0xff00ffff;
408 tmpVal = tmpVal | (a << 16);
413 static void ath9k_hw_set_ar9287_power_cal_table(
struct ath_hw *ah,
419 u16 pdGainOverlap_t2;
422 u16 numPiers = 0,
i,
j;
423 u16 numXpdGain, xpdMask;
425 u32 reg32, regOffset, regChainOffset,
regval;
433 pdGainOverlap_t2 = pEepData->
modalHeader.pdGainOverlap;
442 pRawDatasetOpenLoop =
455 xpdGainValues[numXpdGain] =
462 (numXpdGain - 1) & 0x3);
471 regChainOffset = i * 0x1000;
474 pRawDatasetOpenLoop =
479 ar9287_eeprom_get_tx_gain_index(ah, chan,
481 pCalBChans, numPiers,
483 ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i);
491 pCalBChans, numPiers,
501 if (!ath9k_hw_ar9287_get_eeprom(ah,
504 regval =
SM(pdGainOverlap_t2,
506 |
SM(gainBoundaries[0],
508 |
SM(gainBoundaries[1],
510 |
SM(gainBoundaries[2],
512 |
SM(gainBoundaries[3],
528 pdadcValues[j] = pdadcValues[j+diff];
533 pdadcValues[AR5416_NUM_PDADC_VALUES-diff];
538 (672 << 2) + regChainOffset;
540 for (j = 0; j < 32; j++) {
552 static void ath9k_hw_set_ar9287_power_per_rate_table(
struct ath_hw *ah,
556 u16 antenna_reduction,
560 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
561 pEepData->ctlIndex[i])
564 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
565 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
567 u16 twiceMaxEdgePower;
571 targetPowerCck = {0, {0, 0, 0, 0} };
573 targetPowerCckExt = {0, {0, 0, 0, 0} };
575 targetPowerHt40 = {0, {0, 0, 0, 0} };
576 u16 scaledPower = 0, minCtlPower;
577 static const u16 ctlModesFor11g[] = {
586 u16 twiceMinEdgePower;
602 pCtlMode = ctlModesFor11g;
607 &targetPowerCck, 4,
false);
611 &targetPowerOfdm, 4,
false);
615 &targetPowerHt20, 8,
false);
623 &targetPowerHt40, 8,
true);
627 &targetPowerCckExt, 4,
true);
631 &targetPowerOfdmExt, 4,
true);
635 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
637 (pCtlMode[ctlMode] ==
CTL_2GHT40) ?
true :
false;
640 freq = centers.synth_center;
642 freq = centers.ext_center;
644 freq = centers.ctl_center;
655 if (CMP_CTL || CMP_NO_CTL) {
666 twiceMaxEdgePower =
min(twiceMaxEdgePower,
669 twiceMaxEdgePower = twiceMinEdgePower;
675 minCtlPower = (
u8)
min(twiceMaxEdgePower, scaledPower);
678 switch (pCtlMode[ctlMode]) {
680 for (i = 0; i <
ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
681 targetPowerCck.tPow2x[
i] =
696 for (i = 0; i <
ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
697 targetPowerHt20.tPow2x[
i] =
703 targetPowerCckExt.tPow2x[0] =
704 (
u8)
min((
u16)targetPowerCckExt.tPow2x[0],
709 targetPowerOfdmExt.
tPow2x[0] =
739 for (i = 0; i <
ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
740 ratesArray[
rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
743 ratesArray[
rate1l] = targetPowerCck.tPow2x[0];
745 ratesArray[
rate2l] = targetPowerCck.tPow2x[1];
747 ratesArray[
rate5_5l] = targetPowerCck.tPow2x[2];
749 ratesArray[
rate11l] = targetPowerCck.tPow2x[3];
760 ratesArray[
rateExtCck] = targetPowerCckExt.tPow2x[0];
767 static void ath9k_hw_ar9287_set_txpower(
struct ath_hw *ah,
769 u8 twiceAntennaReduction,
779 memset(ratesArray, 0,
sizeof(ratesArray));
785 ath9k_hw_set_ar9287_power_per_rate_table(ah, chan,
786 &ratesArray[0], cfgCtl,
787 twiceAntennaReduction,
790 ath9k_hw_set_ar9287_power_cal_table(ah, chan);
793 for (i = 0; i <
ARRAY_SIZE(ratesArray); i++) {
868 ht40PowerIncForPdadc, 24)
870 ht40PowerIncForPdadc, 16)
872 ht40PowerIncForPdadc, 8)
874 ht40PowerIncForPdadc, 0));
878 ht40PowerIncForPdadc, 24)
880 ht40PowerIncForPdadc, 16)
882 ht40PowerIncForPdadc, 8)
884 ht40PowerIncForPdadc, 0));
897 static void ath9k_hw_ar9287_set_board_values(
struct ath_hw *ah,
911 regChainOffset = i * 0x1000;
1009 static u16 ath9k_hw_ar9287_get_spur_channel(
struct ath_hw *ah,
1012 #define EEP_MAP9287_SPURCHAN \
1013 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
1015 struct ath_common *common = ath9k_hw_common(ah);
1018 ath_dbg(common, ANI,
"Getting spur idx:%d is2Ghz:%d val:%x\n",
1019 i, is2GHz, ah->
config.spurchans[i][is2GHz]);
1021 switch (ah->
config.spurmode) {
1025 spur_val = ah->
config.spurchans[
i][is2GHz];
1026 ath_dbg(common, ANI,
"Getting spur val from new loc. %d\n",
1036 #undef EEP_MAP9287_SPURCHAN
1040 .check_eeprom = ath9k_hw_ar9287_check_eeprom,
1041 .get_eeprom = ath9k_hw_ar9287_get_eeprom,
1042 .fill_eeprom = ath9k_hw_ar9287_fill_eeprom,
1043 .dump_eeprom = ath9k_hw_ar9287_dump_eeprom,
1044 .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver,
1045 .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev,
1046 .set_board_values = ath9k_hw_ar9287_set_board_values,
1047 .set_txpower = ath9k_hw_ar9287_set_txpower,
1048 .get_spur_channel = ath9k_hw_ar9287_get_spur_channel