17 #include <asm/unaligned.h>
21 static void ath9k_get_txgain_index(
struct ath_hw *
ah,
24 u8 *calChans,
u16 availPiers,
u8 *pwr,
u8 *pcdacIdx)
27 u16 idxL = 0, idxR = 0, numPiers;
33 for (numPiers = 0; numPiers < availPiers; numPiers++)
39 calChans, numPiers, &idxL, &idxR);
41 pcdac = rawDatasetOpLoop[idxL].
pcdac[0][0];
42 *pwr = rawDatasetOpLoop[idxL].
pwrPdg[0][0];
44 pcdac = rawDatasetOpLoop[idxR].
pcdac[0][0];
45 *pwr = (rawDatasetOpLoop[idxL].
pwrPdg[0][0] +
46 rawDatasetOpLoop[idxR].
pwrPdg[0][0])/2;
56 static void ath9k_olc_get_pdadcs(
struct ath_hw *ah,
75 pPDADCValues[
i] = 0x0;
77 pPDADCValues[
i] = 0xFF;
80 static int ath9k_hw_def_get_eeprom_ver(
struct ath_hw *ah)
82 return ((ah->
eeprom.
def.baseEepHeader.version >> 12) & 0xF);
85 static int ath9k_hw_def_get_eeprom_rev(
struct ath_hw *ah)
87 return ((ah->
eeprom.
def.baseEepHeader.version) & 0xFFF);
90 #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
92 static bool __ath9k_hw_def_fill_eeprom(
struct ath_hw *ah)
96 int addr, ar5416_eep_start_loc = 0x100;
102 "Unable to read eeprom region\n");
110 static bool __ath9k_hw_usb_def_fill_eeprom(
struct ath_hw *ah)
119 static bool ath9k_hw_def_fill_eeprom(
struct ath_hw *ah)
128 return __ath9k_hw_usb_def_fill_eeprom(ah);
130 return __ath9k_hw_def_fill_eeprom(ah);
133 #undef SIZE_EEPROM_DEF
135 #if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
174 PR_EEP(
"Chain0 OutputBias", modal_hdr->
ob);
175 PR_EEP(
"Chain0 DriverBias", modal_hdr->
db);
205 static u32 ath9k_hw_def_dump_eeprom(
struct ath_hw *ah,
bool dump_base_hdr,
211 if (!dump_base_hdr) {
212 len +=
snprintf(buf + len, size - len,
213 "%20s :\n",
"2GHz modal Header");
214 len = ath9k_def_dump_modal_eeprom(buf, len, size,
216 len +=
snprintf(buf + len, size - len,
217 "%20s :\n",
"5GHz modal Header");
218 len = ath9k_def_dump_modal_eeprom(buf, len, size,
247 len +=
snprintf(buf + len, size - len,
"%20s : %pM\n",
"MacAddress",
257 static u32 ath9k_hw_def_dump_eeprom(
struct ath_hw *ah,
bool dump_base_hdr,
265 static int ath9k_hw_def_check_eeprom(
struct ath_hw *ah)
268 struct ath_common *common = ath9k_hw_common(ah);
271 bool need_swap =
false;
275 ath_err(common,
"Reading Magic # failed\n");
290 for (addr = 0; addr < size /
sizeof(
u16); addr++) {
297 "Invalid EEPROM Magic. Endianness mismatch.\n");
304 need_swap ?
"True" :
"False");
314 el = el /
sizeof(
u16);
318 for (i = 0; i <
el; i++)
326 "EEPROM Endianness is not native.. Changing.\n");
362 for (i = 0; i < 3; i++) {
376 ath_err(common,
"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
377 sum, ah->
eep_ops->get_eeprom_ver(ah));
394 static u32 ath9k_hw_def_get_eeprom(
struct ath_hw *ah,
408 return get_unaligned_be16(pBase->
macAddr);
410 return get_unaligned_be16(pBase->
macAddr + 2);
412 return get_unaligned_be16(pBase->
macAddr + 4);
471 pModal[band].antennaGainCh[0],
472 pModal[band].antennaGainCh[1]),
473 pModal[band].antennaGainCh[2]);
479 static void ath9k_hw_def_set_gain(
struct ath_hw *ah,
482 u8 txRxAttenLocal,
int regChainOffset,
int i)
504 |
SM(pModal-> bswMargin[i],
535 static void ath9k_hw_def_set_board_values(
struct ath_hw *ah,
540 int i, regChainOffset;
555 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
557 regChainOffset = i * 0x1000;
571 ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
703 static void ath9k_hw_def_set_addac(
struct ath_hw *ah,
706 #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
722 u16 resetFreqBin, freqBin, freqCount = 0;
727 resetFreqBin =
FREQ2FBIN(centers.synth_center,
734 while (freqCount < 3) {
739 if (resetFreqBin >= freqBin)
749 7, 1) & (~0x18)) | biaslevel << 3;
752 6, 1) & (~0xc0)) | biaslevel << 6;
757 static int16_t ath9k_change_gain_boundary_setting(
struct ath_hw *ah,
760 u16 pdGainOverlap_t2,
783 for (k = 0; k < numXpdGain; k++)
784 gb[k] = (
u16)(gb[
k] - *diff);
791 for (k = 0; k < numXpdGain; k++)
792 gb[k] = (
u16)
min(gb_limit, gb[k]);
798 static void ath9k_adjust_pdadc_values(
struct ath_hw *ah,
803 #define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)
815 pdadcValues[
k] = pdadcValues[k + diff];
820 pdadcValues[
k] = pdadcValues[
NUM_PDADC(diff)];
827 static void ath9k_hw_set_def_power_cal_table(
struct ath_hw *ah,
830 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
831 #define SM_PDGAIN_B(x, y) \
832 SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
833 struct ath_common *common = ath9k_hw_common(ah);
837 u16 pdGainOverlap_t2;
842 u16 numXpdGain, xpdMask;
844 u32 reg32, regOffset, regChainOffset;
873 pRawDataset)->vpdPdg[0][0];
882 xpdGainValues[numXpdGain] =
889 (numXpdGain - 1) & 0x3);
900 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
902 regChainOffset = i * 0x1000;
915 ath9k_get_txgain_index(ah, chan,
917 pCalBChans, numPiers, &txPower, &pcdacIdx);
918 ath9k_olc_get_pdadcs(ah, pcdacIdx,
919 txPower/2, pdadcValues);
923 pCalBChans, numPiers,
930 diff = ath9k_change_gain_boundary_setting(ah,
957 ath9k_adjust_pdadc_values(ah, pwr_table_offset,
960 regOffset =
AR_PHY_BASE + (672 << 2) + regChainOffset;
961 for (j = 0; j < 32; j++) {
966 "PDADC (%d,%4x): %4.4x %8.8x\n",
967 i, regChainOffset, regOffset,
970 "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n",
971 i, 4 * j, pdadcValues[4 * j],
972 4 * j + 1, pdadcValues[4 * j + 1],
973 4 * j + 2, pdadcValues[4 * j + 2],
974 4 * j + 3, pdadcValues[4 * j + 3]);
986 static void ath9k_hw_set_def_power_per_rate_table(
struct ath_hw *ah,
990 u16 antenna_reduction,
994 u16 twiceMaxEdgePower;
1001 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
1007 u16 scaledPower = 0, minCtlPower;
1008 static const u16 ctlModesFor11a[] = {
1011 static const u16 ctlModesFor11g[] = {
1016 const u16 *pCtlMode;
1020 u16 twiceMinEdgePower;
1032 pCtlMode = ctlModesFor11g;
1037 &targetPowerCck, 4,
false);
1041 &targetPowerOfdm, 4,
false);
1045 &targetPowerHt20, 8,
false);
1052 &targetPowerHt40, 8,
true);
1056 &targetPowerCckExt, 4,
true);
1060 &targetPowerOfdmExt, 4,
true);
1065 pCtlMode = ctlModesFor11a;
1070 &targetPowerOfdm, 4,
false);
1074 &targetPowerHt20, 8,
false);
1081 &targetPowerHt40, 8,
true);
1085 &targetPowerOfdmExt, 4,
true);
1089 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
1090 bool isHt40CtlMode = (pCtlMode[ctlMode] ==
CTL_5GHT40) ||
1093 freq = centers.synth_center;
1095 freq = centers.ext_center;
1097 freq = centers.ctl_center;
1105 (((cfgCtl & ~CTL_MODE_M) |
1106 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
1114 if ((cfgCtl & ~CTL_MODE_M) ==
SD_NO_CTL) {
1115 twiceMaxEdgePower =
min(twiceMaxEdgePower,
1118 twiceMaxEdgePower = twiceMinEdgePower;
1124 minCtlPower =
min(twiceMaxEdgePower, scaledPower);
1126 switch (pCtlMode[ctlMode]) {
1136 for (i = 0; i <
ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
1137 targetPowerOfdm.tPow2x[
i] =
1138 min((
u16)targetPowerOfdm.tPow2x[i],
1144 for (i = 0; i <
ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
1145 targetPowerHt20.tPow2x[
i] =
1146 min((
u16)targetPowerHt20.tPow2x[i],
1151 targetPowerCckExt.tPow2x[0] =
min((
u16)
1152 targetPowerCckExt.tPow2x[0],
1158 targetPowerOfdmExt.
tPow2x[0],
1176 targetPowerOfdm.tPow2x[0];
1177 ratesArray[
rate36mb] = targetPowerOfdm.tPow2x[1];
1178 ratesArray[
rate48mb] = targetPowerOfdm.tPow2x[2];
1179 ratesArray[
rate54mb] = targetPowerOfdm.tPow2x[3];
1180 ratesArray[
rateXr] = targetPowerOfdm.tPow2x[0];
1182 for (i = 0; i <
ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
1183 ratesArray[
rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
1188 targetPowerCck.
tPow2x[1];
1190 targetPowerCck.
tPow2x[2];
1192 targetPowerCck.
tPow2x[3];
1204 targetPowerCckExt.tPow2x[0];
1209 static void ath9k_hw_def_set_txpower(
struct ath_hw *ah,
1212 u8 twiceAntennaReduction,
1213 u8 powerLimit,
bool test)
1215 #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1222 int i, cck_ofdm_delta = 0;
1224 memset(ratesArray, 0,
sizeof(ratesArray));
1231 ath9k_hw_set_def_power_per_rate_table(ah, chan,
1232 &ratesArray[0], cfgCtl,
1233 twiceAntennaReduction,
1236 ath9k_hw_set_def_power_cal_table(ah, chan);
1239 for (i = 0; i <
ARRAY_SIZE(ratesArray); i++) {
1255 pwr_table_offset = ah->
eep_ops->get_eeprom(ah,
1257 ratesArray[
i] -= pwr_table_offset * 2;
1315 ht40PowerIncForPdadc, 24)
1317 ht40PowerIncForPdadc, 16)
1319 ht40PowerIncForPdadc, 8)
1321 ht40PowerIncForPdadc, 0));
1324 ht40PowerIncForPdadc, 24)
1326 ht40PowerIncForPdadc, 16)
1328 ht40PowerIncForPdadc, 8)
1330 ht40PowerIncForPdadc, 0));
1353 static u16 ath9k_hw_def_get_spur_channel(
struct ath_hw *ah,
u16 i,
bool is2GHz)
1355 #define EEP_DEF_SPURCHAN \
1356 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1357 struct ath_common *common = ath9k_hw_common(ah);
1361 ath_dbg(common, ANI,
"Getting spur idx:%d is2Ghz:%d val:%x\n",
1362 i, is2GHz, ah->
config.spurchans[i][is2GHz]);
1364 switch (ah->
config.spurmode) {
1368 spur_val = ah->
config.spurchans[
i][is2GHz];
1369 ath_dbg(common, ANI,
"Getting spur val from new loc. %d\n",
1379 #undef EEP_DEF_SPURCHAN
1383 .check_eeprom = ath9k_hw_def_check_eeprom,
1384 .get_eeprom = ath9k_hw_def_get_eeprom,
1385 .fill_eeprom = ath9k_hw_def_fill_eeprom,
1386 .dump_eeprom = ath9k_hw_def_dump_eeprom,
1387 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
1388 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
1389 .set_board_values = ath9k_hw_def_set_board_values,
1390 .set_addac = ath9k_hw_def_set_addac,
1391 .set_txpower = ath9k_hw_def_set_txpower,
1392 .get_spur_channel = ath9k_hw_def_get_spur_channel