#include <gpxe/pci.h>#include <unistd.h>#include "ath5k.h"#include "reg.h"#include "base.h"Go to the source code of this file.
Defines | |
| #define | _ATH5K_RESET |
Functions | |
| FILE_LICENCE (MIT) | |
| static int | fls (int x) |
| static int | ath5k_hw_write_ofdm_timings (struct ath5k_hw *ah, struct net80211_channel *channel) |
| ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 | |
| static void | ath5k_hw_write_rate_duration (struct ath5k_hw *ah, unsigned int mode __unused) |
| ath5k_hw_write_rate_duration - fill rate code to duration table | |
| static int | ath5k_hw_nic_reset (struct ath5k_hw *ah, u32 val) |
| int | ath5k_hw_wake (struct ath5k_hw *ah) |
| int | ath5k_hw_nic_wakeup (struct ath5k_hw *ah, int flags, int initial __unused) |
| static int | ath5k_hw_chan_has_spur_noise (struct ath5k_hw *ah, struct net80211_channel *channel) |
| static void | ath5k_hw_tweak_initval_settings (struct ath5k_hw *ah, struct net80211_channel *channel) |
| static void | ath5k_hw_commit_eeprom_settings (struct ath5k_hw *ah, struct net80211_channel *channel, u8 *ant, u8 ee_mode) |
| int | ath5k_hw_reset (struct ath5k_hw *ah, struct net80211_channel *channel, int change_channel) |
Variables | |
| static const unsigned int | control_rates [] |
| #define _ATH5K_RESET |
Definition at line 26 of file ath5k_reset.c.
| FILE_LICENCE | ( | MIT | ) |
| static int fls | ( | int | x | ) | [static] |
Definition at line 40 of file ath5k_reset.c.
References r.
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 }
| static int ath5k_hw_write_ofdm_timings | ( | struct ath5k_hw * | ah, | |
| struct net80211_channel * | channel | |||
| ) | [static] |
ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
: the &struct ath5k_hw : the currently set channel upon reset
Write the delta slope coefficient (used on pilot tracking ?) for OFDM operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
Since delta slope is floating point we split it on its exponent and mantissa and provide these values on hw.
For more infos i think this patent is related http://www.freepatentsonline.com/7184495.html
Definition at line 85 of file ath5k_reset.c.
References ath5k_hw::ah_version, AR5K_AR5212, AR5K_PHY_TIMING_3, AR5K_PHY_TIMING_3_DSC_EXP, AR5K_PHY_TIMING_3_DSC_MAN, AR5K_REG_WRITE_BITS, ath5k_hw_htoclock(), net80211_channel::center_freq, CHANNEL_OFDM, CHANNEL_TURBO, DBG, EFAULT, EINVAL, fls, net80211_channel::hw_value, and u32.
Referenced by ath5k_hw_reset().
00087 { 00088 /* Get exponent and mantissa and set it */ 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 /* Get coefficient 00099 * ALGO: coef = (5 * clock * carrier_freq) / 2) 00100 * we scale coef by shifting clock value by 24 for 00101 * better precision since we use integers */ 00102 /* TODO: Half/quarter rate */ 00103 clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO); 00104 00105 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; 00106 00107 /* Get exponent 00108 * ALGO: coef_exp = 14 - highest set bit position */ 00109 coef_exp = fls(coef_scaled) - 1; 00110 00111 /* Doesn't make sense if it's zero*/ 00112 if (!coef_scaled || !coef_exp) 00113 return -EINVAL; 00114 00115 /* Note: we've shifted coef_scaled by 24 */ 00116 coef_exp = 14 - (coef_exp - 24); 00117 00118 00119 /* Get mantissa (significant digits) 00120 * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */ 00121 coef_man = coef_scaled + 00122 (1 << (24 - coef_exp - 1)); 00123 00124 /* Calculate delta slope coefficient exponent 00125 * and mantissa (remove scaling) and set them on hw */ 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 }
| static void ath5k_hw_write_rate_duration | ( | struct ath5k_hw * | ah, | |
| unsigned int mode | __unused | |||
| ) | [inline, static] |
ath5k_hw_write_rate_duration - fill rate code to duration table
: the &struct ath5k_hw : one of enum ath5k_driver_mode
Write the rate code to duration table upon hw reset. This is a helper for ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on the hardware, based on current mode, for each rate. The rates which are capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have different rate code so we write their value twice (one for long preample and one for short).
Note: Band doesn't matter here, if we set the values for OFDM it works on both a and g modes. So all we have to do is set values for all g rates that include all OFDM and CCK rates. If we operate in turbo or xr/half/ quarter rate mode, we need to use another set of bitrates (that's why we need the mode parameter) but we don't handle these proprietary modes yet.
Definition at line 164 of file ath5k_reset.c.
References ath5k_hw::ah_sc, AR5K_RATE_DUR, AR5K_SET_SHORT_PREAMBLE, ath5k_bitrate_to_hw_rix(), ath5k_hw_reg_write(), ath5k_softc::dev, ath5k_softc::hwinfo, NET80211_BAND_2GHZ, net80211_duration(), net80211_hw_info::nr_rates, net80211_hw_info::rates, u16, and u32.
Referenced by ath5k_hw_reset().
00166 { 00167 struct ath5k_softc *sc = ah->ah_sc; 00168 u16 rate; 00169 int i; 00170 00171 /* Write rate duration table */ 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 /* Set ACK timeout */ 00179 reg = AR5K_RATE_DUR(ath5k_bitrate_to_hw_rix(rate)); 00180 00181 /* An ACK frame consists of 10 bytes. If you add the FCS, 00182 * it's 14 bytes. Note we use the control rate and not the 00183 * actual rate for this rate. See mac80211 tx.c 00184 * ieee80211_duration() for a brief description of 00185 * what rate we should choose to TX ACKs. */ 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 * We're not distinguishing short preamble here, 00195 * This is true, all we'll get is a longer value here 00196 * which is not necessarilly bad. 00197 */ 00198 ath5k_hw_reg_write(ah, tx_time, 00199 reg + (AR5K_SET_SHORT_PREAMBLE << 2)); 00200 } 00201 }
Definition at line 206 of file ath5k_reset.c.
References ath5k_hw::ah_version, AR5K_AR5210, AR5K_CFG, AR5K_INIT_CFG, AR5K_RESET_CTL, AR5K_RESET_CTL_BASEBAND, AR5K_RESET_CTL_DMA, AR5K_RESET_CTL_MAC, AR5K_RESET_CTL_PCU, AR5K_RESET_CTL_PHY, AR5K_RXDP, ath5k_hw_reg_read(), ath5k_hw_reg_write(), U, u32, and udelay().
Referenced by ath5k_hw_nic_wakeup().
00207 { 00208 int ret; 00209 u32 mask = val ? val : ~0U; 00210 00211 /* Read-and-clear RX Descriptor Pointer*/ 00212 ath5k_hw_reg_read(ah, AR5K_RXDP); 00213 00214 /* 00215 * Reset the device and wait until success 00216 */ 00217 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL); 00218 00219 /* Wait at least 128 PCI clocks */ 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 * Reset configuration register (for hw byte-swap). Note that this 00236 * is only set for big endian. We do the necessary magic in 00237 * AR5K_INIT_CFG. 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 }
| int ath5k_hw_wake | ( | struct ath5k_hw * | ah | ) |
Definition at line 248 of file ath5k_reset.c.
References AR5K_PCICFG, AR5K_PCICFG_SPWR_DN, AR5K_SLEEP_CTL, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV, ath5k_hw_reg_read(), ath5k_hw_reg_write(), EIO, u32, and udelay().
Referenced by ath5k_hw_nic_wakeup().
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 /* Preserve sleep duration */ 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 /* Check if the chip did wake up */ 00268 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) & 00269 AR5K_PCICFG_SPWR_DN) == 0) 00270 break; 00271 00272 /* Wait a bit and retry */ 00273 udelay(200); 00274 ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); 00275 } 00276 00277 /* Fail if the chip didn't wake up */ 00278 if (i <= 0) 00279 return -EIO; 00280 00281 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1); 00282 00283 return 0; 00284 }
| int ath5k_hw_nic_wakeup | ( | struct ath5k_hw * | ah, | |
| int | flags, | |||
| int initial | __unused | |||
| ) |
Definition at line 290 of file ath5k_reset.c.
References ath5k_hw::ah_radio, ath5k_hw::ah_sc, ath5k_hw::ah_version, AR5K_AR5210, AR5K_AR5211, AR5K_PHY_MODE, AR5K_PHY_MODE_FREQ_2GHZ, AR5K_PHY_MODE_FREQ_5GHZ, AR5K_PHY_MODE_MOD_CCK, AR5K_PHY_MODE_MOD_DYN, AR5K_PHY_MODE_MOD_OFDM, AR5K_PHY_MODE_RAD_RF5111, AR5K_PHY_MODE_RAD_RF5112, AR5K_PHY_PLL, AR5K_PHY_PLL_40MHZ, AR5K_PHY_PLL_40MHZ_5413, AR5K_PHY_PLL_44MHZ, AR5K_PHY_PLL_RF5111, AR5K_PHY_PLL_RF5112, AR5K_PHY_TURBO, AR5K_PHY_TURBO_MODE, AR5K_PHY_TURBO_SHORT, AR5K_RESET_CTL_BASEBAND, AR5K_RESET_CTL_DMA, AR5K_RESET_CTL_MAC, AR5K_RESET_CTL_PCI, AR5K_RESET_CTL_PCU, AR5K_RESET_CTL_PHY, AR5K_RF5112, AR5K_RF5413, ath5k_hw_nic_reset(), ath5k_hw_reg_read(), ath5k_hw_reg_write(), ath5k_hw_wake(), CHANNEL_2GHZ, CHANNEL_5GHZ, CHANNEL_CCK, CHANNEL_OFDM, CHANNEL_TURBO, DBG, EINVAL, EIO, mdelay(), PCI_CAP_ID_EXP, pci_find_capability(), ath5k_softc::pdev, u32, and udelay().
Referenced by ath5k_hw_attach(), and ath5k_hw_reset().
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 /* Wakeup the device */ 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 * Get channel mode flags 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; /*Zero*/ 00317 clock = AR5K_PHY_PLL_RF5111; /*Zero*/ 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 /* XXX Dynamic OFDM/CCK is not supported by the 00328 * AR5211 so we set MOD_OFDM for plain g (no 00329 * CCK headers) operation. We need to test 00330 * this, 5211 might support ofdm-only g after 00331 * all, there are also initial register values 00332 * in the code for g mode (see initvals.c). */ 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 { /* Reset the device */ 00363 00364 /* ...enable Atheros turbo mode if requested */ 00365 if (flags & CHANNEL_TURBO) 00366 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE, 00367 AR5K_PHY_TURBO); 00368 } 00369 00370 /* reseting PCI on PCI-E cards results card to hang 00371 * and always return 0xffff... so we ingore that flag 00372 * for PCI-E cards */ 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 /* Reset chipset */ 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 /* ...wakeup again!*/ 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 /* ...final warm reset */ 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 /* ...update PLL if needed */ 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 /* ...set the PHY operating mode */ 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 }
| static int ath5k_hw_chan_has_spur_noise | ( | struct ath5k_hw * | ah, | |
| struct net80211_channel * | channel | |||
| ) | [static] |
Definition at line 422 of file ath5k_reset.c.
References ath5k_hw::ah_mac_version, ath5k_hw::ah_radio, AR5K_RF5112, AR5K_RF5413, AR5K_SREV_AR2417, net80211_channel::center_freq, and u8.
Referenced by ath5k_hw_commit_eeprom_settings().
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 }
| static void ath5k_hw_tweak_initval_settings | ( | struct ath5k_hw * | ah, | |
| struct net80211_channel * | channel | |||
| ) | [static] |
Definition at line 443 of file ath5k_reset.c.
References ath5k_hw::ah_mac_srev, ath5k_hw::ah_mac_version, ath5k_hw::ah_phy_revision, ath5k_hw::ah_radio, ath5k_hw::ah_radio_5ghz_revision, ath5k_hw::ah_version, AR5K_AR5212, AR5K_DIAG_SW_5211, AR5K_DIAG_SW_ECO_ENABLE, AR5K_PHY_ADC_CTL, AR5K_PHY_ADC_CTL_INBUFGAIN_OFF, AR5K_PHY_ADC_CTL_INBUFGAIN_ON, AR5K_PHY_ADC_CTL_PWD_ADC_OFF, AR5K_PHY_ADC_CTL_PWD_DAC_OFF, AR5K_PHY_BLUETOOTH, AR5K_PHY_CCKTXCTL, AR5K_PHY_CCKTXCTL_WORLD, AR5K_PHY_DAG_CCK_CTL, AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR, AR5K_PHY_DAG_CCK_CTL_RSSI_THR, AR5K_PHY_FAST_ADC, AR5K_PHY_FRAME_CTL, AR5K_PHY_SCAL, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL_32MHZ_2417, AR5K_PHY_SCAL_32MHZ_HB63, AR5K_QCUDCU_CLKGT, AR5K_REG_DISABLE_BITS, AR5K_REG_ENABLE_BITS, AR5K_REG_SM, AR5K_REG_WRITE_BITS, AR5K_RF5112, AR5K_RF5413, AR5K_SEQ_MASK, AR5K_SREV_AR2417, AR5K_SREV_AR5211, AR5K_SREV_PHY_5212A, AR5K_SREV_PHY_5212B, AR5K_SREV_RAD_5112A, AR5K_TXCFG, AR5K_TXCFG_DCU_DBL_BUF_DIS, AR5K_USEC_1, AR5K_USEC_32, AR5K_USEC_5211, AR5K_USEC_RX_LATENCY_5210, AR5K_USEC_TX_LATENCY_5211, ath5k_eeprom_is_hb63(), ath5k_hw_reg_read(), ath5k_hw_reg_write(), net80211_channel::center_freq, CHANNEL_5GHZ, net80211_channel::hw_value, and u32.
Referenced by ath5k_hw_reset().
00445 { 00446 if (ah->ah_version == AR5K_AR5212 && 00447 ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { 00448 00449 /* Setup ADC control */ 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 /* Disable barker RSSI threshold */ 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 /* Set the mute mask */ 00469 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK); 00470 } 00471 00472 /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */ 00473 if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B) 00474 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH); 00475 00476 /* Enable DCU double buffering */ 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 /* Set DAC/ADC delays */ 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 /* Set fast ADC */ 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 /* Only update if needed */ 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 /* Fix for first revision of the RF5112 RF chipset */ 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 /* 5311 has different tx/rx latency masks 00525 * from 5211, since we deal 5311 the same 00526 * as 5211 when setting initvals, shift 00527 * values here to their proper locations */ 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 /* Clear QCU/DCU clock gating register */ 00536 ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT); 00537 /* Set DAC/ADC delays */ 00538 ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL); 00539 /* Enable PCU FIFO corruption ECO */ 00540 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, 00541 AR5K_DIAG_SW_ECO_ENABLE); 00542 } 00543 }
| static void ath5k_hw_commit_eeprom_settings | ( | struct ath5k_hw * | ah, | |
| struct net80211_channel * | channel, | |||
| u8 * | ant, | |||
| u8 | ee_mode | |||
| ) | [static] |
Definition at line 545 of file ath5k_reset.c.
References ath5k_hw::ah_antenna, ath5k_hw::ah_capabilities, ath5k_hw::ah_phy_revision, ath5k_hw::ah_txpower, AR5K_EEPROM_VERSION_4_1, AR5K_EEPROM_VERSION_5_0, AR5K_EEPROM_VERSION_5_1, AR5K_INIT_CYCRSSI_THR1, AR5K_PHY_ANT_CTL, AR5K_PHY_ANT_CTL_SWTABLE_IDLE, AR5K_PHY_ANT_CTL_TXRX_EN, AR5K_PHY_ANT_SWITCH_TABLE_0, AR5K_PHY_ANT_SWITCH_TABLE_1, AR5K_PHY_DESIRED_SIZE, AR5K_PHY_DESIRED_SIZE_ADC, AR5K_PHY_DESIRED_SIZE_PGA, AR5K_PHY_GAIN, AR5K_PHY_GAIN_2GHZ, AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, AR5K_PHY_GAIN_TXRX_ATTEN, AR5K_PHY_HEAVY_CLIP_ENABLE, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE, AR5K_PHY_IQ_CORR_Q_I_COFF_S, AR5K_PHY_NF, AR5K_PHY_NF_SVAL, AR5K_PHY_NF_THRESH62, AR5K_PHY_NFTHRES, AR5K_PHY_OFDM_SELFCORR, AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, AR5K_PHY_RF_CTL3, AR5K_PHY_RF_CTL3_TXE2XLNA_ON, AR5K_PHY_RF_CTL4, AR5K_PHY_SETTLING, AR5K_PHY_SETTLING_SWITCH, AR5K_PHY_TX_PWR_ADJ, AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA, AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX, AR5K_REG_ENABLE_BITS, AR5K_REG_SM, AR5K_REG_WRITE_BITS, AR5K_SREV_PHY_5212A, ath5k_hw_chan_has_spur_noise(), ath5k_hw_reg_write(), ath5k_capabilities::cap_eeprom, net80211_channel::center_freq, CHANNEL_G, CHANNEL_TURBO, ath5k_eeprom_info::ee_adc_desired_size, ath5k_eeprom_info::ee_adc_desired_size_turbo, ath5k_eeprom_info::ee_atn_tx_rx, ath5k_eeprom_info::ee_atn_tx_rx_turbo, ath5k_eeprom_info::ee_cck_ofdm_gain_delta, ath5k_eeprom_info::ee_cck_ofdm_power_delta, ath5k_eeprom_info::ee_false_detect, ath5k_eeprom_info::ee_i_cal, ath5k_eeprom_info::ee_margin_tx_rx, ath5k_eeprom_info::ee_margin_tx_rx_turbo, ath5k_eeprom_info::ee_noise_floor_thr, ath5k_eeprom_info::ee_pga_desired_size, ath5k_eeprom_info::ee_pga_desired_size_turbo, ath5k_eeprom_info::ee_q_cal, ath5k_eeprom_info::ee_scaled_cck_delta, ath5k_eeprom_info::ee_switch_settling, ath5k_eeprom_info::ee_switch_settling_turbo, ath5k_eeprom_info::ee_thr_62, ath5k_eeprom_info::ee_tx_end2xlna_enable, ath5k_eeprom_info::ee_tx_end2xpa_disable, ath5k_eeprom_info::ee_tx_frm2xpa_enable, net80211_channel::hw_value, ath5k_hw::txp_cck_ofdm_gainf_delta, and ath5k_hw::txp_cck_ofdm_pwr_delta.
Referenced by ath5k_hw_reset().
00547 { 00548 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 00549 s16 cck_ofdm_pwr_delta; 00550 00551 /* Adjust power delta for channel 14 */ 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 /* Set CCK to OFDM power delta on tx power 00561 * adjustment register */ 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 /* For older revs we scale power on sw during tx power 00574 * setup */ 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 /* Set antenna idle switch table */ 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 /* Set antenna switch table */ 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 /* Noise floor threshold */ 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 /* Switch settling time (Turbo) */ 00600 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, 00601 AR5K_PHY_SETTLING_SWITCH, 00602 ee->ee_switch_settling_turbo[ee_mode]); 00603 00604 /* Tx/Rx attenuation (Turbo) */ 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 /* ADC/PGA desired size (Turbo) */ 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 /* Tx/Rx margin (Turbo) */ 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 /* Switch settling time */ 00625 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, 00626 AR5K_PHY_SETTLING_SWITCH, 00627 ee->ee_switch_settling[ee_mode]); 00628 00629 /* Tx/Rx attenuation */ 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 /* ADC/PGA desired size */ 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 /* Tx/Rx margin */ 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 /* XPA delays */ 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 /* XLNA delay */ 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 /* Thresh64 (ANI) */ 00663 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF, 00664 AR5K_PHY_NF_THRESH62, 00665 ee->ee_thr_62[ee_mode]); 00666 00667 00668 /* False detect backoff for channels 00669 * that have spur noise. Write the new 00670 * cyclic power RSSI threshold. */ 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 /* I/Q correction 00682 * TODO: Per channel i/q infos ? */ 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 /* Heavy clipping -disable for now */ 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 }
| int ath5k_hw_reset | ( | struct ath5k_hw * | ah, | |
| struct net80211_channel * | channel, | |||
| int | change_channel | |||
| ) |
Definition at line 698 of file ath5k_reset.c.
References ath5k_hw::ah_bssid, ath5k_hw::ah_calibration, ath5k_hw::ah_capabilities, ath5k_hw::ah_gpio, ath5k_hw::ah_imr, ath5k_hw::ah_mac_srev, ath5k_hw::ah_radio, ath5k_hw::ah_rf_banks, ath5k_hw::ah_sta_id, ath5k_hw::ah_version, AR5K_ANT_FIXED_A, AR5K_ANT_FIXED_B, AR5K_AR5210, AR5K_AR5211, AR5K_AR5212, AR5K_BEACON, AR5K_BEACON_ENABLE, AR5K_BEACON_RESET_TSF, AR5K_DEFAULT_ANTENNA, AR5K_DMASIZE_128B, AR5K_EEPROM_HDR_RFKILL, AR5K_EEPROM_MODE_11A, AR5K_EEPROM_MODE_11B, AR5K_EEPROM_MODE_11G, AR5K_GPIOCR, AR5K_GPIODO, AR5K_HIGH_ID, AR5K_INI_RFGAIN_2GHZ, AR5K_INI_RFGAIN_5GHZ, AR5K_LOW_ID, AR5K_MIC_QOS_CTL, AR5K_MIC_QOS_SEL, AR5K_MODE_11A, AR5K_MODE_11A_TURBO, AR5K_MODE_11B, AR5K_MODE_11G, AR5K_MODE_11G_TURBO, AR5K_MODE_XR, AR5K_PCICFG, AR5K_PCICFG_LEDSTATE, AR5K_PHY, AR5K_PHY_ACT, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ADC_TEST, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL, AR5K_PHY_IQ, AR5K_PHY_IQ_CAL_NUM_LOG_MAX, AR5K_PHY_IQ_RUN, AR5K_PHY_RX_DELAY, AR5K_PHY_RX_DELAY_M, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY_TST1, AR5K_PHY_TST1_TXHOLD, AR5K_PISR, AR5K_QOS_NOACK, AR5K_QOS_NOACK_2BIT_VALUES, AR5K_QOS_NOACK_BIT_OFFSET, AR5K_QOS_NOACK_BYTE_OFFSET, AR5K_QUEUE_DCU_SEQNUM, AR5K_REG_DISABLE_BITS, AR5K_REG_ENABLE_BITS, AR5K_REG_SM, AR5K_REG_WRITE_BITS, AR5K_RF5111, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS_S, AR5K_RXCFG, AR5K_RXCFG_SDMAMW, AR5K_SREV_AR2413, AR5K_SREV_AR5211, AR5K_STA_ID0, AR5K_STA_ID1, AR5K_STA_ID1_ACKCTS_6MB, AR5K_STA_ID1_BASE_RATE_11B, AR5K_STA_ID1_DEFAULT_ANTENNA, AR5K_STA_ID1_DESC_ANTENNA, AR5K_STA_ID1_RTS_DEF_ANTENNA, AR5K_STA_ID1_SELFGEN_DEF_ANT, AR5K_TUNE_BMISS_THRES, AR5K_TUNE_DEFAULT_TXPOWER, AR5K_TUNE_RSSI_THRES, AR5K_TXCFG, AR5K_TXCFG_B_MODE, AR5K_TXCFG_SDMAMR, ath5k_hw_channel(), ath5k_hw_commit_eeprom_settings(), ath5k_hw_gainf_calibrate(), ath5k_hw_get_gpio(), ath5k_hw_nic_wakeup(), ath5k_hw_noise_floor_calibration(), ath5k_hw_reg_read(), ath5k_hw_reg_write(), ath5k_hw_reset_tx_queue(), ath5k_hw_rfgain_init(), ath5k_hw_rfregs_init(), ath5k_hw_set_associd(), ath5k_hw_set_gpio_input(), ath5k_hw_set_gpio_intr(), ath5k_hw_set_imr(), ath5k_hw_set_opmode(), ath5k_hw_tweak_initval_settings(), ath5k_hw_txpower(), ath5k_hw_write_initvals(), ath5k_hw_write_ofdm_timings(), ath5k_hw_write_rate_duration(), ath5k_capabilities::cap_eeprom, net80211_channel::center_freq, CHANNEL_A, CHANNEL_B, CHANNEL_CCK, CHANNEL_G, CHANNEL_MODES, CHANNEL_OFDM, CHANNEL_T, CHANNEL_TG, CHANNEL_XR, DBG, delay, ath5k_eeprom_info::ee_header, EINVAL, net80211_channel::hw_value, mdelay(), NULL, u32, u8, and udelay().
Referenced by ath5k_reset().
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 * Save some registers before a reset 00716 */ 00717 /*DCU/Antenna selection not available on 5210*/ 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 * Save frame sequence count 00768 * For revs. after Oahu, only save 00769 * seq num for DCU 0 (Global seq num) 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 /* Save default antenna */ 00784 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); 00785 00786 if (ah->ah_version == AR5K_AR5212) { 00787 /* Since we are going to write rf buffer 00788 * check if we have any pending gain_F 00789 * optimization settings */ 00790 if (change_channel && ah->ah_rf_banks != NULL) 00791 ath5k_hw_gainf_calibrate(ah); 00792 } 00793 } 00794 00795 /*GPIOs*/ 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 /* AR5K_STA_ID1 flags, only preserve antenna 00802 * settings and ack/cts rate mode */ 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 /* Wakeup the device */ 00812 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, 0); 00813 if (ret) 00814 return ret; 00815 00816 /* PHY access enable */ 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 /* Write initial settings */ 00824 ret = ath5k_hw_write_initvals(ah, mode, change_channel); 00825 if (ret) 00826 return ret; 00827 00828 /* 00829 * 5211/5212 Specific 00830 */ 00831 if (ah->ah_version != AR5K_AR5210) { 00832 00833 /* 00834 * Write initial RF gain settings 00835 * This should work for both 5111/5112 00836 */ 00837 ret = ath5k_hw_rfgain_init(ah, freq); 00838 if (ret) 00839 return ret; 00840 00841 mdelay(1); 00842 00843 /* 00844 * Tweak initval settings for revised 00845 * chipsets and add some more config 00846 * bits 00847 */ 00848 ath5k_hw_tweak_initval_settings(ah, channel); 00849 00850 /* 00851 * Set TX power (FIXME) 00852 */ 00853 ret = ath5k_hw_txpower(ah, channel, ee_mode, 00854 AR5K_TUNE_DEFAULT_TXPOWER); 00855 if (ret) 00856 return ret; 00857 00858 /* Write rate duration table only on AR5212 */ 00859 if (ah->ah_version == AR5K_AR5212) 00860 ath5k_hw_write_rate_duration(ah, mode); 00861 00862 /* 00863 * Write RF buffer 00864 */ 00865 ret = ath5k_hw_rfregs_init(ah, channel, mode); 00866 if (ret) 00867 return ret; 00868 00869 00870 /* Write OFDM timings on 5212*/ 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 /*Enable/disable 802.11b mode on 5111 00879 (enable 2111 frequency converter + CCK)*/ 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 * In case a fixed antenna was set as default 00891 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE 00892 * registers. 00893 */ 00894 if (s_ant != 0) { 00895 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */ 00896 ant[0] = ant[1] = AR5K_ANT_FIXED_A; 00897 else /* 2 - Aux */ 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 /* Commit values from EEPROM */ 00905 ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode); 00906 00907 } else { 00908 /* 00909 * For 5210 we do all initialization using 00910 * initvals, so we don't have to modify 00911 * any settings (5210 also only supports 00912 * a/aturbo modes) 00913 */ 00914 mdelay(1); 00915 /* Disable phy and wait */ 00916 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); 00917 mdelay(1); 00918 } 00919 00920 /* 00921 * Restore saved values 00922 */ 00923 00924 /*DCU/Antenna selection not available on 5210*/ 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 /* Ledstate */ 00942 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]); 00943 00944 /* Gpio settings */ 00945 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); 00946 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); 00947 00948 /* Restore sta_id flags and preserve our mac address*/ 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 * Configure PCU 00957 */ 00958 00959 /* Restore bssid and bssid mask */ 00960 /* XXX: add ah->aid once mac80211 gives this to us */ 00961 ath5k_hw_set_associd(ah, ah->ah_bssid, 0); 00962 00963 /* Set PCU config */ 00964 ath5k_hw_set_opmode(ah); 00965 00966 /* Clear any pending interrupts 00967 * PISR/SISR Not available on 5210 */ 00968 if (ah->ah_version != AR5K_AR5210) 00969 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); 00970 00971 /* Set RSSI/BRSSI thresholds 00972 * 00973 * Note: If we decide to set this value 00974 * dynamicaly, have in mind that when AR5K_RSSI_THR 00975 * register is read it might return 0x40 if we haven't 00976 * wrote anything to it plus BMISS RSSI threshold is zeroed. 00977 * So doing a save/restore procedure here isn't the right 00978 * choice. Instead store it on ath5k_hw */ 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 /* MIC QoS support */ 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 /* QoS NOACK Policy */ 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 * Configure PHY 01002 */ 01003 01004 /* Set channel on PHY */ 01005 ret = ath5k_hw_channel(ah, channel); 01006 if (ret) 01007 return ret; 01008 01009 /* 01010 * Enable the PHY and wait until completion 01011 * This includes BaseBand and Synthesizer 01012 * activation. 01013 */ 01014 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); 01015 01016 /* 01017 * On 5211+ read activation -> rx delay 01018 * and use it. 01019 * 01020 * TODO: Half/quarter rate support 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 * Perform ADC test to see if baseband is ready 01036 * Set tx hold and check adc test register 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 * Start automatic gain control calibration 01049 * 01050 * During AGC calibration RX path is re-routed to 01051 * a power detector so we don't receive anything. 01052 * 01053 * This method is used to calibrate some static offsets 01054 * used together with on-the fly I/Q calibration (the 01055 * one performed via ath5k_hw_phy_calibrate), that doesn't 01056 * interrupt rx path. 01057 * 01058 * While rx path is re-routed to the power detector we also 01059 * start a noise floor calibration, to measure the 01060 * card's noise floor (the noise we measure when we are not 01061 * transmiting or receiving anything). 01062 * 01063 * If we are in a noisy environment AGC calibration may time 01064 * out and/or noise floor calibration might timeout. 01065 */ 01066 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, 01067 AR5K_PHY_AGCCTL_CAL); 01068 01069 /* At the same time start I/Q calibration for QAM constellation 01070 * -no need for CCK- */ 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 /* Wait for gain calibration to finish (we check for I/Q calibration 01081 * during ath5k_phy_calibrate) */ 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 * If we run NF calibration before AGC, it always times out. 01090 * Binary HAL starts NF and AGC calibration at the same time 01091 * and only waits for AGC to finish. Also if AGC or NF cal. 01092 * times out, reset doesn't fail on binary HAL. I believe 01093 * that's wrong because since rx path is routed to a detector, 01094 * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211 01095 * enables noise floor calibration after offset calibration and if noise 01096 * floor calibration fails, reset fails. I believe that's 01097 * a better approach, we just need to find a polling interval 01098 * that suits best, even if reset continues we need to make 01099 * sure that rx path is ready. 01100 */ 01101 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 01102 01103 01104 /* 01105 * Configure QCUs/DCUs 01106 */ 01107 01108 /* TODO: HW Compression support for data queues */ 01109 /* TODO: Burst prefetch for data queues */ 01110 01111 /* 01112 * Reset queues and start beacon timers at the end of the reset routine 01113 * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping 01114 * Note: If we want we can assign multiple qcus on one dcu. 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 * Configure DMA/Interrupts 01124 */ 01125 01126 /* 01127 * Set Rx/Tx DMA Configuration 01128 * 01129 * Set standard DMA size (128). Note that 01130 * a DMA size of 512 causes rx overruns and tx errors 01131 * on pci-e cards (tested on 5424 but since rx overruns 01132 * also occur on 5416/5418 with madwifi we set 128 01133 * for all PCI-E cards to be safe). 01134 * 01135 * XXX: need to check 5210 for this 01136 * TODO: Check out tx triger level, it's always 64 on dumps but I 01137 * guess we can tweak it and see how it goes ;-) 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 /* Pre-enable interrupts on 5211/5212*/ 01147 if (ah->ah_version != AR5K_AR5210) 01148 ath5k_hw_set_imr(ah, ah->ah_imr); 01149 01150 /* 01151 * Setup RFKill interrupt if rfkill flag is set on eeprom. 01152 * TODO: Use gpio pin and polarity infos from eeprom 01153 * TODO: Handle this in ath5k_intr because it'll result 01154 * a nasty interrupt storm. 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 * Disable beacons and reset the register 01169 */ 01170 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | 01171 AR5K_BEACON_RESET_TSF); 01172 01173 return 0; 01174 }
const unsigned int control_rates[] [static] |
1.5.7.1