Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f3b414a authored by Nick Kossifidis's avatar Nick Kossifidis Committed by John W. Linville
Browse files

ath5k: Update gain_F calibration code and add documentation



 * Update and cleanup rf gain optimization code

 * Add comments and refferences to docs and use sane function names

 * Use only step index on ath5k_gain, no need to have a pointer to
   the current step since we can determine te step from it's index,
   this also allows us to put all other structs on rfgain.h and cleanup
   ath5k.h a little

 * No need for ah_rfgain variable, we use ah_gain.g_state for everything

 * Tested on RF2112B chip but gain_F calibration is not yet done
   (we will finish this on the next patch where we'll rewrite rf-buffer
   handling)

 * Use initial rf gain settings for 2316 and 2317 SoCs introduced on a previous patch

 It seems big but it's mostly cleanup, very few functional changes have been made on phy.c

  Signed-off-by: default avatarNick Kossifidis <mickflemm@gmail.com>

Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 33a31826
Loading
Loading
Loading
Loading
+11 −40
Original line number Diff line number Diff line
@@ -649,49 +649,21 @@ struct ath5k_beacon_state {

enum ath5k_rfgain {
	AR5K_RFGAIN_INACTIVE = 0,
	AR5K_RFGAIN_ACTIVE,
	AR5K_RFGAIN_READ_REQUESTED,
	AR5K_RFGAIN_NEED_CHANGE,
};

#define AR5K_GAIN_CRN_FIX_BITS_5111		4
#define AR5K_GAIN_CRN_FIX_BITS_5112		7
#define AR5K_GAIN_CRN_MAX_FIX_BITS		AR5K_GAIN_CRN_FIX_BITS_5112
#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN		15
#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN		20
#define AR5K_GAIN_CCK_PROBE_CORR		5
#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA		15
#define AR5K_GAIN_STEP_COUNT			10
#define AR5K_GAIN_PARAM_TX_CLIP			0
#define AR5K_GAIN_PARAM_PD_90			1
#define AR5K_GAIN_PARAM_PD_84			2
#define AR5K_GAIN_PARAM_GAIN_SEL		3
#define AR5K_GAIN_PARAM_MIX_ORN			0
#define AR5K_GAIN_PARAM_PD_138			1
#define AR5K_GAIN_PARAM_PD_137			2
#define AR5K_GAIN_PARAM_PD_136			3
#define AR5K_GAIN_PARAM_PD_132			4
#define AR5K_GAIN_PARAM_PD_131			5
#define AR5K_GAIN_PARAM_PD_130			6
#define AR5K_GAIN_CHECK_ADJUST(_g) 		\
	((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)

struct ath5k_gain_opt_step {
	s16				gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
	s32				gos_gain;
};

struct ath5k_gain {
	u32			g_step_idx;
	u32			g_current;
	u32			g_target;
	u32			g_low;
	u32			g_high;
	u32			g_f_corr;
	u32			g_active;
	const struct ath5k_gain_opt_step	*g_step;
	u8			g_step_idx;
	u8			g_current;
	u8			g_target;
	u8			g_low;
	u8			g_high;
	u8			g_f_corr;
	u8			g_state;
};


/********************\
  COMMON DEFINITIONS
\********************/
@@ -1053,7 +1025,6 @@ struct ath5k_hw {
	bool			ah_running;
	bool			ah_single_chip;
	bool			ah_combined_mic;
	enum ath5k_rfgain	ah_rf_gain;

	u32			ah_mac_srev;
	u16			ah_mac_version;
@@ -1262,9 +1233,9 @@ extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_cha

/* Initialize RF */
extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode);
extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq);
extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah);
extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah);
extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
/* PHY/RF channel functions */
extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
+1 −1
Original line number Diff line number Diff line
@@ -331,7 +331,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
	ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
	ath5k_hw_set_opmode(ah);

	ath5k_hw_set_rfgain_opt(ah);
	ath5k_hw_rfgain_opt_init(ah);

	return ah;
