/*
* This code is used to optimize rf gain on different environments
- * (temprature mostly) based on feedback from a power detector.
+ * (temperature mostly) based on feedback from a power detector.
*
* It's only used on RF5111 and RF5112, later RF chips seem to have
* auto adjustment on hw -notice they have a much smaller BANK 7 and
AR5K_RF_XPD_GAIN, true);
} else {
- /* TODO: Set high and low gain bits */
- ath5k_hw_rfb_op(ah, rf_regs,
- ee->ee_x_gain[ee_mode],
+ u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
+ if (ee->ee_pd_gains[ee_mode] > 1) {
+ ath5k_hw_rfb_op(ah, rf_regs,
+ pdg_curve_to_idx[0],
AR5K_RF_PD_GAIN_LO, true);
- ath5k_hw_rfb_op(ah, rf_regs,
- ee->ee_x_gain[ee_mode],
+ ath5k_hw_rfb_op(ah, rf_regs,
+ pdg_curve_to_idx[1],
AR5K_RF_PD_GAIN_HI, true);
+ } else {
+ ath5k_hw_rfb_op(ah, rf_regs,
+ pdg_curve_to_idx[0],
+ AR5K_RF_PD_GAIN_LO, true);
+ ath5k_hw_rfb_op(ah, rf_regs,
+ pdg_curve_to_idx[0],
+ AR5K_RF_PD_GAIN_HI, true);
+ }
/* Lower synth voltage on Rev 2 */
ath5k_hw_rfb_op(ah, rf_regs, 2,
AR5K_PHY_CCKTXCTL_WORLD);
}
- ah->ah_current_channel.center_freq = channel->center_freq;
- ah->ah_current_channel.hw_value = channel->hw_value;
+ ah->ah_current_channel = channel;
ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
return 0;
PHY calibration
\*****************/
+void
+ath5k_hw_calibration_poll(struct ath5k_hw *ah)
+{
+ /* Calibration interval in jiffies */
+ unsigned long cal_intval;
+
+ cal_intval = msecs_to_jiffies(ah->ah_cal_intval * 1000);
+
+ /* Initialize timestamp if needed */
+ if (!ah->ah_cal_tstamp)
+ ah->ah_cal_tstamp = jiffies;
+
+ /* For now we always do full calibration
+ * Mark software interrupt mask and fire software
+ * interrupt (bit gets auto-cleared) */
+ if (time_is_before_eq_jiffies(ah->ah_cal_tstamp + cal_intval)) {
+ ah->ah_cal_tstamp = jiffies;
+ ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
+ AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
+ }
+
+}
+
/**
* ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
*
void
ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
{
- struct ieee80211_channel *channel = &ah->ah_current_channel;
+ struct ieee80211_channel *channel = ah->ah_current_channel;
bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
bool use_def_for_sg;
u8 def_ant, tx_ant, ee_mode;
s16 min_pwrL, min_pwrR;
s16 pwr_i;
- if (WARN_ON(stepL[0] == stepL[1] || stepR[0] == stepR[1]))
- return 0;
+ /* Some vendors write the same pcdac value twice !!! */
+ if (stepL[0] == stepL[1] || stepR[0] == stepR[1])
+ return max(pwrL[0], pwrR[0]);
if (pwrL[0] == pwrL[1])
min_pwrL = pwrL[0];
ath5k_get_max_ctl_power(struct ath5k_hw *ah,
struct ieee80211_channel *channel)
{
+ struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
u8 *ctl_val = ee->ee_ctl;
u8 ctl_idx = 0xFF;
u32 target = channel->center_freq;
- ctl_mode = ath_regd_get_band_ctl(&ah->ah_regulatory, channel->band);
+ ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band);
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
/* Fill curves in reverse order
* from lower power (max gain)
* to higher power. Use curve -> idx
- * backmaping we did on eeprom init */
+ * backmapping we did on eeprom init */
u8 idx = pdg_curve_to_idx[pdg];
/* Grab the needed curves by index */
/* Now we have a set of curves for this
* channel on tmpL (x range is table_max - table_min
* and y values are tmpL[pdg][]) sorted in the same
- * order as EEPROM (because we've used the backmaping).
+ * order as EEPROM (because we've used the backmapping).
* So for RF5112 it's from higher power to lower power
* and for RF2413 it's from lower power to higher power.
* For RF5111 we only have one curve. */
int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
{
/*Just a try M.F.*/
- struct ieee80211_channel *channel = &ah->ah_current_channel;
+ struct ieee80211_channel *channel = ah->ah_current_channel;
u8 ee_mode;
ATH5K_TRACE(ah->ah_sc);