00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 FILE_LICENCE ( MIT );
00025
00026 #define _ATH5K_RESET
00027
00028
00029
00030
00031
00032 #include <gpxe/pci.h>
00033 #include <unistd.h>
00034
00035 #include "ath5k.h"
00036 #include "reg.h"
00037 #include "base.h"
00038
00039
00040 static int fls(int x)
00041 {
00042 int r = 32;
00043
00044 if (!x)
00045 return 0;
00046 if (!(x & 0xffff0000u)) {
00047 x <<= 16;
00048 r -= 16;
00049 }
00050 if (!(x & 0xff000000u)) {
00051 x <<= 8;
00052 r -= 8;
00053 }
00054 if (!(x & 0xf0000000u)) {
00055 x <<= 4;
00056 r -= 4;
00057 }
00058 if (!(x & 0xc0000000u)) {
00059 x <<= 2;
00060 r -= 2;
00061 }
00062 if (!(x & 0x80000000u)) {
00063 x <<= 1;
00064 r -= 1;
00065 }
00066 return r;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 static int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
00086 struct net80211_channel *channel)
00087 {
00088
00089 u32 coef_scaled, coef_exp, coef_man,
00090 ds_coef_exp, ds_coef_man, clock;
00091
00092 if (!(ah->ah_version == AR5K_AR5212) ||
00093 !(channel->hw_value & CHANNEL_OFDM)) {
00094 DBG("ath5k: attempt to set OFDM timings on non-OFDM channel\n");
00095 return -EFAULT;
00096 }
00097
00098
00099
00100
00101
00102
00103 clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO);
00104
00105 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
00106
00107
00108
00109 coef_exp = fls(coef_scaled) - 1;
00110
00111
00112 if (!coef_scaled || !coef_exp)
00113 return -EINVAL;
00114
00115
00116 coef_exp = 14 - (coef_exp - 24);
00117
00118
00119
00120
00121 coef_man = coef_scaled +
00122 (1 << (24 - coef_exp - 1));
00123
00124
00125
00126 ds_coef_man = coef_man >> (24 - coef_exp);
00127 ds_coef_exp = coef_exp - 16;
00128
00129 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
00130 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
00131 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
00132 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
00133
00134 return 0;
00135 }
00136
00137
00138
00139
00140
00141
00142 static const unsigned int control_rates[] =
00143 { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
00165 unsigned int mode __unused)
00166 {
00167 struct ath5k_softc *sc = ah->ah_sc;
00168 u16 rate;
00169 int i;
00170
00171
00172 for (i = 0; i < sc->hwinfo->nr_rates[NET80211_BAND_2GHZ]; i++) {
00173 u32 reg;
00174 u16 tx_time;
00175
00176 rate = sc->hwinfo->rates[NET80211_BAND_2GHZ][i];
00177
00178
00179 reg = AR5K_RATE_DUR(ath5k_bitrate_to_hw_rix(rate));
00180
00181
00182
00183
00184
00185
00186 tx_time = net80211_duration(sc->dev, 14, rate);
00187
00188 ath5k_hw_reg_write(ah, tx_time, reg);
00189
00190 if (rate != 20 && rate != 55 && rate != 110)
00191 continue;
00192
00193
00194
00195
00196
00197
00198 ath5k_hw_reg_write(ah, tx_time,
00199 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
00200 }
00201 }
00202
00203
00204
00205
00206 static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
00207 {
00208 int ret;
00209 u32 mask = val ? val : ~0U;
00210
00211
00212 ath5k_hw_reg_read(ah, AR5K_RXDP);
00213
00214
00215
00216
00217 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
00218
00219
00220 udelay(15);
00221
00222 if (ah->ah_version == AR5K_AR5210) {
00223 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
00224 | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
00225 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
00226 | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
00227 } else {
00228 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
00229 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
00230 }
00231
00232 ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, 0);
00233
00234
00235
00236
00237
00238
00239 if ((val & AR5K_RESET_CTL_PCU) == 0)
00240 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
00241
00242 return ret;
00243 }
00244
00245
00246
00247
00248 int ath5k_hw_wake(struct ath5k_hw *ah)
00249 {
00250 unsigned int i;
00251 u32 staid, data;
00252
00253 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
00254 staid &= ~AR5K_STA_ID1_PWR_SV;
00255
00256
00257 data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
00258 if (data & 0xffc00000)
00259 data = 0;
00260 else
00261 data = data & 0xfffcffff;
00262
00263 ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
00264 udelay(15);
00265
00266 for (i = 50; i > 0; i--) {
00267
00268 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
00269 AR5K_PCICFG_SPWR_DN) == 0)
00270 break;
00271
00272
00273 udelay(200);
00274 ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
00275 }
00276
00277
00278 if (i <= 0)
00279 return -EIO;
00280
00281 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
00282
00283 return 0;
00284 }
00285
00286
00287
00288
00289
00290 int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, int initial __unused)
00291 {
00292 struct pci_device *pdev = ah->ah_sc->pdev;
00293 u32 turbo, mode, clock, bus_flags;
00294 int ret;
00295
00296 turbo = 0;
00297 mode = 0;
00298 clock = 0;
00299
00300
00301 ret = ath5k_hw_wake(ah);
00302 if (ret) {
00303 DBG("ath5k: failed to wake up the MAC chip\n");
00304 return ret;
00305 }
00306
00307 if (ah->ah_version != AR5K_AR5210) {
00308
00309
00310
00311
00312 if (ah->ah_radio >= AR5K_RF5112) {
00313 mode = AR5K_PHY_MODE_RAD_RF5112;
00314 clock = AR5K_PHY_PLL_RF5112;
00315 } else {
00316 mode = AR5K_PHY_MODE_RAD_RF5111;
00317 clock = AR5K_PHY_PLL_RF5111;
00318 }
00319
00320 if (flags & CHANNEL_2GHZ) {
00321 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
00322 clock |= AR5K_PHY_PLL_44MHZ;
00323
00324 if (flags & CHANNEL_CCK) {
00325 mode |= AR5K_PHY_MODE_MOD_CCK;
00326 } else if (flags & CHANNEL_OFDM) {
00327
00328
00329
00330
00331
00332
00333 if (ah->ah_version == AR5K_AR5211)
00334 mode |= AR5K_PHY_MODE_MOD_OFDM;
00335 else
00336 mode |= AR5K_PHY_MODE_MOD_DYN;
00337 } else {
00338 DBG("ath5k: invalid radio modulation mode\n");
00339 return -EINVAL;
00340 }
00341 } else if (flags & CHANNEL_5GHZ) {
00342 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
00343
00344 if (ah->ah_radio == AR5K_RF5413)
00345 clock = AR5K_PHY_PLL_40MHZ_5413;
00346 else
00347 clock |= AR5K_PHY_PLL_40MHZ;
00348
00349 if (flags & CHANNEL_OFDM)
00350 mode |= AR5K_PHY_MODE_MOD_OFDM;
00351 else {
00352 DBG("ath5k: invalid radio modulation mode\n");
00353 return -EINVAL;
00354 }
00355 } else {
00356 DBG("ath5k: invalid radio frequency mode\n");
00357 return -EINVAL;
00358 }
00359
00360 if (flags & CHANNEL_TURBO)
00361 turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
00362 } else {
00363
00364
00365 if (flags & CHANNEL_TURBO)
00366 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
00367 AR5K_PHY_TURBO);
00368 }
00369
00370
00371
00372
00373 if (pci_find_capability(pdev, PCI_CAP_ID_EXP))
00374 bus_flags = 0;
00375 else
00376 bus_flags = AR5K_RESET_CTL_PCI;
00377
00378
00379 if (ah->ah_version == AR5K_AR5210) {
00380 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
00381 AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
00382 AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
00383 mdelay(2);
00384 } else {
00385 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
00386 AR5K_RESET_CTL_BASEBAND | bus_flags);
00387 }
00388 if (ret) {
00389 DBG("ath5k: failed to reset the MAC chip\n");
00390 return -EIO;
00391 }
00392
00393
00394 ret = ath5k_hw_wake(ah);
00395 if (ret) {
00396 DBG("ath5k: failed to resume the MAC chip\n");
00397 return ret;
00398 }
00399
00400
00401 if (ath5k_hw_nic_reset(ah, 0)) {
00402 DBG("ath5k: failed to warm reset the MAC chip\n");
00403 return -EIO;
00404 }
00405
00406 if (ah->ah_version != AR5K_AR5210) {
00407
00408
00409 if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
00410 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
00411 udelay(300);
00412 }
00413
00414
00415 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
00416 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
00417 }
00418
00419 return 0;
00420 }
00421
00422 static int ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
00423 struct net80211_channel *channel)
00424 {
00425 u8 refclk_freq;
00426
00427 if ((ah->ah_radio == AR5K_RF5112) ||
00428 (ah->ah_radio == AR5K_RF5413) ||
00429 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
00430 refclk_freq = 40;
00431 else
00432 refclk_freq = 32;
00433
00434 if ((channel->center_freq % refclk_freq != 0) &&
00435 ((channel->center_freq % refclk_freq < 10) ||
00436 (channel->center_freq % refclk_freq > 22)))
00437 return 1;
00438 else
00439 return 0;
00440 }
00441
00442
00443 static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
00444 struct net80211_channel *channel)
00445 {
00446 if (ah->ah_version == AR5K_AR5212 &&
00447 ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
00448
00449
00450 ath5k_hw_reg_write(ah,
00451 (AR5K_REG_SM(2,
00452 AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
00453 AR5K_REG_SM(2,
00454 AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
00455 AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
00456 AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
00457 AR5K_PHY_ADC_CTL);
00458
00459
00460
00461
00462 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
00463 AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
00464
00465 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
00466 AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
00467
00468
00469 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
00470 }
00471
00472
00473 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
00474 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
00475
00476
00477 if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
00478 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
00479 AR5K_TXCFG_DCU_DBL_BUF_DIS);
00480
00481
00482 if (ah->ah_version == AR5K_AR5212) {
00483 u32 scal;
00484 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
00485 scal = AR5K_PHY_SCAL_32MHZ_2417;
00486 else if (ath5k_eeprom_is_hb63(ah))
00487 scal = AR5K_PHY_SCAL_32MHZ_HB63;
00488 else
00489 scal = AR5K_PHY_SCAL_32MHZ;
00490 ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
00491 }
00492
00493
00494 if ((ah->ah_radio == AR5K_RF5413) ||
00495 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
00496 u32 fast_adc = 1;
00497
00498 if (channel->center_freq == 2462 ||
00499 channel->center_freq == 2467)
00500 fast_adc = 0;
00501
00502
00503 if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
00504 ath5k_hw_reg_write(ah, fast_adc,
00505 AR5K_PHY_FAST_ADC);
00506 }
00507
00508
00509 if (ah->ah_radio == AR5K_RF5112 &&
00510 ah->ah_radio_5ghz_revision <
00511 AR5K_SREV_RAD_5112A) {
00512 u32 data;
00513 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
00514 AR5K_PHY_CCKTXCTL);
00515 if (channel->hw_value & CHANNEL_5GHZ)
00516 data = 0xffb81020;
00517 else
00518 data = 0xffb80d20;
00519 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
00520 }
00521
00522 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
00523 u32 usec_reg;
00524
00525
00526
00527
00528 usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
00529 ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
00530 AR5K_USEC_32 |
00531 AR5K_USEC_TX_LATENCY_5211 |
00532 AR5K_REG_SM(29,
00533 AR5K_USEC_RX_LATENCY_5210)),
00534 AR5K_USEC_5211);
00535
00536 ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
00537
00538 ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
00539
00540 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
00541 AR5K_DIAG_SW_ECO_ENABLE);
00542 }
00543 }
00544
00545 static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
00546 struct net80211_channel *channel, u8 *ant, u8 ee_mode)
00547 {
00548 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
00549 s16 cck_ofdm_pwr_delta;
00550
00551
00552 if (channel->center_freq == 2484)
00553 cck_ofdm_pwr_delta =
00554 ((ee->ee_cck_ofdm_power_delta -
00555 ee->ee_scaled_cck_delta) * 2) / 10;
00556 else
00557 cck_ofdm_pwr_delta =
00558 (ee->ee_cck_ofdm_power_delta * 2) / 10;
00559
00560
00561
00562 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
00563 if (channel->hw_value == CHANNEL_G)
00564 ath5k_hw_reg_write(ah,
00565 AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
00566 AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
00567 AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
00568 AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
00569 AR5K_PHY_TX_PWR_ADJ);
00570 else
00571 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
00572 } else {
00573
00574
00575 ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
00576 ah->ah_txpower.txp_cck_ofdm_gainf_delta =
00577 ee->ee_cck_ofdm_gain_delta;
00578 }
00579
00580
00581 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
00582 AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
00583 (ah->ah_antenna[ee_mode][0] |
00584 AR5K_PHY_ANT_CTL_TXRX_EN));
00585
00586
00587 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
00588 AR5K_PHY_ANT_SWITCH_TABLE_0);
00589 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
00590 AR5K_PHY_ANT_SWITCH_TABLE_1);
00591
00592
00593 ath5k_hw_reg_write(ah,
00594 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
00595 AR5K_PHY_NFTHRES);
00596
00597 if ((channel->hw_value & CHANNEL_TURBO) &&
00598 (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
00599
00600 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
00601 AR5K_PHY_SETTLING_SWITCH,
00602 ee->ee_switch_settling_turbo[ee_mode]);
00603
00604
00605 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
00606 AR5K_PHY_GAIN_TXRX_ATTEN,
00607 ee->ee_atn_tx_rx_turbo[ee_mode]);
00608
00609
00610 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
00611 AR5K_PHY_DESIRED_SIZE_ADC,
00612 ee->ee_adc_desired_size_turbo[ee_mode]);
00613
00614 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
00615 AR5K_PHY_DESIRED_SIZE_PGA,
00616 ee->ee_pga_desired_size_turbo[ee_mode]);
00617
00618
00619 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
00620 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
00621 ee->ee_margin_tx_rx_turbo[ee_mode]);
00622
00623 } else {
00624
00625 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
00626 AR5K_PHY_SETTLING_SWITCH,
00627 ee->ee_switch_settling[ee_mode]);
00628
00629
00630 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
00631 AR5K_PHY_GAIN_TXRX_ATTEN,
00632 ee->ee_atn_tx_rx[ee_mode]);
00633
00634
00635 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
00636 AR5K_PHY_DESIRED_SIZE_ADC,
00637 ee->ee_adc_desired_size[ee_mode]);
00638
00639 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
00640 AR5K_PHY_DESIRED_SIZE_PGA,
00641 ee->ee_pga_desired_size[ee_mode]);
00642
00643
00644 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
00645 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
00646 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
00647 ee->ee_margin_tx_rx[ee_mode]);
00648 }
00649
00650
00651 ath5k_hw_reg_write(ah,
00652 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
00653 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
00654 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
00655 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
00656
00657
00658 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
00659 AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
00660 ee->ee_tx_end2xlna_enable[ee_mode]);
00661
00662
00663 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
00664 AR5K_PHY_NF_THRESH62,
00665 ee->ee_thr_62[ee_mode]);
00666
00667
00668
00669
00670
00671 if (ath5k_hw_chan_has_spur_noise(ah, channel))
00672 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
00673 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
00674 AR5K_INIT_CYCRSSI_THR1 +
00675 ee->ee_false_detect[ee_mode]);
00676 else
00677 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
00678 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
00679 AR5K_INIT_CYCRSSI_THR1);
00680
00681
00682
00683 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
00684 AR5K_PHY_IQ_CORR_ENABLE |
00685 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
00686 ee->ee_q_cal[ee_mode]);
00687
00688
00689 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
00690 ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
00691
00692 return;
00693 }
00694
00695
00696
00697
00698 int ath5k_hw_reset(struct ath5k_hw *ah,
00699 struct net80211_channel *channel, int change_channel)
00700 {
00701 u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
00702 u32 phy_tst1;
00703 u8 mode, freq, ee_mode, ant[2];
00704 int i, ret;
00705
00706 s_ant = 0;
00707 ee_mode = 0;
00708 staid1_flags = 0;
00709 tsf_up = 0;
00710 tsf_lo = 0;
00711 freq = 0;
00712 mode = 0;
00713
00714
00715
00716
00717
00718 if (ah->ah_version != AR5K_AR5210) {
00719
00720 switch (channel->hw_value & CHANNEL_MODES) {
00721 case CHANNEL_A:
00722 mode = AR5K_MODE_11A;
00723 freq = AR5K_INI_RFGAIN_5GHZ;
00724 ee_mode = AR5K_EEPROM_MODE_11A;
00725 break;
00726 case CHANNEL_G:
00727 mode = AR5K_MODE_11G;
00728 freq = AR5K_INI_RFGAIN_2GHZ;
00729 ee_mode = AR5K_EEPROM_MODE_11G;
00730 break;
00731 case CHANNEL_B:
00732 mode = AR5K_MODE_11B;
00733 freq = AR5K_INI_RFGAIN_2GHZ;
00734 ee_mode = AR5K_EEPROM_MODE_11B;
00735 break;
00736 case CHANNEL_T:
00737 mode = AR5K_MODE_11A_TURBO;
00738 freq = AR5K_INI_RFGAIN_5GHZ;
00739 ee_mode = AR5K_EEPROM_MODE_11A;
00740 break;
00741 case CHANNEL_TG:
00742 if (ah->ah_version == AR5K_AR5211) {
00743 DBG("ath5k: TurboG not available on 5211\n");
00744 return -EINVAL;
00745 }
00746 mode = AR5K_MODE_11G_TURBO;
00747 freq = AR5K_INI_RFGAIN_2GHZ;
00748 ee_mode = AR5K_EEPROM_MODE_11G;
00749 break;
00750 case CHANNEL_XR:
00751 if (ah->ah_version == AR5K_AR5211) {
00752 DBG("ath5k: XR mode not available on 5211\n");
00753 return -EINVAL;
00754 }
00755 mode = AR5K_MODE_XR;
00756 freq = AR5K_INI_RFGAIN_5GHZ;
00757 ee_mode = AR5K_EEPROM_MODE_11A;
00758 break;
00759 default:
00760 DBG("ath5k: invalid channel (%d MHz)\n",
00761 channel->center_freq);
00762 return -EINVAL;
00763 }
00764
00765 if (change_channel) {
00766
00767
00768
00769
00770
00771 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
00772
00773 for (i = 0; i < 10; i++)
00774 s_seq[i] = ath5k_hw_reg_read(ah,
00775 AR5K_QUEUE_DCU_SEQNUM(i));
00776
00777 } else {
00778 s_seq[0] = ath5k_hw_reg_read(ah,
00779 AR5K_QUEUE_DCU_SEQNUM(0));
00780 }
00781 }
00782
00783
00784 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
00785
00786 if (ah->ah_version == AR5K_AR5212) {
00787
00788
00789
00790 if (change_channel && ah->ah_rf_banks != NULL)
00791 ath5k_hw_gainf_calibrate(ah);
00792 }
00793 }
00794
00795
00796 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
00797 AR5K_PCICFG_LEDSTATE;
00798 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
00799 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
00800
00801
00802
00803 staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
00804 (AR5K_STA_ID1_DEFAULT_ANTENNA |
00805 AR5K_STA_ID1_DESC_ANTENNA |
00806 AR5K_STA_ID1_RTS_DEF_ANTENNA |
00807 AR5K_STA_ID1_ACKCTS_6MB |
00808 AR5K_STA_ID1_BASE_RATE_11B |
00809 AR5K_STA_ID1_SELFGEN_DEF_ANT);
00810
00811
00812 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, 0);
00813 if (ret)
00814 return ret;
00815
00816
00817 if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
00818 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
00819 else
00820 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
00821 AR5K_PHY(0));
00822
00823
00824 ret = ath5k_hw_write_initvals(ah, mode, change_channel);
00825 if (ret)
00826 return ret;
00827
00828
00829
00830
00831 if (ah->ah_version != AR5K_AR5210) {
00832
00833
00834
00835
00836
00837 ret = ath5k_hw_rfgain_init(ah, freq);
00838 if (ret)
00839 return ret;
00840
00841 mdelay(1);
00842
00843
00844
00845
00846
00847
00848 ath5k_hw_tweak_initval_settings(ah, channel);
00849
00850
00851
00852
00853 ret = ath5k_hw_txpower(ah, channel, ee_mode,
00854 AR5K_TUNE_DEFAULT_TXPOWER);
00855 if (ret)
00856 return ret;
00857
00858
00859 if (ah->ah_version == AR5K_AR5212)
00860 ath5k_hw_write_rate_duration(ah, mode);
00861
00862
00863
00864
00865 ret = ath5k_hw_rfregs_init(ah, channel, mode);
00866 if (ret)
00867 return ret;
00868
00869
00870
00871 if (ah->ah_version == AR5K_AR5212 &&
00872 channel->hw_value & CHANNEL_OFDM) {
00873 ret = ath5k_hw_write_ofdm_timings(ah, channel);
00874 if (ret)
00875 return ret;
00876 }
00877
00878
00879
00880 if (ah->ah_radio == AR5K_RF5111) {
00881 if (mode == AR5K_MODE_11B)
00882 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
00883 AR5K_TXCFG_B_MODE);
00884 else
00885 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
00886 AR5K_TXCFG_B_MODE);
00887 }
00888
00889
00890
00891
00892
00893
00894 if (s_ant != 0) {
00895 if (s_ant == AR5K_ANT_FIXED_A)
00896 ant[0] = ant[1] = AR5K_ANT_FIXED_A;
00897 else
00898 ant[0] = ant[1] = AR5K_ANT_FIXED_B;
00899 } else {
00900 ant[0] = AR5K_ANT_FIXED_A;
00901 ant[1] = AR5K_ANT_FIXED_B;
00902 }
00903
00904
00905 ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode);
00906
00907 } else {
00908
00909
00910
00911
00912
00913
00914 mdelay(1);
00915
00916 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
00917 mdelay(1);
00918 }
00919
00920
00921
00922
00923
00924
00925 if (ah->ah_version != AR5K_AR5210) {
00926
00927 if (change_channel) {
00928 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
00929 for (i = 0; i < 10; i++)
00930 ath5k_hw_reg_write(ah, s_seq[i],
00931 AR5K_QUEUE_DCU_SEQNUM(i));
00932 } else {
00933 ath5k_hw_reg_write(ah, s_seq[0],
00934 AR5K_QUEUE_DCU_SEQNUM(0));
00935 }
00936 }
00937
00938 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
00939 }
00940
00941
00942 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
00943
00944
00945 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
00946 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
00947
00948
00949 ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
00950 AR5K_STA_ID0);
00951 ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
00952 AR5K_STA_ID1);
00953
00954
00955
00956
00957
00958
00959
00960
00961 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
00962
00963
00964 ath5k_hw_set_opmode(ah);
00965
00966
00967
00968 if (ah->ah_version != AR5K_AR5210)
00969 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
00980 AR5K_TUNE_BMISS_THRES <<
00981 AR5K_RSSI_THR_BMISS_S),
00982 AR5K_RSSI_THR);
00983
00984
00985 if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
00986 ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
00987 ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
00988 }
00989
00990
00991 if (ah->ah_version == AR5K_AR5212) {
00992 ath5k_hw_reg_write(ah,
00993 AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
00994 AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
00995 AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
00996 AR5K_QOS_NOACK);
00997 }
00998
00999
01000
01001
01002
01003
01004
01005 ret = ath5k_hw_channel(ah, channel);
01006 if (ret)
01007 return ret;
01008
01009
01010
01011
01012
01013
01014 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
01015
01016
01017
01018
01019
01020
01021
01022 if (ah->ah_version != AR5K_AR5210) {
01023 u32 delay;
01024 delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
01025 AR5K_PHY_RX_DELAY_M;
01026 delay = (channel->hw_value & CHANNEL_CCK) ?
01027 ((delay << 2) / 22) : (delay / 10);
01028
01029 udelay(100 + (2 * delay));
01030 } else {
01031 mdelay(1);
01032 }
01033
01034
01035
01036
01037
01038 phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
01039 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
01040 for (i = 0; i <= 20; i++) {
01041 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
01042 break;
01043 udelay(200);
01044 }
01045 ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
01067 AR5K_PHY_AGCCTL_CAL);
01068
01069
01070
01071 ah->ah_calibration = 0;
01072 if (!(mode == AR5K_MODE_11B)) {
01073 ah->ah_calibration = 1;
01074 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
01075 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
01076 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
01077 AR5K_PHY_IQ_RUN);
01078 }
01079
01080
01081
01082 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
01083 AR5K_PHY_AGCCTL_CAL, 0, 0)) {
01084 DBG("ath5k: gain calibration timeout (%d MHz)\n",
01085 channel->center_freq);
01086 }
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116 ret = ath5k_hw_reset_tx_queue(ah);
01117 if (ret) {
01118 DBG("ath5k: failed to reset TX queue\n");
01119 return ret;
01120 }
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 if (ah->ah_version != AR5K_AR5210) {
01140 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
01141 AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
01142 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
01143 AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
01144 }
01145
01146
01147 if (ah->ah_version != AR5K_AR5210)
01148 ath5k_hw_set_imr(ah, ah->ah_imr);
01149
01150
01151
01152
01153
01154
01155
01156 #if 0
01157 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
01158 ath5k_hw_set_gpio_input(ah, 0);
01159 ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
01160 if (ah->ah_gpio[0] == 0)
01161 ath5k_hw_set_gpio_intr(ah, 0, 1);
01162 else
01163 ath5k_hw_set_gpio_intr(ah, 0, 0);
01164 }
01165 #endif
01166
01167
01168
01169
01170 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
01171 AR5K_BEACON_RESET_TSF);
01172
01173 return 0;
01174 }
01175
01176 #undef _ATH5K_RESET