0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/moduleparam.h>
0018 #include "hw.h"
0019 #include "ar5008_initvals.h"
0020 #include "ar9001_initvals.h"
0021 #include "ar9002_initvals.h"
0022 #include "ar9002_phy.h"
0023
0024
0025
0026 static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
0027 {
0028 if (AR_SREV_9271(ah)) {
0029 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271);
0030 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271);
0031 INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg);
0032 return 0;
0033 }
0034
0035 INIT_INI_ARRAY(&ah->iniPcieSerdes,
0036 ar9280PciePhy_clkreq_always_on_L1_9280);
0037
0038 if (AR_SREV_9287_11_OR_LATER(ah)) {
0039 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
0040 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1);
0041 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
0042 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2);
0043 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2);
0044 } else if (AR_SREV_9280_20_OR_LATER(ah)) {
0045 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2);
0046 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2);
0047
0048 INIT_INI_ARRAY(&ah->iniModesFastClock,
0049 ar9280Modes_fast_clock_9280_2);
0050 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
0051 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160);
0052 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160);
0053 if (AR_SREV_9160_11(ah)) {
0054 INIT_INI_ARRAY(&ah->iniAddac,
0055 ar5416Addac_9160_1_1);
0056 } else {
0057 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160);
0058 }
0059 } else if (AR_SREV_9100_OR_LATER(ah)) {
0060 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100);
0061 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100);
0062 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100);
0063 } else {
0064 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes);
0065 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common);
0066 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac);
0067 }
0068
0069 if (!AR_SREV_9280_20_OR_LATER(ah)) {
0070
0071 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain);
0072
0073
0074 if (!AR_SREV_5416(ah))
0075 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6TPC_9100);
0076 else
0077 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6TPC);
0078 }
0079
0080
0081 if (AR_SREV_9160(ah) || !AR_SREV_5416_22_OR_LATER(ah)) {
0082 struct ar5416IniArray *addac = &ah->iniAddac;
0083 u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns;
0084 u32 *data;
0085
0086 data = devm_kzalloc(ah->dev, size, GFP_KERNEL);
0087 if (!data)
0088 return -ENOMEM;
0089
0090 memcpy(data, addac->ia_array, size);
0091 addac->ia_array = data;
0092
0093 if (!AR_SREV_5416_22_OR_LATER(ah)) {
0094
0095 INI_RA(addac, 31,1) = 0;
0096 }
0097 }
0098 if (AR_SREV_9287_11_OR_LATER(ah)) {
0099 INIT_INI_ARRAY(&ah->iniCckfirNormal,
0100 ar9287Common_normal_cck_fir_coeff_9287_1_1);
0101 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
0102 ar9287Common_japan_2484_cck_fir_coeff_9287_1_1);
0103 }
0104 return 0;
0105 }
0106
0107 static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
0108 {
0109 u32 rxgain_type;
0110
0111 if (ah->eep_ops->get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_17) {
0112 rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
0113
0114 if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
0115 INIT_INI_ARRAY(&ah->iniModesRxGain,
0116 ar9280Modes_backoff_13db_rxgain_9280_2);
0117 else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
0118 INIT_INI_ARRAY(&ah->iniModesRxGain,
0119 ar9280Modes_backoff_23db_rxgain_9280_2);
0120 else
0121 INIT_INI_ARRAY(&ah->iniModesRxGain,
0122 ar9280Modes_original_rxgain_9280_2);
0123 } else {
0124 INIT_INI_ARRAY(&ah->iniModesRxGain,
0125 ar9280Modes_original_rxgain_9280_2);
0126 }
0127 }
0128
0129 static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type)
0130 {
0131 if (ah->eep_ops->get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19) {
0132 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
0133 INIT_INI_ARRAY(&ah->iniModesTxGain,
0134 ar9280Modes_high_power_tx_gain_9280_2);
0135 else
0136 INIT_INI_ARRAY(&ah->iniModesTxGain,
0137 ar9280Modes_original_tx_gain_9280_2);
0138 } else {
0139 INIT_INI_ARRAY(&ah->iniModesTxGain,
0140 ar9280Modes_original_tx_gain_9280_2);
0141 }
0142 }
0143
0144 static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type)
0145 {
0146 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
0147 INIT_INI_ARRAY(&ah->iniModesTxGain,
0148 ar9271Modes_high_power_tx_gain_9271);
0149 else
0150 INIT_INI_ARRAY(&ah->iniModesTxGain,
0151 ar9271Modes_normal_power_tx_gain_9271);
0152 }
0153
0154 static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
0155 {
0156 u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
0157
0158 if (AR_SREV_9287_11_OR_LATER(ah))
0159 INIT_INI_ARRAY(&ah->iniModesRxGain,
0160 ar9287Modes_rx_gain_9287_1_1);
0161 else if (AR_SREV_9280_20(ah))
0162 ar9280_20_hw_init_rxgain_ini(ah);
0163
0164 if (AR_SREV_9271(ah)) {
0165 ar9271_hw_init_txgain_ini(ah, txgain_type);
0166 } else if (AR_SREV_9287_11_OR_LATER(ah)) {
0167 INIT_INI_ARRAY(&ah->iniModesTxGain,
0168 ar9287Modes_tx_gain_9287_1_1);
0169 } else if (AR_SREV_9280_20(ah)) {
0170 ar9280_20_hw_init_txgain_ini(ah, txgain_type);
0171 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
0172
0173 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
0174 if (AR_SREV_9285E_20(ah)) {
0175 INIT_INI_ARRAY(&ah->iniModesTxGain,
0176 ar9285Modes_XE2_0_high_power);
0177 } else {
0178 INIT_INI_ARRAY(&ah->iniModesTxGain,
0179 ar9285Modes_high_power_tx_gain_9285_1_2);
0180 }
0181 } else {
0182 if (AR_SREV_9285E_20(ah)) {
0183 INIT_INI_ARRAY(&ah->iniModesTxGain,
0184 ar9285Modes_XE2_0_normal_power);
0185 } else {
0186 INIT_INI_ARRAY(&ah->iniModesTxGain,
0187 ar9285Modes_original_tx_gain_9285_1_2);
0188 }
0189 }
0190 }
0191 }
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
0203 bool power_off)
0204 {
0205 u8 i;
0206 u32 val;
0207
0208
0209 if (!power_off ) {
0210 if (AR_SREV_9280_20_OR_LATER(ah)) {
0211
0212
0213
0214
0215
0216 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
0217 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
0218 INI_RA(&ah->iniPcieSerdes, i, 1));
0219 }
0220 } else {
0221 ENABLE_REGWRITE_BUFFER(ah);
0222
0223 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
0224 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
0225
0226
0227 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
0228 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
0229 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
0230
0231
0232
0233
0234
0235 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
0236
0237 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
0238 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
0239 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
0240
0241
0242 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
0243
0244 REGWRITE_BUFFER_FLUSH(ah);
0245 }
0246
0247 udelay(1000);
0248 }
0249
0250 if (power_off) {
0251
0252 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
0253
0254 val = REG_READ(ah, AR_WA);
0255
0256
0257
0258
0259
0260
0261
0262 if (ah->config.pcie_waen) {
0263 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
0264 val |= AR_WA_D3_L1_DISABLE;
0265 } else {
0266 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah)) {
0267 if (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)
0268 val |= AR_WA_D3_L1_DISABLE;
0269 } else if (AR_SREV_9280(ah)) {
0270 if (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE)
0271 val |= AR_WA_D3_L1_DISABLE;
0272 }
0273 }
0274
0275 if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
0276
0277
0278
0279
0280 val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
0281 }
0282
0283 if (AR_SREV_9280(ah))
0284 val |= AR_WA_BIT22;
0285
0286 if (AR_SREV_9285E_20(ah))
0287 val |= AR_WA_BIT23;
0288
0289 REG_WRITE(ah, AR_WA, val);
0290 } else {
0291 if (ah->config.pcie_waen) {
0292 val = ah->config.pcie_waen;
0293 val &= (~AR_WA_D3_L1_DISABLE);
0294 } else {
0295 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah)) {
0296 val = AR9285_WA_DEFAULT;
0297 val &= (~AR_WA_D3_L1_DISABLE);
0298 } else if (AR_SREV_9280(ah)) {
0299
0300
0301
0302
0303 val = AR9280_WA_DEFAULT;
0304 val &= (~AR_WA_D3_L1_DISABLE);
0305 } else {
0306 val = AR_WA_DEFAULT;
0307 }
0308 }
0309
0310
0311 if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
0312 val |= (AR_WA_BIT6 | AR_WA_BIT7);
0313
0314 if (AR_SREV_9285E_20(ah))
0315 val |= AR_WA_BIT23;
0316
0317 REG_WRITE(ah, AR_WA, val);
0318
0319
0320 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
0321 }
0322 }
0323
0324 static int ar9002_hw_get_radiorev(struct ath_hw *ah)
0325 {
0326 u32 val;
0327 int i;
0328
0329 ENABLE_REGWRITE_BUFFER(ah);
0330
0331 REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
0332 for (i = 0; i < 8; i++)
0333 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
0334
0335 REGWRITE_BUFFER_FLUSH(ah);
0336
0337 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
0338 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
0339
0340 return ath9k_hw_reverse_bits(val, 8);
0341 }
0342
0343 int ar9002_hw_rf_claim(struct ath_hw *ah)
0344 {
0345 u32 val;
0346
0347 REG_WRITE(ah, AR_PHY(0), 0x00000007);
0348
0349 val = ar9002_hw_get_radiorev(ah);
0350 switch (val & AR_RADIO_SREV_MAJOR) {
0351 case 0:
0352 val = AR_RAD5133_SREV_MAJOR;
0353 break;
0354 case AR_RAD5133_SREV_MAJOR:
0355 case AR_RAD5122_SREV_MAJOR:
0356 case AR_RAD2133_SREV_MAJOR:
0357 case AR_RAD2122_SREV_MAJOR:
0358 break;
0359 default:
0360 ath_err(ath9k_hw_common(ah),
0361 "Radio Chip Rev 0x%02X not supported\n",
0362 val & AR_RADIO_SREV_MAJOR);
0363 return -EOPNOTSUPP;
0364 }
0365
0366 ah->hw_version.analog5GhzRev = val;
0367
0368 return 0;
0369 }
0370
0371 void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
0372 {
0373 if (AR_SREV_9287_13_OR_LATER(ah)) {
0374 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
0375 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
0376 REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
0377 REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
0378 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
0379 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
0380 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
0381 }
0382 }
0383
0384 static void ar9002_hw_init_hang_checks(struct ath_hw *ah)
0385 {
0386 if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
0387 ah->config.hw_hang_checks |= HW_BB_RIFS_HANG;
0388 ah->config.hw_hang_checks |= HW_BB_DFS_HANG;
0389 }
0390
0391 if (AR_SREV_9280(ah))
0392 ah->config.hw_hang_checks |= HW_BB_RX_CLEAR_STUCK_HANG;
0393
0394 if (AR_SREV_5416(ah) || AR_SREV_9100(ah) || AR_SREV_9160(ah))
0395 ah->config.hw_hang_checks |= HW_MAC_HANG;
0396 }
0397
0398
0399 int ar9002_hw_attach_ops(struct ath_hw *ah)
0400 {
0401 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
0402 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
0403 int ret;
0404
0405 ret = ar9002_hw_init_mode_regs(ah);
0406 if (ret)
0407 return ret;
0408
0409 priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
0410 priv_ops->init_hang_checks = ar9002_hw_init_hang_checks;
0411
0412 ops->config_pci_powersave = ar9002_hw_configpcipowersave;
0413
0414 ret = ar5008_hw_attach_phy_ops(ah);
0415 if (ret)
0416 return ret;
0417
0418 if (AR_SREV_9280_20_OR_LATER(ah))
0419 ar9002_hw_attach_phy_ops(ah);
0420
0421 ar9002_hw_attach_calib_ops(ah);
0422 ar9002_hw_attach_mac_ops(ah);
0423 return 0;
0424 }
0425
0426 void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
0427 {
0428 u32 modesIndex;
0429 int i;
0430
0431 if (IS_CHAN_5GHZ(chan))
0432 modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
0433 else
0434 modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
0435
0436 ENABLE_REGWRITE_BUFFER(ah);
0437
0438 for (i = 0; i < ah->iniModes_9271_ANI_reg.ia_rows; i++) {
0439 u32 reg = INI_RA(&ah->iniModes_9271_ANI_reg, i, 0);
0440 u32 val = INI_RA(&ah->iniModes_9271_ANI_reg, i, modesIndex);
0441 u32 val_orig;
0442
0443 if (reg == AR_PHY_CCK_DETECT) {
0444 val_orig = REG_READ(ah, reg);
0445 val &= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
0446 val_orig &= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
0447
0448 REG_WRITE(ah, reg, val|val_orig);
0449 } else
0450 REG_WRITE(ah, reg, val);
0451 }
0452
0453 REGWRITE_BUFFER_FLUSH(ah);
0454 }