commit a1091593168be19a255d879254ab39314c848d84 Author: Jiri Slaby Date: Sun Jul 15 17:29:59 2007 +0200 calibration diff --git a/ath.c b/ath.c index 871a58d..e6c38a8 100644 --- a/ath.c +++ b/ath.c @@ -51,10 +51,13 @@ enum { ATH_DEBUG_MODE = 0x00000040, /* mode init/setup */ ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */ ATH_DEBUG_INTR = 0x00001000, /* ISR */ + ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */ ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */ ATH_DEBUG_ANY = 0xffffffff }; +static int ath_calinterval = ATH_SHORT_CALIB; + static int countrycode = CTRY_DEFAULT; static int outdoor = true; static int xchanmode = true; @@ -566,6 +569,9 @@ static int ath_init(struct ath_softc *sc) ath5k_hw_set_intr(sc->ah, sc->imask); + mod_timer(&sc->calib_tim, jiffies + + msecs_to_jiffies(ath_calinterval * 1000)); + ret = 0; done: mutex_unlock(&sc->lock); @@ -752,6 +758,9 @@ static int ath_stop_hw(struct ath_softc *sc) } } mutex_unlock(&sc->lock); + + del_timer_sync(&sc->calib_tim); + return ret; } @@ -1138,6 +1147,39 @@ static struct ieee80211_ops ath_hw_ops = { .beacon_update = NULL, }; +/* + * Periodically recalibrate the PHY to account + * for temperature/environment changes. + */ +static void ath_calibrate(unsigned long data) +{ + struct ath_softc *sc = (void *)data; + struct ath_hw *ah = sc->ah; + + sc->stats.ast_per_cal++; + + DPRINTF(sc, ATH_DEBUG_CALIBRATE, "ath: channel %u/%x\n", + sc->curchan->chan, sc->curchan->val); + + if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) { + /* + * Rfgain is out of bounds, reset the chip + * to load new gain values. + */ + sc->stats.ast_per_rfgain++; + DPRINTF(sc, ATH_DEBUG_RESET, "calibration, resetting\n"); + ath_reset(sc->hw); + } + if (ath5k_hw_phy_calibrate(ah, sc->curchan)) { + DPRINTF(sc, ATH_DEBUG_ANY, "ath: calibration of channel %u " + "failed\n", sc->curchan->chan); + sc->stats.ast_per_calfail++; + } + + mod_timer(&sc->calib_tim, jiffies + + msecs_to_jiffies(ath_calinterval * 1000)); +} + static irqreturn_t ath_intr(int irq, void *dev_id) { struct ath_softc *sc = dev_id; @@ -1670,8 +1712,8 @@ static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) tasklet_init(&sc->rxtq, ath_tasklet_rx, (unsigned long)sc); tasklet_init(&sc->txtq, ath_tasklet_tx, (unsigned long)sc); + setup_timer(&sc->calib_tim, ath_calibrate, (unsigned long)sc); #ifdef BLE - setup_timer(&sc->cal_ch, ath_calibrate, (unsigned long)hw); setup_timer(&sc->sc_ledtimer, ath_led_off, (unsigned long)sc); sc->blinking = 0; @@ -1983,6 +2025,8 @@ enum { DEV_ATH = 9, /* XXX known by hal */ }; +static int mincalibrate = 1; +static int maxint = 0x7ffffff / 1000; #define CTL_AUTO -2 /* cannot be CTL_ANY or CTL_NONE */ static ctl_table ath_static_sysctls[] = { @@ -2016,6 +2060,15 @@ static ctl_table ath_static_sysctls[] = { .maxlen = sizeof(xchanmode), .proc_handler = proc_dointvec }, + { .ctl_name = CTL_AUTO, + .procname = "calibrate", + .mode = 0644, + .data = &ath_calinterval, + .maxlen = sizeof(ath_calinterval), + .extra1 = &mincalibrate, + .extra2 = &maxint, + .proc_handler = proc_dointvec_minmax + }, { 0 } }; static ctl_table ath_ath_table[] = { diff --git a/ath.h b/ath.h index a085294..25393f7 100644 --- a/ath.h +++ b/ath.h @@ -52,6 +52,9 @@ #define ATH_TIMEOUT 1000 +#define ATH_LONG_CALIB 30 /* seconds */ +#define ATH_SHORT_CALIB 1 + /* * Maximum acceptable MTU * MAXFRAMEBODY - WEP - QOS - RSN/WPA: @@ -243,12 +246,11 @@ struct ath_softc { COMMIT /* beacon sent, commit change */ } sc_updateslot; /* slot time update fsm */ - struct timer_list sc_cal_ch; /* calibration timer */ - struct timer_list sc_scan_ch; /* AP scan timer */ struct iw_statistics sc_iwstats; /* wireless statistics block */ struct ctl_table_header *sc_sysctl_header; struct ctl_table *sc_sysctls; #endif + struct timer_list calib_tim; /* calibration timer */ }; void ath_sysctl_register(void); diff --git a/ath/if_ath.c b/ath/if_ath.c index 794df8a..264724f 100644 --- a/ath/if_ath.c +++ b/ath/if_ath.c @@ -3340,64 +3340,8 @@ ath_tx_tasklet(unsigned long data) netif_wake_queue(&sc->sc_rawdev); } - -static void -ath_tx_timeout(struct net_device *dev) -{ - struct ath_softc *sc = dev->priv; - sc->sc_stats.ast_watchdog++; - ath_init(dev); -} - -#endif -#ifdef BLE #endif -static void -ath_next_scan(unsigned long arg) -{ -#ifdef BLE - struct net_device *dev = (struct net_device *) arg; - struct ath_softc *sc = dev->priv; - - if (ic->ic_state == IEEE80211_S_SCAN) - ieee80211_next_scan(ic); -#endif -} -/* - * Periodically recalibrate the PHY to account - * for temperature/environment changes. - */ -static void -ath_calibrate(unsigned long arg) -{ - struct ieee80211_hw *hw = (void *)arg; - struct ath_softc *sc = hw->priv; - struct ath_hal *ah = sc->sc_ah; - - sc->sc_stats.ast_per_cal++; - - DPRINTF(sc, ATH_DEBUG_CALIBRATE, "%s: channel %u/%x\n", - __func__, sc->sc_curchan.freq, sc->sc_curchan.channel_flags); - - if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) { - /* - * Rfgain is out of bounds, reset the chip - * to load new gain values. - */ - sc->sc_stats.ast_per_rfgain++; - DPRINTF(sc, ATH_DEBUG_RESET, "calibration, resetting\n"); - ath_reset(hw); - } - if (!ath5k_hw_phy_calibrate(ah, &sc->sc_curchan)) { - DPRINTF(sc, ATH_DEBUG_ANY, - "%s: calibration of channel %u failed\n", - __func__, sc->sc_curchan.freq); - sc->sc_stats.ast_per_calfail++; - } - sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ); - add_timer(&sc->sc_cal_ch); -} #ifdef BLE static int ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) @@ -4434,7 +4378,6 @@ ath_sysctl_halparam(ctl_table *ctl, int write, struct file *filp, static int mindwelltime = 100; /* 100ms */ static int mincalibrate = 1; /* once a second */ -static int maxint = 0x7fffffff; /* 32-bit big */ #define CTL_AUTO -2 /* cannot be CTL_ANY or CTL_NONE */ diff --git a/ath5k.h b/ath5k.h index 012bb46..77e21dd 100644 --- a/ath5k.h +++ b/ath5k.h @@ -968,9 +968,6 @@ struct ath_hw { /* * Prototypes */ -typedef bool (ath5k_rfgain_t)(struct ath_hw *, struct ieee80211_channel *, - unsigned int); - /* General Functions */ u16 ath_hal_computetxtime(struct ath_hw *hal, const struct ath5k_rate_table *rates, u32 frame_length, u16 rate_index, bool short_preamble); /* Attach/Detach Functions */ @@ -1063,15 +1060,7 @@ bool ath5k_check_channel(struct ath_hw *hal, u16 freq, unsigned int flags); bool ath_hal_init_channels(struct ath_hw *hal, struct ieee80211_channel *channels, unsigned int max_channels, u_int *channels_size, enum ieee80211_countrycode country, u16 mode, bool outdoor, bool extended); u16 ath5k_get_regdomain(struct ath_hw *hal); /* PHY/RF access functions */ -bool ath5k_hw_channel(struct ath_hw *hal, struct ieee80211_channel *channel); -u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel); -bool ath5k_hw_rf5110_channel(struct ath_hw *hal, struct ieee80211_channel *channel); -bool ath5k_hw_rf5111_chan2athchan(unsigned int ieee, struct ath5k_athchan_2ghz *athchan); -bool ath5k_hw_rf5111_channel(struct ath_hw *hal, struct ieee80211_channel *channel); -bool ath5k_hw_rf5112_channel(struct ath_hw *hal, struct ieee80211_channel *channel); -bool ath5k_hw_phy_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel); -bool ath5k_hw_rf5110_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel); -bool ath5k_hw_rf511x_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel); +int ath5k_hw_phy_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel); bool ath5k_hw_phy_disable(struct ath_hw *hal); void ath5k_hw_set_def_antenna(struct ath_hw *hal, unsigned int ant); unsigned int ath5k_hw_get_def_antenna(struct ath_hw *hal); @@ -1079,10 +1068,6 @@ unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits, u32 firs u32 ath5k_hw_rfregs_gainf_corr(struct ath_hw *hal); bool ath5k_hw_rfregs_gain_readback(struct ath_hw *hal); s32 ath5k_hw_rfregs_gain_adjust(struct ath_hw *hal); -bool ath5k_hw_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, unsigned int mode); -bool ath5k_hw_rf5111_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, unsigned int mode); -bool ath5k_hw_rf5112_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, unsigned int mode); -void ath5k_hw_ar5211_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, unsigned int freq, unsigned int ee_mode); bool ath5k_hw_rfgain(struct ath_hw *hal, unsigned int phy, u_int freq); enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath_hw *hal); /* Misc functions */ diff --git a/ath5k_hw.c b/ath5k_hw.c index 2b8cce7..121d464 100644 --- a/ath5k_hw.c +++ b/ath5k_hw.c @@ -66,6 +66,16 @@ static int ath5k_hw_get_capabilities(struct ath_hw *); static int ath5k_eeprom_init(struct ath_hw *); static int ath5k_eeprom_read_mac(struct ath_hw *, u8 *); +static int ath5k_hw_channel(struct ath_hw *, struct ieee80211_channel *); +static int ath5k_hw_rfregs(struct ath_hw *, struct ieee80211_channel *, + unsigned int); +static int ath5k_hw_rf5111_rfregs(struct ath_hw *, struct ieee80211_channel *, + unsigned int); +static int ath5k_hw_rf5112_rfregs(struct ath_hw *, struct ieee80211_channel *, + unsigned int); +static void ath5k_hw_ar5211_rfregs(struct ath_hw *, struct ieee80211_channel *, + unsigned int, unsigned int); + /* * Initial register dumps */ @@ -983,9 +993,9 @@ int ath5k_hw_reset(struct ath_hw *hal, enum ieee80211_if_types op_mode, * Write RF registers * TODO:Does this work on 5211 (5111) ? */ - if (ath5k_hw_rfregs(hal, channel, mode) == false) { - return -EINPROGRESS; - } + ret = ath5k_hw_rfregs(hal, channel, mode); + if (ret) + return ret; /* * Configure additional registers @@ -1137,8 +1147,9 @@ int ath5k_hw_reset(struct ath_hw *hal, enum ieee80211_if_types op_mode, /* * Set channel and calibrate the PHY */ - if (ath5k_hw_channel(hal, channel) == false) - return -EIO; + ret = ath5k_hw_channel(hal, channel); + if (ret) + return ret; /* * Enable the PHY and wait until completion @@ -4522,51 +4533,9 @@ ath5k_get_regdomain(struct ath_hw *hal) \*************************/ /* - * Set a channel on the radio chip - */ -bool -ath5k_hw_channel(struct ath_hw *hal, struct ieee80211_channel *channel) -{ - bool ret; - - /* - * Check bounds supported by the PHY - * (don't care about regulation restrictions at this point) - */ - if ((channel->freq < hal->ah_capabilities.cap_range.range_2ghz_min || - channel->freq > hal->ah_capabilities.cap_range.range_2ghz_max) && - (channel->freq < hal->ah_capabilities.cap_range.range_5ghz_min || - channel->freq > hal->ah_capabilities.cap_range.range_5ghz_max)) { - AR5K_PRINTF("channel out of supported range (%u MHz)\n", - channel->freq); - return false; - } - - /* - * Set the channel and wait - */ - if (hal->ah_radio == AR5K_RF5110) - ret = ath5k_hw_rf5110_channel(hal, channel); - else if (hal->ah_radio == AR5K_RF5111) - ret = ath5k_hw_rf5111_channel(hal, channel); - else - ret = ath5k_hw_rf5112_channel(hal, channel); - - if (ret == false) - return ret; - - hal->ah_current_channel.freq = channel->freq; - hal->ah_current_channel.val = channel->val; - hal->ah_turbo = channel->val == CHANNEL_T ? true : false; - - return true; -} - -/* * Convertion needed for RF5110 */ -u32 -ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) +static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) { u32 athchan; @@ -4577,8 +4546,7 @@ ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) * different RF/PHY part. */ athchan = (ath5k_hw_bitswap((ath_hal_mhz2ieee(channel->freq, - channel->val) - 24) / 2, 5) << 1) | - (1 << 6) | 0x1; + channel->val) - 24) / 2, 5) << 1) | (1 << 6) | 0x1; return athchan; } @@ -4586,8 +4554,7 @@ ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) /* * Set channel on RF5110 */ -bool -ath5k_hw_rf5110_channel(struct ath_hw *hal, struct ieee80211_channel *channel) +static int ath5k_hw_rf5110_channel(struct ath_hw *hal, struct ieee80211_channel *channel) { u32 data; @@ -4599,14 +4566,14 @@ ath5k_hw_rf5110_channel(struct ath_hw *hal, struct ieee80211_channel *channel) ath5k_hw_reg_write(hal, 0, AR5K_RF_BUFFER_CONTROL_0); mdelay(1); - return true; + return 0; } /* * Convertion needed for 5111 */ -bool -ath5k_hw_rf5111_chan2athchan(unsigned int ieee, struct ath5k_athchan_2ghz *athchan) +static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee, + struct ath5k_athchan_2ghz *athchan) { int channel; @@ -4626,33 +4593,35 @@ ath5k_hw_rf5111_chan2athchan(unsigned int ieee, struct ath5k_athchan_2ghz *athch athchan->a2_athchan = ((channel - 14) * 4) + 132; athchan->a2_flags = 0x46; } else - return false; + return -EINVAL; - return true; + return 0; } /* * Set channel on 5111 */ -bool -ath5k_hw_rf5111_channel(struct ath_hw *hal, struct ieee80211_channel *channel) +static int ath5k_hw_rf5111_channel(struct ath_hw *hal, + struct ieee80211_channel *channel) { + struct ath5k_athchan_2ghz ath_channel_2ghz; unsigned int ieee_channel, ath_channel; u32 data0, data1, clock; - struct ath5k_athchan_2ghz ath_channel_2ghz; + int ret; /* * Set the channel on the RF5111 radio */ data0 = data1 = 0; ath_channel = ieee_channel = ath_hal_mhz2ieee(channel->freq, - channel->val); + channel->val); if (channel->val & CHANNEL_2GHZ) { /* Map 2GHz channel to 5GHz Atheros channel ID */ - if (ath5k_hw_rf5111_chan2athchan(ieee_channel, - &ath_channel_2ghz) == false) - return false; + ret = ath5k_hw_rf5111_chan2athchan(ieee_channel, + &ath_channel_2ghz); + if (ret) + return ret; ath_channel = ath_channel_2ghz.a2_athchan; data0 = ((ath5k_hw_bitswap(ath_channel_2ghz.a2_flags, 8) & 0xff) @@ -4674,14 +4643,14 @@ ath5k_hw_rf5111_channel(struct ath_hw *hal, struct ieee80211_channel *channel) ath5k_hw_reg_write(hal, ((data1 >> 8) & 0xff) | (data0 & 0xff00), AR5K_RF_BUFFER_CONTROL_3); - return true; + return 0; } /* * Set channel on 5112 */ -bool -ath5k_hw_rf5112_channel(struct ath_hw *hal, struct ieee80211_channel *channel) +static int ath5k_hw_rf5112_channel(struct ath_hw *hal, + struct ieee80211_channel *channel) { u32 data, data0, data1, data2; u16 c; @@ -4700,7 +4669,7 @@ ath5k_hw_rf5112_channel(struct ath_hw *hal, struct ieee80211_channel *channel) data0 = ((2 * (c - 672)) - 3040) / 10; data1 = 0; } else - return false; + return -EINVAL; data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8); } else { @@ -4714,7 +4683,7 @@ ath5k_hw_rf5112_channel(struct ath_hw *hal, struct ieee80211_channel *channel) data0 = ath5k_hw_bitswap((c - 4800) / 5, 8); data2 = ath5k_hw_bitswap(1, 2); } else - return false; + return -EINVAL; } data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001; @@ -4722,44 +4691,64 @@ ath5k_hw_rf5112_channel(struct ath_hw *hal, struct ieee80211_channel *channel) ath5k_hw_reg_write(hal, data & 0xff, AR5K_RF_BUFFER); ath5k_hw_reg_write(hal, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5); - return true; + return 0; } /* - * Perform a PHY calibration + * Set a channel on the radio chip */ -bool -ath5k_hw_phy_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel){ +static int ath5k_hw_channel(struct ath_hw *hal, + struct ieee80211_channel *channel) +{ + int ret; - bool ret; + /* + * Check bounds supported by the PHY + * (don't care about regulation restrictions at this point) + */ + if ((channel->freq < hal->ah_capabilities.cap_range.range_2ghz_min || + channel->freq > hal->ah_capabilities.cap_range.range_2ghz_max) && + (channel->freq < hal->ah_capabilities.cap_range.range_5ghz_min || + channel->freq > hal->ah_capabilities.cap_range.range_5ghz_max)) { + AR5K_PRINTF("channel out of supported range (%u MHz)\n", + channel->freq); + return -EINVAL; + } - if (hal->ah_radio == AR5K_RF5110) - ret = ath5k_hw_rf5110_calibrate(hal,channel); - else - ret = ath5k_hw_rf511x_calibrate(hal,channel); + /* + * Set the channel and wait + */ + switch (hal->ah_radio) { + case AR5K_RF5110: + ret = ath5k_hw_rf5110_channel(hal, channel); + break; + case AR5K_RF5111: + ret = ath5k_hw_rf5111_channel(hal, channel); + break; + default: + ret = ath5k_hw_rf5112_channel(hal, channel); + break; + } - return ret; + if (ret) + return ret; + + hal->ah_current_channel.freq = channel->freq; + hal->ah_current_channel.val = channel->val; + hal->ah_turbo = channel->val == CHANNEL_T ? true : false; + + return 0; } + /* * Perform a PHY calibration on RF5110 */ -bool -ath5k_hw_rf5110_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) +static int ath5k_hw_rf5110_calibrate(struct ath_hw *hal, + struct ieee80211_channel *channel) { - bool ret = true; u32 phy_sig, phy_agc, phy_sat, beacon, noise_floor; unsigned int i; - -#define AGC_DISABLE { \ - AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_AGC, \ - AR5K_PHY_AGC_DISABLE); \ - udelay(10); \ -} - -#define AGC_ENABLE { \ - AR5K_REG_DISABLE_BITS(hal, AR5K_PHY_AGC, \ - AR5K_PHY_AGC_DISABLE); \ -} + int ret; /* * Disable beacons and RX/TX queues, wait @@ -4774,7 +4763,8 @@ ath5k_hw_rf5110_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) /* * Set the channel (with AGC turned off) */ - AGC_DISABLE; + AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); + udelay(10); ret = ath5k_hw_channel(hal, channel); /* @@ -4783,9 +4773,9 @@ ath5k_hw_rf5110_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) ath5k_hw_reg_write(hal, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); mdelay(1); - AGC_ENABLE; + AR5K_REG_DISABLE_BITS(hal, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); - if (ret == false) + if (ret) return ret; /* @@ -4813,44 +4803,42 @@ ath5k_hw_rf5110_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) udelay(20); - AGC_DISABLE; + AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); + udelay(10); ath5k_hw_reg_write(hal, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG); - AGC_ENABLE; + AR5K_REG_DISABLE_BITS(hal, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); mdelay(1); /* * Enable calibration and wait until completion */ - AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL); + AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL); - if (ath5k_hw_register_timeout(hal, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL, 0, false)) { - AR5K_PRINTF("calibration timeout (%uMHz)\n", - channel->freq); - ret = false; - } + ret = ath5k_hw_register_timeout(hal, AR5K_PHY_AGCCTL, + AR5K_PHY_AGCCTL_CAL, 0, false); /* Reset to normal state */ ath5k_hw_reg_write(hal, phy_sig, AR5K_PHY_SIG); ath5k_hw_reg_write(hal, phy_agc, AR5K_PHY_AGCCOARSE); ath5k_hw_reg_write(hal, phy_sat, AR5K_PHY_ADCSAT); - if (ret == false) - return false; + if (ret) { + AR5K_PRINTF("calibration timeout (%uMHz)\n", channel->freq); + return ret; + } /* * Enable noise floor calibration and wait until completion */ - AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_NF); + AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF); - if (ath5k_hw_register_timeout(hal, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_NF, 0, false)) { + ret = ath5k_hw_register_timeout(hal, AR5K_PHY_AGCCTL, + AR5K_PHY_AGCCTL_NF, 0, false); + if (ret) { AR5K_PRINTF("noise floor calibration timeout (%uMHz)\n", channel->freq); - return false; + return ret; } /* Wait until the noise floor is calibrated */ @@ -4858,8 +4846,7 @@ ath5k_hw_rf5110_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) mdelay(1); noise_floor = ath5k_hw_reg_read(hal, AR5K_PHY_NF); - if (AR5K_PHY_NF_RVAL(noise_floor) & - AR5K_PHY_NF_ACTIVE) + if (AR5K_PHY_NF_RVAL(noise_floor) & AR5K_PHY_NF_ACTIVE) noise_floor = AR5K_PHY_NF_AVAL(noise_floor); if (noise_floor <= AR5K_TUNE_NOISE_FLOOR) @@ -4869,10 +4856,9 @@ ath5k_hw_rf5110_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) if (noise_floor > AR5K_TUNE_NOISE_FLOOR) { AR5K_PRINTF("noise floor calibration failed (%uMHz)\n", channel->freq); - return false; + return -EIO; } - /* * Re-enable RX/TX and beacons */ @@ -4880,24 +4866,21 @@ ath5k_hw_rf5110_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); ath5k_hw_reg_write(hal, beacon, AR5K_BEACON_5210); -#undef AGC_ENABLE -#undef AGC_DISABLE - - return true; + return 0; } /* * Perform a PHY calibration on RF5111/5112 */ -bool -ath5k_hw_rf511x_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) +static int ath5k_hw_rf511x_calibrate(struct ath_hw *hal, + struct ieee80211_channel *channel) { u32 i_pwr, q_pwr; s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd; AR5K_TRACE; if (hal->ah_calibration == false || - ath5k_hw_reg_read(hal, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) + ath5k_hw_reg_read(hal, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) goto done; hal->ah_calibration = false; @@ -4915,15 +4898,12 @@ ath5k_hw_rf511x_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) q_coff = (((s32)i_pwr / q_coffd) - 64) & 0x1f; /* Commit new IQ value */ - AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_IQ, - AR5K_PHY_IQ_CORR_ENABLE | - ((u32)q_coff) | - ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); + AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE | + ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); - done: +done: /* Start noise floor calibration */ - AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_NF); + AR5K_REG_ENABLE_BITS(hal, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF); /* Request RF gain */ if (channel->val & CHANNEL_5GHZ) { @@ -4933,7 +4913,23 @@ ath5k_hw_rf511x_calibrate(struct ath_hw *hal, struct ieee80211_channel *channel) hal->ah_rf_gain = AR5K_RFGAIN_READ_REQUESTED; } - return true; + return 0; +} + +/* + * Perform a PHY calibration + */ +int ath5k_hw_phy_calibrate(struct ath_hw *hal, + struct ieee80211_channel *channel) +{ + int ret; + + if (hal->ah_radio == AR5K_RF5110) + ret = ath5k_hw_rf5110_calibrate(hal, channel); + else + ret = ath5k_hw_rf511x_calibrate(hal, channel); + + return ret; } bool @@ -4965,9 +4961,8 @@ ath5k_hw_get_def_antenna(struct ath_hw *hal) return false; /*XXX: What do we return for 5210 ?*/ } -unsigned int -ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits, - u32 first, u32 col, bool set) +unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits, + u32 first, u32 col, bool set) { u32 mask, entry, last, data, shift, position; s32 left; @@ -5091,14 +5086,12 @@ ath5k_hw_rfregs_gain_readback(struct ath_hw *hal) hal->ah_gain.g_current <= level[3])); } -s32 -ath5k_hw_rfregs_gain_adjust(struct ath_hw *hal) +s32 ath5k_hw_rfregs_gain_adjust(struct ath_hw *hal) { - int ret = 0; const struct ath5k_gain_opt *go; + int ret = 0; - go = hal->ah_radio == AR5K_RF5111 ? - &rf5111_gain_opt : &rf5112_gain_opt; + go = hal->ah_radio == AR5K_RF5111 ? &rf5111_gain_opt : &rf5112_gain_opt; hal->ah_gain.g_step = &go->go_step[hal->ah_gain.g_step_idx]; @@ -5106,10 +5099,10 @@ ath5k_hw_rfregs_gain_adjust(struct ath_hw *hal) if (hal->ah_gain.g_step_idx == 0) return -1; for (hal->ah_gain.g_target = hal->ah_gain.g_current; - hal->ah_gain.g_target >= hal->ah_gain.g_high && - hal->ah_gain.g_step_idx > 0; - hal->ah_gain.g_step = - &go->go_step[hal->ah_gain.g_step_idx]) { + hal->ah_gain.g_target >= hal->ah_gain.g_high && + hal->ah_gain.g_step_idx > 0; + hal->ah_gain.g_step = + &go->go_step[hal->ah_gain.g_step_idx]) { hal->ah_gain.g_target -= 2 * (go->go_step[--(hal->ah_gain.g_step_idx)].gos_gain - hal->ah_gain.g_step->gos_gain); @@ -5123,12 +5116,12 @@ ath5k_hw_rfregs_gain_adjust(struct ath_hw *hal) if (hal->ah_gain.g_step_idx == (go->go_steps_count - 1)) return -2; for (hal->ah_gain.g_target = hal->ah_gain.g_current; - hal->ah_gain.g_target <= hal->ah_gain.g_low && - hal->ah_gain.g_step_idx < (go->go_steps_count - 1); - hal->ah_gain.g_step = - &go->go_step[hal->ah_gain.g_step_idx]) { + hal->ah_gain.g_target <= hal->ah_gain.g_low && + hal->ah_gain.g_step_idx < go->go_steps_count-1; + hal->ah_gain.g_step = + &go->go_step[hal->ah_gain.g_step_idx]) { hal->ah_gain.g_target -= 2 * - (go->go_step[++(hal->ah_gain.g_step_idx)].gos_gain - + (go->go_step[++hal->ah_gain.g_step_idx].gos_gain - hal->ah_gain.g_step->gos_gain); } @@ -5136,7 +5129,7 @@ ath5k_hw_rfregs_gain_adjust(struct ath_hw *hal) goto done; } - done: +done: #ifdef AR5K_DEBUG AR5K_PRINTF("ret %d, gain step %u, current gain %u, target gain %u\n", ret, @@ -5151,36 +5144,39 @@ ath5k_hw_rfregs_gain_adjust(struct ath_hw *hal) /* * Initialize RF */ -bool -ath5k_hw_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, unsigned int mode) +static int ath5k_hw_rfregs(struct ath_hw *hal, + struct ieee80211_channel *channel, unsigned int mode) { - ath5k_rfgain_t *func = NULL; - bool ret; + int (*func)(struct ath_hw *, struct ieee80211_channel *, unsigned int); + int ret; - if (hal->ah_radio == AR5K_RF5111) { + switch (hal->ah_radio) { + case AR5K_RF5111: hal->ah_rf_banks_size = sizeof(rf5111_rf); func = ath5k_hw_rf5111_rfregs; - } else if (hal->ah_radio == AR5K_RF5112) { + break; + case AR5K_RF5112: if (hal->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) hal->ah_rf_banks_size = sizeof(rf5112a_rf); else hal->ah_rf_banks_size = sizeof(rf5112_rf); func = ath5k_hw_rf5112_rfregs; - } else - return false; + break; + default: + return -EINVAL; + } if (hal->ah_rf_banks == NULL) { /* XXX do extra checks? */ - if ((hal->ah_rf_banks = kmalloc(hal->ah_rf_banks_size, - GFP_KERNEL)) == NULL) { + hal->ah_rf_banks = kmalloc(hal->ah_rf_banks_size, GFP_KERNEL); + if (hal->ah_rf_banks == NULL) { AR5K_PRINT("out of memory\n"); - return false; + return -ENOMEM; } } - ret = (func)(hal, channel, mode); - - if (ret == true) + ret = func(hal, channel, mode); + if (!ret) hal->ah_rf_gain = AR5K_RFGAIN_INACTIVE; return ret; @@ -5189,8 +5185,8 @@ ath5k_hw_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, unsigned /* * Initialize RF5111 */ -bool -ath5k_hw_rf5111_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, unsigned int mode) +static int ath5k_hw_rf5111_rfregs(struct ath_hw *hal, + struct ieee80211_channel *channel, unsigned int mode) { struct ath5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom; const unsigned int rf_size = ARRAY_SIZE(rf5111_rf); @@ -5204,10 +5200,9 @@ ath5k_hw_rf5111_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, un /* Copy values to modify them */ for (i = 0; i < rf_size; i++) { - if (rf5111_rf[i].rf_bank >= - AR5K_RF5111_INI_RF_MAX_BANKS) { + if (rf5111_rf[i].rf_bank >= AR5K_RF5111_INI_RF_MAX_BANKS) { AR5K_PRINT("invalid bank\n"); - return false; + return -EINVAL; } if (bank != rf5111_rf[i].rf_bank) { @@ -5227,12 +5222,12 @@ ath5k_hw_rf5111_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, un obdb = 0; if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[0], - ee->ee_ob[ee_mode][obdb], 3, 119, 0, true)) - return false; + ee->ee_ob[ee_mode][obdb], 3, 119, 0, true)) + return -EINVAL; if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[0], - ee->ee_ob[ee_mode][obdb], 3, 122, 0, true)) - return false; + ee->ee_ob[ee_mode][obdb], 3, 122, 0, true)) + return -EINVAL; obdb = 1; /* Modify bank 6 */ @@ -5245,38 +5240,38 @@ ath5k_hw_rf5111_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, un (channel->freq > 4000 ? 0 : -1))); if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - ee->ee_pwd_84, 1, 51, 3, true)) - return false; + ee->ee_pwd_84, 1, 51, 3, true)) + return -EINVAL; if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - ee->ee_pwd_90, 1, 45, 3, true)) - return false; + ee->ee_pwd_90, 1, 45, 3, true)) + return -EINVAL; } if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - !ee->ee_xpd[ee_mode], 1, 95, 0, true)) - return false; + !ee->ee_xpd[ee_mode], 1, 95, 0, true)) + return -EINVAL; if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - ee->ee_x_gain[ee_mode], 4, 96, 0, true)) - return false; + ee->ee_x_gain[ee_mode], 4, 96, 0, true)) + return -EINVAL; - if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - obdb >= 0 ? ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true)) - return false; + if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], obdb >= 0 ? + ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true)) + return -EINVAL; - if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - obdb >= 0 ? ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true)) - return false; + if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], obdb >= 0 ? + ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true)) + return -EINVAL; /* Modify bank 7 */ if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[7], - ee->ee_i_gain[ee_mode], 6, 29, 0, true)) - return false; + ee->ee_i_gain[ee_mode], 6, 29, 0, true)) + return -EINVAL; if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[7], - ee->ee_xpd[ee_mode], 1, 4, 0, true)) - return false; + ee->ee_xpd[ee_mode], 1, 4, 0, true)) + return -EINVAL; /* Write RF values */ for (i = 0; i < rf_size; i++) { @@ -5284,14 +5279,14 @@ ath5k_hw_rf5111_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, un ath5k_hw_reg_write(hal, rf[i], rf5111_rf[i].rf_register); } - return true; + return 0; } /* * Initialize RF5112 */ -bool -ath5k_hw_rf5112_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, unsigned int mode) +static int ath5k_hw_rf5112_rfregs(struct ath_hw *hal, + struct ieee80211_channel *channel, unsigned int mode) { struct ath5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom; unsigned int rf_size; @@ -5316,7 +5311,7 @@ ath5k_hw_rf5112_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, un for (i = 0; i < rf_size; i++) { if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) { AR5K_PRINT("invalid bank\n"); - return false; + return -EINVAL; } if (bank != rf_ini[i].rf_bank) { @@ -5336,12 +5331,12 @@ ath5k_hw_rf5112_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, un obdb = 0; if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - ee->ee_ob[ee_mode][obdb], 3, 287, 0, true)) - return false; + ee->ee_ob[ee_mode][obdb], 3, 287, 0, true)) + return -EINVAL; if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - ee->ee_ob[ee_mode][obdb], 3, 290, 0, true)) - return false; + ee->ee_ob[ee_mode][obdb], 3, 290, 0, true)) + return -EINVAL; } else { /* For 11a, Turbo and XR */ ee_mode = AR5K_EEPROM_MODE_11A; @@ -5351,12 +5346,12 @@ ath5k_hw_rf5112_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, un (channel->freq > 4000 ? 0 : -1))); if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) - return false; + ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) + return -EINVAL; if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - ee->ee_ob[ee_mode][obdb], 3, 282, 0, true)) - return false; + ee->ee_ob[ee_mode][obdb], 3, 282, 0, true)) + return -EINVAL; } #ifdef notyet @@ -5367,19 +5362,19 @@ ath5k_hw_rf5112_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, un #endif if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[6], - ee->ee_xpd[ee_mode], 1, 302, 0, true)) - return false; + ee->ee_xpd[ee_mode], 1, 302, 0, true)) + return -EINVAL; /* Modify bank 7 */ if (!ath5k_hw_rfregs_op(rf, hal->ah_offset[7], - ee->ee_i_gain[ee_mode], 6, 14, 0, true)) - return false; + ee->ee_i_gain[ee_mode], 6, 14, 0, true)) + return -EINVAL; /* Write RF values */ for (i = 0; i < rf_size; i++) ath5k_hw_reg_write(hal, rf[i], rf_ini[i].rf_register); - return true; + return 0; } /* @@ -5387,9 +5382,9 @@ ath5k_hw_rf5112_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, un * TODO: is this needed ? i mean 5211 has a 5111 RF * doesn't ar5k_rfregs work ? */ -void -ath5k_hw_ar5211_rfregs(struct ath_hw *hal, struct ieee80211_channel *channel, unsigned int freq, - unsigned int ee_mode) +static void ath5k_hw_ar5211_rfregs(struct ath_hw *hal, + struct ieee80211_channel *channel, unsigned int freq, + unsigned int ee_mode) { struct ath5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom; struct ath5k_ar5211_ini_rf rf[ARRAY_SIZE(ar5211_rf)]; @@ -5476,8 +5471,7 @@ ath5k_hw_rfgain(struct ath_hw *hal, unsigned int phy, u_int freq) return true; } -enum ath5k_rfgain -ath5k_hw_get_rf_gain(struct ath_hw *hal) +enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath_hw *hal) { u32 data, type; @@ -5502,18 +5496,18 @@ ath5k_hw_get_rf_gain(struct ath_hw *hal) if (hal->ah_radio == AR5K_RF5112) { ath5k_hw_rfregs_gainf_corr(hal); hal->ah_gain.g_current = - hal->ah_gain.g_current >= hal->ah_gain.g_f_corr ? - (hal->ah_gain.g_current - hal->ah_gain.g_f_corr) : + hal->ah_gain.g_current>=hal->ah_gain.g_f_corr ? + (hal->ah_gain.g_current-hal->ah_gain.g_f_corr) : 0; } if (ath5k_hw_rfregs_gain_readback(hal) && - AR5K_GAIN_CHECK_ADJUST(&hal->ah_gain) && - ath5k_hw_rfregs_gain_adjust(hal)) + AR5K_GAIN_CHECK_ADJUST(&hal->ah_gain) && + ath5k_hw_rfregs_gain_adjust(hal)) hal->ah_rf_gain = AR5K_RFGAIN_NEED_CHANGE; } - done: +done: return hal->ah_rf_gain; }