17 #include <asm/unaligned.h>
21 static int ath9k_hw_4k_get_eeprom_ver(
struct ath_hw *
ah)
23 return ((ah->
eeprom.
map4k.baseEepHeader.version >> 12) & 0xF);
26 static int ath9k_hw_4k_get_eeprom_rev(
struct ath_hw *ah)
28 return ((ah->
eeprom.
map4k.baseEepHeader.version) & 0xFFF);
31 #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
33 static bool __ath9k_hw_4k_fill_eeprom(
struct ath_hw *ah)
37 int addr, eep_start_loc = 64;
42 "Unable to read eeprom region\n");
51 static bool __ath9k_hw_usb_4k_fill_eeprom(
struct ath_hw *ah)
60 static bool ath9k_hw_4k_fill_eeprom(
struct ath_hw *ah)
69 return __ath9k_hw_usb_4k_fill_eeprom(ah);
71 return __ath9k_hw_4k_fill_eeprom(ah);
74 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
129 static u32 ath9k_hw_4k_dump_eeprom(
struct ath_hw *ah,
bool dump_base_hdr,
135 if (!dump_base_hdr) {
136 len +=
snprintf(buf + len, size - len,
137 "%20s :\n",
"2GHz modal Header");
138 len = ath9k_dump_4k_modal_eeprom(buf, len, size,
167 len +=
snprintf(buf + len, size - len,
"%20s : %pM\n",
"MacAddress",
177 static u32 ath9k_hw_4k_dump_eeprom(
struct ath_hw *ah,
bool dump_base_hdr,
185 #undef SIZE_EEPROM_4K
187 static int ath9k_hw_4k_check_eeprom(
struct ath_hw *ah)
189 #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
190 struct ath_common *common = ath9k_hw_common(ah);
194 bool need_swap =
false;
201 ath_err(common,
"Reading Magic # failed\n");
221 "Invalid EEPROM Magic. Endianness mismatch.\n");
228 need_swap ?
"True" :
"False");
238 el = el /
sizeof(
u16);
242 for (i = 0; i <
el; i++)
250 "EEPROM Endianness is not native.. Changing\n");
292 ath_err(common,
"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
293 sum, ah->
eep_ops->get_eeprom_ver(ah));
298 #undef EEPROM_4K_SIZE
301 static u32 ath9k_hw_4k_get_eeprom(
struct ath_hw *ah,
315 return get_unaligned_be16(pBase->
macAddr);
317 return get_unaligned_be16(pBase->
macAddr + 2);
319 return get_unaligned_be16(pBase->
macAddr + 4);
331 return pModal->
db1_1;
355 static void ath9k_hw_set_4k_power_cal_table(
struct ath_hw *ah,
358 struct ath_common *common = ath9k_hw_common(ah);
362 u16 pdGainOverlap_t2;
366 u16 numXpdGain, xpdMask;
368 u32 reg32, regOffset, regChainOffset;
390 xpdGainValues[numXpdGain] =
397 (numXpdGain - 1) & 0x3);
405 regChainOffset = i * 0x1000;
411 pRawDataset, pCalBChans,
412 numPiers, pdGainOverlap_t2,
414 pdadcValues, numXpdGain);
421 |
SM(gainBoundaries[0],
423 |
SM(gainBoundaries[1],
425 |
SM(gainBoundaries[2],
427 |
SM(gainBoundaries[3],
430 regOffset =
AR_PHY_BASE + (672 << 2) + regChainOffset;
431 for (j = 0; j < 32; j++) {
436 "PDADC (%d,%4x): %4.4x %8.8x\n",
437 i, regChainOffset, regOffset,
441 "PDADC %3d Value %3d | "
442 "PDADC %3d Value %3d | "
443 "PDADC %3d Value %3d | "
444 "PDADC %3d Value %3d |\n",
445 i, 4 * j, pdadcValues[4 * j],
446 4 * j + 1, pdadcValues[4 * j + 1],
447 4 * j + 2, pdadcValues[4 * j + 2],
448 4 * j + 3, pdadcValues[4 * j + 3]);
458 static void ath9k_hw_set_4k_power_per_rate_table(
struct ath_hw *ah,
462 u16 antenna_reduction,
465 #define CMP_TEST_GRP \
466 (((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) == \
467 pEepData->ctlIndex[i]) \
468 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
469 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
472 u16 twiceMinEdgePower;
473 u16 twiceMaxEdgePower;
474 u16 scaledPower = 0, minCtlPower;
485 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
491 static const u16 ctlModesFor11g[] = {
498 scaledPower = powerLimit - antenna_reduction;
500 pCtlMode = ctlModesFor11g;
505 &targetPowerCck, 4,
false);
509 &targetPowerOfdm, 4,
false);
513 &targetPowerHt20, 8,
false);
520 &targetPowerHt40, 8,
true);
524 &targetPowerCckExt, 4,
true);
528 &targetPowerOfdmExt, 4,
true);
531 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
532 bool isHt40CtlMode = (pCtlMode[ctlMode] ==
CTL_5GHT40) ||
536 freq = centers.synth_center;
538 freq = centers.ext_center;
540 freq = centers.ctl_center;
559 min(twiceMaxEdgePower,
562 twiceMaxEdgePower = twiceMinEdgePower;
568 minCtlPower = (
u8)
min(twiceMaxEdgePower, scaledPower);
570 switch (pCtlMode[ctlMode]) {
579 for (i = 0; i <
ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
580 targetPowerOfdm.tPow2x[
i] =
581 min((
u16)targetPowerOfdm.tPow2x[i],
586 for (i = 0; i <
ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
587 targetPowerHt20.tPow2x[
i] =
588 min((
u16)targetPowerHt20.tPow2x[i],
593 targetPowerCckExt.tPow2x[0] =
594 min((
u16)targetPowerCckExt.tPow2x[0],
598 targetPowerOfdmExt.
tPow2x[0] =
619 targetPowerOfdm.tPow2x[0];
621 ratesArray[
rate36mb] = targetPowerOfdm.tPow2x[1];
622 ratesArray[
rate48mb] = targetPowerOfdm.tPow2x[2];
623 ratesArray[
rate54mb] = targetPowerOfdm.tPow2x[3];
624 ratesArray[
rateXr] = targetPowerOfdm.tPow2x[0];
626 for (i = 0; i <
ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
627 ratesArray[
rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
642 ratesArray[
rateExtCck] = targetPowerCckExt.tPow2x[0];
648 static void ath9k_hw_4k_set_txpower(
struct ath_hw *ah,
651 u8 twiceAntennaReduction,
661 memset(ratesArray, 0,
sizeof(ratesArray));
668 ath9k_hw_set_4k_power_per_rate_table(ah, chan,
669 &ratesArray[0], cfgCtl,
670 twiceAntennaReduction,
673 ath9k_hw_set_4k_power_cal_table(ah, chan);
676 for (i = 0; i <
ARRAY_SIZE(ratesArray); i++) {
732 ht40PowerIncForPdadc, 24)
734 ht40PowerIncForPdadc, 16)
736 ht40PowerIncForPdadc, 8)
738 ht40PowerIncForPdadc, 0));
741 ht40PowerIncForPdadc, 24)
743 ht40PowerIncForPdadc, 16)
745 ht40PowerIncForPdadc, 8)
747 ht40PowerIncForPdadc, 0));
758 static void ath9k_hw_4k_set_gain(
struct ath_hw *ah,
816 static void ath9k_hw_4k_set_board_values(
struct ath_hw *ah,
823 u8 ob[5], db1[5], db2[5];
824 u8 ant_div_control1, ant_div_control2;
834 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
844 regVal |=
SM(ant_div_control1,
846 regVal |=
SM(ant_div_control2,
848 regVal |=
SM((ant_div_control2 >> 2),
850 regVal |=
SM((ant_div_control1 >> 1),
852 regVal |=
SM((ant_div_control1 >> 2),
860 regVal |=
SM((ant_div_control1 >> 3),
868 ob[0] = pModal->
ob_0;
869 ob[1] = pModal->
ob_1;
870 ob[2] = pModal->
ob_2;
871 ob[3] = pModal->
ob_3;
872 ob[4] = pModal->
ob_4;
874 db1[0] = pModal->
db1_0;
875 db1[1] = pModal->
db1_1;
876 db1[2] = pModal->
db1_2;
877 db1[3] = pModal->
db1_3;
878 db1[4] = pModal->
db1_4;
880 db2[0] = pModal->
db2_0;
881 db2[1] = pModal->
db2_1;
882 db2[2] = pModal->
db2_2;
883 db2[3] = pModal->
db2_3;
884 db2[4] = pModal->
db2_4;
885 }
else if (pModal->
version == 1) {
886 ob[0] = pModal->
ob_0;
887 ob[1] = ob[2] = ob[3] = ob[4] = pModal->
ob_1;
888 db1[0] = pModal->
db1_0;
889 db1[1] = db1[2] = db1[3] = db1[4] = pModal->
db1_1;
890 db2[0] = pModal->
db2_0;
891 db2[1] = db2[2] = db2[3] = db2[4] = pModal->
db2_1;
895 for (i = 0; i < 5; i++) {
896 ob[
i] = pModal->
ob_0;
1048 if ((pBase->
txGainType == 0) && (bb_desired_scale != 0)) {
1052 pwrctrl = mask * bb_desired_scale;
1059 pwrctrl = mask * bb_desired_scale;
1064 pwrctrl = mask * bb_desired_scale;
1071 static u16 ath9k_hw_4k_get_spur_channel(
struct ath_hw *ah,
u16 i,
bool is2GHz)
1073 #define EEP_MAP4K_SPURCHAN \
1074 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
1075 struct ath_common *common = ath9k_hw_common(ah);
1079 ath_dbg(common, ANI,
"Getting spur idx:%d is2Ghz:%d val:%x\n",
1080 i, is2GHz, ah->
config.spurchans[i][is2GHz]);
1082 switch (ah->
config.spurmode) {
1086 spur_val = ah->
config.spurchans[
i][is2GHz];
1087 ath_dbg(common, ANI,
"Getting spur val from new loc. %d\n",
1097 #undef EEP_MAP4K_SPURCHAN
1101 .check_eeprom = ath9k_hw_4k_check_eeprom,
1102 .get_eeprom = ath9k_hw_4k_get_eeprom,
1103 .fill_eeprom = ath9k_hw_4k_fill_eeprom,
1104 .dump_eeprom = ath9k_hw_4k_dump_eeprom,
1105 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
1106 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
1107 .set_board_values = ath9k_hw_4k_set_board_values,
1108 .set_txpower = ath9k_hw_4k_set_txpower,
1109 .get_spur_channel = ath9k_hw_4k_get_spur_channel