err_free:
+1 −1
Original line number Diff line number Diff line
@@ -2518,7 +2518,7 @@ ath5k_calibrate(unsigned long data)
		ieee80211_frequency_to_channel(sc->curchan->center_freq),
		sc->curchan->hw_value);

	if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) {
	if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
		/*
		 * Rfgain is out of bounds, reset the chip
		 * to load new gain values.
+264 −139
Original line number Diff line number Diff line
@@ -78,10 +78,104 @@ static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits,
	return data;
}

static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
/**********************\
* RF Gain optimization *
\**********************/

/*
 * This code is used to optimize rf gain on different environments
 * (temprature 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
 * no gain optimization ladder-.
 *
 * For more infos check out this patent doc
 * http://www.freepatentsonline.com/7400691.html
 *
 * This paper describes power drops as seen on the receiver due to
 * probe packets
 * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
 * %20of%20Power%20Control.pdf
 *
 * And this is the MadWiFi bug entry related to the above
 * http://madwifi-project.org/ticket/1659
 * with various measurements and diagrams
 *
 * TODO: Deal with power drops due to probes by setting an apropriate
 * tx power on the probe packets ! Make this part of the calibration process.
 */

/* Initialize ah_gain durring attach */
int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
{
	/* Initialize the gain optimization values */
	switch (ah->ah_radio) {
	case AR5K_RF5111:
		ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
		ah->ah_gain.g_low = 20;
		ah->ah_gain.g_high = 35;
		ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
		break;
	case AR5K_RF5112:
		ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
		ah->ah_gain.g_low = 20;
		ah->ah_gain.g_high = 85;
		ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

/* Schedule a gain probe check on the next transmited packet.
 * That means our next packet is going to be sent with lower
 * tx power and a Peak to Average Power Detector (PAPD) will try
 * to measure the gain.
 *
 * TODO: Use propper tx power setting for the probe packet so
 * that we don't observe a serious power drop on the receiver
 *
 * XXX:  How about forcing a tx packet (bypassing PCU arbitrator etc)
 * just after we enable the probe so that we don't mess with
 * standard traffic ? Maybe it's time to use sw interrupts and
 * a probe tasklet !!!
 */
static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
{

	/* Skip if gain calibration is inactive or
	 * we already handle a probe request */
	if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
		return;

	ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
			AR5K_PHY_PAPD_PROBE_TXPOWER) |
			AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);

	ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;

}

/* Calculate gain_F measurement correction
 * based on the current step for RF5112 rev. 2 */
static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
{
	u32 mix, step;
	u32 *rf;
	const struct ath5k_gain_opt *go;
	const struct ath5k_gain_opt_step *g_step;

	/* Only RF5112 Rev. 2 supports it */
	if ((ah->ah_radio != AR5K_RF5112) ||
	(ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
		return 0;

	go = &rfgain_opt_5112;

	g_step = &go->go_step[ah->ah_gain.g_step_idx];

	if (ah->ah_rf_banks == NULL)
		return 0;
@@ -89,11 +183,15 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
	rf = ah->ah_rf_banks;
	ah->ah_gain.g_f_corr = 0;

	/* No VGA (Variable Gain Amplifier) override, skip */
	if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1)
		return 0;

	/* Mix gain stepping */
	step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false);
	mix = ah->ah_gain.g_step->gos_param[0];

	/* Mix gain override */
	mix = g_step->gos_param[0];

	switch (mix) {
	case 3:
@@ -113,9 +211,13 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
	return ah->ah_gain.g_f_corr;
}

static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
/* Check if current gain_F measurement is in the range of our
 * power detector windows. If we get a measurement outside range
 * we know it's not accurate (detectors can't measure anything outside
 * their detection window) so we must ignore it */
static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
{
	u32 step, mix, level[4];
	u32 step, mix_ovr, level[4];
	u32 *rf;

	if (ah->ah_rf_banks == NULL)
@@ -127,20 +229,20 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
		step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0,
				false);
		level[0] = 0;
		level[1] = (step == 0x3f) ? 0x32 : step + 4;
		level[2] = (step != 0x3f) ? 0x40 : level[0];
		level[3] = level[2] + 0x32;
		level[1] = (step == 63) ? 50 : step + 4;
		level[2] = (step != 63) ? 64 : level[0];
		level[3] = level[2] + 50 ;

		ah->ah_gain.g_high = level[3] -
			(step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
			(step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
		ah->ah_gain.g_low = level[0] +
			(step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
			(step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
	} else {
		mix = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0,
		mix_ovr = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0,
				false);
		level[0] = level[2] = 0;

		if (mix == 1) {
		if (mix_ovr == 1) {
			level[1] = level[3] = 83;
		} else {
			level[1] = level[3] = 107;
@@ -154,9 +256,12 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
			ah->ah_gain.g_current <= level[3]);
}

static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
/* Perform gain_F adjustment by choosing the right set
 * of parameters from rf gain optimization ladder */
static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
{
	const struct ath5k_gain_opt *go;
	const struct ath5k_gain_opt_step *g_step;
	int ret = 0;

	switch (ah->ah_radio) {
@@ -170,35 +275,39 @@ static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
		return 0;
	}

	ah->ah_gain.g_step = &go->go_step[ah->ah_gain.g_step_idx];
	g_step = &go->go_step[ah->ah_gain.g_step_idx];

	if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {

		/* Reached maximum */
		if (ah->ah_gain.g_step_idx == 0)
			return -1;

		for (ah->ah_gain.g_target = ah->ah_gain.g_current;
				ah->ah_gain.g_target >=  ah->ah_gain.g_high &&
				ah->ah_gain.g_step_idx > 0;
				ah->ah_gain.g_step =
					&go->go_step[ah->ah_gain.g_step_idx])
				g_step = &go->go_step[ah->ah_gain.g_step_idx])
			ah->ah_gain.g_target -= 2 *
			    (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
			    ah->ah_gain.g_step->gos_gain);
			    g_step->gos_gain);

		ret = 1;
		goto done;
	}

	if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {

		/* Reached minimum */
		if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
			return -2;

		for (ah->ah_gain.g_target = ah->ah_gain.g_current;
				ah->ah_gain.g_target <= ah->ah_gain.g_low &&
				ah->ah_gain.g_step_idx < go->go_steps_count-1;
				ah->ah_gain.g_step =
					&go->go_step[ah->ah_gain.g_step_idx])
				g_step = &go->go_step[ah->ah_gain.g_step_idx])
			ah->ah_gain.g_target -= 2 *
			    (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
			    ah->ah_gain.g_step->gos_gain);
			    g_step->gos_gain);

		ret = 2;
		goto done;
@@ -213,6 +322,135 @@ static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
	return ret;
}

/* Main callback for thermal rf gain calibration engine
 * Check for a new gain reading and schedule an adjustment
 * if needed.
 *
 * TODO: Use sw interrupt to schedule reset if gain_F needs
 * adjustment */
enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
{
	u32 data, type;
	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;

	ATH5K_TRACE(ah->ah_sc);

	if (ah->ah_rf_banks == NULL ||
	ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
		return AR5K_RFGAIN_INACTIVE;

	/* No check requested, either engine is inactive
	 * or an adjustment is already requested */
	if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
		goto done;

	/* Read the PAPD (Peak to Average Power Detector)
	 * register */
	data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);

	/* No probe is scheduled, read gain_F measurement */
	if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
		ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
		type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);

		/* If tx packet is CCK correct the gain_F measurement
		 * by cck ofdm gain delta */
		if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
			if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
				ah->ah_gain.g_current +=
					ee->ee_cck_ofdm_gain_delta;
			else
				ah->ah_gain.g_current +=
					AR5K_GAIN_CCK_PROBE_CORR;
		}

		/* Further correct gain_F measurement for
		 * RF5112A radios */
		if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
			ath5k_hw_rf_gainf_corr(ah);
			ah->ah_gain.g_current =
				ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
				(ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
				0;
		}

		/* Check if measurement is ok and if we need
		 * to adjust gain, schedule a gain adjustment,
		 * else switch back to the acive state */
		if (ath5k_hw_rf_check_gainf_readback(ah) &&
		AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
		ath5k_hw_rf_gainf_adjust(ah)) {
			ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
		} else {
			ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
		}
	}

