ath5k_reset.c File Reference

#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 Documentation

#define _ATH5K_RESET

Definition at line 26 of file ath5k_reset.c.


Function Documentation

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 }

static int ath5k_hw_nic_reset ( struct ath5k_hw ah,
u32  val 
) [static]

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 }


Variable Documentation

const unsigned int control_rates[] [static]

Initial value:

        { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }

Definition at line 142 of file ath5k_reset.c.


Generated on Tue Apr 6 20:01:20 2010 for gPXE by  doxygen 1.5.7.1