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