done:
	return ah->ah_gain.g_state;
}

/* Write initial rf gain table to set the RF sensitivity
 * this one works on all RF chips and has nothing to do
 * with gain_F calibration */
int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
{
	const struct ath5k_ini_rfgain *ath5k_rfg;
	unsigned int i, size;

	switch (ah->ah_radio) {
	case AR5K_RF5111:
		ath5k_rfg = rfgain_5111;
		size = ARRAY_SIZE(rfgain_5111);
		break;
	case AR5K_RF5112:
		ath5k_rfg = rfgain_5112;
		size = ARRAY_SIZE(rfgain_5112);
		break;
	case AR5K_RF2413:
		ath5k_rfg = rfgain_2413;
		size = ARRAY_SIZE(rfgain_2413);
		break;
	case AR5K_RF2316:
		ath5k_rfg = rfgain_2316;
		size = ARRAY_SIZE(rfgain_2316);
		break;
	case AR5K_RF5413:
		ath5k_rfg = rfgain_5413;
		size = ARRAY_SIZE(rfgain_5413);
		break;
	case AR5K_RF2317:
	case AR5K_RF2425:
		ath5k_rfg = rfgain_2425;
		size = ARRAY_SIZE(rfgain_2425);
		break;
	default:
		return -EINVAL;
	}

	switch (freq) {
	case AR5K_INI_RFGAIN_2GHZ:
	case AR5K_INI_RFGAIN_5GHZ:
		break;
	default:
		return -EINVAL;
	}

	for (i = 0; i < size; i++) {
		AR5K_REG_WAIT(i);
		ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
			(u32)ath5k_rfg[i].rfg_register);
	}

	return 0;
}



/********************\
* RF Registers setup *
\********************/

