00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include "ath5k_linux_layer.h"
00055 #include "ath5k.h"
00056 #include "reg.h"
00057 #include "debug.h"
00058 #include "base.h"
00059
00065 static int ath5k_hw_post(struct ath5k_hw *ah)
00066 {
00067
00068 static const u32 static_pattern[4] = {
00069 0x55555555, 0xaaaaaaaa,
00070 0x66666666, 0x99999999
00071 };
00072 static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
00073 int i, c;
00074 u16 cur_reg;
00075 u32 var_pattern;
00076 u32 init_val;
00077 u32 cur_val;
00078
00079 for (c = 0; c < 2; c++) {
00080
00081 cur_reg = regs[c];
00082
00083
00084 init_val = ath5k_hw_reg_read(ah, cur_reg);
00085
00086 for (i = 0; i < 256; i++) {
00087 var_pattern = i << 16 | i;
00088 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
00089 cur_val = ath5k_hw_reg_read(ah, cur_reg);
00090
00091 if (cur_val != var_pattern) {
00092 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
00093 return -EAGAIN;
00094 }
00095
00096
00097 var_pattern = 0x0039080f;
00098 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
00099 }
00100
00101 for (i = 0; i < 4; i++) {
00102 var_pattern = static_pattern[i];
00103 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
00104 cur_val = ath5k_hw_reg_read(ah, cur_reg);
00105
00106 if (cur_val != var_pattern) {
00107 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
00108 return -EAGAIN;
00109 }
00110
00111
00112 var_pattern = 0x003b080f;
00113 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
00114 }
00115
00116
00117 ath5k_hw_reg_write(ah, init_val, cur_reg);
00118
00119 }
00120
00121 return 0;
00122
00123 }
00124
00135 int ath5k_hw_attach(struct ath5k_softc *sc)
00136 {
00137 struct ath5k_hw *ah = sc->ah;
00138 struct ath5k_eeprom_info *ee;
00139 int ret;
00140 u32 srev;
00141 u8 mac[ETH_ALEN];
00142
00143
00144
00145
00146 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
00147 ah->ah_turbo = false;
00148 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
00149 ah->ah_imr = 0;
00150 ah->ah_atim_window = 0;
00151 ah->ah_aifs = AR5K_TUNE_AIFS;
00152 ah->ah_cw_min = AR5K_TUNE_CWMIN;
00153 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
00154 ah->ah_software_retry = false;
00155
00156
00157
00158
00159 srev = ath5k_hw_reg_read(ah, AR5K_SREV);
00160 if (srev < AR5K_SREV_AR5311)
00161 ah->ah_version = AR5K_AR5210;
00162 else if (srev < AR5K_SREV_AR5212)
00163 ah->ah_version = AR5K_AR5211;
00164 else
00165 ah->ah_version = AR5K_AR5212;
00166
00167
00168 ret = ath5k_hw_init_desc_functions(ah);
00169 if (ret)
00170 goto err_free;
00171
00172
00173 ret = ath5k_hw_nic_wakeup(ah, 0, true);
00174 if (ret)
00175 goto err_free;
00176
00177
00178 ah->ah_mac_srev = srev;
00179 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
00180 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
00181 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
00182 0xffffffff;
00183 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
00184 CHANNEL_5GHZ);
00185 ah->ah_phy = AR5K_PHY(0);
00186
00187
00188 switch (ah->ah_radio_5ghz_revision & 0xf0) {
00189 case AR5K_SREV_RAD_5111:
00190 ah->ah_radio = AR5K_RF5111;
00191 ah->ah_single_chip = false;
00192 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
00193 CHANNEL_2GHZ);
00194 break;
00195 case AR5K_SREV_RAD_5112:
00196 case AR5K_SREV_RAD_2112:
00197 ah->ah_radio = AR5K_RF5112;
00198 ah->ah_single_chip = false;
00199 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
00200 CHANNEL_2GHZ);
00201 break;
00202 case AR5K_SREV_RAD_2413:
00203 ah->ah_radio = AR5K_RF2413;
00204 ah->ah_single_chip = true;
00205 break;
00206 case AR5K_SREV_RAD_5413:
00207 ah->ah_radio = AR5K_RF5413;
00208 ah->ah_single_chip = true;
00209 break;
00210 case AR5K_SREV_RAD_2316:
00211 ah->ah_radio = AR5K_RF2316;
00212 ah->ah_single_chip = true;
00213 break;
00214 case AR5K_SREV_RAD_2317:
00215 ah->ah_radio = AR5K_RF2317;
00216 ah->ah_single_chip = true;
00217 break;
00218 case AR5K_SREV_RAD_5424:
00219 if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
00220 ah->ah_mac_version == AR5K_SREV_AR2417){
00221 ah->ah_radio = AR5K_RF2425;
00222 ah->ah_single_chip = true;
00223 } else {
00224 ah->ah_radio = AR5K_RF5413;
00225 ah->ah_single_chip = true;
00226 }
00227 break;
00228 default:
00229
00230 if (ah->ah_version == AR5K_AR5210) {
00231 ah->ah_radio = AR5K_RF5110;
00232 ah->ah_single_chip = false;
00233 } else if (ah->ah_version == AR5K_AR5211) {
00234 ah->ah_radio = AR5K_RF5111;
00235 ah->ah_single_chip = false;
00236 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
00237 CHANNEL_2GHZ);
00238 } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
00239 ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
00240 ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
00241 ah->ah_radio = AR5K_RF2425;
00242 ah->ah_single_chip = true;
00243 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
00244 } else if (srev == AR5K_SREV_AR5213A &&
00245 ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
00246 ah->ah_radio = AR5K_RF5112;
00247 ah->ah_single_chip = false;
00248 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
00249 } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
00250 ah->ah_radio = AR5K_RF2316;
00251 ah->ah_single_chip = true;
00252 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
00253 } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
00254 ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
00255 ah->ah_radio = AR5K_RF5413;
00256 ah->ah_single_chip = true;
00257 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
00258 } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
00259 ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
00260 ah->ah_radio = AR5K_RF2413;
00261 ah->ah_single_chip = true;
00262 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
00263 } else {
00264 ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
00265 ret = -ENODEV;
00266 goto err_free;
00267 }
00268 }
00269
00270
00271
00272 if ((srev >= AR5K_SREV_AR5416) &&
00273 (srev < AR5K_SREV_AR2425)) {
00274 ATH5K_ERR(sc, "Device not yet supported.\n");
00275 ret = -ENODEV;
00276 goto err_free;
00277 }
00278
00279
00280
00281
00282 ret = ath5k_hw_post(ah);
00283 if (ret)
00284 goto err_free;
00285
00286
00287 if (srev >= AR5K_SREV_AR5213A)
00288 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_RETRY_FIX);
00289
00290
00291
00292
00293
00294 ret = ath5k_eeprom_init(ah);
00295 if (ret) {
00296 ATH5K_ERR(sc, "unable to init EEPROM\n");
00297 goto err_free;
00298 }
00299
00300 ee = &ah->ah_capabilities.cap_eeprom;
00301
00302
00303 ret = ath5k_hw_set_capabilities(ah);
00304 if (ret) {
00305 ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
00306 sc->pdev->dev_id);
00307 goto err_free;
00308 }
00309
00310 if (srev >= AR5K_SREV_AR2414) {
00311 ah->ah_combined_mic = true;
00312 AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
00313 AR5K_MISC_MODE_COMBINED_MIC);
00314 }
00315
00316
00317 ret = ath5k_eeprom_read_mac(ah, mac);
00318 if (ret) {
00319 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
00320 sc->pdev->dev_id);
00321 goto err_free;
00322 }
00323
00324 ath5k_hw_set_lladdr(ah, mac);
00325
00326
00327 memset(ah->ah_bssid, 0xff, ETH_ALEN);
00328 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
00329 ath5k_hw_set_opmode(ah);
00330
00331 ath5k_hw_rfgain_opt_init(ah);
00332
00333 return 0;
00334 err_free:
00335 return ret;
00336 }
00337
00343 void ath5k_hw_detach(struct ath5k_hw *ah)
00344 {
00345 ATH5K_TRACE(ah->ah_sc);
00346
00347 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
00348
00349 if (ah->ah_rf_banks != NULL)
00350 kfree(ah->ah_rf_banks);
00351
00352 ath5k_eeprom_detach(ah);
00353
00354
00355 kfree(ah);
00356 }