0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0024
0025 #include <linux/pci.h>
0026 #include <linux/slab.h>
0027 #include "ath5k.h"
0028 #include "reg.h"
0029 #include "debug.h"
0030
0031
0032
0033
0034
0035 static int ath5k_hw_post(struct ath5k_hw *ah)
0036 {
0037
0038 static const u32 static_pattern[4] = {
0039 0x55555555, 0xaaaaaaaa,
0040 0x66666666, 0x99999999
0041 };
0042 static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
0043 int i, c;
0044 u16 cur_reg;
0045 u32 var_pattern;
0046 u32 init_val;
0047 u32 cur_val;
0048
0049 for (c = 0; c < 2; c++) {
0050
0051 cur_reg = regs[c];
0052
0053
0054 init_val = ath5k_hw_reg_read(ah, cur_reg);
0055
0056 for (i = 0; i < 256; i++) {
0057 var_pattern = i << 16 | i;
0058 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
0059 cur_val = ath5k_hw_reg_read(ah, cur_reg);
0060
0061 if (cur_val != var_pattern) {
0062 ATH5K_ERR(ah, "POST Failed !!!\n");
0063 return -EAGAIN;
0064 }
0065
0066
0067 var_pattern = 0x0039080f;
0068 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
0069 }
0070
0071 for (i = 0; i < 4; i++) {
0072 var_pattern = static_pattern[i];
0073 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
0074 cur_val = ath5k_hw_reg_read(ah, cur_reg);
0075
0076 if (cur_val != var_pattern) {
0077 ATH5K_ERR(ah, "POST Failed !!!\n");
0078 return -EAGAIN;
0079 }
0080
0081
0082 var_pattern = 0x003b080f;
0083 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
0084 }
0085
0086
0087 ath5k_hw_reg_write(ah, init_val, cur_reg);
0088
0089 }
0090
0091 return 0;
0092
0093 }
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 int ath5k_hw_init(struct ath5k_hw *ah)
0105 {
0106 static const u8 zero_mac[ETH_ALEN] = { };
0107 struct ath_common *common = ath5k_hw_common(ah);
0108 struct pci_dev *pdev = ah->pdev;
0109 struct ath5k_eeprom_info *ee;
0110 int ret;
0111 u32 srev;
0112
0113
0114
0115
0116 ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
0117 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
0118 ah->ah_imr = 0;
0119 ah->ah_retry_short = AR5K_INIT_RETRY_SHORT;
0120 ah->ah_retry_long = AR5K_INIT_RETRY_LONG;
0121 ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
0122 ah->ah_noise_floor = -95;
0123 ah->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO;
0124 ah->ah_current_channel = &ah->channels[0];
0125
0126
0127
0128
0129 ath5k_hw_read_srev(ah);
0130 srev = ah->ah_mac_srev;
0131 if (srev < AR5K_SREV_AR5311)
0132 ah->ah_version = AR5K_AR5210;
0133 else if (srev < AR5K_SREV_AR5212)
0134 ah->ah_version = AR5K_AR5211;
0135 else
0136 ah->ah_version = AR5K_AR5212;
0137
0138
0139 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
0140
0141
0142 ret = ath5k_hw_init_desc_functions(ah);
0143 if (ret)
0144 goto err;
0145
0146
0147 ret = ath5k_hw_nic_wakeup(ah, NULL);
0148 if (ret)
0149 goto err;
0150
0151
0152 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
0153 0xffffffff;
0154 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
0155 NL80211_BAND_5GHZ);
0156
0157
0158 switch (ah->ah_radio_5ghz_revision & 0xf0) {
0159 case AR5K_SREV_RAD_5111:
0160 ah->ah_radio = AR5K_RF5111;
0161 ah->ah_single_chip = false;
0162 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
0163 NL80211_BAND_2GHZ);
0164 break;
0165 case AR5K_SREV_RAD_5112:
0166 case AR5K_SREV_RAD_2112:
0167 ah->ah_radio = AR5K_RF5112;
0168 ah->ah_single_chip = false;
0169 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
0170 NL80211_BAND_2GHZ);
0171 break;
0172 case AR5K_SREV_RAD_2413:
0173 ah->ah_radio = AR5K_RF2413;
0174 ah->ah_single_chip = true;
0175 break;
0176 case AR5K_SREV_RAD_5413:
0177 ah->ah_radio = AR5K_RF5413;
0178 ah->ah_single_chip = true;
0179 break;
0180 case AR5K_SREV_RAD_2316:
0181 ah->ah_radio = AR5K_RF2316;
0182 ah->ah_single_chip = true;
0183 break;
0184 case AR5K_SREV_RAD_2317:
0185 ah->ah_radio = AR5K_RF2317;
0186 ah->ah_single_chip = true;
0187 break;
0188 case AR5K_SREV_RAD_5424:
0189 if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
0190 ah->ah_mac_version == AR5K_SREV_AR2417) {
0191 ah->ah_radio = AR5K_RF2425;
0192 ah->ah_single_chip = true;
0193 } else {
0194 ah->ah_radio = AR5K_RF5413;
0195 ah->ah_single_chip = true;
0196 }
0197 break;
0198 default:
0199
0200 if (ah->ah_version == AR5K_AR5210) {
0201 ah->ah_radio = AR5K_RF5110;
0202 ah->ah_single_chip = false;
0203 } else if (ah->ah_version == AR5K_AR5211) {
0204 ah->ah_radio = AR5K_RF5111;
0205 ah->ah_single_chip = false;
0206 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
0207 NL80211_BAND_2GHZ);
0208 } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
0209 ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
0210 ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
0211 ah->ah_radio = AR5K_RF2425;
0212 ah->ah_single_chip = true;
0213 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
0214 } else if (srev == AR5K_SREV_AR5213A &&
0215 ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
0216 ah->ah_radio = AR5K_RF5112;
0217 ah->ah_single_chip = false;
0218 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
0219 } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) ||
0220 ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) {
0221 ah->ah_radio = AR5K_RF2316;
0222 ah->ah_single_chip = true;
0223 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
0224 } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
0225 ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
0226 ah->ah_radio = AR5K_RF5413;
0227 ah->ah_single_chip = true;
0228 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
0229 } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
0230 ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
0231 ah->ah_radio = AR5K_RF2413;
0232 ah->ah_single_chip = true;
0233 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
0234 } else {
0235 ATH5K_ERR(ah, "Couldn't identify radio revision.\n");
0236 ret = -ENODEV;
0237 goto err;
0238 }
0239 }
0240
0241
0242
0243 if ((srev >= AR5K_SREV_AR5416) && (srev < AR5K_SREV_AR2425)) {
0244 ATH5K_ERR(ah, "Device not yet supported.\n");
0245 ret = -ENODEV;
0246 goto err;
0247 }
0248
0249
0250
0251
0252 ret = ath5k_hw_post(ah);
0253 if (ret)
0254 goto err;
0255
0256
0257 if (srev >= AR5K_SREV_AR5213A)
0258 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_RETRY_FIX);
0259
0260
0261
0262
0263
0264 ret = ath5k_eeprom_init(ah);
0265 if (ret) {
0266 ATH5K_ERR(ah, "unable to init EEPROM\n");
0267 goto err;
0268 }
0269
0270 ee = &ah->ah_capabilities.cap_eeprom;
0271
0272
0273
0274
0275 if ((ah->ah_version == AR5K_AR5212) && pdev && (pci_is_pcie(pdev))) {
0276 ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
0277 ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
0278
0279
0280 ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
0281 ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
0282
0283
0284
0285
0286 if (ee->ee_serdes)
0287 ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
0288 else
0289 ath5k_hw_reg_write(ah, 0xf6800579, AR5K_PCIE_SERDES);
0290
0291
0292 ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
0293
0294
0295 ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
0296 ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
0297 ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
0298
0299
0300 ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
0301 usleep_range(1000, 1500);
0302 }
0303
0304
0305 ret = ath5k_hw_set_capabilities(ah);
0306 if (ret) {
0307 ATH5K_ERR(ah, "unable to get device capabilities\n");
0308 goto err;
0309 }
0310
0311
0312 common->keymax = (ah->ah_version == AR5K_AR5210 ?
0313 AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211);
0314
0315 if (srev >= AR5K_SREV_AR5212_V4 &&
0316 (ee->ee_version < AR5K_EEPROM_VERSION_5_0 ||
0317 !AR5K_EEPROM_AES_DIS(ee->ee_misc5)))
0318 common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
0319
0320 if (srev >= AR5K_SREV_AR2414) {
0321 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
0322 AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
0323 AR5K_MISC_MODE_COMBINED_MIC);
0324 }
0325
0326
0327 ath5k_hw_set_lladdr(ah, zero_mac);
0328
0329
0330 eth_broadcast_addr(common->curbssid);
0331 ath5k_hw_set_bssid(ah);
0332 ath5k_hw_set_opmode(ah, ah->opmode);
0333
0334 ath5k_hw_rfgain_opt_init(ah);
0335
0336 ath5k_hw_init_nfcal_hist(ah);
0337
0338
0339 ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
0340
0341 return 0;
0342 err:
0343 return ret;
0344 }
0345
0346
0347
0348
0349
0350 void ath5k_hw_deinit(struct ath5k_hw *ah)
0351 {
0352 __set_bit(ATH_STAT_INVALID, ah->status);
0353
0354 kfree(ah->ah_rf_banks);
0355
0356 ath5k_eeprom_detach(ah);
0357
0358
0359 }