/*
 * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111
 */
@@ -311,6 +549,8 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah,
		ath5k_hw_reg_write(ah, rf[i], rfb_5111[i].rfb_ctrl_register);
	}

	ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;

	return 0;
}

@@ -407,6 +647,9 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah,
	for (i = 0; i < rf_size; i++)
		ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rfb_ctrl_register);


	ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;

	return 0;
}

@@ -536,125 +779,12 @@ int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
	}

	ret = func(ah, channel, mode);
	if (!ret)
		ah->ah_rf_gain = AR5K_RFGAIN_INACTIVE;

	return ret;
}

int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
{
	const struct ath5k_ini_rfgain *ath5k_rfg;
	unsigned int i, size;

	switch (ah->ah_radio) {
	case AR5K_RF5111:
		ath5k_rfg = rfgain_5111;
		size = ARRAY_SIZE(rfgain_5111);
		break;
	case AR5K_RF5112:
		ath5k_rfg = rfgain_5112;
		size = ARRAY_SIZE(rfgain_5112);
		break;
	case AR5K_RF5413:
		ath5k_rfg = rfgain_5413;
		size = ARRAY_SIZE(rfgain_5413);
		break;
	case AR5K_RF2413:
		ath5k_rfg = rfgain_2413;
		size = ARRAY_SIZE(rfgain_2413);
		break;
	case AR5K_RF2425:
		ath5k_rfg = rfgain_2425;
		size = ARRAY_SIZE(rfgain_2425);
		break;
	default:
		return -EINVAL;
	}

	switch (freq) {
	case AR5K_INI_RFGAIN_2GHZ:
	case AR5K_INI_RFGAIN_5GHZ:
		break;
	default:
		return -EINVAL;
	}

	for (i = 0; i < size; i++) {
		AR5K_REG_WAIT(i);
		ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
			(u32)ath5k_rfg[i].rfg_register);
	}

	return 0;
}

enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah)
{
	u32 data, type;

	ATH5K_TRACE(ah->ah_sc);

	if (ah->ah_rf_banks == NULL || !ah->ah_gain.g_active ||
			ah->ah_version <= AR5K_AR5211)
		return AR5K_RFGAIN_INACTIVE;

	if (ah->ah_rf_gain != AR5K_RFGAIN_READ_REQUESTED)
		goto done;

	data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);

	if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
		ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
		type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);

		if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK)
			ah->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;

		if (ah->ah_radio >= AR5K_RF5112) {
			ath5k_hw_rfregs_gainf_corr(ah);
			ah->ah_gain.g_current =
				ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
				(ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
				0;
		}

		if (ath5k_hw_rfregs_gain_readback(ah) &&
				AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
				ath5k_hw_rfregs_gain_adjust(ah))
			ah->ah_rf_gain = AR5K_RFGAIN_NEED_CHANGE;
	}

done:
	return ah->ah_rf_gain;
}

int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah)
{
	/* Initialize the gain optimization values */
	switch (ah->ah_radio) {
	case AR5K_RF5111:
		ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
		ah->ah_gain.g_step =
		    &rfgain_opt_5111.go_step[ah->ah_gain.g_step_idx];
		ah->ah_gain.g_low = 20;
		ah->ah_gain.g_high = 35;
		ah->ah_gain.g_active = 1;
		break;
	case AR5K_RF5112:
		ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
		ah->ah_gain.g_step =
		    &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
		ah->ah_gain.g_low = 20;
		ah->ah_gain.g_high = 85;
		ah->ah_gain.g_active = 1;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

/**************************\
  PHY/RF channel functions
@@ -1176,13 +1306,8 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
	 * as often as I/Q calibration.*/
	ath5k_hw_noise_floor_calibration(ah, channel->center_freq);

	/* Request RF gain */
	if (channel->hw_value & CHANNEL_5GHZ) {
		ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
			AR5K_PHY_PAPD_PROBE_TXPOWER) |
			AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
		ah->ah_rf_gain = AR5K_RFGAIN_READ_REQUESTED;
	}
	/* Initiate a gain_F calibration */
	ath5k_hw_request_rfgain_probe(ah);

	return 0;
}
+1 −4
Original line number Diff line number Diff line
@@ -441,9 +441,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
	s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
	s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);

	if (change_channel && ah->ah_rf_banks != NULL)
		ath5k_hw_get_rf_gain(ah);


	/*Wakeup the device*/
	ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
@@ -530,7 +527,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
		 * Write initial RF gain settings
		 * This should work for both 5111/5112
		 */
		ret = ath5k_hw_rfgain(ah, freq);
		ret = ath5k_hw_rfgain_init(ah, freq);
		if (ret)
			return ret;

Loading